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