2013-09-20 4 views
0

Так что я пытаюсь узнать себе HLSL, но я в тупике. Я пишу пользовательский шейдер с окружающим освещением и простой предметной подсветкой.HLSL Shader выдает ошибку, когда я пытаюсь использовать значение

Вот код шейдера:

`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_2_0 VertexShaderFunction(); 
     PixelShader = compile ps_2_0 PixelShaderFunction(); 
    } 
} 

`

Проблема была сужена до этого раздела в пиксельный шейдер:

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 для двигателя. Я немного застенчив. Может кто-нибудь мне помочь?

Thanks, Doodles.

Редактировать: Mkay, поэтому я сузил его до довольно точного места. Это когда функция длины вызывается (input.PosOut - LightPosition)

+0

Я вижу только 3 числа при инициализации здесь: 'float4 LightDiffuseColor = float4 (0.3,0.05,0,1); // множитель интенсивности, может ли это быть проблемой? (я не знаком с hlsl) –

+0

Да, это float4 (0,3,0,05,0,1), очень похож на float4 (0,3,0,05,0,1): P – Doodles

ответ

0

Хорошо, поэтому у меня есть решение для этого. Вместо того, чтобы использовать пиксельное освещение для точечных огней, вместо этого я должен использовать вершинное освещение. Семантика позиции не поддерживается для входов пиксельных шейдеров, как показано here. Но положение по-прежнему должно быть выходным для вершинного шейдера, поэтому оно включено в вход пиксельного шейдера, но его нельзя использовать. Мой обновленный код показан ниже:

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(); 
    } 
} 
Смежные вопросы