标签:inpu 法线 分享 模糊 blog com 向量 .com unity3
http://www.cnblogs.com/2Yous/p/4251444.html
Unity3D ShaderLab 漫反射卷积光照模型
漫反射卷积【Diffuse convolution】是一个模糊立方体的过程,它保留了立方图的整体光照强度,只模糊了细节。
这种效果在我们要活得一个更具全局光照表面效果的时候非常有用。
为了实现这种效果,我们需要创建一个卷积运算的立方图。比如ATI的工具制作CubeMapGen。
下载地址:
http://developer.amd.com/tools-and-sdks/archive/legacy-cpu-gpu-tools/cubemapgen/
 
安装完毕后,我们通过右上角的LoadBasemap,LoadCubeMap配置贴图,在设置一下FilterType,Filter Angle等参数后点击右下角的FilterCubeMap按钮。
等待一会就可以Filter完成,点击Save CubeMap to Images按钮,就可以保存我们的立方体图了。
然后就是新建Shader,Material。双击脚本,计入编辑器模式。
1>修改Properties:
Properties {
_MainTint("Global Tint",Color)=(1,1,1,1)
_BumpMap ("Normal Map", 2D) = "bump" {}
_AOMap("Ambient Occlusion Map",2D)="white"{}
_CubeMap("Diffuse Convolution CubeMap",Cube)=""{}
_SpecIntensity("Specular Intensity",Range(0,1))=0.4
_SpecWitdth("Specular Width",Range(0,1))=0.2
}
2>修改SubShader变量
CGPROGRAM
#pragma surface surf DiffuseConvolution
#pragma target 3.0
 
samplerCUBE _CubeMap;
sampler2D _BumpMap;
sampler2D _AOMap;
float4 _MainTint;
float _SpecIntensity;
float _SpecWitdth;
 
struct Input {
float2 uv_MainTex;
float2 uv_AOMap;
float3 worldNormal;
INTERNAL_DATA
};
我们需要模型的世界法线,所以加入INTERNAL_DATA。因为着色器包含一张法线贴图,我们使用它获得修改后的法线。
3>完成光照函数
inline fixed4 LightingDiffuseConvolution(SurfaceOutput s,fixed3 lightDir,fixed3 viewDir,fixed atten){
//计算光照向量;
viewDir = normalize(viewDir);
lightDir = normalize(lightDir);
s.Normal = normalize(s.Normal);
float NdotL = dot(s.Normal,lightDir);
float3 halfVec = normalize(lightDir+viewDir);
//计算高光;
float spec = pow(dot(s.Normal,halfVec),s.Specular*128)*s.Gloss;
//光照模型赋值;
fixed4 c;
c.rgb = (s.Albedo*atten)+spec;
c.a = 1;
return c;
} 
4>surf处理贴图
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_AOMap, IN.uv_AOMap);
float3 normals = UnpackNormal(tex2D(_BumpMap,IN.uv_AOMap)).rgb;
o.Normal = normals;
float3 diffuseVal = texCUBE(_CubeMap,WorldNormalVector(IN,o.Normal)).rgb;
o.Albedo = (c.rgb*diffuseVal)*_MainTint;
o.Specular = _SpecWitdth;
o.Gloss = _SpecIntensity*c.rgb;
o.Alpha = c.a;
}
完成了光照函数后,使用模型的世界法线来对卷积后的立方图进行纹理映射,然后把结果传入output结构体。
返回Unity编辑器,最终效果如下:
 
通过上面的函数,我们首先得到被法线贴图修改后的模型的世界法线,并利用法线数据来查找立方图上的位置以得到他的像素和颜色,
这就是我们要在Input结构体重申明float3 worldNormal,以及INTERNAL_DATA原因。
然后我们使用WorldNormalVector函数来得到最终的法线向量,并用于texCUBE的检索。
Shader "91YGame/CubeMapLight" {
    Properties {
        _MainTint("Global Tint",Color)=(1,1,1,1)
        _BumpMap ("Normal Map", 2D) = "bump" {}
        _AOMap("Ambient Occlusion Map",2D)="white"{}
        _CubeMap("Diffuse Convolution CubeMap",Cube)=""{}
        _SpecIntensity("Specular Intensity",Range(0,1))=0.4
        _SpecWitdth("Specular Width",Range(0,1))=0.2
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf DiffuseConvolution
        #pragma target 3.0
        samplerCUBE _CubeMap;
        sampler2D _BumpMap;
        sampler2D _AOMap;
        float4 _MainTint;
        float _SpecIntensity;
        float _SpecWitdth;
        struct Input {
            float2 uv_MainTex;
            float2 uv_AOMap;
            float3 worldNormal;
            INTERNAL_DATA
        };
        inline fixed4 LightingDiffuseConvolution(SurfaceOutput s,fixed3 lightDir,fixed3 viewDir,fixed atten){
            //计算光照向量;
            viewDir = normalize(viewDir);
            lightDir = normalize(lightDir);
            s.Normal = normalize(s.Normal);
            float NdotL = dot(s.Normal,lightDir);
            float3 halfVec = normalize(lightDir+viewDir);
            //计算高光;
            float spec = pow(dot(s.Normal,halfVec),s.Specular*128)*s.Gloss;
            //光照模型赋值;
            fixed4 c;
            c.rgb = (s.Albedo*atten)+spec;
            c.a = 1;
            return c;
        } 
        void surf (Input IN, inout SurfaceOutput o) {
            half4 c = tex2D (_AOMap, IN.uv_AOMap);
            float3 normals = UnpackNormal(tex2D(_BumpMap,IN.uv_AOMap)).rgb;
            o.Normal = normals;
            float3 diffuseVal = texCUBE(_CubeMap,WorldNormalVector(IN,o.Normal)).rgb;
            o.Albedo = (c.rgb*diffuseVal)*_MainTint;
            o.Specular = _SpecWitdth;
            o.Gloss = _SpecIntensity*c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}
标签:inpu 法线 分享 模糊 blog com 向量 .com unity3
原文地址:http://www.cnblogs.com/alps/p/7112900.html