Created
July 12, 2026 00:38
-
-
Save N8python/1ec6be983c92f8f52b33c0db3635a319 to your computer and use it in GitHub Desktop.
Full model used by N8AO's new neural denoiser.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // N8AO 2.0.0 generated neural Poisson-blur fragment shader | |
| // Variant: Neural-High, 16 denoise taps, perspective camera, standard depth | |
| // Network: 552 inline int8 coefficients, 517 nonzero terms after zero pruning | |
| // This is the exact ShaderMaterial fragment source; Three.js prepends its GLSL3 program prefix. | |
| #define NEURAL_DENOISE | |
| layout(location = 0) out highp vec4 neuralFragColor; | |
| #define gl_FragColor neuralFragColor | |
| uniform sampler2D sceneDiffuse; | |
| uniform highp sampler2D sceneDepth; | |
| uniform sampler2D tDiffuse; | |
| uniform sampler2D blueNoise; | |
| uniform mat4 projectionMatrixInv; | |
| uniform mat4 viewMatrixInv; | |
| uniform vec2 resolution; | |
| uniform float r; | |
| uniform float radius; | |
| uniform float worldRadius; | |
| uniform float index; | |
| uniform float near; | |
| uniform float far; | |
| uniform float distanceFalloff; | |
| uniform bool screenSpaceRadius; | |
| varying vec2 vUv; | |
| highp float linearize_depth(highp float d, highp float zNear,highp float zFar) | |
| { | |
| highp float z_n = 2.0 * d - 1.0; | |
| return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); | |
| } | |
| highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) { | |
| float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0; | |
| float a = farZ / (farZ - nearZ); | |
| float b = farZ * nearZ / (nearZ - farZ); | |
| float linDepth = a + b / depth; | |
| return linearize_depth(linDepth, nearZ, farZ); | |
| } | |
| highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) { | |
| return nearZ + (farZ - nearZ) * d; | |
| } | |
| float depthToClipZ(float depth) { | |
| #ifdef REVERSEDEPTH | |
| return depth; | |
| #else | |
| return depth * 2.0 - 1.0; | |
| #endif | |
| } | |
| bool isBackgroundDepth(float depth) { | |
| #ifdef REVERSEDEPTH | |
| return depth == 0.0; | |
| #else | |
| return depth == 1.0; | |
| #endif | |
| } | |
| vec3 getWorldPosLog(vec3 posS) { | |
| vec2 uv = posS.xy; | |
| float z = posS.z; | |
| float nearZ =near; | |
| float farZ = far; | |
| float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0; | |
| float a = farZ / (farZ - nearZ); | |
| float b = farZ * nearZ / (nearZ - farZ); | |
| float linDepth = a + b / depth; | |
| vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0; | |
| vec4 wpos = projectionMatrixInv * clipVec; | |
| return wpos.xyz / wpos.w; | |
| } | |
| vec3 getWorldPos(float depth, vec2 coord) { | |
| #ifdef LOGDEPTH | |
| #ifndef ORTHO | |
| return getWorldPosLog(vec3(coord, depth)); | |
| #endif | |
| #endif | |
| #ifdef ORTHO | |
| float z = depthToClipZ(depth); | |
| vec4 clipSpacePosition = vec4(coord * 2. - 1., z, 1.); | |
| vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition; | |
| viewSpacePosition.xyz /= viewSpacePosition.w; | |
| return viewSpacePosition.xyz; | |
| #else | |
| vec2 ndc = coord * 2. - 1.; | |
| float ndcZ = depthToClipZ(depth); | |
| mat4 Q = projectionMatrixInv; | |
| vec3 view = vec3(Q[0][0] * ndc.x + Q[3][0], Q[1][1] * ndc.y + Q[3][1], Q[3][2]); | |
| float invW = 1.0 / (Q[2][3] * ndcZ + Q[3][3]); | |
| return view * invW; | |
| #endif | |
| } | |
| #ifdef NEURAL_DENOISE | |
| struct NeuralToken { | |
| highp vec4 lo; | |
| highp vec4 hi; | |
| }; | |
| NeuralToken neuralTapInput(NeuralToken raw) { | |
| NeuralToken scaledInput = NeuralToken( | |
| raw.lo * vec4( | |
| 2.283243417739868, | |
| 0.8810898065567017, | |
| 0.8210930228233337, | |
| 3.752316474914551 | |
| ), | |
| raw.hi * vec4( | |
| 3.6375720500946045, | |
| 2.670454978942871, | |
| 10.249449729919434, | |
| 0.12639354169368744 | |
| ) | |
| ); | |
| return NeuralToken( | |
| max(vec4( | |
| 0.1096231754049479 * (scaledInput.lo.y + 7.0 * scaledInput.lo.z + (-scaledInput.hi.x) + (-7.0 * scaledInput.hi.y) + 31.0 * scaledInput.hi.w) + 1.4143863870620592, | |
| 0.1096231754049479 * ((-scaledInput.lo.x) + 14.0 * scaledInput.lo.y + (-126.0 * scaledInput.lo.z) + (-scaledInput.hi.y) + 2.0 * scaledInput.hi.z + 26.0 * scaledInput.hi.w) + -1.3870972504272245, | |
| 0.1096231754049479 * (66.0 * scaledInput.lo.y + (-73.0 * scaledInput.lo.z) + (-12.0 * scaledInput.hi.z) + 22.0 * scaledInput.hi.w) + 12.96982868512481, | |
| 0.1096231754049479 * ((-76.0 * scaledInput.lo.y) + (-90.0 * scaledInput.lo.z) + (-scaledInput.hi.x) + (-7.0 * scaledInput.hi.y) + (-3.0 * scaledInput.hi.z) + 58.0 * scaledInput.hi.w) + 5.017747360526078 | |
| ), vec4(0.0)), | |
| max(vec4( | |
| 0.1096231754049479 * (2.0 * scaledInput.lo.y + 6.0 * scaledInput.lo.z + 3.0 * scaledInput.hi.y + 4.0 * scaledInput.hi.z + (-40.0 * scaledInput.hi.w)) + -4.1297649139710675, | |
| 0.1096231754049479 * (3.0 * scaledInput.lo.y + (-13.0 * scaledInput.lo.z) + scaledInput.hi.y + (-7.0 * scaledInput.hi.z) + (-13.0 * scaledInput.hi.w)) + 7.631823377900882, | |
| 0.1096231754049479 * ((-7.0 * scaledInput.lo.y) + 10.0 * scaledInput.lo.z + (-2.0 * scaledInput.hi.x) + (-7.0 * scaledInput.hi.y) + (-39.0 * scaledInput.hi.w)) + 2.6245270598182344, | |
| 0.1096231754049479 * ((-13.0 * scaledInput.lo.y) + (-19.0 * scaledInput.lo.z) + (-2.0 * scaledInput.hi.x) + 20.0 * scaledInput.hi.y + (-scaledInput.hi.z) + 3.0 * scaledInput.hi.w) + -3.8866388148399498 | |
| ), vec4(0.0)) | |
| ); | |
| } | |
| NeuralToken neuralTapOutput(NeuralToken inputToken) { | |
| return NeuralToken( | |
| max(vec4( | |
| 0.017949438644286102 * (18.0 * inputToken.lo.x + (-4.0 * inputToken.lo.y) + 47.0 * inputToken.lo.z + 19.0 * inputToken.lo.w + 74.0 * inputToken.hi.x + (-94.0 * inputToken.hi.y) + (-21.0 * inputToken.hi.z) + (-9.0 * inputToken.hi.w)) + -0.3867710530757904, | |
| 0.017949438644286102 * (73.0 * inputToken.lo.x + (-59.0 * inputToken.lo.y) + 88.0 * inputToken.lo.z + (-10.0 * inputToken.lo.w) + (-3.0 * inputToken.hi.x) + 71.0 * inputToken.hi.y + (-7.0 * inputToken.hi.z) + 24.0 * inputToken.hi.w) + 0.1349504142999649, | |
| 0.017949438644286102 * (20.0 * inputToken.lo.x + 74.0 * inputToken.lo.y + 24.0 * inputToken.lo.z + (-31.0 * inputToken.lo.w) + (-12.0 * inputToken.hi.x) + (-10.0 * inputToken.hi.y) + (-15.0 * inputToken.hi.z) + (-45.0 * inputToken.hi.w)) + 0.35706064105033875, | |
| 0.017949438644286102 * ((-126.0 * inputToken.lo.x) + 2.0 * inputToken.lo.y + (-4.0 * inputToken.lo.z) + 27.0 * inputToken.lo.w + (-5.0 * inputToken.hi.x) + 24.0 * inputToken.hi.y + 35.0 * inputToken.hi.z + (-11.0 * inputToken.hi.w)) + -0.5938405394554138 | |
| ), vec4(0.0)), | |
| max(vec4( | |
| 0.017949438644286102 * ((-4.0 * inputToken.lo.x) + 9.0 * inputToken.lo.y + (-8.0 * inputToken.lo.z) + 26.0 * inputToken.lo.w + (-10.0 * inputToken.hi.x) + 27.0 * inputToken.hi.y + 26.0 * inputToken.hi.z + (-20.0 * inputToken.hi.w)) + -0.031154220923781395, | |
| 0.017949438644286102 * (17.0 * inputToken.lo.x + (-50.0 * inputToken.lo.y) + 5.0 * inputToken.lo.z + (-35.0 * inputToken.lo.w) + (-5.0 * inputToken.hi.y) + 12.0 * inputToken.hi.z + (-71.0 * inputToken.hi.w)) + 1.4079623222351074, | |
| 0.017949438644286102 * (89.0 * inputToken.lo.x + (-58.0 * inputToken.lo.y) + 22.0 * inputToken.lo.z + (-83.0 * inputToken.lo.w) + (-115.0 * inputToken.hi.x) + 7.0 * inputToken.hi.y + (-16.0 * inputToken.hi.z) + (-89.0 * inputToken.hi.w)) + -1.9221038818359375, | |
| 0.017949438644286102 * (89.0 * inputToken.lo.x + 22.0 * inputToken.lo.y + inputToken.lo.z + (-20.0 * inputToken.lo.w) + (-22.0 * inputToken.hi.x) + (-25.0 * inputToken.hi.y) + (-26.0 * inputToken.hi.z) + 44.0 * inputToken.hi.w) + 0.6029739379882812 | |
| ), vec4(0.0)) | |
| ); | |
| } | |
| NeuralToken neuralEncodeGlobal(vec4 raw) { | |
| vec3 scaledInput = raw.xyz * vec3( | |
| 10.771836280822754, 1.9548665285110474, 1.612365484237671 | |
| ); | |
| return NeuralToken( | |
| max(vec4( | |
| 0.021090541950849095 * (101.0 * scaledInput.x + (-4.0 * scaledInput.y) + 7.0 * scaledInput.z) + -21.524604707001238, | |
| 0.021090541950849095 * ((-127.0 * scaledInput.x) + 6.0 * scaledInput.y + (-11.0 * scaledInput.z)) + 27.111714715139033, | |
| 0.021090541950849095 * (3.0 * scaledInput.x + scaledInput.y) + -0.6588789590469037, | |
| 0.021090541950849095 * ((-16.0 * scaledInput.x) + (-7.0 * scaledInput.y) + 8.0 * scaledInput.z) + 4.497741949827374 | |
| ), vec4(0.0)), | |
| max(vec4( | |
| 0.021090541950849095 * ((-8.0 * scaledInput.x) + (-scaledInput.y) + 7.0 * scaledInput.z) + 1.690871031740089, | |
| 0.021090541950849095 * ((-4.0 * scaledInput.x)) + 1.080641590014308, | |
| 0.021090541950849095 * ((-12.0 * scaledInput.x) + (-3.0 * scaledInput.y) + (-13.0 * scaledInput.z)) + 2.470025460444304, | |
| 0.021090541950849095 * (scaledInput.x + 2.0 * scaledInput.z) + -0.38586191737528186 | |
| ), vec4(0.0)) | |
| ); | |
| } | |
| NeuralToken neuralKeyProject(NeuralToken inputToken) { | |
| return NeuralToken( | |
| vec4( | |
| 0.1733924937791441 * ((-inputToken.lo.y) + (-inputToken.lo.z) + inputToken.lo.w + inputToken.hi.x + inputToken.hi.y + inputToken.hi.z + inputToken.hi.w) + 0.0, | |
| 0.1733924937791441 * ((-64.0 * inputToken.lo.x) + 32.0 * inputToken.lo.y + 49.0 * inputToken.lo.z + 23.0 * inputToken.lo.w + (-25.0 * inputToken.hi.x) + 4.0 * inputToken.hi.y + 27.0 * inputToken.hi.z + (-22.0 * inputToken.hi.w)) + 0.0, | |
| 0.1733924937791441 * (inputToken.lo.y + (-inputToken.lo.z) + (-inputToken.lo.w) + (-inputToken.hi.x) + inputToken.hi.y + inputToken.hi.z) + 0.0, | |
| 0.1733924937791441 * ((-34.0 * inputToken.lo.x) + 38.0 * inputToken.lo.y + 64.0 * inputToken.lo.z + 88.0 * inputToken.lo.w + 13.0 * inputToken.hi.x + (-53.0 * inputToken.hi.y) + (-41.0 * inputToken.hi.z) + 58.0 * inputToken.hi.w) + 0.0 | |
| ), | |
| vec4( | |
| 0.1733924937791441 * ((-7.0 * inputToken.lo.x) + (-4.0 * inputToken.lo.y) + 79.0 * inputToken.lo.z + (-41.0 * inputToken.lo.w) + 27.0 * inputToken.hi.x + 26.0 * inputToken.hi.y + 14.0 * inputToken.hi.z + 2.0 * inputToken.hi.w) + 0.0, | |
| 0.1733924937791441 * ((-2.0 * inputToken.lo.x) + inputToken.lo.y + inputToken.lo.z + inputToken.lo.w + (-inputToken.hi.x) + (-inputToken.hi.y) + inputToken.hi.z + inputToken.hi.w) + 0.0, | |
| 0.1733924937791441 * (inputToken.lo.x + (-inputToken.lo.y) + (-inputToken.lo.z) + (-inputToken.lo.w) + (-inputToken.hi.x) + (-inputToken.hi.y) + inputToken.hi.z + inputToken.hi.w) + 0.0, | |
| 0.1733924937791441 * (4.0 * inputToken.lo.x + (-3.0 * inputToken.lo.y) + 126.0 * inputToken.lo.z + 42.0 * inputToken.lo.w + (-40.0 * inputToken.hi.x) + (-116.0 * inputToken.hi.y) + 35.0 * inputToken.hi.z + 20.0 * inputToken.hi.w) + 0.0 | |
| ) | |
| ); | |
| } | |
| NeuralToken neuralValueProject(NeuralToken inputToken) { | |
| return NeuralToken( | |
| vec4( | |
| 0.013986751242596301 * ((-16.0 * inputToken.lo.x) + (-6.0 * inputToken.lo.y) + 40.0 * inputToken.lo.z + (-17.0 * inputToken.lo.w) + 84.0 * inputToken.hi.x + (-76.0 * inputToken.hi.y) + 59.0 * inputToken.hi.z + 51.0 * inputToken.hi.w) + 0.0, | |
| 0.013986751242596301 * ((-10.0 * inputToken.lo.x) + (-2.0 * inputToken.lo.y) + (-10.0 * inputToken.lo.z) + (-inputToken.lo.w) + (-23.0 * inputToken.hi.x) + 74.0 * inputToken.hi.y + (-70.0 * inputToken.hi.z) + 23.0 * inputToken.hi.w) + 0.0, | |
| 0.013986751242596301 * ((-5.0 * inputToken.lo.x) + 4.0 * inputToken.lo.y + 4.0 * inputToken.lo.z + (-7.0 * inputToken.lo.w) + (-77.0 * inputToken.hi.x) + 127.0 * inputToken.hi.y + 20.0 * inputToken.hi.z + (-48.0 * inputToken.hi.w)) + 0.0, | |
| 0.013986751242596301 * ((-36.0 * inputToken.lo.x) + 4.0 * inputToken.lo.y + (-17.0 * inputToken.lo.z) + (-12.0 * inputToken.lo.w) + (-4.0 * inputToken.hi.x) + 10.0 * inputToken.hi.y + 29.0 * inputToken.hi.z + (-27.0 * inputToken.hi.w)) + 0.0 | |
| ), | |
| vec4( | |
| 0.013986751242596301 * ((-2.0 * inputToken.lo.x) + 11.0 * inputToken.lo.y + (-47.0 * inputToken.lo.z) + (-50.0 * inputToken.lo.w) + (-54.0 * inputToken.hi.x) + (-3.0 * inputToken.hi.y) + 14.0 * inputToken.hi.z + 11.0 * inputToken.hi.w) + 0.0, | |
| 0.013986751242596301 * ((-23.0 * inputToken.lo.x) + (-inputToken.lo.y) + 109.0 * inputToken.lo.z + 31.0 * inputToken.lo.w + 4.0 * inputToken.hi.x + (-100.0 * inputToken.hi.y) + (-33.0 * inputToken.hi.z) + (-36.0 * inputToken.hi.w)) + 0.0, | |
| 0.013986751242596301 * ((-19.0 * inputToken.lo.x) + (-8.0 * inputToken.lo.z) + 20.0 * inputToken.lo.w + (-35.0 * inputToken.hi.x) + (-24.0 * inputToken.hi.y) + 79.0 * inputToken.hi.z + 2.0 * inputToken.hi.w) + 0.0, | |
| 0.013986751242596301 * (44.0 * inputToken.lo.x + 2.0 * inputToken.lo.y + 5.0 * inputToken.lo.z + 7.0 * inputToken.lo.w + 22.0 * inputToken.hi.x + (-70.0 * inputToken.hi.y) + (-67.0 * inputToken.hi.z) + (-35.0 * inputToken.hi.w)) + 0.0 | |
| ) | |
| ); | |
| } | |
| vec4 neuralQueryScores(NeuralToken key) { | |
| return vec4( | |
| 0.0038647791370749474 * key.lo.x + 0.09565000981092453 * key.lo.y + 0.002756686182692647 * key.lo.z + -0.08183622360229492 * key.lo.w + -0.15209506452083588 * key.hi.x + -0.0006105066277086735 * key.hi.y + 0.0010439646430313587 * key.hi.z + -0.03020688332617283 * key.hi.w, | |
| 0.005065929610282183 * key.lo.x + 0.14488759636878967 * key.lo.y + 0.003160916268825531 * key.lo.z + -0.0855727270245552 * key.lo.w + -0.3123375475406647 * key.hi.x + 0.00039022407145239413 * key.hi.y + 0.0037786494940519333 * key.hi.z + 0.1451321840286255 * key.hi.w, | |
| -0.002009483054280281 * key.lo.x + 0.0597594790160656 * key.lo.y + 0.0045239729806780815 * key.lo.z + -0.08765853196382523 * key.lo.w + -0.13884992897510529 * key.hi.x + -0.0021647117100656033 * key.hi.y + 0.003985927440226078 * key.hi.z + 0.09727758169174194 * key.hi.w, | |
| 0.007170629221946001 * key.lo.x + 0.0786278173327446 * key.lo.y + 0.004103775601834059 * key.lo.z + -0.1198369711637497 * key.lo.w + -0.2925199568271637 * key.hi.x + -0.002055276418104768 * key.hi.y + 0.0030450925696641207 * key.hi.z + 0.14401987195014954 * key.hi.w | |
| ); | |
| } | |
| NeuralToken neuralHead( | |
| vec4 runningSummaryLo[4], | |
| vec4 runningSummaryHi[4] | |
| ) { | |
| return NeuralToken( | |
| max(vec4( | |
| 0.04935851140909355 * ((-45.0 * runningSummaryLo[0].x) + (-7.0 * runningSummaryLo[0].y) + (-45.0 * runningSummaryLo[0].z) + (-20.0 * runningSummaryLo[0].w) + 7.0 * runningSummaryHi[0].x + (-13.0 * runningSummaryHi[0].y) + 120.0 * runningSummaryHi[0].z + (-24.0 * runningSummaryHi[0].w) + (-15.0 * runningSummaryLo[1].x) + (-26.0 * runningSummaryLo[1].y) + (-19.0 * runningSummaryLo[1].z) + runningSummaryLo[1].w + 27.0 * runningSummaryHi[1].x + (-48.0 * runningSummaryHi[1].y) + (-4.0 * runningSummaryHi[1].z) + (-10.0 * runningSummaryHi[1].w) + runningSummaryLo[2].x + (-5.0 * runningSummaryLo[2].y) + (-24.0 * runningSummaryLo[2].z) + 64.0 * runningSummaryLo[2].w + 91.0 * runningSummaryHi[2].x + (-runningSummaryHi[2].y) + (-68.0 * runningSummaryHi[2].z) + 39.0 * runningSummaryHi[2].w + 54.0 * runningSummaryLo[3].x + 39.0 * runningSummaryLo[3].y + 101.0 * runningSummaryLo[3].z + (-40.0 * runningSummaryLo[3].w) + (-127.0 * runningSummaryHi[3].x) + 64.0 * runningSummaryHi[3].y + (-41.0 * runningSummaryHi[3].z) + (-17.0 * runningSummaryHi[3].w)) + -0.15895532071590424, | |
| 0.04935851140909355 * ((-23.0 * runningSummaryLo[0].x) + (-19.0 * runningSummaryLo[0].y) + 3.0 * runningSummaryLo[0].z + 35.0 * runningSummaryLo[0].w + (-2.0 * runningSummaryHi[0].x) + 33.0 * runningSummaryHi[0].y + 3.0 * runningSummaryHi[0].z + 9.0 * runningSummaryHi[0].w + (-64.0 * runningSummaryLo[1].x) + (-32.0 * runningSummaryLo[1].y) + 30.0 * runningSummaryLo[1].z + 42.0 * runningSummaryLo[1].w + (-112.0 * runningSummaryHi[1].x) + 12.0 * runningSummaryHi[1].y + 28.0 * runningSummaryHi[1].z + (-11.0 * runningSummaryHi[1].w) + 15.0 * runningSummaryLo[2].x + 2.0 * runningSummaryLo[2].y + (-4.0 * runningSummaryLo[2].z) + (-7.0 * runningSummaryLo[2].w) + 7.0 * runningSummaryHi[2].x + (-3.0 * runningSummaryHi[2].y) + (-5.0 * runningSummaryHi[2].z) + runningSummaryHi[2].w + 76.0 * runningSummaryLo[3].x + 48.0 * runningSummaryLo[3].y + (-34.0 * runningSummaryLo[3].z) + (-67.0 * runningSummaryLo[3].w) + 103.0 * runningSummaryHi[3].x + (-40.0 * runningSummaryHi[3].y) + (-26.0 * runningSummaryHi[3].z) + runningSummaryHi[3].w) + 0.007501596584916115, | |
| 0.04935851140909355 * (58.0 * runningSummaryLo[0].x + (-11.0 * runningSummaryLo[0].y) + 46.0 * runningSummaryLo[0].z + (-41.0 * runningSummaryLo[0].w) + 5.0 * runningSummaryHi[0].x + (-6.0 * runningSummaryHi[0].y) + (-17.0 * runningSummaryHi[0].z) + (-8.0 * runningSummaryHi[0].w) + 13.0 * runningSummaryLo[1].x + 17.0 * runningSummaryLo[1].y + (-35.0 * runningSummaryLo[1].z) + 45.0 * runningSummaryLo[1].w + 27.0 * runningSummaryHi[1].x + (-17.0 * runningSummaryHi[1].y) + (-28.0 * runningSummaryHi[1].z) + 7.0 * runningSummaryHi[1].w + (-53.0 * runningSummaryLo[2].x) + 12.0 * runningSummaryLo[2].y + (-51.0 * runningSummaryLo[2].z) + 6.0 * runningSummaryLo[2].w + (-32.0 * runningSummaryHi[2].x) + (-5.0 * runningSummaryHi[2].y) + 58.0 * runningSummaryHi[2].z + (-9.0 * runningSummaryHi[2].w) + (-28.0 * runningSummaryLo[3].x) + (-21.0 * runningSummaryLo[3].y) + 37.0 * runningSummaryLo[3].z + (-12.0 * runningSummaryLo[3].w) + runningSummaryHi[3].x + 20.0 * runningSummaryHi[3].y + 2.0 * runningSummaryHi[3].z + 2.0 * runningSummaryHi[3].w) + -0.47742825746536255, | |
| 0.04935851140909355 * (11.0 * runningSummaryLo[0].x + 7.0 * runningSummaryLo[0].y + (-4.0 * runningSummaryLo[0].z) + (-9.0 * runningSummaryLo[0].w) + 2.0 * runningSummaryHi[0].x + (-15.0 * runningSummaryHi[0].y) + (-runningSummaryHi[0].z) + (-8.0 * runningSummaryHi[0].w) + 16.0 * runningSummaryLo[1].x + 12.0 * runningSummaryLo[1].y + (-27.0 * runningSummaryLo[1].z) + (-runningSummaryLo[1].w) + 61.0 * runningSummaryHi[1].x + (-5.0 * runningSummaryHi[1].y) + (-runningSummaryHi[1].z) + 4.0 * runningSummaryHi[1].w + (-7.0 * runningSummaryLo[2].x) + (-2.0 * runningSummaryLo[2].y) + 7.0 * runningSummaryLo[2].z + 4.0 * runningSummaryLo[2].w + runningSummaryHi[2].x + 4.0 * runningSummaryHi[2].y + (-2.0 * runningSummaryHi[2].z) + 4.0 * runningSummaryHi[2].w + (-18.0 * runningSummaryLo[3].x) + (-16.0 * runningSummaryLo[3].y) + 28.0 * runningSummaryLo[3].z + 6.0 * runningSummaryLo[3].w + (-65.0 * runningSummaryHi[3].x) + 16.0 * runningSummaryHi[3].y + 3.0 * runningSummaryHi[3].z + (-3.0 * runningSummaryHi[3].w)) + 0.01632097363471985 | |
| ), vec4(0.0)), | |
| max(vec4( | |
| 0.04935851140909355 * ((-5.0 * runningSummaryLo[0].x) + (-2.0 * runningSummaryLo[0].y) + (-40.0 * runningSummaryLo[0].w) + (-21.0 * runningSummaryHi[0].x) + (-22.0 * runningSummaryHi[0].y) + 14.0 * runningSummaryHi[0].z + 30.0 * runningSummaryHi[0].w + (-21.0 * runningSummaryLo[1].x) + 49.0 * runningSummaryLo[1].y + 15.0 * runningSummaryLo[1].z + (-64.0 * runningSummaryLo[1].w) + 43.0 * runningSummaryHi[1].x + 19.0 * runningSummaryHi[1].y + 23.0 * runningSummaryHi[1].z + 18.0 * runningSummaryHi[1].w + 5.0 * runningSummaryLo[2].x + (-15.0 * runningSummaryLo[2].y) + 21.0 * runningSummaryLo[2].z + 21.0 * runningSummaryLo[2].w + 30.0 * runningSummaryHi[2].x + 17.0 * runningSummaryHi[2].y + (-11.0 * runningSummaryHi[2].z) + (-6.0 * runningSummaryHi[2].w) + 22.0 * runningSummaryLo[3].x + (-38.0 * runningSummaryLo[3].y) + (-20.0 * runningSummaryLo[3].z) + 97.0 * runningSummaryLo[3].w + (-46.0 * runningSummaryHi[3].x) + (-5.0 * runningSummaryHi[3].y) + (-13.0 * runningSummaryHi[3].z) + (-59.0 * runningSummaryHi[3].w)) + -0.48355796933174133, | |
| 0.04935851140909355 * (26.0 * runningSummaryLo[0].x + (-13.0 * runningSummaryLo[0].y) + 11.0 * runningSummaryLo[0].z + (-2.0 * runningSummaryLo[0].w) + (-10.0 * runningSummaryHi[0].x) + (-8.0 * runningSummaryHi[0].y) + 2.0 * runningSummaryHi[0].z + (-15.0 * runningSummaryHi[0].w) + (-17.0 * runningSummaryLo[1].x) + (-27.0 * runningSummaryLo[1].y) + (-9.0 * runningSummaryLo[1].z) + 26.0 * runningSummaryLo[1].w + 7.0 * runningSummaryHi[1].x + (-7.0 * runningSummaryHi[1].y) + 6.0 * runningSummaryHi[1].z + 9.0 * runningSummaryHi[1].w + (-32.0 * runningSummaryLo[2].x) + 5.0 * runningSummaryLo[2].y + (-9.0 * runningSummaryLo[2].z) + 12.0 * runningSummaryLo[2].w + 49.0 * runningSummaryHi[2].x + 17.0 * runningSummaryHi[2].y + (-runningSummaryHi[2].z) + 24.0 * runningSummaryHi[2].w + 20.0 * runningSummaryLo[3].x + 35.0 * runningSummaryLo[3].y + 14.0 * runningSummaryLo[3].z + (-33.0 * runningSummaryLo[3].w) + (-50.0 * runningSummaryHi[3].x) + (-runningSummaryHi[3].y) + (-4.0 * runningSummaryHi[3].z) + (-26.0 * runningSummaryHi[3].w)) + -0.1052703931927681, | |
| 0.04935851140909355 * (11.0 * runningSummaryLo[0].x + 11.0 * runningSummaryLo[0].y + 9.0 * runningSummaryLo[0].z + (-80.0 * runningSummaryLo[0].w) + 30.0 * runningSummaryHi[0].x + 9.0 * runningSummaryHi[0].y + 36.0 * runningSummaryHi[0].z + 6.0 * runningSummaryHi[0].w + (-12.0 * runningSummaryLo[1].x) + (-4.0 * runningSummaryLo[1].y) + (-7.0 * runningSummaryLo[1].z) + 39.0 * runningSummaryLo[1].w + (-10.0 * runningSummaryHi[1].x) + (-30.0 * runningSummaryHi[1].y) + (-49.0 * runningSummaryHi[1].z) + runningSummaryHi[1].w + (-43.0 * runningSummaryLo[2].x) + (-20.0 * runningSummaryLo[2].y) + (-34.0 * runningSummaryLo[2].z) + 76.0 * runningSummaryLo[2].w + (-36.0 * runningSummaryHi[2].x) + (-10.0 * runningSummaryHi[2].y) + 15.0 * runningSummaryHi[2].z + (-8.0 * runningSummaryHi[2].w) + 43.0 * runningSummaryLo[3].x + 31.0 * runningSummaryLo[3].y + 38.0 * runningSummaryLo[3].z + (-42.0 * runningSummaryLo[3].w) + 39.0 * runningSummaryHi[3].x + 37.0 * runningSummaryHi[3].y + (-7.0 * runningSummaryHi[3].z) + 7.0 * runningSummaryHi[3].w) + -0.8414919376373291, | |
| 0.04935851140909355 * (8.0 * runningSummaryLo[0].x + 16.0 * runningSummaryLo[0].y + 28.0 * runningSummaryLo[0].z + (-83.0 * runningSummaryLo[0].w) + 32.0 * runningSummaryHi[0].x + 9.0 * runningSummaryHi[0].y + 23.0 * runningSummaryHi[0].z + (-13.0 * runningSummaryHi[0].w) + 39.0 * runningSummaryLo[1].x + 119.0 * runningSummaryLo[1].y + 23.0 * runningSummaryLo[1].z + (-127.0 * runningSummaryLo[1].w) + (-24.0 * runningSummaryHi[1].x) + 8.0 * runningSummaryHi[1].y + (-48.0 * runningSummaryHi[1].z) + (-29.0 * runningSummaryHi[1].w) + (-7.0 * runningSummaryLo[2].x) + (-33.0 * runningSummaryLo[2].y) + (-12.0 * runningSummaryLo[2].z) + 58.0 * runningSummaryLo[2].w + (-24.0 * runningSummaryHi[2].x) + (-29.0 * runningSummaryHi[2].y) + (-19.0 * runningSummaryHi[2].z) + 12.0 * runningSummaryHi[2].w + (-55.0 * runningSummaryLo[3].x) + (-90.0 * runningSummaryLo[3].y) + 126.0 * runningSummaryLo[3].w + 26.0 * runningSummaryHi[3].x + 42.0 * runningSummaryHi[3].y + 54.0 * runningSummaryHi[3].z + 22.0 * runningSummaryHi[3].w) + -0.21046382188796997 | |
| ), vec4(0.0)) | |
| ); | |
| } | |
| float neuralOutput(NeuralToken head) { | |
| return 0.0030087142047955295 * (11.0 * head.lo.x + 11.0 * head.lo.y + 14.0 * head.lo.z + (-27.0 * head.lo.w) + 9.0 * head.hi.x + (-22.0 * head.hi.y) + 127.0 * head.hi.z + 6.0 * head.hi.w) + -0.0005526235327124596; | |
| } | |
| vec3 neuralSafeNormalize(vec3 value, vec3 fallback) { | |
| float lengthSquared = dot(value, value); | |
| return lengthSquared > 1e-12 ? value * inversesqrt(lengthSquared) : fallback; | |
| } | |
| mat3 neuralLocalFrame(vec3 inputNormal) { | |
| vec3 frameNormal = neuralSafeNormalize(inputNormal, vec3(0.0, 0.0, 1.0)); | |
| vec3 helper = abs(frameNormal.z) < 0.999 | |
| ? vec3(0.0, 0.0, 1.0) | |
| : vec3(0.0, 1.0, 0.0); | |
| vec3 tangent = neuralSafeNormalize( | |
| cross(helper, frameNormal), | |
| vec3(1.0, 0.0, 0.0) | |
| ); | |
| vec3 bitangent = cross(frameNormal, tangent); | |
| return transpose(mat3(tangent, bitangent, frameNormal)); | |
| } | |
| void neuralConsumeToken( | |
| NeuralToken token, | |
| inout vec4 runningMaximum, | |
| inout vec4 runningDenominator, | |
| inout vec4 runningSummaryLo[4], | |
| inout vec4 runningSummaryHi[4] | |
| ) { | |
| NeuralToken key = neuralKeyProject(token); | |
| NeuralToken value = neuralValueProject(token); | |
| vec4 score = neuralQueryScores(key) * 0.3535533905932738; | |
| vec4 newMaximum = max(runningMaximum, score); | |
| vec4 oldScale = exp(runningMaximum - newMaximum); | |
| vec4 newScale = exp(score - newMaximum); | |
| runningSummaryLo[0] = runningSummaryLo[0] * oldScale.x + value.lo * newScale.x; | |
| runningSummaryHi[0] = runningSummaryHi[0] * oldScale.x + value.hi * newScale.x; | |
| runningSummaryLo[1] = runningSummaryLo[1] * oldScale.y + value.lo * newScale.y; | |
| runningSummaryHi[1] = runningSummaryHi[1] * oldScale.y + value.hi * newScale.y; | |
| runningSummaryLo[2] = runningSummaryLo[2] * oldScale.z + value.lo * newScale.z; | |
| runningSummaryHi[2] = runningSummaryHi[2] * oldScale.z + value.hi * newScale.z; | |
| runningSummaryLo[3] = runningSummaryLo[3] * oldScale.w + value.lo * newScale.w; | |
| runningSummaryHi[3] = runningSummaryHi[3] * oldScale.w + value.hi * newScale.w; | |
| runningDenominator = runningDenominator * oldScale + newScale; | |
| runningMaximum = newMaximum; | |
| } | |
| void neuralEncodeTap( | |
| NeuralToken raw, | |
| inout vec4 runningMaximum, | |
| inout vec4 runningDenominator, | |
| inout vec4 runningSummaryLo[4], | |
| inout vec4 runningSummaryHi[4] | |
| ) { | |
| NeuralToken first = neuralTapInput(raw); | |
| NeuralToken token = neuralTapOutput(first); | |
| neuralConsumeToken( | |
| token, | |
| runningMaximum, | |
| runningDenominator, | |
| runningSummaryLo, | |
| runningSummaryHi | |
| ); | |
| } | |
| float neuralFinish( | |
| float baselineAO, | |
| inout vec4 runningMaximum, | |
| inout vec4 runningDenominator, | |
| inout vec4 runningSummaryLo[4], | |
| inout vec4 runningSummaryHi[4] | |
| ) { | |
| vec4 raw = vec4( | |
| baselineAO, | |
| log(max(worldRadius, 1e-6)), | |
| log(max(distanceFalloff, 1e-6)), | |
| 0.0 | |
| ); | |
| NeuralToken token = neuralEncodeGlobal(raw); | |
| neuralConsumeToken( | |
| token, | |
| runningMaximum, | |
| runningDenominator, | |
| runningSummaryLo, | |
| runningSummaryHi | |
| ); | |
| vec4 inverseDenominator = 1.0 / max(runningDenominator, vec4(1e-12)); | |
| runningSummaryLo[0] *= inverseDenominator.x; | |
| runningSummaryHi[0] *= inverseDenominator.x; | |
| runningSummaryLo[1] *= inverseDenominator.y; | |
| runningSummaryHi[1] *= inverseDenominator.y; | |
| runningSummaryLo[2] *= inverseDenominator.z; | |
| runningSummaryHi[2] *= inverseDenominator.z; | |
| runningSummaryLo[3] *= inverseDenominator.w; | |
| runningSummaryHi[3] *= inverseDenominator.w; | |
| NeuralToken head = neuralHead(runningSummaryLo, runningSummaryHi); | |
| return neuralOutput(head); | |
| } | |
| #endif | |
| #include <common> | |
| #define NUM_SAMPLES 16 | |
| uniform vec2 poissonDisk[NUM_SAMPLES]; | |
| void main() { | |
| const float pi = 3.14159; | |
| vec2 texelSize = vec2(1.0 / resolution.x, 1.0 / resolution.y); | |
| vec2 uv = vUv; | |
| vec4 data = texture2D(tDiffuse, vUv); | |
| float occlusion = data.r; | |
| float baseOcc = data.r; | |
| vec3 normal = data.gba * 2.0 - 1.0; | |
| float count = 1.0; | |
| float d = texture2D(sceneDepth, vUv).x; | |
| if (isBackgroundDepth(d)) { | |
| gl_FragColor = data; | |
| return; | |
| } | |
| vec3 worldPos = getWorldPos(d, vUv); | |
| float size = radius; | |
| float angle; | |
| #ifdef NEURAL_DENOISE | |
| // The neural material is only bound for denoise iteration two. | |
| angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).z * PI2; | |
| #else | |
| if (index == 0.0) { | |
| angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).w * PI2; | |
| } else if (index == 1.0) { | |
| angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).z * PI2; | |
| } else if (index == 2.0) { | |
| angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).y * PI2; | |
| } else { | |
| angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).x * PI2; | |
| } | |
| #endif | |
| mat2 rotationMatrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle)); | |
| float radiusToUse = screenSpaceRadius ? distance( | |
| worldPos, | |
| getWorldPos(d, vUv + | |
| vec2(worldRadius, 0.0) / resolution) | |
| ) : worldRadius; | |
| float distanceFalloffToUse =screenSpaceRadius ? | |
| radiusToUse * distanceFalloff | |
| : radiusToUse * distanceFalloff * 0.2; | |
| float invDistance = (1.0 / distanceFalloffToUse); | |
| #ifdef NEURAL_DENOISE | |
| mat3 neuralWorldToLocal = neuralLocalFrame(normal); | |
| float neuralInverseRadius = 1.0 / max(radiusToUse, 1e-6); | |
| float neuralInverseDistance = 1.0 / max(distanceFalloffToUse, 1e-6); | |
| vec4 neuralMaximum = vec4(-1e30); | |
| vec4 neuralDenominator = vec4(0.0); | |
| vec4 neuralSummaryLo[4]; | |
| vec4 neuralSummaryHi[4]; | |
| for (int query = 0; query < 4; query++) { | |
| neuralSummaryLo[query] = vec4(0.0); | |
| neuralSummaryHi[query] = vec4(0.0); | |
| } | |
| #endif | |
| for(int i = 0; i < NUM_SAMPLES; i++) { | |
| vec2 offset = (rotationMatrix * poissonDisk[i]) * texelSize * size; | |
| vec4 dataSample = texture2D(tDiffuse, uv + offset); | |
| float occSample = dataSample.r; | |
| vec3 normalSample = dataSample.gba * 2.0 - 1.0; | |
| float dSample = texture2D(sceneDepth, uv + offset).x; | |
| vec3 worldPosSample = getWorldPos(dSample, uv + offset); | |
| float tangentPlaneDist = abs(dot(worldPosSample - worldPos, normal)); | |
| float rangeCheck = float(!isBackgroundDepth(dSample)) * exp(-1.0 * tangentPlaneDist * invDistance ) * max(dot(normal, normalSample), 0.0); | |
| occlusion += occSample * rangeCheck; | |
| count += rangeCheck; | |
| #ifdef NEURAL_DENOISE | |
| if (!isBackgroundDepth(dSample)) { | |
| vec3 localDelta = (neuralWorldToLocal * (worldPosSample - worldPos)) | |
| * neuralInverseRadius; | |
| vec3 localNormal = neuralWorldToLocal | |
| * neuralSafeNormalize(normalSample, vec3(0.0, 0.0, 1.0)); | |
| NeuralToken rawTap = NeuralToken( | |
| vec4(localDelta, localNormal.x), | |
| vec4( | |
| localNormal.y, | |
| localNormal.z, | |
| occSample, | |
| tangentPlaneDist * neuralInverseDistance | |
| ) | |
| ); | |
| neuralEncodeTap( | |
| rawTap, | |
| neuralMaximum, | |
| neuralDenominator, | |
| neuralSummaryLo, | |
| neuralSummaryHi | |
| ); | |
| } | |
| #endif | |
| } | |
| if (count > 0.0) { | |
| occlusion /= count; | |
| } | |
| occlusion = clamp(occlusion, 0.0, 1.0); | |
| if (occlusion == 0.0) { | |
| occlusion = 1.0; | |
| } | |
| #ifdef NEURAL_DENOISE | |
| occlusion = clamp( | |
| occlusion + neuralFinish( | |
| occlusion, | |
| neuralMaximum, | |
| neuralDenominator, | |
| neuralSummaryLo, | |
| neuralSummaryHi | |
| ), | |
| 0.0, | |
| 1.0 | |
| ); | |
| #endif | |
| gl_FragColor = vec4(occlusion, 0.5 + 0.5 * normal); | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment