OpenGL2: Speedup for SSAO & blur shaders, fix sunlight normals in lightall.

This commit is contained in:
SmileTheory 2016-03-08 18:30:51 -08:00
parent 5738d09969
commit 65b999446d
4 changed files with 56 additions and 53 deletions

View File

@ -15,18 +15,19 @@ float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNea
return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); 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) #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) #else // if defined(USE_VERTICAL_BLUR)
vec2 direction = vec2(0.0, 1.0) * scale; vec2 direction = vec2(0.0, scale.y);
#endif #endif
float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear); vec2 slope = 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) #if defined(USE_GAUSS)
vec4 result = texture2D(imageMap, tex) * gauss[0]; vec4 result = texture2D(imageMap, tex) * gauss[0];
@ -36,25 +37,24 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa
float total = 1.0; float total = 1.0;
#endif #endif
float zLimit = 5.0 / zFar;
int i, j; int i, j;
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
for (j = 1; j < BLUR_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 = getLinearDepth(depthMap, tex + offset, zFarDivZNear);
float depthExpected = depthCenter + dot(centerSlope, offset); float depthExpected = depthCenter + dot(slope, offset);
if(abs(depthSample - depthExpected) < 5.0) float useSample = float(abs(depthSample - depthExpected) < zLimit);
{
#if defined(USE_GAUSS) #if defined(USE_GAUSS)
result += texture2D(imageMap, tex + offset) * gauss[j]; result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample);
total += gauss[j]; total += gauss[j] * useSample;
#else #else
result += texture2D(imageMap, tex + offset); result += texture2D(imageMap, tex + offset) * useSample;
total += 1.0; total += useSample;
#endif #endif
} }
}
direction = -direction; direction = -direction;
} }
@ -64,5 +64,5 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa
void main() 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);
} }

View File

@ -292,7 +292,7 @@ void main()
float shadowValue = texture2D(u_ShadowMap, shadowTex).r; float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
// surfaces not facing the light are always shadowed // 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) #if defined(SHADOWMAP_MODULATE)
lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r; lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r;
@ -330,7 +330,7 @@ void main()
#if defined(USE_PBR) #if defined(USE_PBR)
// diffuse rgb is base color // diffuse rgb is base color
// specular red is smoothness // specular red is gloss
// specular green is metallicness // specular green is metallicness
float gloss = specular.r; float gloss = specular.r;
specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g); specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g);

View File

@ -1,6 +1,6 @@
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;
@ -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.6335801, -0.5247476), vec2(-0.5579782, 0.7491854),
vec2(0.7320465, 0.6317794) vec2(0.7320465, 0.6317794)
); );
#define NUM_SAMPLES 3
// Input: It uses texture coords as the random number seed. // Input: It uses texture coords as the random number seed.
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive. // Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
@ -43,44 +44,43 @@ float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNea
return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); 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 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)); vec2 slope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
if (length(expectedSlope) > 5000.0) if (length(slope) * zFar > 5000.0)
return 1.0; return 1.0;
vec2 offsetScale = vec2(3.0 / sampleZ); vec2 offsetScale = vec2(scale * 1024.0 / scaleZ);
mat2 rmat = randomRotation(tex); mat2 rmat = randomRotation(tex);
float invZFar = 1.0 / zFar;
float zLimit = 20.0 * invZFar;
int i; int i;
for (i = 0; i < 3; i++) for (i = 0; i < NUM_SAMPLES; i++)
{ {
vec2 offset = rmat * poissonDisc[i] * offsetScale; 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) bool s1 = abs(sampleDiff) > zLimit;
result += 1.0; bool s2 = sampleDiff + invZFar > dot(slope, offset);
else result += float(s1 || s2);
{
float expectedZ = sampleZ + dot(expectedSlope, offset);
result += step(expectedZ - 1.0, sampleZ2);
}
} }
result *= 0.33333; result *= 1.0 / float(NUM_SAMPLES);
return result; return result;
} }
void main() 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); gl_FragColor = vec4(vec3(result), 1.0);
} }

View File

@ -1098,8 +1098,8 @@ 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[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); viewInfo[3] = 1.0f / ((float)(tr.quarterImage[0]->height) * tan(backEnd.viewParms.fovY * M_PI / 360.0f) * 2.0f);
FBO_Bind(tr.quarterFbo[0]); FBO_Bind(tr.quarterFbo[0]);
@ -1127,6 +1127,9 @@ const void *RB_DrawSurfs( const void *data ) {
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes); 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]); FBO_Bind(tr.quarterFbo[1]);
qglViewport(0, 0, tr.quarterFbo[1]->width, tr.quarterFbo[1]->height); qglViewport(0, 0, tr.quarterFbo[1]->width, tr.quarterFbo[1]->height);