Artifacts in image that dont appear when using reference device

Started by
17 comments, last by jischneider 11 years, 11 months ago
Ive been having a problem with a sort of white halo showing up around the blocks in my XNA game. When I debugged it in pix, I noticed that it seems to occur in the directional light shader and that it doesnt happen when I set pix to "Force REF". I've attached images of what it looks like in pix on both "Unchanged" and "Force REF" mode. What would cause this kind of thing?

Unchanged:
[attachment=8351:normal.png]

Force REF:
[attachment=8352:ref.png]
Advertisement
Do you use MSAA and a deferred renderer?

[size=1]Project page: [size=1]<

[size=1] XNA FINAL Engine[size=1] [size=1]>
I am using a deferred renderer, but MSAA is off
And what is the surface format of the depth buffer and how do you store the depth information?

You could suffer a lack of precision in the depth buffer.

[size=1]Project page: [size=1]<

[size=1] XNA FINAL Engine[size=1] [size=1]>
These are the render targets used by the deferred renderer:


colorRT = new RenderTarget2D(Engine.Game.GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.Depth24);
normalRT = new RenderTarget2D(Engine.Game.GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.None);
depthRT = new RenderTarget2D(Engine.Game.GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Single, DepthFormat.None);
lightRT = new RenderTarget2D(Engine.Game.GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.None);
finalRT = new RenderTarget2D(Engine.Game.GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.None);


In the GBuffer vertex shader I have output.Depth = output.Position.zw; and in the pixel shader I have output.Depth = input.Depth.x / input.Depth.y
It's really strange. unsure.png

First I think in MSAA because deferred renderers and MSAA don’t work well together, since different fragments will use the same illumination information.

Then I think that the GPU depth buffer could has little differences with your depth buffer. But it looks ok.

I don't know. wacko.png

[size=1]Project page: [size=1]<

[size=1] XNA FINAL Engine[size=1] [size=1]>
I was looking through pix again and I noticed a line that said SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE). So it looks like MSAA is on. I have no idea whats turning it on though. When the graphics device is created, I explicitly turned it off. I checked all the render targets, none of them turn it on either. Ideas?
Yes. Set multisampling in the method Graphics_PreparingDeviceSettings


private static void Graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
{
Device.PresentationParameters.MultiSampleCount = 0;
}


When you don't explicitly set multisampling the render target constructor uses the system value. And the correct place to setting the multisampling count is this method.

[size=1]Project page: [size=1]<

[size=1] XNA FINAL Engine[size=1] [size=1]>
Hmm, that didn't work. I should note that the SetRenderState line I noticed occurs RIGHT before the directional light shader starts rendering. It seems like a shader/render target specific setting, but I can't find anything in the code that might be enabling it.

Game constructor:


public Craft()
{
Game = this;

Graphics = new GraphicsDeviceManager(this)
{
PreferredBackBufferWidth = 1280,
PreferredBackBufferHeight = 720,
SynchronizeWithVerticalRetrace = false,
PreferMultiSampling = false,
IsFullScreen = false
};

Graphics.PreparingDeviceSettings += graphics_PreparingDeviceSettings;
Content.RootDirectory = "Content";

IsFixedTimeStep = false;
//this.Window.AllowUserResizing = true;
//this.IsMouseVisible = true;
}

void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
{
foreach(GraphicsAdapter adapter in GraphicsAdapter.Adapters)
{
if(adapter.Description.Contains("PerfHUD"))
{
e.GraphicsDeviceInformation.Adapter = adapter;
GraphicsAdapter.UseReferenceDevice = true; // this is the modified line from usage in previous xna version
break;
}
}

e.GraphicsDeviceInformation.PresentationParameters.MultiSampleCount = 0;
}



And heres a snippit of the directional light render code path:


class DeferredRenderer
{
private void DrawLights()
{
Engine.Graphics.GraphicsDevice.SetRenderTarget(lightRT);
Engine.Graphics.GraphicsDevice.Clear(Color.Transparent);
Engine.Graphics.GraphicsDevice.BlendState = BlendState.AlphaBlend;
Engine.Graphics.GraphicsDevice.DepthStencilState = DepthStencilState.None;

DirectionalLight.Draw();
PointLight.Draw();

Engine.Graphics.GraphicsDevice.BlendState = BlendState.Opaque;
Engine.Graphics.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
Engine.Graphics.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
Engine.Graphics.GraphicsDevice.SetRenderTarget(null);
}
}


class DirectionalLight
{
private void DrawDirectionalLight()
{
directionalLightEffect.Parameters["ColorMap"].SetValue(DeferredRenderer.ColorRT);
directionalLightEffect.Parameters["NormalMap"].SetValue(DeferredRenderer.NormalRT);
directionalLightEffect.Parameters["DepthMap"].SetValue(DeferredRenderer.DepthRT);

directionalLightEffect.Parameters["LightDirection"].SetValue(LightDirection);

directionalLightEffect.Parameters["DiffuseLightColor"].SetValue(DiffuseColor);
directionalLightEffect.Parameters["AmbientLightColor"].SetValue(AmbientColor);

directionalLightEffect.Parameters["AmbientIntensity"].SetValue(AmbientIntensity);
directionalLightEffect.Parameters["DiffuseIntensity"].SetValue(DiffuseIntensity);

directionalLightEffect.Parameters["SpecularPower"].SetValue(SpecularPower);
directionalLightEffect.Parameters["SpecularIntensity"].SetValue(SpecularIntensity);

directionalLightEffect.Parameters["CameraPosition"].SetValue(Camera.Position);
directionalLightEffect.Parameters["InvertViewProjection"].SetValue(Matrix.Invert(Camera.View * Camera.Projection));

directionalLightEffect.Techniques[0].Passes[0].Apply();
DeferredRenderer.FullScreenQuad.Draw();
}

public static void Draw()
{
foreach(DirectionalLight light in lights)
{
light.DrawDirectionalLight();
}
}
}
Everything looks good.

Maybe it’s a driver problem. Upload your bin directory, I will try your program if you like.

[size=1]Project page: [size=1]<

[size=1] XNA FINAL Engine[size=1] [size=1]>

This topic is closed to new replies.

Advertisement