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
        } 
     }
    

      

  • 相关阅读:
    AcWing 2476. 树套树(线段树套splay)
    LeetCode 1191 K 次串联后最大子数组之和
    LeetCode 668 乘法表中第k小的数
    Java003-String字符串
    云原生CD工具spinnaker部署(容器化灰度发布)
    刷题日记
    8.22 校内模拟赛 题解报告
    关于 CDQ分治(复习)
    解题营_数论
    解题营_动规
  • 原文地址:https://www.cnblogs.com/zdlbbg/p/4329299.html
Copyright © 2011-2022 走看看