I was wondering if the following shading is possible with Panda’s standard shaders or, as I suspect, I need to write a (seemingly simple?) CG shader for this purpose.
What I’d like is a shader that dims the object behind the object it is applied to, but doesn’t dim the object’s transparencies nor the background.
Is this feasible at all with Panda? And if push comes to shove, is it feasible in CG?
Thanks for your help!
Uhmm… no replies. Peculiar. Do you guys think this is because:
a) my question wasn’t clear
b) it’s not doable
c) it’s off-topic
d) there isn’t enough expertise on the subject matter among Panda’s users
Hmm, your question was not really clear. Can you exactly describe what you want and maybe show a small picture (a picture paints a thousand words) ?
Yes, I read it again and I concur I didn’t explain it clearly. Let me try again (no time for a picture right now but you are right and I might supply one later).
I was wondering if it’s possible to make a shader that dims the objects behind the object it is applied to, but doesn’t dim their transparent parts nor the world’s background.
if the pixel behind the object is background: use the background color
if the pixel behind the object is an object, dim the object’s color
if the pixel behind the object is an object and is semi-transparent, dim proportionally to the transparency.
The troublesome thing is, there’s no real concept of a pixel being “behind” an object or not when drawing the frame. You only have the alpha value to look at. You draw all of the pixels for one object, then you independently draw all of the pixels for another object. There’s no memory in the framebuffer, other than the pixel itself, for what you have previously drawn.
There’s also no real distinction between “objects” and “background”. It’s just a pixel. The background is whatever color you cleared the pixels to before you started to draw.
That being said, I bet you could use the stencil buffer to solve this problem. What I gather you’re trying to do is make a distinction between background pixels and object pixels. Object pixels should be treated one way, background pixels should be treated another way. This kind of distinction is what the stencil buffer is designed for. The idea is to clear the stencil buffer to 0 when you clear the frame. Then, when you draw a pixel, check the stencil buffer: if it’s 0, draw the pixel normally (then set it to 1). If it’s 1, draw the pixel with your alpha-dimming mode.
That’s the idea in a nutshell. In practice, it’s still tricky. One problem is that “if” conditionals are difficult to make in a pixel shader. So you have to write your shader cleverly.
It might also be possible to do it without a shader, and with several passes instead.
Another method would be:
draw each object with that “shader” to an off screen buffer that produces dim texture.
draw background as white
normal objects draw as white
dimmer object draw as black
this way you get your z buffer right and don’t mess with dimmer object behind the non dimmer objects.
now draw all your object normally but also add the dim texture to it using scene coordinates. And here you can check how transparent the object is and do your proportionally dimming. Because the background is drawing without that texture it would not be dimmed.
Thank you both for the lead. It’s worth looking into it as it sounds possible. I’ve also spoken with a friend who makes CG shaders for the Visual Effects industry and he thinks it’s possible using gbuffers. Sounds related to what Treeform was hinting at, isn’t it?
Yes, i think gbuffers is type of onscreen buffer. Yet what you are saying is far from simple shader … and whats the effect? As you describe it would be quite ugly? Something between shadow, ghost and fog.
Hehehe, it’s not ugly nor beautiful: it’s functional! It’s really just a functional shader to dim semi-transparent objects that are behind other semi-transparent objects. It’s similar to fog, except that it’s not a continuous fade-out with distance and the background is not affected (does fog affects the background anyway? I don’t remember!).
But I’ll brace myself for what might not be that simple.