From 7dde3fe3414eb604f986ca16435a0547bf571e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=BB=D1=8C=D1=8F=20=D0=91=D0=B5=D0=BB=D0=BE=D0=B2?= Date: Fri, 13 Dec 2024 10:05:53 +0300 Subject: [PATCH] Godrays fixes --- prismarine-viewer/examples/webgpuRenderer.ts | 15 ++ .../webgpuShaders/RadialBlur/frag.wgsl | 132 +----------------- 2 files changed, 21 insertions(+), 126 deletions(-) diff --git a/prismarine-viewer/examples/webgpuRenderer.ts b/prismarine-viewer/examples/webgpuRenderer.ts index c76650260..21014fa25 100644 --- a/prismarine-viewer/examples/webgpuRenderer.ts +++ b/prismarine-viewer/examples/webgpuRenderer.ts @@ -96,6 +96,7 @@ export class WebgpuRenderer { rotationsUniform: GPUBuffer earlyZRejectUniform: GPUBuffer tileSizeUniform: GPUBuffer + clearColorBuffer: GPUBuffer // eslint-disable-next-line max-params @@ -110,6 +111,11 @@ export class WebgpuRenderer { changeBackgroundColor (color: [number, number, number]) { const colorRgba = [color[0], color[1], color[2], 1] this.renderPassDescriptor.colorAttachments[0].clearValue = colorRgba + this.device.queue.writeBuffer( + this.clearColorBuffer, + 0, + new Float32Array(colorRgba) + ) } updateConfig (newParams: RendererParams) { @@ -349,6 +355,11 @@ export class WebgpuRenderer { usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, }) + this.clearColorBuffer = device.createBuffer({ + size: 4 * 4, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }) + this.cameraComputePositionUniform = device.createBuffer({ size: 4 * 4, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, @@ -716,6 +727,10 @@ export class WebgpuRenderer { binding: 2, resource: this.tempTexture.createView(), }, + { + binding: 3, + resource: { buffer: this.clearColorBuffer }, + } ] }) diff --git a/prismarine-viewer/webgpuShaders/RadialBlur/frag.wgsl b/prismarine-viewer/webgpuShaders/RadialBlur/frag.wgsl index afa0139c3..2922939d1 100644 --- a/prismarine-viewer/webgpuShaders/RadialBlur/frag.wgsl +++ b/prismarine-viewer/webgpuShaders/RadialBlur/frag.wgsl @@ -2,13 +2,13 @@ @group(0) @binding(0) var tex: texture_depth_2d; @group(0) @binding(1) var mySampler: sampler; @group(0) @binding(2) var texColor: texture_2d; + @group(0) @binding(3) var clearColor: vec4; const sampleDist : f32 = 1.0; const sampleStrength : f32 = 2.2; const SAMPLES: f32 = 24.; fn hash( p: vec2 ) -> f32 { return fract(sin(dot(p, vec2(41, 289)))*45758.5453); } - fn lOff() -> vec3{ var u = sin(vec2(1.57, 0)); @@ -25,86 +25,6 @@ fn lOff() -> vec3{ return l; } -const SAMPLES1= 16.0; -const INTENSITY = 1.0; -const SCALE = 1; -const BIAS = 0.5; -const SAMPLE_RAD = 0.02; -const MAX_DISTANCE = 0.07; - -const MOD3 = vec3(.1031,.11369,.13787); - -fn hash12(p : vec2) -> f32 -{ - var p3: vec3 = fract(vec3(p.xyx) * MOD3); - p3 += dot(p3, p3.yzx + 19.19); - return fract((p3.x + p3.y) * p3.z); -} - -fn hash22(p : vec2) -> vec2 -{ - var p3: vec3 = fract(vec3(p.xyx) * MOD3); - p3 += dot(p3, p3.yzx+19.19); - return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y)); -} - -fn linearize_depth_ndc(ndc_z: f32, z_near: f32, z_far: f32) -> f32 { - return z_near * z_far / (z_far - ndc_z * (z_far - z_near)); -} - -fn getPosition(uv : vec2) -> vec3 -{ - var fl:f32 = 1.0; - var d:f32 = textureSample(tex, mySampler, uv); - d = linearize_depth_ndc(d, 0.05, 10000); - - var p : vec2 = uv; - var ca :mat3x3 = mat3x3(1.,0.,0.,0.,1.,0.,0.,0.,-1./1.5); - var rd : vec3 = normalize( ca * vec3(p,fl) ); - - var pos : vec3 = rd * d; - return pos; -} - -fn getRandom(uv : vec2) -> vec2 { - return normalize(hash22(uv*126.1231) * 2. - 1.); -} - - -fn doAmbientOcclusion(tcoord:vec2, uv:vec2, p:vec3, cnorm:vec3) -> f32 -{ - var diff:vec3 = getPosition(tcoord + uv) - p; - var l: f32 = length(diff); - var v:vec3 = diff/l; - var d: f32 = l*SCALE; - var ao : f32 = max(0.0,dot(cnorm,v)-BIAS)*(1.0/(1.0+d)); - ao *= smoothstep(MAX_DISTANCE * 0.5, MAX_DISTANCE, l); - return ao; - -} - -fn spiralAO( uv:vec2, p:vec3, n:vec3, rad: f32) -> f32 -{ - var goldenAngle : f32 = 2.4; - var ao : f32 = 0.; - var inv : f32 = 1. / f32(SAMPLES1); - var radius : f32 = 0.; - - var rotatePhase: f32 = hash12( uv*100. ) * 6.28; - var rStep: f32 = inv * rad; - var spiralUV: vec2; - - for (var i = 0.0; i < SAMPLES1; i += 1.0) { - spiralUV.x = sin(rotatePhase); - spiralUV.y = cos(rotatePhase); - radius += rStep; - ao += doAmbientOcclusion(uv, spiralUV * radius, p, n); - rotatePhase += goldenAngle; - } - ao *= inv; - return ao; -} - @fragment fn main( @location(0) uv: vec2f, @@ -118,37 +38,21 @@ fn main( // Sample weight. Decays as we radiate outwards. var weight = 0.04; - // Light offset. Kind of fake. See above. var l = lOff(); - - // Offset texture position (uvs - .5), offset again by the fake light movement. - // It's used to set the blur direction (a direction vector of sorts), and is used - // later to center the spotlight. - // - // The range is centered on zero, which allows the accumulation to spread out in - // all directions. Ie; It's radial. + var tuv = uvs-l.xy*.45; - // Dividing the direction vector above by the sample number and a density factor - // which controls how far the blur spreads out. Higher density means a greater - // blur radius. var dTuv = tuv*density/SAMPLES; - // Grabbing a portion of the initial texture sample. Higher numbers will make the - // scene a little clearer, but I'm going for a bit of abstraction. var temp = textureSample(tex,mySampler, uvs); var col : f32; var outTex = textureSample(texColor, mySampler, uvs); if (temp == 1.0) { col = temp * 0.25; } - // Jittering, to get rid of banding. Vitally important when accumulating discontinuous - // samples, especially when only a few layers are being used. + uvs += dTuv*(hash(uvs.xy - 1.0) * 2. - 1.); - // The radial blur loop. Take a texture sample, move a little in the direction of - // the radial direction vector (dTuv) then take another, slightly less weighted, - // sample, add it to the total, then repeat the process until done. for(var i=0.0; i < SAMPLES; i += 1){ uvs -= dTuv; @@ -160,37 +64,13 @@ fn main( } - uvs = uv; - uvs.y = 1.0 - uvs.y; - - var p = getPosition(uvs); - var n = outTex.xyz; - //var n = vec3(1.0,1.0,1.0); - - var ao = 0.; - var rad = SAMPLE_RAD/p.z; - - ao = spiralAO(uvs, p, n, rad); - ao = 1. - ao * INTENSITY; - - //temp = linearize_depth_ndc(temp, 0.05, 10000)/256; - //return vec4(temp,temp,temp,1.); - //return vec4(ao,ao,ao,1.); + col *= (1. - dot(tuv, tuv)*.75); if (temp == 1.0) { - return outTex; + return clearColor * sqrt(smoothstep(0.0, 1.0, col)); } - //return vec4(ao,ao,ao,1.); - outTex *= vec4(ao,ao,ao,1.0); - - // Multiplying the final color with a spotlight centered on the focal point of the radial - // blur. It's a nice finishing touch... that Passion came up with. If it's a good idea, - // it didn't come from me. :) - col *= (1. - dot(tuv, tuv)*.75); - // Smoothstepping the final color, just to bring it out a bit, then applying some - // loose gamma correction. - return outTex + sqrt(smoothstep(0.0, 1.0, col)); + return outTex + clearColor * sqrt(smoothstep(0.0, 1.0, col)); }