Skybox & Deferred Rendering how to ?

Started by
9 comments, last by lipsryme 11 years, 9 months ago
I'm trying to render a skybox using a skybox shader (forward)
At the same time I'm doing my deferred rendering (Clear, GBuffer, Lighting, Compose).
I just can't get it to work at the same time.
The deferred composition is a fullscreen quad drawn at the screen in screen-space, so I take it it won't display the skybox in the background. Do I have to render my skybox deferred ? or is there something I'm missing :/

My order at the moment is:
1. Set RenderTarget to backbuffer & depthstencil
2. Render Skybox using disabled depth
3. Set RenderTargets to GBuffer Target
4. Clear RT's using readonly depth
5. Render opaque geometry using depth enabled
6. Set render targets off
7. Set Backbuffer & depthstencil again
8. Render Compose FullscreenQuad with depth enabled (depth readonly or depth disabled doesn't draw anything)
Advertisement
Does that work partly? Or do you test just the whole setup?

Try to draw each separate part on the screen.

I had also black screens, but that was because of the culling mode. Try to add this to your shader

pass Pass1
{
CullMode = CCW; //<--- this or CW
VertexShader = compile vs_3_0 VS();
PixelShader = compile ps_3_0 PS();
}
Yea my order looks like this:


// Clear GBuffer Targets
this->ClearGBuffer();
// Draw opaque geometry
this->RenderOpaqueGeometry();
// Calculate Lighting deferred
this->RenderDeferredLighting();

// Compose image
this->ComposeDeferredImage();
// Draw Skybox
if(this->graphicsDesc.useSkybox)
{
this->RenderSkybox();
}


And if I comment out the ComposeDeferredImage function the skybox gets drawn, else its just black (the cube gets drawn though)
I implemented Deferred Rendering with a SkyBox in XNA. There i just use a "selfmade" stencil buffer (XNA discards the stencilbuffer when switching the rendertarget), so when rendering the gBuffer i have an extra target, setting the red-channel to 1 everywhere somthing is drawn. After composing the final image i render the skybox, where the extra target has a red-value of zero. Its really simple and you can use the unused channels for other data (material-IDs or whatever).
You mean you bind the gbuffer RT with the red value you defined again in the skybox shader and do an if on the pixel that are not red?
But does that solve the depth issue?
yea, the skyboxshader reads the stencilmap and uses clip() to discard the pixels with red = 1 (i think it is clip(0.1 - stencil.r). and depth is no problem, you just have to disable depthtesting, because the stencilmap already "knows" where the skybox has to be drawn and where its occluded.

Edit:
Here is the full order:

(- disable depth read/write)
- clear depthBuffer to max depth
- clear gBuffer
- enable depth read/write
- fill gBuffer with terrain/models/...
- disable depth read/write
- draw lights
- combine color + lightmap
- draw skybox
I compare the depth used in the G-buffer to draw the skybox in the pixels where depth is >= 1. Before drawing the skybox I adjust the viewport depth so it is guaranteed to appear behind everything else. Also I make a special case in the lighting pass to completely illuminate the areas that have this depth.

This is my order of procedures (this covers both deferred and light pre-pass methods)

Clear the GBuffer
Set viewport depth range from 0 to n (some value very close to 1)
If using deferred rendering:
- Render the scene to color, normals, and depth in the GBuffer
- Set viewport depth range from n to 1.0
- Render the skybox with face culling disabled, only to the color of the GBuffer
- Accumulate all lighting in the lighting pass
If using light pre-pass rendering:
- Render the scene to normals and depth in the GBuffer
- Accumulate all lighting in the lighting pass
- Clear the viewport, render the scene with just the color to a separate target
- Set viewport depth range from n to 1.0
- Render the skybox’s color with face culling disabled
Combine color with lighting to draw the final image

New game in progress: Project SeedWorld

My development blog: Electronic Meteor

Do you set the depth stencil buffer during the Gbuffer pass ?
Also you have depth disabled when doing the compose ? If I do that nothing gets drawn for me (correction: the skybox gets drawn but the geometry is black)
When filling the gBuffer, depthbuffer read/write/testing has to be enabled. In the compose it should be turned off, because youre just drawing a fullscreenquad, meaning that the full screen should be covered and a depth-test would only cause problems. Did you have a look at your Rendertargets? Before combining, does your Colortarget look right?
And did you test both methods?

I compare the depth used in the G-buffer to draw the skybox in the pixels where depth is >= 1. Before drawing the skybox I adjust the viewport depth so it is guaranteed to appear behind everything else. Also I make a special case in the lighting pass to completely illuminate the areas that have this depth.

This is my order of procedures (this covers both deferred and light pre-pass methods)

Clear the GBuffer
Set viewport depth range from 0 to n (some value very close to 1)
If using deferred rendering:
- Render the scene to color, normals, and depth in the GBuffer
- Set viewport depth range from n to 1.0
- Render the skybox with face culling disabled, only to the color of the GBuffer
- Accumulate all lighting in the lighting pass
If using light pre-pass rendering:
- Render the scene to normals and depth in the GBuffer
- Accumulate all lighting in the lighting pass
- Clear the viewport, render the scene with just the color to a separate target
- Set viewport depth range from n to 1.0
- Render the skybox’s color with face culling disabled
Combine color with lighting to draw the final image


Great this works perfectly! I was trying to render the skybox into the backbuffer and kept wondering why it's not working, when I can just draw it in the albedo target which gets sampled by the compose shader anyway.

This topic is closed to new replies.

Advertisement