irrwowview

Tutorial 10: Shaders

Tutorial 10: Shaders
本教程演示了如何在引擎中使用D3D8, D3D9OpenGL 的着色器,并用着色器创建新的材质。还演示了如何取消在纹理加载时产生的mipmaps,和如何使用文本场景节点。

本教程不解释着色器如何工作。我推荐看D3DOpenGL文档,搜索相关教程或者阅读相关书籍。

程序效果如下图所示:

 

Lets start!

首先,好像之前的其它教程那样需要包含头文件等东西:

#include <irrlicht.h>
#include <iostream>

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

因为要在引擎中使用有趣的着色器,所以我们要设置着色器,用于计算漂亮的颜色。在这个例子中,我们要用简单的顶点着色器来计算基于摄像机坐标的顶点颜色。因此需要告诉着色器下面的数据:世界的逆矩阵用于转换法线,剪裁矩阵用于转换坐标,对象的摄像机和世界坐标用于灯光的角度和灯光颜色。为了可以在每一帧中告诉着色器这些数据,我们必须继承自IShaderConstantSetCallBack 接口类并重载OnSetConstants()方法。这个方法会在每一次设置材质时调用。
IMateralRendererScrvices
接口类的setVertexShaderConstant()方法用于设置着色器需要的数据。如果在这个例子中用户选择使用高级着色器语言(High Level Shader LanguageHLSL)代替汇编语言,你必须设置变量名作为参数代替注册索引。

IrrlichtDevice* device = 0;
bool UseHighLevelShaders = false;

class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:

 


  virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
  {
    video::IVideoDriver* driver = services->getVideoDriver();

    // set inverted world matrix
    // if we are using highlevel shaders (the user can select this when
    // starting the program), we must set the constants by name.

    core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD);
    invWorld.makeInverse();

    if (UseHighLevelShaders)
       services->setVertexShaderConstant("mInvWorld", &invWorld.M[0], 16);
    else
       services->setVertexShaderConstant(&invWorld.M[0], 0, 4);

    // set clip matrix
    core::matrix4 worldViewProj;
    worldViewProj = driver->getTransform(video::ETS_PROJECTION);                           
    worldViewProj *= driver->getTransform(video::ETS_VIEW);
    worldViewProj *= driver->getTransform(video::ETS_WORLD);

    if (UseHighLevelShaders)
       services->setVertexShaderConstant("mWorldViewProj", &worldViewProj.M[0], 16);
    else
       services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4);
                   
    // set camera position
    core::vector3df pos = device->getSceneManager()->
    getActiveCamera()->getAbsolutePosition();

    if (UseHighLevelShaders)
      services->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&pos), 3);
    else
      services->setVertexShaderConstant(reinterpret_cast<f32*>(&pos), 8, 1);

    // set light color
    video::SColorf col(0.0f,1.0f,1.0f,0.0f);

    if (UseHighLevelShaders)
      services->setVertexShaderConstant("mLightColor", reinterpret_cast<f32*>(&col), 4);
    else
      services->setVertexShaderConstant(reinterpret_cast<f32*>(&col), 9, 1);

    // set transposed world matrix
    core::matrix4 world = driver->getTransform(video::ETS_WORLD);
    world = world.getTransposed();

    if (UseHighLevelShaders)
      services->setVertexShaderConstant("mTransWorld", &world.M[0], 16);
    else
      services->setVertexShaderConstant(&world.M[0], 10, 4);
          }
};

正如之前的教程那样,下面几行是引擎的启动。另外,如果显卡支持使用高级着色器就询问用户是否要在例子中使用。

int main()
{
          // let user select driver type

          video::E_DRIVER_TYPE driverType = video::EDT_DIRECTX9;

          printf("Please select the driver you want for this example:\n"\
                    " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
                    " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
                    " (f) NullDevice\n (otherKey) exit\n\n");

          char i;
          std::cin >> i;

          switch(i)
          {
                    case 'a': driverType = video::EDT_DIRECT3D9;break;
                    case 'b': driverType = video::EDT_DIRECT3D8;break;
                    case 'c': driverType = video::EDT_OPENGL;   break;
                    case 'd': driverType = video::EDT_SOFTWARE; break;
                    case 'e': driverType = video::EDT_SOFTWARE2;break;
                    case 'f': driverType = video::EDT_NULL;     break;
                    default: return 1;
          }        

  // ask the user if we should use high level shaders for this example
 
 if (driverType == video::EDT_DIRECT3D9 ||
                     driverType == video::EDT_OPENGL)

 

  {
      printf("Please press 'y' if you want to use high level shaders.\n");
      std::cin >> i;
      if (i == 'y')
         UseHighLevelShaders = true;
          }

          // create device

          device = createDevice(driverType, core::dimension2d<s32>(640, 480));

          if (device == 0)
          {
                    printf("\nWas not able to create driver.\n"\
                               "Please restart and select another driver.\n"
);
                    getch();
                    return 1;
          }        

          video::IVideoDriver* driver = device->getVideoDriver();
          scene::ISceneManager* smgr = device->getSceneManager();
          gui::IGUIEnvironment* gui = device->getGUIEnvironment();

现在是有趣的部份了。如果用Direct3D,需要加载顶点和像素着色器,如果用OpenGL,需要用ARB fragment和顶点程序(译注:不熟悉OpenGL,故ARB fragment不作翻译)。对应的程序写在以下的文件里d3d8.ps, d3d8.vs, d3d9.ps, d3d9.vs, opengl.psopengl.vs(译注:新版本的sdk都在文件的最后加上h,如d3d8.psh)。这个在下面的switch语句中实现了。注意,并不一定要像这个程序那样写着色器。你可以在cpp代码中直接把着色器写成字符串,然后用addShaderMaterial()代替addShaderMaterialFromFile()。

          c8* vsFileName = 0; // filename for the vertex shader
          c8* psFileName = 0; // filename for the pixel shader

          switch(driverType)
          {
          case video::EDT_DIRECT3D8:
                    psFileName = "../../media/d3d8.psh";
                    vsFileName = "../../media/d3d8.vsh";
                    break;
          case video::EDT_DIRECT3D9:
                    if (UseHighLevelShaders)
                    {
                               psFileName = "../../media/d3d9.hlsl";
                               vsFileName = psFileName; // both shaders are in the same file
                    }
                    else
                    {
                               psFileName = "../../media/d3d9.psh";
                               vsFileName = "../../media/d3d9.vsh";
                    }
                    break;
          case video::EDT_OPENGL:
                    if (UseHighLevelShaders)
                    {
                               psFileName = "../../media/opengl.frag";
                               vsFileName = "../../media/opengl.vert";
                    }
                    else
                    {
                               psFileName = "../../media/opengl.psh";
                               vsFileName = "../../media/opengl.vsh";
                    }
                    break;
          }

另外,还要检测选择的硬件和渲染器能否执行着色器。如果不能,则设置文件名为空。虽然不是必需的,但对这个例子十分有用:例如,如果硬件支持顶点着色器而不支持像素着色器,则只用顶点着色器而不用像素着色器创建一个新的材质。否则,如果引擎知道硬件不能完全支持要求使用的着色器,那么引擎根本不会创建任何材质。而根据上面所说的情况,这个例子起码会使用顶点着色器。

          if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
                    !driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
          {
                    device->getLogger()->log("WARNING: Pixel shaders disabled "\
                               "because of missing driver/hardware support.");
                    psFileName = 0;
          }
         
          if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
                    !driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
          {
                    device->getLogger()->log("WARNING: Vertex shaders disabled "\
                               "because of missing driver/hardware support.");
                    vsFileName = 0;
          }

现在,开始创建新的材质。
根据之前的例子你应该知道,在IrrLicht引擎中,通过修改SMaterial::MaterialType的值来设置材质类型。而这个值其实是32位值(译注:具体值可查看枚举E_MATERIAL_TYPE的定义),如可设为video::EMT_SOLID。所以我们创建一个变量然后设置值。为此,获取IGPUProgrammingServices接口类的指针并调用addShaderMaterialFromFiles()方法来返回一个32位值(译注:就是E_MATERIAL_TYPE枚举)。这样就可以了。
这个方法的参数说明如下:首先是顶点和像素着色器所在文件的文件名。
如果你要用addShaderMaterial()代替,不需要文件名,而用包含了着色器代码的字符串。接着的参数是之前定义的IShaderConstantSetCallBack接口类指针。如果不设置常量则把这个参数设0。最后一个参数是告诉引擎基于哪种材质创建。
为了证明这个,我们创建两个基于不同类型的材质,一个是EMT_SOLID另一个是EMT_TRANSPARENT_ADD_COLOR

          // create materials

          video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();

          s32 newMaterialType1 = 0;
          s32 newMaterialType2 = 0;

          if (gpu)
          {
                    MyShaderCallBack* mc = new MyShaderCallBack();
         

 

                    // create the shaders depending on if the user wanted high level
                    // or low level shaders:


                    if (UseHighLevelShaders)
                    {
                               // create material from high level shaders (hlsl or glsl)

                               newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
                                         vsFileName,         "vertexMain", video::EVST_VS_1_1,
                                         psFileName, "pixelMain", video::EPST_PS_1_1,
                                         mc, video::EMT_SOLID);

                               newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
                                         vsFileName,         "vertexMain", video::EVST_VS_1_1,
                                         psFileName, "pixelMain", video::EPST_PS_1_1,
                                         mc, video::EMT_TRANSPARENT_ADD_COLOR);
                    }
                    else
                    {
                               // create material from low level shaders (asm or arb_asm)

                               newMaterialType1 = gpu->addShaderMaterialFromFiles(vsFileName,
                                         psFileName, mc, video::EMT_SOLID);

                               newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName,
                                         psFileName, mc, video::EMT_TRANSPARENT_ADD_COLOR);
                    }

                    mc->drop();
          }

现在是测试这几个材质。我们创建一个用于测试的立方体并设置材质为上面创建的类型。另外,我们在立方体上添加一个文本场景节点和一个旋转动画器,使效果更好。

 

 

          // create test scene node 1, with the new created material type 1

 

 

 

          scene::ISceneNode* node = smgr->addCubeSceneNode(50);

 

          node->setPosition(core::vector3df(0,0,0));

 

          node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));

 

          node->setMaterialFlag(video::EMF_LIGHTING, false);

 

          node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1);

 

 

 

          smgr->addTextSceneNode(gui->getBuiltInFont(),

 

                               L"PS & VS & EMT_SOLID",

 

                               video::SColor(255,255,255,255),          node);

 

 

 

          scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator(

 

                               core::vector3df(0,0.3f,0));

 

          node->addAnimator(anim);

 

          anim->drop();

第二个立方体是相同的,不同的是坐标和把材质设置为另一个上面创建的类型。

          // create test scene node 2, with the new created material type 2

 

 

 

          node = smgr->addCubeSceneNode(50);

 

          node->setPosition(core::vector3df(0,-10,50));

 

          node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));

 

          node->setMaterialFlag(video::EMF_LIGHTING, false);

 

          node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2);

 

 

 

          smgr->addTextSceneNode(gui->getBuiltInFont(),

 

                               L"PS & VS & EMT_TRANSPARENT",

 

                               video::SColor(255,255,255,255),          node);

 

 

 

          anim = smgr->createRotationAnimator(core::vector3df(0,0.3f,0));

 

          node->addAnimator(anim);

 

          anim->drop();


第三个立方体并无用着色器,用于与上面创建的两个立方体比较。

          // add a scene node with no shader

 

 

 

          node = smgr->addCubeSceneNode(50);

 

          node->setPosition(core::vector3df(0,50,25));

 

          node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));

 

          node->setMaterialFlag(video::EMF_LIGHTING, false);

 

          smgr->addTextSceneNode(gui->getBuiltInFont(), L"NO SHADER",

 

                    video::SColor(255,255,255,255), node);

 

           


最后,我们在场景中添加一个天空盒和一个可用户控制的摄像机。取消了天空盒纹理的mipmap功能,因为在这里不需要。

          // add a nice skybox

          driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

          smgr->addSkyBoxSceneNode(
                    driver->getTexture("../../media/irrlicht2_up.jpg"),
                    driver->getTexture("../../media/irrlicht2_dn.jpg"),
                    driver->getTexture("../../media/irrlicht2_lf.jpg"),
                    driver->getTexture("../../media/irrlicht2_rt.jpg"),
                    driver->getTexture("../../media/irrlicht2_ft.jpg"),
                    driver->getTexture("../../media/irrlicht2_bk.jpg"));

          driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

          // add a camera and disable the mouse cursor

          scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
          cam->setPosition(core::vector3df(-100,50,100));
          cam->setTarget(core::vector3df(0,0,0));
          device->getCursorControl()->setVisible(false);


现在要绘制每一个物体。

          int lastFPS = -1;

          while(device->run())
                    if (device->isWindowActive())
          {
                    driver->beginScene(true, true, video::SColor(255,0,0,0));
                    smgr->drawAll();
                    driver->endScene();

                    int fps = driver->getFPS();

                    if (lastFPS != fps)
                    {
                      core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example [";
                      str += driver->getName();
                      str += "] FPS:";
                      str += fps;
                      device->setWindowCaption(str.c_str());
                      lastFPS = fps;
                    }
          }

          device->drop();
         
          return 0;


编译并运行这些代码,我希望你感到愉快:)

 

Shader Files

这些包含着色器代码的文件可以在sdkmedia文件夹中找到。具体内容如下:

D3D9.HLSL

 

// part of the Irrlicht Engine Shader example.

 

// These simple Direct3D9 pixel and vertex shaders
// will be loaded by the shaders

 

// example. Please note that these example shaders don't do
// anything really useful.

 

// They only demonstrate that shaders can be used in Irrlicht.

 

 

 

//-----------------------------------------------------------------------------

 

// Global variables

 

//-----------------------------------------------------------------------------

 

float4x4 mWorldViewProj;  // World * View * Projection transformation

 

float4x4 mInvWorld;       // Inverted world matrix

 

float4x4 mTransWorld;     // Transposed world matrix

 

float3 mLightPos;         // Light position

 

float4 mLightColor;       // Light color

 

 

 

 

 

// Vertex shader output structure

 

struct VS_OUTPUT

 

{

 

          float4 Position   : POSITION;   // vertex position

 

          float4 Diffuse    : COLOR0;     // vertex diffuse color

 

          float2 TexCoord   : TEXCOORD0;  // tex coords

 

};

 

 

 

 

 

VS_OUTPUT vertexMain( in float4 vPosition : POSITION,

 

                      in float3 vNormal   : NORMAL,

 

                      float2 texCoord     : TEXCOORD0 )

 

{

 

          VS_OUTPUT Output;

 

 

 

          // transform position to clip space

 

          Output.Position = mul(vPosition, mWorldViewProj);

 

         

 

          // transform normal

 

          float3 normal = mul(vNormal, mInvWorld);

 

         

 

          // renormalize normal

 

          normal = normalize(normal);

 

         

 

          // position in world coodinates

 

          float3 worldpos = mul(mTransWorld, vPosition);

 

         

 

          // calculate light vector, vtxpos - lightpos

 

          float3 lightVector = worldpos - mLightPos;

 

         

 

          // normalize light vector

 

          lightVector = normalize(lightVector);

 

         

 

          // calculate light color

 

          float3 tmp = dot(-lightVector, normal);

 

          tmp = lit(tmp.x, tmp.y, 1.0);

 

         

 

          tmp = mLightColor * tmp.y;

 

          Output.Diffuse = float4(tmp.x, tmp.y, tmp.z, 0);

 

          Output.TexCoord = texCoord;

 

         

 

          return Output;

 

}

 

 

 

 

 

 

 

// Pixel shader output structure

 

struct PS_OUTPUT

 

{

 

    float4 RGBColor : COLOR0;  // Pixel color   

 

};

 

 

 

 

 

sampler2D tex0;

 

         

 

PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0,

 

                     float4 Position : POSITION,

 

                     float4 Diffuse  : COLOR0 )

 

{

 

          PS_OUTPUT Output;

 

 

 

          float4 col = tex2D( tex0, TexCoord );  // sample color map

 

         

 

          // multiply with diffuse and do other senseless operations

 

          Output.RGBColor = Diffuse * col;

 

          Output.RGBColor *= 4.0;

 

 

 

          return Output;

 

}

 

D3D9.VSH

 

; part of the Irrlicht Engine Shader example.

 

; This Direct3D9 vertex shader will be loaded by the engine.

 

; Please note that these example shaders don't do anything really useful.

 

; They only demonstrate that shaders can be used in Irrlicht.

 

vs.1.1

 

 

 

dcl_position v0;    ; declare position

 

dcl_normal v1;      ; declare normal

 

dcl_color v2;       ; declare color

 

dcl_texcoord0 v3;   ; declare texture coordinate

 

; transpose and transform position to clip space

 

mul r0, v0.x, c4     

 

mad r0, v0.y, c5, r0  

 

mad r0, v0.z, c6, r0  

 

add oPos, c7, r0      

 

 

 

; transform normal

 

dp3 r1.x, v1, c0 

 

dp3 r1.y, v1, c1 

 

dp3 r1.z, v1, c2 

 

 

 

; renormalize normal

 

dp3 r1.w, r1, r1 

 

rsq r1.w, r1.w   

 

mul r1, r1, r1.w 

 

 

 

; calculate light vector

 

m4x4 r6, v0, c10      ; vertex into world position

 

add r2, c8, -r6       ; vtxpos - lightpos

 

 

 

; normalize light vector

 

dp3 r2.w, r2, r2 

 

rsq r2.w, r2.w   

 

mul r2, r2, r2.w 

 

 

 

; calculate light color

 

dp3 r3, r1, r2       ; dp3 with negative light vector

 

lit r5, r3           ; clamp to zero if r3 < 0, r5 has diffuce component in r5.y

 

mul oD0, r5.y, c9    ; ouput diffuse color

 

mov oT0, v3          ; store texture coordinates    

 

D3D9.PSH

 

; part of the Irrlicht Engine Shader example.

 

; This simple Direct3D9 pixel shader will be loaded by the engine.

 

; Please note that these example shaders don't do anything really useful.

 

; They only demonstrate that shaders can be used in Irrlicht.

 

ps.1.1

 

 

 

tex t0          ; sample color map

 

add r0, v0, v0  ; mulitply with color

 

mul t0, t0, r0  ; mulitply with color

 

add r0, t0, t0  ; make it brighter and store result             

 

             

 

D3D8.VSH

 

; part of the Irrlicht Engine Shader example.

 

; This Direct3D9 vertex shader will be loaded by the engine.

 

; Please note that these example shaders don't do anything really useful.

 

; They only demonstrate that shaders can be used in Irrlicht.

 

vs.1.1

 

 

 

; transpose and transform position to clip space

 

mul r0, v0.x, c4     

 

mad r0, v0.y, c5, r0  

 

mad r0, v0.z, c6, r0  

 

add oPos, c7, r0      

 

 

 

; transform normal

 

dp3 r1.x, v1, c0 

 

dp3 r1.y, v1, c1 

 

dp3 r1.z, v1, c2 

 

 

 

; renormalize normal

 

dp3 r1.w, r1, r1 

 

rsq r1.w, r1.w   

 

mul r1, r1, r1.w 

 

 

 

; calculate light vector

 

m4x4 r6, v0, c10      ; vertex into world position

 

add r2, c8, -r6       ; vtxpos - lightpos

 

 

 

; normalize light vector

 

dp3 r2.w, r2, r2 

 

rsq r2.w, r2.w   

 

mul r2, r2, r2.w 

 

 

 

; calculate light color

 

dp3 r3, r1, r2       ; dp3 with negative light vector

 

lit r5, r3           ; clamp to zero if r3 < 0, r5 has diffuce component in r5.y

 

mul oD0, r5.y, c9    ; ouput diffuse color

 

mov oT0, v3          ; store texture coordinates            

 

D3D8.PSH

 

; part of the Irrlicht Engine Shader example.

 

; This simple Direct3D9 pixel shader will be loaded by the engine.

 

; Please note that these example shaders don't do anything really useful.

 

; They only demonstrate that shaders can be used in Irrlicht.

 

ps.1.1

 

 

 

tex t0             ; sample color map

 

mul_x2 t0, t0, v0  ; mulitply with color

 

add r0, t0, t0     ; make it brighter and store result     

 

OPENGL.VSH

 

!!ARBvp1.0

 

# part of the Irrlicht Engine Shader example.

 

# Please note that these example shaders don't do anything really useful.

 

# They only demonstrate that shaders can be used in Irrlicht.

 

#input

 

ATTRIB InPos = vertex.position;

 

ATTRIB InColor = vertex.color;

 

ATTRIB InNormal = vertex.normal;

 

ATTRIB InTexCoord = vertex.texcoord;

 

 

 

#output

 

OUTPUT OutPos = result.position;

 

OUTPUT OutColor = result.color;

 

OUTPUT OutTexCoord = result.texcoord;

 

 

 

PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix.

 

TEMP Temp;

 

TEMP TempColor;

 

TEMP TempNormal;

 

TEMP TempPos;

 

 

 

#transform position to clip space

 

DP4 Temp.x, MVP[0], InPos;

 

DP4 Temp.y, MVP[1], InPos;

 

DP4 Temp.z, MVP[2], InPos;

 

DP4 Temp.w, MVP[3], InPos;

 

 

 

#transform normal

 

DP3 TempNormal.x, InNormal.x, program.local[0];

 

DP3 TempNormal.y, InNormal.y, program.local[1];

 

DP3 TempNormal.z, InNormal.z, program.local[2];

 

 

 

#renormalize normal

 

DP3 TempNormal.w, TempNormal, TempNormal; 

 

RSQ TempNormal.w, TempNormal.w;   

 

MUL TempNormal, TempNormal, TempNormal.w;

 

 

 

# calculate light vector

 

DP4 TempPos.x, InPos, program.local[10];   # vertex into world position

 

DP4 TempPos.y, InPos, program.local[11];

 

DP4 TempPos.z, InPos, program.local[12];

 

DP4 TempPos.w, InPos, program.local[13];

 

 

 

ADD TempPos, program.local[8], -TempPos;    # vtxpos - lightpos

 

 

 

# normalize light vector

 

DP3 TempPos.w, TempPos, TempPos; 

 

RSQ TempPos.w, TempPos.w;   

 

MUL TempPos, TempPos, TempPos.w;

 

 

 

# calculate light color

 

DP3 TempColor, TempNormal, TempPos;    # dp3 with negative light vector

 

LIT OutColor, TempColor;  # clamp to zero if r3 < 0

 

MUL OutColor, TempColor.y, program.local[9]; # ouput diffuse color

 

MOV OutColor.w, 1.0;          # we want alpha to be always 1

 

MOV OutTexCoord, InTexCoord; # store texture coordinate

 

MOV OutPos, Temp;

 

 

 

END

 

OPENGL.PSH

 

!!ARBfp1.0

 

# part of the Irrlicht Engine Shader example.

 

# Please note that these example shaders don't do anything really useful.

 

# They only demonstrate that shaders can be used in Irrlicht.

 

#Input

 

ATTRIB inTexCoord = fragment.texcoord;      # texture coordinates

 

ATTRIB inColor = fragment.color.primary; # interpolated diffuse color

 

 

 

#Output

 

OUTPUT outColor = result.color;

 

 

 

TEMP texelColor;

 

TEMP tmp;

 

TXP texelColor, inTexCoord, texture, 2D;

 

 

 

ADD tmp, inColor, inColor; # mulitply with color

 

MUL texelColor, texelColor, tmp;  # mulitply with color  

 

ADD outColor, texelColor, texelColor;  # make it brighter and store result

 

 

 

END         

 

 

posted on 2008-07-04 11:18 shjy 阅读(825) 评论(1)  编辑 收藏 引用

Feedback

# re: Tutorial 10: Shaders 2011-06-15 14:26 guafeng

很好的翻译,支持一把。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理