HLSL点精灵纹理坐标适用于ATI而不是NVIDIA

时间:2012-08-20 16:18:40

标签: directx textures nvidia hlsl ati

我真的被这个问题困住了。我的HLSL用于渲染带有sprite表纹理坐标的点精灵在所有ATI卡上都能正常工作,但在任何NVIDIA卡上都不行。在NVIDIA卡上,传递的纹理坐标映射到整个精灵表而不是它的一部分。奇怪但它在ATI卡上运行良好。我错过了ATI卡独有的东西吗?

这是我的着色器

struct VS_INPUT
{
        float4 Position   : POSITION;
        float4 Color      : COLOR;
        float4 Texture    : TEXCOORD0;
    //float1 Psize    : PSIZE0;
};


struct VS_OUTPUT
{
        float4 Position   : POSITION;
        float4 Color      : COLOR;
        float2 Texture    : TEXCOORD0;
        float2 Texture_zw : TEXCOORD1;
    float1 Psize      : PSIZE;
};



float4x4 WorldViewProj;
texture Tex <string name = "sprite_coin_test.dds";>;
sampler2D s_2D;
float offset_x=0.0;
float offset_y=0.0;


sampler S0 = sampler_state
{
    Texture = (Tex);
    MinFilter = ANISOTROPIC; //LINEAR;
    MagFilter = ANISOTROPIC; //LINEAR;
    MipFilter = LINEAR;
};


VS_OUTPUT vs_main( in VS_INPUT In )
{
    VS_OUTPUT Out=(VS_OUTPUT)0;                      //create an output vertex

    Out.Position = mul(In.Position, WorldViewProj);  //apply vertex transformation
    Out.Texture  = In.Texture;
        Out.Texture_zw = float2(In.Texture.z, In.Texture.w);
        Out.Color    = In.Color;
    //Out.Psize    = In.Psize;
    Out.Psize=(Out.Position.z)*10.0;
        return Out;                         //return output vertex
}

float4 PS_Particle_main(float2 vPos: TEXCOORD0, float2 text_zw: TEXCOORD1) : COLOR 
{   
        vPos.x*=offset_x;
        vPos.y*=offset_y;

        vPos += float2(text_zw[0], text_zw[1]);    

        return tex2D(s_2D, vPos);
}

technique RenderVS
{   
    pass p0   
    {       
        AlphaBlendEnable        = true;     
        AlphaTestEnable     = false;        
        SrcBlend            = SRCALPHA;     
        DestBlend           = INVSRCALPHA;  

        POINTSPRITEENABLE       = true;     
        POINTSCALEENABLE        = true;
              POINTSIZE_MIN     = 1.0f;     
        POINTSIZE_MAX       = 400.0f;           
                    POINTSCALE_A        = 1.0f;
        POINTSCALE_B        = 1.0f;
        POINTSCALE_C        = 1.0f;
        ZWRITEENABLE        = false;

        Sampler[0]      = (S0);


        VertexShader = compile vs_1_1 vs_main();
        PixelShader = compile ps_2_0 PS_Particle_main();        

    }
}

1 个答案:

答案 0 :(得分:1)

我有一段时间遇到同样的问题,这花了我很多时间。我没有找到任何有关此问题的文档,但通过对ATI和NVIDIA设备的测试,我发现了差异。使用pointsprites ATI工作得很好,它将纹理坐标正确地插入到TEXCOORD0中。相比之下,NVIDIA几乎一样,但他们用TEXCOORD插值器在所有领域中编写纹理坐标。因此,您通过textureCoordinates传递给pixelshader的所有信息都将被覆盖。我通过使用COLOR-interpolator而不是TEXCOORD-interpolator来解决这个问题。很奇怪,但它对我来说很好:)在你的情况下它将是:

struct VS_OUTPUT
{
    float4 Position   : POSITION;
    float4 Color      : COLOR0;
    float2 Texture    : TEXCOORD0;
    float2 Texture_zw : COLOR1;
    float1 Psize      : PSIZE;
};