使用像素级光照/法线贴图的2D渲染 - DirectX

3
我正在寻找最简单、最易于和最快的技术来渲染带有每像素法线的2D纹理四边形。我的意思是一个3D世界,其中摄像机固定,所有纹理四边形都面向同一个方向(摄像机),它们之间将有光点,我希望纹理具有每像素法线值,使它们像3D模型一样发光。
我在网上找到的大多数技术都太复杂和繁重,因为它们涉及真实的3D模型,而我只需要简单的2D四边形。
是否有人知道适当的技术或可以发布有用的教程?哦,只限DX。
谢谢。

1
“真正”的3D模型只是由一堆2D多边形组成的。 - Anon.
"真正的" 3D 模型只是由许多 2D 多边形组成。这是正确的,但当处理 "真正的" 3D 模型时,您还要处理在 3D 空间中的旋转,这使得一切变得更加复杂(因为我找到的技术是设计用于处理这些问题的,它们对我的需求来说过于复杂和繁琐)。同时,请注意一个在 3D 空间中的扁平四边形与由数十个或更多多边形组成的网格之间的巨大差异,而每个多边形的法线都是其因子和法线贴图的结果 - 这是另一个复杂性。 - rubi
你所有的法线都一样吗?完全一样?那么你只需要修改我在答案中提出的方法,而不是使用法线图,直接传入你所需的单个法线即可。为了增加效率,可以直接传入光方向和法线的点积。 - Martin
请注意,如果您使用旋转(用于平铺目的),则需要通过法线变换来处理它。 - elmattic
Mds Elvheim - 对的,我在这个网站上有点新 :) Martin - 非常感谢,但我正在寻找支持多个灯光的东西。同时,在DX中会更好。 Stringer Bell - 你可能是对的。我的引擎只需要X轴翻转,这将使我需要反转红色通道。 - rubi
2个回答

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;
}

我对你的帖子进行了一些编辑,但除此之外,这是正确的。原帖作者应该接受这个答案。 - eodabash
非常感谢 eodabash。能够得到一个被接受的答案当然会很好,但是两年已经过去了,我也不抱什么期望了 :( - Martin

0

在这种情况下,你甚至不需要形成切线基础,这使得它变得非常简单。假设,有定向光,如果你将你的光线转换到视图空间,那么你可以直接用来自法线贴图的法线(N)和光线(L)进行 N.L 计算。你只需将光向量乘以视图矩阵即可将其转换为视图空间。

如果你想要点光源,那就有一点复杂了。首先,你需要将光的位置转换为视图空间。然后,你需要从像素位置中减去光的位置,将得到的向量规范化,并将其用作 N.L 计算中的 L 向量 :)

无论哪种方式...任务完成!:D


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接