Archived

This topic is now archived and is closed to further replies.

Making Flares (D3D)

This topic is 6365 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Now I''m talking about general flares not lensflares. It''s as easy as making particles actually flare is one big particle (2 bilboarded triangles with texture). But there is a problem concerning drawing these flares and i''m curious to know if someone has developed a way to go around this: Flares should be drawn without zbuffer otherwise you can see flares clipping to the objects which doesnt happen at all in real life. But... the flare can be seen if and only if the center point of the flare can be seen. So the problem is how to deternime if the flares centerpoint is behind an object or not. ( I have heard a rhumour that John Carmack removed the flares from quake3arena because they killed the performance (he was using some sort of raytracing technique) so if you can overcome this problem with small performance lost then you can consider yourself as a pro

Share this post


Link to post
Share on other sites
I''d do it similar, trace a line from center of camera to center of flare, and check if it collides with any object. This shouldn''t be too slowly, but just theory, I don''t use flares, but raytracing is (to my knowledge) relatively fast and accurate if done properly.

Share this post


Link to post
Share on other sites
Hmmm.... try this, maybe:
Transform the flare source point manually. Now you''ve got an xyz position, with the Z being some floating point between 0.0 and 1.0.

The tough part is this: You need to see what that number is when it gets written to the Z buffer. I don''t know how you would do this, but you need to know that, say, 0.658374 is actually written into a 16-bit Z buffer as 17831.

Once you do that, take the value in the Z buffer at that XYZ position (by locking the z buffer surface and grabbing a ''pixel''). If the value that''s already in the Z buffer is greater than the manually transformed z buffer position, your flare would be visible. Render it.

Anyone know if there''s a DirectX or OpenGL method for figuring out what the ''real'' Z value is for a given floating point number?



-- Goodlife

-----------------------------
Those whom the gods would destroy, they first drive mad.
--DirectX design team official motto

Share this post


Link to post
Share on other sites
Could you not draw the rest of the scene using a z-buffer and then test the center point of the flare against that z-buffer to determine whether it is visible or not? Seems like a simple way of doing it and all you need to do is make sure to draw all your flares last.

Share this post


Link to post
Share on other sites
I just went stalking through the directx SDK, and it says that the Z buffer values will depend on the hardware manufacturer or method used. So, you can''t very easily find out whether a Z position is occluded or not, given a floating point value.

The only thing you could do is render a single point into the Z
buffer (perhaps completely transparently) and stash the previous Z buffer value somewhere. Then see if the rendered value is not clipped by the previous value, and draw accordingly. Does this make sense?

Psuedocode:

IsFlareVisible() {
...Transform ''flare point''
...Lock Z Buffer
...Get Z buffer value from transformed flare point''s x,y
...Render the flare center as a completely transparent vertex
...Get the Z buffer value from the transformed flare point''s x,y
...Unlock the Z buffer
...If the rendered point is less than the previous value, render the flare
}




-- Goodlife

-----------------------------
Those whom the gods would destroy, they first drive mad.
--DirectX design team official motto

Share this post


Link to post
Share on other sites
The answer here is very simple. Always render your transparent stuff using read-only zbuffer. So if your particle is behind a rock or a wall, it won''t be drawn, but if its in front of a wall it''ll get drawn properly. Now, note this can still cause rendering problems. What if you draw the particle but then at a later point you draw something _behind_ the particle? It looks completely wrong. So a more complete solution is :

- draw all your non-transparent stuff first using full-zbuffer
- draw all your transparent stuff last, using read-only-zbuffer

And for extreme "correctness"

- draw all your non-transparent stuff first, using full zbuffer
- _sort_ all of your transparent polygons from back to front
- render all the transparent polygons using read-only zbuffer.

Voila, problem solved.

Share this post


Link to post
Share on other sites
Skinkage:
Well tell me how to test this center point against zbuffer
in direct3d?

Goodlife:
Yes the zbuffer method would be the best if It wouldn''t be
allmoust impossible to read values from zbuffer because
the formats varies by card manufacturers like sdk help says.

daveb:
Actually you didn''t solve the problem. Your method can
cause partyally seen flares which doesn''t look very good.
What I want here is to draw full flare infront of any objects if
the flares center point can be seen from the camera.

For everyone interested: I know there must be a way
because I have seen demos made with direct3d which have
had correctly working flares so keep on researching



Share this post


Link to post
Share on other sites
Ok then. Here''s how to do it. Just use the Direct3DDevice::ComputeSphereVisibility function with a very small sphere where your flare is. Look in the help file--one of the possible return values is D3DSTATUS_ZNOTVISIBLE if you have z-checking enabled. Hope that helps.

Share this post


Link to post
Share on other sites
I'm sorry to burst you bubble here, but D3DRENDERSTATE_ZVISIBLE isn't supported anymore. So you can't use this technique either.

I have two ways that I recommend trying:

1. If you only have a few flares to render, then use raytracing to see if they are obscured. This shouldn't degrade your perforance too much if you are using datastructures like BSP, Octree and/or portals for your levels.

2. If you have many flares that needs to be rendered, then you might try this: Render your scene as normal, then enable stencil buffering and render point vertices where the flares are. If the flares aren't obscured the pixel in the stencil buffer will be set. After all point vertices have been rendered read the stencil buffer from the 3D card (this is the real bottleneck of this technique) and then check if the positions of the flares are set or not.

- WitchLord

Edited by - WitchLord on July 13, 2000 3:01:53 PM

Share this post


Link to post
Share on other sites
I think my solution is a little similar to Witchlords.

Draw your normal objects first. After that, you draw a point. Check if it is visible using the d3drenderstate LASTPIXEL (or something) and checking if the point is the same color as the point you set. Also remember to turn off fog when doing this.

Is that clear?

------------------------
Captured Reality

Share this post


Link to post
Share on other sites
I think that Shinkage and WhichLord are both right.

The simplest way to test for a point''s visibility is probably to let D3D do it for you with a call to ComputeSphereVisibility using a sphere with a very small radius (or 0 if it will work, but it may not). A return value of D3DSTATUS_ZNOTVISIBLE will indicate if the point is in the view frustum but not visible due to Z Buffer checking.

Whichlord is correct that the D3DRENDERSTATE_ZVISIBLE (which is a renderstate) is no longer supported, but that''s not the same as D3DSTATUS_ZNOTVISIBLE (which is a return code from ComputeSphereVisibility).

The only (very minor) drawback that I see to this method is that the entire ComputeSphereVisibility call appears to have been removed in DX8.

...Syzygy

Share this post


Link to post
Share on other sites
Why I said it wont work because of D3DRENDERSTATE_ZVISIBLE is because it needs to be set if D3DSTATUS_ZNOTVISIBLE is to work. It says so in the docs.

And Shinkage, I''m not sure if D3DRENDERSTATE_ZVISIBLE was ever supported by the hardware. That is the reason Microsoft removed the support for it in DX (I think).



- WitchLord

Share this post


Link to post
Share on other sites
My mistake.
I didn't realize that there was such a difference between "z test" (D3DRENDERSTATE_ZENABLE) and "z-checking" (D3DRENDERSTATE_ZVISIBLE). It's unclear to my why this feature using simple depth buffering, but I made a little test program and WitchLord is absolutely right -- D3DSTATUS_ZNOTVISIBLE is never returned.

Edited by - syzygy on July 14, 2000 3:45:32 AM

Share this post


Link to post
Share on other sites
quote:
Original post by ImNotTheOne

nes8bit:
D3DRENDERSTATE_LASTPIXEL
FALSE to enable drawing the last pixel in a line or triangle. The default value is TRUE.



* nes8bit slaps forehead
See kids...this is why you research before you reply

------------------------
Captured Reality

Share this post


Link to post
Share on other sites
As it is said, it''s nearly impossible to use direct Z-BUFFER values to compare them with C++ operators. But let then use D3D doing this with its Z-test functions.
Formats make us impossible to say if it is less or greater, but we can say if a value is DIFFERENT from another ( according to bit depth ).
There is GodLife algorihtm, with modifications :


Psuedocode:

IsFlareVisible() {
...Transform ''flare point''
...Lock Z Buffer
...Get Z buffer value from transformed flare point''s x,y
...Unlock the Z buffer
...Render the flare center as a completely transparent vertex
...Lock Z Buffer
...Get the Z buffer value from the transformed flare point''s x,y
(...Unlock the Z buffer)
...If the rendered point is DIFFERENT FROM the previous value, THEN D3D DOESN''T HAS FOUND A PIXEL BETWEEN THE FLARE AND THE VIEWER, AND YOU render the flare ( DON''T FORGET TO RESTORE OLD Z-VALUE ); IF THE Z-VALUE IS NOT ALTERED BY OLD VALUE, THERE IS SOMETHING BEFORE THE FLARE, STOP HERE.
}


-- Goodlife + TETRONICS

Just a problem : if the flare is on a previously rendered polygon...

( One good demo to see flares ? Unreal Tournament Demo ! )

Share this post


Link to post
Share on other sites