美文网首页
案例 - vf着色器细讲

案例 - vf着色器细讲

作者: JervieQin | 来源:发表于2018-06-21 22:45 被阅读0次

    本篇用一个案例来讲述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);   //返回一个颜色插值
                }
              ...
    }
    

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

    材质参数

    相关文章

      网友评论

          本文标题:案例 - vf着色器细讲

          本文链接:https://www.haomeiwen.com/subject/edqcyftx.html