@zephyr3d/scene 0.9.21 → 0.9.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation/joint_dynamics/collision.js +1 -7
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/constraints.js +2 -17
- package/dist/animation/joint_dynamics/constraints.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +2 -20
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +1 -3
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +14 -60
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js +3 -3
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/app/app.js +23 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/scriptregistry.js +16 -53
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +2 -0
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/model.js +22 -0
- package/dist/asset/model.js.map +1 -1
- package/dist/blitter/bilateralblur.js +3 -1
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/blitter.js +3 -3
- package/dist/blitter/blitter.js.map +1 -1
- package/dist/camera/camera.js +398 -45
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +69 -2
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +9100 -8712
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +1 -1
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/lambert.js +3 -3
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +8 -5
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +17 -10
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +21 -6
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +33 -11
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/brdf.js +44 -12
- package/dist/material/mixins/pbr/brdf.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +149 -14
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +7 -4
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrblueprint.js +5 -1
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrmr.js +1 -1
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +1 -1
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/shader/helper.js +186 -11
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/skin.js +2 -2
- package/dist/material/skin.js.map +1 -1
- package/dist/material/terrain-cm.js +5 -5
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/water.js +6 -4
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +54 -4
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/compositor.js +41 -0
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/posteffect.js +51 -0
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/sao.js +7 -6
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +3 -3
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +1196 -0
- package/dist/posteffect/ssgi.js.map +1 -0
- package/dist/posteffect/ssr.js +83 -45
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +137 -49
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +5 -4
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +15 -3
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +2 -2
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js +12 -6
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/drawable_mixin.js +8 -5
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +10 -5
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +298 -5
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/gpu_picking.js +7 -5
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/hzb.js +28 -19
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/lightpass.js +18 -4
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/render_queue.js +37 -4
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +8 -3
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +20 -48
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js +18 -58
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +89 -115
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +1003 -715
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_graph_context.js +41 -0
- package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
- package/dist/render/rendergraph/frame_resource_requirements.js +14 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -0
- package/dist/render/rendergraph/history_resource_manager.js +74 -140
- package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +7 -5
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/render_context.js +19 -0
- package/dist/render/rendergraph/render_context.js.map +1 -0
- package/dist/render/rendergraph/render_pipeline.js +315 -0
- package/dist/render/rendergraph/render_pipeline.js.map +1 -0
- package/dist/render/rendergraph/rendergraph.js +158 -141
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/scene_render_context.js +267 -0
- package/dist/render/rendergraph/scene_render_context.js.map +1 -0
- package/dist/render/rendergraph/texture_affinity_cache.js +19 -0
- package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -0
- package/dist/render/rendergraph/types.js +19 -31
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +3 -3
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +10 -6
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/sky.js +197 -35
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js +4 -3
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +2 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +10 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +61 -2
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/light.js +178 -10
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/meshdrawable.js +89 -2
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +2 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +2 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +2 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +34 -1
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +2 -1
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +2 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +2 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js +5 -4
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +10 -3
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/shadow.js +96 -29
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/ssgi.js +63 -0
- package/dist/shaders/ssgi.js.map +1 -0
- package/dist/shaders/ssgi_reprojection.js +118 -0
- package/dist/shaders/ssgi_reprojection.js.map +1 -0
- package/dist/shaders/ssr.js +322 -154
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shadow/esm.js +13 -8
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +15 -12
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +15 -12
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +17 -11
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +20 -2
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadowmapper.js +10 -3
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +16 -13
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +10 -8
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/utility/physical.js +74 -0
- package/dist/utility/physical.js.map +1 -0
- package/dist/utility/rendermipmap.js +2 -2
- package/dist/utility/rendermipmap.js.map +1 -1
- package/dist/utility/serialization/manager.js +3 -1
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +3 -1
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +3 -1
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +598 -2
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +180 -9
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +43 -3
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +3 -1
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +3 -1
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +3 -1
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +2 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +70 -0
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +3 -1
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +3 -1
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +3 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +3 -1
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/values.js +2 -3
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
- package/dist/animation/joint_dynamics/convex_collider.js +0 -320
- package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dualdepthpeeling_oit.js","sources":["../../src/render/dualdepthpeeling_oit.ts"],"sourcesContent":["import type {\r\n AbstractDevice,\r\n BindGroup,\r\n DeviceCaps,\r\n FrameBuffer,\r\n GPUProgram,\r\n PBGlobalScope,\r\n PBInsideFunctionScope,\r\n PBShaderExp,\r\n RenderStateSet,\r\n Texture2D,\r\n TextureFormat\r\n} from '@zephyr3d/device';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { Disposable, Vector4 } from '@zephyr3d/base';\r\nimport type { OIT } from './oit';\r\nimport type { DrawContext } from './drawable';\r\nimport { drawFullscreenQuad } from './fullscreenquad';\r\nimport { tryGetApp } from '../app/api';\r\n\r\nconst DEPTH_FORMAT: TextureFormat = 'rg32f';\r\nconst ACCUM_FORMAT: TextureFormat = 'rgba16f';\r\nconst COLOR_ATTACHMENT_BYTES_PER_SAMPLE = 4 + 8 + 8;\r\n\r\n/**\r\n * Dual depth peeling OIT renderer.\r\n *\r\n * @remarks\r\n * This implementation follows the official dual depth peeling pass structure:\r\n * an initialization pass writes the nearest/farthest transparent depth pair, then\r\n * each peel pass ping-pongs the depth pair while accumulating front and back colors.\r\n *\r\n * It requires MRT, per-target blending, min/max blend equations and blendable\r\n * floating-point color targets. If those capabilities are missing, supportDevice()\r\n * returns false and the transparent pass falls back to sorted alpha blending.\r\n *\r\n * @public\r\n */\r\nexport class DualDepthPeelingOIT extends Disposable implements OIT {\r\n /** Type name of DualDepthPeelingOIT */\r\n public static readonly type = 'ddp';\r\n private static readonly DEPTH_CLEAR = new Vector4(-1, -1, -1, -1);\r\n private static readonly FRONT_CLEAR = new Vector4(0, 0, 0, 1);\r\n private static readonly BACK_CLEAR = new Vector4(0, 0, 0, 0);\r\n private static _compositeProgram: Nullable<GPUProgram> = null;\r\n private static _compositeBindGroup: Nullable<BindGroup> = null;\r\n private static _compositeRenderStates: Nullable<RenderStateSet> = null;\r\n private _numPeels: number;\r\n private _currentPass: number;\r\n private _hash: string;\r\n private _depthTargets: [Nullable<Texture2D>, Nullable<Texture2D>];\r\n private _frontTarget: Nullable<Texture2D>;\r\n private _backTarget: Nullable<Texture2D>;\r\n private _framebuffers: [Nullable<FrameBuffer>, Nullable<FrameBuffer>];\r\n private _device: Nullable<AbstractDevice>;\r\n\r\n /**\r\n * Creates an instance of DualDepthPeelingOIT.\r\n *\r\n * @param numPeels - Number of peel iterations after the initialization pass.\r\n */\r\n constructor(numPeels = 8) {\r\n super();\r\n this._numPeels = Math.max(1, Math.floor(numPeels || 0));\r\n this._currentPass = 0;\r\n this._hash = DualDepthPeelingOIT.type;\r\n this._depthTargets = [null, null];\r\n this._frontTarget = null;\r\n this._backTarget = null;\r\n this._framebuffers = [null, null];\r\n this._device = null;\r\n }\r\n\r\n /** Number of front/back peel iterations after the initialization pass. */\r\n get numPeels() {\r\n return this._numPeels;\r\n }\r\n set numPeels(val: number) {\r\n this._numPeels = Math.max(1, Math.floor(val || 0));\r\n }\r\n\r\n /**\r\n * Checks whether dual depth peeling can run with a capability snapshot.\r\n *\r\n * @param deviceType - The device type.\r\n * @param caps - The device capabilities.\r\n * @returns True if dual depth peeling is supported.\r\n */\r\n static supportDeviceCaps(deviceType: string, caps: DeviceCaps) {\r\n const framebufferCaps = caps.framebufferCaps;\r\n const textureCaps = caps.textureCaps;\r\n const shaderCaps = caps.shaderCaps;\r\n const miscCaps = caps.miscCaps;\r\n const webgl2OrBetter = deviceType !== 'webgl' || shaderCaps.maxUniformBufferSize > 0;\r\n return (\r\n webgl2OrBetter &&\r\n framebufferCaps.maxDrawBuffers >= 3 &&\r\n framebufferCaps.supportPerTargetBlending &&\r\n framebufferCaps.maxColorAttachmentBytesPerSample >= COLOR_ATTACHMENT_BYTES_PER_SAMPLE &&\r\n miscCaps.supportBlendMinMax &&\r\n textureCaps.supportHalfFloatColorBuffer &&\r\n textureCaps.supportFloatColorBuffer &&\r\n textureCaps.supportFloatBlending\r\n );\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.getType}\r\n */\r\n getType() {\r\n return DualDepthPeelingOIT.type;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.supportDevice}\r\n */\r\n supportDevice(deviceType: string) {\r\n const device = tryGetApp()?.device;\r\n return (\r\n !!device &&\r\n device.type === deviceType &&\r\n DualDepthPeelingOIT.supportDeviceCaps(deviceType, device.getDeviceCaps())\r\n );\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.wantsPremultipliedAlpha}\r\n */\r\n wantsPremultipliedAlpha() {\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.wantsAdditiveLightPassAlpha}\r\n */\r\n wantsAdditiveLightPassAlpha() {\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.begin}\r\n */\r\n begin(ctx: DrawContext) {\r\n this.releaseFramebuffers();\r\n if (!ctx.depthTexture) {\r\n return 0;\r\n }\r\n this._device = ctx.device;\r\n this.createFramebuffers(ctx);\r\n return this._numPeels + 1;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.end}\r\n */\r\n end(ctx: DrawContext) {\r\n try {\r\n if (this._frontTarget && this._backTarget) {\r\n this.composite(ctx, ctx.device, this._frontTarget, this._backTarget);\r\n }\r\n } finally {\r\n this.releaseFramebuffers();\r\n this._hash = DualDepthPeelingOIT.type;\r\n }\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.beginPass}\r\n */\r\n beginPass(ctx: DrawContext, pass: number) {\r\n this._currentPass = pass;\r\n const targetIndex = pass & 1;\r\n const currentDepthTarget = this._depthTargets[targetIndex];\r\n const previousDepthTarget = this._depthTargets[targetIndex ^ 1];\r\n const framebuffer = this._framebuffers[targetIndex];\r\n if (!currentDepthTarget || !framebuffer || (pass > 0 && !previousDepthTarget)) {\r\n return false;\r\n }\r\n this._hash =\r\n pass === 0\r\n ? `${this.getType()}#init#${currentDepthTarget.uid}`\r\n : `${this.getType()}#peel#${previousDepthTarget!.uid}`;\r\n ctx.device.pushDeviceStates();\r\n ctx.device.setFramebuffer(framebuffer);\r\n ctx.device.clearFrameBuffer(\r\n pass === 0\r\n ? [DualDepthPeelingOIT.DEPTH_CLEAR, DualDepthPeelingOIT.FRONT_CLEAR, DualDepthPeelingOIT.BACK_CLEAR]\r\n : [DualDepthPeelingOIT.DEPTH_CLEAR, null, null],\r\n null,\r\n null\r\n );\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.endPass}\r\n */\r\n endPass(ctx: DrawContext, _pass: number) {\r\n ctx.device.popDeviceStates();\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.setupFragmentOutput}\r\n */\r\n setupFragmentOutput(scope: PBGlobalScope) {\r\n const pb = scope.$builder;\r\n scope.$outputs.Z_DDP_depth = pb.vec2();\r\n scope.$outputs.Z_DDP_frontColor = pb.vec4();\r\n scope.$outputs.Z_DDP_backColor = pb.vec4();\r\n if (this._currentPass > 0) {\r\n scope.Z_DDP_depthTexture = pb.tex2D().uniform(2).noSampler();\r\n }\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.outputFragmentColor}\r\n */\r\n outputFragmentColor(scope: PBInsideFunctionScope, color: PBShaderExp, ctx: DrawContext) {\r\n const pb = scope.$builder;\r\n scope.$outputs.Z_DDP_depth = pb.vec2(-1, -1);\r\n scope.$outputs.Z_DDP_frontColor = pb.vec4(0, 0, 0, 0);\r\n scope.$outputs.Z_DDP_backColor = pb.vec4(0, 0, 0, 0);\r\n if (this._currentPass === 0) {\r\n scope.$outputs.Z_DDP_depth = pb.vec2(pb.neg(scope.$builtins.fragCoord.z), scope.$builtins.fragCoord.z);\r\n } else {\r\n scope.$l.Z_DDP_prevDepth = pb.textureLoad(\r\n scope.Z_DDP_depthTexture,\r\n pb.ivec2(scope.$builtins.fragCoord.xy),\r\n 0\r\n ).xy;\r\n scope.$l.Z_DDP_frontDepth = pb.neg(scope.Z_DDP_prevDepth.x);\r\n scope.$l.Z_DDP_backDepth = scope.Z_DDP_prevDepth.y;\r\n scope.$l.Z_DDP_curDepth = scope.$builtins.fragCoord.z;\r\n scope.$l.Z_DDP_outputColor = pb.vec4(color.rgb, ctx.lightBlending ? pb.float(0) : color.a);\r\n scope\r\n .$if(\r\n pb.or(\r\n pb.lessThan(pb.add(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_frontDepth),\r\n pb.greaterThan(pb.sub(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_backDepth)\r\n ),\r\n function () {\r\n pb.discard();\r\n }\r\n )\r\n .$elseif(\r\n pb.and(\r\n pb.greaterThan(pb.sub(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_frontDepth),\r\n pb.lessThan(pb.add(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_backDepth)\r\n ),\r\n function () {\r\n this.$outputs.Z_DDP_depth = pb.vec2(\r\n pb.neg(this.$builtins.fragCoord.z),\r\n this.$builtins.fragCoord.z\r\n );\r\n }\r\n )\r\n .$elseif(\r\n pb.and(\r\n pb.lessThan(scope.Z_DDP_curDepth, pb.add(scope.Z_DDP_frontDepth, 0.000001)),\r\n pb.greaterThan(scope.Z_DDP_curDepth, pb.sub(scope.Z_DDP_frontDepth, 0.000001))\r\n ),\r\n function () {\r\n this.$outputs.Z_DDP_frontColor = this.Z_DDP_outputColor;\r\n }\r\n )\r\n .$else(function () {\r\n this.$outputs.Z_DDP_backColor = this.Z_DDP_outputColor;\r\n });\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.applyUniforms}\r\n */\r\n applyUniforms(_ctx: DrawContext, bindGroup: BindGroup) {\r\n if (this._currentPass > 0) {\r\n bindGroup.setTexture('Z_DDP_depthTexture', this._depthTargets[(this._currentPass & 1) ^ 1]!);\r\n }\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.calculateHash}\r\n */\r\n calculateHash() {\r\n return this._hash;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.setRenderStates}\r\n */\r\n setRenderStates(rs: RenderStateSet) {\r\n rs.useBlendingState().enable(false).enableAlphaToCoverage(false);\r\n rs.useDepthState().enableTest(true).enableWrite(false);\r\n\r\n rs.useTargetBlendingState(0)\r\n .enable(true)\r\n .enableAlphaToCoverage(false)\r\n .setBlendEquation('max', 'max')\r\n .setBlendFunc('one', 'one');\r\n\r\n rs.useTargetBlendingState(1)\r\n .enable(true)\r\n .enableAlphaToCoverage(false)\r\n .setBlendEquation('add', 'add')\r\n .setBlendFuncRGB('dst-alpha', 'one')\r\n .setBlendFuncAlpha('zero', 'inv-src-alpha');\r\n\r\n rs.useTargetBlendingState(2)\r\n .enable(true)\r\n .enableAlphaToCoverage(false)\r\n .setBlendEquation('add', 'add')\r\n .setBlendFuncRGB('one', 'inv-src-alpha')\r\n .setBlendFuncAlpha('one', 'inv-src-alpha');\r\n }\r\n\r\n /** @internal */\r\n private createFramebuffers(ctx: DrawContext) {\r\n const device = ctx.device;\r\n const width = ctx.depthTexture!.width;\r\n const height = ctx.depthTexture!.height;\r\n const depthTarget0 = device.pool.fetchTemporalTexture2D(false, DEPTH_FORMAT, width, height, false);\r\n const depthTarget1 = device.pool.fetchTemporalTexture2D(false, DEPTH_FORMAT, width, height, false);\r\n const frontTarget = device.pool.fetchTemporalTexture2D(false, ACCUM_FORMAT, width, height, false);\r\n const backTarget = device.pool.fetchTemporalTexture2D(false, ACCUM_FORMAT, width, height, false);\r\n const framebuffer0 = device.pool.createTemporalFramebuffer(\r\n false,\r\n [depthTarget0, frontTarget, backTarget],\r\n ctx.depthTexture\r\n );\r\n const framebuffer1 = device.pool.createTemporalFramebuffer(\r\n false,\r\n [depthTarget1, frontTarget, backTarget],\r\n ctx.depthTexture\r\n );\r\n device.pool.releaseTexture(depthTarget0);\r\n device.pool.releaseTexture(depthTarget1);\r\n device.pool.releaseTexture(frontTarget);\r\n device.pool.releaseTexture(backTarget);\r\n this._depthTargets = [depthTarget0, depthTarget1];\r\n this._frontTarget = frontTarget;\r\n this._backTarget = backTarget;\r\n this._framebuffers = [framebuffer0, framebuffer1];\r\n }\r\n\r\n /** @internal */\r\n private composite(ctx: DrawContext, device: AbstractDevice, frontTarget: Texture2D, backTarget: Texture2D) {\r\n const currentFramebuffer = device.getFramebuffer();\r\n const colorAttachment = currentFramebuffer?.getColorAttachments()[0] ?? null;\r\n const singleColorFramebuffer =\r\n currentFramebuffer && currentFramebuffer.getColorAttachments().length > 1 && colorAttachment\r\n ? device.pool.fetchTemporalFramebuffer(\r\n false,\r\n 0,\r\n 0,\r\n colorAttachment,\r\n currentFramebuffer.getDepthAttachment(),\r\n false\r\n )\r\n : null;\r\n if (singleColorFramebuffer) {\r\n const viewport = device.getViewport();\r\n const scissor = device.getScissor();\r\n device.pushDeviceStates();\r\n device.setFramebuffer(singleColorFramebuffer);\r\n device.setViewport(viewport);\r\n device.setScissor(scissor);\r\n }\r\n try {\r\n device.setProgram(DualDepthPeelingOIT.getCompositeProgram(device));\r\n DualDepthPeelingOIT._compositeBindGroup!.setTexture('frontTex', frontTarget);\r\n DualDepthPeelingOIT._compositeBindGroup!.setTexture('backTex', backTarget);\r\n device.setBindGroup(0, DualDepthPeelingOIT._compositeBindGroup!);\r\n drawFullscreenQuad(DualDepthPeelingOIT._compositeRenderStates!);\r\n } finally {\r\n if (singleColorFramebuffer) {\r\n device.popDeviceStates();\r\n device.pool.releaseFrameBuffer(singleColorFramebuffer);\r\n }\r\n }\r\n }\r\n\r\n /** @internal */\r\n private releaseFramebuffers() {\r\n if (this._device) {\r\n if (this._framebuffers[0]) {\r\n this._device.pool.releaseFrameBuffer(this._framebuffers[0]);\r\n }\r\n if (this._framebuffers[1]) {\r\n this._device.pool.releaseFrameBuffer(this._framebuffers[1]);\r\n }\r\n }\r\n this._depthTargets = [null, null];\r\n this._frontTarget = null;\r\n this._backTarget = null;\r\n this._framebuffers = [null, null];\r\n this._device = null;\r\n }\r\n\r\n /** @internal */\r\n private static getCompositeProgram(device: AbstractDevice) {\r\n if (!this._compositeProgram) {\r\n this._compositeProgram = device.buildRenderProgram({\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$outputs.uv = pb.vec2();\r\n pb.main(function () {\r\n this.$builtins.position = pb.vec4(this.$inputs.pos, 1, 1);\r\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\r\n if (device.type === 'webgpu') {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n }\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.outColor = pb.vec4();\r\n this.frontTex = pb.tex2D().uniform(0);\r\n this.backTex = pb.tex2D().uniform(0);\r\n pb.main(function () {\r\n this.$l.frontColor = pb.textureSample(this.frontTex, this.$inputs.uv);\r\n this.$l.backColor = pb.textureSample(this.backTex, this.$inputs.uv);\r\n this.$l.remainingAlpha = pb.clamp(pb.mul(this.frontColor.a, pb.sub(1, this.backColor.a)), 0, 1);\r\n this.$outputs.outColor = pb.vec4(\r\n pb.add(this.frontColor.rgb, pb.mul(this.frontColor.a, this.backColor.rgb)),\r\n this.remainingAlpha\r\n );\r\n });\r\n }\r\n })!;\r\n this._compositeProgram.name = '@DualDepthPeelingOIT_Composite';\r\n this._compositeBindGroup = device.createBindGroup(this._compositeProgram.bindGroupLayouts[0]);\r\n this._compositeRenderStates = device.createRenderStateSet();\r\n this._compositeRenderStates\r\n .useBlendingState()\r\n .enable(true)\r\n .setBlendFuncRGB('one', 'src-alpha')\r\n .setBlendFuncAlpha('zero', 'one');\r\n this._compositeRenderStates.useDepthState().enableTest(false).enableWrite(false);\r\n }\r\n return this._compositeProgram;\r\n }\r\n\r\n protected onDispose() {\r\n super.onDispose();\r\n this.releaseFramebuffers();\r\n }\r\n}\r\n"],"names":["DEPTH_FORMAT","ACCUM_FORMAT","COLOR_ATTACHMENT_BYTES_PER_SAMPLE","DualDepthPeelingOIT","Disposable","type","DEPTH_CLEAR","Vector4","FRONT_CLEAR","BACK_CLEAR","_compositeProgram","_compositeBindGroup","_compositeRenderStates","_numPeels","_currentPass","_hash","_depthTargets","_frontTarget","_backTarget","_framebuffers","_device","numPeels","Math","max","floor","val","supportDeviceCaps","deviceType","caps","framebufferCaps","textureCaps","shaderCaps","miscCaps","webgl2OrBetter","maxUniformBufferSize","maxDrawBuffers","supportPerTargetBlending","maxColorAttachmentBytesPerSample","supportBlendMinMax","supportHalfFloatColorBuffer","supportFloatColorBuffer","supportFloatBlending","getType","supportDevice","device","tryGetApp","getDeviceCaps","wantsPremultipliedAlpha","wantsAdditiveLightPassAlpha","begin","ctx","releaseFramebuffers","depthTexture","createFramebuffers","end","composite","beginPass","pass","targetIndex","currentDepthTarget","previousDepthTarget","framebuffer","uid","pushDeviceStates","setFramebuffer","clearFrameBuffer","endPass","_pass","popDeviceStates","setupFragmentOutput","scope","pb","$builder","$outputs","Z_DDP_depth","vec2","Z_DDP_frontColor","vec4","Z_DDP_backColor","Z_DDP_depthTexture","tex2D","uniform","noSampler","outputFragmentColor","color","neg","$builtins","fragCoord","z","$l","Z_DDP_prevDepth","textureLoad","ivec2","xy","Z_DDP_frontDepth","x","Z_DDP_backDepth","y","Z_DDP_curDepth","Z_DDP_outputColor","rgb","lightBlending","float","a","$if","or","lessThan","add","greaterThan","sub","discard","$elseif","and","$else","applyUniforms","_ctx","bindGroup","setTexture","calculateHash","setRenderStates","rs","useBlendingState","enable","enableAlphaToCoverage","useDepthState","enableTest","enableWrite","useTargetBlendingState","setBlendEquation","setBlendFunc","setBlendFuncRGB","setBlendFuncAlpha","width","height","depthTarget0","pool","fetchTemporalTexture2D","depthTarget1","frontTarget","backTarget","framebuffer0","createTemporalFramebuffer","framebuffer1","releaseTexture","currentFramebuffer","getFramebuffer","colorAttachment","getColorAttachments","singleColorFramebuffer","length","fetchTemporalFramebuffer","getDepthAttachment","viewport","getViewport","scissor","getScissor","setViewport","setScissor","setProgram","getCompositeProgram","setBindGroup","drawFullscreenQuad","releaseFrameBuffer","buildRenderProgram","vertex","$inputs","pos","attrib","uv","main","position","mul","fragment","outColor","frontTex","backTex","frontColor","textureSample","backColor","remainingAlpha","clamp","name","createBindGroup","bindGroupLayouts","createRenderStateSet","onDispose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dualdepthpeeling_oit.js","sources":["../../src/render/dualdepthpeeling_oit.ts"],"sourcesContent":["import type {\r\n AbstractDevice,\r\n BindGroup,\r\n DeviceCaps,\r\n FrameBuffer,\r\n GPUProgram,\r\n PBGlobalScope,\r\n PBInsideFunctionScope,\r\n PBShaderExp,\r\n RenderStateSet,\r\n Texture2D,\r\n TextureFormat\r\n} from '@zephyr3d/device';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport { DEPTH_FARTHEST, Disposable, REVERSE_Z, Vector4 } from '@zephyr3d/base';\r\nimport type { OIT } from './oit';\r\nimport type { DrawContext } from './drawable';\r\nimport { drawFullscreenQuad } from './fullscreenquad';\r\nimport { tryGetApp } from '../app/api';\r\n\r\nconst DEPTH_FORMAT: TextureFormat = 'rg32f';\r\nconst ACCUM_FORMAT: TextureFormat = 'rgba16f';\r\nconst COLOR_ATTACHMENT_BYTES_PER_SAMPLE = 4 + 8 + 8;\r\n\r\n/**\r\n * Dual depth peeling OIT renderer.\r\n *\r\n * @remarks\r\n * This implementation follows the official dual depth peeling pass structure:\r\n * an initialization pass writes the nearest/farthest transparent depth pair, then\r\n * each peel pass ping-pongs the depth pair while accumulating front and back colors.\r\n *\r\n * It requires MRT, per-target blending, min/max blend equations and blendable\r\n * floating-point color targets. If those capabilities are missing, supportDevice()\r\n * returns false and the transparent pass falls back to sorted alpha blending.\r\n *\r\n * @public\r\n */\r\nexport class DualDepthPeelingOIT extends Disposable implements OIT {\r\n /** Type name of DualDepthPeelingOIT */\r\n public static readonly type = 'ddp';\r\n private static readonly DEPTH_CLEAR = new Vector4(-1, -1, -1, -1);\r\n private static readonly FRONT_CLEAR = new Vector4(0, 0, 0, 1);\r\n private static readonly BACK_CLEAR = new Vector4(0, 0, 0, 0);\r\n private static _compositeProgram: Nullable<GPUProgram> = null;\r\n private static _compositeBindGroup: Nullable<BindGroup> = null;\r\n private static _compositeRenderStates: Nullable<RenderStateSet> = null;\r\n private _numPeels: number;\r\n private _currentPass: number;\r\n private _hash: string;\r\n private _depthTargets: [Nullable<Texture2D>, Nullable<Texture2D>];\r\n private _frontTarget: Nullable<Texture2D>;\r\n private _backTarget: Nullable<Texture2D>;\r\n private _framebuffers: [Nullable<FrameBuffer>, Nullable<FrameBuffer>];\r\n private _device: Nullable<AbstractDevice>;\r\n\r\n /**\r\n * Creates an instance of DualDepthPeelingOIT.\r\n *\r\n * @param numPeels - Number of peel iterations after the initialization pass.\r\n */\r\n constructor(numPeels = 8) {\r\n super();\r\n this._numPeels = Math.max(1, Math.floor(numPeels || 0));\r\n this._currentPass = 0;\r\n this._hash = DualDepthPeelingOIT.type;\r\n this._depthTargets = [null, null];\r\n this._frontTarget = null;\r\n this._backTarget = null;\r\n this._framebuffers = [null, null];\r\n this._device = null;\r\n }\r\n\r\n /** Number of front/back peel iterations after the initialization pass. */\r\n get numPeels() {\r\n return this._numPeels;\r\n }\r\n set numPeels(val: number) {\r\n this._numPeels = Math.max(1, Math.floor(val || 0));\r\n }\r\n\r\n /**\r\n * Checks whether dual depth peeling can run with a capability snapshot.\r\n *\r\n * @param deviceType - The device type.\r\n * @param caps - The device capabilities.\r\n * @returns True if dual depth peeling is supported.\r\n */\r\n static supportDeviceCaps(deviceType: string, caps: DeviceCaps) {\r\n const framebufferCaps = caps.framebufferCaps;\r\n const textureCaps = caps.textureCaps;\r\n const shaderCaps = caps.shaderCaps;\r\n const miscCaps = caps.miscCaps;\r\n const webgl2OrBetter = deviceType !== 'webgl' || shaderCaps.maxUniformBufferSize > 0;\r\n return (\r\n webgl2OrBetter &&\r\n framebufferCaps.maxDrawBuffers >= 3 &&\r\n framebufferCaps.supportPerTargetBlending &&\r\n framebufferCaps.maxColorAttachmentBytesPerSample >= COLOR_ATTACHMENT_BYTES_PER_SAMPLE &&\r\n miscCaps.supportBlendMinMax &&\r\n textureCaps.supportHalfFloatColorBuffer &&\r\n textureCaps.supportFloatColorBuffer &&\r\n textureCaps.supportFloatBlending\r\n );\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.getType}\r\n */\r\n getType() {\r\n return DualDepthPeelingOIT.type;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.supportDevice}\r\n */\r\n supportDevice(deviceType: string) {\r\n const device = tryGetApp()?.device;\r\n return (\r\n !!device &&\r\n device.type === deviceType &&\r\n DualDepthPeelingOIT.supportDeviceCaps(deviceType, device.getDeviceCaps())\r\n );\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.wantsPremultipliedAlpha}\r\n */\r\n wantsPremultipliedAlpha() {\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.wantsAdditiveLightPassAlpha}\r\n */\r\n wantsAdditiveLightPassAlpha() {\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.begin}\r\n */\r\n begin(ctx: DrawContext) {\r\n this.releaseFramebuffers();\r\n if (!ctx.depthTexture) {\r\n return 0;\r\n }\r\n this._device = ctx.device;\r\n this.createFramebuffers(ctx);\r\n return this._numPeels + 1;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.end}\r\n */\r\n end(ctx: DrawContext) {\r\n try {\r\n if (this._frontTarget && this._backTarget) {\r\n this.composite(ctx, ctx.device, this._frontTarget, this._backTarget);\r\n }\r\n } finally {\r\n this.releaseFramebuffers();\r\n this._hash = DualDepthPeelingOIT.type;\r\n }\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.beginPass}\r\n */\r\n beginPass(ctx: DrawContext, pass: number) {\r\n this._currentPass = pass;\r\n const targetIndex = pass & 1;\r\n const currentDepthTarget = this._depthTargets[targetIndex];\r\n const previousDepthTarget = this._depthTargets[targetIndex ^ 1];\r\n const framebuffer = this._framebuffers[targetIndex];\r\n if (!currentDepthTarget || !framebuffer || (pass > 0 && !previousDepthTarget)) {\r\n return false;\r\n }\r\n this._hash =\r\n pass === 0\r\n ? `${this.getType()}#init#${currentDepthTarget.uid}`\r\n : `${this.getType()}#peel#${previousDepthTarget!.uid}`;\r\n ctx.device.pushDeviceStates();\r\n ctx.device.setFramebuffer(framebuffer);\r\n ctx.device.clearFrameBuffer(\r\n pass === 0\r\n ? [DualDepthPeelingOIT.DEPTH_CLEAR, DualDepthPeelingOIT.FRONT_CLEAR, DualDepthPeelingOIT.BACK_CLEAR]\r\n : [DualDepthPeelingOIT.DEPTH_CLEAR, null, null],\r\n null,\r\n null\r\n );\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.endPass}\r\n */\r\n endPass(ctx: DrawContext, _pass: number) {\r\n ctx.device.popDeviceStates();\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.setupFragmentOutput}\r\n */\r\n setupFragmentOutput(scope: PBGlobalScope) {\r\n const pb = scope.$builder;\r\n scope.$outputs.Z_DDP_depth = pb.vec2();\r\n scope.$outputs.Z_DDP_frontColor = pb.vec4();\r\n scope.$outputs.Z_DDP_backColor = pb.vec4();\r\n if (this._currentPass > 0) {\r\n scope.Z_DDP_depthTexture = pb.tex2D().uniform(2).noSampler();\r\n }\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.outputFragmentColor}\r\n */\r\n outputFragmentColor(scope: PBInsideFunctionScope, color: PBShaderExp, ctx: DrawContext) {\r\n const pb = scope.$builder;\r\n scope.$outputs.Z_DDP_depth = pb.vec2(-1, -1);\r\n scope.$outputs.Z_DDP_frontColor = pb.vec4(0, 0, 0, 0);\r\n scope.$outputs.Z_DDP_backColor = pb.vec4(0, 0, 0, 0);\r\n // The peeling depth encoding is internal to this algorithm; normalize\r\n // device depth to standard orientation (0 = near) so the (-front, back)\r\n // encoding, the max/max blend extraction and the peel window logic stay\r\n // convention independent.\r\n scope.$l.Z_DDP_normDepth = REVERSE_Z\r\n ? pb.sub(1, scope.$builtins.fragCoord.z)\r\n : scope.$builtins.fragCoord.z;\r\n if (this._currentPass === 0) {\r\n scope.$outputs.Z_DDP_depth = pb.vec2(pb.neg(scope.Z_DDP_normDepth), scope.Z_DDP_normDepth);\r\n } else {\r\n scope.$l.Z_DDP_prevDepth = pb.textureLoad(\r\n scope.Z_DDP_depthTexture,\r\n pb.ivec2(scope.$builtins.fragCoord.xy),\r\n 0\r\n ).xy;\r\n scope.$l.Z_DDP_frontDepth = pb.neg(scope.Z_DDP_prevDepth.x);\r\n scope.$l.Z_DDP_backDepth = scope.Z_DDP_prevDepth.y;\r\n scope.$l.Z_DDP_curDepth = scope.Z_DDP_normDepth;\r\n scope.$l.Z_DDP_outputColor = pb.vec4(color.rgb, ctx.lightBlending ? pb.float(0) : color.a);\r\n scope\r\n .$if(\r\n pb.or(\r\n pb.lessThan(pb.add(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_frontDepth),\r\n pb.greaterThan(pb.sub(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_backDepth)\r\n ),\r\n function () {\r\n pb.discard();\r\n }\r\n )\r\n .$elseif(\r\n pb.and(\r\n pb.greaterThan(pb.sub(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_frontDepth),\r\n pb.lessThan(pb.add(scope.Z_DDP_curDepth, 0.000001), scope.Z_DDP_backDepth)\r\n ),\r\n function () {\r\n this.$outputs.Z_DDP_depth = pb.vec2(pb.neg(this.Z_DDP_normDepth), this.Z_DDP_normDepth);\r\n }\r\n )\r\n .$elseif(\r\n pb.and(\r\n pb.lessThan(scope.Z_DDP_curDepth, pb.add(scope.Z_DDP_frontDepth, 0.000001)),\r\n pb.greaterThan(scope.Z_DDP_curDepth, pb.sub(scope.Z_DDP_frontDepth, 0.000001))\r\n ),\r\n function () {\r\n this.$outputs.Z_DDP_frontColor = this.Z_DDP_outputColor;\r\n }\r\n )\r\n .$else(function () {\r\n this.$outputs.Z_DDP_backColor = this.Z_DDP_outputColor;\r\n });\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.applyUniforms}\r\n */\r\n applyUniforms(_ctx: DrawContext, bindGroup: BindGroup) {\r\n if (this._currentPass > 0) {\r\n bindGroup.setTexture('Z_DDP_depthTexture', this._depthTargets[(this._currentPass & 1) ^ 1]!);\r\n }\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.calculateHash}\r\n */\r\n calculateHash() {\r\n return this._hash;\r\n }\r\n\r\n /**\r\n * {@inheritDoc OIT.setRenderStates}\r\n */\r\n setRenderStates(rs: RenderStateSet) {\r\n rs.useBlendingState().enable(false).enableAlphaToCoverage(false);\r\n rs.useDepthState().enableTest(true).enableWrite(false);\r\n\r\n rs.useTargetBlendingState(0)\r\n .enable(true)\r\n .enableAlphaToCoverage(false)\r\n .setBlendEquation('max', 'max')\r\n .setBlendFunc('one', 'one');\r\n\r\n rs.useTargetBlendingState(1)\r\n .enable(true)\r\n .enableAlphaToCoverage(false)\r\n .setBlendEquation('add', 'add')\r\n .setBlendFuncRGB('dst-alpha', 'one')\r\n .setBlendFuncAlpha('zero', 'inv-src-alpha');\r\n\r\n rs.useTargetBlendingState(2)\r\n .enable(true)\r\n .enableAlphaToCoverage(false)\r\n .setBlendEquation('add', 'add')\r\n .setBlendFuncRGB('one', 'inv-src-alpha')\r\n .setBlendFuncAlpha('one', 'inv-src-alpha');\r\n }\r\n\r\n /** @internal */\r\n private createFramebuffers(ctx: DrawContext) {\r\n const device = ctx.device;\r\n const width = ctx.depthTexture!.width;\r\n const height = ctx.depthTexture!.height;\r\n const depthTarget0 = device.pool.fetchTemporalTexture2D(false, DEPTH_FORMAT, width, height, false);\r\n const depthTarget1 = device.pool.fetchTemporalTexture2D(false, DEPTH_FORMAT, width, height, false);\r\n const frontTarget = device.pool.fetchTemporalTexture2D(false, ACCUM_FORMAT, width, height, false);\r\n const backTarget = device.pool.fetchTemporalTexture2D(false, ACCUM_FORMAT, width, height, false);\r\n const framebuffer0 = device.pool.createTemporalFramebuffer(\r\n false,\r\n [depthTarget0, frontTarget, backTarget],\r\n ctx.depthTexture\r\n );\r\n const framebuffer1 = device.pool.createTemporalFramebuffer(\r\n false,\r\n [depthTarget1, frontTarget, backTarget],\r\n ctx.depthTexture\r\n );\r\n device.pool.releaseTexture(depthTarget0);\r\n device.pool.releaseTexture(depthTarget1);\r\n device.pool.releaseTexture(frontTarget);\r\n device.pool.releaseTexture(backTarget);\r\n this._depthTargets = [depthTarget0, depthTarget1];\r\n this._frontTarget = frontTarget;\r\n this._backTarget = backTarget;\r\n this._framebuffers = [framebuffer0, framebuffer1];\r\n }\r\n\r\n /** @internal */\r\n private composite(ctx: DrawContext, device: AbstractDevice, frontTarget: Texture2D, backTarget: Texture2D) {\r\n const currentFramebuffer = device.getFramebuffer();\r\n const colorAttachment = currentFramebuffer?.getColorAttachments()[0] ?? null;\r\n const singleColorFramebuffer =\r\n currentFramebuffer && currentFramebuffer.getColorAttachments().length > 1 && colorAttachment\r\n ? device.pool.fetchTemporalFramebuffer(\r\n false,\r\n 0,\r\n 0,\r\n colorAttachment,\r\n currentFramebuffer.getDepthAttachment(),\r\n false\r\n )\r\n : null;\r\n if (singleColorFramebuffer) {\r\n const viewport = device.getViewport();\r\n const scissor = device.getScissor();\r\n device.pushDeviceStates();\r\n device.setFramebuffer(singleColorFramebuffer);\r\n device.setViewport(viewport);\r\n device.setScissor(scissor);\r\n }\r\n try {\r\n device.setProgram(DualDepthPeelingOIT.getCompositeProgram(device));\r\n DualDepthPeelingOIT._compositeBindGroup!.setTexture('frontTex', frontTarget);\r\n DualDepthPeelingOIT._compositeBindGroup!.setTexture('backTex', backTarget);\r\n device.setBindGroup(0, DualDepthPeelingOIT._compositeBindGroup!);\r\n drawFullscreenQuad(DualDepthPeelingOIT._compositeRenderStates!);\r\n } finally {\r\n if (singleColorFramebuffer) {\r\n device.popDeviceStates();\r\n device.pool.releaseFrameBuffer(singleColorFramebuffer);\r\n }\r\n }\r\n }\r\n\r\n /** @internal */\r\n private releaseFramebuffers() {\r\n if (this._device) {\r\n if (this._framebuffers[0]) {\r\n this._device.pool.releaseFrameBuffer(this._framebuffers[0]);\r\n }\r\n if (this._framebuffers[1]) {\r\n this._device.pool.releaseFrameBuffer(this._framebuffers[1]);\r\n }\r\n }\r\n this._depthTargets = [null, null];\r\n this._frontTarget = null;\r\n this._backTarget = null;\r\n this._framebuffers = [null, null];\r\n this._device = null;\r\n }\r\n\r\n /** @internal */\r\n private static getCompositeProgram(device: AbstractDevice) {\r\n if (!this._compositeProgram) {\r\n this._compositeProgram = device.buildRenderProgram({\r\n vertex(pb) {\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$outputs.uv = pb.vec2();\r\n pb.main(function () {\r\n this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);\r\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\r\n if (device.type === 'webgpu') {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n }\r\n });\r\n },\r\n fragment(pb) {\r\n this.$outputs.outColor = pb.vec4();\r\n this.frontTex = pb.tex2D().uniform(0);\r\n this.backTex = pb.tex2D().uniform(0);\r\n pb.main(function () {\r\n this.$l.frontColor = pb.textureSample(this.frontTex, this.$inputs.uv);\r\n this.$l.backColor = pb.textureSample(this.backTex, this.$inputs.uv);\r\n this.$l.remainingAlpha = pb.clamp(pb.mul(this.frontColor.a, pb.sub(1, this.backColor.a)), 0, 1);\r\n this.$outputs.outColor = pb.vec4(\r\n pb.add(this.frontColor.rgb, pb.mul(this.frontColor.a, this.backColor.rgb)),\r\n this.remainingAlpha\r\n );\r\n });\r\n }\r\n })!;\r\n this._compositeProgram.name = '@DualDepthPeelingOIT_Composite';\r\n this._compositeBindGroup = device.createBindGroup(this._compositeProgram.bindGroupLayouts[0]);\r\n this._compositeRenderStates = device.createRenderStateSet();\r\n this._compositeRenderStates\r\n .useBlendingState()\r\n .enable(true)\r\n .setBlendFuncRGB('one', 'src-alpha')\r\n .setBlendFuncAlpha('zero', 'one');\r\n this._compositeRenderStates.useDepthState().enableTest(false).enableWrite(false);\r\n }\r\n return this._compositeProgram;\r\n }\r\n\r\n protected onDispose() {\r\n super.onDispose();\r\n this.releaseFramebuffers();\r\n }\r\n}\r\n"],"names":["DEPTH_FORMAT","ACCUM_FORMAT","COLOR_ATTACHMENT_BYTES_PER_SAMPLE","DualDepthPeelingOIT","Disposable","type","DEPTH_CLEAR","Vector4","FRONT_CLEAR","BACK_CLEAR","_compositeProgram","_compositeBindGroup","_compositeRenderStates","_numPeels","_currentPass","_hash","_depthTargets","_frontTarget","_backTarget","_framebuffers","_device","numPeels","Math","max","floor","val","supportDeviceCaps","deviceType","caps","framebufferCaps","textureCaps","shaderCaps","miscCaps","webgl2OrBetter","maxUniformBufferSize","maxDrawBuffers","supportPerTargetBlending","maxColorAttachmentBytesPerSample","supportBlendMinMax","supportHalfFloatColorBuffer","supportFloatColorBuffer","supportFloatBlending","getType","supportDevice","device","tryGetApp","getDeviceCaps","wantsPremultipliedAlpha","wantsAdditiveLightPassAlpha","begin","ctx","releaseFramebuffers","depthTexture","createFramebuffers","end","composite","beginPass","pass","targetIndex","currentDepthTarget","previousDepthTarget","framebuffer","uid","pushDeviceStates","setFramebuffer","clearFrameBuffer","endPass","_pass","popDeviceStates","setupFragmentOutput","scope","pb","$builder","$outputs","Z_DDP_depth","vec2","Z_DDP_frontColor","vec4","Z_DDP_backColor","Z_DDP_depthTexture","tex2D","uniform","noSampler","outputFragmentColor","color","$l","Z_DDP_normDepth","REVERSE_Z","sub","$builtins","fragCoord","z","neg","Z_DDP_prevDepth","textureLoad","ivec2","xy","Z_DDP_frontDepth","x","Z_DDP_backDepth","y","Z_DDP_curDepth","Z_DDP_outputColor","rgb","lightBlending","float","a","$if","or","lessThan","add","greaterThan","discard","$elseif","and","$else","applyUniforms","_ctx","bindGroup","setTexture","calculateHash","setRenderStates","rs","useBlendingState","enable","enableAlphaToCoverage","useDepthState","enableTest","enableWrite","useTargetBlendingState","setBlendEquation","setBlendFunc","setBlendFuncRGB","setBlendFuncAlpha","width","height","depthTarget0","pool","fetchTemporalTexture2D","depthTarget1","frontTarget","backTarget","framebuffer0","createTemporalFramebuffer","framebuffer1","releaseTexture","currentFramebuffer","getFramebuffer","colorAttachment","getColorAttachments","singleColorFramebuffer","length","fetchTemporalFramebuffer","getDepthAttachment","viewport","getViewport","scissor","getScissor","setViewport","setScissor","setProgram","getCompositeProgram","setBindGroup","drawFullscreenQuad","releaseFrameBuffer","buildRenderProgram","vertex","$inputs","pos","attrib","uv","main","position","DEPTH_FARTHEST","mul","fragment","outColor","frontTex","backTex","frontColor","textureSample","backColor","remainingAlpha","clamp","name","createBindGroup","bindGroupLayouts","createRenderStateSet","onDispose"],"mappings":"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"}
|
package/dist/render/envlight.js
CHANGED
|
@@ -1,7 +1,60 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Matrix4x4, DRef, Vector3, Vector2, Vector4, REVERSE_Z, Disposable } from '@zephyr3d/base';
|
|
2
2
|
import { getSamplerOptions, fetchSampler } from '../utility/misc.js';
|
|
3
3
|
import { getDevice } from '../app/api.js';
|
|
4
|
+
import { decodeNormalizedFloatFromRGBA } from '../shaders/misc.js';
|
|
4
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Depth-proportional term of the SSGI history rejection tolerance.
|
|
8
|
+
*
|
|
9
|
+
* The surface history stores `linearDepth * cameraFar` in an `rgba16f` alpha
|
|
10
|
+
* channel, so its quantization error grows with depth: fp16 carries ~11 bits of
|
|
11
|
+
* mantissa, giving a relative error near 4.9e-4 (~0.49 world units at a depth of
|
|
12
|
+
* 1000). A purely absolute tolerance is therefore unusable in the distance -- at
|
|
13
|
+
* `ssgiDepthReject`'s 0.5 default, storage quantization alone consumes the whole
|
|
14
|
+
* budget and the test degenerates into dithered noise. This factor keeps roughly
|
|
15
|
+
* 4x headroom over that error while staying far below the depth step of a real
|
|
16
|
+
* disocclusion.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/ const SSGI_DEPTH_TOLERANCE_RELATIVE = 2e-3;
|
|
20
|
+
/**
|
|
21
|
+
* Multiple of the scaled tolerance at which history is dropped outright.
|
|
22
|
+
*
|
|
23
|
+
* Inside this gate the depth term contributes a smooth `exp(-d/tol)` weight
|
|
24
|
+
* rather than a boolean, so confidence decays continuously instead of flipping.
|
|
25
|
+
* At 3x the weight is already down to ~0.05, making the cutoff visually
|
|
26
|
+
* continuous -- which is what keeps a rejection boundary from reading as a
|
|
27
|
+
* staircase after nearest-neighbour sampling quantizes it to texel steps.
|
|
28
|
+
*
|
|
29
|
+
* @internal
|
|
30
|
+
*/ const SSGI_DEPTH_GATE_SCALE = 3;
|
|
31
|
+
/**
|
|
32
|
+
* Clamp distance, in texels, at which history repair reaches its widest radius.
|
|
33
|
+
*
|
|
34
|
+
* The clamp distance says how far the reprojection had to travel to get back on
|
|
35
|
+
* screen, which is a direct measure of how unrelated to this pixel the surviving
|
|
36
|
+
* history is. It scales the repair radius rather than gating repair off: the
|
|
37
|
+
* lighting pass only ever sees the previous frame, so a pixel rotating in from
|
|
38
|
+
* off screen has no fresh data anywhere and both alternatives to spreading the
|
|
39
|
+
* taps look worse than the blur does.
|
|
40
|
+
*
|
|
41
|
+
* @internal
|
|
42
|
+
*/ const SSGI_REPAIR_WIDE_CLAMP_TEXELS = 8;
|
|
43
|
+
/**
|
|
44
|
+
* Repair tap radius in texels, from an interior hole to a camera-edge one.
|
|
45
|
+
*
|
|
46
|
+
* The radius is what trades structure against smoothness. At one texel the taps
|
|
47
|
+
* of neighbouring pixels barely overlap, so detail survives -- correct for a hole
|
|
48
|
+
* in the middle of the screen, where the reprojection landed near its true
|
|
49
|
+
* position. Wide taps instead overlap heavily between neighbours, which turns the
|
|
50
|
+
* one strip of history that survives at a screen edge into a smooth low-frequency
|
|
51
|
+
* estimate of the surface's irradiance rather than a per-column copy of single
|
|
52
|
+
* texels, and copying single texels is what draws streaks along the direction of
|
|
53
|
+
* travel.
|
|
54
|
+
*
|
|
55
|
+
* @internal
|
|
56
|
+
*/ const SSGI_REPAIR_MIN_RADIUS_TEXELS = 1;
|
|
57
|
+
const SSGI_REPAIR_MAX_RADIUS_TEXELS = 16;
|
|
5
58
|
/**
|
|
6
59
|
* Base class for any kind of environment light
|
|
7
60
|
* @public
|
|
@@ -16,6 +69,19 @@ import { getDevice } from '../app/api.js';
|
|
|
16
69
|
/** @internal */ static UNIFORM_NAME_IBL_RADIANCE_MAP_MAX_LOD = 'zIBLRadianceMapMaxLOD';
|
|
17
70
|
/** @internal */ static UNIFORM_NAME_IBL_IRRADIANCE_SH = 'zIBLIrradianceSH';
|
|
18
71
|
/** @internal */ static UNIFORM_NAME_IBL_IRRADIANCE_WINDOW = 'zIBLIrradianceWindow';
|
|
72
|
+
/** @internal */ static UNIFORM_NAME_SSGI_IRRADIANCE = 'zSSGIPreviousIrradiance';
|
|
73
|
+
/** @internal */ static UNIFORM_NAME_SSGI_SURFACE = 'zSSGIPreviousSurface';
|
|
74
|
+
/** @internal */ static UNIFORM_NAME_SSGI_CURRENT_DEPTH = 'zSSGICurrentDepth';
|
|
75
|
+
/** @internal */ static UNIFORM_NAME_SSGI_MOTION = 'zSSGICurrentMotion';
|
|
76
|
+
/** @internal */ static UNIFORM_NAME_SSGI_TARGET_SIZE = 'zSSGITargetSize';
|
|
77
|
+
/** @internal */ static UNIFORM_NAME_SSGI_REPROJECTION = 'zSSGIReprojection';
|
|
78
|
+
/**
|
|
79
|
+
* Transforms a current-frame view-space position into previous-frame clip
|
|
80
|
+
* space, so the reprojected depth can be compared against the surface history
|
|
81
|
+
* in the frame that history was written in. @internal
|
|
82
|
+
*/ static UNIFORM_NAME_SSGI_VIEW_TO_PREV_CLIP = 'zSSGIViewToPrevClip';
|
|
83
|
+
/** Unprojects a screen-space sample back into current view space. @internal */ static UNIFORM_NAME_SSGI_INV_PROJECTION = 'zSSGIInvProjection';
|
|
84
|
+
/** Scratch for the view -> previous clip composition. @internal */ static _viewToPrevClip = new Matrix4x4();
|
|
19
85
|
/** @internal */ _radianceMap;
|
|
20
86
|
/** @internal */ _sheenRadianceMap;
|
|
21
87
|
/** @internal */ _irradianceSH;
|
|
@@ -72,7 +138,7 @@ import { getDevice } from '../app/api.js';
|
|
|
72
138
|
/**
|
|
73
139
|
* {@inheritDoc EnvironmentLighting.initShaderBindings}
|
|
74
140
|
* @override
|
|
75
|
-
*/ initShaderBindings(pb) {
|
|
141
|
+
*/ initShaderBindings(pb, ctx) {
|
|
76
142
|
if (pb.shaderKind === 'fragment') {
|
|
77
143
|
if (this.radianceMap) {
|
|
78
144
|
// Prefiltered radiance cube: mipmap chain indexed by roughness
|
|
@@ -96,12 +162,25 @@ import { getDevice } from '../app/api.js';
|
|
|
96
162
|
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_IRRADIANCE_SH] = pb.vec4[9]().uniformBuffer(0);
|
|
97
163
|
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_IBL_IRRADIANCE_WINDOW] = pb.vec3().uniform(0);
|
|
98
164
|
}
|
|
165
|
+
if (EnvShIBL.hasSSGIHistory(ctx)) {
|
|
166
|
+
const irradianceSampler = pb.getDevice().type === 'webgl' ? 'clamp_nearest_nomip' : 'clamp_linear_nomip';
|
|
167
|
+
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_IRRADIANCE] = pb.tex2D().uniform(0).withSampler(getSamplerOptions(irradianceSampler));
|
|
168
|
+
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_SURFACE] = pb.tex2D().uniform(0).withSampler(getSamplerOptions('clamp_nearest_nomip'));
|
|
169
|
+
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_CURRENT_DEPTH] = pb.tex2D().uniform(0).withSampler(getSamplerOptions('clamp_nearest_nomip'));
|
|
170
|
+
if (ctx?.motionVectorTexture) {
|
|
171
|
+
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_MOTION] = pb.tex2D().uniform(0).withSampler(getSamplerOptions('clamp_nearest_nomip'));
|
|
172
|
+
}
|
|
173
|
+
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_TARGET_SIZE] = pb.vec2().uniform(0);
|
|
174
|
+
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_REPROJECTION] = pb.vec4().uniform(0);
|
|
175
|
+
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_VIEW_TO_PREV_CLIP] = pb.mat4().uniform(0);
|
|
176
|
+
pb.getGlobalScope()[EnvShIBL.UNIFORM_NAME_SSGI_INV_PROJECTION] = pb.mat4().uniform(0);
|
|
177
|
+
}
|
|
99
178
|
}
|
|
100
179
|
}
|
|
101
180
|
/**
|
|
102
181
|
* {@inheritDoc EnvironmentLighting.updateBindGroup}
|
|
103
182
|
* @override
|
|
104
|
-
*/ updateBindGroup(bg) {
|
|
183
|
+
*/ updateBindGroup(bg, ctx) {
|
|
105
184
|
if (this.radianceMap) {
|
|
106
185
|
bg.setValue(EnvShIBL.UNIFORM_NAME_IBL_RADIANCE_MAP_MAX_LOD, this.radianceMap.mipLevelCount - 1);
|
|
107
186
|
bg.setTexture(EnvShIBL.UNIFORM_NAME_IBL_RADIANCE_MAP, this.radianceMap);
|
|
@@ -116,6 +195,24 @@ import { getDevice } from '../app/api.js';
|
|
|
116
195
|
bg.setBuffer(EnvShIBL.UNIFORM_NAME_IBL_IRRADIANCE_SH, this.irradianceSH);
|
|
117
196
|
bg.setValue(EnvShIBL.UNIFORM_NAME_IBL_IRRADIANCE_WINDOW, this.irradianceWindow);
|
|
118
197
|
}
|
|
198
|
+
if (EnvShIBL.hasSSGIHistory(ctx)) {
|
|
199
|
+
bg.setTexture(EnvShIBL.UNIFORM_NAME_SSGI_IRRADIANCE, ctx.SSGIIrradianceHistoryTexture, fetchSampler(ctx.device.type === 'webgl' ? 'clamp_nearest_nomip' : 'clamp_linear_nomip'));
|
|
200
|
+
bg.setTexture(EnvShIBL.UNIFORM_NAME_SSGI_SURFACE, ctx.SSGISurfaceHistoryTexture, fetchSampler('clamp_nearest_nomip'));
|
|
201
|
+
bg.setTexture(EnvShIBL.UNIFORM_NAME_SSGI_CURRENT_DEPTH, ctx.linearDepthTexture, fetchSampler('clamp_nearest_nomip'));
|
|
202
|
+
if (ctx.motionVectorTexture) {
|
|
203
|
+
bg.setTexture(EnvShIBL.UNIFORM_NAME_SSGI_MOTION, ctx.motionVectorTexture, fetchSampler('clamp_nearest_nomip'));
|
|
204
|
+
}
|
|
205
|
+
bg.setValue(EnvShIBL.UNIFORM_NAME_SSGI_TARGET_SIZE, new Vector2(ctx.renderWidth, ctx.renderHeight));
|
|
206
|
+
bg.setValue(EnvShIBL.UNIFORM_NAME_SSGI_REPROJECTION, new Vector4(ctx.camera.ssgiDepthReject, ctx.camera.ssgiNormalReject, ctx.camera.getFarPlane(), ctx.camera.getNearPlane()));
|
|
207
|
+
// View -> world -> previous clip. `prevVPMatrix` is null on the first frame
|
|
208
|
+
// after a history reset; falling back to the current VP makes the expected
|
|
209
|
+
// previous depth equal the current one, so the depth term is a no-op until
|
|
210
|
+
// a real previous frame exists.
|
|
211
|
+
const prevVP = ctx.camera.prevVPMatrix ?? ctx.camera.viewProjectionMatrix;
|
|
212
|
+
Matrix4x4.multiply(prevVP, ctx.camera.worldMatrix, EnvShIBL._viewToPrevClip);
|
|
213
|
+
bg.setValue(EnvShIBL.UNIFORM_NAME_SSGI_VIEW_TO_PREV_CLIP, EnvShIBL._viewToPrevClip);
|
|
214
|
+
bg.setValue(EnvShIBL.UNIFORM_NAME_SSGI_INV_PROJECTION, ctx.camera.getInvProjectionMatrix());
|
|
215
|
+
}
|
|
119
216
|
}
|
|
120
217
|
/**
|
|
121
218
|
* {@inheritDoc EnvironmentLighting.getRadiance}
|
|
@@ -134,7 +231,7 @@ import { getDevice } from '../app/api.js';
|
|
|
134
231
|
/**
|
|
135
232
|
* {@inheritDoc EnvironmentLighting.getIrradiance}
|
|
136
233
|
* @override
|
|
137
|
-
*/ getIrradiance(scope, normal) {
|
|
234
|
+
*/ getIrradiance(scope, normal, ctx) {
|
|
138
235
|
const pb = scope.$builder;
|
|
139
236
|
const that = this;
|
|
140
237
|
pb.func('Z_sh_Y0', [
|
|
@@ -209,7 +306,203 @@ import { getDevice } from '../app/api.js';
|
|
|
209
306
|
}
|
|
210
307
|
this.$return(this.c);
|
|
211
308
|
});
|
|
212
|
-
|
|
309
|
+
const iblIrradiance = pb.getGlobalScope().Z_sh_eval(normal);
|
|
310
|
+
if (!EnvShIBL.hasSSGIHistory(ctx)) {
|
|
311
|
+
return iblIrradiance;
|
|
312
|
+
}
|
|
313
|
+
const useMotionReprojection = !!ctx?.motionVectorTexture;
|
|
314
|
+
pb.func('Z_ssgi_reprojectIrradiance', [
|
|
315
|
+
pb.vec3('currentNormal'),
|
|
316
|
+
pb.vec3('ibl')
|
|
317
|
+
], function() {
|
|
318
|
+
this.$l.uv = pb.div(pb.vec2(this.$builtins.fragCoord.xy), this[EnvShIBL.UNIFORM_NAME_SSGI_TARGET_SIZE]);
|
|
319
|
+
if (useMotionReprojection) {
|
|
320
|
+
this.$l.motion = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_MOTION], this.uv, 0).xy;
|
|
321
|
+
this.$l.previousUV = pb.sub(this.uv, this.motion);
|
|
322
|
+
this.$l.motionValid = pb.not(pb.any(pb.greaterThanEqual(pb.abs(this.motion), pb.vec2(5e4))));
|
|
323
|
+
} else {
|
|
324
|
+
this.$l.previousUV = this.uv;
|
|
325
|
+
this.$l.motionValid = pb.bool(true);
|
|
326
|
+
}
|
|
327
|
+
this.$l.params = this[EnvShIBL.UNIFORM_NAME_SSGI_REPROJECTION];
|
|
328
|
+
this.$l.fallback = pb.mul(this.ibl, this.light.envLightStrength);
|
|
329
|
+
this.$l.normalizedCurrentNormal = pb.normalize(this.currentNormal);
|
|
330
|
+
this.$l.depthTolerance = pb.max(this.params.x, 1e-4);
|
|
331
|
+
this.$l.texelSize = pb.div(pb.vec2(1), this[EnvShIBL.UNIFORM_NAME_SSGI_TARGET_SIZE]);
|
|
332
|
+
this.$l.halfTexel = pb.mul(this.texelSize, 0.5);
|
|
333
|
+
this.$l.maxUV = pb.sub(pb.vec2(1), this.halfTexel);
|
|
334
|
+
this.$l.previousUVInBounds = pb.and(this.motionValid, pb.all(pb.greaterThanEqual(this.previousUV, pb.vec2(0))), pb.all(pb.lessThanEqual(this.previousUV, pb.vec2(1))));
|
|
335
|
+
this.$l.previousSampleUV = pb.clamp(this.previousUV, this.halfTexel, this.maxUV);
|
|
336
|
+
this.$l.previousSurface = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_SURFACE], this.previousSampleUV, 0);
|
|
337
|
+
this.$l.previousNormal = pb.normalize(pb.sub(pb.mul(this.previousSurface.rgb, 2), pb.vec3(1)));
|
|
338
|
+
this.$l.currentDepthSample = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_CURRENT_DEPTH], this.uv, 0);
|
|
339
|
+
this.$l.currentDepth = pb.mul(pb.getDevice().type === 'webgl' ? decodeNormalizedFloatFromRGBA(this, this.currentDepthSample) : this.currentDepthSample.r, this.params.z);
|
|
340
|
+
// The surface history holds a Z measured in the *previous* frame's view
|
|
341
|
+
// space, so the current Z cannot be compared against it directly: under
|
|
342
|
+
// camera rotation a static, correctly reprojected point has
|
|
343
|
+
// `dz ~ r * sin(theta) * dphi`, which crosses any fixed threshold at the
|
|
344
|
+
// screen edges and drops history in the exact staircase pattern that
|
|
345
|
+
// nearest-neighbour sampling of the reprojected UV produces. Rebuild the
|
|
346
|
+
// current view-space position and push it through `view -> previous clip`
|
|
347
|
+
// instead; `clip.w` is `-view.z`, i.e. the same positive view-space
|
|
348
|
+
// distance the history stores.
|
|
349
|
+
this.$l.ndc = pb.sub(pb.mul(this.uv, 2), pb.vec2(1));
|
|
350
|
+
this.$l.nearPlaneRay = pb.mul(this[EnvShIBL.UNIFORM_NAME_SSGI_INV_PROJECTION], pb.vec4(this.ndc, REVERSE_Z ? 1 : -1, 1));
|
|
351
|
+
// Perspective unprojection of the near-plane NDC depth (GL -1, reverse
|
|
352
|
+
// ZO 1) lands on the near plane, where view z is exactly -near; scaling
|
|
353
|
+
// that ray by depth/near walks it out to the sample without a
|
|
354
|
+
// non-linear depth round trip.
|
|
355
|
+
this.$l.viewPos = pb.mul(pb.div(this.nearPlaneRay.xyz, this.nearPlaneRay.w), pb.div(this.currentDepth, pb.max(this.params.w, 1e-6)));
|
|
356
|
+
this.$l.expectedPreviousDepth = pb.mul(this[EnvShIBL.UNIFORM_NAME_SSGI_VIEW_TO_PREV_CLIP], pb.vec4(this.viewPos, 1)).w;
|
|
357
|
+
this.$l.depthDelta = pb.abs(pb.sub(this.previousSurface.a, this.expectedPreviousDepth));
|
|
358
|
+
// fp16 storage error scales with depth, so the tolerance has to as well.
|
|
359
|
+
this.$l.scaledDepthTolerance = pb.add(this.depthTolerance, pb.mul(this.currentDepth, SSGI_DEPTH_TOLERANCE_RELATIVE));
|
|
360
|
+
this.$l.depthWeight = pb.exp(pb.neg(pb.div(this.depthDelta, this.scaledDepthTolerance)));
|
|
361
|
+
this.$l.depthValid = pb.lessThanEqual(this.depthDelta, pb.mul(this.scaledDepthTolerance, SSGI_DEPTH_GATE_SCALE));
|
|
362
|
+
this.$l.normalValid = pb.greaterThanEqual(pb.dot(this.normalizedCurrentNormal, this.previousNormal), this.params.y);
|
|
363
|
+
this.$l.previousIrradiance = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_IRRADIANCE], this.previousSampleUV, 0);
|
|
364
|
+
this.$l.previousAlpha = pb.clamp(this.previousIrradiance.a, 0, 1);
|
|
365
|
+
this.$l.exactHistoryValid = pb.and(this.previousUVInBounds, this.depthValid, this.normalValid, pb.greaterThan(this.previousAlpha, 1e-4));
|
|
366
|
+
this.$if(this.exactHistoryValid, function() {
|
|
367
|
+
// Weighting confidence by the depth term keeps the gate boundary a ramp
|
|
368
|
+
// rather than a step, so residual reprojection error on moving geometry
|
|
369
|
+
// and grazing surfaces fades out instead of outlining itself.
|
|
370
|
+
this.$l.exactConfidence = pb.mul(this.previousAlpha, this.depthWeight);
|
|
371
|
+
this.$if(pb.greaterThan(this.exactConfidence, 1e-4), function() {
|
|
372
|
+
this.$return(pb.mix(this.fallback, this.previousIrradiance.rgb, this.exactConfidence));
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
// Repair disoccluded and off-screen history from nearby samples before
|
|
376
|
+
// falling back to IBL. Sampling around the clamped reprojected position
|
|
377
|
+
// fills camera-edge holes, while current UV provides a conservative
|
|
378
|
+
// screen-stationary candidate for invalid motion vectors.
|
|
379
|
+
this.$l.repairCenter = this.$choice(this.motionValid, this.previousSampleUV, pb.clamp(this.uv, this.halfTexel, this.maxUV));
|
|
380
|
+
// How far the reprojection had to be clamped to land back on screen. For a
|
|
381
|
+
// hole in the interior this is zero and the taps really are neighbours of
|
|
382
|
+
// the reprojected point, but for geometry rotating in from off screen the
|
|
383
|
+
// clamp can travel hundreds of pixels -- and the depth and normal terms
|
|
384
|
+
// cannot catch that, because the edge texel it lands on is usually the same
|
|
385
|
+
// continuous surface (same normal, similar depth) merely sampled somewhere
|
|
386
|
+
// spatially unrelated. Its irradiance therefore belongs to a different part
|
|
387
|
+
// of the surface, so reading it as a point sample smears into streaks along
|
|
388
|
+
// the direction of travel. Drive the tap radius with it instead, trading
|
|
389
|
+
// that structure for a blur.
|
|
390
|
+
this.$l.repairClampTexels = pb.div(pb.length(pb.sub(this.previousSampleUV, this.previousUV)), pb.max(pb.min(this.texelSize.x, this.texelSize.y), 1e-8));
|
|
391
|
+
// Widen the taps as the clamp travel grows. Only meaningful while the motion
|
|
392
|
+
// vector is usable: without one the centre is already the current UV by
|
|
393
|
+
// construction, so there is no travel to react to.
|
|
394
|
+
this.$l.repairRadius = pb.mix(pb.float(SSGI_REPAIR_MIN_RADIUS_TEXELS), pb.float(SSGI_REPAIR_MAX_RADIUS_TEXELS), this.$choice(this.motionValid, pb.smoothStep(0, SSGI_REPAIR_WIDE_CLAMP_TEXELS, this.repairClampTexels), pb.float(0)));
|
|
395
|
+
// Taps this far apart straddle real depth variation across the surface, so a
|
|
396
|
+
// gate tuned for immediate neighbours would reject most of them and bring
|
|
397
|
+
// the dark band back. Loosen it with the radius and lean on the normal term,
|
|
398
|
+
// which stays strict, to keep the average on one surface.
|
|
399
|
+
this.$l.repairDepthTolerance = pb.mul(this.scaledDepthTolerance, SSGI_DEPTH_GATE_SCALE, pb.add(1, this.repairRadius));
|
|
400
|
+
this.$l.repairSum = pb.vec3(0);
|
|
401
|
+
this.$l.repairWeight = pb.float(0);
|
|
402
|
+
// A full ring rather than a cross: at the wide end four taps are not an
|
|
403
|
+
// average but four distant point copies, and their axis alignment paints
|
|
404
|
+
// directional artifacts of its own.
|
|
405
|
+
const repairSamples = [
|
|
406
|
+
{
|
|
407
|
+
currentUV: false,
|
|
408
|
+
x: 0,
|
|
409
|
+
y: 0,
|
|
410
|
+
kernel: 1
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
currentUV: false,
|
|
414
|
+
x: -1,
|
|
415
|
+
y: 0,
|
|
416
|
+
kernel: 0.7
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
currentUV: false,
|
|
420
|
+
x: 1,
|
|
421
|
+
y: 0,
|
|
422
|
+
kernel: 0.7
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
currentUV: false,
|
|
426
|
+
x: 0,
|
|
427
|
+
y: -1,
|
|
428
|
+
kernel: 0.7
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
currentUV: false,
|
|
432
|
+
x: 0,
|
|
433
|
+
y: 1,
|
|
434
|
+
kernel: 0.7
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
currentUV: false,
|
|
438
|
+
x: -0.7071,
|
|
439
|
+
y: -0.7071,
|
|
440
|
+
kernel: 0.5
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
currentUV: false,
|
|
444
|
+
x: 0.7071,
|
|
445
|
+
y: -0.7071,
|
|
446
|
+
kernel: 0.5
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
currentUV: false,
|
|
450
|
+
x: -0.7071,
|
|
451
|
+
y: 0.7071,
|
|
452
|
+
kernel: 0.5
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
currentUV: false,
|
|
456
|
+
x: 0.7071,
|
|
457
|
+
y: 0.7071,
|
|
458
|
+
kernel: 0.5
|
|
459
|
+
},
|
|
460
|
+
{
|
|
461
|
+
currentUV: true,
|
|
462
|
+
x: 0,
|
|
463
|
+
y: 0,
|
|
464
|
+
kernel: 0.5
|
|
465
|
+
}
|
|
466
|
+
];
|
|
467
|
+
for(let i = 0; i < repairSamples.length; i++){
|
|
468
|
+
const sample = repairSamples[i];
|
|
469
|
+
const baseUV = sample.currentUV ? this.uv : this.repairCenter;
|
|
470
|
+
this.$l[`repairUV${i}`] = pb.add(baseUV, pb.mul(this.texelSize, pb.vec2(sample.x, sample.y), this.repairRadius));
|
|
471
|
+
this.$l[`repairUVValid${i}`] = pb.and(pb.all(pb.greaterThanEqual(this[`repairUV${i}`], this.halfTexel)), pb.all(pb.lessThanEqual(this[`repairUV${i}`], this.maxUV)));
|
|
472
|
+
this.$l[`repairSurface${i}`] = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_SURFACE], pb.clamp(this[`repairUV${i}`], this.halfTexel, this.maxUV), 0);
|
|
473
|
+
this.$l[`repairNormal${i}`] = pb.normalize(pb.sub(pb.mul(this[`repairSurface${i}`].rgb, 2), pb.vec3(1)));
|
|
474
|
+
// Compared against the reprojected depth, not the current one: the taps
|
|
475
|
+
// are samples of the previous frame's surface, so they live in the same
|
|
476
|
+
// space as `expectedPreviousDepth`.
|
|
477
|
+
this.$l[`repairDepthDelta${i}`] = pb.abs(pb.sub(this[`repairSurface${i}`].a, this.expectedPreviousDepth));
|
|
478
|
+
this.$l[`repairNormalDot${i}`] = pb.dot(this.normalizedCurrentNormal, this[`repairNormal${i}`]);
|
|
479
|
+
this.$l[`repairSurfaceValid${i}`] = pb.and(this[`repairUVValid${i}`], pb.lessThanEqual(this[`repairDepthDelta${i}`], this.repairDepthTolerance), pb.greaterThanEqual(this[`repairNormalDot${i}`], this.params.y));
|
|
480
|
+
this.$l[`repairIrradiance${i}`] = pb.textureSampleLevel(this[EnvShIBL.UNIFORM_NAME_SSGI_IRRADIANCE], pb.clamp(this[`repairUV${i}`], this.halfTexel, this.maxUV), 0);
|
|
481
|
+
// Same widening as the hard gate above: a falloff tuned for immediate
|
|
482
|
+
// neighbours decays to nothing across a wide tap and starves the average.
|
|
483
|
+
this.$l[`repairDepthWeight${i}`] = pb.exp(pb.neg(pb.div(this[`repairDepthDelta${i}`], this.repairDepthTolerance)));
|
|
484
|
+
this.$l[`repairNormalWeight${i}`] = pb.pow(pb.max(0, this[`repairNormalDot${i}`]), 8);
|
|
485
|
+
this.$l[`repairSampleWeight${i}`] = pb.mul(pb.float(this[`repairSurfaceValid${i}`]), pb.clamp(this[`repairIrradiance${i}`].a, 0, 1), this[`repairDepthWeight${i}`], this[`repairNormalWeight${i}`], // The screen-stationary tap only exists to cover unusable motion
|
|
486
|
+
// vectors; while motion is valid it is a history read at the wrong world
|
|
487
|
+
// point, which survives the depth term on any flat surface and leaves a
|
|
488
|
+
// stationary ghost.
|
|
489
|
+
sample.currentUV ? pb.float(pb.not(this.motionValid)) : pb.float(1), sample.kernel);
|
|
490
|
+
this.repairSum = pb.add(this.repairSum, pb.mul(this[`repairIrradiance${i}`].rgb, this[`repairSampleWeight${i}`]));
|
|
491
|
+
this.repairWeight = pb.add(this.repairWeight, this[`repairSampleWeight${i}`]);
|
|
492
|
+
}
|
|
493
|
+
this.$if(pb.greaterThan(this.repairWeight, 1e-4), function() {
|
|
494
|
+
this.$l.repairedIrradiance = pb.div(this.repairSum, this.repairWeight);
|
|
495
|
+
// Repaired samples are intentionally capped below full confidence so
|
|
496
|
+
// newly traced irradiance replaces the extrapolation on following frames.
|
|
497
|
+
this.$l.repairConfidence = pb.mul(pb.clamp(this.repairWeight, 0, 1), 0.85);
|
|
498
|
+
this.$return(pb.mix(this.fallback, this.repairedIrradiance, this.repairConfidence));
|
|
499
|
+
});
|
|
500
|
+
this.$return(this.fallback);
|
|
501
|
+
});
|
|
502
|
+
return scope.Z_ssgi_reprojectIrradiance(normal, iblIrradiance);
|
|
503
|
+
}
|
|
504
|
+
/** Whether all textures required by the lighting reprojection are scoped. @internal */ static hasSSGIHistory(ctx) {
|
|
505
|
+
return !!(ctx?.SSGI && ctx.SSGIIrradianceHistoryTexture && ctx.SSGISurfaceHistoryTexture && (ctx.device.type !== 'webgpu' || ctx.motionVectorTexture) && ctx.linearDepthTexture);
|
|
213
506
|
}
|
|
214
507
|
/**
|
|
215
508
|
* {@inheritDoc EnvironmentLighting.hasRadiance}
|