[semi solved] volume textures

Jon

18-05-2007 23:01:04

While I'm not quite to the point of admitting defeat when it comes to variable sized textures and indexed splatting, I am taking some time to implement the volume texture approach.

256x256x256 RGBA should take about 64M of texture memory. And while this number of textures is excessive, it does seem quite doable on a variety of cards.

Somewhere along the line I decided I probably could do quite well with 256x256 textures, and the time to think about that restriction is after this splatting mode is working.

Now that the explanation of what and why is out of the way, I am running into problems with the volume textures. Given that I have no experience with them, this is expected, but I am hoping that someone will see the error of my ways.

The texture file is made from 16 png images, 256x256. I am using nvdxt to create a DDS file which looks fine when examined with the DirectX Texture Tool (from the SDK). Fine meaning there are 16 slices, and DXT5 compression is being used. I can move from slice to slice, and the textures are correct. (Note: for simplicity, the textures are uniform colors so I can tell what slice is being sampled).

Even better news is that when I use PIX to capture a frame, I can see the texture unit being loaded, and the texture attributes are correct. (Note: getting everyone to stop making mipmaps was a gotcha). Here is a screenshot from PIX so we can see what DirectX has loaded:



Note also: PIX has some nice features. Being able to browse the textures, and showing the floating point coordinates in the toolbar is an unexpected bonus.

So what happens? The wrong color is being returned by the fragment program, which in turn means the wrong color is being returned from the tex3D lookup. Now I cheated a little, and forced (0,0,0) as the volume coordinate to sample. That should be guaranteed to be a valid point, and a corner of the volume. Given uniform colors for the slices, there are only two colors which can be returned no matter how the volume is rotated.

The problem is: I get some oddball gray which is not in any of the slices, and certainly not the blue or yellow which are the first and last slices.

Ogre is loading the volume correctly, it is assigned to the correct sampler. The (0,0,0) coords are in fact being used for the lookup.

So I conclude that my understanding of what tex3D wants to see in a volume texture is wrong. Any suggestions?

Edit: of course the minute I post this I have a brainstorm and may have fixed things. Two problems:
1) I was missing the "tex_address_mode clamp" in the material for the volume
2) There appears to be an interpolation between slices, so an offset needs to be added to Z so that the height is midway between slice boundaries. For 16 slices, to get to slice 2 Z will be 1/16+1/32. The floating point color values are a little off, but the integer values look fine.

Time to investigate more complex textures to see if this interpolation is going to continue to be a problem.

Jon

18-05-2007 23:58:32

Here is a screenshot with 16 textures in a single pass:



Next I'd like to determine how much texture memory the volume texture is taking up.

Falagard

22-05-2007 20:45:52

Looks cool :-)
What does it look like with some real textures?

Jon

23-05-2007 04:00:20

I'll post some real screenshots after I've dealt with a problem which has finally pushed me over the edge.

I touched on this peripherally in another post, but the situation is far worse for me now than I mentioned. Paging is seriously messed up for me, with pages loading/unloading, unloading multiple times (= crash), not showing up when they should.

A couple of posts have mentioned problems with tile visibility, and I think this is related.

Obviously something I'm doing is different than what others are doing. The kicker is that I am running an almost stock demo application -- that is, I changed some of the key bindings and added an overlay. I have not touched any of the paging code. Well until now that is.

Forgive me if I seem overly cranky, but I've had it with these issues. It is hard to tweak a splatting mode when pages aren't being displayed.

So, everything went on hold until I can get to the bottom of what is going on.

The first discovery is that there were 3 (!) cameras active in the demo application, and they were fighting each other with visibility changes. I have moved some of this code into the scene manager, so that it can perform tests on *all* active cameras at once, rather than whatever camera is passed into updatePaging this week.

That was the good news. The bad news is that I keep hitting more wierd stuff, which puts me further behind. I have seen pages unloaded which do not have a Page Node. When I look at them in the debugger, they are not marked as loaded/preloaded/loading/preloading, but were on an unload queue before making their way to _uninit().

At one point I swear I saw a page unload twice back to back -- well the second unload hit an assert I added.

I wonder if my running around the map at warp speed is causing some of these problems. Pages may be getting placed on load queues and then move out of camera range before they are loaded. And stuff like that.

At the moment I am adding more logging to try to learn the sordid history of this page which is unloaded before it is loaded. Too bad I don't have a reliable way of reproducing this. But given about an hour of messing around I can usually hit the assert.

Falagard

23-05-2007 06:22:41

Why not work on your solution within the built in TerrainSceneManager in Ogre instead of PLM2 if you're having problems?

Whatever solution you come up with will work in both - at least the shader code and materials should, right?

Jon

23-05-2007 19:13:56

I'm not ready to give up on PLSM yet. My terrain generator is set up to work with PLSM, and I'd need to spend time changing that if I switched scene managers. Obviously there is a point where that becomes desirable.

I'd like a paging scene manager too. I believe we would agree that PLSM isn't really paging as a lot of data is held in memory during the entire run. But it might be easier to address those concerns with PLSM than to wedge paging into TSM.

Besides I tend to obsess on whatever problem I'm looking at, and this needs to be addressed sometime.

Today's discovery is that I can have pages loaded and visible, but not have the corresponding renderables on a render queue. In the following screenshot, the camera is on a page which is loaded and visible, walking the render queues in the debugger confirmed that the renderable was not queued.

Paulo

26-05-2007 20:38:21

Hello,

Because you seem otherwise occupied i decided to try getting some splats working with volume textures, i got everything working 100% in no time, went like a dream... untill i turned on filtering and mipmaping :shock:

I'm getting all kinds of problems between splats as it tries to filter between textures/mip map levels, and after hours of pulling my hair out and reading about it, it looks like its "impossible" to use mipmaps with volume textures in this way.

Apparently the same kind of problems with mipmaps appear when using a "Texture Atlas" instead of a volume texture.

Just wondering... do you know about these problems and have any kind of work around?

Jon

27-05-2007 00:09:17

I pulled my hair out as well, which is why I turned off filtering and mipmaps.

I started putting in the alpha blending, and discovered that texture coordinates are relative to the *page*. To verify this I walked around and dumped frame data when the tile coordinates changed. then compared them to the texture coordinates sent into the fragment program. The values reset to 0 as *pages* were crossed, and decreased by 1/8 as tile boundaries were reached (using 8x8 tiles on a page).

Trivia for some, but might be useful to others.

Note: I haven't heard anything back from my question in the main forum about meshes not being drawn. I can confirm that when there is a problem view frustum calculations look correct, tiles are loaded and visible, meshes are being sent to the GPU. The only thing odd was the ordering: most of the time meshes were sent by distance from the camera (back to front), but occasionally meshes were sent out of order.

Jon

27-05-2007 20:46:32

I think the shader compiler has a bug.

If I do something like this in a shader:

if (delta > 0)
{
value = 2.0;
}
else
{
value = 3.0;
}


3.0 is returned when delta > 0.

But... If I do the following:


value = (delta > 0) ? 2.0 : 3.0;


Then 2.0 is returned.

I see partial-precision math being performed in the "if" case. The : ? solution also takes about half the assembly instructions and does not use _pp. Maybe I'm misusing if() in some way, but the cG book doesn't draw a distinction.

Now I could change the pixel shader version to prevent _pp in the first place, but that isn't the point.