Skip to content

Commit 7f15c4b

Browse files
committed
Light: Allow multiple lights
1 parent e82de1f commit 7f15c4b

File tree

3 files changed

+55
-39
lines changed

3 files changed

+55
-39
lines changed

src/Shader/LightPass.hlsl

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ cbuffer ScreenQuadBuffer : register(b0)
33
{
44
matrix InverseView;
55
matrix InverseProjection;
6-
float3 cameraPos;
7-
float2 screenSize;
6+
float4 cameraPos;
7+
float4 screenInfo;
88
}
99

1010
struct LightData {
@@ -84,6 +84,7 @@ float GeometrySmith(float3 N, float3 V, float3 L, float roughness)
8484
float3 ReconstructPosition(int2 pixelCoord, uint index)
8585
{
8686
float depth = depthTex.Load(pixelCoord, index).r;
87+
float2 screenSize = float2(screenInfo.x, screenInfo.y);
8788

8889
float2 ndc = (float2(pixelCoord) / screenSize) * 2.0f - 1.0f;
8990
ndc.y *= -1.0f;
@@ -127,9 +128,7 @@ PixelOutput PixelMain(VertexOutput input, uint index : SV_SampleIndex)
127128
{
128129
float depth = depthTex.Load(input.position.xy, index).r;
129130
float3 color = float3(0.f, 0.f, 0.f);
130-
131-
float3 lightPos = Lights[0].position.rgb;
132-
float3 lightColor = Lights[0].color.rgb;
131+
133132

134133
int2 pixelCoord = int2(input.position.xy);
135134

@@ -141,34 +140,42 @@ PixelOutput PixelMain(VertexOutput input, uint index : SV_SampleIndex)
141140
float ao = ormData.r;
142141
float roughness = ormData.g;
143142
float metallic = ormData.b;
143+
uint numLights = screenInfo.z;
144144

145-
float3 V = normalize(cameraPos - pos);
146-
float3 F0 = lerp(float3(0.04f, 0.04f, 0.04f), albedoColor, metallic);
145+
for (uint i = 0; i < numLights; i++)
146+
{
147+
float3 lightPos = Lights[i].position.rgb;
148+
float3 lightColor = Lights[i].color.rgb;
147149

148-
float3 L = normalize(lightPos - pos);
149-
float3 H = normalize(V + L);
150-
float distance = length(lightPos - pos);
151-
float attenuation = 1.0f / (distance * distance + 1.f);
152-
float3 radiance = lightColor * attenuation;
153-
radiance *= (1.0 + metallic * 0.2);
150+
float3 V = normalize(cameraPos.xyz - pos);
151+
float3 F0 = lerp(float3(0.04f, 0.04f, 0.04f), albedoColor, metallic);
154152

155-
float NDF = DistributionGGX(N, H, roughness);
156-
float G = GeometrySmith(N, V, L, roughness);
157-
float3 F = FresnelShlick(saturate(dot(H, V)), F0);
153+
float3 L = normalize(lightPos - pos);
154+
float3 H = normalize(V + L);
155+
float distance = length(lightPos - pos);
156+
float attenuation = 1.0f / (distance * distance + 1.f);
157+
float3 radiance = lightColor * attenuation;
158+
radiance *= (1.0 + metallic * 0.2);
158159

159-
float3 kS = F;
160-
float3 kD = (1.0 - kS) * (1.0 - metallic);
160+
float NDF = DistributionGGX(N, H, roughness);
161+
float G = GeometrySmith(N, V, L, roughness);
162+
float3 F = FresnelShlick(saturate(dot(H, V)), F0);
161163

162-
float3 numerator = NDF * G * F;
163-
float denominator = 4.f * max(dot(N, V), 0.f) * max(dot(N, L), 0.f) + 0.0001f;
164-
float3 specular = numerator / denominator;
164+
float3 kS = F;
165+
float3 kD = (1.0 - kS) * (1.0 - metallic);
165166

166-
float NdotL = max(dot(N, L), 0.f);
167-
float3 Lo = (kD * albedoColor / PI + specular) * radiance * NdotL;
167+
float3 numerator = NDF * G * F;
168+
float denominator = 4.f * max(dot(N, V), 0.f) * max(dot(N, L), 0.f) + 0.0001f;
169+
float3 specular = numerator / denominator;
168170

169-
float3 ambient = 0.1f * albedoColor * ao;
171+
float NdotL = max(dot(N, L), 0.f);
172+
float3 Lo = (kD * albedoColor / PI + specular) * radiance * NdotL;
170173

171-
color = ambient + Lo;
174+
color += Lo;
175+
}
176+
177+
float3 ambient = 0.1f * albedoColor * ao;
178+
color += ambient;
172179

173180
/* Tonemap */
174181
color = color / (color + 1.0);

src/private/Core/Renderer/ScreenQuad.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ void ScreenQuad::Render() {
251251

252252
void ScreenQuad::InitConstantBuffer() {
253253
if (D3D12* renderer = dynamic_cast<D3D12*>(this->m_renderer)) {
254-
Camera* currentCamera = this->m_sceneMgr->GetCurrentScene()->GetCurrentCamera();
254+
Scene* scene = m_sceneMgr->GetCurrentScene();
255+
Camera* currentCamera = scene->GetCurrentCamera();
255256

256257
Transform cameraTransform = this->m_sceneMgr->GetCurrentScene()->GetCurrentCamera()->transform;
257258
XMVECTOR eye = XMVectorSet(
@@ -288,12 +289,19 @@ void ScreenQuad::InitConstantBuffer() {
288289
this->m_sqCBuffData.InverseProjection = XMMatrixInverse(nullptr, this->m_sqCBuffData.InverseProjection);
289290

290291

291-
this->m_sqCBuffData.cameraPosition = XMFLOAT3(
292+
this->m_sqCBuffData.cameraPosition = XMFLOAT4(
292293
currentCamera->transform.location.x,
293294
currentCamera->transform.location.y,
294-
currentCamera->transform.location.z
295+
currentCamera->transform.location.z,
296+
0.f
295297
);
296298

299+
std::vector<Light*> lights = scene->GetLights();
300+
this->m_sqCBuffData.screenInfo.x = renderer->m_nWidth;
301+
this->m_sqCBuffData.screenInfo.y = renderer->m_nHeight;
302+
this->m_sqCBuffData.screenInfo.z = lights.size();
303+
this->m_sqCBuffData.screenInfo.w = 0.f;
304+
297305
UINT nConstantBufferSize = (sizeof(this->m_sqCBuffData) + 255) & ~255;
298306

299307
renderer->CreateBuffer(&this->m_sqCBuffData, nConstantBufferSize, m_sqCBuffer);
@@ -310,9 +318,6 @@ void ScreenQuad::InitConstantBuffer() {
310318

311319
this->m_dev->CreateConstantBufferView(&cbvDesc, sqBuffDesc.cpuHandle);
312320

313-
Scene* scene = m_sceneMgr->GetCurrentScene();
314-
std::vector<Light*> lights = scene->GetLights();
315-
316321
std::vector<LightBuffer> lightArray;
317322
for (Light* light : lights) {
318323
lightArray.push_back(light->m_lightBuffer);
@@ -337,7 +342,8 @@ void ScreenQuad::InitConstantBuffer() {
337342

338343
void ScreenQuad::UpdateConstantBuffer() {
339344
if (D3D12* renderer = dynamic_cast<D3D12*>(this->m_renderer)) {
340-
Camera* currentCamera = this->m_sceneMgr->GetCurrentScene()->GetCurrentCamera();
345+
Scene* scene = m_sceneMgr->GetCurrentScene();
346+
Camera* currentCamera = scene->GetCurrentCamera();
341347

342348
Transform cameraTransform = this->m_sceneMgr->GetCurrentScene()->GetCurrentCamera()->transform;
343349
XMVECTOR eye = XMVectorSet(
@@ -374,22 +380,25 @@ void ScreenQuad::UpdateConstantBuffer() {
374380
this->m_sqCBuffData.InverseProjection = XMMatrixInverse(nullptr, this->m_sqCBuffData.InverseProjection);
375381

376382

377-
this->m_sqCBuffData.cameraPosition = XMFLOAT3(
383+
this->m_sqCBuffData.cameraPosition = XMFLOAT4(
378384
currentCamera->transform.location.x,
379385
currentCamera->transform.location.y,
380-
currentCamera->transform.location.z
386+
currentCamera->transform.location.z,
387+
0.f
381388
);
382389

390+
std::vector<Light*> lights = scene->GetLights();
391+
this->m_sqCBuffData.screenInfo.x = renderer->m_nWidth;
392+
this->m_sqCBuffData.screenInfo.y = renderer->m_nHeight;
393+
this->m_sqCBuffData.screenInfo.z = lights.size();
394+
383395
UINT nConstantBufferSize = (sizeof(this->m_sqCBuffData) + 255) & ~255;
384396

385397
PVOID pData;
386398
ThrowIfFailed(this->m_sqCBuffer->Map(0, nullptr, &pData));
387399
memcpy(pData, &this->m_sqCBuffData, nConstantBufferSize);
388400
this->m_sqCBuffer->Unmap(0, nullptr);
389401

390-
Scene* scene = m_sceneMgr->GetCurrentScene();
391-
std::vector<Light*> lights = scene->GetLights();
392-
393402
std::vector<LightBuffer> lightArray;
394403
for (Light* light : lights) {
395404
lightArray.push_back(light->m_lightBuffer);

src/public/Core/Renderer/ScreenQuad.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class ResourceManager;
2323
struct ScreenQuadBuffer {
2424
XMMATRIX InverseView;
2525
XMMATRIX InverseProjection;
26-
XMFLOAT3 cameraPosition;
27-
XMFLOAT2 screenSize;
26+
XMFLOAT4 cameraPosition;
27+
XMFLOAT4 screenInfo;
2828
};
2929

3030
struct SkyboxBuffer {

0 commit comments

Comments
 (0)