PixelShaderOutput PixelShaderFunction(MTVertexToPixel PSIn) { PixelShaderOutput output; // Texture planar projection calculations float3 blend_weights = abs(PSIn.Normal); // Start with normal passed in. blend_weights = (blend_weights - 0.2); // Tighten up the blending zone. Original GPU Gems muls by 7 arbitrarily. blend_weights = max(blend_weights, 0); //Eliminate any negatives. blend_weights /= (blend_weights.x + blend_weights.y + blend_weights.z ).xxx; // original planar texture mapping way. // output.Color = tex2D(TextureSampler0, PSIn.TextureCoords.xz)*PSIn.TextureWeights.x; // output.Color += tex2D(TextureSampler1, PSIn.TextureCoords.xz)*PSIn.TextureWeights.y; // output.Color += tex2D(TextureSampler2, PSIn.TextureCoords.xz)*PSIn.TextureWeights.z; // output.Color += tex2D(TextureSampler3, PSIn.TextureCoords.xz)*PSIn.TextureWeights.w; float4 cXY; float4 cXZ; float4 cYZ; cXY = tex2D(TextureSampler0, PSIn.TextureCoords.xy); cXZ = tex2D(TextureSampler0, PSIn.TextureCoords.xz); cYZ = tex2D(TextureSampler0, PSIn.TextureCoords.yz); output.Color = (cXY*blend_weights.z + cXZ*blend_weights.y + cYZ*blend_weights.x) * PSIn.TextureWeights.x; cXY = tex2D(TextureSampler1, PSIn.TextureCoords.xy); cXZ = tex2D(TextureSampler1, PSIn.TextureCoords.xz); cYZ = tex2D(TextureSampler1, PSIn.TextureCoords.yz); output.Color += (cXY*blend_weights.z + cXZ*blend_weights.y + cYZ*blend_weights.x) * PSIn.TextureWeights.y; cXY = tex2D(TextureSampler2, PSIn.TextureCoords.xy); cXZ = tex2D(TextureSampler2, PSIn.TextureCoords.xz); cYZ = tex2D(TextureSampler2, PSIn.TextureCoords.yz); output.Color += (cXY*blend_weights.z + cXZ*blend_weights.y + cYZ*blend_weights.x) * PSIn.TextureWeights.z; cXY = tex2D(TextureSampler3, PSIn.TextureCoords.xy); cXZ = tex2D(TextureSampler3, PSIn.TextureCoords.xz); cYZ = tex2D(TextureSampler3, PSIn.TextureCoords.yz); output.Color += (cXY*blend_weights.z + cXZ*blend_weights.y + cYZ*blend_weights.x)*PSIn.TextureWeights.w; (etc...)

This is definitely simpler, but there are some interesting bits. In the original bit that tightens up the blend zone

blend_weights = (blend_weights - 0.2) * 7;

Ryan Geiss of Nvidia adds the arbitrary multiplication by 7. Removing that, or changing it to 1000... doesn't seem to make a difference, so I removed it. In any case I can't see any visual difference (and there shouldn't be any, I should think, as you basically normalize the blend values shortly thereafter).

One other thing I am curious about was the color multiplication. There he did:

blended_color = col1.xyzw * blend_weights.xxxx +

col2.xyzw * blend_weights.yyyy +

col3.xyzw * blend_weights.zzzz;

I'm curious why he did 'col1.xyzw * blend_weights.xxxx' rather than simply 'col1 * blend_weights.x'. Possibly this is quicker somehow (avoiding any type of casting or type checking)? In any case I simply did the latter and it seems to work fine.

I decided to test my changes this with a worst-case texture, so I grabbed a brick texture and replaced the basic grass with it. Looks to be working pretty well so far:

Back to the normal textures looks good, too:

## No comments:

## Post a Comment