From 538d516c9a2aea3014c10b9c76a9a25c17becdb5 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 2 Mar 2017 18:07:47 +0100 Subject: [PATCH] Upload shadow map index for each light to main.fp Move storage buffer binding location --- src/gl/dynlights/gl_dynlight1.cpp | 6 +++++- src/gl/dynlights/gl_shadowmap.cpp | 25 ++++++++++++++----------- src/gl/dynlights/gl_shadowmap.h | 8 +++++++- wadsrc/static/shaders/glsl/main.fp | 2 +- wadsrc/static/shaders/glsl/shadowmap.fp | 10 +++++----- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index 2f8ef44edc..4037545aa8 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -108,6 +108,10 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD i = 1; } + float shadowIndex = (float)GLRenderer->mShadowMap.ShadowMapIndex(light); + if (!!(light->flags4 & MF4_ATTENUATE)) // Store attenuate flag in the sign bit of the float + shadowIndex = -shadowIndex; + float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)]; data[0] = pos.X; data[1] = pos.Z; @@ -116,7 +120,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD data[4] = r; data[5] = g; data[6] = b; - data[7] = !!(light->flags4 & MF4_ATTENUATE); + data[7] = shadowIndex; return true; } diff --git a/src/gl/dynlights/gl_shadowmap.cpp b/src/gl/dynlights/gl_shadowmap.cpp index d0b6f77150..b1c95ff03a 100644 --- a/src/gl/dynlights/gl_shadowmap.cpp +++ b/src/gl/dynlights/gl_shadowmap.cpp @@ -53,7 +53,7 @@ void FShadowMap::Update() GLRenderer->mBuffers->BindShadowMapFB(); GLRenderer->mShadowMapShader->Bind(); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mLightList); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mLightBSP.GetNodesBuffer()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLightBSP.GetSegsBuffer()); @@ -63,7 +63,7 @@ void FShadowMap::Update() const auto &viewport = GLRenderer->mScreenViewport; glViewport(viewport.left, viewport.top, viewport.width, viewport.height); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0); @@ -72,7 +72,8 @@ void FShadowMap::Update() void FShadowMap::UploadLights() { - lights.Clear(); + mLights.Clear(); + mLightToShadowmap.Clear(mLightToShadowmap.CountUsed() * 2); // To do: allow clearing a TMap while building up a reserve TThinkerIterator it(STAT_DLIGHT); while (true) @@ -80,17 +81,19 @@ void FShadowMap::UploadLights() ADynamicLight *light = it.Next(); if (!light) break; - lights.Push(light->X()); - lights.Push(light->Y()); - lights.Push(light->Z()); - lights.Push(light->GetRadius()); + mLightToShadowmap[light] = mLights.Size(); - if (lights.Size() == 1024) // Only 1024 lights for now + mLights.Push(light->X()); + mLights.Push(light->Y()); + mLights.Push(light->Z()); + mLights.Push(light->GetRadius()); + + if (mLights.Size() == 1024) // Only 1024 lights for now break; } - while (lights.Size() < 1024 * 4) - lights.Push(0.0f); + while (mLights.Size() < 1024 * 4) + mLights.Push(0.0f); if (mLightList == 0) glGenBuffers(1, (GLuint*)&mLightList); @@ -98,6 +101,6 @@ void FShadowMap::UploadLights() int oldBinding = 0; glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding); glBindBuffer(GL_SHADER_STORAGE_BUFFER, mLightList); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float) * lights.Size(), &lights[0], GL_STATIC_DRAW); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float) * mLights.Size(), &mLights[0], GL_STATIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding); } \ No newline at end of file diff --git a/src/gl/dynlights/gl_shadowmap.h b/src/gl/dynlights/gl_shadowmap.h index 1289965f22..cc32ec7776 100644 --- a/src/gl/dynlights/gl_shadowmap.h +++ b/src/gl/dynlights/gl_shadowmap.h @@ -2,6 +2,9 @@ #pragma once #include "gl/dynlights/gl_lightbsp.h" +#include "tarray.h" + +class ADynamicLight; class FShadowMap { @@ -12,12 +15,15 @@ public: void Clear(); void Update(); + int ShadowMapIndex(ADynamicLight *light) { return mLightToShadowmap[light]; } + private: void UploadLights(); FLightBSP mLightBSP; int mLightList = 0; - TArray lights; + TArray mLights; + TMap mLightToShadowmap; FShadowMap(const FShadowMap &) = delete; FShadowMap &operator=(FShadowMap &) = delete; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index a6bc6bbd7f..2e27e57702 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -154,7 +154,7 @@ float diffuseContribution(vec3 lightDirection, vec3 normal) float pointLightAttenuation(vec4 lightpos, float attenuate) { float attenuation = max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; - if (attenuate == 0.0) + if (attenuate >= 0.0) // Sign bit is the attenuate flag { return attenuation; } diff --git a/wadsrc/static/shaders/glsl/shadowmap.fp b/wadsrc/static/shaders/glsl/shadowmap.fp index 9b5fc27829..1c9b3a754b 100644 --- a/wadsrc/static/shaders/glsl/shadowmap.fp +++ b/wadsrc/static/shaders/glsl/shadowmap.fp @@ -16,11 +16,6 @@ struct GPUSeg vec4 bSolid; }; -layout(std430, binding = 1) buffer LightList -{ - vec4 lights[]; -}; - layout(std430, binding = 2) buffer LightNodes { GPUNode bspNodes[]; @@ -31,6 +26,11 @@ layout(std430, binding = 3) buffer LightSegs GPUSeg bspSegs[]; }; +layout(std430, binding = 4) buffer LightList +{ + vec4 lights[]; +}; + //=========================================================================== // // Ray/BSP collision test. Returns where the ray hit something.