Upload shadow map index for each light to main.fp

Move storage buffer binding location
This commit is contained in:
Magnus Norddahl 2017-03-02 18:07:47 +01:00
parent d450deee76
commit 538d516c9a
5 changed files with 32 additions and 19 deletions

View file

@ -108,6 +108,10 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD
i = 1; 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)]; float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)];
data[0] = pos.X; data[0] = pos.X;
data[1] = pos.Z; data[1] = pos.Z;
@ -116,7 +120,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD
data[4] = r; data[4] = r;
data[5] = g; data[5] = g;
data[6] = b; data[6] = b;
data[7] = !!(light->flags4 & MF4_ATTENUATE); data[7] = shadowIndex;
return true; return true;
} }

View file

@ -53,7 +53,7 @@ void FShadowMap::Update()
GLRenderer->mBuffers->BindShadowMapFB(); GLRenderer->mBuffers->BindShadowMapFB();
GLRenderer->mShadowMapShader->Bind(); 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, 2, mLightBSP.GetNodesBuffer());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLightBSP.GetSegsBuffer()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLightBSP.GetSegsBuffer());
@ -63,7 +63,7 @@ void FShadowMap::Update()
const auto &viewport = GLRenderer->mScreenViewport; const auto &viewport = GLRenderer->mScreenViewport;
glViewport(viewport.left, viewport.top, viewport.width, viewport.height); 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, 2, 0);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0);
@ -72,7 +72,8 @@ void FShadowMap::Update()
void FShadowMap::UploadLights() void FShadowMap::UploadLights()
{ {
lights.Clear(); mLights.Clear();
mLightToShadowmap.Clear(mLightToShadowmap.CountUsed() * 2); // To do: allow clearing a TMap while building up a reserve
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT); TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
while (true) while (true)
@ -80,17 +81,19 @@ void FShadowMap::UploadLights()
ADynamicLight *light = it.Next(); ADynamicLight *light = it.Next();
if (!light) break; if (!light) break;
lights.Push(light->X()); mLightToShadowmap[light] = mLights.Size();
lights.Push(light->Y());
lights.Push(light->Z());
lights.Push(light->GetRadius());
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; break;
} }
while (lights.Size() < 1024 * 4) while (mLights.Size() < 1024 * 4)
lights.Push(0.0f); mLights.Push(0.0f);
if (mLightList == 0) if (mLightList == 0)
glGenBuffers(1, (GLuint*)&mLightList); glGenBuffers(1, (GLuint*)&mLightList);
@ -98,6 +101,6 @@ void FShadowMap::UploadLights()
int oldBinding = 0; int oldBinding = 0;
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding); glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mLightList); 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); glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding);
} }

View file

@ -2,6 +2,9 @@
#pragma once #pragma once
#include "gl/dynlights/gl_lightbsp.h" #include "gl/dynlights/gl_lightbsp.h"
#include "tarray.h"
class ADynamicLight;
class FShadowMap class FShadowMap
{ {
@ -12,12 +15,15 @@ public:
void Clear(); void Clear();
void Update(); void Update();
int ShadowMapIndex(ADynamicLight *light) { return mLightToShadowmap[light]; }
private: private:
void UploadLights(); void UploadLights();
FLightBSP mLightBSP; FLightBSP mLightBSP;
int mLightList = 0; int mLightList = 0;
TArray<float> lights; TArray<float> mLights;
TMap<ADynamicLight*, int> mLightToShadowmap;
FShadowMap(const FShadowMap &) = delete; FShadowMap(const FShadowMap &) = delete;
FShadowMap &operator=(FShadowMap &) = delete; FShadowMap &operator=(FShadowMap &) = delete;

View file

@ -154,7 +154,7 @@ float diffuseContribution(vec3 lightDirection, vec3 normal)
float pointLightAttenuation(vec4 lightpos, float attenuate) float pointLightAttenuation(vec4 lightpos, float attenuate)
{ {
float attenuation = max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; 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; return attenuation;
} }

View file

@ -16,11 +16,6 @@ struct GPUSeg
vec4 bSolid; vec4 bSolid;
}; };
layout(std430, binding = 1) buffer LightList
{
vec4 lights[];
};
layout(std430, binding = 2) buffer LightNodes layout(std430, binding = 2) buffer LightNodes
{ {
GPUNode bspNodes[]; GPUNode bspNodes[];
@ -31,6 +26,11 @@ layout(std430, binding = 3) buffer LightSegs
GPUSeg bspSegs[]; GPUSeg bspSegs[];
}; };
layout(std430, binding = 4) buffer LightList
{
vec4 lights[];
};
//=========================================================================== //===========================================================================
// //
// Ray/BSP collision test. Returns where the ray hit something. // Ray/BSP collision test. Returns where the ray hit something.