I have a planet terrain shader that perturbs vertex positions by using a 3D fractal noise lookup on a sphere as the heightmap. It works perfectly 99.9% of the time except for these bizarre glitch vertices that occasionally appear. It looks like a spike in the middle of the otherwise normal mesh.
I've narrowed it down to the trilinear texture lookups into the noise. The glitch always only affects a single vertex, smaller than a texel in size. It occurs consistently for the same position lookup in the texture
Annoyingly, my fractal lookup is pretty basic and after looking over this code and trying dozens of things I remain stumped to the cause. I suspect the problem must be some sort of glitch in the vertex shader trilinear filtering; I see few other possibilities at this point. Anyway, here's some pics of the glitch and the relevant code for the vertex shader (I omit the pixel shader for brevity).
#define textureSize 80.0
#define halfTexelSize 0.00625
#define texelSize 0.0125
texture NoiseRealVertex;
sampler3D NoiseRealVertexSampler = sampler_state {
Texture = <NoiseRealVertex>;
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
MinFilter = Point;
MagFilter = Point;
MipFilter = Point;
};
// Vertex Noise Functions
float4 tex3D_trilinear(float3 t)
{
t -= halfTexelSize.xxx;
float3 f = frac(t * textureSize);
float4 x = float4(t, 0);
float4 t000 = tex3Dlod(NoiseRealVertexSampler, x);
float4 t100 = tex3Dlod(NoiseRealVertexSampler, x + float4(texelSize, 0, 0, 0));
float4 t010 = tex3Dlod(NoiseRealVertexSampler, x + float4(0, texelSize, 0, 0));
float4 t110 = tex3Dlod(NoiseRealVertexSampler, x + float4(texelSize, texelSize, 0, 0));
float4 t001 = tex3Dlod(NoiseRealVertexSampler, x + float4(0, 0, texelSize, 0));
float4 t101 = tex3Dlod(NoiseRealVertexSampler, x + float4(texelSize, 0, texelSize, 0));
float4 t011 = tex3Dlod(NoiseRealVertexSampler, x + float4(0, texelSize, texelSize, 0));
float4 t111 = tex3Dlod(NoiseRealVertexSampler, x + float4(texelSize, texelSize, texelSize, 0));
return lerp(
lerp(
lerp(t000, t100, f.x),
lerp(t010, t110, f.x),
f.y),
lerp(
lerp(t001, t101, f.x),
lerp(t011, t111, f.x),
f.y)
, f.z);
}