Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / Old-ish DBP texturing bug - blue outline

Author
Message
Lampton Worm
22
Years of Service
User Offline
Joined: 4th Sep 2002
Location: United Kingdom
Posted: 18th Feb 2006 01:32 Edited at: 18th Feb 2006 02:08
Hi,

I remember getting this in DBP a while ago, but I think it was sorted out. Anyway, check the attached, I have a texture with alpha overlapped onto another one, check out the outline... any ideas how to fix it? I tried messing with the transparency flags but no go at this point, and also with backdrop on/off and various flags on the image load.

Here's a snippet:



..and image attached,

Cheers

Attachments

Login to view attachments
Kaiyodo
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: UK
Posted: 18th Feb 2006 20:55
Well you can 'fix' it in a couple of ways, creating the objects in the opposite order (i.e. just copy the block of code that creates plane 1 under the code that creates plane 2), or you could set dbDisableObjectZRead() on both your objects.

Both of these methods will fall over if you decide you want to move the camera about though. For transparent objects to work properly (and by transparent I mean ones with a proper alpha channel, not single a single transparent colour) you need to draw the objects in reverse Z order after all of the non-transparent objects have been drawn. Unfortunately DB doesn't let you control this as far as I know, so transparency will never work properly in all situations. If anyone knows how to make it work then I'd be glad to hear too

Kaiyodo.
Barnski
18
Years of Service
User Offline
Joined: 26th Jan 2006
Location: Switzerland, Zurich
Posted: 18th Feb 2006 22:47
I wonder; is this an issue of Direct X in general, or just related to DBP (which would suggest that TGC implemented some functions not properly..)?

If the latter is the case, then this would be one of my major feature requests after the U6.0 has come out. Or what do you think..?

-- I just started with DarkSDK, by translating DBP Projects. --
Kaiyodo
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: UK
Posted: 19th Feb 2006 16:18
I suppose you could call it a DirectX issue, but it's more an issue of the interaction between alpha blending and zbuffers.

The blue outline is a consequence of the tree in front being drawn before the tree in the background. The alpha blended edges of the front tree write to the zbuffer even though they may be 'almost' completely transparent and so block out the pixels of the background tree when that comes to be rendered. The result is that you get the background showing through the edges.

There are many techniques to get around this: The easiest is to sort all of the transparent polys so they get drawn from back to front, however this is computationally very expensive. A good approximation can be achieved by sorting your transparent objects from back to front in Z order and drawing them after your opaque objects. It's not perfect, but it's normally good enough and it's a technique widely used in games.

If you're feeling technical then could have a look on Google for 'Depth Peeling' which is very expensive, but can give very good results.

Unfortunately as I've found, none of these are possible in DarkSDK as you have no control over the object draw order. I'd love a function dbRenderObject() which would allow me to control the draw order instead of leaving it to DarkSDK.

Sorted alpha blending has always been a problem since 3d hardware arrived. To my knowledge there was only one 3d card that ever did hardware alpha sorting and that was the old PowerVR (which was also the hardware used in the DreamCast). Pity it was a bit rubbish in all other respects really.

Anyway, I'll shut up now

Kaiyodo.
Barnski
18
Years of Service
User Offline
Joined: 26th Jan 2006
Location: Switzerland, Zurich
Posted: 19th Feb 2006 23:15
Thanks for sharing your knowledge Kaiyodo.

But there is one thing I don't understand; the graphic card seems to know which object is in front of an other one, I mean that's why it draws objects over others, isn't it... why doesn't the alpha blending work synchronously with that?!
This seems really strange to me...

-- I just started with DarkSDK, by translating DBP Projects. --
Kaiyodo
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: UK
Posted: 20th Feb 2006 16:48
The problem is that the graphics card only knows which pixels are in front of each other, it never had any concept of objects (it only gets list of triangles sent to it) it's up to the higher level code to determine which order the triangles get sent to the card.

The reason the PowerVR card managed to cope with sorted alpha blending was that it was a 'scene capture' card, meaning that all of the data was stored up before being rendered. When you have all of the data available you can do all sorts of clever stuff with it, including sorting all of the alpha triangles properly in hardware. The other 99% of graphics cards (and all current generation cards) use a more piecemeal approach to rendering: Each list of triangles it recieves (which roughly equates to an object in DB) it processes, draws on the screen, and then forgets about. All that remains of the object on the graphics card are a few pixels in the backbuffer and some entires in the zbuffer. Basically it doesn't have enough information by the time the next object comes 'round to drawing to sort it properly.

Kaiyodo.
Barnski
18
Years of Service
User Offline
Joined: 26th Jan 2006
Location: Switzerland, Zurich
Posted: 21st Feb 2006 00:31
If you have two objects (or two triangles) in a line (behind each other), then the graphic card will have to figure out what parts of which triangle is to be drawn, right?

How can the card start rendering if it hasn't yet got all the triangles... ?!hm, with help of that z-buffer thing? but then it will probably OVERDRAW a lot of already drawn pixels... and lose GPU cycles for nothing... strange approach! Ok but it would lose those GPU cycles anyway if it waits until all data has been passed through..

oh well, lets forget about this. I hope that they will look over the object draw order again.. maybe there IS something that can be done to improve alpha blending, even if its not perfect. but manually setting z-buffer flags and that stuff isn't really what leads to simple code that can easily be reused / enhanced...

-- I just started with DarkSDK, by translating DBP Projects. --
Kaiyodo
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: UK
Posted: 21st Feb 2006 15:38
If the graphics card had to wait for all of the triangles to be sent before it started rendering then it'd spend a lot of time twiddling its thumbs waiting. Once it's recieved a set of triangles it tries to render them as soon as it can so it always keeps busy.

The zbuffer prevents any overdraw by holding depth information for every pixel on the screen. Before a pixel is drawn it compares its z depth against the one already in the zbuffer. If the pixel is close it gets drawn, if it's further away it doesn't. This is exactly the behaviour that causes the blue outline with the trees.

The mostly transparent pixels in the foreground tree egde look at the zbuffer, see that it's empty and draw their pixels. When the background tree comes to draw it finds that there is already a closer entry in the zbuffer so it doesn't draw, even thought the pixel that was drawn is mostly transparent.

Alpha blending it a case where you actually want overdraw, you want the background to show through.

Kaiyodo.
Barnski
18
Years of Service
User Offline
Joined: 26th Jan 2006
Location: Switzerland, Zurich
Posted: 21st Feb 2006 17:42 Edited at: 21st Feb 2006 17:52
Well I first thought this too:
Quote: "
If the graphics card had to wait for all of the triangles to be sent before it started rendering then it'd spend a lot of time twiddling its thumbs waiting. Once it's recieved a set of triangles it tries to render them as soon as it can so it always keeps busy.
"


But I think there is a simple solution to this, namely pipelining:
While we retrieve the next set of triangles, we render the current set. or vice versa said: while rendering the current full set of triangles, we recieve the next full set of triangles... its quite the same as your description, and its using the same time, but does render everything in one go. after all there have to be calculated all triangles...
The use of the z buffer just makes the calculation smaller, I guess one could think of it as a "pre-result" that is stored and used for further computation. its easier math to project triangles and compare z buffer than to REALLY render a couple of triangles and determine the resulting POLYgon (note; poly can have more edges than just 3).

Still, I see no reason why z-buffering should prevent the card from correctly draw transparency. Why? well, if the pixel is transparent (meaning that at this rendered point the texture is black, or whatever color is set to be transparent) then it is just not drawn.

OK, you might say now, but you forget that the rendered triangle is not rendered 1:1, which means that the pixels on screen may represent several pixels on the texture (because of stretching, meaning the triangle is smaller, and / or not facing directly to the screen.
Well then, I answer, so I just store a third value for each pixel, the so called stencil buffer (I am purely guessing that this is the name for what I think of now ), which indicates that this pixel is semi-transparent. the color (first value) will then NOT be mixed with the background, but left to the color that the texture has there (without mixing it with the proper amount of black / background color). Getting complicated here, I admit, what do I do when another pixel is rendered above the just calculated one? well, I create a linked_list for that pixel. At the end, when everything has been rendered, I go through all pixels that have a linked list of transparency information (alpha is it called), and compute the final result for this pixel.

BANG! there you have that long waited fully functional and perfectly implemented transparency, alpha blending, and anti-aliasing effect!!! without any blue outline.

OK possible the use of the linked_list and its time overhead does prevent the graphic card industry to implement that approach (or maybe just because I lack crucial intellect and my here presented ideas are nothing else than pure, black, bull-ssssshh..)

Yea, but who knows that for sure

Btw, one year ago I was close to code a software 3d renderer, but we decided to make a Raytracer, since you get better looking result with also better render-speed... (if using mathematical describable objects, and not using 2 many triangles)

here you can have a look: http://www.buss.org


it was a project-contest that was part of our course, and well, yea, we won the contest

now enough credits for me, I already talked too much, maybe too much nonsence too, so I go away and learn for my exams

greets,
Barnski

*edit: hmmm btw, do the movies in the cookies section on the page for you also look wrong/comic stylish?? or is it just that I need to get the latest wmv decoder for my mediaplayer *
**edit2: no the files are OK, its just my win media player **

-- I just started with DarkSDK, by translating DBP Projects. --
Kaiyodo
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: UK
Posted: 21st Feb 2006 23:00
Quote: "Still, I see no reason why z-buffering should prevent the card from correctly draw transparency. Why? well, if the pixel is transparent (meaning that at this rendered point the texture is black, or whatever color is set to be transparent) then it is just not drawn."


What you're describing there is 1 bit transparency, just on or off, and that has no problems sorting. A completely transparent pixel doesn't write to the zbuffer so it won't cause any problems.

There are many ways to fix transparency, your version may work, but I got a little lost half way through your explanation (throwing the stencil buffer in there too was quite a surprise I'm just explaining how current hardware works, and the steps we have to use to get around its limitations.

I'll have a quick try at explaining why the zbuffer breaks transparency again ...

Pixel 'A' gets drawn at 1% alpha in the foreground, even though it's so transparent it's almost invisible it still has to write its z value into the zbuffer because it's not exactly 0% alpha. Pixel 'B' tries to draw in the background, checks its z against the value in the zbuffer and sees that a closer value is already in there (from pixel 'A'), it fails the ztest and doesn't get drawn. What's left on the screen at that point is 99% background and 1% of pixel 'A'.

Draw them the other way around and you'll see 1% pixel 'A' and 99% pixel 'B'. This time pixel 'B' passes the ztest because it got in before pixel 'A' set the zbuffer to a closer value. That's how we'd want it to look.

Good luck with the exams anyway, I won't take up any more of your time with my ramblings

Kaiyodo.
Zeal
22
Years of Service
User Offline
Joined: 10th Oct 2002
Location: Colorado Springs, CO
Posted: 16th Mar 2006 12:42
Good read!

So the standard way to do this in the 'real' world is to set the draw order of each object manually? I imagine this is done on a per object basis rather than per vertex/poly?

Why wouldnt DarkSDK do this automatically behind the scenese? I mean arent they already doing depth testing on objects? Or are all the objects being thrown at the video card in a completely random order?

All you need is zeal
Kaiyodo
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: UK
Posted: 17th Mar 2006 00:23 Edited at: 17th Mar 2006 00:24
You generally throw objects at the graphics card in the order that gets you the least shader/texture changes (i.e. draw all of the objects of the same texture in a group) as changing shader/texture is quite expensive.

The zbuffer will take care of the draw ordering of opaque objects for you. If you're drawing alpha blended objects of course, then performance comes secondary to making it look right and you'll want to be sorting by Z.

So yes, you generally have to sort your objects manually every frame (unless the camera never moves ) to get alpha blended objects to look right.

Kaiyodo.
LeeBamber
TGC Lead Developer
24
Years of Service
User Offline
Joined: 21st Jan 2000
Location: England
Posted: 21st Mar 2006 14:51
In U6 GDK, just use:

dbSetObjectTransparency(1,3);
dbSetObjectTransparency(2,3);

And DBP takes care of the Z-order rendering. It is a special transparency and sorting mode that takes care of things. Also, transparency mode of 4 will use an alpha test (draw or do not draw) which does not require the objects to be sorted, allowing polygons of the same mesh to interleave without the inter-mesh sorting issues (used in grass and tree tricks of modern games).

"Small, smart, and running around the legs of dinosaurs to find enough food to survive, bedroom programmers aren't extinct after all "
Lampton Worm
22
Years of Service
User Offline
Joined: 4th Sep 2002
Location: United Kingdom
Posted: 21st Mar 2006 16:05
Cheers Lee
Smithy
19
Years of Service
User Offline
Joined: 8th Dec 2004
Location: Switzerland
Posted: 22nd Mar 2006 09:20
Thanks Lee!

Oh and hopefully it will be described in the help files..?
(What mode uses what tests/techniques)

//Awards: Best DM at NeverwinterConventionIII (NWCon3)
//Sys: Pentium IV 3200E/Prescott;800Mhz FSB;HT;WinXPPro;ATIR9700PRO;1024MB RAM(2x512MB"DualChanneled";VC++7.net;Delphi6;ADSL512;
Kaiyodo
19
Years of Service
User Offline
Joined: 24th Aug 2005
Location: UK
Posted: 22nd Mar 2006 17:22
And maybe some enums/constants for the possible values too? It doesn't feel right to me passing random numbers into functions

I'd much rather have ..

dbSetObjectTransparency(1, SORT_TRANSPARENT);
dbSetObjectTransparency(1, SORT_TRANSPARENT_ALPHATEST);

Not a biggie though, I can always make them myself

Kaiyodo
Profit
18
Years of Service
User Offline
Joined: 19th Feb 2006
Location: United States
Posted: 22nd Mar 2006 23:14
I just want to make sure something, U6 GDK hasn't been released yet right?

common people are walking in line.
Miguel Melo
19
Years of Service
User Offline
Joined: 8th Aug 2005
Location:
Posted: 22nd Mar 2006 23:32 Edited at: 22nd Mar 2006 23:33
Quote: "I just want to make sure something, U6 GDK hasn't been released yet right?"


Sadly not... here's hoping.

I have vague plans for World Domination

Login to post a reply

Server time is: 2024-11-19 05:40:52
Your offset time is: 2024-11-19 05:40:52