Unity Shader之自定义漫反射光照模型

不积跬步,无以至千里;不积小流,无以成江海。(来自《劝学》- 荀子)

在CSDN或者其他前辈的blog中大家都可以找到类似的教程
为什么我还要去写呢 , 主要是因为我想加入些自己的理解

发现文字真是个好东西,它可以引起人们的无限遐想,所以很多前辈都会推荐看书学习,也许正是因为这个原因吧。

本节重点
:如何在unity shader中实现可定义光照模型
注:unity3D在cginc中已经提供了很强大的光照模型函数,不过,一个好的项目,或者是一个好的游戏视觉冲击,需要的就不仅仅是这些了。

直接上代码了,注释将尽可能详细

shader"Cook Book Shader / Basic Diffuse"
{
    Properties
    {
        _MainTex("MainTex",2D) = "white"{}  
    }

    SubShader
    {
        //告诉系统在渲染非透明物体时调用这个着色器,当然也有在渲染透明物体时的设置,以后再说
        Tags{"RenderType" = "Opaque"}
        LOD 200

        CGPROGRAM
        //告诉着色器将采用basicdiffuse光照模型进行计算
        #pragma surface surf BasicDiffuse

        //声明一个光照模型函数,这里注意,函数名的格式是:Lighting + 你自定义的任何名字  以这里为例:Lighting + BasicDiffuse
        inline float4 LightingBasicDiffuse(SurfaceOutput s,fixed3 LightDir,fixed atten)
        { 
            //max大家应该很清楚,就是取当前最大值
            //而dot函数是CG语言的内置数学函数,作用呢便是知道两个向量之间的角度是多少
            //a b 两个向量点积运算可以用公式:a b  = ||a|| ||b|| cos(a与b的夹角)
            //所以大家可以计算出,如果两个向量之间夹角是锐角,点积结果将大于0,反之将小于0,如果恰巧等于90度则点积结果为0

            //所以 在这里进行点积运算,max的作用便是限制点击函数的计算结果,确保计算结果永远大于0
            float DifLight = max(0,dot(s.Normal,LightDir));

            float4 col;
            //s.Albedo是surf函数处理后的输出,也就是说我们这个光照模型将在原基础上进行增强
            //这里的_LightColor0.rgb则来自unity,由Unity根据场景中的光源得到的,它在Lighting.cginc中声明的
            //然后再与刚才计算的光强系数(DifLight)和输入的衰减系数(atten)相乘
            col.rgb = s.Albedo  * _LightColor0.rgb * (DifLight * atten * 2);
            col.a = s.Alpha;

            return col;
        }


        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf(Input IN,inout SurfaceOutput o)
        {
            float4 c = tex2D(_MainTex,IN.uv_MainTex);

            o.Albedo = c.rgb;
            o.Alpha = c.a;

        }





        ENDCG

    }

    fallback"Diffuse"
}

在最后介绍下三种格式的光照模型函数

1.half4 LightingName1(SurfaceOutput s,half3 LightDir,half atten){}
该函数用于不需要视角方向的前向着色(也就是我们刚才用的)
2.half4 LightingName2(SurfaceOutput s,half3 LightDir,half3 viewDir,half atten){}
该函数用于需要视角方向的前向着色(多了个viewDir)
3.half4 LightingName3_PrePass(SurfaceOutput s, half4 Light){}
用于延迟着色

还是忘记了说明一些问题,下面进行补充吧
1.surfaceOutput:是表面着色器的标准输出结构,它的内容是这样的

struct SurfaceOutput   
{  
    half3 Albedo;            //也就是纹理颜色值(r,g,b),上述shader中可以看出它的作用   
    half3 Normal;            //法线,法向量(x, y, z)  , 上述中也用到了
    half3 Emission;          //自发光颜色值(r, g,b)   
    half Specular;           //镜面反射度   
    half Gloss;              //光泽度  
    half Alpha;              //透明度 ,上述中也用到了 
}; 

2.表面着色器必须放在SubShader块内,而不是指定在某个pass内,因为,表面着色器将在多重通道内编译自己。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值