参考教程
学习记录
这篇文章中我们简单介绍玻璃和冰效果。此次使用框架文件如下:
玻璃和冰的主要实现与我们之前介绍过的 水 实现类似,我们将它背后所能看见的物体渲染至纹理,然后通过法线贴图对纹理进行一定程度上的移位,达成效果。类似如下:
在渲染这个的时候,我们需要以下几张纹理(使用冰来介绍):
物体纹理:
冰的表面纹理:
冰的法线纹理:
在原教程中,对其渲染描述如下:
Step 1: Render the scene that is behind the glass to a texture, this is called the refraction.
Step 2: Project the refraction texture onto the glass surface.
Step 3: Perturb the texture coordinates of the refraction texture using a normal map to simulate light traveling through glass.
Step 4: Combine the perturbed refraction texture with a glass color texture for the final result.
We will now examine how to implement each step for both glass and ice.
我们来看代码实现吧。首先来看这次新增的 GlassShaderClass
类,这个类也是从 TextureShaderClass
类修改而成,它相比于普通的纹理渲染类多了一个 GlassBufferType
,如下:
1 | struct GlassBufferType |
refractionScale
决定了我们最后纹理的移位程度。
除多了一个缓冲之外,它的渲染使用三张纹理资源,如下:
1 | bool Render(ID3D11DeviceContext*, int, DirectX::XMMATRIX, DirectX::XMMATRIX, DirectX::XMMATRIX, ID3D11ShaderResourceView* , ID3D11ShaderResourceView* , ID3D11ShaderResourceView* , float); |
其最终的声明如下:
1 | //////////////////////////////////////////////////////////////////////////////// |
当使用多张纹理的时候,我们再设置的时候需要一一设置,在 SetShaderParameters
方法中,我们对其进行配置:
1 | // Set shader texture resource in the pixel shader. |
限于篇幅,其它的实现基本与 TextureShaderClass
相同,使用多缓冲的操作我们也介绍过很多次了,所以在此暂且不表。
在其对应的顶点着色器中,我们向像素着色器里新传入一个变量 refractionPosition
(折射顶点坐标):
1 | cbuffer MatrixBuffer |
像素着色器中,我们使用法线纹理读出的法线对折射纹理进行移位,然后使用最终使用折射纹理和冰本身纹理进行混合:
1 | SamplerState sampleType; |
由于我们的玻璃模型需要两个纹理贴图(颜色纹理和法线纹理),所以我们修改 ModelClass
,使其可以适应两张纹理,修改后如下:
1 | //////////////////////////////////////////////////////////////////////////////// |
我们新增了 m_NormalTexture
成员变量以及它的读取和释放函数,并且在构造函数中使用了默认为空的第三个参数,这样我们可以根据自己需求选择是否使用模型的法线纹理。
最后来看 GraphicsClass
,我们新增了 m_WindowModel
,m_GlassShader
,m_RenderTexture
成员变量以及他们的初始化等操作。
最终渲染时,我们首先渲染我们的 cube 至纹理,然后就可以使用纹理来渲染冰效果。部分代码如下:
1 | bool GraphicsClass::Frame() |
我们在这里渲染了两次 cube ,第一次渲染至纹理其纹理供我们渲染冰所用,第二次渲染至后台呈现所用。最终效果如下:
(渲染玻璃只是更换颜色法线贴图就可以)