[iortcw] 38/152: All: Rend2: Merge recents updates Add r_shadowBlur Add r_glossType Speedup for SSAO & blur shaders, fix sunlight normals in lightall Create FBOs if target image exists, not cvar settings Fixes to depth blur and ssao More ssao/depth blur improvements
Simon McVittie
smcv at debian.org
Fri Sep 8 10:39:55 UTC 2017
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to annotated tag 1.5a
in repository iortcw.
commit 9831dc25942ca81dddd289b4c29606dfd886de8b
Author: MAN-AT-ARMS <M4N4T4RMS at gmail.com>
Date: Sat Mar 12 07:26:31 2016 -0500
All: Rend2: Merge recents updates
Add r_shadowBlur
Add r_glossType
Speedup for SSAO & blur shaders, fix sunlight normals in lightall
Create FBOs if target image exists, not cvar settings
Fixes to depth blur and ssao
More ssao/depth blur improvements
---
MP/code/rend2/glsl/depthblur_fp.glsl | 69 +++++++++++++++++-----------
MP/code/rend2/glsl/depthblur_vp.glsl | 5 +-
MP/code/rend2/glsl/lightall_fp.glsl | 18 ++++++--
MP/code/rend2/glsl/ssao_fp.glsl | 54 +++++++++++-----------
MP/code/rend2/tr_backend.c | 88 +++++++++++++++++++-----------------
MP/code/rend2/tr_fbo.c | 44 +++++++++++++-----
MP/code/rend2/tr_glsl.c | 17 +++++++
MP/code/rend2/tr_image.c | 7 ++-
MP/code/rend2/tr_init.c | 6 ++-
MP/code/rend2/tr_local.h | 4 ++
SP/code/rend2/glsl/depthblur_fp.glsl | 69 +++++++++++++++++-----------
SP/code/rend2/glsl/depthblur_vp.glsl | 5 +-
SP/code/rend2/glsl/lightall_fp.glsl | 18 ++++++--
SP/code/rend2/glsl/ssao_fp.glsl | 54 +++++++++++-----------
SP/code/rend2/tr_backend.c | 88 +++++++++++++++++++-----------------
SP/code/rend2/tr_fbo.c | 44 +++++++++++++-----
SP/code/rend2/tr_glsl.c | 17 +++++++
SP/code/rend2/tr_image.c | 7 ++-
SP/code/rend2/tr_init.c | 6 ++-
SP/code/rend2/tr_local.h | 4 ++
20 files changed, 400 insertions(+), 224 deletions(-)
diff --git a/MP/code/rend2/glsl/depthblur_fp.glsl b/MP/code/rend2/glsl/depthblur_fp.glsl
index 93895b4..9685f6d 100644
--- a/MP/code/rend2/glsl/depthblur_fp.glsl
+++ b/MP/code/rend2/glsl/depthblur_fp.glsl
@@ -1,58 +1,75 @@
uniform sampler2D u_ScreenImageMap;
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;
+//float gauss[8] = float[8](0.17, 0.17, 0.16, 0.14, 0.12, 0.1, 0.08, 0.06);
//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[3] = float[3](0.60, 0.19, 0.0066);
-#define GAUSS_SIZE 4
+#define BLUR_SIZE 4
+//#define USE_GAUSS
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
{
- float sampleZDivW = texture2D(depthMap, tex).r;
- return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
+ float sampleZDivW = texture2D(depthMap, tex).r;
+ return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
}
-vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar)
+vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale)
{
- float scale = 1.0 / 256.0;
+ float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear);
+
+ // enable for less blurring for farther objects
+ scale /= clamp(zFarDivZNear * depthCenter / 32.0, 1.0, 2.0);
#if defined(USE_HORIZONTAL_BLUR)
- vec2 direction = vec2(1.0, 0.0) * scale;
+ vec2 direction = vec2(scale.x * 2.0, 0.0);
+ vec2 nudge = vec2(0.0, scale.y * 0.5);
#else // if defined(USE_VERTICAL_BLUR)
- vec2 direction = vec2(0.0, 1.0) * scale;
+ vec2 direction = vec2(0.0, scale.y * 2.0);
+ vec2 nudge = vec2(scale.x * 0.5, 0.0);
#endif
-
- float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
- vec2 centerSlope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
-
+
+ vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
+
+#if defined(USE_GAUSS)
vec4 result = texture2D(imageMap, tex) * gauss[0];
float total = gauss[0];
+#else
+ vec4 result = texture2D(imageMap, tex);
+ float total = 1.0;
+#endif
+ float zLimit = 5.0 / zFar;
int i, j;
for (i = 0; i < 2; i++)
{
- for (j = 1; j < GAUSS_SIZE; j++)
+ for (j = 1; j < BLUR_SIZE; j++)
{
- vec2 offset = direction * j;
- float depthSample = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
- float depthExpected = depthCenter + dot(centerSlope, offset);
- if(abs(depthSample - depthExpected) < 5.0)
- {
- result += texture2D(imageMap, tex + offset) * gauss[j];
- total += gauss[j];
- }
+ vec2 offset = direction * (float(j) - 0.25) + nudge;
+ float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear);
+ float depthExpected = depthCenter + dot(slope, offset);
+ float useSample = float(abs(depthSample - depthExpected) < zLimit);
+#if defined(USE_GAUSS)
+ result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample);
+ total += gauss[j] * useSample;
+#else
+ result += texture2D(imageMap, tex + offset) * useSample;
+ total += useSample;
+#endif
+ nudge = -nudge;
}
-
+
direction = -direction;
- }
-
+ nudge = -nudge;
+ }
+
return result / total;
}
void main()
-{
- gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
+{
+ gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw);
}
diff --git a/MP/code/rend2/glsl/depthblur_vp.glsl b/MP/code/rend2/glsl/depthblur_vp.glsl
index 9c46a79..ba0b6c5 100644
--- a/MP/code/rend2/glsl/depthblur_vp.glsl
+++ b/MP/code/rend2/glsl/depthblur_vp.glsl
@@ -1,12 +1,15 @@
attribute vec4 attr_Position;
attribute vec4 attr_TexCoord0;
+uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
+
varying vec2 var_ScreenTex;
void main()
{
gl_Position = attr_Position;
- var_ScreenTex = attr_TexCoord0.xy;
+ var_ScreenTex = (floor(attr_TexCoord0.xy * (1.0 / u_ViewInfo.zw - vec2(1.0))) + vec2(0.5)) * u_ViewInfo.zw;
+
//vec2 screenCoords = gl_Position.xy / gl_Position.w;
//var_ScreenTex = screenCoords * 0.5 + 0.5;
}
diff --git a/MP/code/rend2/glsl/lightall_fp.glsl b/MP/code/rend2/glsl/lightall_fp.glsl
index 6a0a515..f16298a 100644
--- a/MP/code/rend2/glsl/lightall_fp.glsl
+++ b/MP/code/rend2/glsl/lightall_fp.glsl
@@ -292,7 +292,7 @@ void main()
float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
// surfaces not facing the light are always shadowed
- shadowValue *= clamp(dot(var_Normal.xyz, var_PrimaryLightDir.xyz), 0.0, 1.0);
+ shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0);
#if defined(SHADOWMAP_MODULATE)
lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r;
@@ -330,21 +330,31 @@ void main()
#if defined(USE_PBR)
// diffuse rgb is base color
- // specular red is smoothness
+ // specular red is gloss
// specular green is metallicness
- float roughness = 1.0 - specular.r;
+ float gloss = specular.r;
specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g);
diffuse.rgb *= 1.0 - specular.g;
#else
// diffuse rgb is diffuse
// specular rgb is specular reflectance at normal incidence
// specular alpha is gloss
- float roughness = exp2(-3.0 * specular.a);
+ float gloss = specular.a;
// adjust diffuse by specular reflectance, to maintain energy conservation
diffuse.rgb *= vec3(1.0) - specular.rgb;
#endif
+ #if defined(GLOSS_IS_GLOSS)
+ float roughness = exp2(-3.0 * gloss);
+ #elif defined(GLOSS_IS_SMOOTHNESS)
+ float roughness = 1.0 - gloss;
+ #elif defined(GLOSS_IS_ROUGHNESS)
+ float roughness = gloss;
+ #elif defined(GLOSS_IS_SHININESS)
+ float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25);
+ #endif
+
reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness);
gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
diff --git a/MP/code/rend2/glsl/ssao_fp.glsl b/MP/code/rend2/glsl/ssao_fp.glsl
index 6263284..93f6185 100644
--- a/MP/code/rend2/glsl/ssao_fp.glsl
+++ b/MP/code/rend2/glsl/ssao_fp.glsl
@@ -1,6 +1,6 @@
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;
@@ -11,6 +11,7 @@ vec2(0.5784913, -0.002528916), vec2(0.192888, 0.4064181),
vec2(-0.6335801, -0.5247476), vec2(-0.5579782, 0.7491854),
vec2(0.7320465, 0.6317794)
);
+#define NUM_SAMPLES 3
// Input: It uses texture coords as the random number seed.
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
@@ -39,48 +40,47 @@ mat2 randomRotation( const vec2 p )
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
{
- float sampleZDivW = texture2D(depthMap, tex).r;
- return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
+ float sampleZDivW = texture2D(depthMap, tex).r;
+ return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
}
-float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar)
+float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar, const vec2 scale)
{
float result = 0;
- float sampleZ = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
+ float sampleZ = getLinearDepth(depthMap, tex, zFarDivZNear);
+ float scaleZ = zFarDivZNear * sampleZ;
- vec2 expectedSlope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
-
- if (length(expectedSlope) > 5000.0)
+ vec2 slope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
+
+ if (length(slope) * zFar > 5000.0)
return 1.0;
-
- vec2 offsetScale = vec2(3.0 / sampleZ);
-
+
+ vec2 offsetScale = vec2(scale * 1024.0 / scaleZ);
+
mat2 rmat = randomRotation(tex);
-
+
+ float invZFar = 1.0 / zFar;
+ float zLimit = 20.0 * invZFar;
int i;
- for (i = 0; i < 3; i++)
+ for (i = 0; i < NUM_SAMPLES; i++)
{
vec2 offset = rmat * poissonDisc[i] * offsetScale;
- float sampleZ2 = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
-
- if (abs(sampleZ - sampleZ2) > 20.0)
- result += 1.0;
- else
- {
- float expectedZ = sampleZ + dot(expectedSlope, offset);
- result += step(expectedZ - 1.0, sampleZ2);
- }
+ float sampleDiff = getLinearDepth(depthMap, tex + offset, zFarDivZNear) - sampleZ;
+
+ bool s1 = abs(sampleDiff) > zLimit;
+ bool s2 = sampleDiff + invZFar > dot(slope, offset);
+ result += float(s1 || s2);
}
-
- result *= 0.33333;
-
+
+ result *= 1.0 / float(NUM_SAMPLES);
+
return result;
}
void main()
{
- float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
-
+ float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz);
+
gl_FragColor = vec4(vec3(result), 1.0);
}
diff --git a/MP/code/rend2/tr_backend.c b/MP/code/rend2/tr_backend.c
index 7ac01f6..f793694 100644
--- a/MP/code/rend2/tr_backend.c
+++ b/MP/code/rend2/tr_backend.c
@@ -1223,6 +1223,9 @@ const void *RB_DrawSurfs( const void *data ) {
if (glRefConfig.framebufferObject && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL) && (r_depthPrepass->integer || (backEnd.viewParms.flags & VPF_DEPTHSHADOW)))
{
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;
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@@ -1241,10 +1244,14 @@ const void *RB_DrawSurfs( const void *data ) {
qglCopyTextureImage2D(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
}
- if (r_ssao->integer)
+ if (tr.hdrDepthFbo)
{
// need the depth in a texture we can do GL_LINEAR sampling on, so copy it to an HDR image
- FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
+ ivec4_t srcBox;
+
+ VectorSet4(srcBox, 0, tr.renderDepthImage->height, tr.renderDepthImage->width, -tr.renderDepthImage->height);
+
+ FBO_BlitFromTexture(tr.renderDepthImage, srcBox, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
}
if (r_sunlightMode->integer && backEnd.viewParms.flags & VPF_USESUNLIGHT)
@@ -1309,15 +1316,12 @@ const void *RB_DrawSurfs( const void *data ) {
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg);
{
- vec4_t viewInfo;
vec3_t viewVector;
float zmax = backEnd.viewParms.zFar;
float ymax = zmax * tan(backEnd.viewParms.fovY * 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);
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWFORWARD, viewVector);
VectorScale(backEnd.refdef.viewaxis[1], xmax, viewVector);
@@ -1325,13 +1329,39 @@ const void *RB_DrawSurfs( const void *data ) {
VectorScale(backEnd.refdef.viewaxis[2], ymax, viewVector);
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWUP, viewVector);
- VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
-
GLSL_SetUniformVec4(&tr.shadowmaskShader, UNIFORM_VIEWINFO, viewInfo);
}
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)
@@ -1339,6 +1369,10 @@ const void *RB_DrawSurfs( const void *data ) {
vec4_t quadVerts[4];
vec2_t texCoords[4];
+ viewInfo[2] = 1.0f / ((float)(tr.quarterImage[0]->width) * tan(backEnd.viewParms.fovX * M_PI / 360.0f) * 2.0f);
+ viewInfo[3] = 1.0f / ((float)(tr.quarterImage[0]->height) * tan(backEnd.viewParms.fovY * M_PI / 360.0f) * 2.0f);
+ viewInfo[3] *= (float)backEnd.viewParms.viewportHeight / (float)backEnd.viewParms.viewportWidth;
+
FBO_Bind(tr.quarterFbo[0]);
qglViewport(0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height);
@@ -1360,20 +1394,14 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.hdrDepthImage, TB_COLORMAP);
- {
- 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);
- }
+ GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
+ viewInfo[2] = 1.0f / (float)(tr.quarterImage[0]->width);
+ viewInfo[3] = 1.0f / (float)(tr.quarterImage[0]->height);
+
FBO_Bind(tr.quarterFbo[1]);
qglViewport(0, 0, tr.quarterFbo[1]->width, tr.quarterFbo[1]->height);
@@ -1384,16 +1412,7 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
- {
- 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);
- }
+ GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
@@ -1408,16 +1427,7 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
- {
- 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);
- }
+ GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
@@ -1803,10 +1813,6 @@ const void *RB_PostProcess(const void *data)
srcBox[2] = backEnd.viewParms.viewportWidth * tr.screenSsaoImage->width / (float)glConfig.vidWidth;
srcBox[3] = backEnd.viewParms.viewportHeight * tr.screenSsaoImage->height / (float)glConfig.vidHeight;
- //FBO_BlitFromTexture(tr.screenSsaoImage, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO);
- srcBox[1] = tr.screenSsaoImage->height - srcBox[1];
- srcBox[3] = -srcBox[3];
-
FBO_Blit(tr.screenSsaoFbo, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO);
}
diff --git a/MP/code/rend2/tr_fbo.c b/MP/code/rend2/tr_fbo.c
index 1229376..d013748 100644
--- a/MP/code/rend2/tr_fbo.c
+++ b/MP/code/rend2/tr_fbo.c
@@ -310,7 +310,15 @@ void FBO_Init(void)
qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
- if (r_drawSunRays->integer)
+ if (tr.screenScratchImage)
+ {
+ 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 (tr.sunRaysImage)
{
tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height);
FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT, 0);
@@ -332,7 +340,7 @@ void FBO_Init(void)
if (tr.sunShadowDepthImage[0])
{
- for ( i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
{
tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height);
// FIXME: this next line wastes 16mb with 4x1024x1024 sun shadow maps, skip if OpenGL 4.3+ or ARB_framebuffer_no_attachments
@@ -341,44 +349,58 @@ void FBO_Init(void)
FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0);
R_CheckFBO(tr.sunShadowFbo[i]);
}
+ }
+ if (tr.screenShadowImage)
+ {
tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height);
FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.screenShadowFbo);
}
- for (i = 0; i < 2; i++)
+ if (tr.textureScratchImage[0])
{
- tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
- FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
- R_CheckFBO(tr.textureScratchFbo[i]);
+ for (i = 0; i < 2; i++)
+ {
+ tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
+ FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+ R_CheckFBO(tr.textureScratchFbo[i]);
+ }
}
+ if (tr.calcLevelsImage)
{
tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height);
FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.calcLevelsFbo);
}
+ if (tr.targetLevelsImage)
{
tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height);
FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.targetLevelsFbo);
}
- for (i = 0; i < 2; i++)
+ if (tr.quarterImage[0])
{
- tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
- FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
- R_CheckFBO(tr.quarterFbo[i]);
+ for (i = 0; i < 2; i++)
+ {
+ tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
+ FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+ R_CheckFBO(tr.quarterFbo[i]);
+ }
}
- if (r_ssao->integer)
+ if (tr.hdrDepthImage)
{
tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height);
FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.hdrDepthFbo);
+ }
+ if (tr.screenSsaoImage)
+ {
tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height);
FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.screenSsaoFbo);
diff --git a/MP/code/rend2/tr_glsl.c b/MP/code/rend2/tr_glsl.c
index 9cfa025..b9b73e2 100644
--- a/MP/code/rend2/tr_glsl.c
+++ b/MP/code/rend2/tr_glsl.c
@@ -1075,6 +1075,23 @@ void GLSL_InitGPUShaders(void)
if (r_cubeMapping->integer)
Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
+
+ switch (r_glossType->integer)
+ {
+ case 0:
+ default:
+ Q_strcat(extradefines, 1024, "#define GLOSS_IS_GLOSS\n");
+ break;
+ case 1:
+ Q_strcat(extradefines, 1024, "#define GLOSS_IS_SMOOTHNESS\n");
+ break;
+ case 2:
+ Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n");
+ break;
+ case 3:
+ Q_strcat(extradefines, 1024, "#define GLOSS_IS_SHININESS\n");
+ break;
+ }
}
if (i & LIGHTDEF_USE_SHADOWMAP)
diff --git a/MP/code/rend2/tr_image.c b/MP/code/rend2/tr_image.c
index d6c1b80..644fe00 100644
--- a/MP/code/rend2/tr_image.c
+++ b/MP/code/rend2/tr_image.c
@@ -2927,6 +2927,12 @@ void R_CreateBuiltinImages( void ) {
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)
tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
@@ -2974,7 +2980,6 @@ void R_CreateBuiltinImages( void ) {
if (r_ssao->integer)
{
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)
diff --git a/MP/code/rend2/tr_init.c b/MP/code/rend2/tr_init.c
index 1787326..7d7675f 100644
--- a/MP/code/rend2/tr_init.c
+++ b/MP/code/rend2/tr_init.c
@@ -166,6 +166,7 @@ cvar_t *r_baseNormalY;
cvar_t *r_baseParallax;
cvar_t *r_baseSpecular;
cvar_t *r_baseGloss;
+cvar_t *r_glossType;
cvar_t *r_mergeLightmaps;
cvar_t *r_dlightMode;
cvar_t *r_pshadowDist;
@@ -181,6 +182,7 @@ cvar_t *r_sunlightMode;
cvar_t *r_drawSunRays;
cvar_t *r_sunShadows;
cvar_t *r_shadowFilter;
+cvar_t *r_shadowBlur;
cvar_t *r_shadowMapSize;
cvar_t *r_shadowCascadeZNear;
cvar_t *r_shadowCascadeZFar;
@@ -1345,6 +1347,7 @@ void R_Register( void ) {
r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH );
r_baseSpecular = ri.Cvar_Get( "r_baseSpecular", "0.04", CVAR_ARCHIVE | CVAR_LATCH );
r_baseGloss = ri.Cvar_Get( "r_baseGloss", "0.1", CVAR_ARCHIVE | CVAR_LATCH );
+ r_glossType = ri.Cvar_Get("r_glossType", "1", CVAR_ARCHIVE | CVAR_LATCH);
r_dlightMode = ri.Cvar_Get( "r_dlightMode", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_pshadowDist = ri.Cvar_Get( "r_pshadowDist", "128", CVAR_ARCHIVE );
r_mergeLightmaps = ri.Cvar_Get( "r_mergeLightmaps", "1", CVAR_ARCHIVE | CVAR_LATCH );
@@ -1362,7 +1365,8 @@ void R_Register( void ) {
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_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_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "1024", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "0", CVAR_ARCHIVE | CVAR_LATCH );
diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h
index b2a7f7e..5778ecf 100644
--- a/MP/code/rend2/tr_local.h
+++ b/MP/code/rend2/tr_local.h
@@ -1651,6 +1651,7 @@ typedef struct {
image_t *sunRaysImage;
image_t *renderDepthImage;
image_t *pshadowMaps[MAX_DRAWN_PSHADOWS];
+ image_t *screenScratchImage;
image_t *textureScratchImage[2];
image_t *quarterImage[2];
image_t *calcLevelsImage;
@@ -1669,6 +1670,7 @@ typedef struct {
FBO_t *sunRaysFbo;
FBO_t *depthFbo;
FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS];
+ FBO_t *screenScratchFbo;
FBO_t *textureScratchFbo[2];
FBO_t *quarterFbo[2];
FBO_t *calcLevelsFbo;
@@ -1990,6 +1992,7 @@ extern cvar_t *r_baseNormalY;
extern cvar_t *r_baseParallax;
extern cvar_t *r_baseSpecular;
extern cvar_t *r_baseGloss;
+extern cvar_t *r_glossType;
extern cvar_t *r_dlightMode;
extern cvar_t *r_pshadowDist;
extern cvar_t *r_mergeLightmaps;
@@ -2005,6 +2008,7 @@ extern cvar_t *r_sunlightMode;
extern cvar_t *r_drawSunRays;
extern cvar_t *r_sunShadows;
extern cvar_t *r_shadowFilter;
+extern cvar_t *r_shadowBlur;
extern cvar_t *r_shadowMapSize;
extern cvar_t *r_shadowCascadeZNear;
extern cvar_t *r_shadowCascadeZFar;
diff --git a/SP/code/rend2/glsl/depthblur_fp.glsl b/SP/code/rend2/glsl/depthblur_fp.glsl
index 93895b4..9685f6d 100644
--- a/SP/code/rend2/glsl/depthblur_fp.glsl
+++ b/SP/code/rend2/glsl/depthblur_fp.glsl
@@ -1,58 +1,75 @@
uniform sampler2D u_ScreenImageMap;
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;
+//float gauss[8] = float[8](0.17, 0.17, 0.16, 0.14, 0.12, 0.1, 0.08, 0.06);
//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[3] = float[3](0.60, 0.19, 0.0066);
-#define GAUSS_SIZE 4
+#define BLUR_SIZE 4
+//#define USE_GAUSS
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
{
- float sampleZDivW = texture2D(depthMap, tex).r;
- return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
+ float sampleZDivW = texture2D(depthMap, tex).r;
+ return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
}
-vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar)
+vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale)
{
- float scale = 1.0 / 256.0;
+ float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear);
+
+ // enable for less blurring for farther objects
+ scale /= clamp(zFarDivZNear * depthCenter / 32.0, 1.0, 2.0);
#if defined(USE_HORIZONTAL_BLUR)
- vec2 direction = vec2(1.0, 0.0) * scale;
+ vec2 direction = vec2(scale.x * 2.0, 0.0);
+ vec2 nudge = vec2(0.0, scale.y * 0.5);
#else // if defined(USE_VERTICAL_BLUR)
- vec2 direction = vec2(0.0, 1.0) * scale;
+ vec2 direction = vec2(0.0, scale.y * 2.0);
+ vec2 nudge = vec2(scale.x * 0.5, 0.0);
#endif
-
- float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
- vec2 centerSlope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
-
+
+ vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
+
+#if defined(USE_GAUSS)
vec4 result = texture2D(imageMap, tex) * gauss[0];
float total = gauss[0];
+#else
+ vec4 result = texture2D(imageMap, tex);
+ float total = 1.0;
+#endif
+ float zLimit = 5.0 / zFar;
int i, j;
for (i = 0; i < 2; i++)
{
- for (j = 1; j < GAUSS_SIZE; j++)
+ for (j = 1; j < BLUR_SIZE; j++)
{
- vec2 offset = direction * j;
- float depthSample = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
- float depthExpected = depthCenter + dot(centerSlope, offset);
- if(abs(depthSample - depthExpected) < 5.0)
- {
- result += texture2D(imageMap, tex + offset) * gauss[j];
- total += gauss[j];
- }
+ vec2 offset = direction * (float(j) - 0.25) + nudge;
+ float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear);
+ float depthExpected = depthCenter + dot(slope, offset);
+ float useSample = float(abs(depthSample - depthExpected) < zLimit);
+#if defined(USE_GAUSS)
+ result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample);
+ total += gauss[j] * useSample;
+#else
+ result += texture2D(imageMap, tex + offset) * useSample;
+ total += useSample;
+#endif
+ nudge = -nudge;
}
-
+
direction = -direction;
- }
-
+ nudge = -nudge;
+ }
+
return result / total;
}
void main()
-{
- gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
+{
+ gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw);
}
diff --git a/SP/code/rend2/glsl/depthblur_vp.glsl b/SP/code/rend2/glsl/depthblur_vp.glsl
index 9c46a79..ba0b6c5 100644
--- a/SP/code/rend2/glsl/depthblur_vp.glsl
+++ b/SP/code/rend2/glsl/depthblur_vp.glsl
@@ -1,12 +1,15 @@
attribute vec4 attr_Position;
attribute vec4 attr_TexCoord0;
+uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
+
varying vec2 var_ScreenTex;
void main()
{
gl_Position = attr_Position;
- var_ScreenTex = attr_TexCoord0.xy;
+ var_ScreenTex = (floor(attr_TexCoord0.xy * (1.0 / u_ViewInfo.zw - vec2(1.0))) + vec2(0.5)) * u_ViewInfo.zw;
+
//vec2 screenCoords = gl_Position.xy / gl_Position.w;
//var_ScreenTex = screenCoords * 0.5 + 0.5;
}
diff --git a/SP/code/rend2/glsl/lightall_fp.glsl b/SP/code/rend2/glsl/lightall_fp.glsl
index 6a0a515..f16298a 100644
--- a/SP/code/rend2/glsl/lightall_fp.glsl
+++ b/SP/code/rend2/glsl/lightall_fp.glsl
@@ -292,7 +292,7 @@ void main()
float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
// surfaces not facing the light are always shadowed
- shadowValue *= clamp(dot(var_Normal.xyz, var_PrimaryLightDir.xyz), 0.0, 1.0);
+ shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0);
#if defined(SHADOWMAP_MODULATE)
lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r;
@@ -330,21 +330,31 @@ void main()
#if defined(USE_PBR)
// diffuse rgb is base color
- // specular red is smoothness
+ // specular red is gloss
// specular green is metallicness
- float roughness = 1.0 - specular.r;
+ float gloss = specular.r;
specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g);
diffuse.rgb *= 1.0 - specular.g;
#else
// diffuse rgb is diffuse
// specular rgb is specular reflectance at normal incidence
// specular alpha is gloss
- float roughness = exp2(-3.0 * specular.a);
+ float gloss = specular.a;
// adjust diffuse by specular reflectance, to maintain energy conservation
diffuse.rgb *= vec3(1.0) - specular.rgb;
#endif
+ #if defined(GLOSS_IS_GLOSS)
+ float roughness = exp2(-3.0 * gloss);
+ #elif defined(GLOSS_IS_SMOOTHNESS)
+ float roughness = 1.0 - gloss;
+ #elif defined(GLOSS_IS_ROUGHNESS)
+ float roughness = gloss;
+ #elif defined(GLOSS_IS_SHININESS)
+ float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25);
+ #endif
+
reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness);
gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
diff --git a/SP/code/rend2/glsl/ssao_fp.glsl b/SP/code/rend2/glsl/ssao_fp.glsl
index 6263284..93f6185 100644
--- a/SP/code/rend2/glsl/ssao_fp.glsl
+++ b/SP/code/rend2/glsl/ssao_fp.glsl
@@ -1,6 +1,6 @@
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;
@@ -11,6 +11,7 @@ vec2(0.5784913, -0.002528916), vec2(0.192888, 0.4064181),
vec2(-0.6335801, -0.5247476), vec2(-0.5579782, 0.7491854),
vec2(0.7320465, 0.6317794)
);
+#define NUM_SAMPLES 3
// Input: It uses texture coords as the random number seed.
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
@@ -39,48 +40,47 @@ mat2 randomRotation( const vec2 p )
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
{
- float sampleZDivW = texture2D(depthMap, tex).r;
- return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
+ float sampleZDivW = texture2D(depthMap, tex).r;
+ return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
}
-float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar)
+float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar, const vec2 scale)
{
float result = 0;
- float sampleZ = zFar * getLinearDepth(depthMap, tex, zFarDivZNear);
+ float sampleZ = getLinearDepth(depthMap, tex, zFarDivZNear);
+ float scaleZ = zFarDivZNear * sampleZ;
- vec2 expectedSlope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
-
- if (length(expectedSlope) > 5000.0)
+ vec2 slope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
+
+ if (length(slope) * zFar > 5000.0)
return 1.0;
-
- vec2 offsetScale = vec2(3.0 / sampleZ);
-
+
+ vec2 offsetScale = vec2(scale * 1024.0 / scaleZ);
+
mat2 rmat = randomRotation(tex);
-
+
+ float invZFar = 1.0 / zFar;
+ float zLimit = 20.0 * invZFar;
int i;
- for (i = 0; i < 3; i++)
+ for (i = 0; i < NUM_SAMPLES; i++)
{
vec2 offset = rmat * poissonDisc[i] * offsetScale;
- float sampleZ2 = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear);
-
- if (abs(sampleZ - sampleZ2) > 20.0)
- result += 1.0;
- else
- {
- float expectedZ = sampleZ + dot(expectedSlope, offset);
- result += step(expectedZ - 1.0, sampleZ2);
- }
+ float sampleDiff = getLinearDepth(depthMap, tex + offset, zFarDivZNear) - sampleZ;
+
+ bool s1 = abs(sampleDiff) > zLimit;
+ bool s2 = sampleDiff + invZFar > dot(slope, offset);
+ result += float(s1 || s2);
}
-
- result *= 0.33333;
-
+
+ result *= 1.0 / float(NUM_SAMPLES);
+
return result;
}
void main()
{
- float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y);
-
+ float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz);
+
gl_FragColor = vec4(vec3(result), 1.0);
}
diff --git a/SP/code/rend2/tr_backend.c b/SP/code/rend2/tr_backend.c
index ed156fd..5380004 100644
--- a/SP/code/rend2/tr_backend.c
+++ b/SP/code/rend2/tr_backend.c
@@ -1475,6 +1475,9 @@ const void *RB_DrawSurfs( const void *data ) {
if (glRefConfig.framebufferObject && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL) && (r_depthPrepass->integer || (backEnd.viewParms.flags & VPF_DEPTHSHADOW)))
{
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;
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@@ -1493,10 +1496,14 @@ const void *RB_DrawSurfs( const void *data ) {
qglCopyTextureImage2D(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
}
- if (r_ssao->integer)
+ if (tr.hdrDepthFbo)
{
// need the depth in a texture we can do GL_LINEAR sampling on, so copy it to an HDR image
- FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
+ ivec4_t srcBox;
+
+ VectorSet4(srcBox, 0, tr.renderDepthImage->height, tr.renderDepthImage->width, -tr.renderDepthImage->height);
+
+ FBO_BlitFromTexture(tr.renderDepthImage, srcBox, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
}
if (r_sunlightMode->integer && backEnd.viewParms.flags & VPF_USESUNLIGHT)
@@ -1561,15 +1568,12 @@ const void *RB_DrawSurfs( const void *data ) {
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg);
{
- vec4_t viewInfo;
vec3_t viewVector;
float zmax = backEnd.viewParms.zFar;
float ymax = zmax * tan(backEnd.viewParms.fovY * 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);
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWFORWARD, viewVector);
VectorScale(backEnd.refdef.viewaxis[1], xmax, viewVector);
@@ -1577,13 +1581,39 @@ const void *RB_DrawSurfs( const void *data ) {
VectorScale(backEnd.refdef.viewaxis[2], ymax, viewVector);
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWUP, viewVector);
- VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
-
GLSL_SetUniformVec4(&tr.shadowmaskShader, UNIFORM_VIEWINFO, viewInfo);
}
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)
@@ -1591,6 +1621,10 @@ const void *RB_DrawSurfs( const void *data ) {
vec4_t quadVerts[4];
vec2_t texCoords[4];
+ viewInfo[2] = 1.0f / ((float)(tr.quarterImage[0]->width) * tan(backEnd.viewParms.fovX * M_PI / 360.0f) * 2.0f);
+ viewInfo[3] = 1.0f / ((float)(tr.quarterImage[0]->height) * tan(backEnd.viewParms.fovY * M_PI / 360.0f) * 2.0f);
+ viewInfo[3] *= (float)backEnd.viewParms.viewportHeight / (float)backEnd.viewParms.viewportWidth;
+
FBO_Bind(tr.quarterFbo[0]);
qglViewport(0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height);
@@ -1612,20 +1646,14 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.hdrDepthImage, TB_COLORMAP);
- {
- 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);
- }
+ GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
+ viewInfo[2] = 1.0f / (float)(tr.quarterImage[0]->width);
+ viewInfo[3] = 1.0f / (float)(tr.quarterImage[0]->height);
+
FBO_Bind(tr.quarterFbo[1]);
qglViewport(0, 0, tr.quarterFbo[1]->width, tr.quarterFbo[1]->height);
@@ -1636,16 +1664,7 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
- {
- 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);
- }
+ GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
@@ -1660,16 +1679,7 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
- {
- 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);
- }
+ GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
@@ -2055,10 +2065,6 @@ const void *RB_PostProcess(const void *data)
srcBox[2] = backEnd.viewParms.viewportWidth * tr.screenSsaoImage->width / (float)glConfig.vidWidth;
srcBox[3] = backEnd.viewParms.viewportHeight * tr.screenSsaoImage->height / (float)glConfig.vidHeight;
- //FBO_BlitFromTexture(tr.screenSsaoImage, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO);
- srcBox[1] = tr.screenSsaoImage->height - srcBox[1];
- srcBox[3] = -srcBox[3];
-
FBO_Blit(tr.screenSsaoFbo, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO);
}
diff --git a/SP/code/rend2/tr_fbo.c b/SP/code/rend2/tr_fbo.c
index 1229376..d013748 100644
--- a/SP/code/rend2/tr_fbo.c
+++ b/SP/code/rend2/tr_fbo.c
@@ -310,7 +310,15 @@ void FBO_Init(void)
qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
- if (r_drawSunRays->integer)
+ if (tr.screenScratchImage)
+ {
+ 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 (tr.sunRaysImage)
{
tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height);
FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT, 0);
@@ -332,7 +340,7 @@ void FBO_Init(void)
if (tr.sunShadowDepthImage[0])
{
- for ( i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
{
tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height);
// FIXME: this next line wastes 16mb with 4x1024x1024 sun shadow maps, skip if OpenGL 4.3+ or ARB_framebuffer_no_attachments
@@ -341,44 +349,58 @@ void FBO_Init(void)
FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0);
R_CheckFBO(tr.sunShadowFbo[i]);
}
+ }
+ if (tr.screenShadowImage)
+ {
tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height);
FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.screenShadowFbo);
}
- for (i = 0; i < 2; i++)
+ if (tr.textureScratchImage[0])
{
- tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
- FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
- R_CheckFBO(tr.textureScratchFbo[i]);
+ for (i = 0; i < 2; i++)
+ {
+ tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
+ FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+ R_CheckFBO(tr.textureScratchFbo[i]);
+ }
}
+ if (tr.calcLevelsImage)
{
tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height);
FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.calcLevelsFbo);
}
+ if (tr.targetLevelsImage)
{
tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height);
FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.targetLevelsFbo);
}
- for (i = 0; i < 2; i++)
+ if (tr.quarterImage[0])
{
- tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
- FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
- R_CheckFBO(tr.quarterFbo[i]);
+ for (i = 0; i < 2; i++)
+ {
+ tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
+ FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0);
+ R_CheckFBO(tr.quarterFbo[i]);
+ }
}
- if (r_ssao->integer)
+ if (tr.hdrDepthImage)
{
tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height);
FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.hdrDepthFbo);
+ }
+ if (tr.screenSsaoImage)
+ {
tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height);
FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT, 0);
R_CheckFBO(tr.screenSsaoFbo);
diff --git a/SP/code/rend2/tr_glsl.c b/SP/code/rend2/tr_glsl.c
index 9cfa025..b9b73e2 100644
--- a/SP/code/rend2/tr_glsl.c
+++ b/SP/code/rend2/tr_glsl.c
@@ -1075,6 +1075,23 @@ void GLSL_InitGPUShaders(void)
if (r_cubeMapping->integer)
Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
+
+ switch (r_glossType->integer)
+ {
+ case 0:
+ default:
+ Q_strcat(extradefines, 1024, "#define GLOSS_IS_GLOSS\n");
+ break;
+ case 1:
+ Q_strcat(extradefines, 1024, "#define GLOSS_IS_SMOOTHNESS\n");
+ break;
+ case 2:
+ Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n");
+ break;
+ case 3:
+ Q_strcat(extradefines, 1024, "#define GLOSS_IS_SHININESS\n");
+ break;
+ }
}
if (i & LIGHTDEF_USE_SHADOWMAP)
diff --git a/SP/code/rend2/tr_image.c b/SP/code/rend2/tr_image.c
index f2eaaab..65a4f92 100644
--- a/SP/code/rend2/tr_image.c
+++ b/SP/code/rend2/tr_image.c
@@ -2936,6 +2936,12 @@ void R_CreateBuiltinImages( void ) {
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)
tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat);
@@ -2983,7 +2989,6 @@ void R_CreateBuiltinImages( void ) {
if (r_ssao->integer)
{
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)
diff --git a/SP/code/rend2/tr_init.c b/SP/code/rend2/tr_init.c
index b485415..d338fd1 100644
--- a/SP/code/rend2/tr_init.c
+++ b/SP/code/rend2/tr_init.c
@@ -171,6 +171,7 @@ cvar_t *r_baseNormalY;
cvar_t *r_baseParallax;
cvar_t *r_baseSpecular;
cvar_t *r_baseGloss;
+cvar_t *r_glossType;
cvar_t *r_mergeLightmaps;
cvar_t *r_dlightMode;
cvar_t *r_pshadowDist;
@@ -186,6 +187,7 @@ cvar_t *r_sunlightMode;
cvar_t *r_drawSunRays;
cvar_t *r_sunShadows;
cvar_t *r_shadowFilter;
+cvar_t *r_shadowBlur;
cvar_t *r_shadowMapSize;
cvar_t *r_shadowCascadeZNear;
cvar_t *r_shadowCascadeZFar;
@@ -1368,6 +1370,7 @@ void R_Register( void ) {
r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH );
r_baseSpecular = ri.Cvar_Get( "r_baseSpecular", "0.04", CVAR_ARCHIVE | CVAR_LATCH );
r_baseGloss = ri.Cvar_Get( "r_baseGloss", "0.1", CVAR_ARCHIVE | CVAR_LATCH );
+ r_glossType = ri.Cvar_Get("r_glossType", "1", CVAR_ARCHIVE | CVAR_LATCH);
r_dlightMode = ri.Cvar_Get( "r_dlightMode", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_pshadowDist = ri.Cvar_Get( "r_pshadowDist", "128", CVAR_ARCHIVE );
r_mergeLightmaps = ri.Cvar_Get( "r_mergeLightmaps", "1", CVAR_ARCHIVE | CVAR_LATCH );
@@ -1385,7 +1388,8 @@ void R_Register( void ) {
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_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_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "1024", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "0", CVAR_ARCHIVE | CVAR_LATCH );
diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h
index 554427c..759df11 100644
--- a/SP/code/rend2/tr_local.h
+++ b/SP/code/rend2/tr_local.h
@@ -1664,6 +1664,7 @@ typedef struct {
image_t *sunRaysImage;
image_t *renderDepthImage;
image_t *pshadowMaps[MAX_DRAWN_PSHADOWS];
+ image_t *screenScratchImage;
image_t *textureScratchImage[2];
image_t *quarterImage[2];
image_t *calcLevelsImage;
@@ -1682,6 +1683,7 @@ typedef struct {
FBO_t *sunRaysFbo;
FBO_t *depthFbo;
FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS];
+ FBO_t *screenScratchFbo;
FBO_t *textureScratchFbo[2];
FBO_t *quarterFbo[2];
FBO_t *calcLevelsFbo;
@@ -2010,6 +2012,7 @@ extern cvar_t *r_baseNormalY;
extern cvar_t *r_baseParallax;
extern cvar_t *r_baseSpecular;
extern cvar_t *r_baseGloss;
+extern cvar_t *r_glossType;
extern cvar_t *r_dlightMode;
extern cvar_t *r_pshadowDist;
extern cvar_t *r_mergeLightmaps;
@@ -2025,6 +2028,7 @@ extern cvar_t *r_sunlightMode;
extern cvar_t *r_drawSunRays;
extern cvar_t *r_sunShadows;
extern cvar_t *r_shadowFilter;
+extern cvar_t *r_shadowBlur;
extern cvar_t *r_shadowMapSize;
extern cvar_t *r_shadowCascadeZNear;
extern cvar_t *r_shadowCascadeZFar;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git
More information about the Pkg-games-commits
mailing list