Unity3D ShaderLab BRDF模拟

Unity3D ShaderLab BRDF模拟

在上一篇,说到了使用渐变纹理着色,使用一个值来控制纹理的uv坐标,但是这也就表示我们只能得到一个线性的光照效果。

那么我们能不能通过观察方向的向量结合光照方向形成双向的反射变化呢,既然说到这里,肯定是可以做到的,

这就是我们的BRDF effect,我们可以简单的把BRDF看作为入射光在不透明物体表面同时反射到观察方向和出射光方向。

BRDFBidirectional Reflectance Distribution Function具体的内容讲解,可以查阅百度百科。

光线照到一个物体,首先产生反射,吸收和透射,所以BRDF的关键因素即为多少光被反射、吸收和透射(折射)了,是怎样变化的,同学你的初中物理哦。

我们先讨论效果的模拟实现,如何利用多变的纹理来变化我们的模型效果。

 

开始code之前,我们需要一个多维度的渐变纹理,所以至少3个方向的渐变色域。

这一次,我们借用上一篇使用渐变纹理着色的codeBasicMyHalfLessDiffuse】,我们要把之前的inline float4 LightingHalfBRDFDiffuse(SurfaceOutput s,fixed3 lightDir,fixed atten)函数修改为4个参数

1>inline float4 LightingHalfBRDFDiffuse(SurfaceOutput s,fixed3 lightDir,half3 viewDir,fixed atten)

2:加入视角的观察方向参数>float rimLight = max(0,dot(s.Normal,viewDir));

3:修改通过txt2D()函数获得的rgb>tex2D(_BRDFTex,float2(halfLight,rimLight)).rgb;

 技术分享

上图就是我们修改完毕的光照模型函数了。那么最后的渲染结果是什么样的呢。

技术分享

请注意,_EmissiveColor,_AmbientColor都是白色哦。我们确实是借助图片的渐变色来实现而已,在上面的效果中,我们主要是展现了更多变的rgb对模型的渲染效果。

总结上面的过程,在我们使用观察方向参数时候,我们可以创建一个简单的衰减效果,我们可以通过不同的衰减的形式制作出各种效果。

由于rimLightdifLight的结果都是0-1,所以我们可以使用这两个值来选择渐变的不同区域。那么最关键的就是理解我们从点乘运算获得的值,以及如何控制纹理。

code start------------------------------------------------------------

 

Shader "91YGame/BasicMyHalfBRDFDiffuse" {
    Properties {
        _EmissiveColor("Emissive Color",Color) = (1,1,1,1)
        _AmbientColor("Ambient Color",Color)=(1,1,1,1)
        _MySliderValue("Slider Value",Range(0,10))=1.3
        _BRDFTex ("BRDF Texture", 2D) = ""
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        //#pragma surface surf Lambert
        #pragma surface surf HalfBRDFDiffuse

        float4 _EmissiveColor;
        float4 _AmbientColor;
        float _MySliderValue;
        sampler2D _BRDFTex;

        struct Input {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o) {
            float4 c;
            c=pow((_EmissiveColor+_AmbientColor),_MySliderValue);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }

        inline float4 LightingHalfBRDFDiffuse(SurfaceOutput s,fixed3 lightDir,half3 viewDir,fixed atten){
            float difLight = max(0,dot(s.Normal,lightDir));
            float rimLight = max(0,dot(s.Normal,viewDir));
            float halfLight=difLight*0.5+0.5;
            float3 bfColor = tex2D(_BRDFTex,float2(halfLight,rimLight)).rgb;
            float4 col;
            col.rgb = s.Albedo * _LightColor0.rgb*bfColor;
            col.a=s.Alpha;
            return col;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

code end--------------------------------------------------------------

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。