OGRE CG教程 (一):OGRE CG 基础

来源:互联网 发布:云狐网络科技园怎么样 编辑:程序博客网 时间:2024/05/16 16:14

Example 1: Plain Texture 

例子1:平面纹理

This is a working example of how to create a very simple shader. The shader just applies a single texture to an object. No lighting is performed.
这是一个简单的shader教程.给物体贴上一个简单的纹理,不执行任何光照效果.

First, create a .material file. The filename is unimportant, but make sure it's in a directory that the game is scanning for media. In the example applications, this is configured in 'resources.cfg'. Add the following material definition to the material file.
首先.创造一个纹理文件;文件的名字并不重要;但是一定要保证ogre能找到这个纹理;在这个例子中,我们需要在'resources.cfg'这个文件里面添加进我们的材质文件的名称.然后我们在那个材质文件中添加进以下的纹理.

// CG Vertex shader definition  定义CG的顶点着色程序vertex_program PlainTexture_VS cg            {        // Look in this source file for shader code  系统会在<span style="font-family: Arial, Helvetica, sans-serif;">GameObjStandard.cg这个文件中找到入口函数</span>    source GameObjStandard.cg        // Use this function for the vertex shader     入口函数           entry_point main_plain_texture_vp            // Compile the shader to vs_1_1 format    编译CG所使用的格式    profiles vs_1_1                         // This block saves us from manually setting parameters in code  代码中手动设置的变量被存在以下的代码块中        default_params                        {                // Ogre will put the worldviewproj into our 'worldViewProj' parameter for us.  ogre会自动的把世界矩阵存入下面的变量        param_named_auto worldViewProj worldviewproj_matrix                        // Note that 'worldViewProj' is a parameter in the cg code.    }} // CG Pixel shader definition  定义CG的片段着色器fragment_program PlainTexture_PS cg            {        // Look in this source file for shader code    source GameObjStandard.cg                // Use this function for the pixel shader        entry_point main_plain_texture_fp            // Compile to ps_1_1 format        profiles ps_1_1                    } material PlainTexture  //我们所使用的材质{        // Material has one technique  材质只有一种技术    technique                        {                // This technique has one pass  这个技术只有一个通道,这个通道使用顶点和片段着色器        pass                            {                        // Make this pass use the vertex shader defined above            vertex_program_ref PlainTexture_VS                {            }                        // Make this pass use the pixel shader defined above            fragment_program_ref PlainTexture_PS                {            }            texture_unit            {                                // This pass will use this 2D texture as its input  Ten.png为输入纹理                texture Ten.png 2d                    }        }    }}

This material made references to another file which contains the CG pixel and vertex shaders. Create a file 'GameObjStandard.cg' (also in a media directory) and add the following block. This time the name of the file is important, as the material file refers specifically to it.
CG文件里的顶点和片段着色器和这个材质是相关联的;
接下来我们在相同的目录下创建一个文件'GameObjStandard.cg' 这个文件名必须和材质里source所提及的CG文件一致.

void main_plain_texture_vp(  //顶点着色器        // Vertex Inputs        float4 position        : POSITION,    // Vertex position in model space  模型空间中的顶点        float2 texCoord0    : TEXCOORD0,    // Texture UV set 0         // Outputs        out float4 oPosition    : POSITION,    // Transformed vertex position 转换后的顶点坐标        out float2 uv0        : TEXCOORD0,    // UV0         // Model Level Inputs        uniform float4x4 worldViewProj){    // Calculate output position  计算输出的位置    oPosition = mul(worldViewProj, position);     // Simply copy the input vertex UV to the output  简单的对纹理坐标进行赋值    uv0 = texCoord0;} void main_plain_texture_fp(  //片段着色器        // Pixel Inputs          float2 uv0        : TEXCOORD0,    // UV interpolated for current pixel  当前像素的纹理坐标         // Outputs        out float4 color    : COLOR,    // Output color we want to write 我们想要输出的颜色         // Model Level Inputs        uniform sampler2D texture)        // Texture we're going to use  纹理输入{    // Just sample texture using supplied UV    color = tex2D(texture, uv0);  //用纹理坐标查找纹理中对应坐标的颜色}

The keyword uniform identifies the parameters you will have to supply in the material file.

  • Some parameters can be supplied by the Ogre Engine (param_named_auto), like a light position.
  • Some parameters can be supplied by your material file (param_named) like a texture map.
  • Some parameters can be supplied by your application (custom).
关键字uniform定义变量的意义:
param_named_auto: 由Ogre引擎自动提供,就像是光照
param_named:由材质文件所提供,就像是纹理映射
custom:由用户应用程序进行定义的.

Finally, in the game code, you need to set the material on the entity. To do so, you'll want a line of code something like the following:
最后,必须在你的代码中给实体添加上材质.
pOgreEntity->setMaterialName( "PlainTexture" );

The texture should render on the object. If the material failed to compile properly, it will render white.
正常情况下,纹理会对物体进行渲染.如果纹理编译失败,物体将会被渲染成白色.

Example 2: Texture with modulated color

例子2:可调整颜色的纹理

Now let's say that we want to tweak our simple shader by modulating the texture with another color, and also specify an alpha value for the object.

现在,我们要对刚刚的shader做些简单的修改,我们将会把纹理输出的颜色调整为其他颜色,也会对物体的alpha值进行处理.

Colors and modulation basics:

  • In shaders, color values are normally in the range 0..1. A pure red would be R=1, G=0, B=0.
  • A color can be stored in a float3, or a float4 with the fourth component containing alpha information.
  • The RGB components can be accessed as either .r, .g, .b, .a or .x, .y, .z, .w
  • Modulate means multiply. Let's take an example:
    • Lets say that reading the texture with the tex2D returns (R=1, G=0.5, B=0)
    • Lets say we then modulate that with a pink (R=1, G=0.25, B=0.25)
    • This gives an output of (1*1, 0.5*0.25, 0*0.25) = (1, 0.125, 0)
    • The result is that the source texture gets a pink tone to it. Note that modulating with numbers in the range 0..1 only makes things darker, and modulating low numbers together goes to black quickly.
颜色调制的基础
在shader中,颜色值正常情况下在0~1之间,比如纯红是R = 1 G=0 B=0.
一个颜色可以为float3类型或者float4类型,float4类型多出一个alpha通道
RGBA和XYZW都可以表示颜色
可调制的意思是做乘法,举个栗子:
(1 0.5 0) * (1 0.25 0.25) = (1*1 0.5*0.25 0*0.25) = (1 0.125 0).
我们注意到,调制后的颜色范围还是在0~1之间.而且调制后的颜色会变得更黑.(因为小于1的数总是越乘越小)

First, define a new material. The key important notes are:

  • The vertex shader doesn't need to do anything different than before, so we're going to use the same one as the material before. We don't need to define a new 'vertex program', though a better naming than 'PlainTexture_VS' would have been more appropriate :-)
  • There's going to be a new pixel shader, so we define a new 'fragment program' block in the material file. It's the same as the last one except it has a different 'entry point' and it defines a default value for our new 'colorModulate' parameter.
  • The material 'pass' block now has a line 'scene_blend alpha_blend'. This means that the pixel shader alpha channel output will be used to blend the color with what's already in the frame buffer. An alpha output of 0 would cause the object to be invisible, and a value of 1 would make it entirely solid.
  • The 'fragment_program_ref' references the name of our new 'fragment program' block.
首先,我们定义一个新的材质.以下几点非常重要:
·顶点着色器不需要做任何改变.所以我们和之前用的材质也不做任何改变.
·我们需要定义一个新的片段着色器,材质文件中片段着色器的声明需稍作修改,修改片段着色器的入口.而且我们需要重新定义一个默认变量colorModule
·材质中的通道需要增加一行 scene_blend alpha_blend.意思是像素着色器产生的颜色会和帧缓存中已经存在的像素进行混合.如果片段着色器的颜色输出中alpha为0,则说明物体是不可见的.若为1,则为完全可见.
·fragment_program_ref中的内容和之前完全一样.
fragment_program TextureModColor_PS cg{    source GameObjStandard.cg     // Different entry point for pixel shader  和之前的入口不一样    entry_point main_tex_mod_col_fp     profiles ps_1_1     default_params    {        // Specify a default value for a new parameter        // Note that we don't need to specify whether it's a pixel of vertex shader parameter
<span style="white-space:pre"></span>//如果我们没有指定colorModulate的值,它默认为 (1 0 0 0.5)        param_named colorModulate float4 1 0 0 0.5            }} material TextureModColor{    technique    {        pass        {            // Makes the pixel shader alpha output be used for alpha blending            scene_blend alpha_blend                         vertex_program_ref PlainTexture_VS            {            }            fragment_program_ref TextureModColor_PS            {            }            texture_unit            {                texture Ten.png 2d            }        }    }}

Now add the following new pixel shader to your CG file. The key noteworthy changes from the first pixel shader are:

  • There's a new 'colorModulate' function. Note how the parameter name matches the default value set in the material.
  • After the texture sample, we modulate the texture with the new parameter.
  • The last line explicitly puts the alpha value from the parameter into the alpha channel of the output variable.
    • Actually this isn't strictly needed in my case. My texture doesn't have an alpha channel, so the texture sample just puts a 1 into the alpha channel. Then the modulate for the alpha channel operation makes gives color.a = 1 * colorModulate.a, which is the same as color.a = colorModulate.a. I'll leave the line in though as it demonstrates that you can assign values into RGBA too...
为CG文件添加新的像素着色器
·我们在函数中添加新的变量"colorModulate",注意这个变量是如何和材质的变量默认值进行匹配的.
·我们用新的变量来调制颜色;
·最后一行我们用"colorModulate"的alpha值作为输出颜色的alpha值.
□实际上.这在我们的例子中并不是严格需要的,我们的纹理并没有alpha通道,所以纹理的alpha通道默认为1,然后我们使用调制对纹理的alpha通道进行改变.

void main_tex_mod_col_fp(            float2 diffuse        : TEXCOORD0,            out float4 color    : COLOR,            uniform float4 colorModulate,    // Added the color parameter  添加参数            uniform sampler2D texture){    color = tex2D(texture, diffuse);        // Sample the texture    color = color * colorModulate;            // Multiply the pixel color by colorModulate    color.a = colorModulate.a;            // Set the output alpha to be colorModulate.w}

Programmatic control of color parameter

使用编程控制颜色参数

So far the material we've defined applies a default color modulation and alpha value to the object. We can control this value dynamically from code on a per entity (or rather sub entity) basis. First we need to add a line to the 'fragment program ref' block in the material:
目前为止,我们定义的材质使用默认的颜色调制和alpha值.我们可以在程序中动态的调整他的值.首先,我们必须在材质中的片段处理程序的声明加入如下的代码:
fragment_program_ref TextureModColor_PS            {                param_named_auto colorModulate custom 1            }

This means that our parameter 'colorModulate' can be set from code by setting parameter '1'. 
这意味着我们的变量colorModulate被标号为1.
Now we add some lines to your test application at some point after the material is attached to the object. For example:
现在我们添加一些代码道程序中,要在材质被贴到物体之后.

// Init material    mEntity->setMaterialName( "TextureModColor" ); #define COLOR_MODULATE_PARAM_INDEX 1    SubEntity* pSub = mEntity->getSubEntity(0);    pSub->setCustomParameter(COLOR_MODULATE_PARAM_INDEX, Vector4(0.f, 0.f, 1.0f, 0.2f));

















0 0
原创粉丝点击