Unified · Split
| @@ -52,7 +52,7 @@ var overlaysCounter = new CounterWidget(panel, "Overlays", Render.overlay3D); · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | var resizing = false; |
| 54 | 54 | var previousMode = Settings.getValue(SETTINGS_KEY, -1); |
| 55 | −previousMode = 1; | |
| 55 | +previousMode = 4; // FIXME: just for debug purpose | |
| 56 | 56 | Menu.addActionGroup(MENU, ACTIONS, ACTIONS[previousMode + 1]); |
| 57 | 57 | Render.deferredDebugMode = previousMode; |
| 58 | 58 | Render.deferredDebugSize = { x: 0.0, y: -1.0, z: 1.0, w: 1.0 }; // Reset to default size |
| @@ -80,7 +80,8 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getOcclusionPipeline() { · 79 unmodified lines | ||
| 80 | 80 | slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionParamsBuffer"), AmbientOcclusionEffect_ParamsSlot)); |
| 81 | 81 | slotBindings.insert(gpu::Shader::Binding(std::string("deferredTransformBuffer"), AmbientOcclusionEffect_DeferredTransformSlot)); |
| 82 | 82 | slotBindings.insert(gpu::Shader::Binding(std::string("pyramidMap"), AmbientOcclusionEffect_PyramidMapSlot)); |
| 83 | − | |
| 83 | + | |
| 84 | + slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), AmbientOcclusionEffect_PyramidMapSlot + 1)); | |
| 84 | 85 | gpu::Shader::makeProgram(*program, slotBindings); |
| 85 | 86 | |
| 86 | 87 | |
| @@ -90,7 +91,8 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getOcclusionPipeline() { · 3 unmodified lines | ||
| 90 | 91 | state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); |
| 91 | 92 | |
| 92 | 93 | state->setColorWriteMask(true, true, true, false); |
| 93 | − | |
| 94 | + //state->setColorWriteMask(true, true, true, true); | |
| 95 | + | |
| 94 | 96 | // Good to go add the brand new pipeline |
| 95 | 97 | _occlusionPipeline = gpu::Pipeline::create(program, state); |
| 96 | 98 | } |
| @@ -147,83 +149,6 @@ const gpu::PipelinePointer& AmbientOcclusionEffect::getVBlurPipeline() { · 50 unmodified lines | ||
| 147 | 149 | |
| 148 | 150 | // Good to go add the brand new pipeline |
| 149 | 151 | _vBlurPipeline = gpu::Pipeline::create(program, state); |
| 150 | − | |
| 151 | − const char blur_frag[] = R"SCRIBE(#version 410 core | |
| 152 | − // | |
| 153 | − // Created by Sam Gateau on 12/31/2015 | |
| 154 | − // Copyright 2015 High Fidelity, Inc. | |
| 155 | − // | |
| 156 | − // Distributed under the Apache License, Version 2.0. | |
| 157 | − // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | |
| 158 | − // | |
| 159 | − | |
| 160 | − struct AmbientOcclusionParams { | |
| 161 | − vec4 _clipInfo; | |
| 162 | − mat4 _projection; | |
| 163 | − vec4 _radius_s0_s1_s2; | |
| 164 | − }; | |
| 165 | − | |
| 166 | − uniform ambientOcclusionParamsBuffer { | |
| 167 | − AmbientOcclusionParams params; | |
| 168 | − }; | |
| 169 | − | |
| 170 | − float evalZeyeFromZdb(float depth) { | |
| 171 | − return params._clipInfo.x / (depth * params._clipInfo.y + params._clipInfo.z); | |
| 172 | − } | |
| 173 | − | |
| 174 | − // the depth texture | |
| 175 | − uniform sampler2D depthMap; | |
| 176 | − | |
| 177 | − in vec2 varTexCoord0; | |
| 178 | − out vec4 outFragColor; | |
| 179 | − | |
| 180 | − ivec2 ssC = ivec2(gl_FragCoord.xy); | |
| 181 | − | |
| 182 | − vec4 temp = texelFetch(source, ssC, 0); | |
| 183 | − | |
| 184 | − keyPassThrough = temp.KEY_COMPONENTS; | |
| 185 | − float key = unpackKey(keyPassThrough); | |
| 186 | − | |
| 187 | − VALUE_TYPE sum = temp.VALUE_COMPONENTS; | |
| 188 | − | |
| 189 | − if (key == 1.0) { | |
| 190 | − // Sky pixel (if you aren't using depth keying, disable this test) | |
| 191 | − result = sum; | |
| 192 | − return; | |
| 193 | − } | |
| 194 | − | |
| 195 | − // Base weight for depth falloff. Increase this for more blurriness, | |
| 196 | − // decrease it for better edge discrimination | |
| 197 | − float BASE = gaussian[0]; | |
| 198 | − float totalWeight = BASE; | |
| 199 | − sum *= totalWeight; | |
| 200 | − | |
| 201 | − | |
| 202 | − for (int r = -R; r <= R; ++r) { | |
| 203 | − // We already handled the zero case above. This loop should be unrolled and the static branch optimized out, | |
| 204 | − // so the IF statement has no runtime cost | |
| 205 | − if (r != 0) { | |
| 206 | − temp = texelFetch(source, ssC + axis * (r * SCALE), 0); | |
| 207 | − float tapKey = unpackKey(temp.KEY_COMPONENTS); | |
| 208 | − VALUE_TYPE value = temp.VALUE_COMPONENTS; | |
| 209 | − | |
| 210 | − // spatial domain: offset gaussian tap | |
| 211 | − float weight = 0.3 + gaussian[abs(r)]; | |
| 212 | − | |
| 213 | − // range domain (the "bilateral" weight). As depth difference increases, decrease weight. | |
| 214 | − weight *= max(0.0, 1.0 | |
| 215 | − - (EDGE_SHARPNESS * 2000.0) * abs(tapKey - key) | |
| 216 | − ); | |
| 217 | − | |
| 218 | − sum += value * weight; | |
| 219 | − totalWeight += weight; | |
| 220 | − } | |
| 221 | − } | |
| 222 | − | |
| 223 | − const float epsilon = 0.0001; | |
| 224 | − result = sum / (totalWeight + epsilon); | |
| 225 | − | |
| 226 | − )SCRIBE"; | |
| 227 | 152 | } |
| 228 | 153 | return _vBlurPipeline; |
| 229 | 154 | } |
| @@ -346,6 +271,7 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext · 116 unmodified lines | ||
| 346 | 271 | RenderArgs* args = renderContext->getArgs(); |
| 347 | 272 | auto framebufferCache = DependencyManager::get<FramebufferCache>(); |
| 348 | 273 | auto depthBuffer = framebufferCache->getPrimaryDepthTexture(); |
| 274 | + auto normalBuffer = framebufferCache->getDeferredNormalTexture(); | |
| 349 | 275 | auto pyramidFBO = framebufferCache->getDepthPyramidFramebuffer(); |
| 350 | 276 | auto occlusionFBO = framebufferCache->getOcclusionFramebuffer(); |
| 351 | 277 | auto occlusionBlurredFBO = framebufferCache->getOcclusionBlurredFramebuffer(); |
| @@ -366,7 +292,7 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext · 14 unmodified lines | ||
| 366 | 292 | |
| 367 | 293 | setClipInfo(args->_viewFrustum->getNearClip(), args->_viewFrustum->getFarClip()); |
| 368 | 294 | _parametersBuffer.edit<Parameters>()._projection = monoProjMat; |
| 369 | − | |
| 295 | + _parametersBuffer.edit<Parameters>()._pixelInfo = args->_viewport; | |
| 370 | 296 | |
| 371 | 297 | auto pyramidPipeline = getPyramidPipeline(); |
| 372 | 298 | auto occlusionPipeline = getOcclusionPipeline(); |
| @@ -404,9 +330,13 @@ void AmbientOcclusionEffect::run(const render::SceneContextPointer& sceneContext · 31 unmodified lines | ||
| 404 | 330 | |
| 405 | 331 | // Occlusion pass |
| 406 | 332 | batch.setPipeline(occlusionPipeline); |
| 333 | + | |
| 334 | + // batch.setFramebuffer(occlusionFinalFBO); | |
| 407 | 335 | batch.setResourceTexture(AmbientOcclusionEffect_PyramidMapSlot, pyramidFBO->getRenderBuffer(0)); |
| 336 | + batch.setResourceTexture(AmbientOcclusionEffect_PyramidMapSlot + 1, normalBuffer); | |
| 408 | 337 | batch.draw(gpu::TRIANGLE_STRIP, 4); |
| 409 | − | |
| 338 | + batch.setResourceTexture(AmbientOcclusionEffect_PyramidMapSlot + 1, gpu::TexturePointer()); | |
| 339 | + | |
| 410 | 340 | // Blur 1 pass |
| 411 | 341 | batch.setFramebuffer(occlusionBlurredFBO); |
| 412 | 342 | batch.setPipeline(firstHBlurPipeline); |
| @@ -34,6 +34,7 @@ private: · 33 unmodified lines | ||
| 34 | 34 | // Class describing the uniform buffer with all the parameters common to the AO shaders |
| 35 | 35 | class Parameters { |
| 36 | 36 | public: |
| 37 | + glm::vec4 _pixelInfo; | |
| 37 | 38 | glm::vec4 _clipInfo; |
| 38 | 39 | glm::mat4 _projection; |
| 39 | 40 | glm::vec4 _radius_radius2_InvRadius6_s2{ 0.5, 0.5 * 0.5, 1.0 / (0.25 * 0.25 * 0.25), 0.0 }; |
| @@ -68,11 +68,14 @@ struct DeferredFragment { · 67 unmodified lines | ||
| 68 | 68 | vec4 position; |
| 69 | 69 | vec3 normal; |
| 70 | 70 | vec3 diffuse; |
| 71 | − float opacity; | |
| 71 | + float obscurance; | |
| 72 | 72 | vec3 specular; |
| 73 | 73 | float gloss; |
| 74 | + int mode; | |
| 74 | 75 | }; |
| 75 | 76 | |
| 77 | +const int LIGHT_MAPPED = 1; | |
| 78 | + | |
| 76 | 79 | DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec2 texcoord) { |
| 77 | 80 | DeferredFragment frag; |
| 78 | 81 | frag.depthVal = texture(depthMap, texcoord).r; |
| @@ -88,11 +91,16 @@ DeferredFragment unpackDeferredFragment(DeferredTransform deferredTransform, vec · 9 unmodified lines | ||
| 88 | 91 | } |
| 89 | 92 | frag.position = evalEyePositionFromZ(deferredTransform, frag.depthVal, texcoord); |
| 90 | 93 | |
| 91 | − // Unpack the normal from the map | |
| 94 | + // Unpack the normal from the map | |
| 92 | 95 | frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0)); |
| 96 | + | |
| 97 | + frag.mode = 0; | |
| 98 | + if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { | |
| 99 | + frag.mode = LIGHT_MAPPED; | |
| 100 | + } | |
| 93 | 101 | |
| 94 | 102 | frag.diffuse = frag.diffuseVal.xyz; |
| 95 | − frag.opacity = frag.normalVal.w; | |
| 103 | + frag.obscurance = frag.diffuseVal.w; | |
| 96 | 104 | frag.specular = frag.specularVal.xyz; |
| 97 | 105 | frag.gloss = frag.specularVal.w; |
| 98 | 106 | |
| @@ -105,7 +105,7 @@ void FramebufferCache::createPrimaryFramebuffer() { · 104 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | |
| 107 | 107 | // For AO: |
| 108 | − _depthPyramidTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::HALF, gpu::RGB), width, height, smoothSampler)); | |
| 108 | + _depthPyramidTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RGB), width, height, smoothSampler)); | |
| 109 | 109 | _depthPyramidFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); |
| 110 | 110 | _depthPyramidFramebuffer->setRenderBuffer(0, _depthPyramidTexture); |
| 111 | 111 | _depthPyramidFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); |
| @@ -27,7 +27,7 @@ void main(void) { · 26 unmodified lines | ||
| 27 | 27 | DeferredTransform deferredTransform = getDeferredTransform(); |
| 28 | 28 | DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); |
| 29 | 29 | |
| 30 | − if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { | |
| 30 | + if (frag.mode == LIGHT_MAPPED) { | |
| 31 | 31 | vec3 color = evalLightmappedColor( |
| 32 | 32 | deferredTransform.viewInverse, |
| 33 | 33 | 1.0, |
| @@ -38,7 +38,7 @@ void main(void) { · 4 unmodified lines | ||
| 38 | 38 | } else { |
| 39 | 39 | vec3 color = evalAmbienSphereGlobalColor( |
| 40 | 40 | deferredTransform.viewInverse, |
| 41 | − 1.0, | |
| 41 | + frag.obscurance, | |
| 42 | 42 | frag.position.xyz, |
| 43 | 43 | frag.normal, |
| 44 | 44 | frag.diffuse, |
| @@ -28,7 +28,7 @@ void main(void) { · 27 unmodified lines | ||
| 28 | 28 | DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); |
| 29 | 29 | |
| 30 | 30 | // Light mapped or not ? |
| 31 | − if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { | |
| 31 | + if (frag.mode == LIGHT_MAPPED) { | |
| 32 | 32 | vec3 color = evalLightmappedColor( |
| 33 | 33 | deferredTransform.viewInverse, |
| 34 | 34 | 1.0, |
| @@ -39,7 +39,7 @@ void main(void) { · 4 unmodified lines | ||
| 39 | 39 | } else { |
| 40 | 40 | vec3 color = evalAmbienGlobalColor( |
| 41 | 41 | deferredTransform.viewInverse, |
| 42 | − 1.0, | |
| 42 | + frag.obscurance, | |
| 43 | 43 | frag.position.xyz, |
| 44 | 44 | frag.normal, |
| 45 | 45 | frag.diffuse, |
| @@ -28,7 +28,7 @@ void main(void) { · 27 unmodified lines | ||
| 28 | 28 | DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0); |
| 29 | 29 | |
| 30 | 30 | // Light mapped or not ? |
| 31 | − if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { | |
| 31 | + if (frag.mode == LIGHT_MAPPED) { | |
| 32 | 32 | vec3 color = evalLightmappedColor( |
| 33 | 33 | deferredTransform.viewInverse, |
| 34 | 34 | 1.0, |
| @@ -39,7 +39,7 @@ void main(void) { · 4 unmodified lines | ||
| 39 | 39 | } else { |
| 40 | 40 | vec3 color = evalSkyboxGlobalColor( |
| 41 | 41 | deferredTransform.viewInverse, |
| 42 | − 1.0, | |
| 42 | + frag.obscurance, | |
| 43 | 43 | frag.position.xyz, |
| 44 | 44 | frag.normal, |
| 45 | 45 | frag.diffuse, |
| @@ -11,9 +11,28 @@ · 10 unmodified lines | ||
| 11 | 11 | <@if not SSAO_SLH@> |
| 12 | 12 | <@def SSAO_SLH@> |
| 13 | 13 | |
| 14 | +<@func declarePackOcclusionDepth()@> | |
| 15 | + | |
| 16 | +const float FAR_PLANE_Z = -300.0; | |
| 17 | + | |
| 18 | +float CSZToDephtKey(float z) { | |
| 19 | + return clamp(z * (1.0 / FAR_PLANE_Z), 0.0, 1.0); | |
| 20 | +} | |
| 21 | +vec3 packOcclusionDepth(float occlusion, float depth) { | |
| 22 | + // Round to the nearest 1/256.0 | |
| 23 | + float temp = floor(depth * 256.0); | |
| 24 | + return vec3(occlusion, temp * (1.0 / 256.0), depth * 256.0 - temp); | |
| 25 | +} | |
| 26 | +vec2 unpackOcclusionDepth(vec3 packed) { | |
| 27 | + float z = packed.y * (256.0 / 257.0) + packed.z * (1.0 / 257.0); | |
| 28 | + return vec2(packed.x, z); | |
| 29 | +} | |
| 30 | +<@endfunc@> | |
| 31 | + | |
| 14 | 32 | <@func declareAmbientOcclusion()@> |
| 15 | 33 | |
| 16 | 34 | struct AmbientOcclusionParams { |
| 35 | + vec4 _pixelInfo; | |
| 17 | 36 | vec4 _clipInfo; |
| 18 | 37 | mat4 _projection; |
| 19 | 38 | vec4 _radius_radius2_InvRadius6_s2; |
| @@ -23,8 +42,11 @@ uniform ambientOcclusionParamsBuffer { · 3 unmodified lines | ||
| 23 | 42 | AmbientOcclusionParams params; |
| 24 | 43 | }; |
| 25 | 44 | |
| 45 | +vec2 getWidthHeight() { | |
| 46 | + return params._pixelInfo.zw; | |
| 47 | +} | |
| 26 | 48 | float getProjScale() { |
| 27 | − return 500.0; // this should be viewportHeight * Proj[1][1] / 2.0 | |
| 49 | + return getWidthHeight().y * params._projection[1][1] * 0.5; | |
| 28 | 50 | } |
| 29 | 51 | |
| 30 | 52 | float getRadius() { |
| @@ -50,8 +72,77 @@ vec3 evalEyePositionFromZeye(float Zeye, vec2 texcoord) { · 19 unmodified lines | ||
| 50 | 72 | } |
| 51 | 73 | |
| 52 | 74 | vec3 evalEyeNormal(vec3 C) { |
| 53 | − return normalize(cross(dFdy(C), dFdx(C))); | |
| 75 | + //return normalize(cross(dFdy(C), dFdx(C))); | |
| 76 | + return normalize(cross(dFdx(C), dFdy(C))); | |
| 54 | 77 | } |
| 78 | + | |
| 79 | +<@endfunc@> | |
| 80 | + | |
| 81 | +<@func declareBlurPass(axis)@> | |
| 82 | + | |
| 83 | +<$declarePackOcclusionDepth()$> | |
| 84 | + | |
| 85 | +// the source occlusion texture | |
| 86 | +uniform sampler2D occlusionMap; | |
| 87 | + | |
| 88 | +vec2 fetchOcclusionDepthRaw(ivec2 coords, out vec3 raw) { | |
| 89 | + raw = texelFetch(occlusionMap, coords, 0).xyz; | |
| 90 | + return unpackOcclusionDepth(raw); | |
| 91 | +} | |
| 92 | + | |
| 93 | +vec2 fetchOcclusionDepth(ivec2 coords) { | |
| 94 | + return unpackOcclusionDepth(texelFetch(occlusionMap, coords, 0).xyz); | |
| 95 | +} | |
| 96 | + | |
| 97 | + | |
| 98 | +const int BLUR_RADIUS = 4; | |
| 99 | +const int RADIUS_SCALE = 2; | |
| 100 | +const float EDGE_SHARPNESS = 1.0; | |
| 101 | + | |
| 102 | +const float gaussian[BLUR_RADIUS + 1] = | |
| 103 | +// float[](0.356642, 0.239400, 0.072410, 0.009869); // R = 2 | |
| 104 | +// float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // R = 3 | |
| 105 | +float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // R = 4 | |
| 106 | +// float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // R = 5.0 | |
| 107 | + | |
| 108 | +vec3 getBlurredOcclusion(vec2 coord) { | |
| 109 | + ivec2 ssC = ivec2(coord); | |
| 110 | + | |
| 111 | + vec3 rawSample; | |
| 112 | + vec2 occlusionDepth = fetchOcclusionDepthRaw(ssC, rawSample); | |
| 113 | + float key = occlusionDepth.y; | |
| 114 | + float sum = occlusionDepth.x; | |
| 115 | + | |
| 116 | + // Base weight for depth falloff. Increase this for more blurriness, | |
| 117 | + // decrease it for better edge discrimination | |
| 118 | + float BASE = gaussian[0]; | |
| 119 | + float totalWeight = BASE; | |
| 120 | + sum *= totalWeight; | |
| 121 | + | |
| 122 | + for (int r = -BLUR_RADIUS; r <= BLUR_RADIUS; ++r) { | |
| 123 | + // We already handled the zero case above. This loop should be unrolled and the static branch optimized out, | |
| 124 | + // so the IF statement has no runtime cost | |
| 125 | + if (r != 0) { | |
| 126 | + vec2 tapOZ = fetchOcclusionDepth(ssC + <$axis$> * (r * RADIUS_SCALE)); | |
| 127 | + | |
| 128 | + // spatial domain: offset gaussian tap | |
| 129 | + float weight = 0.3 + gaussian[abs(r)]; | |
| 130 | + | |
| 131 | + // range domain (the "bilateral" weight). As depth difference increases, decrease weight. | |
| 132 | + weight *= max(0.0, 1.0 - (EDGE_SHARPNESS * 2000.0) * abs(tapOZ.y - key)); | |
| 133 | + | |
| 134 | + sum += tapOZ.x * weight; | |
| 135 | + totalWeight += weight; | |
| 136 | + } | |
| 137 | + } | |
| 138 | + | |
| 139 | + const float epsilon = 0.0001; | |
| 140 | + float result = sum / (totalWeight + epsilon); | |
| 141 | + | |
| 142 | + rawSample.x = result; | |
| 143 | + return rawSample; | |
| 144 | +} | |
| 145 | + | |
| 55 | 146 | <@endfunc@> |
| 56 | 147 | |
| 57 | 148 | |
| @@ -10,14 +10,14 @@ · 9 unmodified lines | ||
| 10 | 10 | // |
| 11 | 11 | |
| 12 | 12 | <@include ssao.slh@> |
| 13 | −<$declareAmbientOcclusion()$> | |
| 14 | 13 | |
| 15 | −// the depth texture | |
| 16 | −uniform sampler2D occlusionMap; | |
| 14 | +const ivec2 horizontal = ivec2(1,0); | |
| 15 | +<$declareBlurPass(horizontal)$> | |
| 16 | + | |
| 17 | 17 | |
| 18 | 18 | in vec2 varTexCoord0; |
| 19 | 19 | out vec4 outFragColor; |
| 20 | 20 | |
| 21 | 21 | void main(void) { |
| 22 | − outFragColor = texture(occlusionMap, varTexCoord0); | |
| 22 | + outFragColor = vec4(getBlurredOcclusion(gl_FragCoord.xy), 1.0); | |
| 23 | 23 | } |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | <@include ssao.slh@> |
| 13 | 13 | <$declareAmbientOcclusion()$> |
| 14 | +<$declarePackOcclusionDepth()$> | |
| 14 | 15 | |
| 15 | 16 | const int NUM_SAMPLES = 11; |
| 16 | 17 | const float INV_NUM_SAMPLES = 1.0 / float(NUM_SAMPLES); |
| @@ -21,34 +22,15 @@ const int MAX_MIP_LEVEL = 5; · 4 unmodified lines | ||
| 21 | 22 | // the depth pyramid texture |
| 22 | 23 | uniform sampler2D pyramidMap; |
| 23 | 24 | |
| 24 | −float getZeye(vec2 texcoord) { | |
| 25 | − return -texture(pyramidMap, texcoord, 0).x; | |
| 26 | −} | |
| 27 | − | |
| 28 | 25 | vec3 evalEyePosition(vec2 texcoord) { |
| 29 | − float Zeye = getZeye(texcoord); | |
| 26 | + float Zeye = -texture(pyramidMap, texcoord, 0).x; | |
| 30 | 27 | return evalEyePositionFromZeye(Zeye, texcoord); |
| 31 | 28 | } |
| 32 | 29 | |
| 33 | 30 | in vec2 varTexCoord0; |
| 34 | 31 | out vec4 outFragColor; |
| 35 | 32 | |
| 36 | −/** Used for packing Z into the GB channels */ | |
| 37 | −float CSZToKey(float z) { | |
| 38 | − return clamp(z * (1.0 / params._clipInfo.z), 0.0, 1.0); | |
| 39 | −} | |
| 40 | − | |
| 41 | −/** Used for packing Z into the GB channels */ | |
| 42 | −void packKey(float key, out vec2 p) { | |
| 43 | − // Round to the nearest 1/256.0 | |
| 44 | − float temp = floor(key * 256.0); | |
| 45 | − | |
| 46 | − // Integer part | |
| 47 | − p.x = temp * (1.0 / 256.0); | |
| 48 | − | |
| 49 | − // Fractional part | |
| 50 | − p.y = key * 256.0 - temp; | |
| 51 | −} | |
| 33 | +uniform sampler2D normalMap; | |
| 52 | 34 | |
| 53 | 35 | vec2 tapLocation(int sampleNumber, float spinAngle, out float ssR){ |
| 54 | 36 | // Radius relative to ssR |
| @@ -76,7 +58,7 @@ vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) { · 21 unmodified lines | ||
| 76 | 58 | // Offset to pixel center |
| 77 | 59 | //P = reconstructCSPosition(vec2(ssP) + vec2(0.5), P.z); |
| 78 | 60 | |
| 79 | − vec2 tapUV = (vec2(ssP) + vec2(0.5)) / textureSize(pyramidMap, 0); | |
| 61 | + vec2 tapUV = (vec2(ssP) + vec2(0.5)) / getWidthHeight(); | |
| 80 | 62 | P = evalEyePositionFromZeye(P.z, tapUV); |
| 81 | 63 | return P; |
| 82 | 64 | } |
| @@ -128,14 +110,11 @@ void main(void) { · 45 unmodified lines | ||
| 128 | 110 | |
| 129 | 111 | vec3 Cp = evalEyePosition(varTexCoord0); |
| 130 | 112 | |
| 131 | − // packKey(CSZToKey(Cp.z), bilateralKey); | |
| 132 | − | |
| 133 | 113 | // Hash function used in the HPG12 AlchemyAO paper |
| 134 | 114 | float randomPatternRotationAngle = (3 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 10; |
| 135 | − //float randomPatternRotationAngle = 0; | |
| 136 | − | |
| 137 | 115 | |
| 138 | 116 | vec3 Cn = evalEyeNormal(Cp); |
| 117 | + // vec3 Cn = normalize((texelFetch(normalMap, ssC, 0).xyz * 2.0) - vec3(1.0)); | |
| 139 | 118 | |
| 140 | 119 | // Choose the screen-space sample radius |
| 141 | 120 | // proportional to the projected area of the sphere |
| @@ -143,20 +122,20 @@ void main(void) { · 1 unmodified line | ||
| 143 | 122 | |
| 144 | 123 | float sum = 0.0; |
| 145 | 124 | for (int i = 0; i < NUM_SAMPLES; ++i) { |
| 146 | − sum += sampleAO(ssC, Cp, Cn, ssDiskRadius, i, randomPatternRotationAngle); | |
| 125 | + sum += sampleAO(ssC, Cp, Cn, ssDiskRadius, i, randomPatternRotationAngle); | |
| 147 | 126 | } |
| 148 | 127 | |
| 149 | 128 | float A = max(0.0, 1.0 - sum * getInvRadius6() * 5.0 * INV_NUM_SAMPLES); |
| 150 | 129 | |
| 151 | 130 | // Bilateral box-filter over a quad for free, respecting depth edges |
| 152 | 131 | // (the difference that this makes is subtle) |
| 153 | − if (abs(dFdx(Cp.z)) < 0.02) { | |
| 132 | + /*if (abs(dFdx(Cp.z)) < 0.02) { | |
| 154 | 133 | A -= dFdx(A) * ((ssC.x & 1) - 0.5); |
| 155 | 134 | } |
| 156 | 135 | if (abs(dFdy(Cp.z)) < 0.02) { |
| 157 | 136 | A -= dFdy(A) * ((ssC.y & 1) - 0.5); |
| 158 | − } | |
| 159 | − | |
| 137 | + }*/ | |
| 160 | 138 | |
| 161 | − outFragColor = vec4(A, debugValue(Cn.y, 10)); | |
| 139 | + outFragColor = vec4(packOcclusionDepth(A, CSZToDephtKey(Cp.z)), 1.0); | |
| 140 | + //outFragColor = vec4(0.5 * (Cn + vec3(1.0)), A); | |
| 162 | 141 | } |
| @@ -8,16 +8,15 @@ · 7 unmodified lines | ||
| 8 | 8 | // Distributed under the Apache License, Version 2.0. |
| 9 | 9 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html |
| 10 | 10 | // |
| 11 | − | |
| 12 | 11 | <@include ssao.slh@> |
| 13 | −<$declareAmbientOcclusion()$> | |
| 14 | 12 | |
| 15 | −// the depth texture | |
| 16 | −uniform sampler2D occlusionMap; | |
| 13 | +const ivec2 vertical = ivec2(0,1); | |
| 14 | +<$declareBlurPass(vertical)$> | |
| 17 | 15 | |
| 18 | 16 | in vec2 varTexCoord0; |
| 19 | 17 | out vec4 outFragColor; |
| 20 | 18 | |
| 21 | 19 | void main(void) { |
| 22 | − outFragColor = vec4(0.0, 0.0, 0.0, texture(occlusionMap, varTexCoord0).x); | |
| 20 | + float occlusion = getBlurredOcclusion(gl_FragCoord.xy).x; | |
| 21 | + outFragColor = vec4(0.0, 0.0, 0.0, occlusion); | |
| 23 | 22 | } |