2
\$\begingroup\$

I try to create a small and simple 3D games on XNA.

I recently started to add a skyBox after added a sun in my game with the sample by Microsoft here http://xbox.create.msdn.com/en-US/education/catalog/sample/lens_flare . The problem is , after add a skybox . My sun reacts strangely, it is no longer displayed. And occasionally, it bug. Appears and disappears repeatedly. Certainly because the sun is behind my skybox.

Youtube

I upload a video on YouTube of my problem too ;-) : https://www.youtube.com/watch?v=i8mdaibMqA4&feature=youtu.be

Problem identical

My problem is same as this : OcclusionQuery: how to ignore some objects?

Here is my file "SkyBox.fx"

 float4x4 WVP; float4 TextureColor; float AmountColorMix; float Depth; TextureCube tex; sampler cubeSampler = sampler_state { texture = <tex>; AddressU = CLAMP; AddressV = CLAMP; }; struct VertexShaderInput { float4 Position : POSITION0; }; struct VertexShaderOutput { float4 Position : POSITION0; float3 PosTex : TEXCOORD0; }; VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; output.Position = mul(input.Position, WVP).xyww; output.PosTex = input.Position; return output; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { float4 color = texCUBE(cubeSampler,input.PosTex); return lerp(color, TextureColor, AmountColorMix); } technique Technique1 { pass Pass1 { CullMode = None; VertexShader = compile vs_3_0 VertexShaderFunction(); PixelShader = compile ps_3_0 PixelShaderFunction(); } } 

Create and Draw the SkyBox (function)

 /* ********************************* */ // Draw the SkyBox /* ********************************* */ #region DrawSky public void DrawSky() { arcadia.Game.GraphicsDevice.SetVertexBuffer(skyVertices); arcadia.Game.GraphicsDevice.Indices = skyIndices; skyEffect.Parameters["WVP"].SetValue(Matrix.CreateTranslation(arcadia.camera.Position) * arcadia.camera.View * arcadia.camera.Projection); skyEffect.Parameters["TextureColor"].SetValue(arcadia.lensFlare.ColorSun.ToVector4()); skyEffect.Parameters["AmountColorMix"].SetValue(0.25f); skyEffect.CurrentTechnique.Passes[0].Apply(); arcadia.Game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, number_of_vertices, 0, number_of_indices / 3); } #endregion #region Creating a basic VertexBuffer void CreateCubeVertexBuffer() { Vector3[] cubeVertices = new Vector3[number_of_vertices]; cubeVertices[0] = new Vector3(-1, -1, -1); cubeVertices[1] = new Vector3(-1, -1, 1); cubeVertices[2] = new Vector3(1, -1, 1); cubeVertices[3] = new Vector3(1, -1, -1); cubeVertices[4] = new Vector3(-1, 1, -1); cubeVertices[5] = new Vector3(-1, 1, 1); cubeVertices[6] = new Vector3(1, 1, 1); cubeVertices[7] = new Vector3(1, 1, -1); VertexDeclaration VertexPositionDeclaration = new VertexDeclaration ( new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0) ); skyVertices = new VertexBuffer(arcadia.Game.GraphicsDevice, VertexPositionDeclaration, number_of_vertices, BufferUsage.WriteOnly); skyVertices.SetData<Vector3>(cubeVertices); } #endregion #region Creating a basic IndexBuffer void CreateCubeIndexBuffer() { UInt16[] cubeIndices = new UInt16[number_of_indices]; //bottom face cubeIndices[0] = 0; cubeIndices[1] = 2; cubeIndices[2] = 3; cubeIndices[3] = 0; cubeIndices[4] = 1; cubeIndices[5] = 2; //top face cubeIndices[6] = 4; cubeIndices[7] = 6; cubeIndices[8] = 5; cubeIndices[9] = 4; cubeIndices[10] = 7; cubeIndices[11] = 6; //front face cubeIndices[12] = 5; cubeIndices[13] = 2; cubeIndices[14] = 1; cubeIndices[15] = 5; cubeIndices[16] = 6; cubeIndices[17] = 2; //back face cubeIndices[18] = 0; cubeIndices[19] = 7; cubeIndices[20] = 4; cubeIndices[21] = 0; cubeIndices[22] = 3; cubeIndices[23] = 7; //left face cubeIndices[24] = 0; cubeIndices[25] = 4; cubeIndices[26] = 1; cubeIndices[27] = 1; cubeIndices[28] = 4; cubeIndices[29] = 5; //right face cubeIndices[30] = 2; cubeIndices[31] = 6; cubeIndices[32] = 3; cubeIndices[33] = 3; cubeIndices[34] = 6; cubeIndices[35] = 7; skyIndices = new IndexBuffer(arcadia.Game.GraphicsDevice, IndexElementSize.SixteenBits, number_of_indices, BufferUsage.WriteOnly); skyIndices.SetData<UInt16>(cubeIndices); } #endregion 
\$\endgroup\$
5
  • \$\begingroup\$ What do you mean by "depth scale?" It's not clear. \$\endgroup\$ Commented Jun 17, 2014 at 20:29
  • \$\begingroup\$ I mean Depth Scale , because i have a skybox and a sun in my game. the problem is my sun is outside the skybox. I want make my skybox bigger. My problem is exacly same as this gamedev.stackexchange.com/questions/64624/… . I see the guy answer => You could alternatively achieve the same result by writing a depth of 1.0f from your pixel shader . Do you have some idea ? \$\endgroup\$ Commented Jun 17, 2014 at 20:33
  • 1
    \$\begingroup\$ It should not be possible to make your skybox bigger. The entire idea behind a skybox is that it cover the bounds of your viewing volume. What you probably want is simply not to depth test your sun against the sky at all. Think of the sun as an object infinitely far away for the purposes of lighting and for this as well. Basically, just stop writing to the depth buffer when you draw your skybox and assign your sun the depth of your far plane and you will be good. \$\endgroup\$ Commented Jun 18, 2014 at 1:00
  • \$\begingroup\$ Hi Andon M. Coleman . Thanks a lot for your answer. I already assign the depth or my far plane to the sun. But i don't know what you mean by "stop writing to the depth buffer" when i draw my skybox. I add now in my description the way , how i draw the skybox. I hope you can show me a example . Thanks again \$\endgroup\$ Commented Jun 18, 2014 at 8:28
  • \$\begingroup\$ I change the description and add the logic code of my skybox (Create and Draw skybox) and upload a video on YouTube (the link is on the description) . I hope it's more clear like this ;-) \$\endgroup\$ Commented Jun 18, 2014 at 9:18

2 Answers 2

2
\$\begingroup\$

Finally i solve and fix the problem by myself .

Add

GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; 

before draw the skyBox

And Add

arcadia.Game.GraphicsDevice.DepthStencilState = DepthStencilState.Default; 

after finish draw the skyBox

Full Code:

#region DrawSky public void DrawSky() { arcadia.Game.GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead; arcadia.Game.GraphicsDevice.SetVertexBuffer(skyVertices); arcadia.Game.GraphicsDevice.Indices = skyIndices; skyEffect.Parameters["WVP"].SetValue(Matrix.CreateTranslation(arcadia.camera.Position) * arcadia.camera.View * arcadia.camera.Projection); skyEffect.Parameters["TextureColor"].SetValue(arcadia.lensFlare.ColorSun.ToVector4()); skyEffect.Parameters["AmountColorMix"].SetValue(0.25f); skyEffect.CurrentTechnique.Passes[0].Apply(); arcadia.Game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, number_of_vertices, 0, number_of_indices / 3); arcadia.Game.GraphicsDevice.DepthStencilState = DepthStencilState.Default; } #endregion 
\$\endgroup\$
1
\$\begingroup\$

One way of handling this is to modify the depth range in your viewport when drawing the skybox.

For XNA you would set both MinDepth and MaxDepth to 1, leaving the other members the same as your main viewport, like so:

Viewport.MinDepth = 1.0f; Viewport.MaxDepth = 1.0f; 

This will ensure that your skybox is always drawn to the back of the scene, and using this technique you don't need to worry about the skybox size at all: you could even draw it as a 10x10x10 cube around the view point and it would still work. This will also work well with any other kind of object you want to add in the sky (birds, etc).

Another way is to output a depth of 1.0f from your pixel shader, but that's generally not recommended as it can interfere with your GPU's early-Z optimizations.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.