每像素照明/法线贴图的2D渲染 - directX

时间:2009-12-15 20:48:07

标签: c++ graphics directx shader

我正在寻找最简单,最简单和最快速的技术,以每像素法线渲染2D纹理四边形。 我的意思是一个3D世界,相机固定,所有纹理四边形面向相同的方向(相机),它们之间会有光点,我希望纹理具有每像素的正常值,所以它们会像点亮3D模型一样点亮。

我在网上找到的大多数技术都太复杂和沉重,因为它们指的是真正的3D模型,而我所需要的只是简单的2d四边形。

有没有人知道适当的技术或者可以发布有用的教程? 哦,只有DX才能使用。

感谢。

2 个答案:

答案 0 :(得分:3)

我对XNA而不是directX更有经验,但原理是相同的。

您需要一个法线贴图,这会告诉您的着色器确切地说明在给定点处的曲面法线是什么。然后你需要你的四边形进行纹理映射(它们可能已经是,所以这不是任何额外的工作)。然后使用像素着色器绘制四边形,在着色器内部执行以下操作:

//This shader only handles one directional light, there are various tecnhiques for handling multiple lights.
float3 LightDirection;

//Normal map, set this before rendering the quad
Texture NormalMap;
//sampler
sampler normalSampler = sampler_state
{
  texture = <NormalMap>;
}

//Diffusemap, set this before rendering the quad. This is just your normal texture you want applied to the quad
Texture DiffuseMap;
//sampler
sampler diffuseSampler = sampler_state
{
  texture = <DiffuseMap>;
}

/* you probably need a vertex shader to run all your translations etc, that's pretty bog standard stuff so I won't include one here */

float4 PixelShader(float2 texCoord : TEXCOORD0) : COLOR0
{
  //standard directional lighting equation with normals
  float3 Normal = tex2D(normalSampler, texCoord);
  float dot = dot(LightDirection, Normal);
  return tex2D(normalSampler, texCoord) * dot;
}

答案 1 :(得分:0)

那么在这种情况下你甚至不需要形成切线基础,这使得它变得非常容易。假设,定向照明,如果您将光线转换为视图空间,则可以直接将光线(L)与法线贴图中的法线(N)相对应。您只需将光矢量乘以视图矩阵即可将光矢量转换为视图空间。

如果你想要点光源,它会有点复杂。您需要先将光线位置转换为视图空间。然后你需要从你的像素位置减去你的光位置,将结果矢量标准化并在N.L计算中将其用作你的L矢量:)

要么......工作完成了! :d