0

(C++) The title pretty much sums up it all;

I want to let a texture (or a sprite, or whatever) of a light be rendered in front of everything if a certain point in the 3D space is not hidden behind something else.

How do I do that? I can render it over everything by disabling the Zbuffer temporarily during the drawing process, but I don't know how to check if the point is being hidden.

Do I have to calculate some sort of collision between the point and the camera? Or will some kind of sprite setup make the trick?

Banderi
  • 656
  • 3
  • 7
  • 29

1 Answers1

1

If I understand your question, you want to render a 2D image in 3D space - with all the appropriate depth buffering.

I would use a "billboard". Just render a simple quad in 3D space - making sure it's pointed at the viewer - and apply the "light" texture to it. You'll want to enable alpha blending, otherwise you'll just see a big square with a picture plastered on it - presumably not what you are looking for.

Another approach - that would probably be more work, but give more control - would be manually rendering or not rendering each pixel on the back buffer using a pixel shader. This kind of "blending" is explained pretty simply in Frank Luna's DirectX 9 book.

Sorry, I see now the crux of your problem was about calculating visibility, not how to render a billboard.

If your scene is simple enough, "manually calculating visibility" might just be comparing the distance from the camera of your test point and one or two other objects.

Otherwise, I think your on the right track with the ZBuffer. Manually calculate the depth of the test point (normalizing from 0.0 to 1.0 based on how the View Frustum is defined), project it onto screen space and compare that value to the value in the ZBuffer (at the same projected screen space coordinates). If your calculated depth value is less than the value in the ZBuffer, it's visible.

That's really the only general way I can think of to determine the visibility of a single 3D point.

Hope that helps.

Mark Stevens
  • 2,366
  • 14
  • 9
  • Well that's already what I use to draw the image, but how can I hide it when a certain point is not visible and make it on top of everything else when it is? – Banderi Sep 26 '12 at 17:45
  • Ok, if the goal is to simply turn it off completely if a "certain point" is invisible, I would manually calculate the visibility of that point and just render/not render the billboard. As far as making it on top - I would just rendering it in screen space. – Mark Stevens Sep 26 '12 at 17:50
  • Perfect! Exactly! Now, how do I calculate the visibility of that point? xD (and actually, by certain point I mean the point where I render the image of the light, so if there's an easier way to to this, may it be welcome!) – Banderi Sep 26 '12 at 17:56
  • 1
    Good answer but neglects to mention that Direct3D provides an "occlusion query" mechanism ( http://msdn.microsoft.com/en-us/library/windows/desktop/bb147308%28v=vs.85%29.aspx and http://msdn.microsoft.com/en-us/library/windows/desktop/bb172594%28v=vs.85%29.aspx - see D3DQUERYTYPE_OCCLUSION). To test visibility of a point, start an occlusion query, render some test geometry at the point, end the query and check the result for how many pixels passed visibility checking. On the other hand, maybe it's a bit overkill for what you're doing and just checking the depth buffer directly is better. – timday Sep 26 '12 at 18:16
  • I tried the query (wanted to test how they work), it works just fine, thanks! Thank you all very much! :) – Banderi Sep 26 '12 at 19:45