mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
store shadow map index in the light actor instead of a separate TMap
This frees another file of a direct renderer dependency and generally also should be faster
This commit is contained in:
parent
4a3f7e8dd5
commit
f57c804a5a
4 changed files with 25 additions and 31 deletions
|
@ -229,5 +229,7 @@ public:
|
|||
LightFlags lightflags;
|
||||
DAngle SpotInnerAngle = 10.0;
|
||||
DAngle SpotOuterAngle = 25.0;
|
||||
|
||||
int mShadowmapIndex = 1024;
|
||||
|
||||
};
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
||||
CVAR(Int, gl_attenuate, -1, 0); // This is mainly a debug option.
|
||||
|
||||
|
@ -117,10 +116,10 @@ void gl_AddLightToList(int group, ADynamicLight * light, FDynLightData &ldata)
|
|||
i = 1;
|
||||
}
|
||||
|
||||
// Store attenuate flag in the sign bit of the float.
|
||||
float shadowIndex = GLRenderer->mShadowMap.ShadowMapIndex(light) + 1.0f;
|
||||
float shadowIndex = light->mShadowmapIndex + 1.0f;
|
||||
bool attenuate;
|
||||
|
||||
// Store attenuate flag in the sign bit of the float.
|
||||
if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE);
|
||||
else attenuate = !!gl_attenuate;
|
||||
|
||||
|
|
|
@ -42,12 +42,7 @@
|
|||
the fragment shader (main.fp) needs to sample from row 20. That is, the V texture coordinate needs
|
||||
to be 20.5/1024.
|
||||
|
||||
mLightToShadowmap is a hash map storing which line each ADynamicLight is assigned to. The public
|
||||
ShadowMapIndex function allows the main rendering to find the index and upload that along with the
|
||||
normal light data. From there, the main.fp shader can sample from the shadow map texture, which
|
||||
is currently always bound to texture unit 16.
|
||||
|
||||
The texel row for each light is split into four parts. One for each direction, like a cube texture,
|
||||
The texel row for each light is split into four parts. One for each direction, like a cube texture,
|
||||
but then only in 2D where this reduces itself to a square. When main.fp samples from the shadow map
|
||||
it first decides in which direction the fragment is (relative to the light), like cubemap sampling does
|
||||
for 3D, but once again just for the 2D case.
|
||||
|
@ -97,6 +92,20 @@ CUSTOM_CVAR(Int, gl_shadowmap_quality, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Bool, gl_light_shadowmap, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
// Unset any residual shadow map indices in the light actors.
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
while (auto light = it.Next())
|
||||
{
|
||||
light->mShadowmapIndex = 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FShadowMap::Update()
|
||||
{
|
||||
UpdateCycles.Reset();
|
||||
|
@ -152,42 +161,32 @@ bool FShadowMap::IsEnabled() const
|
|||
return gl_light_shadowmap && !!(gl.flags & RFL_SHADER_STORAGE_BUFFER);
|
||||
}
|
||||
|
||||
int FShadowMap::ShadowMapIndex(ADynamicLight *light)
|
||||
{
|
||||
if (IsEnabled())
|
||||
{
|
||||
auto val = mLightToShadowmap.CheckKey(light);
|
||||
if (val != nullptr) return *val;
|
||||
}
|
||||
return 1024;
|
||||
}
|
||||
|
||||
void FShadowMap::UploadLights()
|
||||
{
|
||||
if (mLights.Size() != 1024 * 4) mLights.Resize(1024 * 4);
|
||||
int lightindex = 0;
|
||||
mLightToShadowmap.Clear(mLightToShadowmap.CountUsed() * 2); // To do: allow clearing a TMap while building up a reserve
|
||||
|
||||
// Todo: this should go through the blockmap in a spiral pattern around the player so that closer lights are preferred.
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
while (auto light = it.Next())
|
||||
{
|
||||
LightsProcessed++;
|
||||
if (light->shadowmapped)
|
||||
if (light->shadowmapped && lightindex < 1024 * 4)
|
||||
{
|
||||
LightsShadowmapped++;
|
||||
|
||||
mLightToShadowmap[light] = lightindex >> 2;
|
||||
light->mShadowmapIndex = lightindex >> 2;
|
||||
|
||||
mLights[lightindex] = light->X();
|
||||
mLights[lightindex+1] = light->Y();
|
||||
mLights[lightindex+2] = light->Z();
|
||||
mLights[lightindex+3] = light->GetRadius();
|
||||
lightindex += 4;
|
||||
|
||||
if (lightindex == 1024*4) // Only 1024 lights for now
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
light->mShadowmapIndex = 1024;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,6 @@ public:
|
|||
// Update shadow map texture
|
||||
void Update();
|
||||
|
||||
// Return the assigned shadow map index for a given light
|
||||
int ShadowMapIndex(ADynamicLight *light);
|
||||
|
||||
// Test if a world position is in shadow relative to the specified light and returns false if it is
|
||||
bool ShadowTest(ADynamicLight *light, const DVector3 &pos);
|
||||
|
||||
|
@ -42,9 +39,6 @@ private:
|
|||
// Working buffer for creating the list of lights. Stored here to avoid allocating memory each frame
|
||||
TArray<float> mLights;
|
||||
|
||||
// The assigned shadow map index for each light
|
||||
TMap<ADynamicLight*, int> mLightToShadowmap;
|
||||
|
||||
// OpenGL storage buffers for the AABB tree
|
||||
int mNodesBuffer = 0;
|
||||
int mLinesBuffer = 0;
|
||||
|
|
Loading…
Reference in a new issue