- Add gl_shadowmap_quality cvar that controls the resolution of the 1D shadow map texture

This commit is contained in:
Magnus Norddahl 2017-06-04 00:44:49 +02:00
parent 265df4b797
commit 7acb492852
8 changed files with 47 additions and 14 deletions

View file

@ -82,6 +82,23 @@ ADD_STAT(shadowmap)
return out; return out;
} }
CUSTOM_CVAR(Int, gl_shadowmap_quality, 128, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
switch (self)
{
case 32:
case 64:
case 128:
case 256:
case 512:
case 1024:
break;
default:
self = 128;
break;
}
}
void FShadowMap::Update() void FShadowMap::Update()
{ {
UpdateCycles.Reset(); UpdateCycles.Reset();
@ -102,11 +119,12 @@ void FShadowMap::Update()
GLRenderer->mBuffers->BindShadowMapFB(); GLRenderer->mBuffers->BindShadowMapFB();
GLRenderer->mShadowMapShader->Bind(); GLRenderer->mShadowMapShader->Bind();
GLRenderer->mShadowMapShader->ShadowmapQuality.Set(gl_shadowmap_quality);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer);
glViewport(0, 0, SHADOWMAP_QUALITY, 1024); glViewport(0, 0, gl_shadowmap_quality, 1024);
GLRenderer->RenderScreenQuad(); GLRenderer->RenderScreenQuad();
const auto &viewport = GLRenderer->mScreenViewport; const auto &viewport = GLRenderer->mScreenViewport;

View file

@ -8,10 +8,6 @@
class ADynamicLight; class ADynamicLight;
struct level_info_t; struct level_info_t;
// This constant must match the same constant in shadowmap.fp
//#define SHADOWMAP_QUALITY 1024
#define SHADOWMAP_QUALITY 128
class FShadowMap class FShadowMap
{ {
public: public:

View file

@ -81,6 +81,7 @@ FGLRenderBuffers::~FGLRenderBuffers()
ClearBloom(); ClearBloom();
ClearExposureLevels(); ClearExposureLevels();
ClearAmbientOcclusion(); ClearAmbientOcclusion();
ClearShadowMap();
} }
void FGLRenderBuffers::ClearScene() void FGLRenderBuffers::ClearScene()
@ -759,18 +760,27 @@ void FGLRenderBuffers::BindShadowMapTexture(int texunit)
glBindTexture(GL_TEXTURE_2D, mShadowMapTexture); glBindTexture(GL_TEXTURE_2D, mShadowMapTexture);
} }
void FGLRenderBuffers::ClearShadowMap()
{
DeleteFrameBuffer(mShadowMapFB);
DeleteTexture(mShadowMapTexture);
mCurrentShadowMapSize = 0;
}
void FGLRenderBuffers::CreateShadowMap() void FGLRenderBuffers::CreateShadowMap()
{ {
if (mShadowMapTexture != 0) if (mShadowMapTexture != 0 && gl_shadowmap_quality == mCurrentShadowMapSize)
return; return;
ClearShadowMap();
GLint activeTex, textureBinding, frameBufferBinding; GLint activeTex, textureBinding, frameBufferBinding;
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding);
mShadowMapTexture = Create2DTexture("ShadowMap", GL_R32F, SHADOWMAP_QUALITY, 1024); mShadowMapTexture = Create2DTexture("ShadowMap", GL_R32F, gl_shadowmap_quality, 1024);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -781,6 +791,8 @@ void FGLRenderBuffers::CreateShadowMap()
glBindTexture(GL_TEXTURE_2D, textureBinding); glBindTexture(GL_TEXTURE_2D, textureBinding);
glActiveTexture(activeTex); glActiveTexture(activeTex);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding); glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding);
mCurrentShadowMapSize = gl_shadowmap_quality;
} }
//========================================================================== //==========================================================================

View file

@ -87,6 +87,7 @@ private:
void ClearBloom(); void ClearBloom();
void ClearExposureLevels(); void ClearExposureLevels();
void ClearAmbientOcclusion(); void ClearAmbientOcclusion();
void ClearShadowMap();
void CreateScene(int width, int height, int samples, bool needsSceneTextures); void CreateScene(int width, int height, int samples, bool needsSceneTextures);
void CreatePipeline(int width, int height); void CreatePipeline(int width, int height);
void CreateBloom(int width, int height); void CreateBloom(int width, int height);
@ -140,6 +141,7 @@ private:
// Shadow map texture // Shadow map texture
GLuint mShadowMapTexture = 0; GLuint mShadowMapTexture = 0;
GLuint mShadowMapFB = 0; GLuint mShadowMapFB = 0;
int mCurrentShadowMapSize = 0;
static bool FailedCreate; static bool FailedCreate;
static bool BuffersActive; static bool BuffersActive;

View file

@ -40,6 +40,7 @@ void FShadowMapShader::Bind()
mShader.SetFragDataLocation(0, "FragColor"); mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/shadowmap"); mShader.Link("shaders/glsl/shadowmap");
mShader.SetAttribLocation(0, "PositionInProjection"); mShader.SetAttribLocation(0, "PositionInProjection");
ShadowmapQuality.Init(mShader, "ShadowmapQuality");
} }
mShader.Bind(); mShader.Bind();
} }

View file

@ -8,6 +8,8 @@ class FShadowMapShader
public: public:
void Bind(); void Bind();
FBufferedUniform1f ShadowmapQuality;
private: private:
FShaderProgram mShader; FShaderProgram mShader;
}; };

View file

@ -27,6 +27,7 @@ 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 (Bool, gl_light_shadowmap);
EXTERN_CVAR (Int, gl_shadowmap_quality);
EXTERN_CVAR(Int, gl_fogmode) EXTERN_CVAR(Int, gl_fogmode)
EXTERN_CVAR(Int, gl_lightmode) EXTERN_CVAR(Int, gl_lightmode)

View file

@ -3,8 +3,9 @@ in vec2 TexCoord;
out vec4 FragColor; out vec4 FragColor;
// This constant must match the same constant in gl_shadowmap.h // This constant must match the same constant in gl_shadowmap.h
// #define SHADOWMAP_QUALITY 1024 // #define ShadowmapQuality 1024
#define SHADOWMAP_QUALITY 128 //#define ShadowmapQuality 128
uniform float ShadowmapQuality;
struct GPUNode struct GPUNode
{ {
@ -144,12 +145,12 @@ void main()
if (radius > 0.0) if (radius > 0.0)
{ {
vec2 pixelpos; vec2 pixelpos;
switch (int(gl_FragCoord.x) / int(SHADOWMAP_QUALITY/4)) switch (int(gl_FragCoord.x) / int(ShadowmapQuality/4.0))
{ {
case 0: pixelpos = vec2((gl_FragCoord.x - float(SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8), 1.0); break; case 0: pixelpos = vec2((gl_FragCoord.x - float(ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0), 1.0); break;
case 1: pixelpos = vec2(1.0, (gl_FragCoord.x - float(SHADOWMAP_QUALITY/4 + SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8)); break; case 1: pixelpos = vec2(1.0, (gl_FragCoord.x - float(ShadowmapQuality/4.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0)); break;
case 2: pixelpos = vec2(-(gl_FragCoord.x - float(SHADOWMAP_QUALITY/2 + SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8), -1.0); break; case 2: pixelpos = vec2(-(gl_FragCoord.x - float(ShadowmapQuality/2.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0), -1.0); break;
case 3: pixelpos = vec2(-1.0, -(gl_FragCoord.x - float(SHADOWMAP_QUALITY*3/4 + SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8)); break; case 3: pixelpos = vec2(-1.0, -(gl_FragCoord.x - float(ShadowmapQuality*3.0/4.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0)); break;
} }
pixelpos = lightpos + pixelpos * radius; pixelpos = lightpos + pixelpos * radius;