From 0d1deddae57a4dcdb9eaa1e31e8405888a1357d6 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 2 Mar 2017 19:10:57 +0100 Subject: [PATCH] Bind shadow map texture for main.fp and sample from the shadowmap texture --- src/gl/dynlights/gl_shadowmap.cpp | 2 ++ src/gl/shaders/gl_shader.cpp | 3 +++ wadsrc/static/shaders/glsl/main.fp | 34 ++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/gl/dynlights/gl_shadowmap.cpp b/src/gl/dynlights/gl_shadowmap.cpp index b1c95ff03a..b70304db0a 100644 --- a/src/gl/dynlights/gl_shadowmap.cpp +++ b/src/gl/dynlights/gl_shadowmap.cpp @@ -67,6 +67,8 @@ void FShadowMap::Update() glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, 0); + GLRenderer->mBuffers->BindShadowMapTexture(16); + FGLDebug::PopGroup(); } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 421139050c..d36f4c4fa7 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -270,6 +270,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * if (tempindex > 0) glUniform1i(tempindex, i - 1); } + int shadowmapindex = glGetUniformLocation(hShader, "ShadowMap"); + if (shadowmapindex > 0) glUniform1i(shadowmapindex, 16); + glUseProgram(0); return !!linked; } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 2e27e57702..0d4cf0607e 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -26,6 +26,7 @@ out vec4 FragNormal; uniform sampler2D tex; +uniform sampler2D ShadowMap; vec4 Process(vec4 color); vec4 ProcessTexel(); @@ -132,6 +133,34 @@ float R_DoomLightingEquation(float light) return lightscale; } +//=========================================================================== +// +// Check if light is in shadow according to its 1D shadow map +// +//=========================================================================== + +float shadowmapAttenuation(vec4 lightpos, float shadowIndex) +{ + float u; + float v = (abs(shadowIndex) + 0.5) / 1024.0; + vec2 dir = (pixelpos.xz - lightpos.xz); + if (abs(dir.x) > abs(dir.y)) + { + if (dir.x >= 0.0) + u = dir.y / dir.x * 0.125 + (0.25 + 0.125); + else + u = dir.y / dir.x * 0.125 + (0.75 + 0.125); + } + else + { + if (dir.y >= 0.0) + u = dir.x / dir.y * 0.125 + 0.125; + else + u = dir.x / dir.y * 0.125 + (0.50 + 0.125); + } + return texture(ShadowMap, vec2(u, v)).x < dot(dir, dir) ? 1.0 : 0.0; +} + //=========================================================================== // // Standard lambertian diffuse light calculation @@ -151,10 +180,11 @@ float diffuseContribution(vec3 lightDirection, vec3 normal) // //=========================================================================== -float pointLightAttenuation(vec4 lightpos, float attenuate) +float pointLightAttenuation(vec4 lightpos, float shadowIndex) { float attenuation = max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; - if (attenuate >= 0.0) // Sign bit is the attenuate flag + attenuation *= shadowmapAttenuation(lightpos, shadowIndex); + if (shadowIndex >= 0.0) // Sign bit is the attenuated light flag { return attenuation; }