From 0de30b0387f54b5db7c4c0b6ebd1ba2c7502d62b Mon Sep 17 00:00:00 2001 From: harry7557558 Date: Fri, 12 Apr 2024 22:00:15 -0400 Subject: [PATCH] multistep <1spp expand --- implicit3-rt/frag-render.glsl | 2 +- implicit3-rt/script.js | 1 + scripts/render-rt.js | 48 +++++++++++++++++++++++++++++++---- shaders/frag-rt-expand.glsl | 29 +++++++++++++++++++++ shaders/frag-rt-post.glsl | 6 ++++- shaders/frag-tonemap.glsl | 15 +---------- 6 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 shaders/frag-rt-expand.glsl diff --git a/implicit3-rt/frag-render.glsl b/implicit3-rt/frag-render.glsl index c4b42ed..a2ccff7 100644 --- a/implicit3-rt/frag-render.glsl +++ b/implicit3-rt/frag-render.glsl @@ -1310,7 +1310,7 @@ void main(void) { float u = dot(col, ru), v = dot(col, rv), w = dot(col, rd); totcol = vec4(u, v, w, u*u+v*v); } - else totcol += vec4(col, 1) / sSamples; + else totcol += vec4(col, 1); } } fragColor = totcol; diff --git a/implicit3-rt/script.js b/implicit3-rt/script.js index 48a6dd6..ee4a9f3 100644 --- a/implicit3-rt/script.js +++ b/implicit3-rt/script.js @@ -356,6 +356,7 @@ vec3 {%funname%}Color(float x, float y, float z) {\n\ "sky_model.glsl", "../shaders/frag-copy.glsl", "../shaders/frag-rt-post.glsl", + "../shaders/frag-rt-expand.glsl", "../shaders/frag-tonemap.glsl", "../shaders/dnn-conv2d-3.glsl", "../shaders/dnn-conv2d110.glsl", diff --git a/scripts/render-rt.js b/scripts/render-rt.js index a8090b3..2c4c2f2 100644 --- a/scripts/render-rt.js +++ b/scripts/render-rt.js @@ -5,14 +5,17 @@ var renderer = { gl: null, renderSource: "", copySource: "", + expandSource: "", postSource: "", tonemapSource: "", positionBuffer: null, renderProgram: null, copyProgram: null, + expandProgram: null, postProgram: null, renderTarget: null, renderTargetAccum: null, + expandTarget: null, denoiseTarget: null, tonemapProgram: null, tonemapTarget: null, @@ -153,11 +156,16 @@ async function drawScene(state, transformMatrix, lightDir) { } } + let outputFramebuffer = renderer.denoiser ? + renderer.denoiseTarget.framebuffer : + renderer.tonemapTarget.framebuffer; + let fractionalSpp = state.iSpp < (renderer.denoiser ? 2 : 2); + // post processing gl.useProgram(renderer.postProgram); - gl.bindFramebuffer(gl.FRAMEBUFFER, renderer.denoiser ? - renderer.denoiseTarget.framebuffer : - renderer.tonemapTarget.framebuffer); + gl.bindFramebuffer(gl.FRAMEBUFFER, fractionalSpp ? + renderer.expandTarget.framebuffer : outputFramebuffer + ); setPositionBuffer(gl, renderer.postProgram); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, renderer.renderTargetAccum.texture); @@ -171,6 +179,30 @@ async function drawScene(state, transformMatrix, lightDir) { state.iSpp+state.sSamples); renderPass(); + // expand for <1spp + if (fractionalSpp) { + gl.useProgram(renderer.expandProgram); + gl.bindFramebuffer(gl.FRAMEBUFFER, outputFramebuffer); + setPositionBuffer(gl, renderer.expandProgram); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, renderer.expandTarget.texture); + gl.uniform1i(gl.getUniformLocation(renderer.expandProgram, "iChannel0"), 0); + renderPass(); + } + var niter = state.iSpp<1.0/64.0 ? 3 : + state.iSpp<1.0/16.0 ? 2 : + state.iSpp<1.0/4.0 ? 1 : 0; + for (var i = 0; i < niter; i++) { + gl.bindTexture(gl.TEXTURE_2D, renderer.expandTarget.sampler); + gl.copyTexImage2D(gl.TEXTURE_2D, + 0, gl.RGBA32F, 0, 0, state.width, state.height, 0); + setPositionBuffer(gl, renderer.expandProgram); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, renderer.expandTarget.sampler); + gl.uniform1i(gl.getUniformLocation(renderer.expandProgram, "iChannel0"), 0); + renderPass(); + } + // denoising if (renderer.denoiser) { gl.bindTexture(gl.TEXTURE_2D, renderer.denoiseTarget.sampler); @@ -308,6 +340,7 @@ function initWebGL() { "void main(){vXy=vertexPosition.xy;gl_Position=vertexPosition;}"; renderer.renderSource = getShaderSource("frag-render.glsl"); renderer.copySource = getShaderSource("../shaders/frag-copy.glsl"); + renderer.expandSource = getShaderSource("../shaders/frag-rt-expand.glsl"); renderer.postSource = getShaderSource("../shaders/frag-rt-post.glsl"); renderer.tonemapSource = getShaderSource("../shaders/frag-tonemap.glsl"); console.timeEnd("load glsl code"); @@ -369,6 +402,10 @@ function updateBuffers() { renderer.renderTargetNormal = createRenderTarget(gl, state.width, state.height, false, true, true); if (oldRenderTargetNormal) destroyRenderTarget(gl, oldRenderTargetNormal); + var oldExpandTarget = renderer.expandTarget; + renderer.expandTarget = createRenderTarget(gl, state.width, state.height, false, true, true); + if (oldExpandTarget) destroyRenderTarget(gl, oldExpandTarget); + var oldDenoiseTarget = renderer.denoiseTarget; renderer.denoiseTarget = createRenderTarget(gl, state.width, state.height, false, true, true); if (oldDenoiseTarget) destroyRenderTarget(gl, oldDenoiseTarget); @@ -625,9 +662,10 @@ function updateShaderFunction(funCode, funGradCode, params) { prevCode.tonemapSource = tonemapSource; } - if (!renderer.copyProgram) { + if (!renderer.copyProgram) renderer.copyProgram = createShaderProgram(gl, null, renderer.copySource); - } + if (!renderer.expandProgram) + renderer.expandProgram = createShaderProgram(gl, null, renderer.expandSource); if (!renderer.postProgram) renderer.postProgram = createShaderProgram(gl, null, renderer.postSource); diff --git a/shaders/frag-rt-expand.glsl b/shaders/frag-rt-expand.glsl new file mode 100644 index 0000000..f8ccfc7 --- /dev/null +++ b/shaders/frag-rt-expand.glsl @@ -0,0 +1,29 @@ +#version 300 es +precision highp float; + +uniform sampler2D iChannel0; +out vec4 fragColor; + +void main(void) { + + vec4 x = vec4(0); + for (float s = 0.; s < 3.; s++) { + mat2 m = mat2(1); + for (float r = 0.; r < 4.; r++) { + for (float l = 0.; l < 2.*s; l++) { + vec2 p = gl_FragCoord.xy + m * vec2(s, s-l); + x = texelFetch(iChannel0, ivec2(p)-1, 0); + if (x.w > 0.0) break; + } + if (x.w > 0.0) break; + m = mat2(1,1,-1,1) * m; + } + if (x.w > 0.0) break; + } + x /= x.w; + + if (isnan(x.x+x.y+x.z)) + x = vec4(0); + + fragColor = x; +} diff --git a/shaders/frag-rt-post.glsl b/shaders/frag-rt-post.glsl index 087a6d6..16f8a30 100644 --- a/shaders/frag-rt-post.glsl +++ b/shaders/frag-rt-post.glsl @@ -12,8 +12,12 @@ void main(void) { vec4 pixel0 = texelFetch(iChannel0, ivec2(gl_FragCoord.xy), 0); vec4 pixel1 = texelFetch(iChannel1, ivec2(gl_FragCoord.xy), 0); vec4 pixel = pixel0 + pixel1; + if (pixel.w == 0.0) { + fragColor = vec4(0); + return; + } vec3 col = max(pixel.xyz/pixel.w, 0.0); fragColor = denoise ? - vec4(log(pow(col/min(iSpp,1.0), vec3(1.0/2.2))+1.0), 0.0) : + vec4(log(pow(col, vec3(1.0/2.2))+1.0), 1.0) : vec4(col, 1.0) * pixel.w; } diff --git a/shaders/frag-tonemap.glsl b/shaders/frag-tonemap.glsl index 19a1b0d..c0afc63 100644 --- a/shaders/frag-tonemap.glsl +++ b/shaders/frag-tonemap.glsl @@ -31,20 +31,7 @@ vec3 tonemapUncharted2(vec3 x) { void main(void) { - vec4 x = vec4(0); - for (float s = 0.; s < 16.; s++) { - mat2 m = mat2(1); - for (float r = 0.; r < 4.; r++) { - for (float l = 0.; l < 2.*s; l++) { - vec2 p = gl_FragCoord.xy + m * vec2(s, s-l); - x = texelFetch(iChannel0, ivec2(p), 0); - if (x.w > 0.0) break; - } - if (x.w > 0.0) break; - m = mat2(1,1,-1,1) * m; - } - if (x.w > 0.0) break; - } + vec4 x = texelFetch(iChannel0, ivec2(gl_FragCoord.xy), 0); x /= x.w; x.xyz = tonemap{%TONEMAP%}(x.xyz);