Advertisement

Anisotropic mipmapping with tex2Dlod for equirectangular environment?

Started by July 01, 2019 04:02 PM
3 comments, last by MJP 5 years, 7 months ago

I'm playing with equirectangular environment maps in a DX9 framework and am curious about proper sampling.  Any help is appreciated.

So an equirectangular map represents 360 degrees in X axis but only 180 degrees in Y axis.  If I sample a mip map, I'm going to get a box blur that's effectively stretched in the X axis.  And it looks like I need to figure out my own miplevels and use tex2Dlod to avoid seaming problems.

Is there a way to do anisotropic mipmapping with a tex2Dlod so that I can get the hardware to "stretch" the texture for me, in order to get a more appropriate aspect on the sample?

I'm curious too-- if this is possible, could it be used (with multiple, rotated copies of a texture) to approximate a tunable Gaussian blur?

anisotropicbox.thumb.png.13adf63e11252b34532641231d736833.png

 

It seems like you could do a lot to eliminate box blur artifacts, and with the ability to set different radii, two independently, seems like it might be sufficient for real-time environment map filtering.  Seems like it could potentially be done in hardware from a single texture instance as well.

tex2Dlod will never give you anistropic filtering, since you're explicitly specifying a single mip level. For AF to kick in you need a pair of gradients/mip levels where the values don't match. This will happen naturally if you use a sampler state with AF enabled and allow the hardware to automatically pick your mip levels based on your UV gradients. Basically the hardware will generate two separate mip levels based on the U and V gradients and then take multiple samples if there is any "stretching". You can also manually supply U and V gradients using tex2Dgrad, but I don't see why that would be necessary in this case.

You can try to abuse AF to do custom filters and such, and in theory it should work. But in practice the IHV's like to play fast and loose with the spec in order to improve performance, which can lead to unpredictable results across different video cards. So you probably don't want to go down that road.

Advertisement

When I just use tex2D and let the hardware do the mip, I get a nasty seam:

 

image.png.96e2d07ac26add00d9ef8ed34573a1d2.png

 


	texture2D envTex <
    string ResourceName = ENVTEX;
>;
	sampler envSamp = sampler_state {
    texture = <envTex>;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
    MIPFILTER = LINEAR;
    AddressU  = WRAP;
    AddressV = CLAMP;
};
	...
	
float2 vecToLatLong(float3 inp)
{
    float lat = (normalize(float3(inp.x, inp.z, 0))).x;
    lat = acos(lat);
    lat = remap(lat, 0, PI, 0, 0.5f);
    lat = lerp(lat, 1.0f-lat, inp.z<0);
    
    float long = acos(inp.y);
    long = remap(long, 0, PI, 0, 1);
    
    return float2(lat, long);
    
}
	
float4 BufferShadow_PS(BufferShadow_OUTPUT IN, uniform bool useTexture, uniform bool useSphereMap, uniform bool useToon) : COLOR
{
	    float3 normal = normalize(IN.Normal);
    float3 eye = normalize(IN.Eye);
	    float3 diffUV = normal.xyz;
    diffUV.xy = vecToLatLong(diffUV.xyz);
    float4 envColDiff = tex2D(envSamp, diffUV.xy);
    return envColDiff;
    
}
	

Artifact disappears when point sampling or using tex2Dlod, and Googling finds people telling me I have to adjust the mip, which makes sense-- there's a fragment where I'm stretching all the way across the texture.

 

But maybe there's some other trick?  I don't know.  (Beyond the fact that my trig is always kind of held together with string and chewing gum.)

 

Thanks for hint regarding tex2Dgrad, I'll look into that.  I'm still a HLSL baby, I just get into it when modelling inspiration isn't hitting :)  Thanks for advice regarding AF and hw, nice to have a heads up for those kind of issues, but I'll probably still play with it, I'm just making things for myself mostly.

Ahh I see what you mean now. So that's happening because there's discontinuity in your function that produces your equirectangular UV mapping from the direction vector. You'll end up with neighboring pixels in the quad where some are at U = 1.0 and the others are at U = 1.0, which causes the screen-space derivative to be really high causing a low-resolution mip level to get selected. tex2Dlod sidesteps this issue since you're overriding the hardware's mip level selection, but then you'll want to be sure to that you're at least roughly matching your selected mip level to the projection of the texels onto the screen.

Ideally you would fix this by somehow removing the discontinuity in your UV calculation. There may already be a trick for doing that with equirectangular mapping, but you could probably also detect the discontinuity by looking a the derivatives of U in screen space (using ddx() and ddy()), and then "fix up" the gradients that you then pass to tex2Dgrad.

This topic is closed to new replies.

Advertisement