Add menu option for disabling shadow maps and detecting if storage buffers are available or not

This commit is contained in:
Magnus Norddahl 2017-03-10 19:10:40 +01:00
parent b281a697ce
commit b660493051
8 changed files with 40 additions and 2 deletions

View file

@ -59,6 +59,7 @@ CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_light_sprites, 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_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR (Bool, gl_light_shadowmap, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
//========================================================================== //==========================================================================
// //

View file

@ -26,6 +26,7 @@
#include "gl/dynlights/gl_dynlight.h" #include "gl/dynlights/gl_dynlight.h"
#include "gl/system/gl_interface.h" #include "gl/system/gl_interface.h"
#include "gl/system/gl_debug.h" #include "gl/system/gl_debug.h"
#include "gl/system/gl_cvars.h"
#include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_postprocessstate.h" #include "gl/renderer/gl_postprocessstate.h"
#include "gl/renderer/gl_renderbuffers.h" #include "gl/renderer/gl_renderbuffers.h"
@ -67,6 +68,9 @@
void FShadowMap::Update() void FShadowMap::Update()
{ {
if (!IsEnabled())
return;
UploadAABBTree(); UploadAABBTree();
UploadLights(); UploadLights();
@ -97,12 +101,25 @@ void FShadowMap::Update()
bool FShadowMap::ShadowTest(ADynamicLight *light, const DVector3 &pos) bool FShadowMap::ShadowTest(ADynamicLight *light, const DVector3 &pos)
{ {
if (mAABBTree) if (IsEnabled() && mAABBTree)
return mAABBTree->RayTest(light->Pos(), pos) >= 1.0f; return mAABBTree->RayTest(light->Pos(), pos) >= 1.0f;
else else
return true; return true;
} }
bool FShadowMap::IsEnabled() const
{
return gl_light_shadowmap && !!(gl.flags & RFL_SHADER_STORAGE_BUFFER);
}
int FShadowMap::ShadowMapIndex(ADynamicLight *light)
{
if (IsEnabled())
return mLightToShadowmap[light];
else
return 1024;
}
void FShadowMap::UploadLights() void FShadowMap::UploadLights()
{ {
mLights.Clear(); mLights.Clear();

View file

@ -20,11 +20,14 @@ public:
void Update(); void Update();
// Return the assigned shadow map index for a given light // Return the assigned shadow map index for a given light
int ShadowMapIndex(ADynamicLight *light) { return mLightToShadowmap[light]; } int ShadowMapIndex(ADynamicLight *light);
// Test if a world position is in shadow relative to the specified light and returns false if it is // 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); bool ShadowTest(ADynamicLight *light, const DVector3 &pos);
// Returns true if gl_light_shadowmap is enabled and supported by the hardware
bool IsEnabled() const;
private: private:
// Upload the AABB-tree to the GPU // Upload the AABB-tree to the GPU
void UploadAABBTree(); void UploadAABBTree();

View file

@ -105,6 +105,11 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
vp_comb << "#define USE_QUAD_DRAWER\n"; vp_comb << "#define USE_QUAD_DRAWER\n";
} }
if (!!(gl.flags & RFL_SHADER_STORAGE_BUFFER))
{
vp_comb << "#define SUPPORTS_SHADOWMAPS\n";
}
vp_comb << defines << i_data.GetString().GetChars(); vp_comb << defines << i_data.GetString().GetChars();
FString fp_comb = vp_comb; FString fp_comb = vp_comb;

View file

@ -26,6 +26,7 @@ EXTERN_CVAR (Bool, gl_attachedlights);
EXTERN_CVAR (Bool, gl_lights_checkside); EXTERN_CVAR (Bool, gl_lights_checkside);
EXTERN_CVAR (Bool, gl_light_sprites); EXTERN_CVAR (Bool, gl_light_sprites);
EXTERN_CVAR (Bool, gl_light_particles); EXTERN_CVAR (Bool, gl_light_particles);
EXTERN_CVAR (Bool, gl_light_shadowmap);
EXTERN_CVAR(Int, gl_fogmode) EXTERN_CVAR(Int, gl_fogmode)
EXTERN_CVAR(Int, gl_lightmode) EXTERN_CVAR(Int, gl_lightmode)

View file

@ -2656,6 +2656,7 @@ GLLIGHTMNU_LIGHTDEFS = "Enable light definitions";
GLLIGHTMNU_CLIPLIGHTS = "Clip lights"; GLLIGHTMNU_CLIPLIGHTS = "Clip lights";
GLLIGHTMNU_LIGHTSPRITES = "Lights affect sprites"; GLLIGHTMNU_LIGHTSPRITES = "Lights affect sprites";
GLLIGHTMNU_LIGHTPARTICLES = "Lights affect particles"; GLLIGHTMNU_LIGHTPARTICLES = "Lights affect particles";
GLLIGHTMNU_LIGHTSHADOWMAP = "Light shadowmaps";
// OpenGL Preferences // OpenGL Preferences
GLPREFMNU_TITLE = "OPENGL PREFERENCES"; GLPREFMNU_TITLE = "OPENGL PREFERENCES";

View file

@ -226,6 +226,7 @@ OptionMenu "GLLightOptions"
Option "$GLLIGHTMNU_CLIPLIGHTS", gl_lights_checkside, "YesNo" Option "$GLLIGHTMNU_CLIPLIGHTS", gl_lights_checkside, "YesNo"
Option "$GLLIGHTMNU_LIGHTSPRITES", gl_light_sprites, "YesNo" Option "$GLLIGHTMNU_LIGHTSPRITES", gl_light_sprites, "YesNo"
Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "YesNo" Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "YesNo"
Option "$GLLIGHTMNU_LIGHTSHADOWMAP", gl_light_shadowmap, "YesNo"
} }
OptionMenu "GLPrefOptions" OptionMenu "GLPrefOptions"

View file

@ -139,6 +139,8 @@ float R_DoomLightingEquation(float light)
// //
//=========================================================================== //===========================================================================
#ifdef SUPPORTS_SHADOWMAPS
float sampleShadowmap(vec2 lightpos, vec2 testpos, float v) float sampleShadowmap(vec2 lightpos, vec2 testpos, float v)
{ {
float u; float u;
@ -173,6 +175,9 @@ float sampleShadowmap(vec2 lightpos, vec2 testpos, float v)
float shadowmapAttenuation(vec4 lightpos, float shadowIndex) float shadowmapAttenuation(vec4 lightpos, float shadowIndex)
{ {
if (shadowIndex <= -1024.0 || shadowIndex >= 1024.0)
return 1.0; // No shadowmap available for this light
float v = (abs(shadowIndex) + 0.5) / 1024.0; float v = (abs(shadowIndex) + 0.5) / 1024.0;
vec2 dir = (pixelpos.xz - lightpos.xz); vec2 dir = (pixelpos.xz - lightpos.xz);
vec2 normal = normalize(vec2(-dir.y, dir.x)); vec2 normal = normalize(vec2(-dir.y, dir.x));
@ -184,6 +189,8 @@ float shadowmapAttenuation(vec4 lightpos, float shadowIndex)
return sum / PCF_COUNT; return sum / PCF_COUNT;
} }
#endif
//=========================================================================== //===========================================================================
// //
// Standard lambertian diffuse light calculation // Standard lambertian diffuse light calculation
@ -206,7 +213,9 @@ float diffuseContribution(vec3 lightDirection, vec3 normal)
float pointLightAttenuation(vec4 lightpos, float shadowIndex) float pointLightAttenuation(vec4 lightpos, float shadowIndex)
{ {
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;
#ifdef SUPPORTS_SHADOWMAPS
attenuation *= shadowmapAttenuation(lightpos, shadowIndex); attenuation *= shadowmapAttenuation(lightpos, shadowIndex);
#endif
if (shadowIndex >= 0.0) // Sign bit is the attenuated light flag if (shadowIndex >= 0.0) // Sign bit is the attenuated light flag
{ {
return attenuation; return attenuation;