Forked from transitive-bullshit/billboard_ssao.frag
Last active
August 29, 2015 14:19
-
-
Save sakrist/e84a4e2bfd9948741610 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define SAMPLE_COUNT {{ sampleCount }} | |
#define USE_ACTUAL_NORMALS {{ useActualNormals }} | |
uniform sampler2D sGBuffer; | |
uniform sampler2D sNoise; | |
uniform float uSampleRadius; | |
uniform float uIntensity; | |
uniform vec2 uNoiseScale; | |
uniform vec3 uKernel[SAMPLE_COUNT]; | |
// reconstructs view-space unit normal from view-space position | |
vec3 reconstructNormalVS(vec3 positionVS) { | |
return normalize(cross(dFdx(positionVS), dFdy(positionVS))); | |
} | |
void main() { | |
gBufferGeomComponents gBufferValue = decodeGBufferGeom(sGBuffer, varyingTexCoords, clipFar); | |
vec3 cameraToPositionRay = normalize(varyingCameraFarPlaneWorldSpace - cameraPositionWorldSpace); | |
vec3 origin = cameraToPositionRay * gBufferValue.depth + cameraPositionWorldSpace; | |
#if USE_ACTUAL_NORMALS | |
vec3 normal = gBufferValue.normal; | |
#else | |
vec3 originVS = (viewMatrix * vec4(origin, 1.0)).xyz; | |
vec3 normal = reconstructNormalVS(originVS); | |
#endif | |
normal = normalize(normal * normalMatrix); | |
vec3 rvec = texture2D(sNoise, varyingTexCoords * uNoiseScale).xyz * 2.0 - 1.0; | |
vec3 tangent = normalize(rvec - normal * dot(rvec, normal)); | |
vec3 bitangent = cross(normal, tangent); | |
mat3 tbn = mat3(tangent, bitangent, normal); | |
float occlusion = 0.0; | |
for (int i = 0; i < SAMPLE_COUNT; ++i) { | |
vec3 sample = origin + (tbn * uKernel[i]) * uSampleRadius; | |
vec4 offset = viewProjectionMatrix * vec4(sample, 1.0); | |
offset.xy = (offset.xy / offset.w) * 0.5 + 0.5; | |
float depth = length(sample - cameraPositionWorldSpace); | |
float sampleDepth = decodeGBufferDepth(sGBuffer, offset.xy, clipFar); | |
float rangeDelta = abs(gBufferValue.depth - sampleDepth); | |
float rangeCheck = smoothstep(0.0, 1.0, uSampleRadius / rangeDelta); | |
occlusion += rangeCheck * step(sampleDepth, depth); | |
} | |
occlusion = 1.0 - occlusion / float(SAMPLE_COUNT); | |
occlusion = clamp(pow(occlusion, uIntensity), 0.0, 1.0); | |
gl_FragColor = vec4(occlusion, occlusion, occlusion, 1.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment