我正在将我的GLSL Directional Light Shader从OpenGL移植到DirectX11。
我的LightDirection是(1,0,0)(图片中从左到右)
GLSL中的Shader看起来像这样:
#version 330 core
uniform sampler2D DiffuseMap;
uniform sampler2D NormalMap;
uniform sampler2D PositionMap;
uniform sampler2D DepthMap;
uniform vec3 LightDirection;
uniform vec3 LightColor;
uniform vec2 Resolution;
vec2 CalcTexCoord()
{
return gl_FragCoord.xy / Resolution;
}
void main()
{
vec4 norm = texture2D( NormalMap, CalcTexCoord());
float Factor = dot(norm.xyz,-LightDirection);
vec4 lights = vec4(LightColor*Factor,1);
gl_FragColor = lights;
}
这导致:
砖块的颜色为蓝色,来自左侧的光线。
我将代码移植到HLSL:
cbuffer MatrixBuffer
{
matrix Scale;
matrix Rotation;
matrix Translation;
matrix View;
matrix Projection;
float3 LightDirection;
float3 LightColor;
float2 Resolution;
};
tbuffer textureBuffer
{
Texture2D DiffuseMap;
Texture2D NormalMap;
Texture2D PositionMap;
Texture2D DepthMap;
};
SamplerState TextureSampler;
struct VertexShaderInput
{
float3 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Color : COLOR0;
float3 Normal : NORMAL;
};
struct VertexShaderOutput
{
float4 Position : SV_POSITION;
float2 UV : TEXCOORD0;
float3 Color : COLOR0;
float3 Normal : NORMAL;
};
struct PixelShaderOutput
{
float4 color: SV_TARGET0;
};
float2 CalcTexCoord(float4 Position)
{
return Position.xy / Resolution;
}
VertexShaderOutput VS_MAIN(VertexShaderInput input)
{
VertexShaderOutput Output = (VertexShaderOutput)0;
float4 pos = float4(input.Position.xyz, 1);
float4x4 Model = mul(mul(Scale, Rotation), Translation);
float4x4 MVP = mul(mul(Model, View), Projection);
Output.Position = mul(pos, MVP);
Output.UV = input.UV;
Output.Color = input.Color;
Output.Normal = input.Normal;
return Output;
}
PixelShaderOutput PS_MAIN(VertexShaderOutput input)
{
PixelShaderOutput output;
float4 norm = NormalMap.Sample(TextureSampler, input.UV);
float Factor = dot(norm.xyz,-LightDirection);
float4 lights = float4(LightColor*Factor, 1);
output.color = lights;
return output;
}
technique10 Main
{
pass p0
{
SetVertexShader(CompileShader(vs_5_0, VS_MAIN()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS_MAIN()));
}
};
结果如下:
我得出结论,错误是因为我无法否定我的常规。
如果我绘制我的法线贴图,它们看起来完全相同
但是否定法线否定了这一结果:
现在我该如何解决问题,以便正确绘制砖块?
答案 0 :(得分:0)
所以我现在解决了这个问题。
问题在于,当在HLSL中对Texture进行采样时,范围只能从0到1.但是纹理保存在-1到1的范围内。不过OpenGL可以使用它,但是DirectX并没有这样做。吨。
要修复它,只需将其转换为0到1的范围,并在需要时将其转换回来。
从-1和1到0-1:
output.normalMap = (float4(input.Normal,1) +1)/2;
从0-1到-1和1:
float4 norm = (NormalMap.Sample(SampleType, UV) *2 )-1;