首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >DirectX 11漫射照明实现

DirectX 11漫射照明实现
EN

Stack Overflow用户
提问于 2017-10-01 21:37:06
回答 1查看 1.6K关注 0票数 2

以下:.php?page=2

我试图实现漫射照明,但我认为我没有理解什么…,我不知道我是否正确地计算它。

多维数据集的顶点信息是:

代码语言:javascript
运行
复制
SimpleVertex vertices[] =
        {
            { DirectX::XMFLOAT3(-1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
            { DirectX::XMFLOAT3(1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
            { DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
            { DirectX::XMFLOAT3(-1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },

            { DirectX::XMFLOAT3(-1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
            { DirectX::XMFLOAT3(1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
            { DirectX::XMFLOAT3(1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
            { DirectX::XMFLOAT3(-1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, -1.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },

            { DirectX::XMFLOAT3(-1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
            { DirectX::XMFLOAT3(-1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
            { DirectX::XMFLOAT3(-1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
            { DirectX::XMFLOAT3(-1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(-1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },

            { DirectX::XMFLOAT3(1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
            { DirectX::XMFLOAT3(1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
            { DirectX::XMFLOAT3(1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
            { DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(1.0f, 0.0f, 0.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },

            { DirectX::XMFLOAT3(-1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
            { DirectX::XMFLOAT3(1.0f, -1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
            { DirectX::XMFLOAT3(1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
            { DirectX::XMFLOAT3(-1.0f, 1.0f, -1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },

            { DirectX::XMFLOAT3(-1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 1.0f) },
            { DirectX::XMFLOAT3(1.0f, -1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 1.0f) },
            { DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f), DirectX::XMFLOAT2(0.0f, 0.0f) },
            { DirectX::XMFLOAT3(-1.0f, 1.0f, 1.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 1.0f), DirectX::XMFLOAT2(1.0f, 0.0f) },
        };

顶点着色器是:

代码语言:javascript
运行
复制
cbuffer ConstantBuffer : register( b0 )
{
    matrix World;
    matrix View;
    matrix Projection;
    float4 vMeshColor;
};

struct VS_INPUT
{
    float4 Position : POSITION;
    float3 Normal : NORMAL;
    float2 Texture : TEXCOORD0;
};

struct PS_INPUT
{
    float4 Position : SV_POSITION;
    float3 Normal : TEXCOORD0;
    float2 Texture : TEXCOORD1;
};

PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;

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

    output.Normal = mul( input.Normal, World );
    output.Normal = mul( output.Normal, View );
    output.Normal = mul( output.Normal, Projection );
    output.Normal = normalize( output.Normal );

    output.Texture = input.Texture;

    return output;
}

像素为:

代码语言:javascript
运行
复制
PS_OUTPUT PS( PS_INPUT input )
{
    PS_OUTPUT output;
    float4 ambient = {0.1, 0.0, 0.0, 1.0};
    float4 lightColor = { 1.0f, 1.0f, 1.0f, 1.0f};

    float3 lightPosition = ( 1.0f, 1.0f, 0.0f );
    float3 lightDirection = normalize(lightPosition - input.Position);

    float1 diffuse = saturate( dot( lightDirection, input.Normal )) * lightColor;

    output.color = diffuse;

    //float4 solidColor = float4( 1.0f, 1.0f, 0.0f, 1.0f );
    //output.color = solidColor;
    return output;
}

结果(当立方体旋转50次时):

CPP:https://github.com/walbourn/directx-sdk-samples/blob/master/Direct3D11Tutorials/Tutorial06/Tutorial06.cpp

HLSL:https://github.com/walbourn/directx-sdk-samples/blob/master/Direct3D11Tutorials/Tutorial06/Tutorial06.fx

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-01 22:29:21

这里的信息不多,但是法线是指向某个顶点(点)某一方向的方向向量(方向)。当你计算漫射照明时,你得到的是光的位置,得到顶点的位置(在这里,我假设从立方体),然后你找到两个矢量之间的角度。把它描绘成一个三角形,你画一条从光点到立方体上顶点的线,然后计算出从光到法向量之间的夹角(直线指向垂直的,正交的,或者是直射的)。这两个向量之间的角度越高,它就越暗,因为你拿的是“点积”。当角度是直角时,点积将为零,意味着没有光。当“法线”方向直接指向光的方向时,点积的值是1,意思是全光。当你把这个点积(基本上是光强度)乘以另一种颜色时,你正在调整顶点(或立方体)原有颜色的亮度。调节你所看到的颜色。希望这解释了些什么。

当你改变数字的时候,你为什么会看到你看到的,我不知道。

我只想补充一下,关于为什么你看到不同的东西,如果你改变了法线的位置,法线向量几乎总是一个单位向量(长度为1)。当你做照明计算时,如果两个向量都是正规化的(都是单位矢量,或者都是长度为1的向量),你只能得到0到1之间的期望值。否则,你可以得到大大小小的负数。如果你用一个像45这样的大数作为你的照明乘法因子,那么事情就不会是正确的。着色器中的颜色是0到1之间的值。

更新:好的,这会变得很复杂,我不知道我是否能画一幅画来显示这个。在这段代码中,你取了立方体的每个角顶点,然后把它乘以所谓的世界/视图/投影矩阵。基本上,它取到立方体的顶点,移动到它在世界上的位置,然后将它移动到摄像机位置的相反位置,这通常意味着接近原点(0,0,0)在摄像机前面。然后投影矩阵就是将这些点转换到屏幕上的东西。这里需要记住的是,用这个神奇的WVP矩阵乘以顶点着色器中的输入顶点,最终的结果是,顶点在摄像机前结束,然后投影到屏幕上。

现在有第二部分正在发生,那就是照明计算。它可以在世界空间中完成,也可以在world视图转换完成之后进行。在这种情况下,代码在世界空间中进行照明计算,这意味着从你的立方体的顶点在它的局部空间,它被转换到它的世界位置。它可能在世界上的任何地方,它可能是(150,20,60)。你需要把它转换成这个世界位置,因为光的位置也在这个空间的某个地方。法向量通常是单位向量(长度为1的向量)。描绘法向量,从(0,0,0)开始,指向一个方向。

首先,将法向量乘以世界矩阵,这是错误的。理想情况下,应该发生的是法线向量应该“跟随”顶点位置的变换,然后从这个变换的世界位置指出一个长度。我希望我能画出一些东西来更好地解释它。第一个是绝对错误的,第二个是用世界矩阵乘以位置的,我认为也是错误的。

编辑:我看了教程代码,它运行良好。你指定一个光点为(1,1,0),然后在你的着色器中使用它。另一方面,在本教程中,两个亮点是:

代码语言:javascript
运行
复制
XMFLOAT4( -0.577f, 0.577f, -0.577f, 1.0f ),
XMFLOAT4( 0.0f, 0.0f, -1.0f, 1.0f ),

你会看到的第二个是单位向量,只有Z是-1。第一个也是单位向量(长度为1),因为A平方+B平方+C平方=长度。这就是为什么这两个都是单位向量和点积将得到正确的结果。另一方面,你的(1,1,0)向量不是单位向量。我不确定这是否有区别,但无论如何,您的代码和教程中的代码并不相同,我不确定这些更改是否是您的代码不能工作的原因。还请注意,恰克的轻码工作,因为立方体是在中心,如果它被移动到任何其他地方,你会发现到处都是照明缺陷。我想他这么做只是为了演示。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46517144

复制
相关文章

相似问题

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