HLSL Shader ส่งข้อผิดพลาดเมื่อฉันพยายามใช้ค่า

ดังนั้นฉันจึงพยายามเรียนรู้ HLSL ด้วยตัวเอง แต่ฉันก็นิ่งงัน ฉันกำลังเขียนเชดเดอร์แบบกำหนดเองซึ่งมีแสงโดยรอบและสีแสงจุดที่เรียบง่าย

นี่คือรหัสเชเดอร์:

`float4x4 World;
float4x4 View;
float4x4 Projection;

// TODO: add effect parameters here.

float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.5;

float4 DiffuseColor = float4(1, 1, 1, 1);

float3 LightPosition = float3(32, 32, 64);
float4 LightDiffuseColor = float4(0.3, 0.05, 0, 1); // intensity multiplier
float4 LightSpecularColor = float4(1, 1, 1, 1); // intensity multiplier
float LightDistance = 50;

texture Texture;
sampler2D textureSampler = sampler_state {
    Texture = (Texture);
    MinFilter = Point;
    MagFilter = Point;
    AddressU = Wrap;
    AddressV = Wrap;
};

struct VertexShaderInput
{
    float4 Pos: POSITION;
    float2 TexCoords : TEXCOORD0;
    float4 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 PosOut : POSITION;
    float2 TextureCoordinate : TEXCOORD0;
    float3 Normal : TEXCOORD1;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(input.Pos, World);
    float4 viewPosition = mul(worldPosition, View);
    output.PosOut= mul(viewPosition, Projection);

    output.TextureCoordinate = input.TexCoords;
    output.Normal = mul(input.Normal, World);

    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{ 
    float attenuation = saturate(1.0f - (length(input.PosOut - LightPosition) / LightDistance));

    float4 textureColor = tex2D(textureSampler, input.TextureCoordinate);
    textureColor.a = 1;

    float4 lightCol = 
    //LightDiffuseColor;
    mul(LightDiffuseColor, attenuation); 

    float4 ambient = (AmbientColor * AmbientIntensity);
    ambient.a = 1;

    return saturate(textureColor * ambient + lightCol);
}

technique Textured
{
    pass Pass1
    {
        // TODO: set renderstates here.

        VertexShader = compile vs
float attenuation = saturate(1.0f - (length(input.PosOut - LightPosition) / LightDistance));    
...
float4 lightCol = 
//LightDiffuseColor;
mul(LightDiffuseColor, attenuation); 

return saturate(textureColor * ambient + lightCol);
0 VertexShaderFunction(); PixelShader = compile ps
float attenuation = saturate(1.0f - (length(input.PosOut - LightPosition) / LightDistance));    
...
float4 lightCol = 
//LightDiffuseColor;
mul(LightDiffuseColor, attenuation); 

return saturate(textureColor * ambient + lightCol);
0 PixelShaderFunction(); } }

`

ปัญหาถูกจำกัดให้แคบลงเหลือเพียงส่วนนี้ใน Pixel Shader:

float attenuation = saturate(1.0f - (length(input.PosOut - LightPosition) / LightDistance));    
...
float4 lightCol = 
//LightDiffuseColor;
mul(LightDiffuseColor, attenuation); 

return saturate(textureColor * ambient + lightCol);

มันจะทำงานได้ดีถ้าฉันใช้แค่ LightDiffuseColor แต่ทันทีที่ฉันพยายามคูณมัน มันก็แสดงข้อผิดพลาดนี้:

GameContentShadersSimpleTexture.fx(35,21) error X4502 invalid ps_2_0 input semantic 'POSITION'

ฉันใช้ XNA สำหรับเครื่องยนต์ ฉันค่อนข้างนิ่งงันที่นี่ ใครสามารถช่วยฉันได้บ้าง?

ขอบคุณ ดูเดิล

แก้ไข: ใช่แล้ว ดังนั้นฉันจึงจำกัดให้แคบลงให้เหลือเพียงจุดที่แม่นยำ ถึงเวลาที่ฟังก์ชัน length ถูกเรียกใช้ (input.PosOut - LightPosition)


person Doodles    schedule 20.09.2013    source แหล่งที่มา
comment
ฉันเห็นตัวเลขเพียง 3 ตัวในการเริ่มต้นที่นี่: float4 LightDiffuseColor = float4(0.3,0.05,0,1); // intensity multiplier นั่นอาจเป็นปัญหาหรือไม่ (ฉันไม่คุ้นเคยกับ hlsl)   -  person Jeroen van Langen    schedule 20.09.2013
comment
ใช่ มันเป็น float4(0.3,0.05,0,1) ดูเหมือน float4(0.3,0.05,0.1) มาก :P   -  person Doodles    schedule 20.09.2013


คำตอบ (1)


เอาล่ะ ฉันมีวิธีแก้ปัญหาสำหรับเรื่องนี้ แทนที่จะใช้การจัดแสงต่อพิกเซลสำหรับไฟส่องเฉพาะจุด ฉันควรใช้แสงจุดยอดแทน ตำแหน่ง semantic ไม่รองรับอินพุต pixel shader ดังที่เห็น ที่นี่ แต่ตำแหน่งยังคงต้องเป็น ouput สำหรับจุดยอดเชเดอร์ ดังนั้นจึงรวมอยู่ในอินพุตพิกเซลเชเดอร์ แต่ไม่สามารถใช้ได้ รหัสที่อัปเดตของฉันแสดงอยู่ด้านล่าง:

float4x4 World;
float4x4 View;
float4x4 Projection;

// TODO: add effect parameters here.

float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.5;

float4 DiffuseColor = float4(1, 1, 1, 1);

float3 LightPosition = float3(32, 32, 48);
float4 LightDiffuseColor = float4(0.3, 0.05, 0, 1);
float4 LightSpecularColor = float4(1, 1, 1, 1); // intensity multiplier
float LightDistance = 100;

texture Texture;
sampler2D textureSampler = sampler_state {
    Texture = (Texture);
    MinFilter = Point;
    MagFilter = Point;
    AddressU = Wrap;
    AddressV = Wrap;
};

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float4 Normal : NORMAL0;
    float2 TextureCoordinate : TEXCOORD0;
};

struct PixelShaderInput
{
    float4 Position : POSITION0;
    float4 Color : COLOR1;
    float3 Normal : TEXCOORD0;
    float2 TextureCoordinate : TEXCOORD1;
};

PixelShaderInput VertexShaderFunction(VertexShaderInput input)
{
    PixelShaderInput output;

    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position= mul(viewPosition, Projection);

    output.Color = mul(LightDiffuseColor,saturate(1.0f - (length(mul(input.Position, World) - LightPosition) / LightDistance)));
    output.TextureCoordinate = input.TextureCoordinate;
    output.Normal = mul(input.Normal, World);

    return output;
}

float4 PixelShaderFunction(PixelShaderInput input) : COLOR0
{ 
    float4 textureColor = tex2D(textureSampler, input.TextureCoordinate);
    textureColor.a = 1;

    float4 ambient = (AmbientColor * AmbientIntensity);
    ambient.a = 1;

    return saturate(textureColor * ambient + input.Color);
}

technique Textured
{
    pass Pass1
    {
        // TODO: set renderstates here.

        VertexShader = compile vs_1_1 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
person Doodles    schedule 21.09.2013