From 65b999446d7a00c12156490e4593b31c2e6b204b Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 8 Mar 2016 18:30:51 -0800 Subject: [PATCH] OpenGL2: Speedup for SSAO & blur shaders, fix sunlight normals in lightall. --- code/renderergl2/glsl/depthblur_fp.glsl | 46 +++++++++++----------- code/renderergl2/glsl/lightall_fp.glsl | 4 +- code/renderergl2/glsl/ssao_fp.glsl | 52 ++++++++++++------------- code/renderergl2/tr_backend.c | 7 +++- 4 files changed, 56 insertions(+), 53 deletions(-) diff --git a/code/renderergl2/glsl/depthblur_fp.glsl b/code/renderergl2/glsl/depthblur_fp.glsl index 15f7be27..60a261c5 100644 --- a/code/renderergl2/glsl/depthblur_fp.glsl +++ b/code/renderergl2/glsl/depthblur_fp.glsl @@ -11,22 +11,23 @@ float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044); 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) { - vec2 scale = u_ViewInfo.zw; + float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear); + //scale /= zFarDivZNear * depthCenter; + //int blurSteps = int(float(BLUR_SIZE) / (zFarDivZNear * depthCenter)); #if defined(USE_HORIZONTAL_BLUR) - vec2 direction = vec2(1.0, 0.0) * scale; + vec2 direction = vec2(scale.x, 0.0); #else // if defined(USE_VERTICAL_BLUR) - vec2 direction = vec2(0.0, 1.0) * scale; + vec2 direction = vec2(0.0, scale.y); #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]; @@ -36,33 +37,32 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa float total = 1.0; #endif + float zLimit = 5.0 / zFar; int i, j; for (i = 0; i < 2; i++) { 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) - { + 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]; - total += gauss[j]; + result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample); + total += gauss[j] * useSample; #else - result += texture2D(imageMap, tex + offset); - total += 1.0; + result += texture2D(imageMap, tex + offset) * useSample; + total += useSample; #endif - } } - + direction = -direction; - } - + } + 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/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index 8edbebda..f16298a3 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/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,7 +330,7 @@ void main() #if defined(USE_PBR) // diffuse rgb is base color - // specular red is smoothness + // specular red is gloss // specular green is metallicness float gloss = specular.r; specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g); diff --git a/code/renderergl2/glsl/ssao_fp.glsl b/code/renderergl2/glsl/ssao_fp.glsl index 6263284c..84f18cb7 100644 --- a/code/renderergl2/glsl/ssao_fp.glsl +++ b/code/renderergl2/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); + float sampleDiff = getLinearDepth(depthMap, tex + offset, zFarDivZNear) - sampleZ; - if (abs(sampleZ - sampleZ2) > 20.0) - result += 1.0; - else - { - float expectedZ = sampleZ + dot(expectedSlope, offset); - result += step(expectedZ - 1.0, sampleZ2); - } + 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.zw); + gl_FragColor = vec4(vec3(result), 1.0); } diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c index 985b8f9f..3796d4d2 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -1098,8 +1098,8 @@ const void *RB_DrawSurfs( const void *data ) { vec4_t quadVerts[4]; vec2_t texCoords[4]; - viewInfo[2] = 1.0f / (float)(tr.quarterImage[0]->width); - viewInfo[3] = 1.0f / (float)(tr.quarterImage[0]->height); + 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); FBO_Bind(tr.quarterFbo[0]); @@ -1127,6 +1127,9 @@ const void *RB_DrawSurfs( const void *data ) { 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);