Unity Shaders and Effects Cookbook:使用2D渐变纹理模拟BRDF

发表于2017-11-24
评论0 809浏览

下面给大家介绍下使用2D渐变纹理模拟BRDF,BRDF,双向反射分布函数,简单理解为入射光在不透明物体上,同时反射到观察者方向和出射光方向。


首先用PS创建一个渐变图片,先用 前景色到背景色渐变 ,然后前景色到透明渐变。


上面也说了,BRDF 是入射光 同时反射到 出射光 和 观察者眼睛方向的,所以这里我们要选择 需要视角方向的前向着色


仍然以基本的漫反射光照模型为例,主要修改下面代码。

1、使用 需要视角方向的前向着色

//需要视角方向的前向着色  
inline float4 LightingBasicDiffuseWithViewDir(SurfaceOutput s,fixed3 lightDir,half3 viewDir,fixed atten)  
{  
    float difLight=dot(s.Normal , lightDir); //根据法线与光照方向的夹角计算cos值  
    float rimLight=dot(s.Normal , viewDir);  
    float hLambert=difLight * 0.5 + 0.5;  
    float3 ramp = tex2D(_RampTex,float2(hLambert,rimLight)).rgb;  
    float4 col;  
    col.rgb=s.Albedo * _LightColor0.rgb * (ramp);  
    col.a=s.Alpha;  
    return col;  
}  

2、指定光照模型
#pragma surface surf BasicDiffuseWithViewDir  

完整Shader代码:
Shader "CookBookShaders/BRDF" {  
    Properties {  
        _EmissiveColor("Emissive Color",Color) = (1,1,1,1) //设置默认值  
        _AmbientColor("Ambient Color",Color) = (1,1,1,1)  
        _PowValue("Power Value",Range(0,10)) = 2.5  
        _RampTex("Ramp Texture",2D) = "" //添加_RampTex属性接受一个Texture  
    }  
    SubShader {  
        Tags { "RenderType"="Opaque" }  
        LOD 200  
        CGPROGRAM  
        #pragma surface surf BasicDiffuseWithViewDir  
        float4 _EmissiveColor;  
        float4 _AmbientColor;  
        float _PowValue;  
        sampler2D _RampTex;  
        struct Input {  
            float2 uv_MainTex;  
        };  
        void surf (Input IN, inout SurfaceOutput o)   
        {  
            float4 c;  
            c=pow((_EmissiveColor+_AmbientColor),_PowValue);  
            o.Albedo = c.rgb;  
            o.Alpha = c.a;  
        }  
        //需要视角方向的前向着色  
        inline float4 LightingBasicDiffuseWithViewDir(SurfaceOutput s,fixed3 lightDir,half3 viewDir,fixed atten)  
        {  
            float difLight=dot(s.Normal , lightDir); //根据法线与光照方向的夹角计算cos值  
            float rimLight=dot(s.Normal , viewDir);  
            float hLambert=difLight * 0.5 + 0.5;  
            float3 ramp = tex2D(_RampTex,float2(hLambert,rimLight)).rgb;  
            float4 col;  
            col.rgb=s.Albedo * _LightColor0.rgb * (ramp);  
            col.a=s.Alpha;  
            return col;  
        }  
        ENDCG  
    }   
    //FallBack "Diffuse"  
}  

运行效果,右边的球就是BRDF效果,可以下载例子项目观看:


主要的是 我们使用了需要视角方向的前向着色,然后根据 法线 和 视角方向角度计算 COS 值 得到 rimLight ,以 hLambert 和 rimLight 作为UV值去采样,从而得到图中效果。


示例工程下载:http://pan.baidu.com/s/1dDNTotj

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论