Thinking in Shader(3)

Thinking in Shader(3)

分类: 图形学 Cg 463人阅读 评论(1) 收藏 举报
开发环境

Window7

CgToolkit

 

        羽化的第十九篇博客,隔了一个星期才出现,也许就是所谓惰性吧,工作开始忙起来了,所以可能有时候不能达到一星期一篇的目标了,但研究还在继续,因为羽化是个不喜欢半途而废的人,首先是听说的弟弟要去参军了,真是一个好消息,对于他来说进入军队也是个很好的锻炼,回想小时候弟弟妹妹围着两个哥哥打转的日子已经一去不复返了,我们都在慢慢长大,价值观和人生观在慢慢出现了很大的差异,联系也越来越少,也许现在羽化不是一个称职的兄长,在弟弟妹妹面对人生的艰难时刻没有站出来鼓励他们,也没给予作为哥哥应有的可靠和关爱才会导致他们慢慢荒废了学业,但羽化知道,他们都是善良的人,这是最好的,也是用什么都无法换来的,希望他们弟弟妹妹们能在未来的路上走得开心,顺利~ ~ 最近闲来和飞噶去上海动物园一趟,里面动物如人各种众生相,总的来说,其实我们所处的社会就是一个巨大动物园,都谈不上真正的自由。。。话说今天帮飞噶女朋友搬家,在普陀附近居然半天找不到吃的地方。。。

        好吧~ ~继续开始Cg的学习。

   

 

 

绑定语义

       这里是个顶点数据绑定的语义的例子

 

  1. struct myinputs {  
  2. float3 myPosition : POSITION;  
  3. float3 myNormal : NORMAL;  
  4. float3 myTangent : TANGENT;  
  5. float refractive_index : TEXCOORD3;  
  6. };  
  7. outdata foo(myinputs indata)  
  8. {  
  9. /* ... */  
  10. // Within the program, the parameters are referred to as   
  11. // “indata.myPosition”, “indata.myNormal”, and so on.   
  12. /* ... */  
  13. }  
  14.   
  15. /*还可以写成*/  
  16. outdata foo(float3 myPosition : POSITION,  
  17. float3 myNormal : NORMAL,  
  18. float3 myTangent : TANGENT,  
  19. float refractive_index : TEXCOORD3) {  
  20. /* ... */  
  21. // Within the program, the parameters are referred to by   
  22. // their variable names: “myPosition”, “myNormal”,   
  23. // “myTangent”, and “refractive_index”.   
  24. /* ... */  
  25. }  
struct myinputs {
float3 myPosition : POSITION;
float3 myNormal : NORMAL;
float3 myTangent : TANGENT;
float refractive_index : TEXCOORD3;
};
outdata foo(myinputs indata)
{
/* ... */
// Within the program, the parameters are referred to as
// “indata.myPosition”, “indata.myNormal”, and so on.
/* ... */
}

/*还可以写成*/
outdata foo(float3 myPosition : POSITION,
float3 myNormal : NORMAL,
float3 myTangent : TANGENT,
float refractive_index : TEXCOORD3) {
/* ... */
// Within the program, the parameters are referred to by
// their variable names: “myPosition”, “myNormal”,
// “myTangent”, and “refractive_index”.
/* ... */
}

 

绑定语义的概念和普通语言中基本类似,Cg中提供的几种语义有:

POSITION

BLENDWEIGHT

NORMAL

TANGENT

BINORMAL

PSIZE

BLENDINDICES

TEXCOORD0—TEXCOORD7

COLOR0–COLOR1

 

 

Varying Outputs和顶点程序的来往

         顶点程序输出通过光栅和可用的Varying Outputs片段程序,作为顶点和片段程序的交互,他们必须保证数据能在彼此间传输通过,作为应用与顶点程序传输的数据流,Cg使用绑定语义指明了顶点程序与片段程序。

         下面的程序是对应顶点输出:

  1. // Vertex program   
  2. struct myvf  
  3. {  
  4.     float4 pout : POSITION; // Used for rasterization   
  5.     float4 diffusecolor : COLOR0;  
  6.     float4 uv0 : TEXCOORD0;  
  7.     float4 uv1 : TEXCOORD1;  
  8. };  
  9. myvf foo(/* ... */)  
  10. {  
  11.     myvf outstuff;  
  12. /* ... */  
  13.     return outstuff;  
  14. }  
// Vertex program
struct myvf
{
	float4 pout : POSITION; // Used for rasterization
	float4 diffusecolor : COLOR0;
	float4 uv0 : TEXCOORD0;
	float4 uv1 : TEXCOORD1;
};
myvf foo(/* ... */)
{
	myvf outstuff;
/* ... */
	return outstuff;
}

         再者,下面的是另一个例子展示如何应用相同数据作为片段程序输入:

  1. // Fragment program   
  2. struct myvf  
  3. {  
  4.     float4 diffusecolor : COLOR0;  
  5.     float4 uv0 : TEXCOORD0;  
  6.     float4 uv1 : TEXCOORD1;  
  7. };  
  8. fragout bar(myvf indata)  
  9. {  
  10.     float4 x = indata.uv0;  
  11. /* ... */  
  12. }  
// Fragment program
struct myvf
{
	float4 diffusecolor : COLOR0;
	float4 uv0 : TEXCOORD0;
	float4 uv1 : TEXCOORD1;
};
fragout bar(myvf indata)
{
	float4 x = indata.uv0;
/* ... */
}

         所有顶点程序必须声明和设置一个顶点输出通过POSITOIN,这个值是光栅需要的。

         为了确保顶点程序和片段程序的互通,双方必须使用相同的结构对应各自的输入和输出,如下面的程序:

 

  1. struct myvert2frag  
  2. {  
  3.     float4 pos : POSITION;  
  4.     float4 uv0 : TEXCOORD0;  
  5.     float4 uv1 : TEXCOORD1;  
  6. };  
  7. // Vertex program   
  8. myvert2frag vertmain(...)   
  9. {  
  10.     myvert2frag outdata;  
  11. /* ... */  
  12.     return outdata;  
  13. }  
  14. // Fragment program   
  15. void fragmain(myvert2frag indata )   
  16. {  
  17.     float4 tcoord = indata.uv0;  
  18. /* ... */  
  19. }  
struct myvert2frag
{
	float4 pos : POSITION;
	float4 uv0 : TEXCOORD0;
	float4 uv1 : TEXCOORD1;
};
// Vertex program
myvert2frag vertmain(...) 
{
	myvert2frag outdata;
/* ... */
	return outdata;
}
// Fragment program
void fragmain(myvert2frag indata ) 
{
	float4 tcoord = indata.uv0;
/* ... */
}

 

         注意:一些顶点输出的语义是针对光栅,这些值实际上不能用在片段程序,即使他们出现在输入的结构中,例如indata.pos值是连接POSITION片段语义却不能在fragmain的shader中识别出来。

 

 

Arrays数组

         这里说说Cg中的数组,因为Cg不支持指针,所以用数组的情况很多。其实用法都类似,在书中有个地方羽化觉得比较诡异,就是Unsized Arrays,原来是一个很简单的调用,而官方貌似把这个当成一种特性,貌似这只是种技巧。。。具体实例如下:

  1. float myfunc(float vals[])   
  2. {  
  3.     float sum = 0;  
  4.     for (int i = 0; i < vals.length; i++)   
  5.     {  
  6.         sum += vals[i];  
  7.     }  
  8.     return sum;  
  9. }  
  10. float4 main(...)  
  11. {  
  12.     float vals1[2];  
  13.     float vals2[76];  
  14.     ...  
  15.     float myval1 = myfunc(vals1); // match   
  16.     float myval2 = myfunc(vals2); // match   
  17.     ...  
  18. }  
float myfunc(float vals[]) 
{
	float sum = 0;
	for (int i = 0; i < vals.length; i++) 
	{
		sum += vals[i];
	}
	return sum;
}
float4 main(...)
{
	float vals1[2];
	float vals2[76];
	...
	float myval1 = myfunc(vals1); // match
	float myval2 = myfunc(vals2); // match
	...
}

运算符

         Cg支持普通的运算符(+,-,*,/)同样支持矢量运算,例如:

         float3(a, b, c) * float3(A, B, C) equals float3(a*A,b*B, c*C)

         a * float3(A, B, C) is equal to float3(a*A, a*B, a*C)

 

 

Advanced Fragment Profiles先进的片段配置   

        Cg提供了先进的片段配置方便纹理的查找,通常情况下需要两个参数:

        Texturesampler纹理采样器---通常类型为sampler, sampler1D,sampler2D,sampler3D, samplerCUBE, samplerRECT和通过a filter,clamp, wrap,similar configuration结合一张纹理图片,注意不能直接用在Cg语言中,通常是通过应用作为统一参数提供个程序。

        Texturecoordinate纹理坐标---根据纹理的类型来查找,通常这个坐标可能是scalar,a two‐vector, athree‐vector, or a four‐vector.

         下面是一个使用tex2D()功能来执行纹理查找确定这个片段的RGBA颜色的例子:

  1. void applytex(uniform sampler2D mytexture,   
  2.                 float2 uv : TEXCOORD0,  
  3.                 out float4 outcolor : COLOR)   
  4. {  
  5.     outcolor = tex2D(mytexture, uv);  
  6. }  
void applytex(uniform sampler2D mytexture, 
				float2 uv : TEXCOORD0,
				out float4 outcolor : COLOR) 
{
	outcolor = tex2D(mytexture, uv);
}
         Cg提供了一个多样性的纹理查找功能,具体可以翻手册。

 

CgFX

         CgFX是一种强大的通用的着色器规范和交换格式。对于实时图像艺术家和开发者来说,这种格式提供了几个好处:

1.封装多种渲染技术,提供细节层、功能、性能的回调。

2.支持Cg、汇编和固定功能Shader

3.可编辑参数和嵌入式GUI

4.多通道Shader

5.渲染状态和纹理状态规范

     羽化个人认为CgFX就像一个IDE和SDK的结合-0-

 

 

Techniques方法和Passes传递

         CgFX文件包含一个或者多个方法,这些方法通过GPU硬件判断提供适应,同样可以用于提供细节层、功能、性能的回调。例如:

  1. technique PixelShaderVersion  
  2. {…};  
  3. technique FixedFunctionVersion  
  4. {…};  
  5. technique LowDetailVersion  
  6. {…};  
technique PixelShaderVersion
{…};
technique FixedFunctionVersion
{…};
technique LowDetailVersion
{…};

         一个方法都包含一个或者多个传递,每一个传递代表一套渲染状态和Shaders来申请一次单一的渲染通过。

 

 

下期预告:

Thinking in Shader(4)




posted @ 2013-03-23 18:16  小薇林  阅读(201)  评论(0编辑  收藏  举报