Shader学习心得

来源:互联网 发布:js defer promise 编辑:程序博客网 时间:2024/05/02 01:50

  以下的教程由乌龟和毛驴的技术小屋原创,转载请注明原始文章出处,并保留这段话,请勿侵权.

  1.1 序言

  以前一直觉得,学习shader最好是在Visual Studio的环境下进行学习,因为这样不仅能够学到DirectX和C++的一些使用方法,而且对于Shader在实际应用时也有好处.结果今天就碰得灰头土脸的.

  1.2 碰壁过程

  下面是我的程序段:


     ID3DXEffect* g_pEffect = NULL;
  3DXCreateEffectFromFile( g_pd3dDevice, "simple.fx", NULL, NULL, dwShaderFlags, NULL, &g_pEffect, NULL );

  下面是我的.fx程序:


      float4x4 WorldViewProj : WorldViewProjection;
  float4 mainVS(float3 pos : POSITION) : POSITION{
  return mul(float4(pos.xyz, 1.0), WorldViewProj);
  }
  float4 mainPS() : COLOR {
  return float4(1.0, 1.0, 1.0, 1.0);
  }
  technique technique0 {
  pass p0 {
  CullMode = None;
  VertexShader = compile vs_1_1 mainVS();
  PixelShader = compile ps_1_1 mainPS();
  }
  }

  编译的时候没有提示错误,也可以运行.但是在运行中出错,没有出错的信息.

  对于几乎没有在VS C++环境下编程的我来说.这是非常抓狂的事情.在网上找了下代码,把我的程序改了一下,可以看到错误信息了.下面是修改后的程序段


    ID3DXBuffer* error_buffer;
  hr = D3DXCreateEffectFromFile( g_pd3dDevice, "simple.fx", NULL, NULL, dwShaderFlags, NULL, &g_pEffect, &error_buffer );
  if(error_buffer)
  {
  MessageBox(NULL, (char *) (error_buffer->GetBuffERPointer()), "ERROR", MB_OK);
  error_buffer->Release();
  }
  if(FAILED(hr))
  {
  MessageBox(NULL, "D3DXCreateEffectFromFile() - FAILED", "ERROR", MB_OK);
  return false;
  }

   下面是出错的信息:

  

  图片看不清楚?请点击这里查看原图(大图)。

  大概是说现在PS_1_X的版本不被支持了.于是乎,我想到,如果还有一些其他的疑难杂症,如果我想调试shader,如果我想很快的能够在修改shader后,把matieral赋值,如果我想方便的建立View和Projection矩阵.那VS显然是不能胜任的.

  花了点时间找了找.使用NVIDIA的 FX Composer 2.5是一个很好的选择.它支持D3D10,而且有一个类似于3D MAX的窗口,可以拖动物体,这样也不用很麻烦的去建立View和Projection矩阵.操作也很方便,比ATI的那个工具感觉还好一点.用来学习Shader是很不错的选择(广告啊)

  在NVIDIA的网站上可以方便的下到它

  http://developer.download.nvidia.com/tools/Shader_Debugger/FX_Composer2_Shader_Debugger_Bundle_2.51.0827.1525.exe

  安装时注意要选择No commercial,这样就不会被要求输入序列号了.

  1.3 建立我们的第一个Shader

  选择File-New Project:

  Step 1: 选择 ,当你选择其他的东西茶壶什么的也可以.也可以选择其他的.x文件,这样在右下角就可以看到一个白色的小球了

  Step 2: 选择 ,选择HLSL FX.选择下一步,然后选择Empty,选择finish.这样左上角的Materials框里面就有一个白圆了.

  Step 3: 把白圆拖动到右下角的球上,把特效和物体关联,这个特效文件的运行效果如下:

  

  是不是感觉到非常的”所见即所得”?

  如果你想看看这个shader文件,在白圆上面按右键,选择edit,显示出的就是.fx文件的源程序,把这个程序复制到vs里面,进行了相关了初始化和设置参数操作后,也可以正常了使用了.

  Fx Composer 2.5的其他情况你也可以自己看看安装后的帮助文件,我这里就不说太多了(其实我也是今天才开始用的,以后有了心得再慢慢写出来 :-D)今后的重点主要放在shader的编写上.

  2.1 为我们的shader增加贴图

   Step 1:  在我们的Empty Effect中:

  float4x4 WorldViewProj : WorldViewProjection;

  下面一行按右键,选择”Insert Snippets”

  在右边的框中选择”Texture and Sampler”

  在打了一个框的Name上面双击,修改为diffuse,这样所有的”Name”就自动变为了”diffuse”了

   Step 2: 添加程序段,使得代码变为

float4x4 WorldViewProj : WorldViewProjection;

 

texture diffuse <

      string ResourceName = "";//Optional default file name

      string UIName = "diffuse Texture";

      string ResourceType = "2D";

      >;

 

sampler2D diffuseSampler = sampler_state {

      Texture = <diffuse>;

      MinFilter = Linear;

      MagFilter = Linear;

      MipFilter = Linear;

      AddressU = Wrap;

      AddressV = Wrap;

      };

    

struct VS_OUTPUT

{

     float4 pos : POSITION;

     float2 tex : TEXCOORD0;

};

 

VS_OUTPUT mainVS(float4 pos : POSITION,float2 tex : TEXCOORD0){

     VS_OUTPUT vsOut;

     vsOut.pos = mul(pos,WorldViewProj);

     vsOut.tex = tex;

     return vsOut;

}

 

float4 mainPS(float2 tex : TEXCOORD0) : COLOR {

     return tex2D(diffuseSampler, tex);

}

 

technique technique0 {

     pass p0 {

              VertexShader = compile vs_3_0 mainVS();

              PixelShader = compile ps_3_0 mainPS();

     }

}

  Step 2:选择我们的Empty Effect文件,在右上方的Property 表格的 Parameter中的”diffuse Texture”选项中选择一个你喜欢的贴图文件.

   Step 3:按下Ctrl + F7,编译Shader,然后把这个Shader拖动到我们需要显示的物体上面

  2.2 解释代码的含义

texture diffuse <

      string ResourceName = "";//Optional default file name

      string UIName = "diffuse Texture";

      string ResourceType = "2D";

      >;

  可能很多人对代码中 < … > 中的内容感觉到很茫然,其实这些内容对我们DirectX中使用来说用处不大,主要作用是使得FX Composer可以识别出我们的参数,并且在参数面板中显示,方便我们修改

return tex2D(diffuseSampler, tex);

  根据diffuseSample取样器,对tex所对应的贴图坐标进行插值运算,如果你对这块代码理解不清楚,请自己找本HLSL相关的书籍看看.第一章开头的引用数目或许对你有帮助

  2.3 运行效果

Shader学习心得(2):FX的功能之Insert Snippets,以及贴图的shader实现