首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将方向光从OpenGL移植到DirectX11

将方向光从OpenGL移植到DirectX11
EN

Stack Overflow用户
提问于 2015-04-30 13:50:07
回答 1查看 184关注 0票数 0

我正在移植我的GLSL方向光影从OpenGL到DirectX11。

我的LightDirection是(1,0,0) (从左到右)

GLSL中的着色器如下所示:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
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()));
    }
};

其结果是:

我得出的结论是,错误是因为我不能否定我的正常值。

如果我画出我的正常地图,它们看起来完全一样。

但绘制法线却否定了这一结果:

现在我该如何解决这个问题,使我的砖头画得正确?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-04 21:12:39

所以我现在修好了。

问题是,在HLSL中采样纹理时,范围只能从0到1,但是纹理保存在-1到1之间。不知怎么的,OpenGL可以处理这个问题,但是DirectX不能。

要修复它,只需将其转换为0到1之间的范围,并在需要时将其转换回。

从-1和1到0-1:

代码语言:javascript
复制
output.normalMap = (float4(input.Normal,1) +1)/2;

从0-1到-1和1:

代码语言:javascript
复制
float4 norm = (NormalMap.Sample(SampleType, UV) *2 )-1;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29969567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档