• Unity里基础光照(Lambert、Phong、BlinnPhong模型)的Shader代码


    //以下是各种光照模型(Lambert、Phong、BlinnPhong、Gourand)的Shader代码,在Unity里创建一个Material后可以选择使用,各行代码都有注释,不再详细解释了。

    Shader "MyShader/BaseShader"
    {
    //包含Lambert、Phone、Blin-Phong模型
        Properties
        {//定义属性
            _Diffuse("Diffuse",Color) = (1,1,1,1)
            _Specular("Specular",Color) = (1,1,1,1)
            _Gloss("Gloss",Range(5,255)) = 5
            [Toggle(_Phong)] _Phong("Phong",float) = 1
            [Toggle(BlinnPhong)] _BlinnPhong("BlinnPhong",float) = 1
            _MainTex ("Texture", 2D) = "white" {}
        }

        SubShader
        {
            Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"} //定义Tag
            //LOD 100

            Pass
            {
                CGPROGRAM
                #include "UnityCG.cginc"    //库函数
                #include "Lighting.cginc"
                //定义触发器,改变光照模型
                #pragma shader_feature _PHONG
                #pragma shader_feature _BLINNPHONG
                #pragma shader_feature _LAMBERT
                #pragma shader_feature _GOURAND
                
                #pragma vertex vert //顶点着色器名称
                #pragma fragment frag   //片元着色器名称
      
                float4 _Diffuse;    //全局参数,漫反射、高光颜色、高光参数
                float4 _Specular;
                float _Gloss;

                struct a2v
                {//应用传入顶点着色器的变量
                    float4 vertex : POSITION;
                    float3 normal :NORMAL;
                    float2 uv : TEXCOORD0;
                };

                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                    float3 worldNormal: NORMAL;
                    float3 worldPos: TEXCOORD1;
                    float3 color: TEXCOORD2;                
                };

                sampler2D _MainTex;
                float4 _MainTex_ST;

                v2f vert (a2v v)
                {//顶点着色器
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);  //顶点空间到裁剪空间
                    //o.worldNormal = normalize(mul(v.normal,(float 3x3) unity_worldTo));
                    o.worldNormal = UnityObjectToWorldNormal(v.normal);   //法线转换到世界空间
                    o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;   //顶点位置转换到世界空间

                    o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                    #if defined(_GOURAND)
                        float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _Diffuse;    //环境光
                        float3 worldLight = normalize(_WorldSpaceLightPos0.xyz);    //归一化光方向
                        float3 worldNormal = normalize(o.worldNormal);              //归一化worldNormal
                        float NdotL = max(0, dot(worldLight, worldNormal));         //法线和光线的点积,即余弦值
                        float3 diffuse = _LightColor0.rgb * _Diffuse.rgb * NdotL;    //计算漫反射Lambert
                        float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - o.worldPos.xyz);  //视角方向
                        float3 reflectDir = normalize(reflect(-worldLight,worldNormal));  //计算反射方向,worldLight表示入射光方向
                        float VdotR = max(0, dot(reflectDir, viewDir));         //反射光方向与观察方向的夹角,点积结果为夹角的余弦值
                        float3 specular = _LightColor0.rgb * _Specular.rgb * pow(VdotR, _Gloss);    //高光值
                        o.color = diffuse + ambient + specular;     //Gourand模型最后输出的颜色值
                    #endif
                    return o;
                }

                fixed4 frag (v2f i) : SV_Target
                {//片元着色器
                    // sample the texture
                    //fixed4 col = tex2D(_MainTex, i.uv);
                    float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _Diffuse;     //环境光
                    float3 worldLight = normalize(_WorldSpaceLightPos0.xyz);       //归一化光方向
                    float3 worldNormal = normalize(i.worldNormal);                //归一化worldNormal
                    float NdotL = max(0, dot(worldNormal,worldLight));             //计算漫反射Lambert公式
                    fixed4 renderTex = tex2D(_MainTex, i.uv);  

                    float3 diffuse = _LightColor0.rgb * _Diffuse.rgb * NdotL;         //计算Diffuse光
                    float3 specular;    //存储高光值
                    float3 color;       //存储最终颜色值

                    float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);  //归一化视方向
                    #if defined(_LAMBERT)
                        color = diffuse;    //Lambert模型
                    #endif
                    
                    //#if defined(_PHONG)
                      //Phong模型计算
                        float3 reflectDir = normalize(reflect(-worldLight,worldNormal));    //计算反射方向,worldLight表示入射光方向
                        float VdotR = max(0, dot(viewDir,reflectDir));   //反射光方向与观察方向的夹角,dot(ViewDir,ReflectDir)
                        specular = _LightColor0.rgb * _Specular.rgb * pow(VdotR, _Gloss); //计算高光反射
                        color = ambient + diffuse + specular;
                    //#endif
                    
                    #if defined(_BLINNPHONG)
                       //BlinnPhong模型计算
                        float3 halfDir = (worldLight +viewDir);  //计算半角向量,光线方向+视方向的结果归一化
                        float NdotH = saturate(dot(halfDir,worldNormal));   //半角向量与法线方向的点积,结果归一化
                        specular = _LightColor0.rgb * _Specular.rgb * pow(NdotH, _Gloss);   //计算BlinnPhong的高光值
                        color = ambient + diffuse + specular;
                    #endif
                    
                    #if defined(_GOURAND)
                        color = i.color;    //直接使用顶点着色器中计算出来的颜色值
                    #endif
                    color = color * renderTex.rgb;
                    return fixed4(color,1.0);
                }
                ENDCG
            }
        }
    }

    每日进步一点点
  • 相关阅读:
    深度学习(十一) 残差网络
    深度学习(十) GoogleNet
    深度学习(九) 深度学习最全优化方法总结比较(SGD,Momentum,Nesterov Momentum,Adagrad,Adadelta,RMSprop,Adam)
    联合概率
    深度学习(八) Batch Normalization
    概率论
    设计者模式(八) 装饰者模式
    使用Adobe Photoshop CC 2015批量修改图片尺寸
    Turn.js 实现翻书效果的学习与总结
    TweenMax动画库学习(六)
  • 原文地址:https://www.cnblogs.com/laoyueblogs/p/15805672.html
Copyright © 2020-2023  润新知