My plant/bush type models have an annoying sparkling effect. I’ve seen this before and it’s usually when i’ve forgotten to turn on Mipmapping for the model’s texture.
It’s definitely on for these (clump of grass, bush, larger bush) but as you can see they sparkle annoying when you move away from them.
Here’s a Youtube video of the problem.
Initially I thought there was a problem with my instanced model shader for the grass but the larger bush is just a normal non-instanced render and still shows the same problem.
Maybe the sampler is wrong? I’m a bit stumped. I could add a depth of field or FXAA type post processing effect to hide it and maybe that’s what I’ll need to do.
Here’s the shader for the instanced models:
// Camera settings.
float4x4 World;
float4x4 View;
float4x4 Projection;
float3 DiffuseLight = 1.25;
float3 AmbientLight = 0.25;
bool Highlight = true;
texture2D Texture;
sampler2D Sampler = sampler_state
{
Texture = (Texture);
MinFilter = Anisotropic; // Minification Filter
MagFilter = Anisotropic; // Magnification Filter
MipFilter = Linear; // Mip-mapping
AddressU = Wrap; // Address Mode for U Coordinates
AddressV = Wrap; // Address Mode for V Coordinates
};
struct VertexShaderInput
{
float4 Position : POSITION0;
float3 Normal : NORMAL0;
float2 TextureCoordinate : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 TextureCoordinate : TEXCOORD0;
float2 Depth : TEXCOORD1;
float3 Normal : TEXCOORD2;
};
struct PixelShaderOutput
{
half4 Color : COLOR0;
half4 Normal : COLOR1;
half4 Depth : COLOR2;
};
// Vertex shader helper function shared between the two techniques.
VertexShaderOutput VertexShaderCommon(VertexShaderInput input, float4x4 instanceTransform)
{
VertexShaderOutput output;
// Apply the world and camera matrices to compute the output position.
float4 worldPosition = mul(float4(input.Position.xyz,1), instanceTransform);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);// Compute lighting, using a simple Lambert model.
float3 worldNormal = mul(input.Normal, instanceTransform);
//output.Normal = half4(worldNormal,0);
output.Normal = half4(input.Normal,0); //normalize(mul(input.Normal, (float3x3)World));
output.Depth.x = output.Position.z;
output.Depth.y = output.Position.w;
// Copy across the input texture coordinate.
output.TextureCoordinate = input.TextureCoordinate;
return output;
}
// Hardware instancing reads the per-instance world transform from a secondary vertex stream.
VertexShaderOutput HardwareInstancingVertexShader(VertexShaderInput input,
float4x4 instanceTransform : BLENDWEIGHT)
{
return VertexShaderCommon(input, mul(World, transpose(instanceTransform)));
}
PixelShaderOutput PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
PixelShaderOutput output;
float4 color = tex2D(Sampler, input.TextureCoordinate);
output.Depth = input.Depth.x / input.Depth.y;
if (color.a < 0.4)
discard;color.a = 0;
if (Highlight)
color.r *= 50.0f;
output.Color = color * 2.5f;
//output.Normal = half4(input.Normal,1);
// read the normal from the normal map
float3 normalFromMap = input.Normal;
//tranform to [-1,1]
//normalFromMap = 2.0f * normalFromMap - 1.0f;
//normalize the result
normalFromMap = normalize(normalFromMap);
//output the normal, in [0,1] space
output.Normal.rgb = 0.5f * (normalFromMap + 1.0f);
//specular Power
output.Normal.a = 1; //specularAttributes.a;
return output;
}
// Hardware instancing technique.
technique HardwareInstancing
{
pass Pass1
{
VertexShader = compile vs_4_0 HardwareInstancingVertexShader();
PixelShader = compile ps_4_0 PixelShaderFunction();
}
}