Skip to content

Commit ea0e8ac

Browse files
committed
GITechDemo:
*Implemented volumetric light and fog effect for directional light *Two new utility textures and their corresponding GIMP project files have been added for use with the volumetric lighting effect: a dither map (Bayer matrix) and a 3D noise texture (fog density map) *CSM specific shader code has been moved to a HLSL header file to avoid copy-pasting code in the volumetric lighting shader *Added a bilateral blur shader (depth-aware separable Gaussian blur) *Added an upscale filter (nearest-depth - bilinear hybrid) *Added a custom build event to build tools (ModelCompiler and TextureCompiler) and then build data assets *Minor modifications to some shaders *Load times are now shown for each resource in the console *Fixed a problem in model compilation script *Data asset compilation scripts now verify if compiled files already exist *Moved SSAO pass from post-processing pass to lighting pass (since it contributes to scene lighting and must be applied before indirect or volumetric lights) *Bokeh DoF shader depth blur fix *Organized files into filters (Solution Explorer) *Added a GIMP Python script for generating a multi-layered image with noise (for use as a 3D noise texture) LibRenderer: *Thread synchronization changes in ResourceManager *Compiler warning fix in GMTL
1 parent 14f57d8 commit ea0e8ac

35 files changed

+1475
-320
lines changed

GITechDemo/Code/AppMain/GITechDemo.vcxproj

Lines changed: 288 additions & 0 deletions
Large diffs are not rendered by default.

GITechDemo/Code/AppMain/GITechDemo.vcxproj.filters

Lines changed: 172 additions & 138 deletions
Large diffs are not rendered by default.

GITechDemo/Code/AppMain/GITechDemo/GITechDemo.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ namespace GITechDemoApp
5656

5757
}
5858

59+
template <typename T> string tostr(const T& t) {
60+
ostringstream os;
61+
os << t;
62+
return os.str();
63+
}
64+
5965
GITechDemo::GITechDemo()
6066
: App()
6167
, m_fDeltaTime(0.f)
@@ -177,6 +183,10 @@ void GITechDemo::LoadResources(unsigned int thId, unsigned int thCount)
177183
if (!ResourceMgr)
178184
return;
179185

186+
Framework* const pFW = Framework::GetInstance();
187+
if (!pFW)
188+
return;
189+
180190
bool bAllInitialized = false;
181191
do
182192
{
@@ -192,9 +202,10 @@ void GITechDemo::LoadResources(unsigned int thId, unsigned int thCount)
192202
std::stringstream msg;
193203
msg << "Thread " << thId << " - ";
194204
msg << ResourceTypeMap[resList[i]->GetResourceType()] << ": \"" << resList[i]->GetDesc() << "\"";
195-
cout << msg.str() + " (start)\n";
205+
cout << msg.str() + " start\n";
206+
const unsigned startTicks = pFW->GetTicks();
196207
resList[i]->Init();
197-
cout << msg.str() + " (finish)\n";
208+
cout << msg.str() + " finished in " + tostr((float)(pFW->GetTicks() - startTicks) / 1000.f) + "ms\n";
198209
resList[i]->UnlockRes();
199210
}
200211
}

GITechDemo/Code/AppMain/GITechDemo/RenderScheme/DepthOfFieldPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void DepthOfFieldPass::Update(const float fDeltaTime)
5656
1.f / LightAccumulationBuffer.GetRenderTarget()->GetWidth(),
5757
1.f / LightAccumulationBuffer.GetRenderTarget()->GetHeight()
5858
);
59-
f2TexSourceSize = Vec2f(
59+
f2TexSize = Vec2f(
6060
(float)LightAccumulationBuffer.GetRenderTarget()->GetWidth(),
6161
(float)LightAccumulationBuffer.GetRenderTarget()->GetHeight()
6262
);
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
#include "stdafx.h"
2+
3+
#include <Renderer.h>
4+
#include <ResourceManager.h>
5+
#include <RenderState.h>
6+
#include <RenderTarget.h>
7+
#include <Texture.h>
8+
using namespace LibRendererDll;
9+
10+
#include "GITechDemo.h"
11+
#include "DirectionalLightVolumePass.h"
12+
using namespace GITechDemoApp;
13+
14+
#include "RenderResourcesDef.h"
15+
16+
namespace GITechDemoApp
17+
{
18+
extern float CASCADE_MAX_VIEW_DEPTH;
19+
20+
bool DIR_LIGHT_VOLUME_ENABLE = true;
21+
bool DIR_LIGHT_VOLUME_QUARTER_RES = true;
22+
bool DIR_LIGHT_VOLUME_BLUR_SAMPLES = true;
23+
bool DIR_LIGHT_VOLUME_BLUR_DEPTH_AWARE = true;
24+
bool DIR_LIGHT_VOLUME_UPSCALE_DEPTH_AWARE = true;
25+
}
26+
27+
DirectionalLightVolumePass::DirectionalLightVolumePass(const char* const passName, RenderPass* const parentPass)
28+
: RenderPass(passName, parentPass)
29+
{
30+
fElapsedTime = 0.f;
31+
}
32+
33+
DirectionalLightVolumePass::~DirectionalLightVolumePass()
34+
{}
35+
36+
void DirectionalLightVolumePass::Update(const float fDeltaTime)
37+
{
38+
if (DIR_LIGHT_VOLUME_QUARTER_RES)
39+
VolumetricLightAccumulationBuffer = VolumetricLightQuarterBuffer;
40+
else
41+
VolumetricLightAccumulationBuffer = VolumetricLightFullBuffer;
42+
43+
Vec4f v4CamPosLightVS = f44ScreenToLightViewMat * Vec4f(0.f, 0.f, 0.f, 1.f);
44+
v4CamPosLightVS /= v4CamPosLightVS[3];
45+
f3CameraPositionLightVS = Vec3f(v4CamPosLightVS[0], v4CamPosLightVS[1], v4CamPosLightVS[2]);
46+
fRaymarchDistanceLimit = CASCADE_MAX_VIEW_DEPTH;
47+
f2TexSize = Vec2f(
48+
(float)VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetWidth(),
49+
(float)VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetHeight()
50+
);
51+
bSingleChannelCopy = true;
52+
BayerMatrix.GetTexture()->SetAddressingMode(SAM_WRAP);
53+
BayerMatrix.GetTexture()->SetFilter(SF_MIN_MAG_POINT_MIP_NONE);
54+
texDitherMap = BayerMatrix.GetTextureIndex();
55+
NoiseTexture.GetTexture()->SetAddressingMode(SAM_WRAP);
56+
NoiseTexture.GetTexture()->SetFilter(SF_MIN_MAG_LINEAR_MIP_NONE);
57+
texNoise = NoiseTexture.GetTextureIndex();
58+
fElapsedTime += fDeltaTime;
59+
f3FogBox = Vec3f(CASCADE_MAX_VIEW_DEPTH, CASCADE_MAX_VIEW_DEPTH, CASCADE_MAX_VIEW_DEPTH);
60+
}
61+
62+
void DirectionalLightVolumePass::CalculateLightVolume()
63+
{
64+
Renderer* RenderContext = Renderer::GetInstance();
65+
if (!RenderContext)
66+
return;
67+
68+
PUSH_PROFILE_MARKER("Raymarch (scatter)");
69+
70+
VolumetricLightAccumulationBuffer[0]->Enable();
71+
72+
const bool blendEnable = RenderContext->GetRenderStateManager()->GetColorBlendEnabled();
73+
RenderContext->GetRenderStateManager()->SetColorBlendEnabled(false);
74+
75+
f2HalfTexelOffset = Vec2f(0.5f / LightAccumulationBuffer.GetRenderTarget()->GetWidth(), 0.5f / LightAccumulationBuffer.GetRenderTarget()->GetHeight());
76+
texShadowMap = ShadowMapDir.GetRenderTarget()->GetDepthBuffer();
77+
texDepthBuffer = GBuffer.GetRenderTarget()->GetDepthBuffer();
78+
79+
DirectionalLightVolumeShader.Enable();
80+
RenderContext->DrawVertexBuffer(FullScreenTri);
81+
DirectionalLightVolumeShader.Disable();
82+
83+
RenderContext->GetRenderStateManager()->SetColorBlendEnabled(blendEnable);
84+
85+
VolumetricLightAccumulationBuffer[0]->Disable();
86+
87+
POP_PROFILE_MARKER();
88+
}
89+
90+
void DirectionalLightVolumePass::GatherSamples()
91+
{
92+
Renderer* RenderContext = Renderer::GetInstance();
93+
if (!RenderContext)
94+
return;
95+
96+
ResourceManager* ResourceMgr = RenderContext->GetResourceManager();
97+
if (!ResourceMgr)
98+
return;
99+
100+
PUSH_PROFILE_MARKER("Bilateral blur (gather)");
101+
102+
const bool blendEnable = RenderContext->GetRenderStateManager()->GetColorBlendEnabled();
103+
RenderContext->GetRenderStateManager()->SetColorBlendEnabled(false);
104+
105+
const float fBlurDepthFalloffBkp = fBlurDepthFalloff;
106+
if (!DIR_LIGHT_VOLUME_BLUR_DEPTH_AWARE)
107+
fBlurDepthFalloff = 0.f;
108+
109+
PUSH_PROFILE_MARKER("Horizontal");
110+
111+
VolumetricLightAccumulationBuffer[1]->Enable();
112+
113+
f2HalfTexelOffset = Vec2f(0.5f / VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetWidth(), 0.5f / LightAccumulationBuffer.GetRenderTarget()->GetHeight());
114+
f2TexelSize = Vec2f(
115+
1.f / (float)VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetWidth(),
116+
1.f / (float)VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetHeight()
117+
);
118+
f2DepthHalfTexelOffset = Vec2f(
119+
0.5f / (float)LightAccumulationBuffer.GetRenderTarget()->GetWidth(),
120+
0.5f / (float)LightAccumulationBuffer.GetRenderTarget()->GetHeight()
121+
);
122+
ResourceMgr->GetTexture(
123+
VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetColorBuffer(0)
124+
)->SetFilter(SF_MIN_MAG_POINT_MIP_NONE);
125+
ResourceMgr->GetTexture(
126+
VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetColorBuffer(0)
127+
)->SetAddressingMode(SAM_CLAMP);
128+
texSource = VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetColorBuffer(0);
129+
f2BlurDir = Vec2f(1.f, 0.f);
130+
131+
BilateralBlurShader.Enable();
132+
RenderContext->DrawVertexBuffer(FullScreenTri);
133+
BilateralBlurShader.Disable();
134+
135+
VolumetricLightAccumulationBuffer[1]->Disable();
136+
137+
POP_PROFILE_MARKER();
138+
139+
PUSH_PROFILE_MARKER("Vertical");
140+
141+
VolumetricLightAccumulationBuffer[0]->Enable();
142+
143+
f2HalfTexelOffset = Vec2f(0.5f / VolumetricLightAccumulationBuffer[1]->GetRenderTarget()->GetWidth(), 0.5f / LightAccumulationBuffer.GetRenderTarget()->GetHeight());
144+
f2TexelSize = Vec2f(
145+
1.f / (float)VolumetricLightAccumulationBuffer[1]->GetRenderTarget()->GetWidth(),
146+
1.f / (float)VolumetricLightAccumulationBuffer[1]->GetRenderTarget()->GetHeight()
147+
);
148+
f2DepthHalfTexelOffset = Vec2f(
149+
0.5f / (float)LightAccumulationBuffer.GetRenderTarget()->GetWidth(),
150+
0.5f / (float)LightAccumulationBuffer.GetRenderTarget()->GetHeight()
151+
);
152+
ResourceMgr->GetTexture(
153+
VolumetricLightAccumulationBuffer[1]->GetRenderTarget()->GetColorBuffer(0)
154+
)->SetFilter(SF_MIN_MAG_POINT_MIP_NONE);
155+
ResourceMgr->GetTexture(
156+
VolumetricLightAccumulationBuffer[1]->GetRenderTarget()->GetColorBuffer(0)
157+
)->SetAddressingMode(SAM_CLAMP);
158+
texSource = VolumetricLightAccumulationBuffer[1]->GetRenderTarget()->GetColorBuffer(0);
159+
f2BlurDir = Vec2f(0.f, 1.f);
160+
161+
BilateralBlurShader.Enable();
162+
RenderContext->DrawVertexBuffer(FullScreenTri);
163+
BilateralBlurShader.Disable();
164+
165+
VolumetricLightAccumulationBuffer[0]->Disable();
166+
167+
POP_PROFILE_MARKER();
168+
169+
if (!DIR_LIGHT_VOLUME_BLUR_DEPTH_AWARE)
170+
fBlurDepthFalloff = fBlurDepthFalloffBkp;
171+
172+
RenderContext->GetRenderStateManager()->SetColorBlendEnabled(blendEnable);
173+
174+
POP_PROFILE_MARKER();
175+
}
176+
177+
void DirectionalLightVolumePass::ApplyLightVolume()
178+
{
179+
Renderer* RenderContext = Renderer::GetInstance();
180+
if (!RenderContext)
181+
return;
182+
183+
ResourceManager* ResourceMgr = RenderContext->GetResourceManager();
184+
if (!ResourceMgr)
185+
return;
186+
187+
PUSH_PROFILE_MARKER("Apply (bilateral upscale)");
188+
189+
const float fUpsampleDepthThresholdBkp = fUpsampleDepthThreshold;
190+
if (!DIR_LIGHT_VOLUME_UPSCALE_DEPTH_AWARE)
191+
fUpsampleDepthThreshold = 1.f;
192+
193+
LightAccumulationBuffer.Enable();
194+
195+
f2HalfTexelOffset = Vec2f(
196+
0.5f / LightAccumulationBuffer.GetRenderTarget()->GetWidth(),
197+
0.5f / LightAccumulationBuffer.GetRenderTarget()->GetHeight()
198+
);
199+
f2TexelSize = Vec2f(
200+
1.f / (float)VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetWidth(),
201+
1.f / (float)VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetHeight()
202+
);
203+
f2DepthHalfTexelOffset = Vec2f(
204+
0.5f / (float)LightAccumulationBuffer.GetRenderTarget()->GetWidth(),
205+
0.5f / (float)LightAccumulationBuffer.GetRenderTarget()->GetHeight()
206+
);
207+
f2TexSize = Vec2f(
208+
(float)VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetWidth(),
209+
(float)VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetHeight()
210+
);
211+
ResourceMgr->GetTexture(
212+
VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetColorBuffer(0)
213+
)->SetFilter(SF_MIN_MAG_LINEAR_MIP_NONE);
214+
ResourceMgr->GetTexture(
215+
VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetColorBuffer(0)
216+
)->SetAddressingMode(SAM_CLAMP);
217+
texSource = VolumetricLightAccumulationBuffer[0]->GetRenderTarget()->GetColorBuffer(0);
218+
texDepthBuffer = GBuffer.GetRenderTarget()->GetDepthBuffer();
219+
220+
if (DIR_LIGHT_VOLUME_QUARTER_RES)
221+
{
222+
NearestDepthUpscaleShader.Enable();
223+
RenderContext->DrawVertexBuffer(FullScreenTri);
224+
NearestDepthUpscaleShader.Disable();
225+
}
226+
else
227+
{
228+
ColorCopyShader.Enable();
229+
RenderContext->DrawVertexBuffer(FullScreenTri);
230+
ColorCopyShader.Disable();
231+
}
232+
233+
LightAccumulationBuffer.Disable();
234+
235+
if (!DIR_LIGHT_VOLUME_UPSCALE_DEPTH_AWARE)
236+
fUpsampleDepthThreshold = fUpsampleDepthThresholdBkp;
237+
238+
POP_PROFILE_MARKER();
239+
}
240+
241+
void DirectionalLightVolumePass::Draw()
242+
{
243+
if (DIR_LIGHT_VOLUME_ENABLE)
244+
{
245+
LibRendererDll::RenderTarget* pCurrRT = LibRendererDll::RenderTarget::GetActiveRenderTarget();
246+
if (pCurrRT)
247+
pCurrRT->Disable();
248+
249+
CalculateLightVolume();
250+
251+
if (DIR_LIGHT_VOLUME_BLUR_SAMPLES)
252+
GatherSamples();
253+
254+
ApplyLightVolume();
255+
256+
pCurrRT->Enable();
257+
}
258+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef DIRECTIONAL_LIGHT_VOLUME_PASS_H_
2+
#define DIRECTIONAL_LIGHT_VOLUME_PASS_H_
3+
4+
#include "RenderPass.h"
5+
6+
namespace GITechDemoApp
7+
{
8+
class RenderTarget;
9+
10+
class DirectionalLightVolumePass : public RenderPass
11+
{
12+
IMPLEMENT_RENDER_PASS(DirectionalLightVolumePass)
13+
14+
protected:
15+
void CalculateLightVolume();
16+
void GatherSamples();
17+
void ApplyLightVolume();
18+
19+
private:
20+
RenderTarget** VolumetricLightAccumulationBuffer;
21+
};
22+
}
23+
24+
#endif // DIRECTIONAL_LIGHT_VOLUME_PASS_H_

GITechDemo/Code/AppMain/GITechDemo/RenderScheme/MotionBlurPass.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ void MotionBlurPass::CalculateMotionBlur()
4444
if (!RenderContext)
4545
return;
4646

47+
ResourceManager* ResourceMgr = RenderContext->GetResourceManager();
48+
if (!ResourceMgr)
49+
return;
50+
4751
PUSH_PROFILE_MARKER("Calculate");
4852

4953
MotionBlurBuffer.Enable();
@@ -55,6 +59,7 @@ void MotionBlurPass::CalculateMotionBlur()
5559
0.5f / LightAccumulationBuffer.GetRenderTarget()->GetWidth(),
5660
0.5f / LightAccumulationBuffer.GetRenderTarget()->GetHeight()
5761
);
62+
ResourceMgr->GetTexture(LightAccumulationBuffer.GetRenderTarget()->GetColorBuffer())->SetAddressingMode(SAM_MIRROR);
5863
texSource = LightAccumulationBuffer.GetRenderTarget()->GetColorBuffer();
5964
texDepthBuffer = GBuffer.GetRenderTarget()->GetDepthBuffer();
6065

GITechDemo/Code/AppMain/GITechDemo/RenderScheme/RenderScheme.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,23 @@ CREATE_ROOT_PASS()
4242
// Compute direct light contribution from the directional light
4343
#include "DirectionalLightPass.h"
4444
ADD_RENDER_PASS(DIRECTIONAL_LIGHT_PASS, DirectionalLightPass, "Directional Light Pass", LIGHTING_PASS)
45+
46+
// Screen space ambient occlusion (done here so as no to affect indirect and volumetric lights)
47+
#include "SSAOPass.h"
48+
ADD_RENDER_PASS(SSAO_PASS, SSAOPass, "SSAO Pass", LIGHTING_PASS)
4549

4650
// Compute indirect (1 unoccluded bounce) light contribution from the directional light
4751
#include "DirectionalIndirectLightPass.h"
4852
ADD_RENDER_PASS(DIRECTIONAL_INDIRECT_LIGHT_PASS, DirectionalIndirectLightPass, "Directional Indirect Light Pass", LIGHTING_PASS)
53+
54+
// Volumetric directional light
55+
#include "DirectionalLightVolumePass.h"
56+
ADD_RENDER_PASS(DIRECTIONAL_LIGHT_VOLUME_PASS, DirectionalLightVolumePass, "Directional Light Volume Pass", LIGHTING_PASS)
4957

5058
// Apply post-processing effect chain
5159
#include "PostProcessingPass.h"
5260
ADD_RENDER_PASS(POST_PROCESSING_PASS, PostProcessingPass, "Post-Processing Pass", ROOT_PASS)
5361

54-
// Screen space ambient occlusion
55-
#include "SSAOPass.h"
56-
ADD_RENDER_PASS(SSAO_PASS, SSAOPass, "SSAO Pass", POST_PROCESSING_PASS)
57-
5862
// HDR framebuffer downsampling (1/4 and 1/16) for bloom, tone mapping, etc.
5963
#include "HDRDownsamplePass.h"
6064
ADD_RENDER_PASS(HDR_DOWNSAMPLE_PASS, HDRDownsamplePass, "HDR Downsample Pass", POST_PROCESSING_PASS)

0 commit comments

Comments
 (0)