[Unity3D][Shader]PANCgShader--第一章 基础--03 vertex参数

vertex阶段数据是怎么来的?

gameobject的Mesh Renderer组件会每一帧把mesh的所有数据信息发往GPU。
这也就是所谓的draw call。每一次的draw call都会有性能消耗,因此每次向GPU发送一个较大容量的mesh数据比发送若干个小mesh数据更高效。
mesh数据包括三角面列表,每个三角面由3个顶点定义,每个顶点又包含若干属性,这些属性通过vertex输入参数传入vertex shader中后都是可读的。这些参数往往通过语义(semantic)来指定,比如POSITION,NORMAL,TEXCOORD0,TEXCOORD1,TEXCOORD2,TANGENT,COLOR。

语义详解:
https://docs.unity3d.com/Manual/SL-ShaderSemantics.html

vertex输入参数,及对其进行可视化

vertex的输入参数:

      struct vertexInput {
         float4 vertex : POSITION; // position (in object coordinates, 
            // i.e. local or model coordinates)
         float4 tangent : TANGENT;  
            // vector orthogonal to the surface normal
         float3 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 tex. coors. 
         float4 texcoord2 : TEXCOORD2; // 2nd set of tex. coors. 
         float4 texcoord3 : TEXCOORD3; // 3rd set of tex. coors. 
         fixed4 color : COLOR; // color (usually constant)
      };

可视化shader:

Shader "My/DebuggingOfShaders"
{ 
    SubShader
    {         
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
				
			struct vertexInput{
				float4 vertex:POSITION;//in object coordinates,i.e. local or model coordinates
				float4 tangent:TANGENT;//vector orthogonal to the surface normal
				float3 normal:NORMAL;//surface normal vector(in object coordinates,usually normalized to unit length)
				float4 texcoord0:TEXCOORD0;//0th set of texture coordinates(a.k.a. "UV", between 0 and 1)
				float4 texcoord1:TEXCOORD1;//1st set of tex. coors.
				float4 texcoord2:TEXCOORD2;//2nd set of tex. coors.
				float4 texcoord3:TEXCOORD3;//3rd set of tex. coors.
				fixed4 color:COLOR;//color(usually constant)
			};

			struct vertexOutput{
				float4 pos:SV_POSITION;							
			    float4 col:TEXCOORD0;
			};

            vertexOutput vert (vertexInput input)
            {                			   
			   vertexOutput output;
			   output.pos=UnityObjectToClipPos(input.vertex);
			   output.col=input.texcoord0;
			    
				//other possibilities to play with:
				//output.col=input.vertex;
				//output.col=input.tangent;
				//output.col=float4(input.normal,1.0);
				//output.col=float4((input.normal+float3(1.0,1.0,1.0))*0.5,1.0);//basicly normal value is between -1 and 1,here map the value to 0 and 1,which can fit color range
				//output.col=input.texcoord1;
				//output.col=input.color;
			   return output;
            }

            fixed4 frag (vertexOutput input) : COLOR
            {
               return input.col;			    
            }
            ENDCG
        }
    }
}

预定义输入结构体

Unity3D中UnityCG.cginc(Unity->Editor->Data->CGIncludes)中已经预定义了一些常用的输入结构体,包括appdata_base,appdata_tan,appdata_full,appdata_img

   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;
      float4 texcoord2 : TEXCOORD2;
      float4 texcoord3 : TEXCOORD3;
      fixed4 color : COLOR;
      // and additional texture coordinates only on XBOX360
   };

   struct appdata_img {
      float4 vertex : POSITION;
      half2 texcoord : TEXCOORD0;
   };

在shader脚本中只需要通过#include "UnityCG.cginc"引入该文件,就可以任意使用上述结构了。

一些常识

图片的坐标范围[0,1]
标准化后的法线范围[-1,1]; normal是3纬结构,只有x,y,z值
COLOR范围[0,1],当设置COLOR的值小于0,或者大于1;会分别被设置为0,1

发布了198 篇原创文章 · 获赞 23 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/iningwei/article/details/100569139