Texturing artifact of some kinds

Started by
5 comments, last by Warwick Michael Dumas 11 years, 8 months ago
Hi. I mentioned before my unconventional decision to use DX9 as a rendering platform. I've now all but completed this project but something does not look quite right. I'm drawing a dish which is yellow on the inside with purple outside it; the back of the dish shows a purple stripe, which it should not.

I tried it with two different sorts of meshes. One of them is with points arranged in concentric circles and an algorithm that basically sweeps anticlockwise over points on the previous (inner) circle to create triangles for each point on each circle.
The other is square mesh with two triangles per square. I always use this square mesh to define the texture dynamically, and it is defined in such a way that radially equal points always get the same colour.
I calculate vertex normals in the main program and light the vertices in a vertex shader. I also do shadow mapping in the pixel shader but I'm pretty sure that's nothing to do with the problem.

Here are some of my output avi files
'radial' mesh:
https://dl.dropbox.c...LARagain670.zip
'square' mesh:
https://dl.dropbox.c...totalperRow.zip
Those are both so high resolution that it's likely 1 triangle per pixel or more. That may have something to do with the problem although I don't see why it should do. It probably is best to focus attention on the cutaway animation - the lower one - but see also on the upper one, it can be seen that going upwards, the stripes form a sinusoidal pattern.

Here is a somewhat lower resolution mesh. There is some mistexturing probably because the wall of the dish is very thin. 'radial' mesh.
https://dl.dropbox.c...OLARagain50.zip

I tried to upload all the code, because I don't know which bit is relevant, but it says 'You aren't permitted to upload this kind of file'. Don't know why text files cause such umbrage but there you go.

Anyway maybe looking at this, someone will have some suggestion of what could be going wrong.
I've checked that the computed normals all have the same sign for the y-component, and tried inverting them. And I'm certain the texture doesn't have a bizarre purple region. I also can't believe it's meant to look this way with the lighting. I'm at my wits' end, any suggestions appreciated. smile.png
Advertisement
Do you use backface culling? If two triangles get too close together, the z-buffer stops being able to reliably tell which one is in-front of the other one.
It looks like your outside purple tri and your inside yellow tri are becoming almost equal, and the z-buffer isn't able to reliably determine that the yelllow one should be on top. However, if back-face culling was enabled, then the (backwards facing) purple triangle would be rejected before rasterization occurs.

P.S. D3D9 isn't an unconventional choice -- it's the only choice (aside from OpenGL) for targeting SM3.0 (360/PS3 era) GPUs, D3D11 does not have a feature level for this class of GPU, for some stupid reason...
I think you've got some z-fighting issues on the very thin regions. If this is a scientific application of some-kind then you may not be able to adjust values, but you could :

* increase the thickness to reduce z-fighting
* if you are using a 16 bit depth texture, increase it to 32 or 64 bit depth.
* make sure your near and far z's are as close to the geometry as possible, this spread's the geometries depth over the full range of the z-buffer.
* break up your geometry into inner and outer surfaces, so that you can sort them and then render them with the z-buffer turned off, so
1. render far outer surface .. 2 render far inner surface ... 3 render near inner surface ... 4 render near outer surface
or something like that, you'll probably have to consider the particulars of the geometry that can form to decide if and how it can be broken up like this.

edit : oh yeah, your're right Hodgman backface culling 8-. A lot easier.
Thank you both.
I had it set to not culling.
If I set
pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW);
then nothing happens, the mesh is not rendered
If I set
pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
then it's a significant improvement:
https://dl.dropbox.com/u/6773194/testPOLARagain670_CULLCCW.zip

I will look into the z-fighting and probably post again...
OK it definitely is z-fighting because I try SetRenderState( D3DRS_ZFUNC, D3DCMP_LESS ) and different bits go wrong.

I made another improvement by moving the far clipping frame from 5000.0f to 12.0f -- thanks for that.

It's still not perfect. smile.png

I tried to force a 32 bit depth buffer ...
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D32;
... but CreateDevice then failed.
But maybe this is likely to work if I just make it run fullscreen? I'd rather run windowed if I can do, but if needs must.

"1. render far outer surface .. 2 render far inner surface ... 3 render near inner surface ... 4 render near outer surface"
In general the data is not as simple as here, so I can't predict what areas have a particular depth.

"* if you are using a 16 bit depth texture, increase it to 32 or 64 bit depth."
It's 32-bit R8G8B8X8. I don't understand why the texture would make a difference though?

"* increase the thickness to reduce z-fighting"
I can't do it.

Seems quite strange that it insists on 16bit although the z coordinates of vertices are float ? I'm sure if I could get it to just stick to 32 bit instead of casting to 16 when it projects, it would be fine. And that seems like it must be the key to it, I don't think 65536 depth values is going to be enough.

What happens if I set
d3dpp.EnableAutoDepthStencil = FALSE;
--I have to manage my own z-buffering? It sounds like too much of a challenge? blink.png

I made another improvement by moving the far clipping frame from 5000.0f to 12.0f -- thanks for that.
What is your [font=courier new,courier,monospace]near[/font] value? The [font=courier new,courier,monospace]far[/font] value (is good to set correctly, but) isn't nearly as important as the [font=courier new,courier,monospace]near[/font] value -- to approximate, 50% of your depth values are distributed between [font=courier new,courier,monospace]near[/font] and [font=courier new,courier,monospace]2*near[/font], with the rest being spread between [font=courier new,courier,monospace]2*near[/font] and [font=courier new,courier,monospace]far[/font].

Regarding your auto-depth failing, try D24S8 instead of D32.
To create your own depth buffer manually, you use the [font=courier new,courier,monospace]CreateDepthStencilSurface[/font] function, usually with the format of [font=courier new,courier,monospace]D3DFMT_D24S8[/font], and then use [font=courier new,courier,monospace]SetDepthStencilSurface[/font] to activate/bind it.
D24S8 did it. Awesomeness.

The near value is 1.0f whereas my camera is at e.g. (3.5,5,-6) and the corner of the graph is at (3,,-3). I may well end up entering a formula for the near clipping frame value, because I might yet mess around with the camera position. But with 24-bit z buffer it does work fine anyway.

Cheers,

Warwick


This work helps to bring about focus fusion as a viable energy source.
www.focusfusion.org

This topic is closed to new replies.

Advertisement