RobertBeckebans / RBDOOM-3-BFG

Doom 3 BFG Edition source port with updated DX12 / Vulkan renderer and modern game engine features
https://www.moddb.com/mods/rbdoom-3-bfg
GNU General Public License v3.0
1.38k stars 247 forks source link

Screen Space Ambient Occlusion #284

Closed RobertBeckebans closed 3 years ago

RobertBeckebans commented 8 years ago

Implementation based on http://graphics.cs.williams.edu/papers/SAOHPG12/

Current results: http://imgur.com/a/zjecr

aFoxNamedMorris commented 8 years ago

Holy shit! Looks good, dude! Just a question, though:

Does this implementation cause seams in the skyboxes? This was a huge issue in AO attempts for Doom 3 (2004).

RobertBeckebans commented 8 years ago

I can avoid that because this technique requires a normal G-Buffer pass and I can simply write black normals for the sky so the AO pass will skip those pixels.

2016-01-13 2:35 GMT+01:00 aFoxNamedMorris notifications@github.com:

Holy shit! Looks good, dude! Just a question, though:

Does this implementation cause seams in the skyboxes? This was a huge issue in AO attempts for Doom 3 (2004).

— Reply to this email directly or view it on GitHub https://github.com/RobertBeckebans/RBDOOM-3-BFG/issues/284#issuecomment-171124732 .

aFoxNamedMorris commented 8 years ago

Oh hell yes! Thank you!

BielBdeLuna commented 8 years ago

@RobertBeckebans could the AO only be applied on things illuminated by ambient lights? AO looks very strange when you're lighting a corner with the flashlight and there are those shadows.

aFoxNamedMorris commented 8 years ago

@BielBdeLuna In real life, shining a flashlight into the corner of a room will only slightly illuminate the places where the walls/floor/ceiling converge. There's still a slight shadow.

BielBdeLuna commented 8 years ago

yes but in that case more than a shadow there should be a reinforcement of the light due light bouncing arround

I propose that if there is an ambient light then there is AO but then the more diffuse light that surface gets the less AO there is, so diffuse light undermine the AO but only inversely proportional to the amount of diffuse light, so the less diffuse light there is the more AO.

BielBdeLuna commented 8 years ago

@RobertBeckebans SSAO nor SSGI work when I activate them, the screen goes black, and once I deactivate them the exposure is 0 or near zero and it takes a second or two to go back to the normal exposure

If I use r_SSAODebug 1 the screen goes middle gray, just the decals appear textured, but no AO shadows appear in the corners, they seem to work only in a tiny topmost fraction of the screen

SSGI doesn't work also

ghost commented 8 years ago

Both SSAO and SSGI works on my build, however SSAO slows the game down to a crawl at 15 fps, without it I get 60 fps average.

aFoxNamedMorris commented 8 years ago

SSAO works fine. The tonemapping is occasionally going crazy, but the SSGI seems to do nothing on my end so far. Nvidia graphics on 64-bit Linux.

ghost commented 8 years ago

@aFoxNamedMorris Agreed, and the size, distortion and "reflection texture" from the flashlight changes according to distance. This is something I still have to see in a game.

RobertBeckebans commented 8 years ago

r_useSSAO should be stable with all OpenGL drivers however it can be slow with resolutions higher than Full HD. I get steady 60 fps with all features enabled at Full HD with a 3 years old Geforce GTX 660 ti. However I get performance drops down to 45 fps at 2560x1440. The screen space global illumination code is highly experimental research and outcommented. However here are a few screenshots of its current state: http://imgur.com/a/zXDPr

BielBdeLuna commented 8 years ago

now I see it, there are compile errors from the shaders on my end, I haven't modified, maybe my drivers can't understand them? like always Oibaf Mesa 11.2 running on a Sandy Bridge with a Ubuntu 15.10. I got the following errors:

----- Initializing Render Shaders -----
While compiling fragment program renderprogs/AmbientOcclusion_AO.pixel
-----------------
  1: // filename renderprogs/AmbientOcclusion_AO.pixel
  2: #version 300 es
  3: #define PC
  4: precision mediump float;
  5: precision lowp sampler2D;
  6: precision lowp sampler2DShadow;
  7: precision lowp sampler2DArray;
  8: precision lowp sampler2DArrayShadow;
  9: precision lowp samplerCube;
 10: precision lowp samplerCubeShadow;
 11: precision lowp sampler3D;
 12: 
 13: void clip( float v ) { if ( v < 0.0 ) { discard; } }
 14: void clip( vec2 v ) { if ( any( lessThan( v, vec2( 0.0 ) ) ) ) { discard; } }
 15: void clip( vec3 v ) { if ( any( lessThan( v, vec3( 0.0 ) ) ) ) { discard; } }
 16: void clip( vec4 v ) { if ( any( lessThan( v, vec4( 0.0 ) ) ) ) { discard; } }
 17: 
 18: float saturate( float v ) { return clamp( v, 0.0, 1.0 ); }
 19: vec2 saturate( vec2 v ) { return clamp( v, 0.0, 1.0 ); }
 20: vec3 saturate( vec3 v ) { return clamp( v, 0.0, 1.0 ); }
 21: vec4 saturate( vec4 v ) { return clamp( v, 0.0, 1.0 ); }
 22: 
 23: vec4 tex2D( sampler2D sampler, vec2 texcoord ) { return texture( sampler, texcoord.xy ); }
 24: vec4 tex2D( sampler2DShadow sampler, vec3 texcoord ) { return vec4( texture( sampler, texcoord.xyz ) ); }
 25: 
 26: vec4 tex2D( sampler2D sampler, vec2 texcoord, vec2 dx, vec2 dy ) { return textureGrad( sampler, texcoord.xy, dx, dy ); }
 27: vec4 tex2D( sampler2DShadow sampler, vec3 texcoord, vec2 dx, vec2 dy ) { return vec4( textureGrad( sampler, texcoord.xyz, dx, dy ) ); }
 28: 
 29: vec4 texCUBE( samplerCube sampler, vec3 texcoord ) { return texture( sampler, texcoord.xyz ); }
 30: vec4 texCUBE( samplerCubeShadow sampler, vec4 texcoord ) { return vec4( texture( sampler, texcoord.xyzw ) ); }
 31: 
 32: vec4 tex2Dproj( sampler2D sampler, vec3 texcoord ) { return textureProj( sampler, texcoord ); }
 33: vec4 tex3Dproj( sampler3D sampler, vec4 texcoord ) { return textureProj( sampler, texcoord ); }
 34: 
 35: vec4 tex2Dbias( sampler2D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xy, texcoord.w ); }
 36: vec4 tex3Dbias( sampler3D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }
 37: vec4 texCUBEbias( samplerCube sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }
 38: 
 39: vec4 tex2Dlod( sampler2D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xy, texcoord.w ); }
 40: vec4 tex3Dlod( sampler3D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }
 41: vec4 texCUBElod( samplerCube sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }
 42: 
 43: 
 44: uniform vec4 _fa_[5];
 45: 
 46: float dot4 (vec4 a , vec4 b ) {return dot ( a , b ) ; }
 47: float dot4 (vec2 a , vec4 b ) {return dot ( vec4 ( a , 0 , 1 ) , b ) ; }
 48: const float DOOM_TO_METERS = 0.0254;
 49: const float METERS_TO_DOOM = ( 1.0 / DOOM_TO_METERS );
 50: const float radius = 1.0 * METERS_TO_DOOM;
 51: const float radius2 = radius * radius;
 52: const float invRadius2 = 1.0 / radius2;
 53: const float bias = 0.01 * METERS_TO_DOOM;
 54: const float intensity = 0.6;
 55: const float projScale = 500.0;
 56: uniform sampler2D samp0;
 57: uniform sampler2D samp1;
 58: 
 59: in vec2 vofi_TexCoord0;
 60: 
 61: out vec4 fo_FragColor;
 62: 
 63: vec3 reconstructCSPosition (vec2 S , float z ) {
 64:    vec4 P ;
 65:    P. z = z * 2.0 - 1.0 ;
 66:    P. xy = ( S * _fa_[0 /* rpScreenCorrectionFactor */] . xy ) * 2.0 - 1.0 ;
 67:    P. w = 1.0 ;
 68:    vec4 csP ;
 69:    csP. x = dot4 ( P , _fa_[1 /* rpModelMatrixX */] ) ;
 70:    csP. y = dot4 ( P , _fa_[2 /* rpModelMatrixY */] ) ;
 71:    csP. z = dot4 ( P , _fa_[3 /* rpModelMatrixZ */] ) ;
 72:    csP. w = dot4 ( P , _fa_[4 /* rpModelMatrixW */] ) ;
 73:    csP. xyz /= csP. w ;
 74:    return csP. xyz ;
 75: }
 76: vec3 sampleNormal (sampler2D normalBuffer , ivec2 ssC , int mipLevel ) {
 77:    return texelFetch ( normalBuffer , ssC , mipLevel ). xyz * 2.0 - 1.0 ;
 78: }
 79: vec2 tapLocation (int sampleNumber , float spinAngle , out float ssR ) {
 80:    float alpha = float ( sampleNumber + 0.5 ) * ( 1.0 / 11 ) ;
 81:    float angle = alpha * ( 7 * 6.28 ) + spinAngle ;
 82:    ssR = alpha ;
 83:    return vec2 ( cos ( angle ) , sin ( angle ) ) ;
 84: }
 85: vec3 getPosition (ivec2 ssP , sampler2D cszBuffer ) {
 86:    vec3 P ;
 87:    P. z = texelFetch ( cszBuffer , ssP , 0 ). r ;
 88:    P = reconstructCSPosition ( vec2 ( ssP ) + vec2 ( 0.5 ) , P. z ) ;
 89:    return P ;
 90: }
 91: void computeMipInfo (float ssR , ivec2 ssP , sampler2D cszBuffer , out int mipLevel , out ivec2 mipP ) {
 92:    mipLevel = clamp ( int ( floor ( log2 ( ssR ) ) ) - ( 3 ) , 0 , ( 5 ) ) ;
 93:    mipP = clamp ( ssP >> mipLevel , ivec2 ( 0 ) , textureSize ( cszBuffer , mipLevel ) - ivec2 ( 1 ) ) ;
 94: }
 95: vec3 getOffsetPosition (ivec2 issC , vec2 unitOffset , float ssR , sampler2D cszBuffer , float invCszBufferScale ) {
 96:    ivec2 ssP = ivec2 ( ssR * unitOffset ) + issC ;
 97:    vec3 P ;
 98:    int mipLevel ;
 99:    ivec2 mipP ;
100:    computeMipInfo ( ssR , ssP , cszBuffer , mipLevel , mipP ) ;
101:    P. z = texelFetch ( cszBuffer , mipP , mipLevel ). r ;
102:    P = reconstructCSPosition ( vec2 ( ssP ) + vec2 ( 0.5 ) , P. z ) ;
103:    return P ;
104: }
105: float fallOffFunction (float vv , float vn , float epsilon ) {
106:    float f = max ( 1.0 - vv * invRadius2 , 0.0 ) ;
107:    return f * max ( ( vn - bias ) * inversesqrt ( epsilon + vv ) , 0.0 ) ;
108: }
109: float aoValueFromPositionsAndNormal (vec3 C , vec3 n_C , vec3 Q ) {
110:    vec3 v = Q - C ;
111:    float vv = dot ( v , v ) ;
112:    float vn = dot ( v , n_C ) ;
113:    const float epsilon = 0.001 ;
114:    return fallOffFunction ( vv , vn , epsilon ) * mix ( 1.0 , max ( 0.0 , 1.5 * n_C. z ) , 0.35 ) ;
115: }
116: float sampleAO (ivec2 issC , in vec3 C , in vec3 n_C , in float ssDiskRadius , in int tapIndex , in float randomPatternRotationAngle , in sampler2D cszBuffer , in float invCszBufferScale ) {
117:    float ssR ;
118:    vec2 unitOffset = tapLocation ( tapIndex , randomPatternRotationAngle , ssR ) ;
119:    ssR = max ( 0.75 , ssR * ssDiskRadius ) ;
120:    vec3 Q = getOffsetPosition ( issC , unitOffset , ssR , cszBuffer , invCszBufferScale ) ;
121:    return aoValueFromPositionsAndNormal ( C , n_C , Q ) ;
122: }
123: const float MIN_RADIUS = 3.0;
124: void main() {
125:    fo_FragColor = vec4 ( 1.0 , 0.0 , 0.0 , 1.0 ) ;
126:    ivec2 ssP = ivec2 ( gl_FragCoord. xy ) ;
127:    vec3 C = getPosition ( ssP , samp1 ) ;
128:    fo_FragColor . r = 0.0 ;
129:    vec3 n_C = sampleNormal ( samp0 , ssP , 0 ) ;
130:    if ( length ( n_C ) < 0.01 )
131:    {
132:        fo_FragColor . r = 1.0 ;
133:        return ;
134:    }
135:    n_C = normalize ( n_C ) ;
136:    float randomPatternRotationAngle = ( ( ( 3 * ssP. x ) ^ ( ssP. y + ssP. x * ssP. y ) )
137:    ) * 10 ;
138:    float ssDiskRadius = - projScale * radius / C. z ;
139:    if ( ssDiskRadius <= MIN_RADIUS )
140:    {
141:        fo_FragColor . r = 1.0 ;
142:        return ;
143:    }
144:    float sum = 0.0 ;
145:    for ( int i = 0 ; i < 11 ; ++ i )
146:    {
147:        sum += sampleAO ( ssP , C , n_C , ssDiskRadius , i , randomPatternRotationAngle , samp1 , 1 ) ;
148:    }
149:    float A = pow ( max ( 0.0 , 1.0 - sqrt ( sum * ( 3.0 / 11 ) ) ) , intensity ) ;
150:    fo_FragColor . r = mix ( 1.0 , A , saturate ( ssDiskRadius - MIN_RADIUS ) ) ;
151: }
-----------------
0:80(24): error: could not implicitly convert operands to arithmetic operator
0:80(16): error: cannot construct `float' from a non-numeric data type
0:80(49): error: could not implicitly convert operands to arithmetic operator
0:80(16): error: operands to arithmetic operators must be numeric
0:81(26): error: could not implicitly convert operands to arithmetic operator
0:81(16): error: operands to arithmetic operators must be numeric
0:81(16): error: operands to arithmetic operators must be numeric
0:136(2): error: initializer of type int cannot be assigned to variable of type float
0:147(9): error: no matching function for call to `sampleAO(ivec2, vec3, vec3, float, int, int, sampler2D, int)'; candidates are:
0:147(9): error:    float sampleAO(ivec2, vec3, vec3, float, int, float, sampler2D, float)
0:147(2): error: operands to arithmetic operators must be numeric
0:149(51): error: could not implicitly convert operands to arithmetic operator
0:149(43): error: operands to arithmetic operators must be numeric
0:149(36): error: no matching function for call to `sqrt(error)'; candidates are:
0:149(36): error:    float sqrt(float)
0:149(36): error:    vec2 sqrt(vec2)
0:149(36): error:    vec3 sqrt(vec3)
0:149(36): error:    vec4 sqrt(vec4)
0:149(30): error: operands to arithmetic operators must be numeric
0:149(18): error: no matching function for call to `max(float, error)'; candidates are:
0:149(18): error:    float max(float, float)
0:149(18): error:    float max(float, float)
0:149(18): error:    vec2 max(vec2, float)
0:149(18): error:    vec3 max(vec3, float)
0:149(18): error:    vec4 max(vec4, float)
0:149(18): error:    vec2 max(vec2, vec2)
0:149(18): error:    vec3 max(vec3, vec3)
0:149(18): error:    vec4 max(vec4, vec4)
0:149(18): error:    int max(int, int)
0:149(18): error:    ivec2 max(ivec2, int)
0:149(18): error:    ivec3 max(ivec3, int)
0:149(18): error:    ivec4 max(ivec4, int)
0:149(18): error:    ivec2 max(ivec2, ivec2)
0:149(18): error:    ivec3 max(ivec3, ivec3)
0:149(18): error:    ivec4 max(ivec4, ivec4)
0:149(18): error:    uint max(uint, uint)
0:149(18): error:    uvec2 max(uvec2, uint)
0:149(18): error:    uvec3 max(uvec3, uint)
0:149(18): error:    uvec4 max(uvec4, uint)
0:149(18): error:    uvec2 max(uvec2, uvec2)
0:149(18): error:    uvec3 max(uvec3, uvec3)
0:149(18): error:    uvec4 max(uvec4, uvec4)
0:149(12): error: no matching function for call to `pow(error, float)'; candidates are:
0:149(12): error:    float pow(float, float)
0:149(12): error:    vec2 pow(vec2, vec2)
0:149(12): error:    vec3 pow(vec3, vec3)
0:149(12): error:    vec4 pow(vec4, vec4)

While compiling fragment program renderprogs/AmbientOcclusion_AO.pixel
-----------------
  1: // filename renderprogs/AmbientOcclusion_AO.pixel
  2: #version 300 es
  3: #define PC
  4: precision mediump float;
  5: precision lowp sampler2D;
  6: precision lowp sampler2DShadow;
  7: precision lowp sampler2DArray;
  8: precision lowp sampler2DArrayShadow;
  9: precision lowp samplerCube;
 10: precision lowp samplerCubeShadow;
 11: precision lowp sampler3D;
 12: 
 13: void clip( float v ) { if ( v < 0.0 ) { discard; } }
 14: void clip( vec2 v ) { if ( any( lessThan( v, vec2( 0.0 ) ) ) ) { discard; } }
 15: void clip( vec3 v ) { if ( any( lessThan( v, vec3( 0.0 ) ) ) ) { discard; } }
 16: void clip( vec4 v ) { if ( any( lessThan( v, vec4( 0.0 ) ) ) ) { discard; } }
 17: 
 18: float saturate( float v ) { return clamp( v, 0.0, 1.0 ); }
 19: vec2 saturate( vec2 v ) { return clamp( v, 0.0, 1.0 ); }
 20: vec3 saturate( vec3 v ) { return clamp( v, 0.0, 1.0 ); }
 21: vec4 saturate( vec4 v ) { return clamp( v, 0.0, 1.0 ); }
 22: 
 23: vec4 tex2D( sampler2D sampler, vec2 texcoord ) { return texture( sampler, texcoord.xy ); }
 24: vec4 tex2D( sampler2DShadow sampler, vec3 texcoord ) { return vec4( texture( sampler, texcoord.xyz ) ); }
 25: 
 26: vec4 tex2D( sampler2D sampler, vec2 texcoord, vec2 dx, vec2 dy ) { return textureGrad( sampler, texcoord.xy, dx, dy ); }
 27: vec4 tex2D( sampler2DShadow sampler, vec3 texcoord, vec2 dx, vec2 dy ) { return vec4( textureGrad( sampler, texcoord.xyz, dx, dy ) ); }
 28: 
 29: vec4 texCUBE( samplerCube sampler, vec3 texcoord ) { return texture( sampler, texcoord.xyz ); }
 30: vec4 texCUBE( samplerCubeShadow sampler, vec4 texcoord ) { return vec4( texture( sampler, texcoord.xyzw ) ); }
 31: 
 32: vec4 tex2Dproj( sampler2D sampler, vec3 texcoord ) { return textureProj( sampler, texcoord ); }
 33: vec4 tex3Dproj( sampler3D sampler, vec4 texcoord ) { return textureProj( sampler, texcoord ); }
 34: 
 35: vec4 tex2Dbias( sampler2D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xy, texcoord.w ); }
 36: vec4 tex3Dbias( sampler3D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }
 37: vec4 texCUBEbias( samplerCube sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }
 38: 
 39: vec4 tex2Dlod( sampler2D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xy, texcoord.w ); }
 40: vec4 tex3Dlod( sampler3D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }
 41: vec4 texCUBElod( samplerCube sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }
 42: 
 43: 
 44: uniform vec4 _fa_[5];
 45: 
 46: float dot4 (vec4 a , vec4 b ) {return dot ( a , b ) ; }
 47: float dot4 (vec2 a , vec4 b ) {return dot ( vec4 ( a , 0 , 1 ) , b ) ; }
 48: const float DOOM_TO_METERS = 0.0254;
 49: const float METERS_TO_DOOM = ( 1.0 / DOOM_TO_METERS );
 50: const float radius = 1.0 * METERS_TO_DOOM;
 51: const float radius2 = radius * radius;
 52: const float invRadius2 = 1.0 / radius2;
 53: const float bias = 0.01 * METERS_TO_DOOM;
 54: const float intensity = 0.6;
 55: const float projScale = 500.0;
 56: uniform sampler2D samp0;
 57: uniform sampler2D samp1;
 58: 
 59: in vec2 vofi_TexCoord0;
 60: 
 61: out vec4 fo_FragColor;
 62: 
 63: vec3 reconstructCSPosition (vec2 S , float z ) {
 64:    vec4 P ;
 65:    P. z = z * 2.0 - 1.0 ;
 66:    P. xy = ( S * _fa_[0 /* rpScreenCorrectionFactor */] . xy ) * 2.0 - 1.0 ;
 67:    P. w = 1.0 ;
 68:    vec4 csP ;
 69:    csP. x = dot4 ( P , _fa_[1 /* rpModelMatrixX */] ) ;
 70:    csP. y = dot4 ( P , _fa_[2 /* rpModelMatrixY */] ) ;
 71:    csP. z = dot4 ( P , _fa_[3 /* rpModelMatrixZ */] ) ;
 72:    csP. w = dot4 ( P , _fa_[4 /* rpModelMatrixW */] ) ;
 73:    csP. xyz /= csP. w ;
 74:    return csP. xyz ;
 75: }
 76: vec3 sampleNormal (sampler2D normalBuffer , ivec2 ssC , int mipLevel ) {
 77:    return texelFetch ( normalBuffer , ssC , mipLevel ). xyz * 2.0 - 1.0 ;
 78: }
 79: vec2 tapLocation (int sampleNumber , float spinAngle , out float ssR ) {
 80:    float alpha = float ( sampleNumber + 0.5 ) * ( 1.0 / 11 ) ;
 81:    float angle = alpha * ( 7 * 6.28 ) + spinAngle ;
 82:    ssR = alpha ;
 83:    return vec2 ( cos ( angle ) , sin ( angle ) ) ;
 84: }
 85: vec3 getPosition (ivec2 ssP , sampler2D cszBuffer ) {
 86:    vec3 P ;
 87:    P. z = texelFetch ( cszBuffer , ssP , 0 ). r ;
 88:    P = reconstructCSPosition ( vec2 ( ssP ) + vec2 ( 0.5 ) , P. z ) ;
 89:    return P ;
 90: }
 91: void computeMipInfo (float ssR , ivec2 ssP , sampler2D cszBuffer , out int mipLevel , out ivec2 mipP ) {
 92:    mipLevel = clamp ( int ( floor ( log2 ( ssR ) ) ) - ( 3 ) , 0 , ( 5 ) ) ;
 93:    mipP = clamp ( ssP >> mipLevel , ivec2 ( 0 ) , textureSize ( cszBuffer , mipLevel ) - ivec2 ( 1 ) ) ;
 94: }
 95: vec3 getOffsetPosition (ivec2 issC , vec2 unitOffset , float ssR , sampler2D cszBuffer , float invCszBufferScale ) {
 96:    ivec2 ssP = ivec2 ( ssR * unitOffset ) + issC ;
 97:    vec3 P ;
 98:    int mipLevel ;
 99:    ivec2 mipP ;
100:    computeMipInfo ( ssR , ssP , cszBuffer , mipLevel , mipP ) ;
101:    P. z = texelFetch ( cszBuffer , mipP , mipLevel ). r ;
102:    P = reconstructCSPosition ( vec2 ( ssP ) + vec2 ( 0.5 ) , P. z ) ;
103:    return P ;
104: }
105: float fallOffFunction (float vv , float vn , float epsilon ) {
106:    float f = max ( 1.0 - vv * invRadius2 , 0.0 ) ;
107:    return f * max ( ( vn - bias ) * inversesqrt ( epsilon + vv ) , 0.0 ) ;
108: }
109: float aoValueFromPositionsAndNormal (vec3 C , vec3 n_C , vec3 Q ) {
110:    vec3 v = Q - C ;
111:    float vv = dot ( v , v ) ;
112:    float vn = dot ( v , n_C ) ;
113:    const float epsilon = 0.001 ;
114:    return fallOffFunction ( vv , vn , epsilon ) * mix ( 1.0 , max ( 0.0 , 1.5 * n_C. z ) , 0.35 ) ;
115: }
116: float sampleAO (ivec2 issC , in vec3 C , in vec3 n_C , in float ssDiskRadius , in int tapIndex , in float randomPatternRotationAngle , in sampler2D cszBuffer , in float invCszBufferScale ) {
117:    float ssR ;
118:    vec2 unitOffset = tapLocation ( tapIndex , randomPatternRotationAngle , ssR ) ;
119:    ssR = max ( 0.75 , ssR * ssDiskRadius ) ;
120:    vec3 Q = getOffsetPosition ( issC , unitOffset , ssR , cszBuffer , invCszBufferScale ) ;
121:    return aoValueFromPositionsAndNormal ( C , n_C , Q ) ;
122: }
123: const float MIN_RADIUS = 3.0;
124: void main() {
125:    fo_FragColor = vec4 ( 1.0 , 0.0 , 0.0 , 1.0 ) ;
126:    ivec2 ssP = ivec2 ( gl_FragCoord. xy ) ;
127:    vec3 C = getPosition ( ssP , samp1 ) ;
128:    fo_FragColor . r = 0.0 ;
129:    vec3 n_C = sampleNormal ( samp0 , ssP , 0 ) ;
130:    if ( length ( n_C ) < 0.01 )
131:    {
132:        fo_FragColor . r = 1.0 ;
133:        return ;
134:    }
135:    n_C = normalize ( n_C ) ;
136:    float randomPatternRotationAngle = ( ( ( 3 * ssP. x ) ^ ( ssP. y + ssP. x * ssP. y ) )
137:    ) * 10 ;
138:    float ssDiskRadius = - projScale * radius / C. z ;
139:    if ( ssDiskRadius <= MIN_RADIUS )
140:    {
141:        fo_FragColor . r = 1.0 ;
142:        return ;
143:    }
144:    float sum = 0.0 ;
145:    for ( int i = 0 ; i < 11 ; ++ i )
146:    {
147:        sum += sampleAO ( ssP , C , n_C , ssDiskRadius , i , randomPatternRotationAngle , samp1 , 1 ) ;
148:    }
149:    float A = pow ( max ( 0.0 , 1.0 - sqrt ( sum * ( 3.0 / 11 ) ) ) , intensity ) ;
150:    fo_FragColor . r = mix ( 1.0 , A , saturate ( ssDiskRadius - MIN_RADIUS ) ) ;
151:    fo_FragColor = vec4 ( fo_FragColor . r , fo_FragColor . r , fo_FragColor . r , 1.0 ) ;
152: }
-----------------
0:80(24): error: could not implicitly convert operands to arithmetic operator
0:80(16): error: cannot construct `float' from a non-numeric data type
0:80(49): error: could not implicitly convert operands to arithmetic operator
0:80(16): error: operands to arithmetic operators must be numeric
0:81(26): error: could not implicitly convert operands to arithmetic operator
0:81(16): error: operands to arithmetic operators must be numeric
0:81(16): error: operands to arithmetic operators must be numeric
0:136(2): error: initializer of type int cannot be assigned to variable of type float
0:147(9): error: no matching function for call to `sampleAO(ivec2, vec3, vec3, float, int, int, sampler2D, int)'; candidates are:
0:147(9): error:    float sampleAO(ivec2, vec3, vec3, float, int, float, sampler2D, float)
0:147(2): error: operands to arithmetic operators must be numeric
0:149(51): error: could not implicitly convert operands to arithmetic operator
0:149(43): error: operands to arithmetic operators must be numeric
0:149(36): error: no matching function for call to `sqrt(error)'; candidates are:
0:149(36): error:    float sqrt(float)
0:149(36): error:    vec2 sqrt(vec2)
0:149(36): error:    vec3 sqrt(vec3)
0:149(36): error:    vec4 sqrt(vec4)
0:149(30): error: operands to arithmetic operators must be numeric
0:149(18): error: no matching function for call to `max(float, error)'; candidates are:
0:149(18): error:    float max(float, float)
0:149(18): error:    float max(float, float)
0:149(18): error:    vec2 max(vec2, float)
0:149(18): error:    vec3 max(vec3, float)
0:149(18): error:    vec4 max(vec4, float)
0:149(18): error:    vec2 max(vec2, vec2)
0:149(18): error:    vec3 max(vec3, vec3)
0:149(18): error:    vec4 max(vec4, vec4)
0:149(18): error:    int max(int, int)
0:149(18): error:    ivec2 max(ivec2, int)
0:149(18): error:    ivec3 max(ivec3, int)
0:149(18): error:    ivec4 max(ivec4, int)
0:149(18): error:    ivec2 max(ivec2, ivec2)
0:149(18): error:    ivec3 max(ivec3, ivec3)
0:149(18): error:    ivec4 max(ivec4, ivec4)
0:149(18): error:    uint max(uint, uint)
0:149(18): error:    uvec2 max(uvec2, uint)
0:149(18): error:    uvec3 max(uvec3, uint)
0:149(18): error:    uvec4 max(uvec4, uint)
0:149(18): error:    uvec2 max(uvec2, uvec2)
0:149(18): error:    uvec3 max(uvec3, uvec3)
0:149(18): error:    uvec4 max(uvec4, uvec4)
0:149(12): error: no matching function for call to `pow(error, float)'; candidates are:
0:149(12): error:    float pow(float, float)
0:149(12): error:    vec2 pow(vec2, vec2)
0:149(12): error:    vec3 pow(vec3, vec3)
0:149(12): error:    vec4 pow(vec4, vec4)

While compiling fragment program renderprogs/DeepGBufferRadiosity_radiosity.pixel
-----------------
  1: // filename renderprogs/DeepGBufferRadiosity_radiosity.pixel
  2: #version 300 es
  3: #define PC
  4: precision mediump float;
  5: precision lowp sampler2D;
  6: precision lowp sampler2DShadow;
  7: precision lowp sampler2DArray;
  8: precision lowp sampler2DArrayShadow;
  9: precision lowp samplerCube;
 10: precision lowp samplerCubeShadow;
 11: precision lowp sampler3D;
 12: 
 13: void clip( float v ) { if ( v < 0.0 ) { discard; } }
 14: void clip( vec2 v ) { if ( any( lessThan( v, vec2( 0.0 ) ) ) ) { discard; } }
 15: void clip( vec3 v ) { if ( any( lessThan( v, vec3( 0.0 ) ) ) ) { discard; } }
 16: void clip( vec4 v ) { if ( any( lessThan( v, vec4( 0.0 ) ) ) ) { discard; } }
 17: 
 18: float saturate( float v ) { return clamp( v, 0.0, 1.0 ); }
 19: vec2 saturate( vec2 v ) { return clamp( v, 0.0, 1.0 ); }
 20: vec3 saturate( vec3 v ) { return clamp( v, 0.0, 1.0 ); }
 21: vec4 saturate( vec4 v ) { return clamp( v, 0.0, 1.0 ); }
 22: 
 23: vec4 tex2D( sampler2D sampler, vec2 texcoord ) { return texture( sampler, texcoord.xy ); }
 24: vec4 tex2D( sampler2DShadow sampler, vec3 texcoord ) { return vec4( texture( sampler, texcoord.xyz ) ); }
 25: 
 26: vec4 tex2D( sampler2D sampler, vec2 texcoord, vec2 dx, vec2 dy ) { return textureGrad( sampler, texcoord.xy, dx, dy ); }
 27: vec4 tex2D( sampler2DShadow sampler, vec3 texcoord, vec2 dx, vec2 dy ) { return vec4( textureGrad( sampler, texcoord.xyz, dx, dy ) ); }
 28: 
 29: vec4 texCUBE( samplerCube sampler, vec3 texcoord ) { return texture( sampler, texcoord.xyz ); }
 30: vec4 texCUBE( samplerCubeShadow sampler, vec4 texcoord ) { return vec4( texture( sampler, texcoord.xyzw ) ); }
 31: 
 32: vec4 tex2Dproj( sampler2D sampler, vec3 texcoord ) { return textureProj( sampler, texcoord ); }
 33: vec4 tex3Dproj( sampler3D sampler, vec4 texcoord ) { return textureProj( sampler, texcoord ); }
 34: 
 35: vec4 tex2Dbias( sampler2D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xy, texcoord.w ); }
 36: vec4 tex3Dbias( sampler3D sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }
 37: vec4 texCUBEbias( samplerCube sampler, vec4 texcoord ) { return texture( sampler, texcoord.xyz, texcoord.w ); }
 38: 
 39: vec4 tex2Dlod( sampler2D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xy, texcoord.w ); }
 40: vec4 tex3Dlod( sampler3D sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }
 41: vec4 texCUBElod( samplerCube sampler, vec4 texcoord ) { return textureLod( sampler, texcoord.xyz, texcoord.w ); }
 42: 
 43: 
 44: uniform vec4 _fa_[5];
 45: 
 46: float dot4 (vec4 a , vec4 b ) {return dot ( a , b ) ; }
 47: float dot4 (vec2 a , vec4 b ) {return dot ( vec4 ( a , 0 , 1 ) , b ) ; }
 48: const float DOOM_TO_METERS = 0.0254;
 49: const float METERS_TO_DOOM = ( 1.0 / DOOM_TO_METERS );
 50: const float radius = 1.0 * METERS_TO_DOOM;
 51: const float radius2 = radius * radius;
 52: const float projScale = 500.0;
 53: uniform sampler2D samp0;
 54: uniform sampler2D samp1;
 55: uniform sampler2D samp2;
 56: 
 57: in vec2 vofi_TexCoord0;
 58: 
 59: out vec4 fo_FragColor;
 60: 
 61: vec3 reconstructCSPosition (vec2 S , float z ) {
 62:    vec4 P ;
 63:    P. z = z * 2.0 - 1.0 ;
 64:    P. xy = ( S * _fa_[0 /* rpScreenCorrectionFactor */] . xy ) * 2.0 - 1.0 ;
 65:    P. w = 1.0 ;
 66:    vec4 csP ;
 67:    csP. x = dot4 ( P , _fa_[1 /* rpModelMatrixX */] ) ;
 68:    csP. y = dot4 ( P , _fa_[2 /* rpModelMatrixY */] ) ;
 69:    csP. z = dot4 ( P , _fa_[3 /* rpModelMatrixZ */] ) ;
 70:    csP. w = dot4 ( P , _fa_[4 /* rpModelMatrixW */] ) ;
 71:    csP. xyz /= csP. w ;
 72:    return csP. xyz ;
 73: }
 74: vec3 sampleNormal (sampler2D normalBuffer , ivec2 ssC , int mipLevel ) {
 75:    return texelFetch ( normalBuffer , ssC , mipLevel ). xyz * 2.0 - 1.0 ;
 76: }
 77: vec2 tapLocation (int sampleNumber , float spinAngle , float radialJitter , out float ssR ) {
 78:    float alpha = float ( sampleNumber + radialJitter ) * ( 1.0 / 11 ) ;
 79:    float angle = alpha * ( 7 * 6.28 ) + spinAngle ;
 80:    ssR = alpha ;
 81:    return vec2 ( cos ( angle ) , sin ( angle ) ) ;
 82: }
 83: vec3 getPosition (ivec2 ssP , sampler2D cszBuffer ) {
 84:    vec3 P ;
 85:    P. z = texelFetch ( cszBuffer , ssP , 0 ). r ;
 86:    P = reconstructCSPosition ( vec2 ( ssP ) + vec2 ( 0.5 ) , P. z ) ;
 87:    return P ;
 88: }
 89: void computeMipInfo (float ssR , ivec2 ssP , sampler2D cszBuffer , inout int mipLevel , inout ivec2 mipP ) {
 90:    mipLevel = clamp ( int ( floor ( log2 ( ssR ) ) ) - ( 3 ) , 0 , ( 5 ) ) ;
 91:    mipP = clamp ( ssP >> mipLevel , ivec2 ( 0 ) , textureSize ( cszBuffer , mipLevel ) - ivec2 ( 1 ) ) ;
 92: }
 93: void getOffsetPositionNormalAndLambertian (ivec2 ssP ,
 94: float ssR ,
 95: sampler2D cszBuffer ,
 96: sampler2D bounceBuffer ,
 97: sampler2D normalBuffer ,
 98: inout vec3 Q ,
 99: inout vec3 lambertian_tap ,
100: inout vec3 n_tap ) {
101:    int mipLevel ;
102:    ivec2 texel ;
103:    computeMipInfo ( ssR , ssP , cszBuffer , mipLevel , texel ) ;
104:    float z = texelFetch ( cszBuffer , texel , mipLevel ). r ;
105:    vec3 n = sampleNormal ( normalBuffer , ssP , 0 ) ;
106:    lambertian_tap = texelFetch ( bounceBuffer , ssP , 0 ). rgb ;
107:    n_tap = n ;
108:    Q = reconstructCSPosition ( ( vec2 ( ssP ) + vec2 ( 0.5 ) ) , z ) ;
109: }
110: void iiValueFromPositionsAndNormalsAndLambertian (ivec2 ssP , vec3 X , vec3 n_X , vec3 Y , vec3 n_Y , vec3 radiosity_Y , inout vec3 E , inout float weight_Y , inout float visibilityWeight_Y ) {
111:    vec3 YminusX = Y - X ;
112:    vec3 w_i = normalize ( YminusX ) ;
113:    weight_Y = ( ( dot ( w_i , n_X ) > 0.0 )
114:    && ( dot ( - w_i , n_Y ) > 0.01 )
115:    ) ? 1.0 : 0.0 ;
116:    if ( ( dot ( YminusX , YminusX ) < radius2 ) &&
117:    ( weight_Y > 0 ) )
118:    {
119:        E = radiosity_Y * dot ( w_i , n_X ) ;
120:    }
121:    else
122:    {
123:        E = vec3 ( 0 ) ;
124:    }
125: }
126: void sampleIndirectLight (in ivec2 ssC ,
127: in vec3 C ,
128: in vec3 n_C ,
129: in vec3 C_peeled ,
130: in vec3 n_C_peeled ,
131: in float ssDiskRadius ,
132: in int tapIndex ,
133: in float randomPatternRotationAngle ,
134: in float radialJitter ,
135: in sampler2D cszBuffer ,
136: in sampler2D nBuffer ,
137: in sampler2D bounceBuffer ,
138: inout vec3 irradianceSum ,
139: inout float numSamplesUsed ,
140: inout vec3 iiPeeled ,
141: inout float weightSumPeeled ) {
142:    float visibilityWeightPeeled0 , visibilityWeightPeeled1 ;
143:    float ssR ;
144:    vec2 unitOffset = tapLocation ( tapIndex , randomPatternRotationAngle , radialJitter , ssR ) ;
145:    ssR *= ssDiskRadius ;
146:    ivec2 ssP = ivec2 ( ssR * unitOffset ) + ssC ;
147:    vec3 E ;
148:    float visibilityWeight ;
149:    float weight_Y ;
150:    vec3 Q , lambertian_tap , n_tap ;
151:    getOffsetPositionNormalAndLambertian ( ssP , ssR , cszBuffer , bounceBuffer , nBuffer , Q , lambertian_tap , n_tap ) ;
152:    iiValueFromPositionsAndNormalsAndLambertian ( ssP , C , n_C , Q , n_tap , lambertian_tap , E , weight_Y , visibilityWeight ) ;
153:    numSamplesUsed += weight_Y ;
154:    irradianceSum += E ;
155: }
156: void main() {
157:    fo_FragColor = vec4 ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
158:    ivec2 ssC = ivec2 ( gl_FragCoord. xy ) ;
159:    vec3 C = getPosition ( ssC , samp1 ) ;
160:    vec3 C_peeled = vec3 ( 0 ) ;
161:    vec3 n_C_peeled = vec3 ( 0 ) ;
162:    vec3 n_C = sampleNormal ( samp0 , ssC , 0 ) ;
163:    float ssDiskRadius = - projScale * radius / C. z ;
164:    float randomPatternRotationAngle = ( 3 * ssC. x ^ ssC. y + ssC. x * ssC. y ) * 10 ;
165:    float radialJitter = fract ( sin ( gl_FragCoord. x * 1e2 +
166:    gl_FragCoord. y ) * 1e5 + sin ( gl_FragCoord. y * 1e3 ) * 1e3 ) * 0.8 + 0.1 ;
167:    float numSamplesUsed = 0.0 ;
168:    vec3 irradianceSum = vec3 ( 0 ) ;
169:    vec3 ii_peeled = vec3 ( 0 ) ;
170:    float peeledSum = 0.0 ;
171:    for ( int i = 0 ; i < 11 ; ++ i )
172:    {
173:        sampleIndirectLight ( ssC , C , n_C , C_peeled , n_C_peeled , ssDiskRadius , i , randomPatternRotationAngle , radialJitter , samp1 , samp0 , samp2 , irradianceSum , numSamplesUsed , ii_peeled , peeledSum ) ;
174:    }
175:    float solidAngleHemisphere = 2 * 3.14159265358979323846 ;
176:    vec3 E_X = irradianceSum * solidAngleHemisphere / ( numSamplesUsed + 0.00001 ) ;
177:    fo_FragColor . rgb = E_X ;
178:    fo_FragColor . a = 1 - numSamplesUsed / float ( 11 ) ;
179: }
-----------------
0:78(24): error: could not implicitly convert operands to arithmetic operator
0:78(16): error: cannot construct `float' from a non-numeric data type
0:78(58): error: could not implicitly convert operands to arithmetic operator
0:78(16): error: operands to arithmetic operators must be numeric
0:79(26): error: could not implicitly convert operands to arithmetic operator
0:79(16): error: operands to arithmetic operators must be numeric
0:79(16): error: operands to arithmetic operators must be numeric
0:117(4): error: could not implicitly convert operands to relational operator
0:117(4): error: RHS of `&&' must be scalar boolean
0:164(2): error: initializer of type int cannot be assigned to variable of type float
0:173(2): error: no matching function for call to `sampleIndirectLight(ivec2, vec3, vec3, vec3, vec3, float, int, int, float, sampler2D, sampler2D, sampler2D, vec3, float, vec3, float)'; candidates are:
0:173(2): error:    void sampleIndirectLight(ivec2, vec3, vec3, vec3, vec3, float, int, float, float, sampler2D, sampler2D, sampler2D, vec3, float, vec3, float)
0:175(31): error: could not implicitly convert operands to arithmetic operator
0:178(21): error: could not implicitly convert operands to arithmetic operator
ghost commented 8 years ago

@RobertBeckebans It my be that my Geforce 630 is a bit too weak for the SSAO, as I've experienced SSAO performance issues on some games, on others I did not. My monitor only goes up to 1366x768, so I'm not running at HD. Are there more options for the SSAO type in the shader, r_useSSAO 1, 2, 3? Lower, higher quality versions, or sampling levels?

@BielBdeLuna I've had rendering issues in the past with Oibaf Mesa, might need something implemented still.

RobertBeckebans commented 8 years ago

@BielBdeLuna That is one of the reasons I want Vulkan. It is one of OpenGL biggest design flaws that OpenGL drivers are allowed to use their own shit compiler. You don't ship shader code with DX 11 or Vulkan. Drivers should only interpret bytecode in a standard format.

RobertBeckebans commented 8 years ago

@Yetta1 Yeah I will try to render the SSAO shader at the half resolution and use the result for bilateral upsampling.