以下:https://www.gamasutra.com/view/feature/131275/implementing_lighting_models_with_.php?page=2
我正在尝试实现漫反射照明,但我认为我不理解某些东西......而且我不知道我是否正确计算它。
多维数据集的顶点信息是:
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) },
};
顶点着色器是:
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;
}
Pixel Is:
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;
}
答案 0 :(得分:1)
此处没有太多信息可以继续,但法线是从顶点(点)指向某个方向的方向向量(方向)。当你计算漫反射光照时,你得到光的位置,得到顶点的位置(点,在这种情况下,我假设从立方体),你找到两个矢量之间的角度。将其描绘为三角形,从光源位置到立方体上的顶点绘制一条直线,并计算该光线与光线之间的角度与法线向量(指向垂直,正交或直线的直线)之间的角度。立方体表面。这两个矢量之间的角度越大,它就越暗,因为你采用了#34;点积"。当角度成直角时,点积将为零,意味着没有光。当"正常"方向直接指向光的方向,点积的值为1,意味着全光。当您将此点积(基本上是光强度)与另一种颜色相乘时,您需要调整顶点(或立方体)所具有的原始颜色的亮度。这会调节您看到的颜色。希望能解释一下。
至于为何你在改变数字时看到你所看到的内容,我不知道。
我只是添加,关于为什么你看到一些不同的东西,如果你用位置改变法线,法线向量几乎总是一个单位向量(长度为1)。当您进行光照计算时,如果两个向量都被标准化,则只能获得0到1之间的所需值(既是单位向量,又是长度为1的向量)。否则你可以获得大量或小的负数。如果你使用像45这样的大量数字作为你的光照倍增系数,那么事情就不会是正确的。着色器中的颜色是介于0和1之间的值。
更新:好的,解释起来很复杂,而且我不知道我是否可以画一张照片来表明这一点。在这段代码中发生了什么,你正在对立方体的每个角顶点进行处理,然后将它与所谓的世界/视图/投影矩阵相乘。基本上,它采用立方体的顶点,将其移动到世界中的位置,然后将其移动到相机位置的倒数位置,这通常意味着靠近原点(0) ,0,0)在相机前面。然后投影矩阵将这些点转换到屏幕上。这里要记住的重要一点是,通过这个神奇的WVP矩阵将顶点着色器中的入射顶点相乘,最终结果是顶点最终位于摄像机前面,然后投影到屏幕上。
现在还有第二部分正在发生,这就是照明计算。它可以在世界空间中完成,或者在世界x视图转换完成后完成。在这种情况下,代码在世界空间中进行光照计算,这意味着无论多维数据集的顶点位于其局部空间中的哪个位置,它都会转换为其世界位置。它可能在世界的任何地方,也可能是(150,20,60)。你需要将它转换到这个世界位置,因为光线位置也在这个空间的世界某个地方。法向量通常是单位向量(长度为1的向量)。画出从(0,0,0)开始并指向一个方向的法线向量。
在第一个将法向量乘以世界矩阵的情况下,这是错误的。理想情况下,应该发生的是法线向量应该遵循'顶点位置的变换,然后从变换后的世界位置指出一个长度。我希望我可以画一些东西来更好地解释它。第一个肯定是错的,第二个你把位置乘以世界矩阵也是错误的我认为。
编辑:我浏览了教程代码,它运行正常。指定(1,1,0)的亮点,然后在着色器中使用它。另一方面,在本教程中,两个亮点是:
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)向量不是一个单位向量。我不确定这是否有区别,但无论如何你的代码和教程都不一样,我不确定这些改变是否是原因你的代码不起作用。还要注意Chuck的光代码是有效的,因为立方体位于中心位置,如果它被移动到任何其他地方,你会在任何地方发现光线。我猜他只是为了演示这样做。