locked
Point Sprite in Direct3D 11.1 with Direct3D 9_1 Profile

    Question

  • How to achieve point sprite rendering in DirectX11.1 with profile 9_1 ? I can do it with geometry shader in profile 10_0, but without it, it doesn't work (lack a function to enable it in Direct3D 11.1 under profile 9_1 ?, like the old D3DRS_POINTSPRITENABLE in D3D9

    Here the shader used (no error in D3D_DEBUG, but nothing draw).

    // Vertex shader

    cbuffer cb0
    {
      float4x4 ModelViewProjectionMatrix;
    };

    float4 stransform(float3 attr_Vertex)
    {
       return mul(ModelViewProjectionMatrix, float4(attr_Vertex, 1.0));
    }

    struct GS_INPUT
    {

        float4 Color: COLOR0;
        float2 TexCoord: TEXCOORD0; // Same signature than VS_OUTPUT
        float PointSize: PSIZE;
        float4 Position: SV_Position;
    };

    GS_INPUT main(
         float3 attr_Vertex: POSITION,
         float attr_PointSize: PSIZE,
         float4 attr_Color: COLOR0
    )
    {
       GS_INPUT Out;
       Out.Position = stransform(attr_Vertex);
       Out.PointSize = max(1.0, attr_PointSize);
       Out.Color = attr_Color.bgra * attr_Color.a;
       Out.TexCoord = float2(0.0, 0.0); // Unused in DX10 profile
       return Out;
    }

    // PS:

    sampler s0; Texture2D <float4> texture0;

    struct VS_OUTPUT {
       float4 Color: COLOR;
       float2 TexCoord: TEXCOORD0; // Assuming Texcoord and size generated ?
    };

    float4 main( struct VS_OUTPUT  In): SV_Target
    {
        float4 r0 = texture0.Sample(s0, In.TexCoord).r;
        return r0 * In.Color;
    }

    // Geometry Shader not used in profile 9.1


    cbuffer cb0
    {
       float4 ScrSpcScale;
    };


    struct GS_INPUT
    {
        float4 Color: COLOR0;
        float2 TexCoord: TEXCOORD0;
        float PointSize: PSIZE;
        float4 Position: SV_Position;
    };

    struct VS_OUTPUT {
       float4 Color: COLOR;
       float2 TexCoord: TEXCOORD0;
       float4 Position: SV_Position;
    };

    [maxvertexcount(4)]
    void main(point GS_INPUT In[1], inout TriangleStream<VS_OUTPUT> Stream)
    {
     VS_OUTPUT Out;
      
     const float2 offsets[4] = {
      float2(-1.0,  1.0),
      float2( 1.0,  1.0),
      float2(-1.0, -1.0),
      float2( 1.0, -1.0),
     };

     float s = 1.0 * ScrSpcScale.x / ScrSpcScale.y;
     float t = 1.0;

     [unroll]
     for (uint i = 0; i < 4; i++){
      Out.Position = In[0].Position;
      float2 p = float2(offsets[i].x * s, offsets[i].y * t);
      Out.Position.xy += p * In[0].PointSize;
         
      Out.TexCoord.xy = offsets[i] * 0.5 + 0.5;
                Out.Color = In[0].Color;
      Stream.Append(Out);
     }
    }

     

     

    Tuesday, November 6, 2012 1:14 AM

Answers

  • it is actually using a point list in fact. It displays just a single point, not a point sprite. I know that a Direct3D 9.1 profile can perfectly handling point sprites (I mean even the Geforce 2MX had it), and sure that Direct3D 11.1 omitted to support point sprite for D3D 9.1 profile ..., especially when I see that the vertex shader can output a PSIZE semantic without any warnings from Direct3D.

    Actually my app is scaling by feature level : from 9_1 to 11_1, and adapt most of the features like handling texture greater than 2048x2048, the shaders already pre-compiled in vs_4_0_level_9_1 and in vs_4_0 for Direct3D 10 or better, etc..

    I can move to some draw triangles for Pre D3D10, but the performances will be much worst, especially if the device is not Direct3D 10, it either a ARM tablet or a very low end PC.

    But frankly, I think it could be also fixed by Direct3D 11.1 driver, by assuming than when a Draw call with point list is performed, with a texture sampler attached and writing to a PSIZE, then point sprite should be enabled and the point sprite could be rendered, using the 'PSIZE' produced by the vertex shader.

    Right, it just render a point. (with the correct color but not sized, not texture).

    • Marked as answer by execom_rt Thursday, November 8, 2012 6:15 AM
    Wednesday, November 7, 2012 2:42 AM

All replies

  • Geometry Shaders are not supported by Feature Level 9.x devices, and the old "fixed-function" Direct3D 9 feature D3DRS_POINTSPRITENABLE  is not exposed in DirecxtX 11.1.

    You should use standard sprites rather than points sprites for Feature Level 9.x devices.

    Tuesday, November 6, 2012 7:12 PM
  • Well it is not really an option for me

    I need to render a cloud of several thousands of point sprites - space simulation - something like this app I'm writing: http://www.youtube.com/watch?feature=player_embedded&v=pqPP1Kx33kk, which is ready to ship on Windows Store (much improved that this old video), but still missing the support for pre-Direct3D 10

    So you are confirming that point sprite is not available in Feature Level 9.x, even if I can write shader that write into a PSIZE semantic size in the the vertex shader.

    I couldn't even find any documentation explaining what the semantic PSIZE is doing in DirectX11.1 in feature level 9.x: It seems that I can write a value into it, but it doesn't do anything, and without error (even in debug mode, there is no error, the shader is fully validated, and no warning about PSIZE being written into it).

    There is some features from D3D9 backported to D3D11 (like the clip planes), but it seems that point sprite was 'forgotten' (in D3D11_RASTERIZER_DESC1). I hope this will be fixed in D3D11.2 maybe.

    If you have some suggestions for an implemation (the previous code, was, well, just a single 'draw' call, for drawing everything.

    Tuesday, November 6, 2012 9:08 PM
  • This is a case of having to scale by feature level. Obviously you want to use the GS point-sprite solution for Feature Level 10.0, but you need something that works on Feature Level 9.1. Have you tried a point-list?
    Tuesday, November 6, 2012 11:46 PM
  • it is actually using a point list in fact. It displays just a single point, not a point sprite. I know that a Direct3D 9.1 profile can perfectly handling point sprites (I mean even the Geforce 2MX had it), and sure that Direct3D 11.1 omitted to support point sprite for D3D 9.1 profile ..., especially when I see that the vertex shader can output a PSIZE semantic without any warnings from Direct3D.

    Actually my app is scaling by feature level : from 9_1 to 11_1, and adapt most of the features like handling texture greater than 2048x2048, the shaders already pre-compiled in vs_4_0_level_9_1 and in vs_4_0 for Direct3D 10 or better, etc..

    I can move to some draw triangles for Pre D3D10, but the performances will be much worst, especially if the device is not Direct3D 10, it either a ARM tablet or a very low end PC.

    But frankly, I think it could be also fixed by Direct3D 11.1 driver, by assuming than when a Draw call with point list is performed, with a texture sampler attached and writing to a PSIZE, then point sprite should be enabled and the point sprite could be rendered, using the 'PSIZE' produced by the vertex shader.

    Right, it just render a point. (with the correct color but not sized, not texture).

    • Marked as answer by execom_rt Thursday, November 8, 2012 6:15 AM
    Wednesday, November 7, 2012 2:42 AM