unity3d shader 自定义光照函数

Posted 不务正业的人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity3d shader 自定义光照函数相关的知识,希望对你有一定的参考价值。

希望实现一个根据摄像机朝向与网格法向关系控制光照亮度的双面shader。

代码如下

Shader "Custom/UnlitOP" {
    Properties{ 
        _Color("Main Color", Color) = (1,1,1,1)                  //渲染需要外部设置的颜色
        _MainTex("Base (RGB)", 2D) = "white" {}                  //材质
        _CamDir("Camera Dirction",Vector) = (0.1,0.2,0.3,0.4)          //摄像机的朝向

    }
        SubShader{
        Tags{ "RenderType" = "Opaque" "Queue" = "Geometry"}
        ZWrite On  
        LOD 200
        Cull Off            //双面shader
        CGPROGRAM
#pragma surface surf myLightModel    //用了自定义的光照模型



    sampler2D _MainTex;          
    float4 _Color;
    float4 _CamDir;            //摄像机朝向变量
    //命名规则:Lighting接#pragma suface之后起的名字   
    //lightDir :点到光源的单位向量   viewDir:点到摄像机的单位向量   atten:衰减系数   
    float4 LightingmyLightModel(SurfaceOutput s, float3 lightDir, half3 viewDir, half atten)
    {
        float4 c;
        float3 cr;
        cr = _CamDir.xyz;

        float diffuseF = max(0, abs(dot(s.Normal, cr)/2.0));    //由于是双面shader,所以正反面的颜色应该一样,否则会不同,/2是让dot结果在0-1之间。
        
        c.rgb = s.Albedo*_LightColor0.rgb*(diffuseF);        //_LightColor0是内置的属性,应该跟当前光照有关。
        c.a = s.Alpha;
        return c;
    }

    struct Input {
        float2 uv_MainTex;
        float4 _Color;
    };

    void surf(Input IN, inout SurfaceOutput o) {
        //half4 c = tex2D(_MainTex, IN.uv_MainTex)*_Color;
        o.Albedo = _Color.rgb;
        o.Alpha = _Color.a;
    }
    ENDCG
    }
        FallBack "Diffuse"
}

下面是有透明效果的版本,基本一样,就是要注意Tags的写法,以及关闭ZWrite,开启Ztest,使用Blend。另外在调试中发生了一点意外,完全一样的代码,开始时始终透明物体被渲在了所有不透明物体后面,怎么改代码都没用,后来将材质的shader都改成standard试试好用,再改回来就正常了。这点事弄了半下午...... 

Shader "Custom/UnlitTR" {
    Properties{
        _Color("Main Color", Color) = (1,1,1,1)
        _MainTex("Base (RGB)", 2D) = "white" {}
    _CamDir("Camera Dirction",Vector) = (0.1,0.2,0.3,0.4)

    }
        SubShader{
        Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
        ZWrite Off
        ZTest On
        LOD 200
        Blend SrcAlpha OneMinusSrcAlpha
        CGPROGRAM
#pragma surface surf myLightModel alpha  



    sampler2D _MainTex;
    float4 _Color;
    float4 _CamDir;

    //命名规则:Lighting接#pragma suface之后起的名字   
    //lightDir :点到光源的单位向量   viewDir:点到摄像机的单位向量   atten:衰减系数   
    float4 LightingmyLightModel(SurfaceOutput s, float3 lightDir, half3 viewDir, half atten)
    {

        float4 c;
        float3 cr;
        cr = _CamDir.xyz;
        float diffuseF = max(0, abs(dot(s.Normal, cr) / 2.0));
        c.rgb = s.Albedo*_LightColor0.rgb*(diffuseF);
        c.a = s.Alpha;
        return c;
    }

    struct Input {
        float2 uv_MainTex;
        float4 _Color;
    };

    void surf(Input IN, inout SurfaceOutput o) {
        //half4 c = tex2D(_MainTex, IN.uv_MainTex)*_Color;
        o.Albedo = _Color.rgb;
        o.Alpha = _Color.a;
    }
    ENDCG
    }
        FallBack "Diffuse"
}

 

以上是关于unity3d shader 自定义光照函数的主要内容,如果未能解决你的问题,请参考以下文章

Unity关闭shader中的光照模型以及如何自定义光照模型

[Unity Shader] 逐顶点光照和逐片元光照

Unity Shaders学习笔记之为创建自定义慢反射光照模型

Unity3D Shader编程之二 雪山飞狐篇:Unity的基本Shader框架写法&颜色光照与材质

浅墨Unity3D Shader编程之二 雪山飞狐篇:Unity的基本Shader框架写法&颜色光照与材质

Unity Shader 光照模型(基础公式和代码实现)