Point sprites on Xbox

Originally posted to Shawn Hargreaves Blog on MSDN, Wednesday, January 3, 2007

Those of you who have tried to render point sprites on Xbox will have noticed they don't work quite the same as on Windows.

We are working on updating the XNA documentation to cover the various Xbox HLSL extensions, but in the meantime, here's what you need to know to make point sprites work.

First a reminder of the things that are common to both platforms. To draw point sprites, you need to set the PointSpriteEnable renderstate to true. In your vertex shader you must write the sprite center position to the POSITION0 output semantic, and the sprite size to the PSIZE0 semantic.

On Windows, your pixel shader will typically take a float2 input parameter using the TEXCOORD0 semantic. But on Xbox, you should use the SPRITETEXCOORD semantic, and the parameter type is float4. The coordinate values you want will be in the Z and W fields, and may be negative. Crazy, huh?

Here is a typical point sprite pixel shader that will work the same on both Windows and Xbox:

    struct PS_INPUT
    {
        #ifdef XBOX
            float4 TexCoord : SPRITETEXCOORD;
        #else
            float2 TexCoord : TEXCOORD0;
        #endif
        
        float4 Color : COLOR0;
    };

    float4 PixelShader(PS_INPUT input) : COLOR0
    {
        float2 texCoord;

        #ifdef XBOX
            texCoord = abs(input.TexCoord.zw);
        #else
            texCoord = input.TexCoord.xy;
        #endif

        return tex2D(Sampler, texCoord) * input.Color;
    }

One final gotcha may occur if you are using dynamic vertex buffers to render point sprite particles. On Windows that is typically done using the Discard vertex buffer locking semantic, which is not supported on Xbox. The best way to render dynamic geometry on Xbox is using the GraphicsDevice.DrawUserPrimitives method (which works on Windows as well).

Blog index   -   Back to my homepage