案例 - vf着色器细讲

本篇用一个案例来讲述vf着色器的基础。
案例 1.0

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "ShaderLearning/1_SimpleShader"{
    Properties{
        
    }
    SubShader{
        Tags{

        }
        pass{
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            //顶点着色器代码,它是逐顶点执行得
            //POSITION / SV_POSITION 都是 CG/HLSL中得语义。负责告诉系统输入值和输出值
            //POSITION把模型顶点坐标填充到 v 中输入系统
            //SV_POSITION告诉 unity 输出得是 裁剪空间中得顶点坐标
            //如果没有这些 语义 的话, 渲染起完全不知道输入输出是什么 
            float4 vert(float4 v:POSITION) : SV_POSITION{
                return UnityObjectToClipPos(v);    //将模型的顶点坐标转换成裁剪坐标
            }

            //SV_TARGET是系统值,表示该函数返回的是用于下一个阶段OutPut Merger的颜色值
            fixed4 frag():SV_TARGET{
                return fixed4(1,1,0,0);   //返回一个自定义的颜色值
            }
            
            ENDCG
        }
    }
    Fallback "VertexLit"
}

结果
将此shader赋予材质球,结果将是给材质球染上一层黄色。

材质球效果

到此为止,一个最基础不过的vf着色器就写好了。接下来,我们逐渐丰富器内容。

案例2.0
要想呈现效果更丰富,那么得获取到一些数据,然后加以修改才行。
在CGPROGRAM下,我们要定义一些要获取的数据类型:

           //定义输入顶点着色器阶段的数据类型
           //a : application    v : vertex
           //我们知道,渲染流水线分为3个阶段:应用阶段,几何阶段(包含顶点着色器),光栅化阶段(包含片元着色器)
           //a2v意即将数据从应用阶段传到顶点着色器中
           struct a2v{
               //语义的作用:
               float4 vertex:POSITION;        //用模型空间的顶点坐标填充
               float3 normal:NORMAL;          //用模型空间的法线方向填充
               float4 texcoord:TEXCOORD;      //用模型的第一套纹理坐标填充

               //此外还有有一些其他的语义:TANGENT,COLOR,TEXCOORD1-3 等等。
               //详情:https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647.aspx
               //那么,这些语义的数据从哪里获得呢?
               //在unity中,他们是由使用该材质的Mesh Render提供的。在每帧调用DC的时候,该组件会把它负责渲染的模型数据发送给unity shader

           };

           //顶点着色器 和 片元着色器 之间的通信
           //此结构体定义由顶点着色器传入片元着色器的数据结构
           struct v2f{
               //SV_POSITION告诉unity , pos里包含了顶点在裁剪空间中的位置信息。
               float4 pos : SV_POSITION;
               //COLOR0语义可以用于存储颜色信息
               fixed3 color : COLOR0;
           };

然后在顶点着色器、片元着色器阶段处理这些数据:

            //因为要返回的数据类型已经在v2f中定义,所以此时要把SV_POSITION删除
            v2f vert(a2v v) {   
                v2f o;

              //将模型的顶点坐标转换成裁剪坐标
                o.pos = UnityObjectToClipPos(v.vertex);  

                //v.normal包含顶点的法线方向,其分量范围在【-1,1】
                //通过下列公式,将值映射在【0,1】,使得颜色更加明亮
                o.color = v.normal * 0.5 + fixed3(0.5,0.5,0.5);

                return o;    
            }

            //SV_TARGET是系统值,表示该函数返回的是用于下一个阶段OutPut Merger的颜色值
            fixed4 frag(v2f i):SV_TARGET{
                return fixed4(i.color,1);   //返回一个颜色插值
            }

结果
这样就能使材质按照其法线值来染上相应的颜色。

材质球效果

案例3.0
到目前为止,我们只是获取模型上的顶点数据来进行修改呈现,接下来我们通过获取外部数据来修改呈现效果。

    Properties{
        _Color("Color Tint",Color) = (1,1,1,1)
    }
pass{
          ...
            fixed4 _Color;
          ...
            fixed4 frag(v2f i):SV_TARGET{
                fixed3 c = i.color;
                
                //使用_Color来控制输出颜色
                c *= _Color.rgb;
                return fixed4(c,1);   //返回一个颜色插值
            }
          ...
}

结果
这就能够在材质面板中,调节参数,来控制显示结果

材质参数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容