Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

The moon is drawn with two draw calls, but both draw wrong on the xbox so I'm just displaying one draw for simplicity.


This is how the moon should look on the PC:

enter image description here

How it looks on the XBOX:

enter image description here

The texture flickers, disappears, looks like a gradient from bottom to top, lines run through it, and so on as the camera moves around. For example after moving the camera slightly it looks like this: http://olhovsky.com/xna/xbox_moon2.png

public void Draw(Camera cam) 
{ 
    GraphicsDevice gd = Game3.GDM.GraphicsDevice; 

    Vector3 position = Position + cam.Position; 
    Matrix world = Matrix.CreateScale(2.0f); 
    world *= Matrix.CreateConstrainedBillboard( 
    position, cam.Position, Vector3.Down, cam.Forward, null); 

    _moonEffect2.Parameters["World"].SetValue(world); 
    _moonEffect2.Parameters["View"].SetValue(cam.View); 
    _moonEffect2.Parameters["Projection"].SetValue(cam.Projection); 

    // Draw blended part of moon only. 
    _moonEffect2.Parameters["AlphaTestDirection"].SetValue(-1); 
    gd.BlendState = BlendState.AlphaBlend; 
    gd.RasterizerState = RasterizerState.CullNone; 
    gd.DepthStencilState = DepthStencilState.DepthRead; 
    ScreenQuadDraw.DrawQuad(_moonQuad, _moonEffect2); 
} 

Here is the shader used, nothing complicated here: http://www.olhovsky.com/xna/Moon.fx

Does anyone know why the texture is not being displayed properly on the xbox? Is there another state I should be setting perhaps?

share|improve this question
    
Unless you are doing it in DrawQuad, you aren't explicitly setting the texture for the moon. –  r2d2rigo Mar 28 '11 at 8:06
    
@r2d2rigo: It is set once at load time on the cloned effect "_moonEffect2" and then never set again, as that is more efficient. –  Olhovsky Apr 1 '11 at 18:23

1 Answer 1

up vote 4 down vote accepted

The solution was to remove the unused color input from the shader.

Old pixel shader:

float4 PixelShaderFunction(float2 texCoord : TEXCOORD0, float4 color : COLOR0) : COLOR0
{
    color = tex2D(TextureSampler, texCoord);

    // Apply the alpha test.
    clip((color.a - AlphaTestThreshold) * AlphaTestDirection);

    return color;
}

New pixel shader:

float4 PixelShaderFunction(float2 texCoord : TEXCOORD0) : COLOR0
{
    float4 color = tex2D(TextureSampler, texCoord);

    // Apply the alpha test.
    clip((color.a - AlphaTestThreshold) * AlphaTestDirection);

    return color;
}
share|improve this answer
    
Any Idea why this is? –  Jonathan Connell May 30 '11 at 9:57
    
On the xbox 360, not binding anything to the color input is probably akin to having a pointer to an uninitialized value. Then you can have random values instead of a default value (zero), which is the case on windows. In fact, it might not be all windows GPUs that have that behavior. It's possible that some windows GPUs also exhibit the xbox behavior. Anyway, you don't want to have unused inputs anyway, for performance reasons, so it's not so bad. –  Olhovsky May 30 '11 at 13:20
    
Agreed. Only the output image seems weird to me, as you're not using the color attribute in the actual shader. Maybe the output is contiguous after the input, and so the unbinded 'color' overwrites the ouput color? I dunno :p –  Jonathan Connell May 30 '11 at 14:10
    
Now that I look more closely at my shader, my explanation makes little sense. The color value is set from a texture before it is used either way, so the initial value of color shouldn't matter. I don't know why this happens. The moral though, is not to have unused inputs to your shader function. –  Olhovsky May 30 '11 at 19:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.