Unity3d Shaderlab Diffuse reflectance convolution illumination model
The diffuse convolution "diffuse convolution" is the process of a fuzzy cube that retains the overall illumination intensity of the cubic graph, blurring only the details.
This effect is useful when we want to live a more global illumination surface effect.
to achieve this effect, we need to create a cubic diagram of the convolution operation. such as ATI 's tool making Cubemapgen.
:
http://developer.amd.com/tools-and-sdks/archive/legacy-cpu-gpu-tools/cubemapgen/
After installation, we configure the map through the loadbasemap,loadcubemap in the upper right corner, setting the filtertype,Filter Angle Click the Filtercubemap button in the lower right corner after the parameters .
Wait a minute and you'll be able Filter Finish, click Save CubeMap to Images button, you can save our cube chart.
Then there is the new Shader,Material. Double-click the script to count into the editor mode.
1> Modify 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> modifying subshader variables
Cgprogram #pragma surface surf diffuseconvolution#pragma target 3.0 Samplercube _cubemap;sampler2d _ Bumpmap;sampler2d _aomap;float4 _maintint; float _specintensity; float struct Input {float2 uv_maintex;float2 uv_aomap;float3 worldnormal;internal_data};
We need the model's world normals , so join internal_data. Because the shader contains a normal map, we use it to get the modified normals.
3> Complete the illumination function
Inline fixed4 lightingdiffuseconvolution (surfaceoutput s,fixed3 lightdir,fixed3 Viewdir,fixedatten) {//calculate the light vector;Viewdir=normalize (viewdir); Lightdir=normalize (lightdir); S.normal=normalize (s.normal);floatNdotl =dot (s.normal,lightdir); FLOAT3 Halfvec= Normalize (lightdir+viewdir);//Calculate high light;floatSpec = POW (dot (s.normal,halfvec), s.specular* -)*S.gloss;//The illumination model assigns the value;fixed4 C;c.rgb= (S.albedo*atten) +SPEC;C.A=1;returnC;}
4>surf Handling Stickers
void== = = = (c.rgb*diffuseval) * == _ specintensity*= c.a;}
After the illumination function is completed, the world normal of the model is used to map the cubic graph after the convolution, and then the result is passed to the output structure body.
Return to the Unity editor with the final effect as follows:
Using the above function, we first get the world normal of the model modified by the normal map, and use the normal data to find the position on the cubic chart to get his pixel and color.
That's what we're going to do in Input structure weight statement float3 worldnormal, and internal_data reason.
then we use Worldnormalvector function to get the final normal vector, and to Texcube the search.
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 $Cgprogram#pragmaSurface Surf Diffuseconvolution#pragmaTarget 3.0Samplercube _cubemap; Sampler2d _bumpmap; Sampler2d _aomap; FLOAT4 _maintint; float_specintensity; float_specwitdth; structInput {float2 Uv_maintex; FLOAT2 Uv_aomap; FLOAT3 Worldnormal; Internal_data}; Inline fixed4 lightingdiffuseconvolution (surfaceoutput s,fixed3 lightdir,fixed3 Viewdir,fixedatten) { //calculate the light vector;Viewdir =normalize (Viewdir); Lightdir=normalize (Lightdir); S.normal=normalize (s.normal); floatNdotl =dot (s.normal,lightdir); FLOAT3 Halfvec= Normalize (lightdir+Viewdir); //Calculate high light; floatSpec = POW (dot (s.normal,halfvec), s.specular* -)*S.gloss; //The illumination model assigns the value;fixed4 C; C.rgb= (S.albedo*atten) +spec; C.A=1; returnC; } voidSurf (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"}
Unity3d Shaderlab Diffuse reflectance convolution illumination model