Directx HLSL点精灵纹理坐标适用于ATI而非NVIDIA

Directx HLSL点精灵纹理坐标适用于ATI而非NVIDIA,directx,textures,nvidia,hlsl,ati,Directx,Textures,Nvidia,Hlsl,Ati,我真的被这件事难住了。我的HLSL用于渲染具有精灵表纹理坐标的点精灵,在所有ATI卡上都能正常工作,但在任何NVIDIA卡上都不能。在NVIDIA卡上,传递的纹理坐标映射到整个精灵表,而不是其中的一部分。奇怪,但在ATI卡上工作正常。我是否缺少ATI卡特有的功能 这是我的着色器 struct VS_INPUT { float4 Position : POSITION; float4 Color : COLOR; float4 Text

我真的被这件事难住了。我的HLSL用于渲染具有精灵表纹理坐标的点精灵,在所有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();        

    }
}
结构与输入的对比 { 浮动位置4:位置; 浮动4颜色:颜色; float4纹理:TEXCOORD0; //浮动1心灵感应:心灵感应0; }; 结构与输出 { 浮动位置4:位置; 浮动4颜色:颜色; float2纹理:TEXCOORD0; float2纹理:TEXCOORD1; 浮动1心灵感应:心灵感应; }; 浮动4x4 WorldViewProj; 纹理纹理; 取样器2D_2D; 浮动偏移量_x=0.0; 浮动偏移量y=0.0; 采样器S0=采样器_状态 { 纹理=(Tex); MinFilter=各向异性;//线性; MagFilter=各向异性;//线性; MipFilter=线性; }; VS_输出VS_主(输入VS_输入) { VS_OUTPUT Out=(VS_OUTPUT)0;//创建输出顶点 Out.Position=mul(In.Position,WorldViewProj);//应用顶点变换 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;//返回输出顶点 } float4 PS_Particle_main(float2 vPos:TEXCOORD0,float2 text_zw:TEXCOORD1):颜色 { vPos.x*=偏移量x; vPos.y*=偏移量y; vPos+=float2(text_zw[0],text_zw[1]); 返回tex2D(s_2D,vPos); } 技术渲染器 { 通过p0 { AlphaBlendEnable=true; AlphaTestEnable=false; SrcBlend=SRCALPHA; destlend=INVSRCALPHA; POINTSPRITEENABLE=true; POINTSCALEENABLE=true; POINTSIZE_MIN=1.0f; POINTSIZE_MAX=400.0f; 点标度_A=1.0f; 点标度_B=1.0f; 点标度C=1.0f; ZWRITEENABLE=false; 取样器[0]=(S0); VertexShader=编译vs_1_1 vs_main(); PixelShader=编译ps_2_0 ps_粒子_main(); } }
我有一段时间也遇到了同样的问题,花了我很多时间。我没有发现任何关于这个问题的文档,但是通过在ATI和NVIDIA设备上的测试,我发现了差异。使用pointsprites ATI,它可以将纹理坐标正确插值到TEXCOORD0中。相比之下,NVIDIA的功能几乎相同,但他们使用TEXCOORD插值器在所有字段中写入纹理坐标。因此,通过纹理坐标传递给pixelshader的所有信息都将被覆盖。我通过使用颜色插值器而不是TEXCOORD插值器解决了这个问题。很奇怪,但对我来说效果很好:)在你的情况下是:

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

同样的行为似乎也适用于英特尔GPU。至少在我亲自测试过的HD4000上。颜色插值器也适用于这些设备。