说实话这一章真没怎么看懂,不过先写出来吧,理解多少是多少,不对的地方欢迎大虾们批评指正。
本章主要讲述了如何对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);
1.3 Debugging of Shaders (调试着色器),布布扣,bubuko.com