OpenGL2: Add r_shadowBlur.

This commit is contained in:
SmileTheory 2016-03-07 02:27:03 -08:00
parent a331637745
commit 90d6f941f8
6 changed files with 73 additions and 43 deletions

View File

@ -1,13 +1,13 @@
uniform sampler2D u_ScreenImageMap; uniform sampler2D u_ScreenImageMap;
uniform sampler2D u_ScreenDepthMap; uniform sampler2D u_ScreenDepthMap;
uniform vec4 u_ViewInfo; // zfar / znear, zfar uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
varying vec2 var_ScreenTex; varying vec2 var_ScreenTex;
//float gauss[5] = float[5](0.30, 0.23, 0.097, 0.024, 0.0033); //float gauss[5] = float[5](0.30, 0.23, 0.097, 0.024, 0.0033);
float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044); float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044);
//float gauss[3] = float[3](0.60, 0.19, 0.0066); //float gauss[3] = float[3](0.60, 0.19, 0.0066);
#define GAUSS_SIZE 4 #define BLUR_SIZE 4
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
{ {
@ -17,7 +17,7 @@ float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNea
vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar) vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar)
{ {
float scale = 1.0 / 256.0; vec2 scale = u_ViewInfo.zw;
#if defined(USE_HORIZONTAL_BLUR) #if defined(USE_HORIZONTAL_BLUR)
vec2 direction = vec2(1.0, 0.0) * scale; vec2 direction = vec2(1.0, 0.0) * scale;
@ -27,22 +27,32 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa
float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear); float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
vec2 centerSlope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y)); vec2 centerSlope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
#if defined(USE_GAUSS)
vec4 result = texture2D(imageMap, tex) * gauss[0]; vec4 result = texture2D(imageMap, tex) * gauss[0];
float total = gauss[0]; float total = gauss[0];
#else
vec4 result = texture2D(imageMap, tex);
float total = 1.0;
#endif
int i, j; int i, j;
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
for (j = 1; j < GAUSS_SIZE; j++) for (j = 1; j < BLUR_SIZE; j++)
{ {
vec2 offset = direction * j; vec2 offset = direction * j;
float depthSample = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear); float depthSample = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
float depthExpected = depthCenter + dot(centerSlope, offset); float depthExpected = depthCenter + dot(centerSlope, offset);
if(abs(depthSample - depthExpected) < 5.0) if(abs(depthSample - depthExpected) < 5.0)
{ {
#if defined(USE_GAUSS)
result += texture2D(imageMap, tex + offset) * gauss[j]; result += texture2D(imageMap, tex + offset) * gauss[j];
total += gauss[j]; total += gauss[j];
#else
result += texture2D(imageMap, tex + offset);
total += 1.0;
#endif
} }
} }

View File

@ -956,6 +956,9 @@ const void *RB_DrawSurfs( const void *data ) {
if (glRefConfig.framebufferObject && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL) && (r_depthPrepass->integer || (backEnd.viewParms.flags & VPF_DEPTHSHADOW))) if (glRefConfig.framebufferObject && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL) && (r_depthPrepass->integer || (backEnd.viewParms.flags & VPF_DEPTHSHADOW)))
{ {
FBO_t *oldFbo = glState.currentFBO; FBO_t *oldFbo = glState.currentFBO;
vec4_t viewInfo;
VectorSet4(viewInfo, backEnd.viewParms.zFar / r_znear->value, backEnd.viewParms.zFar, 0.0, 0.0);
backEnd.depthFill = qtrue; backEnd.depthFill = qtrue;
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@ -1042,15 +1045,12 @@ const void *RB_DrawSurfs( const void *data ) {
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg); GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg);
{ {
vec4_t viewInfo;
vec3_t viewVector; vec3_t viewVector;
float zmax = backEnd.viewParms.zFar; float zmax = backEnd.viewParms.zFar;
float ymax = zmax * tan(backEnd.viewParms.fovY * M_PI / 360.0f); float ymax = zmax * tan(backEnd.viewParms.fovY * M_PI / 360.0f);
float xmax = zmax * tan(backEnd.viewParms.fovX * M_PI / 360.0f); float xmax = zmax * tan(backEnd.viewParms.fovX * M_PI / 360.0f);
float zmin = r_znear->value;
VectorScale(backEnd.refdef.viewaxis[0], zmax, viewVector); VectorScale(backEnd.refdef.viewaxis[0], zmax, viewVector);
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWFORWARD, viewVector); GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWFORWARD, viewVector);
VectorScale(backEnd.refdef.viewaxis[1], xmax, viewVector); VectorScale(backEnd.refdef.viewaxis[1], xmax, viewVector);
@ -1058,13 +1058,39 @@ const void *RB_DrawSurfs( const void *data ) {
VectorScale(backEnd.refdef.viewaxis[2], ymax, viewVector); VectorScale(backEnd.refdef.viewaxis[2], ymax, viewVector);
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWUP, viewVector); GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWUP, viewVector);
VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
GLSL_SetUniformVec4(&tr.shadowmaskShader, UNIFORM_VIEWINFO, viewInfo); GLSL_SetUniformVec4(&tr.shadowmaskShader, UNIFORM_VIEWINFO, viewInfo);
} }
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes); RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
if (r_shadowBlur->integer)
{
viewInfo[2] = 1.0f / (float)(tr.screenScratchFbo->width);
viewInfo[3] = 1.0f / (float)(tr.screenScratchFbo->height);
FBO_Bind(tr.screenScratchFbo);
GLSL_BindProgram(&tr.depthBlurShader[0]);
GL_BindToTMU(tr.screenShadowImage, TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords);
FBO_Bind(tr.screenShadowFbo);
GLSL_BindProgram(&tr.depthBlurShader[1]);
GL_BindToTMU(tr.screenScratchImage, TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords);
}
} }
if (r_ssao->integer) if (r_ssao->integer)
@ -1072,6 +1098,9 @@ const void *RB_DrawSurfs( const void *data ) {
vec4_t quadVerts[4]; vec4_t quadVerts[4];
vec2_t texCoords[4]; vec2_t texCoords[4];
viewInfo[2] = 1.0f / (float)(tr.quarterImage[0]->width);
viewInfo[3] = 1.0f / (float)(tr.quarterImage[0]->height);
FBO_Bind(tr.quarterFbo[0]); FBO_Bind(tr.quarterFbo[0]);
qglViewport(0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height); qglViewport(0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height);
@ -1093,16 +1122,7 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.hdrDepthImage, TB_COLORMAP); GL_BindToTMU(tr.hdrDepthImage, TB_COLORMAP);
{ GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
vec4_t viewInfo;
float zmax = backEnd.viewParms.zFar;
float zmin = r_znear->value;
VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
}
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes); RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
@ -1117,16 +1137,7 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP); GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP); GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
{ GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
vec4_t viewInfo;
float zmax = backEnd.viewParms.zFar;
float zmin = r_znear->value;
VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
}
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes); RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
@ -1141,16 +1152,7 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP); GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP); GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
{ GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
vec4_t viewInfo;
float zmax = backEnd.viewParms.zFar;
float zmin = r_znear->value;
VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
}
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes); RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);

View File

@ -310,6 +310,14 @@ void FBO_Init(void)
qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
} }
if (r_shadowBlur->integer)
{
tr.screenScratchFbo = FBO_Create("screenScratch", tr.screenScratchImage->width, tr.screenScratchImage->height);
FBO_AttachImage(tr.screenScratchFbo, tr.screenScratchImage, GL_COLOR_ATTACHMENT0_EXT, 0);
FBO_AttachImage(tr.screenScratchFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0);
R_CheckFBO(tr.screenScratchFbo);
}
if (r_drawSunRays->integer) if (r_drawSunRays->integer)
{ {
tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height); tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height);

View File

@ -2754,6 +2754,12 @@ void R_CreateBuiltinImages( void ) {
tr.renderImage = R_CreateImage("_render", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat); tr.renderImage = R_CreateImage("_render", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat);
if (r_shadowBlur->integer)
tr.screenScratchImage = R_CreateImage("screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
if (r_shadowBlur->integer || r_ssao->integer)
tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
if (r_drawSunRays->integer) if (r_drawSunRays->integer)
tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat); tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
@ -2801,7 +2807,6 @@ void R_CreateBuiltinImages( void ) {
if (r_ssao->integer) if (r_ssao->integer)
{ {
tr.screenSsaoImage = R_CreateImage("*screenSsao", NULL, width / 2, height / 2, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); tr.screenSsaoImage = R_CreateImage("*screenSsao", NULL, width / 2, height / 2, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB);
} }
if (r_shadows->integer == 4) if (r_shadows->integer == 4)

View File

@ -162,6 +162,7 @@ cvar_t *r_sunlightMode;
cvar_t *r_drawSunRays; cvar_t *r_drawSunRays;
cvar_t *r_sunShadows; cvar_t *r_sunShadows;
cvar_t *r_shadowFilter; cvar_t *r_shadowFilter;
cvar_t *r_shadowBlur;
cvar_t *r_shadowMapSize; cvar_t *r_shadowMapSize;
cvar_t *r_shadowCascadeZNear; cvar_t *r_shadowCascadeZNear;
cvar_t *r_shadowCascadeZFar; cvar_t *r_shadowCascadeZFar;
@ -1252,7 +1253,8 @@ void R_Register( void )
r_sunShadows = ri.Cvar_Get( "r_sunShadows", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_sunShadows = ri.Cvar_Get( "r_sunShadows", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowFilter = ri.Cvar_Get( "r_shadowFilter", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_shadowFilter = ri.Cvar_Get( "r_shadowFilter", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowMapSize = ri.Cvar_Get( "r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH ); r_shadowBlur = ri.Cvar_Get("r_shadowBlur", "0", CVAR_ARCHIVE | CVAR_LATCH);
r_shadowMapSize = ri.Cvar_Get("r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH);
r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "8", CVAR_ARCHIVE | CVAR_LATCH ); r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "8", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "1024", CVAR_ARCHIVE | CVAR_LATCH ); r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "1024", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "0", CVAR_ARCHIVE | CVAR_LATCH );

View File

@ -1520,6 +1520,7 @@ typedef struct {
image_t *sunRaysImage; image_t *sunRaysImage;
image_t *renderDepthImage; image_t *renderDepthImage;
image_t *pshadowMaps[MAX_DRAWN_PSHADOWS]; image_t *pshadowMaps[MAX_DRAWN_PSHADOWS];
image_t *screenScratchImage;
image_t *textureScratchImage[2]; image_t *textureScratchImage[2];
image_t *quarterImage[2]; image_t *quarterImage[2];
image_t *calcLevelsImage; image_t *calcLevelsImage;
@ -1538,6 +1539,7 @@ typedef struct {
FBO_t *sunRaysFbo; FBO_t *sunRaysFbo;
FBO_t *depthFbo; FBO_t *depthFbo;
FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS]; FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS];
FBO_t *screenScratchFbo;
FBO_t *textureScratchFbo[2]; FBO_t *textureScratchFbo[2];
FBO_t *quarterFbo[2]; FBO_t *quarterFbo[2];
FBO_t *calcLevelsFbo; FBO_t *calcLevelsFbo;
@ -1807,6 +1809,7 @@ extern cvar_t *r_sunlightMode;
extern cvar_t *r_drawSunRays; extern cvar_t *r_drawSunRays;
extern cvar_t *r_sunShadows; extern cvar_t *r_sunShadows;
extern cvar_t *r_shadowFilter; extern cvar_t *r_shadowFilter;
extern cvar_t *r_shadowBlur;
extern cvar_t *r_shadowMapSize; extern cvar_t *r_shadowMapSize;
extern cvar_t *r_shadowCascadeZNear; extern cvar_t *r_shadowCascadeZNear;
extern cvar_t *r_shadowCascadeZFar; extern cvar_t *r_shadowCascadeZFar;