将平行光从OpenGL移植到DirectX11
我正在将我的GLSL平行光着色器从OpenGL移植到DirectX11 我的光照方向是(1,0,0)(图中从左到右) GLSL中的着色器如下所示:将平行光从OpenGL移植到DirectX11,opengl,directx,glsl,hlsl,Opengl,Directx,Glsl,Hlsl,我正在将我的GLSL平行光着色器从OpenGL移植到DirectX11 我的光照方向是(1,0,0)(图中从左到右) GLSL中的着色器如下所示: #version 330 core uniform sampler2D DiffuseMap; uniform sampler2D NormalMap; uniform sampler2D PositionMap; uniform sampler2D DepthMap; uniform vec3 LightDirection; uniform v
#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()));
}
};
其结果是:
我得出结论,这个错误是因为我不能否定我的法线
如果我画法线贴图,它们看起来完全一样
但绘制法线会导致以下结果:
现在我如何解决这个问题,以便正确绘制砖块?因此我现在解决了这个问题
问题在于,在HLSL中采样纹理时,范围只能从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;
检查输入布局,以确保将法线数据实际输入着色器。它们被绘制到纹理上,该纹理显示在最后一个纹理之前的图片中。法线贴图使用什么格式?OGL和DX之间是否相同?可能是输入映射问题。使用GPU捕获工具(Diagnostics、Nsight等)验证正常数据是否实际进入。如果这不是问题,您可以使用GPU工具调试像素,并找出丢失/不正确的数据。对于每个实现,您的常规地图查找完全不同。。。DirectX根据传入的UV坐标查找UV,OpenGL使用窗口相对坐标查找法线信息。。。