翻译 Cg Program in Unity - 1.3 Debug (一)

来源:互联网 发布:java for循环嵌套 编辑:程序博客网 时间:2024/06/06 03:22

本章我们来讨论一下vertex input parameters. 它是基于上一章的内容滴!

这个教程我们介绍一下一个在Unity调试Shader的主要技术: false-color image. 也就 通过将fragment中的颜色值设置成shader 中的 value 表现出来. 然后在得到的结果图片中的颜色强度就可以用来得到在shader中的一个value的结果. 这可能看起来是一个非常"原始"的调试方法,但是不幸的是, 在Unity中暂时木有其他办法.....

那么Vertex Data又是从哪儿来的呢?

在上一章中, 你已经看到fragment shader如何从vertex shader中获得一个值, 也知道output结构体的含义了. 接下来问题就是vertex函数中所用到的参数的值又是哪儿来的呢?在Unity中, 答案是每一帧Mesh Render这个组件会把所有相关的data都发送OpenGL. ( 这一步通常被叫做"draw call". 注意每一个draw call都有相同的性能开销, 因此, 在一次draw发一个很大的mesh的data比发送很多次小的data要高效率得多.)这个数据通常包含了一个很长的三角形列表, 其中的每一个三角形都由三个顶点表示. 每一个顶点都有确定的属性, 包含了它的位置. 这些属性都可以在vertex shader中通过vertex input参数获得. 在Cg中不同的vertex input参数和顶点的各个属性的对应关系可以通过语义绑定来区分, 也就是说每一个vertex input参数都需要做语义绑定. 例如, 使用 POSITION, NORMAL, TEXCOORD0, TEXCOORD1, TANGENT, COLOR, 等等. 无论怎样, 在Unity中的Cg语言,内置的vertex input参数都被已经做好了语义绑定. 我们将在接下来讨论.


内置的Vertex Input参数以及怎样让他们可以被看到

在Unity中, 内置的vertex input参数(position, surface normal, two sets of texture coordinattes, tangent vector, vertex color)不仅仅有固定的语义绑定, 同时还有固定的名字和类型. 不幸的是, 他们需要被包含在单一的结构体中, 例如:

struct vertexInput {float4 vertex : POSITION; // position (in object coordinates,// i.e. local or model coordinates)float4 tangent : TANGENT;// vector orthogonal to the surface normalfloat3 normal : NORMAL; // surface normal vector (in object// coordinates; usually normalized to unit length)float4 texcoord : TEXCOORD0; // 0th set of texture// coordinates (a.k.a. “UV”; between 0 and 1)float4 texcoord1 : TEXCOORD1; // 1st set of texture// coordinates (a.k.a. “UV”; between 0 and 1)fixed4 color : COLOR; // color (usually constant)};

这个结构体这样用:

Shader "Cg shader with all built-in vertex input parameters" {SubShader {Pass {CGPROGRAM#pragma vertex vert#pragma fragment fragstruct 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; // set the output color// other possibilities to play with:// 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}}}
在"RGB Cube"那章, 我们已经看到, 如何通过将顶点坐标设置成fragment中的color值来让坐标值可视化. 在这个例子中, fragment的color被设置成texture coordinate, 因此我们就可以看到Unity的不同的texture coordinate是咋回事啦!

注意前三个组件中的tangent表示切方向. 而缩放和第四个组件由指定的方法设置, 他们通常被用在parallax mapping(视差贴图中)(详细的在之后讲).

预定义Input结构体

通常, 你应该自己指定实际所需要的参数, 这样可以提高shader的性能. 当然, Unity这边也提供了一些已经定义好的预定义input结构体给大家: appdata_base, appdata_tan, 和appdata_full 来覆盖大多数情况需要用到的参数.他们的定义在 UnityCg.cginc文件中(路径自己搜索吧...)
struct appdata_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 coordinates only on XBOX360};
这个UnityCg.cginc 用 #include "UnityCg.cginc" 来引用. 于是上面那个shader可以重写为:
Shader "Cg shader with all built-in vertex input parameters" {SubShader {Pass {CGPROGRAM#pragma vertex vert#pragma fragment frag<span style="color:#ff6666;">#include "UnityCG.cginc"</span>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}}}
我去,这一章好长,分成两段把.



0 0