【发布时间】:2015-08-01 07:18:14
【问题描述】:
我正在阅读 Frank D. Luna 的 DirectX 11 3D 游戏编程简介,但似乎无法理解为什么我们要在 Pixel Shader 中实现光照?如果您能给我发送一些关于该主题的参考页面,我将不胜感激。
谢谢。
【问题讨论】:
标签: directx hlsl lighting pixel-shader
我正在阅读 Frank D. Luna 的 DirectX 11 3D 游戏编程简介,但似乎无法理解为什么我们要在 Pixel Shader 中实现光照?如果您能给我发送一些关于该主题的参考页面,我将不胜感激。
谢谢。
【问题讨论】:
标签: directx hlsl lighting pixel-shader
照明可以通过多种方式完成。有数百篇关于该主题的 SIGGRAPH 论文。
对于游戏,有几种常见的方法(或者更常见的是,游戏会混合使用这些方法)
静态光照或光照贴图:光照是离线计算的,通常使用全局光照求解器,并将结果烘焙到纹理中。这些lightmaps 在运行时与基础漫反射纹理混合,以创建复杂的阴影和微妙的光照感,但实际上都没有改变。光照贴图的伟大之处在于您可以捕获非常有趣且复杂的光照技术,这些光照技术的计算成本非常高,然后以非常低廉的成本“重播”它们。限制是您不能移动灯光,尽管有一些技术可以在顶部分层有限数量的动态灯光。
延迟光照:在这种方法中,多次渲染场景以将信息编码到屏幕外纹理中,然后进行额外的传递以计算最终图像。这里通常场景中的每个灯光都有一个渲染通道。见deferred shading。延迟着色的好处在于,它可以很容易地使用艺术驱动的内容来缩放渲染器,而没有太多的硬限制——你可以为更多的光做更多的通道,例如,它们只是简单的相加。延迟着色的问题在于,每次传递往往只做很少的计算,而且许多传递确实会严重推动现代 GPU 的内存带宽,而现代 GPU 的计算能力远大于带宽。
单面前向照明:这通常称为平面shading。这里使用面法线为每个三角形/多边形执行一次照明。在现代 GPU 上,这通常在可编程顶点着色器上完成,但也可以使用几何着色器来计算每个面的法线,而不必在顶点中复制它。结果不是很逼真,但绘制起来非常便宜,因为每个面的颜色是恒定的。这实际上仅在您想要“Tron 外观”或其他一些 non-photorealistic rendering 技术时使用。
顶点前向光照:这是经典光照,其中光照计算是按顶点和按顶点法线执行的。然后在三角形/多边形的面上插入每个顶点的颜色 (Gouraud shading)。这种光照很便宜,在现代 GPU 上会在顶点着色器中完成,但是对于许多复杂的材质来说,结果可能过于平滑,并且任何高光都会变得模糊或丢失。
每像素前向光照:这是您问题的核心:这里的光照每像素计算一次。这可能类似于经典的Phong 或Blinn/Phong 着色,其中法线在顶点之间插值或normal maps,其中第二个纹理提供表面的法线信息。在现代 GPU 中,这是在像素着色器中完成的,并且可以提供更多的表面信息、更好的镜面高光、粗糙度等,但代价是更多的像素着色器计算。在现代 GPU 上,它们往往具有相对于内存带宽的大量计算能力,因此与过去相比,每像素照明非常实惠。事实上,Physically Based Rendering 技术在现代游戏中非常流行,这些技术往往具有非常长且复杂的像素着色器,为场景中每个表面上的每个像素组合了从 6 到 8 个纹理的数据。
这是一个非常粗略的调查,正如我所说,关于这个主题有大量的书籍、文章和背景。
您的问题的简短回答是: 因为我们可以!
【讨论】: