| @@ -12,6 +12,7 @@ const viewer = new ThreeViewer({ | |||
| canvas: document.getElementById('mcanvas') as HTMLCanvasElement, | |||
| msaa: true, | |||
| plugins: [ProgressivePlugin], | |||
| tonemap: false, | |||
| }) | |||
| async function init() { | |||
| @@ -31,6 +32,9 @@ async function init() { | |||
| // to render ssao buffer to screen, uncomment this line: | |||
| // viewer.renderManager.screenPass.overrideReadBuffer = ssaoTarget | |||
| // or set a custom pipeline | |||
| // viewer.renderManager.autoBuildPipeline = false | |||
| // viewer.renderManager.pipeline = ['gbuffer', 'ssao', 'screen'] | |||
| const targetPreview = await viewer.addPlugin(RenderTargetPreviewPlugin) | |||
| targetPreview.addTarget(()=>ssaoTarget, 'ssao', false, true, true, (s)=>`${s} = vec4(${s}.r);`) | |||
| @@ -181,10 +181,11 @@ export class SSAOPluginPass extends ExtendedShaderPass implements IPipelinePass | |||
| constructor(public readonly passId: IPassID, public target?: ValOrFunc<WebGLRenderTarget|undefined>) { | |||
| super({ | |||
| defines: { | |||
| LINEAR_DEPTH: 1, // todo set from unpack extension | |||
| NUM_SAMPLES: 11, | |||
| NUM_SPIRAL_TURNS: 3, | |||
| PERSPECTIVE_CAMERA: 1, // set in PerspectiveCamera2 | |||
| ['LINEAR_DEPTH']: 1, // todo set from unpack extension | |||
| ['NUM_SAMPLES']: 11, | |||
| ['NUM_SPIRAL_TURNS']: 3, | |||
| ['SSAO_PACKING']: 1, // 1 is (r: ssao, gba: depth), 2 is (rgb: ssao, a: 1), 3 is (rgba: packed_ssao), 4 is (rgb: packed_ssao, a: 1) | |||
| ['PERSPECTIVE_CAMERA']: 1, // set in PerspectiveCamera2 | |||
| }, | |||
| uniforms: { | |||
| tLastThis: {value: null}, | |||
| @@ -258,6 +259,7 @@ export class SSAOPluginPass extends ExtendedShaderPass implements IPipelinePass | |||
| }, | |||
| shaderExtender: (shader, _material, _renderer) => { | |||
| if (!shader.defines.SSAO_ENABLED) return | |||
| // todo: only SSAO_PACKING = 1 and 2 is supported. Not 3 and 4 right now. | |||
| shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <aomap_fragment>', ssaoPatch) | |||
| }, | |||
| onObjectRender: (_object, material, renderer: any) => { | |||
| @@ -149,18 +149,28 @@ void main() { | |||
| float aoValue = sum * saoData.y * INV_NUM_SAMPLES; | |||
| // bool disableAO = getSelectionBit(getGBufferFlags(vUv).a) > 0 ? true : false; | |||
| // bool disableAO = getSelectionBit(getGBufferFlags(vUv).a) > 0 ? true : false; | |||
| aoValue = 1. - clamp(aoValue, 0., 1.); | |||
| // todo why so many packing options? | |||
| #if SSAO_PACKING == 1 // (r: ssao, gba: depth) | |||
| // so that depth can also be sampled with ssao if required? | |||
| gl_FragColor.gba = packFloatToRGB(centerDepth); | |||
| gl_FragColor.r = aoValue;// + (lastAO.r) * frameCount)/(frameCount+1.); | |||
| #elif SSAO_PACKING == 2 // (rgb: ssao, a: 1) | |||
| gl_FragColor.rgb = vec3(aoValue); | |||
| gl_FragColor.a = 1.; | |||
| #elif SSAO_PACKING == 3 // (rgba: packed_ssao) | |||
| gl_FragColor.rgba = packDepthToRGBA(aoValue); // from packing | |||
| #elif SSAO_PACKING == 4 // (rgb: packed_ssao, a: 1) | |||
| gl_FragColor.rgb = packFloatToRGB(aoValue); | |||
| gl_FragColor.a = 1.; | |||
| #endif | |||
| // vec4 lastAO = texture2D( tLastThis, vUv ); | |||
| // gl_FragColor.r = (vec4(aoValue)).r;// + (lastAO.r) * frameCount)/(frameCount+1.); | |||
| gl_FragColor.r = aoValue;// + (lastAO.r) * frameCount)/(frameCount+1.); | |||
| // gl_FragColor.r = (vec4(aoValue)).r;// + (lastAO.r) * frameCount)/(frameCount+1.); | |||
| // gl_FragColor.r = aoValue + (lastAO.r) * frameCount)/(frameCount+1.); | |||
| // gl_FragColor.r = aoValue; | |||
| // gl_FragColor = vec4(centerDepth); | |||
| } | |||
| @@ -3,6 +3,8 @@ | |||
| #if defined(SSAO_ENABLED) && SSAO_ENABLED > 0 | |||
| // note: depth can also be sampled and used when SSAO_PACKING = 1. | |||
| // reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture | |||
| float ambientOcclusion = tSSAOMapTexelToLinear ( texture2D( tSSAOMap, viewToScreen(vViewPosition.xyz).xy )).r; //todo: check encoding for tSSAOMap | |||