-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New SSAO Algorithm #62
base: rend2
Are you sure you want to change the base?
Changes from 9 commits
2744651
38dbbca
6ad9c1f
5e725ac
26b6c4e
f81afaa
64fcc23
fc0091e
b86d4b4
3cba753
41c7243
d12fa4c
4c44001
addfdbd
e78dec8
f08a371
b3936d0
d888306
3d04b09
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,95 +8,92 @@ void main() | |
{ | ||
gl_Position = attr_Position; | ||
var_ScreenTex = attr_TexCoord0.xy; | ||
//vec2 screenCoords = gl_Position.xy / gl_Position.w; | ||
//var_ScreenTex = screenCoords * 0.5 + 0.5; | ||
} | ||
|
||
/*[Fragment]*/ | ||
uniform sampler2D u_ScreenDepthMap; | ||
uniform vec4 u_ViewInfo; // zfar / znear, zfar | ||
uniform sampler2D u_ScreenDepthMap; // colormap | ||
uniform sampler2D u_ScreenImageMap; // lightmap | ||
uniform vec4 u_ViewInfo; // znear, zfar, 0, 0 | ||
uniform vec2 u_ScreenInfo; // width, height | ||
|
||
uniform vec4 u_SSAOSettings; // aocap, strength, aoMultiplier, lightmap | ||
uniform vec4 u_SSAOSettings2; // noise, aorange, depthTolerance, 0 | ||
|
||
in vec2 var_ScreenTex; | ||
|
||
out vec4 out_Color; | ||
|
||
vec2 poissonDisc[9] = vec2[9]( | ||
vec2(-0.7055767, 0.196515), vec2(0.3524343, -0.7791386), | ||
vec2(0.2391056, 0.9189604), vec2(-0.07580382, -0.09224417), | ||
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) | ||
); | ||
|
||
// Input: It uses texture coords as the random number seed. | ||
// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive. | ||
// Author: Michael Pohoreski | ||
// Copyright: Copyleft 2012 :-) | ||
// Source: http://stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader | ||
|
||
float random( const vec2 p ) | ||
{ | ||
// We need irrationals for pseudo randomness. | ||
// Most (all?) known transcendental numbers will (generally) work. | ||
const vec2 r = vec2( | ||
23.1406926327792690, // e^pi (Gelfond's constant) | ||
2.6651441426902251); // 2^sqrt(2) (Gelfond-Schneider constant) | ||
//return fract( cos( mod( 123456789., 1e-7 + 256. * dot(p,r) ) ) ); | ||
return mod( 123456789., 1e-7 + 256. * dot(p,r) ); | ||
// | ||
// AO Shader by Monsterovich :D | ||
// | ||
|
||
vec2 camerarange = vec2(u_ViewInfo.x, u_ViewInfo.y); | ||
|
||
float readDepth( in vec2 coord ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can znear and zfar values be passed in as function parameters? I'd like to avoid using global variables unless it's necessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
return (2.0 * camerarange.x) / (camerarange.y + camerarange.x - texture2D( u_ScreenDepthMap, coord ).x * (camerarange.y - camerarange.x)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All the GLSL shaders in rend2 are compiled with version "GLSL 1.50 Core". This means the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
} | ||
|
||
mat2 randomRotation( const vec2 p ) | ||
{ | ||
float r = random(p); | ||
float sinr = sin(r); | ||
float cosr = cos(r); | ||
return mat2(cosr, sinr, -sinr, cosr); | ||
float compareDepths( in float depth1, in float depth2 ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pass in znear and zfar as arguments There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
float diff = sqrt( clamp(1.0-(depth1-depth2) / ( u_SSAOSettings2.y /* aorange */ / (u_ViewInfo.y - u_ViewInfo.x)),0.0,1.0) ); | ||
float ao = min(u_SSAOSettings.x /* aocap */,max(0.0,depth1-depth2-u_SSAOSettings2.z /* depthTolerance */) * u_SSAOSettings.z /* aoMultiplier */) * diff; | ||
return ao; | ||
} | ||
|
||
float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) | ||
vec2 rand(vec2 coord) //generating random noise | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the comment - it's already obvious from the function name that it generates random numbers. What's not obvious is the range of numbers that the function can output. Does the function output random numbers between 0 and 1? 0 and 0.004? Perhaps a comment can be added to explain that instead There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed. |
||
{ | ||
float sampleZDivW = texture(depthMap, tex).r; | ||
return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); | ||
float noiseX = (fract(sin(dot(coord ,vec2(12.9898,78.233))) * 43758.5453)); | ||
float noiseY = (fract(sin(dot(coord ,vec2(12.9898,78.233)*2.0)) * 43758.5453)); | ||
return vec2(noiseX,noiseY)*0.004; | ||
} | ||
|
||
float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar) | ||
void main(void) | ||
{ | ||
float result = 0; | ||
|
||
float sampleZ = zFar * getLinearDepth(depthMap, tex, zFarDivZNear); | ||
|
||
vec2 expectedSlope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y)); | ||
|
||
if (length(expectedSlope) > 5000.0) | ||
return 1.0; | ||
|
||
vec2 offsetScale = vec2(3.0 / sampleZ); | ||
|
||
mat2 rmat = randomRotation(tex); | ||
|
||
float depth = readDepth( var_ScreenTex ); | ||
vec2 noise = rand( var_ScreenTex ); | ||
|
||
float d; | ||
|
||
float pw = 1.0 / u_ScreenInfo.x; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can avoid having There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think you need
If you really want to continue using |
||
float ph = 1.0 / u_ScreenInfo.y; | ||
if (u_SSAOSettings2.x > 0) // apply random noise? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enabling this looks...really bad. Why have it at all? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed. |
||
{ | ||
pw /= clamp(depth,0.05,1.0)+(noise.x*(1.0-noise.x)); | ||
ph /= clamp(depth,0.05,1.0)+(noise.y*(1.0-noise.y)); | ||
} | ||
|
||
float aoCap = u_SSAOSettings.x; | ||
float ao = 0.0; | ||
float aoScale = 1.0; | ||
|
||
int i; | ||
for (i = 0; i < 3; i++) | ||
for (i = 0; i < 4; i++) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only sampling depths sideways and up/down doesn't look very good - it almost looks kind of pixelated. I think this needs to be changed to sampling in directions all around the currently pixel, not just left/up/down/right. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an awful lot of samples now... you're doing 64 samples now. Can you reduce this down to 16 again (like you had before)? |
||
{ | ||
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); | ||
} | ||
d = readDepth( vec2(var_ScreenTex.x+pw,var_ScreenTex.y+ph)); | ||
ao += compareDepths(depth,d) / aoScale; | ||
|
||
d = readDepth( vec2(var_ScreenTex.x-pw,var_ScreenTex.y+ph)); | ||
ao += compareDepths(depth,d) / aoScale; | ||
|
||
d = readDepth( vec2(var_ScreenTex.x+pw,var_ScreenTex.y-ph)); | ||
ao += compareDepths(depth,d) / aoScale; | ||
|
||
d = readDepth( vec2(var_ScreenTex.x-pw,var_ScreenTex.y-ph)); | ||
ao += compareDepths(depth,d) / aoScale; | ||
|
||
pw *= 2.0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By multiplying by 2 you're skipping depth samples in later loops... is that intentional? i.e. you read left/right/up/down going from ±1, ±2, ±4, ±8... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you multiplying |
||
ph *= 2.0; | ||
aoScale *= 1.2; | ||
} | ||
|
||
result *= 0.33333; | ||
|
||
return result; | ||
} | ||
|
||
void main() | ||
{ | ||
float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y); | ||
|
||
out_Color = vec4(vec3(result), 1.0); | ||
ao /= 16.0; | ||
ao *= u_SSAOSettings.y; | ||
|
||
float done = (1.1 - ao); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why 1.1? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops. Changed it to 1.0. |
||
if (u_SSAOSettings.w > 1) | ||
{ | ||
float orig = texture2D(u_ScreenImageMap,var_ScreenTex).x; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
But also, which texture is this reading? Why does a SSAO shader need anything other than the screen's depth texture? |
||
done *= (1.0 - orig) * u_SSAOSettings.w; | ||
} | ||
|
||
out_Color = vec4(done, done, done, 0.0); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2001,7 +2001,7 @@ static void RB_RenderSSAO() | |
{ | ||
const float zmax = backEnd.viewParms.zFar; | ||
const float zmin = r_znear->value; | ||
const vec4_t viewInfo = { zmax / zmin, zmax, 0.0f, 0.0f }; | ||
const vec4_t viewInfo = { zmin, zmax, 0.0f, 0.0f }; | ||
|
||
|
||
FBO_Bind(tr.quarterFbo[0]); | ||
|
@@ -2029,6 +2029,19 @@ static void RB_RenderSSAO() | |
GL_BindToTMU(tr.hdrDepthImage, TB_COLORMAP); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two texture samplers in the SSAO shader, but this is the only texture that gets bound. There should be another bind for the second texture... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought it was already bound. Where can I find TB_LIGHTMAP? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which texture are you expecting to read from? |
||
GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo); | ||
|
||
const vec2_t screenInfo = { (float)glConfig.vidWidth, (float)glConfig.vidHeight }; | ||
GLSL_SetUniformVec2(&tr.ssaoShader, UNIFORM_SCREENINFO, screenInfo); | ||
|
||
const vec4_t ssaoSettings = { std::fabs(r_ssao_aocap->value), | ||
std::fabs(r_ssao_strength->value), | ||
std::fabs(r_ssao_aoMultiplier->value), | ||
std::fabs(r_ssao_lightmap->value) }; | ||
GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_SSAOSETTINGS, ssaoSettings); | ||
const vec4_t ssaoSettings2 = { std::abs(r_ssao_noise->integer), | ||
std::fabs(r_ssao_aorange->value), | ||
std::fabs(r_ssao_depthTolerance->value), 0 }; | ||
GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_SSAOSETTINGS2, ssaoSettings2); | ||
|
||
RB_InstantQuad2(quadVerts, texCoords); | ||
|
||
FBO_Bind(tr.quarterFbo[1]); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,6 +111,9 @@ static uniformInfo_t uniformsInfo[] = | |
{ "u_SpecularScale", GLSL_VEC4, 1 }, | ||
|
||
{ "u_ViewInfo", GLSL_VEC4, 1 }, | ||
{ "u_ScreenInfo", GLSL_VEC2, 1 }, | ||
{ "u_SSAOSettings", GLSL_VEC4, 1 }, | ||
{ "u_SSAOSettings2", GLSL_VEC4, 1 }, | ||
{ "u_ViewOrigin", GLSL_VEC3, 1 }, | ||
{ "u_LocalViewOrigin", GLSL_VEC3, 1 }, | ||
{ "u_ViewForward", GLSL_VEC3, 1 }, | ||
|
@@ -1884,6 +1887,7 @@ static int GLSL_LoadGPUProgramSSAO( | |
|
||
qglUseProgram(tr.ssaoShader.program); | ||
GLSL_SetUniformInt(&tr.ssaoShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP); | ||
GLSL_SetUniformInt(&tr.ssaoShader, UNIFORM_SCREENIMAGEMAP, TB_LIGHTMAP); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't need this anymore |
||
qglUseProgram(0); | ||
|
||
GLSL_FinishGPUShader(&tr.ssaoShader); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,6 +133,14 @@ cvar_t *r_srgb; | |
cvar_t *r_depthPrepass; | ||
cvar_t *r_ssao; | ||
|
||
cvar_t *r_ssao_aocap; | ||
cvar_t *r_ssao_strength; | ||
cvar_t *r_ssao_aoMultiplier; | ||
cvar_t *r_ssao_lightmap; | ||
cvar_t *r_ssao_noise; | ||
cvar_t *r_ssao_aorange; | ||
cvar_t *r_ssao_depthTolerance; | ||
|
||
cvar_t *r_normalMapping; | ||
cvar_t *r_specularMapping; | ||
cvar_t *r_deluxeMapping; | ||
|
@@ -1479,6 +1487,15 @@ void R_Register( void ) | |
r_depthPrepass = ri.Cvar_Get( "r_depthPrepass", "1", CVAR_ARCHIVE, "" ); | ||
r_ssao = ri.Cvar_Get( "r_ssao", "0", CVAR_LATCH | CVAR_ARCHIVE, "" ); | ||
|
||
r_ssao_aocap = ri.Cvar_Get( "r_ssao_aocap", "1.5", CVAR_ARCHIVE, "" ); | ||
r_ssao_strength = ri.Cvar_Get( "r_ssao_strength", "1.0", CVAR_ARCHIVE, "" ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How are strength and aoMultiplier different? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forgot to remove. I added it for testing purposes. |
||
r_ssao_aoMultiplier = ri.Cvar_Get( "r_ssao_aoMultiplier", "20000.0", CVAR_ARCHIVE, "" ); | ||
char val[32]; sprintf(val, "%f", std::sqrt(10)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why have you used |
||
r_ssao_lightmap = ri.Cvar_Get( "r_ssao_lightmap", val, CVAR_ARCHIVE, "" ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's this for? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does this cvar do? It looks like you're multiplying the result of the shader by this value.. but you already have a multiplier cvar ( |
||
r_ssao_noise = ri.Cvar_Get( "r_ssao_noise", "0", CVAR_ARCHIVE, "" ); | ||
r_ssao_aorange = ri.Cvar_Get( "r_ssao_aorange", "128.0", CVAR_ARCHIVE, "" ); | ||
r_ssao_depthTolerance = ri.Cvar_Get( "r_ssao_depthTolerance", "0.0", CVAR_ARCHIVE, "" ); | ||
|
||
r_normalMapping = ri.Cvar_Get( "r_normalMapping", "1", CVAR_ARCHIVE | CVAR_LATCH, "" ); | ||
r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_ARCHIVE | CVAR_LATCH, "" ); | ||
r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH, "" ); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems unnecessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.