使用每像素照明/法线贴图进行 2D 渲染 - directX

发布于 2024-08-15 03:53:37 字数 245 浏览 5 评论 0原文

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

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

有谁知道适当的技术或可以发布有用的教程吗? 哦,仅限 DX。

谢谢。

I'm looking for the simplest, easiest and fastest technique to render 2D textured quads with per-pixel normals.
what i mean is a 3D world where the camera is fixed and all the texture quads are facing to the same direction (the camera), and between them there will be light points, and i want the textures to have per-pixel normal values so they'll lit as if they were 3D models.

most techniques i found on the net are way too complicated and heavy cause they refer to real 3D models, while all i need is simple 2d quads.

does anyone knows an appropriate technique or can post a useful tutorial?
oh, and DX only pls.

thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眉黛浅 2024-08-22 03:53:37

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

I'm more experienced with XNA rather than directX, but the principle is the same.

You need a normal map, this tells your shader exactly what the surface normal is at a given point. You then need your quads to be texture mapped (they probably already are, so this isn't really any extra work). Then you draw the quads with a pixel shader, inside the shader you do something like:

//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;
}
情感失落者 2024-08-22 03:53:37

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

如果你想要点照明,那就有点复杂了。您需要首先将灯光位置转换为视图空间。然后你需要从你的像素位置中减去你的光位置,对结果向量进行归一化,并将其用作 NL 计算中的 L 向量:)

要么,方式......工作完成! :D

Well in that case you don't even need to form a tangent basis which makes it quite easy. Assuming, directional lighting, if you transform your light into view space then you can directly N.L the light (L) against the normal (N) from the normal map. You transform teh light vector into view space by simply multiplying it by the view matrix.

It is a little more complicated if you want point lighting. You need to first transform your light position into view space. Then you need to subtract your light position from your pixel position, normalise the resulting vector and use that as your L vector in the N.L calculation :)

Either, way ... job done! :D

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文