Unity3D — Shader 顶点片段着色器


顶点片段着色器:复杂、灵活度尕高、用到CG

语义绑定

  • 顶点的模型坐标 float4 POSITION
  • 顶点的屏幕坐标 float4 SV_POSTION
  • 顶点法线向量坐标 float3 NORMAL
  • 第⼀个UV坐标 float4 TEXCOORD0
  • 第⼆个…第四个UV坐标 float4 TEXCOORD1…3
  • 顶点切线向量坐标 float4 TENGENT
  • 顶点颜色值 float4 COLO

示例代码

示例1

Shader "Zhongdudu/nine"
{
    Properties
    {
        _MainCol("颜色",Color)=(1,0,0,1)
    }
    
    SubShader
    {
        Pass
        {
        
            CGPROGRAM //------CG开始------
            
            //顶点着色器的编译指令
            //每有一个顶点就执行一次
            #pragma vertex vert
            //片段着色器的编译指令
            //每有一个像素就执行一次
            #pragma fragment frag
            
            //声明外部属性
            fixed4 _MainCol;
            
            //顶点函数
            //参数输入:模型坐标;返回值输出:屏幕坐标
            half4 vert(half4 localPos:POSITION):SV_POSITION //语义绑定,返回的是什么就绑什么
            {
                //将模型坐标转换为屏幕坐标
                return UnityObjectToClipPos(localPos);
            }
            
            //片段函数
            //返回值语义绑定:每个像素的颜色
            fixed4 frag():COLOR
            {
                return _MainCol;
            }
                        
            ENDCG //------CG结束------
            
        }
    }
}

示例2

Shader "Zhongdudu/ten"
{
    Properties
    {
        _ColorOffset("颜色偏移量",Range(-0.5,1.5))=0.2
        
        _RedOffset("红色偏移量",Range(-0.5,2))=0
        _GreenOffset("绿色偏移量",Range(-0.5,2))=0
        _BlueOffset("蓝色偏移量",Range(-0.5,2))=0
    }
    
    SubShader
    {
        Pass
        {
            CGPROGRAM //------CG开始------
            
            //顶点着色器的编译指令
            //每有一个顶点就执行一次
            #pragma vertex vert
            //片段着色器的编译指令
            //每有一个像素就执行一次
            #pragma fragment frag
            
            //声明外部属性
            fixed _ColorOffset;
            fixed _RedOffset;
            fixed _GreenOffset;
            fixed _BlueOffset;
            
            //顶点函数输出结构体
            struct v2f
            {
                //屏幕坐标
                half4 clipPos:SV_POSITION;
                //理解为一个临时变量,用于存储本地坐标
                fixed4 lPos:TEXCOORD0;
            };
            
            //顶点函数
            //参数输入:模型坐标;返回值输出:v2f结构体
            v2f vert(half4 localPos:POSITION)
            {
                //声明一个结构体对象
                v2f o;
                //将本地坐标临时存储到v2f中
                o.lPos = localPos + 
                    half4(_RedOffset,
                    _GreenOffset,_BlueOffset,0);
                //将屏幕坐标输出到v2f
                o.clipPos = UnityObjectToClipPos(localPos);
                //最终返回这个结构体对象
                return o;
            }
            
            //片段函数
            //参数输入:v2f;返回值语义绑定:每个像素的颜色
            fixed4 frag(v2f input):COLOR
            {
                //将v2f中的本地坐标当成一个颜色去返回
                return input.lPos;
            }
                        
            ENDCG //------CG结束------
        }
    }
}

示例3

Shader "Zhongdudu/zero"
{
    Properties
    {
        _DiffuseColor("漫反射颜色",Color)=(1,0,0,1)
    }
    
    SubShader
    {
        Pass
        {
            Tags{ "LightMode"="ForwardBase" }
        
            CGPROGRAM //------CG开始------
            
            //顶点着色器的编译指令
            //每有一个顶点就执行一次
            #pragma vertex vert
            //片段着色器的编译指令
            //每有一个像素就执行一次
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            
            //顶点输入结构体
            struct appdata
            {
                //顶点模型坐标
                half4 vertexPos:POSITION;
                //顶点法线向量
                half3 vertexNormal:NORMAL;
            };
            
            //顶点输出结构体
            struct v2f
            {
                //顶点屏幕坐标
                half4 screenPos:SV_POSITION;
                //顶点屏幕法线
                half3 screenNormal:NORMAL;
            };
            
            //声明漫反射颜色属性
            fixed4 _DiffuseColor;
            //光照颜色【内部变量】
            fixed4 _LightColor0;
            
            //顶点函数
            v2f vert(appdata data)
            {
                //顶点输出结构体对象
                v2f o;
                //将顶点模型坐标,转换为顶点屏幕坐标
                o.screenPos = UnityObjectToClipPos(data.vertexPos);
                //将顶点模型法线,转换为顶点屏幕法线
                o.screenNormal = mul(half4(data.vertexNormal,1),unity_WorldToObject).xyz;
                //返回结果
                return o;
            }
            
            //片段函数
            half4 frag(v2f vertexInput):COLOR
            {
                //求入射光线的单位向量
                half3 lightDir = normalize(_WorldSpaceLightPos0);
                //求法线向量的单位向量
                half3 normalDir = normalize(vertexInput.screenNormal);
                //通过漫反射公式计算所得每个像素的颜色【兰伯特】
                //half3 diffuseColor = _DiffuseColor.rgb 
                    //* _LightColor0.rgb
                    //* max(0,dot(lightDir,normalDir));
                //通过漫反射公式计算所得每个像素的颜色【半兰伯特】
                half3 diffuseColor = _DiffuseColor.rgb 
                    * _LightColor0.rgb
                    * (0.5 * dot(lightDir,normalDir) + 0.5);
                //漫反射颜色再加上环境光
                return half4(diffuseColor,1) + UNITY_LIGHTMODEL_AMBIENT;
            }
                        
            ENDCG //------CG结束------
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值