1.3 Debugging of Shaders (调试着色器)

来源:互联网 发布:软件融合器 编辑:程序博客网 时间:2024/05/29 15:44

说实话这一章真没怎么看懂,不过先写出来吧,理解多少是多少,不对的地方欢迎大虾们批评指正。

本章主要讲述了如何对unity中的shander进行调试。其调试技术据说是个很久远的技术@_^这里举了一个如何生成假色图(false-color  images)的例子,通过改变片段着色器fragment   shader中color属性的输入参数值(即RGB某一基色的亮度)来得到着色器shader的输出数值。

上一章讲了如何将顶点着色器vertex  shader结构体中的输出参量作为片段着色器fragment   shader的输入参量,得到shader的过程。那么vertex  shader的数据是如何得到的呢?在unity中,游戏对象的网格渲染器Mesh   Renderer组件会通过OpenGL接口实时传回每一帧游戏对象的网格数据。这个过程我们通常称之为“draw   call”。这里传回的数据通常包含一个三角形列表,列表中定义了每个三角形3个顶点的属性和位置信息。顶点中的这些属性值就为vertex的输入参量。在unity中这些参量也叫做内嵌vertex输入参量。通常包括:位置信息position,曲面法线surface   normal,2组纹理坐标texture   coordinates,切向量tangent   vector和顶点颜色vertex   color的名字、数据类型和语义。这些input  vertex   parameters属性是以独立的结构体呈现的。例如:

struct   vertexInput {

         float4 vertex : POSITION; // position(in object coordinates,

            // i.e. local or model coordinates)

         float4 tangent : TANGENT; 

            // vector orthogonal to the surfacenormal

         float3 normal : NORMAL; // surfacenormal vector (in object

            // coordinates; usually normalizedto unit length)

         float4 texcoord : TEXCOORD0;  // 0th set of texture

            // coordinates (a.k.a. “UV”;between 0 and 1)

         float4 texcoord1 : TEXCOORD1; // 1stset of texture

            // coordinates  (a.k.a. “UV”; between 0 and 1)

         fixed4 color : COLOR; // color (usuallyconstant)

      };

 

这个结构体的使用方法如下:

 

Shader"Cg shader with all built-in vertex input parameters" {

   SubShader {

      Pass {

         CGPROGRAM

 

         #pragma vertex vert 

         #pragma fragment frag

 

         struct vertexInput {

            float4 vertex : POSITION;

            float4 tangent : TANGENT; 

            float3 normal : NORMAL;

            float4 texcoord : TEXCOORD0; 

            float4 texcoord1 : TEXCOORD1;

            fixed4 color : COLOR;

         };

         struct vertexOutput {

            float4 pos : SV_POSITION;

            float4 col : TEXCOORD0;

         };

 

         vertexOutput vert(vertexInput input)

         {

            vertexOutput output;

 

            output.pos =  mul(UNITY_MATRIX_MVP, input.vertex);

            output.col = input.texcoord; // setthe output color

            // other possibilities to playwith:

            // output.col = input.vertex;

            // output.col = input.tangent;

            // output.col =float4(input.normal, 1.0);

            // output.col = input.texcoord;

            // output.col = input.texcoord1;

            // output.col = input.color;

            return output;

         }

 

         float4 frag(vertexOutput input) : COLOR

         {

            return input.col;

         }

 

         ENDCG 

      }

   }

}

 

在输入结构体预定义中,已经定义了appdata_base,appdata_tan, appdata_full三个常用类型,在文件UnityCG.cginc中保存。在使用过程中用include加载UnityCG.cginc文件即可使用。

structappdata_base {

      float4 vertex : POSITION;

      float3 normal : NORMAL;

      float4 texcoord : TEXCOORD0;

   };

   struct appdata_tan {

      float4 vertex : POSITION;

      float4 tangent : TANGENT;

      float3 normal : NORMAL;

      float4 texcoord : TEXCOORD0;

   };

   struct appdata_full {

      float4 vertex : POSITION;

      float4 tangent : TANGENT;

      float3 normal : NORMAL;

      float4 texcoord : TEXCOORD0;

      float4 texcoord1 : TEXCOORD1;

      fixed4 color : COLOR;

      // and additional texture coordinatesonly on XBOX360)

   };

 

前面的程序可重写为:

Shader"Cg shader with all built-in vertex input parameters" {

   SubShader {

      Pass {

         CGPROGRAM

 

         #pragma vertex vert 

         #pragma fragment frag

         #include "UnityCG.cginc"

 

         struct vertexOutput {

            float4 pos : SV_POSITION;

            float4 col : TEXCOORD0;

         };

 

         vertexOutput vert(appdata_full input)

         {

            vertexOutput output;

 

            output.pos =  mul(UNITY_MATRIX_MVP, input.vertex);

            output.col = input.texcoord;

            return output;

         }

 

         float4 frag(vertexOutput input) :COLOR

         {

            return input.col;

         }

 

         ENDCG 

      }

   }

}

 

 

如何演示假色图false-color  images呢?

如果将vertex输入参数使用纹理坐标(二维(x,y))texcoord的x轴取值来代表fragment color的红色组件值,则不论输出颜色是纯红色、黄色、洋红色所有情况取值red组件的值都是1,另外不论输出颜色是蓝色、绿色还是浅蓝色所有情况取值,此时的red组件的值都是0. 例如:

output.col= float4(input.texcoord.x, 0.0, 0.0, 1.0);

//float4(red,green,blue,alpha)此处透明度alpha的取值为1.0,在此处它的

//取值是不会对shader产生影响的.

 

这里设置red组件为纹理x轴坐标,设置绿色组件和蓝色组件都为0.此时的shader如图所示:

        

一个类似表面有经度的球。一个从0度到180度,由0(没有颜色——黑色)到1(纯红色)的渐变的球,而后又从180度到360度从新开始。

 

既然x坐标形成一个类似于经度的球,那么y坐标就会形成一个类似于纬度的球。此处因为纹理坐标取值范围为0到1,作用于坐标上0值为底部(南极),1为顶部(北极)。

output.col= float4(input.texcoord.y ,0.0, 0.0, 1.0);

生成地shader效果如图所示:

      

    

 

法向量normalized  vectors的取值范围是-1到+1之间。为让每一个color组件取值范围都在(0,1)之间,就将每一个组件都增加1,然后整体除以2,如下所示:

output.col= float4( (input.normal + float3(1.0, 1.0, 1.0)) / 2.0, 1.0);


   

 

 

这里法线向量是一个三维向量(x,y,z),它中黑色即没有颜色坐标轴取值为-1,亮度最大即各组件为纯RGB,坐标取值为+1.

output.col= float4(input.normal, 1.0);


    

 

      

 

调试练习

output.col = input.texcoord -float4(1.5, 2.3, 1.1, 0.0);

 output.col = float4(input.texcoord.z);

 output.col = input.texcoord / tan(0.0);

这几种情况都是黑色的shader即没有颜色,因为此时RGB三个组件的的值都为0。

 

下面的内容没怎么看懂,有兴趣的自己试着做做吧。  大笑

The following lines require someknowledge about the dot and cross product:

            output.col = dot(input.normal,float3(input.tangent)) *

               input.texcoord;

            output.col =dot(cross(input.normal, float3(input.tangent)),

               input.normal) * input.texcoord;

            output.col =float4(cross(input.normal, input.normal), 1.0);

 

output.col = float4(cross(input.normal,

               float3(input.vertex)), 1.0);

               // only for a sphere!

Does the function radians() alwaysreturn black? What's that good for?

            output.col =radians(input.texcoord);

0 0