引言
本节我们将应用 Falcor 的色调映射器以显示高动态范围输出
In Tutorials 10 and 12, we added high dynamic range environment maps and indirect illumination. With these two additions, we sometimes get renderngs that are perfectly correct but might be too dark or bright to clearly display on our monitors. As we add more complex materials (and, eventually, area lighting using actual measured light power) these problems quickly become worse.
在教程 10 和 12中,我们添加了高动态范围环境贴图和间接照明。通过这两个添加,我们有时会得到完全正确的渲染,但可能太暗或太亮而无法在我们的显示器上清晰显示。随着我们添加更复杂的材料(最终,使用实际测量的光功率进行区域照明),这些问题很快变得更糟。
This tutorial takes a quick detour to add a pass to tone map our rendered output. Tone mapping and high dynamic range imaging are widely studied areas. Rather than dive into details, I suggest you find a textbook on the topic (perhaps this one) for a guide on picking the right algorithm for your needs.
本教程快速绕道,为我们渲染的输出添加一个传递到色调映射的通道。色调映射和高动态范围成像是广泛研究的领域。与其深入细节,我建议您查找有关该主题的教科书(可能是这本教科书),以获取有关根据您的需要选择正确算法的指南。
Falcor has a built-in tone mapping utility, and we are simply going to expose this utility in a new
SimpleToneMappingPass
.
Falcor有一个内置的色调映射实用程序,我们只是要在一个新的 SimpleToneMappingPass
.
A Render Pass Leveraging Falcor’s Tone Mapper
Unlike the last few tutorials, let’s start again from the beginning: the
main()
function inTutor13-SimpleToneMapping.cpp
. This this tutorial, we are adding a fourth render pass to out pipeline:
与上几篇教程不同,让我们从头开始:main()
. Tutor13-SimpleToneMapping.cpp
在本教程中,我们将向输出管道添加第四个渲染通道:
pipeline->setPass(0, LightProbeGBufferPass::create()); |
Here what we are doing is:
- Creating our G-buffer
- Rendering our one-bounce diffuse global illumination into the
HDRColorOutput
texture- Temporally accumulating from and storing the accumualted result into
HDRColorOutput
- Tone mapping the result from
HDRColorOutput
into our final outputkOutputChannel
我们正在做的是:
- 创建我们的 G 缓冲区
- 将我们的单次反射漫反射全局照明渲染到
HDRColorOutput
纹理中 - 临时累加并将累加的结果存储到
HDRColorOutput
- 将结果从色调映射
HDRColorOutput
到我们的最终输出kOutputChannel
Defining the Tone Mapping Render Pass
Our render pass definition in
SimpleToneMappingPass.h
is mostly boilerplate, with the key data being:
我们的渲染通道定义 SimpleToneMappingPass.h
,关键数据是:
std::string mInChannel; // Input texture for tonemapping |
Here
mInputChannel
andmOutputChannel
are input and output buffers, copied from the constructor (so based on the initialization inmain()
, these are"HDRColorOutput"
andkOutputChannel
).
这里 mInputChannel
和 mOutputChannel
是输入和输出缓冲区,从构造函数复制(因此基于 中的初始化 main()
,它们是 "HDRColorOutput"
和 kOutputChannel
)。
mpGfxState
is a default DirectX pipeline state, as we used in Tutorial 2.
mpGfxState
是我们在教程 2中使用的默认 DirectX 管道状态。
mpToneMapper
is an instantiation of Falcor’s tone mapping utility class. There are a number of methods to configure the tonemapping, includingsetOperator()
,setExposureKey()
, etc. The tone mapper class also provides a GUI, so the user can configure the settings dynamically at run time.
mpToneMapper
是 Falcor 的色调映射实用程序类的实例。配置色调映射的方法有很多,包括setOperator()
、setExposureKey()
等。色调映射器类还提供了一个 GUI,因此用户可以在运行时动态配置设置。
Applying our Tone Mapping
The key operations in
SimpleToneMappingPass::initialize()
include:
关键操作 SimpleToneMappingPass::initialize()
包括:
mpToneMapper = ToneMapping::create( ToneMapping::Operator::Clamp ); |
The first line instantiates the class and initializes it to use a clamping operator. The clamp operator does no tone mapping, essentially copying the input texture to the output. The second line initializes a default DirectX raster state (needed while tone mapping).
第一行实例化该类并将其初始化为使用钳位运算符。钳位操作符不进行色调映射,本质上是将输入纹理复制到输出。第二行初始化默认的 DirectX 光栅状态(色调映射时需要)。
To perform tone mapping, our
SimpleToneMappingPass::execute()
looks as follows:
为了执行色调映射,我们 SimpleToneMappingPass::execute()
看起来如下:
void SimpleToneMappingPass::execute(RenderContext::SharedPtr pRenderContext) |
The first two lines get our input and output buffers as frame buffer objects (as required by
mpToneMapper
).mpToneMapper->execute()
performs tone mapping, and thepushGraphicsState()
andpopGraphicsState()
ensure changes in the tone mapper don’t affect the rest of our program.
前两行将我们的输入和输出缓冲区作为帧缓冲区对象(根据 要求 mpToneMapper
)。 mpToneMapper->execute()
执行色调映射,pushGraphicsState()
和 popGraphicsState()
确保色调映射器中的更改不会影响我们程序的其余部分。
One last observation: in order to expose the class parameters in the UI, we need to add
mpToneMapper->renderUI()
to ourrenderGui()
method:
最后一个观察:为了在 UI 中公开类参数,我们需要在 mpToneMapper->renderUI()
我们的 renderGui()
方法中添加:
void SimpleToneMappingPass::renderGui(Gui* pGui) |
What Does it Look Like?
That covers the important points of this tutorial. When running, you get the following result:
这涵盖了本教程的重点。运行时,您会得到以下结果:
With this tutorial, you can apply Falcor’s built-in tone mapping to allow rendering of very dark or very bright environments.
通过本教程,您可以应用 Falcor 的内置色调映射来渲染非常黑暗或非常明亮的环境。
Tutorial 14 changes our Lambertian material model to use Falcor’s standard GGX materials and extends our one-bounce global illumination to an arbitrary, user-controllable number of bounces.
教程 14将我们的 Lambertian 材质模型更改为使用 Falcor 的标准GGX 材质,并将我们的单反射全局照明扩展到任意的、用户可控数量的反射。