Bi-Directional Texture Function Results and Problems

I worked through one of the tutorials on GPU Gems 2. It's titled "Approxmiate bi-directional texture functions", by Jan Kautz.

It's discussed in his paper "Decoupling BRDFs from Surface Mesostructures", which is easily found on google.

Basically, it involves taking a series of photos of a material at differnet lighting angles and using the series of photos to form a 3D texture. During rendering, the phong equation is evaluated and the photo with the closest average brightness is chosen as the texture to be sampled. In a way, it's using a dozen of the same textures (but lit under different conditions) to do texturing rather than one.

I followed the idea, make the 3D texture, loaded into Rendermonkey and modified the Phong shader to do texture sampling from a texture volume. It worked and it's pretty cool. But there are some issues.

First a comparison between Phong lit texture mapping vs. bi-directional texture functions:

Phong
-------
Phong.jpg


BTF
----
BTF.jpg


As you can see the grooves on the cloth is much more pronounced and the image is brighter overall. You can also almost get a 'feel' for the texture, which is always nice.


At certain angles however, the moire is intolerable:
btf.jpg


This is what happens if I try to apply filtering in rendermonkey:
filtered.jpg


It garbles up everything.
 
Last edited by a moderator:
(Continued due to image limit):

This is what happens if I get too close to the object:
problem.jpg

The banding seems to be caused by not blending between the different layers within the 3D texture. How could I enable triliear filtering for 3D textures?

I'd love to upload the rendermonkey file for you guys but the 3D texture (1024x1024x8) is 26MB.

But do leave your thoughts. :)
 
Have you set the D3DSAMP_MAGFILTER, _MINFILTER and _MIPFILTER states of the texture object to (at least) D3DTEXF_LINEAR? (assuming you're using a D3D effect)

The moiré is already intolerable on the first two images. Have you tried D3DTEXF_ANISOTROPIC for _MINFILTER and _MAGFILTER, plus setting _MAXANISOTROPY to 16?
 
Xmas,
I have tried enabling those filtering options you suggested. The second last image I posted is its result.

A problem is that slanted surfaces such as the lid of the teapot is excessively blurred. This shouldn't be.

But the bigger problem is that the lighting is wrong. You can tell in that picture that regions such as the bottom of the teapot are getting brighter. This is because the texture sampler is wrapping the coordinates so that values less than 0.0 end up using 1.0 instead.

Now I have tried to clamp this but this has just revealed more problems.

My images are arranged from 0 to 7 such that image 0 is the darkest and image 7 is the brightest. My understanding is that a texture coordniate for W (the layer dimention in a 3D texture) is set to 0.0, it should index the first image and 1.0 should index the 7th. It doesn't seem to work this way. I have tried rendering the teapot using values from 0.0 to 1.0 and both 0.0 and 1.0 map to the darest image, image 0. A coordinate of 0.8 seems to use the brighest image. At 0.9, it's already darker. It's pretty baffeling. It also means clamping is not working since a value greater than 1.0 (something very bright) is getting mapped to 1.0, which somehow indexes image slice 0, my darkest image.

Where can I get some better understanding of how D3D is treating these volume texture layers?

I've also tried implementing this in OpenGL. It's got the same issues. A big specular highlight ends up being rendered as a dark patch.
 
JF_Aidan_Pryde said:
Xmas,
I have tried enabling those filtering options you suggested. The second last image I posted is its result.

A problem is that slanted surfaces such as the lid of the teapot is excessively blurred. This shouldn't be.
MAXANISOTROPY is set to 16? And you don't force AF in the CP?

My images are arranged from 0 to 7 such that image 0 is the darkest and image 7 is the brightest. My understanding is that a texture coordniate for W (the layer dimention in a 3D texture) is set to 0.0, it should index the first image and 1.0 should index the 7th. It doesn't seem to work this way. I have tried rendering the teapot using values from 0.0 to 1.0 and both 0.0 and 1.0 map to the darest image, image 0. A coordinate of 0.8 seems to use the brighest image. At 0.9, it's already darker. It's pretty baffeling. It also means clamping is not working since a value greater than 1.0 (something very bright) is getting mapped to 1.0, which somehow indexes image slice 0, my darkest image.
The texel center for the k'th texel in one dimension is always at (k + 0.5) * (1 / texsize) in D3D. So for your eight slices, you need to use 1/16, 3/16, 5/16, etc. for the W texture dimension.

If you imagine your texels as squares or cubes, you have to hit the center to get exactly that texel value with filtering. At 0, you are exactly at the left border of the leftmost texel, while 1 means the rightmost border of the rightmost texel.
 
Back
Top