| canvas: document.getElementById('mcanvas') as HTMLCanvasElement, | canvas: document.getElementById('mcanvas') as HTMLCanvasElement, | ||||
| msaa: true, | msaa: true, | ||||
| plugins: [ProgressivePlugin], | plugins: [ProgressivePlugin], | ||||
| tonemap: false, | |||||
| }) | }) | ||||
| async function init() { | async function init() { | ||||
| // to render ssao buffer to screen, uncomment this line: | // to render ssao buffer to screen, uncomment this line: | ||||
| // viewer.renderManager.screenPass.overrideReadBuffer = ssaoTarget | // 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) | const targetPreview = await viewer.addPlugin(RenderTargetPreviewPlugin) | ||||
| targetPreview.addTarget(()=>ssaoTarget, 'ssao', false, true, true, (s)=>`${s} = vec4(${s}.r);`) | targetPreview.addTarget(()=>ssaoTarget, 'ssao', false, true, true, (s)=>`${s} = vec4(${s}.r);`) |
| constructor(public readonly passId: IPassID, public target?: ValOrFunc<WebGLRenderTarget|undefined>) { | constructor(public readonly passId: IPassID, public target?: ValOrFunc<WebGLRenderTarget|undefined>) { | ||||
| super({ | super({ | ||||
| defines: { | 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: { | uniforms: { | ||||
| tLastThis: {value: null}, | tLastThis: {value: null}, | ||||
| }, | }, | ||||
| shaderExtender: (shader, _material, _renderer) => { | shaderExtender: (shader, _material, _renderer) => { | ||||
| if (!shader.defines.SSAO_ENABLED) return | 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) | shader.fragmentShader = shaderReplaceString(shader.fragmentShader, '#include <aomap_fragment>', ssaoPatch) | ||||
| }, | }, | ||||
| onObjectRender: (_object, material, renderer: any) => { | onObjectRender: (_object, material, renderer: any) => { |
| float aoValue = sum * saoData.y * INV_NUM_SAMPLES; | 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.); | 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? | // so that depth can also be sampled with ssao if required? | ||||
| gl_FragColor.gba = packFloatToRGB(centerDepth); | 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 ); | // 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.r = aoValue; | ||||
| // gl_FragColor = vec4(centerDepth); | // gl_FragColor = vec4(centerDepth); | ||||
| } | } |
| #if defined(SSAO_ENABLED) && SSAO_ENABLED > 0 | #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 | // 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 | float ambientOcclusion = tSSAOMapTexelToLinear ( texture2D( tSSAOMap, viewToScreen(vViewPosition.xyz).xy )).r; //todo: check encoding for tSSAOMap | ||||