zoukankan      html  css  js  c++  java
  • Unity3D教程宝典之Shader篇:第十四讲Surface Shader

     
        用Shader来实现光照是比较复杂的,有不同的光类型,不同的阴影选项,不同的Render Path(forward和Deferred)。 Unity只是把光照模型封装处理了,Shader的代码还是用CG/HLSL编写的。
     
     
    例一:最简单的Surface Shader
    Shader "Custom/T_3_0" {
        Properties {
            _MainTex ("Base (RGB)", 2D) = "white" {}
        }
        SubShader {
            CGPROGRAM
            #pragma surface surf Lambert
            sampler2D _MainTex;
            struct Input {
                float2 uv_MainTex;
            } ;
            void surf (Input IN, inout SurfaceOutput o) {
                half4 c = tex2D (_MainTex, IN.uv_MainTex);
                o.Albedo = c.rgb;
                o.Alpha = c.a;
            }
            ENDCG
        }  
    }
    

      

    表面处理函数从顶点处理函数(这里自动顶点处理)接收参数Input IN,输出SurfaceOutput o至光照模型(这里是Lambert)。
    这里我们就做了三件事:
    (1)通过uv取得了贴图对应uv的颜色c
      (2)把c.rgb赋给o.Albedo
      (3) 把c.a赋给o.Alpha
    这就完成了。之后让任一物体使用该Shader,则不管加什么光都能正确显示。真的很简单!
     
     
    表面处理函数surf的输入及输出
     
    (1)输入
    struct Input {
        float2 uv_MainTex;
        float3 viewDir;
        float4 anyName:COLOR;
        float4 screenPos;
        float3 worldPos;
        float3 worldRefl;
    } ;
    

      

    uv_MainTex: uv
    viewDir: 入视角
    screenPos:裁剪空间位置
    worldPos:世界空间位置
     
     
    (2)输出
    struct SurfaceOutput {
        half3 Albedo;
        half3 Normal;
        half3 Emission;
        half Specular;
        half Gloss;
        half Alpha;
    };
    

      

    Albedo:漫反射颜色
    Normal: 法线
    Emission:自发光颜色
    Specular:镜面反射系数
    Gloss:
    Alpha:透明值
     
     
     
    Surface Shader参数
     
    Surface Shader可以通过加参数实现额外的控制,例如加顶点处理函数,alpha混合等。
    注意:
    如果使用的光照模型是Unity自带的Lambert或者BlinnPhong:
    alpha混合,alpha混合等功能必须使用Surface Shader参数。
    之前例如AlphaTest Greater 0.3 等代码就不能再加了。如果加了的话,光照失效,物体为一片漆黑。
     
    如果使用的光照模型是自定义光照模型
    只要在surf中给o.Alpha正常赋值(如赋贴图颜色的a值),那么之前例如AlphaTest Greater 0.3 等代码依然可以照常使用。具体相关代码可以参考下一讲中的代码。
     
     
    (1)alpha混合
    直接加参数Alpha即可

    #pragma surface surf BlinnPhong alpha

    (2)alphatest

    加入一个变量,这里起名为_Cutoff, 然后在#pragma surface结尾处加上alphatest:_Cutoff。

    效果是alpha值大于_Cutoff时,才会输出颜色

    Shader "Custom/T_3_0" {
        Properties {
            _MainTex ("Base (RGB)", 2D) = "white" {}
            _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
        }
        SubShader {
            CGPROGRAM
            #pragma surface surf Lambert alphatest:_Cutoff
            sampler2D _MainTex;
            struct Input {
                float2 uv_MainTex;
            } ;
            void surf (Input IN, inout SurfaceOutput o) {
                half4 c = tex2D (_MainTex, IN.uv_MainTex);
                o.Albedo = c.rgb;
                o.Alpha = c.a;
            }
            ENDCG
        }  
    }
    

      

    (3)顶点函数

    例:臃肿的模型

    实现方法,将顶点向法线方向延伸一段距离

    【风宇冲】Unity3D教程宝典之Shader篇:第十四讲Surface <wbr>Shader

     Shader "Example/Normal Extrusion" {
        Properties {
            _MainTex ("Texture", 2D) = "white" {}
            _Amount ("Extrusion Amount", Range(-1,1)) = 0.5
        }
        SubShader {
            Tags { "RenderType" = "Opaque" }
            CGPROGRAM
            #pragma surface surf Lambert vertex:vert
            struct Input {
                float2 uv_MainTex;
            };
            float _Amount;
            void vert (inout appdata_full v) {
                v.vertex.xyz += v.normal * _Amount;
            }
            sampler2D _MainTex;
            void surf (Input IN, inout SurfaceOutput o) {
                o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
            }
            ENDCG
        } 
        Fallback "Diffuse"
    }
    

      

    (4)finalcolor

    finalcolor:ColorFunction

    对颜色输出作最后的更改

    Shader "Example/Tint Final Color" {
        Properties {
            _MainTex ("Texture", 2D) = "white" {}
            _ColorTint ("Tint", Color) = (1.0, 0.6, 0.6, 1.0)
        }
        SubShader {
            CGPROGRAM
            #pragma surface surf Lambert finalcolor:mycolor
            struct Input {
                float2 uv_MainTex;
            };
            fixed4 _ColorTint;
            void mycolor (Input IN, SurfaceOutput o, inout fixed4 color)
            {
                //在这里对最后输出的颜色color进行修改
                color *= _ColorTint;
            }
            sampler2D _MainTex;
            void surf (Input IN, inout SurfaceOutput o) {
                o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
            }
            ENDCG
        } 
     }
    

      

  • 相关阅读:
    Neko's loop HDU-6444(网络赛1007)
    Parameters
    SETLOCAL
    RD / RMDIR Command
    devenv 命令用法
    Cannot determine the location of the VS Common Tools folder.
    'DEVENV' is not recognized as an internal or external command,
    How to change Visual Studio default environment setting
    error signing assembly unknown error
    What is the Xcopy Command?:
  • 原文地址:https://www.cnblogs.com/zdlbbg/p/4329299.html
Copyright © 2011-2022 走看看