当前位置:首页 > 多媒体 > 图形/图像

Unity Shader——Writing Surface Shaders(三)——Surface Shader Lighting Examples

优良自学吧提供Unity Shader——Writing Surface Shaders(三)——Surface Shader Lighting Examples,Unity Shader——Writing Surface Shaders(3)——Surface Shader Lighting ExamplesSurface Shader 光照例子   这里有一些自定义光照模型和Surface Shaders的例子。通常的Surface Sh

Unity Shader——Writing Surface Shaders(3)——Surface Shader Lighting Examples

Surface Shader 光照例子

  这里有一些自定义光照模型和Surface Shaders的例子。通常的Surface Shader例子在这里。

  由于延迟光照在某些自定义的逐材质光照模型中表现得并不好,在下面大多数例子中,我们让shader只编译到正向渲染中。

漫反射(Diffuse)

  让我们以使用内建Lambert光照模型的shader作为开始吧!

Shader "Example/Diffuse Texture" {
    Properties {
      _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM
      #pragma surface surf Lambert
      
      struct Input {
          float2 uv_MainTex;
      };
      
      sampler2D _MainTex;
      
      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

  下面是使用一张纹理贴图和不使用一张真实的纹理贴图的样子(此场景中有一个方向光)

Unity Shader——Writing Surface Shaders(三)——Surface Shader Lighting Examples Unity Shader——Writing Surface Shaders(三)——Surface Shader Lighting Examples

  现在,我们来做个完全一样的,但是使用我们自己的光照模型,而不是内建Lambert光照模型。Surface Shader光照模型仅是一些我们需要编写的函数。这里有一个简单的Lambert光照模型。注意到只有CGPROGRAM部分发生了改变,周边的shader代码是完全一样的:

Shader "Example/Diffuse Texture" {
        Properties {
            _MainTex ("Texture", 2D) = "white" {}
        }
        SubShader {
        Tags { "RenderType" = "Opaque" }
        CGPROGRAM
          #pragma surface surf SimpleLambert
  
          half4 LightingSimpleLambert (SurfaceOutput s, half3 lightDir, half atten) {
              half NdotL = dot (s.Normal, lightDir);
              half4 c;
              c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2);
              c.a = s.Alpha;
              return c;
          }
  
        struct Input {
            float2 uv_MainTex;
        };
        
        sampler2D _MainTex;
        
        void surf (Input IN, inout SurfaceOutput o) {
            o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        }
        ENDCG
        }
        Fallback "Diffuse"
    }

  所以我们的简单漫反射光照模型就是LightingSimpleLambert 函数。它通过计算表面法线和光线方向的点积来计算光照,然后应用光照衰减和颜色。

环绕漫反射(Diffuse Wrap)

  这里是环绕漫反射——漫反射光照的修改版,即照明环绕在物体的边缘。它对用来仿照次表面散射效果很有用。因为只是CGPROGRAM 部分发生了改变,老生常谈一次,周边的shader代码就省略了:

 ...ShaderLab code...
    CGPROGRAM
    #pragma surface surf WrapLambert

    half4 LightingWrapLambert (SurfaceOutput s, half3 lightDir, half atten) {
        half NdotL = dot (s.Normal, lightDir);
        half diff = NdotL * 0.5 + 0.5;
        half4 c;
        c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
        c.a = s.Alpha;
        return c;
    }

    struct Input {
        float2 uv_MainTex;
    };
    
    sampler2D _MainTex;
        void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
    }
    ENDCG
    ...ShaderLab code...

Unity Shader——Writing Surface Shaders(三)——Surface Shader Lighting Examples Unity Shader——Writing Surface Shaders(三)——Surface Shader Lighting Examples

卡通渐变(Toon Ramp)

  下面是一个"渐变(Ramp)"光照模型。它使用一张渐变纹理来定义表面怎样对光线和法线的夹角做出反应。这能用来实现多种效果,包括卡通光照。

...ShaderLab code...
    CGPROGRAM
    #pragma surface surf Ramp

    sampler2D _Ramp;

    half4 LightingRamp (SurfaceOutput s, half3 lightDir, half atten) {
        half NdotL = dot (s.Normal, lightDir);
        half diff = NdotL * 0.5 + 0.5;
        half3 ramp = tex2D (_Ramp, float2(diff)).rgb;
        half4 c;
        c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
        c.a = s.Alpha;
        return c;
    }

    struct Input {
        float2 uv_MainTex;
    };
    
    sampler2D _MainTex;
    
    void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
    }
    ENDCG
    ...ShaderLab code...

Unity Shader——Writing Surface Shaders(三)——Surface Shader Lighting Examples Unity Shader——Writing Surface Shaders(三)——Surface Shader Lighting Examples

Unity Shader——Writing Surface Shaders(三)——Surface Shader Lighting Examples

简单镜面(Simple Specular)

  下面是一个简单镜面光照模型。这对于内置的BlinnPhong实际所做的内容来说非常简单。我们把它放在这来说明它是如何工作的。

  ...ShaderLab code...
    CGPROGRAM
    #pragma surface surf SimpleSpecular

    half4 LightingSimpleSpecular (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
        half3 h = normalize (lightDir + viewDir);

        half diff = max (0, dot (s.Normal, lightDir));

        float nh = max (0, dot (s.Normal, h));
        float spec = pow (nh, 48.0);

        half4 c;
        c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten * 2);
        c.a = s.Alpha;
        return c;
    }

    struct Input {
        float2 uv_MainTex;
    };
    
    sampler2D _MainTex;
    
    void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
    }
    ENDCG
    ...ShaderLab code...

解码光照贴图(Decoding Lightmaps)

  我们将以这样一个shader作为开始:它模仿内置的光照贴图解码工作,使用Unity自带的DecodeLightmap函数解码lightmap中储存的数据信息,以及使用自带的UNITY_DIRBASIS宏定义方向光照贴图(Directional lightmap)的基本向量: 

 Shader "Example/Standard Lightmap Decoding" {
        Properties {
            _MainTex ("Texture", 2D) = "white" {}
        }
        SubShader {
            Tags { "RenderType" = "Opaque" }
            CGPROGRAM

            #pragma surface surf Standard

            half4 LightingStandard (SurfaceOutput s, half3 lightDir, half atten) {
                half NdotL = dot (s.Normal, lightDir);
                half4 c; c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2);
                c.a = s.Alpha;
                return c;
            }

            inline fixed4 LightingStandard_SingleLightmap (SurfaceOutput s, fixed4 color) {
                half3 lm = DecodeLightmap (color);
                return fixed4(lm, 0);
            }

            inline fixed4 LightingStandard_DualLightmap (SurfaceOutput s, fixed4 totalColor, fixed4 indirectOnlyColor, half indirectFade) {
                half3 lm = lerp (DecodeLightmap (indirectOnlyColor), DecodeLightmap (totalColor), indirectFade);
                return fixed4(lm, 0);
            }

            inline fixed4 LightingStandard_StandardLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, bool surfFuncWritesNormal) {
                UNITY_DIRBASIS

                half3 lm = DecodeLightmap (color);
                half3 scalePerBasisVector = DecodeLightmap (scale);

                if (surfFuncWritesNormal)
                {
                    half3 normalInRnmBasis = saturate (mul (unity_DirBasis, s.Normal));
                    lm *= dot (normalInRnmBasis, scalePerBasisVector);
                }

                return fixed4(lm, 0);
            }

            struct Input {
                float2 uv_MainTex;
            };
            
            sampler2D _MainTex;
            
            void surf (Input IN, inout SurfaceOutput o) {
                o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
            }
            ENDCG
            }
        Fallback "Diffuse"
    }

  现在,让我们为光照贴图中储存的光添加些色调映射(tone mapping):

Shader "Example/Tonemapped Lightmap Decoding" {
        Properties {
            _MainTex ("Texture", 2D) = "white" {}
            _Gain ("Lightmap tone-mapping Gain", Float) = 1
            _Knee ("Lightmap tone-mapping Knee", Float) = 0.5
            _Compress ("Lightmap tone-mapping Compress", Float) = 0.33
        }
        SubShader {
            Tags { "RenderType" = "Opaque" }
            CGPROGRAM

            #pragma surface surf Tonemapped

            half4 LightingTonemapped (SurfaceOutput s, half3 lightDir, half atten) {
                half NdotL = dot (s.Normal, lightDir);
                half4 c; c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2); c.a = s.Alpha;
                return c;
            }

            half _Gain;
            half _Knee;
            half _Compress;
            
            inline half3 TonemapLight (half3 i) {
                i *= _Gain;
                return (i > _Knee)? (((i - _Knee)*_Compress)+_Knee): i;
            }

            inline fixed4 LightingTonemapped_SingleLightmap (SurfaceOutput s, fixed4 color) {
                half3 lm = TonemapLight(DecodeLightmap (color));
                return fixed4(lm, 0);
            }

            inline fixed4 LightingTonemapped_DualLightmap (SurfaceOutput s, fixed4 totalColor, fixed4 indirectOnlyColor, half indirectFade) {
                half3 lm = TonemapLight(lerp (DecodeLightmap (indirectOnlyColor), DecodeLightmap (totalColor), indirectFade));
                return fixed4(lm, 0);
            }

            inline fixed4 LightingTonemapped_StandardLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, bool surfFuncWritesNormal) {
                UNITY_DIRBASIS

                half3 lm = TonemapLight(DecodeLightmap (color));
                half3 scalePerBasisVector = DecodeLightmap (scale);

                if (surfFuncWritesNormal)
                {
                    half3 normalInRnmBasis = saturate (mul (unity_DirBasis, s.Normal));
                    lm *= dot (normalInRnmBasis, scalePerBasisVector);
                }

                return fixed4(lm, 0);
            }

            struct Input {
                float2 uv_MainTex;
            };
            
            sampler2D _MainTex;
            
            void surf (Input IN, inout SurfaceOutput o) {
                o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
            }
            ENDCG
        }
        Fallback "Diffuse"
    }

 


(本文来自互联网,不代表搜站(http://www.ylzx8.cn/)的观点和立场)
本站所有内容来自互联网,若本站收录的信息无意侵犯了贵司版权,请给我们来信(ylzx8cn@163.com),我们会及时处理和回复,谢谢

最近更新