Unity Shader:(四)从0到1动手写一个调色板Shader

0.   先写一个嘿简单的Shader

 1 Shader "Test/SimpleShader"
 2 {
 3     SubShader
 4     {
 5         Pass
 6         {
 7             CGPROGRAM
 8             #pragma vertex vert  //代表顶点着色器的函数名
 9             #pragma fragment frag   //代表片元着色器的函数名
10             float4 vert(float4 v:POSITION) :SV_POSITION  //加粗部分是CG里的语义,是固定的
11             {
12                 return UnityObjectToClipPos(v);
13             }
14             fixed4 frag() : SV_Target
15             {
16                 return fixed4(1.0,1.0,1.0,1.0);  //代表的Color,(1,1,1)是白色,(0,0,0)是黑色
17             }
18             ENDCG
19         }
20     }
21 }

要定义更多的数据就要用到结构体了,来看看怎么写吧。

 1 Shader "Test/SimpleShader"
 2 {
 3     SubShader
 4     {
 5         Pass
 6         {
 7             CGPROGRAM
 8             #pragma vertex vert
 9             #pragma fragment frag
10 
11             //使用结构体来定义顶点着色器的输入
12             struct a2v 
13             {
14                 float4 vertex:POSITION; //用模型空间的顶点坐标填充vertex
15                 float3 normal:NORMAL;  //用模型空间的法线方向填充normal
16                 float4 texcoord:TEXCOORD0; //用模型的第一套纹理填充texcoord
17             };
18             float4 vert(a2v v) :SV_POSITION  //注意传参是结构体参数
19             {
20                 return UnityObjectToClipPos (v.vertex);
21             }
22             fixed4 frag() : SV_Target
23             {
24                 return fixed4(1.0,1.0,1.0,1.0);
25             }
26             ENDCG
27         }
28     }
29 }

现在做一个颜色渐变的小球吧!!!需要把顶点着色器的信息传给片元着色器,那么就要定义一个结构体struct v2f 和方法v2f vert(a2v v)  来接收顶点着色器的输出。然后把返回值传给片元着色器fixed4 frag(v2f i): SV_Target

Shader "Test/SimpleShader"
{
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //使用结构体来定义顶点着色器的输入
            struct a2v 
            {
                float4 vertex:POSITION; //用模型空间的顶点坐标填充vertex
                float3 normal:NORMAL;  //用模型空间的法线方向填充normal
                float4 texcoord:TEXCOORD0; //用模型的第一套纹理填充texcoord
            };
            struct v2f 
            {
                float4 pos:POSITION;
                fixed3 color : COLOR0;
            };

            v2f vert(a2v v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.color = v.normal*0.5 + fixed3(0.5, 0.5, 0.5);  
                return o;
            }
            fixed4 frag(v2f i) : SV_Target
            {
                return fixed4(i.color,1.0);
            }
            ENDCG
        }
    }
}

效果图:

 哎呀再前进一步!在材质面板显示一个颜色拾取器方便控制颜色。

根据前面介绍的,我们可以通过定义一个颜色属性,来显示到材质面板。再把这个属性赋值给片元着色器。下面加粗部分是新增加的代码。

 1 Shader "Test/SimpleShader"
 2 {
 3     Properties{ _Color("Pick Color",Color)=(1.0,1.0,1.0,1.0)}
 4     SubShader
 5     {
 6         Pass
 7         {
 8             CGPROGRAM
 9             #pragma vertex vert
10             #pragma fragment frag
11 
12             fixed4 _Color;
13 
14             //使用结构体来定义顶点着色器的输入
15             struct a2v 
16             {
17                 float4 vertex:POSITION; //用模型空间的顶点坐标填充vertex
18                 float3 normal:NORMAL;  //用模型空间的法线方向填充normal
19                 float4 texcoord:TEXCOORD0; //用模型的第一套纹理填充texcoord
20             };
21             struct v2f 
22             {
23                 float4 pos:POSITION;
24                 fixed3 color : COLOR0;
25             };
26 
27             v2f vert(a2v v)
28             {
29                 v2f o;
30                 o.pos = UnityObjectToClipPos(v.vertex);
31                 o.color = v.normal*0.5 + fixed3(0.5, 0.5, 0.5);
32                 return o;
33             }
34             fixed4 frag(v2f i) : SV_Target
35             {
36                 fixed3 c = i.color;
37                 c *= _Color.rgb;  //这里是*,就是叠加这个效果
38                 return fixed4(c,1.0);
39             }
40             ENDCG
41         }
42     }
43 }

效果图:可以看得出来是叠加效果。

 

 下一节我们再介绍语义,调式,优化。

posted @ 2022-02-10 23:36  番茄玛丽  阅读(389)  评论(0编辑  收藏  举报