You copied the Doc URL to your clipboard.

The WorldSpaceNormalCreator shader

The shader code that implements the conversion is quite straightforward. Instead of using the actual vertex position, it uses the texture coordinate of the vertex as its position. This causes the object to be projected onto a 2D plane, the same as when texturing.

To make the OpenGL pipeline work correctly, the UV coordinates are moved from the standard [0,1] range to the [-1,1] range and invert the Y coordinate. The Z coordinate is not used so it can be set to 0 or any value within the near and far clip planes:

output.pos = half4(input.tex.x*2.0 - 1.0,((1.0-input.tex.y)*2.0 - 1.0), 0.0, 1.0);  		
output.tc = input.tex; 

The normal, tangent and bitangent are computed in the vertex shader and passed to the fragment shader to execute the conversion:

output.normalInWorld  = normalize(mul(half4(input.normal, 0.0), _World2Object).xyz);
output.tangentWorld   = normalize(mul(_Object2World, half4(input.tangent.xyz, 0.0)).xyz);
output.bitangentWorld = normalize(cross(output.normalInWorld, output.tangentWorld) 
					* input.tangent.w); 

The fragment shader:

  1. Converts the normal from tangent space to world space.
  2. Scales the normal to the [0,1] range.
  3. Outputs the normal to the new texture.

The following code shows this:

half3 normalInWorld = half3(0.0,0.0,0.0);
half3 bumpNormal = UnpackNormal(tex2D(_BumpMapGlobal, input.tc));
half3x3 local2WorldTranspose = half3x3( input.tangentWorld,
                                        input.bitangentWorld,    
                                        input.normalInWorld);
normalInWorld = normalize(mul(bumpNormal, local2WorldTranspose));
normalInWorld = normalInWorld*0.5 + 0.5;
return  half4(normalInWorld,1.0); 

The following image shows a tangent space normal map before processing:

Figure 5-90 Original tangent space normal map


The following image shows a world space normal map generated by the tool:

Figure 5-91 Generated world space normal map


Was this page helpful? Yes No