@zephyr3d/scene 0.9.18 → 0.9.20
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/convex_collider.js +320 -0
- package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
- package/dist/app/scriptregistry.js +124 -6
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +1 -0
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/camera/camera.js +240 -201
- package/dist/camera/camera.js.map +1 -1
- package/dist/index.d.ts +458 -9
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/material/meshmaterial.js +2 -2
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +11 -5
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lit.js +10 -0
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/shader/helper.js +138 -10
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/skin.js +4 -6
- package/dist/material/skin.js.map +1 -1
- package/dist/material/water.js +1 -1
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +177 -29
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/compositor.js +111 -204
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/motionblur.js +3 -0
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js +79 -0
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssr.js +238 -7
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +16 -15
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +121 -19
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +1 -1
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +7 -1
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js +52 -8
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +331 -0
- package/dist/render/dualdepthpeeling_oit.js.map +1 -0
- package/dist/render/envlight.js +6 -3
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/hzb.js +11 -4
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/lightpass.js +21 -12
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/renderer.js +7 -3
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +79 -0
- package/dist/render/rendergraph/blackboard.js.map +1 -0
- package/dist/render/rendergraph/device_pool_allocator.js +10 -1
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +41 -11
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +551 -201
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/rendergraph.js +29 -0
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +12 -2
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +297 -0
- package/dist/render/shadow_mask_pass.js.map +1 -0
- package/dist/render/weightedblended_oit.js +5 -0
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +1 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +1 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +1 -0
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/msdftext.js +1 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +1 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +1 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +1 -0
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +1 -0
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +1 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +1 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/ssr.js +52 -21
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/utility/misc.js +10 -1
- package/dist/utility/misc.js.map +1 -1
- package/dist/utility/serialization/manager.js +1 -0
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +1 -0
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +1 -0
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +35 -2
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +1 -0
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +1 -0
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +1 -0
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +1 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +1 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +1 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +1 -0
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +1 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +1 -0
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/values.js +11 -1
- package/dist/values.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"posteffect.js","sources":["../../src/posteffect/posteffect.ts"],"sourcesContent":["import type { AbstractDevice, CompareFunc, RenderStateSet, Texture2D } from '@zephyr3d/device';\r\nimport type { DrawContext } from '../render';\r\nimport { drawFullscreenQuad } from '../render/fullscreenquad';\r\nimport { copyTexture, fetchSampler } from '../utility/misc';\r\nimport { Disposable } from '@zephyr3d/base';\r\n\r\n/**\r\n * Rendering layer of post processing effects\r\n * @public\r\n *\r\n */\r\nexport enum PostEffectLayer {\r\n opaque = 0,\r\n transparent = 1,\r\n end = 2\r\n}\r\n\r\n/**\r\n * Base class for any type of post effect\r\n * @public\r\n */\r\nexport class AbstractPostEffect extends Disposable {\r\n private static _defaultRenderStates: { CompareFunc?: RenderStateSet } = {};\r\n protected _enabled: boolean;\r\n protected _layer: PostEffectLayer;\r\n /**\r\n * Creates an instance of a post effect\r\n * @param name - Name of the post effect\r\n */\r\n constructor() {\r\n super();\r\n this._enabled = true;\r\n this._layer = PostEffectLayer.end;\r\n }\r\n /** Whether this post effect is enabled */\r\n get enabled() {\r\n return this._enabled;\r\n }\r\n set enabled(val) {\r\n this._enabled = !!val;\r\n }\r\n /** Whether this post effect will be rendered at opaque phase */\r\n get layer() {\r\n return this._layer;\r\n }\r\n /**\r\n * Check if the post effect should be rendered upside down.\r\n * @param device - The device object\r\n * @returns true if the post effect should be rendered upside down\r\n */\r\n needFlip(device: AbstractDevice) {\r\n return device.type === 'webgpu' && !!device.getFramebuffer();\r\n }\r\n /**\r\n * Checks whether this post effect requires the linear depth texture\r\n * @returns true if the linear depth texture is required.\r\n */\r\n requireLinearDepthTexture(_ctx: DrawContext) {\r\n return false;\r\n }\r\n /**\r\n * Checks whether this post effect requires the scene depth buffer\r\n * @returns true if the scene depth buffer is required.\r\n */\r\n requireDepthAttachment(_ctx: DrawContext) {\r\n return false;\r\n }\r\n /**\r\n * Apply the post effect\r\n * @param camera - Camera used the render the scene\r\n * @param inputColorTexture - The previous scene color texture\r\n * @param sceneDepthTexture - The linear scene depth texture\r\n * @param srgbOutput - Whether the result should be gamma corrected\r\n *\r\n * @remarks\r\n * The frame buffer of the post effect is already set when apply() is called.\r\n */\r\n apply(ctx: DrawContext, inputColorTexture: Texture2D, sceneDepthTexture: Texture2D, srgbOutput: boolean) {\r\n this.passThrough(ctx, inputColorTexture, srgbOutput);\r\n }\r\n /**\r\n *\r\n * @param ctx - Draw context\r\n * @param inputColorTexture - Input color texture\r\n * @param srgbOutput - Whether the result should be gamma corrected\r\n */\r\n protected passThrough(\r\n ctx: DrawContext,\r\n inputColorTexture: Texture2D,\r\n srgbOutput: boolean,\r\n renderStates?: RenderStateSet\r\n ) {\r\n copyTexture(\r\n inputColorTexture,\r\n ctx.device.getFramebuffer()!,\r\n fetchSampler('clamp_nearest_nomip'),\r\n renderStates,\r\n 0,\r\n srgbOutput\r\n );\r\n }\r\n /**\r\n * Draws a fullscreen quad\r\n * @param renderStateSet - Render states that will be used when drawing the fullscreen quad.\r\n */\r\n protected drawFullscreenQuad(renderStateSet?: RenderStateSet) {\r\n drawFullscreenQuad(renderStateSet);\r\n }\r\n /** @internal */\r\n protected createVertexLayout(device: AbstractDevice) {\r\n return device.createVertexLayout({\r\n vertexBuffers: [\r\n {\r\n buffer: device.createVertexBuffer('position_f32x2', new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]))!\r\n }\r\n ]\r\n });\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this.destroy();\r\n }\r\n /** @internal */\r\n protected createRenderStates(device: AbstractDevice) {\r\n const renderStates = device.createRenderStateSet();\r\n renderStates.useRasterizerState().setCullMode('none');\r\n renderStates.useDepthState().enableTest(false).enableWrite(false);\r\n return renderStates;\r\n }\r\n /** @internal */\r\n protected destroy() {}\r\n /** @internal */\r\n static getDefaultRenderState(ctx: DrawContext, compareFunc: CompareFunc) {\r\n let renderState = this._defaultRenderStates[compareFunc as keyof typeof this._defaultRenderStates];\r\n if (!renderState) {\r\n renderState = ctx.device.createRenderStateSet();\r\n renderState.useRasterizerState().setCullMode('none');\r\n renderState\r\n .useDepthState()\r\n .enableTest(compareFunc !== 'always')\r\n .enableWrite(false)\r\n .setCompareFunc(compareFunc);\r\n this._defaultRenderStates[compareFunc as keyof typeof this._defaultRenderStates] = renderState;\r\n }\r\n return renderState;\r\n }\r\n}\r\n"],"names":["PostEffectLayer","AbstractPostEffect","Disposable","_defaultRenderStates","_enabled","_layer","enabled","val","layer","needFlip","device","type","getFramebuffer","requireLinearDepthTexture","_ctx","requireDepthAttachment","apply","ctx","inputColorTexture","sceneDepthTexture","srgbOutput","passThrough","renderStates","copyTexture","fetchSampler","drawFullscreenQuad","renderStateSet","createVertexLayout","vertexBuffers","buffer","createVertexBuffer","Float32Array","onDispose","destroy","createRenderStates","createRenderStateSet","useRasterizerState","setCullMode","useDepthState","enableTest","enableWrite","getDefaultRenderState","compareFunc","renderState","setCompareFunc"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"posteffect.js","sources":["../../src/posteffect/posteffect.ts"],"sourcesContent":["import type { AbstractDevice, CompareFunc, RenderStateSet, Texture2D, TextureFormat } from '@zephyr3d/device';\r\nimport type { DrawContext } from '../render';\r\nimport { drawFullscreenQuad } from '../render/fullscreenquad';\r\nimport { copyTexture, fetchSampler } from '../utility/misc';\r\nimport { Disposable } from '@zephyr3d/base';\r\nimport type { Nullable } from '@zephyr3d/base';\r\nimport type { RenderGraph } from '../render/rendergraph/rendergraph';\r\nimport type { RGHandle, RGPassBuilder } from '../render/rendergraph/types';\r\nimport type { RGBlackboard } from '../render/rendergraph/blackboard';\r\nimport { FrameResources } from '../render/rendergraph/blackboard';\r\nimport type { HistoryResourceManager } from '../render/rendergraph/history_resource_manager';\r\n\r\n/**\r\n * Rendering layer of post processing effects\r\n * @public\r\n *\r\n */\r\nexport enum PostEffectLayer {\r\n opaque = 0,\r\n transparent = 1,\r\n end = 2\r\n}\r\n\r\n/**\r\n * History texture binding required while a post effect executes.\r\n * @public\r\n */\r\nexport interface PostEffectHistoryRead {\r\n /** History resource name (see {@link RGHistoryResources}). */\r\n name: string;\r\n /** Graph handle of the imported previous-frame texture. */\r\n handle: RGHandle;\r\n}\r\n\r\n/**\r\n * Output target of a post effect, created through {@link PostEffectSetupContext.createOutput}.\r\n * @public\r\n */\r\nexport interface PostEffectOutput {\r\n /** Color handle produced by this effect. Return it from {@link AbstractPostEffect.setup}. */\r\n color: RGHandle;\r\n /**\r\n * Graph framebuffer to render into, or null when the effect must render to the\r\n * device default framebuffer (screen).\r\n */\r\n framebuffer: Nullable<RGHandle>;\r\n /** Whether the effect must gamma-correct its final write. */\r\n srgbOutput: boolean;\r\n}\r\n\r\n/**\r\n * Build-time context handed to {@link AbstractPostEffect.setup}.\r\n *\r\n * The context carries everything an effect needs to declare its passes on the\r\n * render graph. Where the effect output physically lands (intermediate texture,\r\n * backbuffer or screen) is decided by {@link PostEffectSetupContext.createOutput};\r\n * effect implementations never deal with final-target selection themselves.\r\n *\r\n * @public\r\n */\r\nexport interface PostEffectSetupContext {\r\n /** The render graph being built for this frame. */\r\n readonly graph: RenderGraph;\r\n /** Frame draw context. Read configuration from it, never textures. */\r\n readonly ctx: DrawContext;\r\n /** Named frame resources (linear depth, motion vectors, GBuffer, ...). */\r\n readonly blackboard: RGBlackboard;\r\n /** Chain input: color output of the previous effect (or the scene color). */\r\n readonly input: RGHandle;\r\n /** Intermediate color format of the post effect chain. */\r\n readonly colorFormat: TextureFormat;\r\n /** Render width in pixels. */\r\n readonly width: number;\r\n /** Render height in pixels. */\r\n readonly height: number;\r\n /** Cross-frame history resources, or null when unavailable. */\r\n readonly history: Nullable<HistoryResourceManager<Texture2D>>;\r\n /**\r\n * Scene depth attachment for intermediate passes that depth-test against\r\n * scene depth: either a graph texture handle or a backend depth texture.\r\n * Pass it as the depthAttachment of intermediate framebuffers; the final\r\n * pass gets it through createOutput({needDepthAttachment: true}).\r\n */\r\n readonly sceneDepthAttachment: unknown;\r\n /**\r\n * Ordering/lifetime dependencies that every pass created by this effect must\r\n * declare with {@link RGPassBuilder.read}.\r\n * @internal\r\n */\r\n readonly dependencies: readonly RGHandle[];\r\n /**\r\n * History texture bindings that must be in a read scope while this effect\r\n * executes (legacy apply path).\r\n * @internal\r\n */\r\n readonly historyReads: readonly PostEffectHistoryRead[];\r\n /**\r\n * Create the output target for the effect's final pass.\r\n *\r\n * Must be called exactly once, inside the setup callback of the pass that\r\n * produces the effect's final color. The compositor decides whether this\r\n * resolves to an intermediate texture or a direct write to the final target.\r\n *\r\n * @param builder - The pass builder of the effect's final pass.\r\n * @param opts - Set needDepthAttachment when the pass depth-tests against scene depth.\r\n * @returns The resolved output target.\r\n */\r\n createOutput(builder: RGPassBuilder, opts?: { needDepthAttachment?: boolean }): PostEffectOutput;\r\n}\r\n\r\n/**\r\n * Base class for any type of post effect\r\n * @public\r\n */\r\nexport class AbstractPostEffect extends Disposable {\r\n private static _defaultRenderStates: { CompareFunc?: RenderStateSet } = {};\r\n protected _enabled: boolean;\r\n protected _layer: PostEffectLayer;\r\n /**\r\n * Creates an instance of a post effect\r\n * @param name - Name of the post effect\r\n */\r\n constructor() {\r\n super();\r\n this._enabled = true;\r\n this._layer = PostEffectLayer.end;\r\n }\r\n /** Whether this post effect is enabled */\r\n get enabled() {\r\n return this._enabled;\r\n }\r\n set enabled(val) {\r\n this._enabled = !!val;\r\n }\r\n /** Whether this post effect will be rendered at opaque phase */\r\n get layer() {\r\n return this._layer;\r\n }\r\n /**\r\n * Check if the post effect should be rendered upside down.\r\n * @param device - The device object\r\n * @returns true if the post effect should be rendered upside down\r\n */\r\n needFlip(device: AbstractDevice) {\r\n return device.type === 'webgpu' && !!device.getFramebuffer();\r\n }\r\n /**\r\n * Checks whether this post effect requires the linear depth texture\r\n * @returns true if the linear depth texture is required.\r\n */\r\n requireLinearDepthTexture(_ctx: DrawContext) {\r\n return false;\r\n }\r\n /**\r\n * Checks whether this post effect requires the scene depth buffer\r\n * @returns true if the scene depth buffer is required.\r\n */\r\n requireDepthAttachment(_ctx: DrawContext) {\r\n return false;\r\n }\r\n /**\r\n * Checks whether this post effect requires the motion vector texture\r\n * @returns true if the motion vector texture is required.\r\n */\r\n requireMotionVectorTexture(_ctx: DrawContext) {\r\n return false;\r\n }\r\n /**\r\n * Apply the post effect\r\n * @param camera - Camera used the render the scene\r\n * @param inputColorTexture - The previous scene color texture\r\n * @param sceneDepthTexture - The linear scene depth texture\r\n * @param srgbOutput - Whether the result should be gamma corrected\r\n *\r\n * @remarks\r\n * The frame buffer of the post effect is already set when apply() is called.\r\n */\r\n apply(ctx: DrawContext, inputColorTexture: Texture2D, sceneDepthTexture: Texture2D, srgbOutput: boolean) {\r\n this.passThrough(ctx, inputColorTexture, srgbOutput);\r\n }\r\n /**\r\n * Declare this effect's passes on the render graph.\r\n *\r\n * The default implementation wraps {@link AbstractPostEffect.apply} into a\r\n * single graph pass, so effects only overriding apply() work unchanged.\r\n * Multi-pass effects override this method to declare each internal step as\r\n * its own pass, calling {@link PostEffectSetupContext.createOutput} inside\r\n * the final pass.\r\n *\r\n * @param s - Build-time setup context.\r\n * @returns The effect's output color handle.\r\n */\r\n setup(s: PostEffectSetupContext): RGHandle {\r\n return this._setupFromApply(s);\r\n }\r\n /**\r\n * Wraps the legacy apply() entry into a single graph pass.\r\n * @internal\r\n */\r\n protected _setupFromApply(s: PostEffectSetupContext): RGHandle {\r\n const passName = `PostEffect:${this.constructor.name}`;\r\n return s.graph.addPass(passName, (builder) => {\r\n builder.read(s.input);\r\n for (const dep of s.dependencies) {\r\n builder.read(dep);\r\n }\r\n for (const binding of s.historyReads) {\r\n builder.read(binding.handle);\r\n }\r\n // Declare reads according to the effect's declared requirements so the\r\n // executor keeps exactly the textures this effect samples alive. Effects\r\n // reaching frame textures through DrawContext fields must declare them\r\n // via requireLinearDepthTexture / requireMotionVectorTexture.\r\n const linearDepthHandle = this.requireLinearDepthTexture(s.ctx)\r\n ? s.blackboard.get(FrameResources.LinearDepth)\r\n : null;\r\n if (linearDepthHandle) {\r\n builder.read(linearDepthHandle);\r\n }\r\n const motionVectorHandle = this.requireMotionVectorTexture(s.ctx)\r\n ? s.blackboard.get(FrameResources.MotionVector)\r\n : null;\r\n if (motionVectorHandle) {\r\n builder.read(motionVectorHandle);\r\n }\r\n const output = s.createOutput(builder, {\r\n needDepthAttachment: this.requireDepthAttachment(s.ctx)\r\n });\r\n builder.setExecute((rg) => {\r\n const device = s.ctx.device;\r\n const inputTexture = rg.getTexture<Texture2D>(s.input);\r\n const linearDepthTexture = linearDepthHandle\r\n ? rg.getTexture<Texture2D>(linearDepthHandle)\r\n : s.ctx.linearDepthTexture!;\r\n const applyEffect = () => {\r\n device.pushDeviceStates();\r\n try {\r\n device.setFramebuffer(output.framebuffer ? rg.getFramebuffer(output.framebuffer) : null);\r\n this.apply(s.ctx, inputTexture, linearDepthTexture, output.srgbOutput);\r\n } finally {\r\n device.popDeviceStates();\r\n }\r\n };\r\n if (s.history && s.historyReads.length > 0) {\r\n s.history.beginReadScope(\r\n s.historyReads.map((binding) => ({\r\n name: binding.name,\r\n texture: rg.getTexture<Texture2D>(binding.handle)\r\n }))\r\n );\r\n try {\r\n applyEffect();\r\n } finally {\r\n s.history.endReadScope();\r\n }\r\n } else {\r\n applyEffect();\r\n }\r\n });\r\n return output.color;\r\n });\r\n }\r\n /**\r\n *\r\n * @param ctx - Draw context\r\n * @param inputColorTexture - Input color texture\r\n * @param srgbOutput - Whether the result should be gamma corrected\r\n */\r\n protected passThrough(\r\n ctx: DrawContext,\r\n inputColorTexture: Texture2D,\r\n srgbOutput: boolean,\r\n renderStates?: RenderStateSet\r\n ) {\r\n copyTexture(\r\n inputColorTexture,\r\n ctx.device.getFramebuffer()!,\r\n fetchSampler('clamp_nearest_nomip'),\r\n renderStates,\r\n 0,\r\n srgbOutput\r\n );\r\n }\r\n /**\r\n * Draws a fullscreen quad\r\n * @param renderStateSet - Render states that will be used when drawing the fullscreen quad.\r\n */\r\n protected drawFullscreenQuad(renderStateSet?: RenderStateSet) {\r\n drawFullscreenQuad(renderStateSet);\r\n }\r\n /** @internal */\r\n protected createVertexLayout(device: AbstractDevice) {\r\n return device.createVertexLayout({\r\n vertexBuffers: [\r\n {\r\n buffer: device.createVertexBuffer('position_f32x2', new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]))!\r\n }\r\n ]\r\n });\r\n }\r\n protected onDispose() {\r\n super.onDispose();\r\n this.destroy();\r\n }\r\n /** @internal */\r\n protected createRenderStates(device: AbstractDevice) {\r\n const renderStates = device.createRenderStateSet();\r\n renderStates.useRasterizerState().setCullMode('none');\r\n renderStates.useDepthState().enableTest(false).enableWrite(false);\r\n return renderStates;\r\n }\r\n /** @internal */\r\n protected destroy() {}\r\n /** @internal */\r\n static getDefaultRenderState(ctx: DrawContext, compareFunc: CompareFunc) {\r\n let renderState = this._defaultRenderStates[compareFunc as keyof typeof this._defaultRenderStates];\r\n if (!renderState) {\r\n renderState = ctx.device.createRenderStateSet();\r\n renderState.useRasterizerState().setCullMode('none');\r\n renderState\r\n .useDepthState()\r\n .enableTest(compareFunc !== 'always')\r\n .enableWrite(false)\r\n .setCompareFunc(compareFunc);\r\n this._defaultRenderStates[compareFunc as keyof typeof this._defaultRenderStates] = renderState;\r\n }\r\n return renderState;\r\n }\r\n}\r\n"],"names":["PostEffectLayer","AbstractPostEffect","Disposable","_defaultRenderStates","_enabled","_layer","enabled","val","layer","needFlip","device","type","getFramebuffer","requireLinearDepthTexture","_ctx","requireDepthAttachment","requireMotionVectorTexture","apply","ctx","inputColorTexture","sceneDepthTexture","srgbOutput","passThrough","setup","s","_setupFromApply","passName","name","graph","addPass","builder","read","input","dep","dependencies","binding","historyReads","handle","linearDepthHandle","blackboard","get","FrameResources","LinearDepth","motionVectorHandle","MotionVector","output","createOutput","needDepthAttachment","setExecute","rg","inputTexture","getTexture","linearDepthTexture","applyEffect","pushDeviceStates","setFramebuffer","framebuffer","popDeviceStates","history","length","beginReadScope","map","texture","endReadScope","color","renderStates","copyTexture","fetchSampler","drawFullscreenQuad","renderStateSet","createVertexLayout","vertexBuffers","buffer","createVertexBuffer","Float32Array","onDispose","destroy","createRenderStates","createRenderStateSet","useRasterizerState","setCullMode","useDepthState","enableTest","enableWrite","getDefaultRenderState","compareFunc","renderState","setCompareFunc"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skinsss.js","sources":["../../src/posteffect/skinsss.ts"],"sourcesContent":["import { Vector2, Vector4 } from '@zephyr3d/base';\r\nimport type { BindGroup, GPUProgram, Texture2D } from '@zephyr3d/device';\r\nimport type { DrawContext } from '../render';\r\nimport { ShaderHelper } from '../material';\r\nimport { linearToGamma } from '../shaders/misc';\r\nimport { fetchSampler } from '../utility/misc';\r\nimport { AbstractPostEffect, PostEffectLayer } from './posteffect';\r\n\r\n/**\r\n * Stylized screen-space skin scattering pass.\r\n *\r\n * @remarks\r\n * This is intentionally separate from the profile-based {@link SSS} pass. It follows the simpler\r\n * depth-aware blur used by many character renderers: a skin material writes a lighting multiplier\r\n * into a side buffer, then this pass performs a fixed 9x9 depth-aware blur and composites it back\r\n * over the opaque color.\r\n *\r\n * @public\r\n */\r\nexport class SkinSSS extends AbstractPostEffect {\r\n private static _program: GPUProgram | null = null;\r\n private _bindGroup: BindGroup | null;\r\n private _strength: number;\r\n private _opacity: number;\r\n private _sampleStep: number;\r\n private _depthScale: number;\r\n private _colorBoost: number;\r\n\r\n constructor() {\r\n super();\r\n this._layer = PostEffectLayer.opaque;\r\n this._bindGroup = null;\r\n this._strength = 1;\r\n this._opacity = 0.18;\r\n this._sampleStep = 2;\r\n this._depthScale = 80;\r\n this._colorBoost = 1;\r\n }\r\n\r\n /** Final blend strength. */\r\n get strength() {\r\n return this._strength;\r\n }\r\n set strength(val) {\r\n this._strength = Math.max(0, val ?? 0);\r\n }\r\n\r\n /** Bias subtracted from the blurred skin mask before compositing. */\r\n get opacity() {\r\n return this._opacity;\r\n }\r\n set opacity(val) {\r\n this._opacity = Math.max(0, Math.min(1, val ?? 0));\r\n }\r\n\r\n /** Pixel spacing between blur taps. The reference shader uses 2. */\r\n get sampleStep() {\r\n return this._sampleStep;\r\n }\r\n set sampleStep(val) {\r\n this._sampleStep = Math.max(0.25, val ?? 0.25);\r\n }\r\n\r\n /** Depth rejection scale. The reference shader uses 80. */\r\n get depthScale() {\r\n return this._depthScale;\r\n }\r\n set depthScale(val) {\r\n this._depthScale = Math.max(0, val ?? 0);\r\n }\r\n\r\n /** Multiplier applied to the blurred skin lighting multiplier before compositing. */\r\n get colorBoost() {\r\n return this._colorBoost;\r\n }\r\n set colorBoost(val) {\r\n this._colorBoost = Math.max(0, val ?? 0);\r\n }\r\n\r\n requireLinearDepthTexture() {\r\n return true;\r\n }\r\n\r\n apply(ctx: DrawContext, inputColorTexture: Texture2D, sceneDepthTexture: Texture2D, srgbOutput: boolean) {\r\n if (!ctx.SkinSSSTexture || this._strength <= 0) {\r\n this.passThrough(ctx, inputColorTexture, srgbOutput);\r\n return;\r\n }\r\n const device = ctx.device;\r\n let program = SkinSSS._program;\r\n if (!program) {\r\n program = this.createProgram(ctx);\r\n SkinSSS._program = program;\r\n }\r\n if (!this._bindGroup) {\r\n this._bindGroup = device.createBindGroup(program.bindGroupLayouts[0]);\r\n }\r\n this._bindGroup.setTexture('colorTex', inputColorTexture, fetchSampler('clamp_linear'));\r\n this._bindGroup.setTexture('skinTex', ctx.SkinSSSTexture, fetchSampler('clamp_linear'));\r\n this._bindGroup.setTexture('depthTex', sceneDepthTexture, fetchSampler('clamp_nearest_nomip'));\r\n this._bindGroup.setValue('cameraNearFar', new Vector2(ctx.camera.getNearPlane(), ctx.camera.getFarPlane()));\r\n this._bindGroup.setValue(\r\n 'targetSize',\r\n new Vector4(inputColorTexture.width, inputColorTexture.height, inputColorTexture.width, inputColorTexture.height)\r\n );\r\n this._bindGroup.setValue('strength', this._strength);\r\n this._bindGroup.setValue('opacity', this._opacity);\r\n this._bindGroup.setValue('sampleStep', this._sampleStep);\r\n this._bindGroup.setValue('depthScale', this._depthScale);\r\n this._bindGroup.setValue('colorBoost', this._colorBoost);\r\n this._bindGroup.setValue('flip', this.needFlip(device) ? 1 : 0);\r\n this._bindGroup.setValue('srgbOut', srgbOutput ? 1 : 0);\r\n device.setProgram(program);\r\n device.setBindGroup(0, this._bindGroup);\r\n this.drawFullscreenQuad();\r\n }\r\n\r\n private createProgram(ctx: DrawContext) {\r\n const program = ctx.device.buildRenderProgram({\r\n vertex(pb) {\r\n this.flip = pb.int().uniform(0);\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 this.$if(pb.notEqual(this.flip, 0), function () {\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.colorTex = pb.tex2D().uniform(0);\r\n this.skinTex = pb.tex2D().uniform(0);\r\n this.depthTex = pb.tex2D().uniform(0);\r\n this.cameraNearFar = pb.vec2().uniform(0);\r\n this.targetSize = pb.vec4().uniform(0);\r\n this.strength = pb.float().uniform(0);\r\n this.opacity = pb.float().uniform(0);\r\n this.sampleStep = pb.float().uniform(0);\r\n this.depthScale = pb.float().uniform(0);\r\n this.colorBoost = pb.float().uniform(0);\r\n this.srgbOut = pb.int().uniform(0);\r\n this.$outputs.outColor = pb.vec4();\r\n pb.func('readDepth01', [pb.vec2('uv')], function () {\r\n this.$return(ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0));\r\n });\r\n pb.main(function () {\r\n this.$l.uv = this.$inputs.uv;\r\n this.$l.baseColor = pb.textureSampleLevel(this.colorTex, this.uv, 0);\r\n this.$l.result = this.baseColor.rgb;\r\n this.$l.centerDepth01 = this.readDepth01(this.uv);\r\n this.$if(pb.lessThan(this.centerDepth01, 1), function () {\r\n this.$l.centerDepth = pb.max(pb.mul(this.centerDepth01, this.cameraNearFar.y), 1e-4);\r\n this.$l.sum = pb.vec4(0);\r\n this.$l.weightSum = pb.float(0);\r\n this.$for(pb.int('y'), -4, 5, function () {\r\n this.$for(pb.int('x'), -4, 5, function () {\r\n this.$l.offsetPx = pb.mul(pb.vec2(pb.float(this.x), pb.float(this.y)), this.sampleStep);\r\n this.$l.sampleUV = pb.clamp(\r\n pb.add(this.uv, pb.div(this.offsetPx, this.targetSize.xy)),\r\n pb.vec2(0),\r\n pb.vec2(1)\r\n );\r\n this.$l.skinSample = pb.textureSampleLevel(this.skinTex, this.sampleUV, 0);\r\n this.$if(pb.lessThanEqual(this.skinSample.a, 1e-4), function () {\r\n this.skinSample = pb.vec4(0, 0, 0, this.opacity);\r\n });\r\n this.$l.sampleDepth01 = this.readDepth01(this.sampleUV);\r\n this.$l.sampleDepth = pb.max(pb.mul(this.sampleDepth01, this.cameraNearFar.y), 1e-4);\r\n this.$l.depthWeight = pb.clamp(\r\n pb.sub(\r\n 1,\r\n pb.div(\r\n pb.mul(pb.abs(pb.sub(this.centerDepth, this.sampleDepth)), this.depthScale),\r\n this.centerDepth\r\n )\r\n ),\r\n 0,\r\n 1\r\n );\r\n this.depthWeight = pb.mul(\r\n this.depthWeight,\r\n this.depthWeight,\r\n pb.sub(3, pb.mul(this.depthWeight, 2))\r\n );\r\n this.sum = pb.add(this.sum, pb.mul(this.skinSample, this.depthWeight));\r\n this.weightSum = pb.add(this.weightSum, this.depthWeight);\r\n });\r\n });\r\n this.$if(pb.greaterThan(this.weightSum, 1e-4), function () {\r\n this.$l.blurredSkin = pb.div(this.sum, this.weightSum);\r\n this.$l.alphaDelta = pb.sub(this.blurredSkin.a, this.opacity);\r\n this.$l.referenceLit = pb.mul(\r\n this.baseColor.rgb,\r\n pb.add(\r\n pb.vec3(pb.sub(1, this.alphaDelta)),\r\n pb.mul(this.blurredSkin.rgb, pb.max(pb.sub(1, this.opacity), 0), this.colorBoost)\r\n )\r\n );\r\n this.result = pb.add(\r\n this.baseColor.rgb,\r\n pb.mul(pb.sub(this.referenceLit, this.baseColor.rgb), this.strength)\r\n );\r\n });\r\n });\r\n this.$if(pb.equal(this.srgbOut, 0), function () {\r\n this.$outputs.outColor = pb.vec4(this.result, this.baseColor.a);\r\n }).$else(function () {\r\n this.$outputs.outColor = pb.vec4(linearToGamma(this, this.result), this.baseColor.a);\r\n });\r\n });\r\n }\r\n })!;\r\n program.name = '@SkinSSS';\r\n return program;\r\n }\r\n}\r\n"],"names":["SkinSSS","AbstractPostEffect","_program","_bindGroup","_strength","_opacity","_sampleStep","_depthScale","_colorBoost","_layer","PostEffectLayer","opaque","strength","val","Math","max","opacity","min","sampleStep","depthScale","colorBoost","requireLinearDepthTexture","apply","ctx","inputColorTexture","sceneDepthTexture","srgbOutput","SkinSSSTexture","passThrough","device","program","createProgram","createBindGroup","bindGroupLayouts","setTexture","fetchSampler","setValue","Vector2","camera","getNearPlane","getFarPlane","Vector4","width","height","needFlip","setProgram","setBindGroup","drawFullscreenQuad","buildRenderProgram","vertex","pb","flip","int","uniform","$inputs","pos","vec2","attrib","$outputs","uv","main","$builtins","position","vec4","add","mul","xy","$if","notEqual","y","neg","fragment","colorTex","tex2D","skinTex","depthTex","cameraNearFar","targetSize","float","srgbOut","outColor","func","$return","ShaderHelper","sampleLinearDepth","$l","baseColor","textureSampleLevel","result","rgb","centerDepth01","readDepth01","lessThan","centerDepth","sum","weightSum","$for","offsetPx","x","sampleUV","clamp","div","skinSample","lessThanEqual","a","sampleDepth01","sampleDepth","depthWeight","sub","abs","greaterThan","blurredSkin","alphaDelta","referenceLit","vec3","equal","$else","linearToGamma","name"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAQA;;;;;;;;;;IAWO,MAAMA,OAAgBC,SAAAA,kBAAAA,CAAAA;AAC3B,IAAA,OAAeC,WAA8B,IAAK;IAC1CC,UAA6B;IAC7BC,SAAkB;IAClBC,QAAiB;IACjBC,WAAoB;IACpBC,WAAoB;IACpBC,WAAoB;IAE5B,WAAc,EAAA;QACZ,KAAK,EAAA;AACL,QAAA,IAAI,CAACC,MAAM,GAAGC,eAAAA,CAAgBC,MAAM;QACpC,IAAI,CAACR,UAAU,GAAG,IAAA;QAClB,IAAI,CAACC,SAAS,GAAG,CAAA;QACjB,IAAI,CAACC,QAAQ,GAAG,IAAA;QAChB,IAAI,CAACC,WAAW,GAAG,CAAA;QACnB,IAAI,CAACC,WAAW,GAAG,EAAA;QACnB,IAAI,CAACC,WAAW,GAAG,CAAA;AACrB;iCAGA,IAAII,QAAW,GAAA;QACb,OAAO,IAAI,CAACR,SAAS;AACvB;IACA,IAAIQ,QAAAA,CAASC,GAAG,EAAE;AAChB,QAAA,IAAI,CAACT,SAAS,GAAGU,KAAKC,GAAG,CAAC,GAAGF,GAAO,IAAA,CAAA,CAAA;AACtC;0EAGA,IAAIG,OAAU,GAAA;QACZ,OAAO,IAAI,CAACX,QAAQ;AACtB;IACA,IAAIW,OAAAA,CAAQH,GAAG,EAAE;QACf,IAAI,CAACR,QAAQ,GAAGS,IAAKC,CAAAA,GAAG,CAAC,CAAA,EAAGD,IAAKG,CAAAA,GAAG,CAAC,CAAA,EAAGJ,GAAO,IAAA,CAAA,CAAA,CAAA;AACjD;yEAGA,IAAIK,UAAa,GAAA;QACf,OAAO,IAAI,CAACZ,WAAW;AACzB;IACA,IAAIY,UAAAA,CAAWL,GAAG,EAAE;AAClB,QAAA,IAAI,CAACP,WAAW,GAAGQ,KAAKC,GAAG,CAAC,MAAMF,GAAO,IAAA,IAAA,CAAA;AAC3C;gEAGA,IAAIM,UAAa,GAAA;QACf,OAAO,IAAI,CAACZ,WAAW;AACzB;IACA,IAAIY,UAAAA,CAAWN,GAAG,EAAE;AAClB,QAAA,IAAI,CAACN,WAAW,GAAGO,KAAKC,GAAG,CAAC,GAAGF,GAAO,IAAA,CAAA,CAAA;AACxC;0FAGA,IAAIO,UAAa,GAAA;QACf,OAAO,IAAI,CAACZ,WAAW;AACzB;IACA,IAAIY,UAAAA,CAAWP,GAAG,EAAE;AAClB,QAAA,IAAI,CAACL,WAAW,GAAGM,KAAKC,GAAG,CAAC,GAAGF,GAAO,IAAA,CAAA,CAAA;AACxC;IAEAQ,yBAA4B,GAAA;QAC1B,OAAO,IAAA;AACT;AAEAC,IAAAA,KAAAA,CAAMC,GAAgB,EAAEC,iBAA4B,EAAEC,iBAA4B,EAAEC,UAAmB,EAAE;QACvG,IAAI,CAACH,IAAII,cAAc,IAAI,IAAI,CAACvB,SAAS,IAAI,CAAG,EAAA;AAC9C,YAAA,IAAI,CAACwB,WAAW,CAACL,GAAAA,EAAKC,iBAAmBE,EAAAA,UAAAA,CAAAA;AACzC,YAAA;AACF;QACA,MAAMG,MAAAA,GAASN,IAAIM,MAAM;QACzB,IAAIC,OAAAA,GAAU9B,QAAQE,QAAQ;AAC9B,QAAA,IAAI,CAAC4B,OAAS,EAAA;YACZA,OAAU,GAAA,IAAI,CAACC,aAAa,CAACR,GAAAA,CAAAA;AAC7BvB,YAAAA,OAAAA,CAAQE,QAAQ,GAAG4B,OAAAA;AACrB;AACA,QAAA,IAAI,CAAC,IAAI,CAAC3B,UAAU,EAAE;YACpB,IAAI,CAACA,UAAU,GAAG0B,MAAAA,CAAOG,eAAe,CAACF,OAAAA,CAAQG,gBAAgB,CAAC,CAAE,CAAA,CAAA;AACtE;AACA,QAAA,IAAI,CAAC9B,UAAU,CAAC+B,UAAU,CAAC,UAAA,EAAYV,mBAAmBW,YAAa,CAAA,cAAA,CAAA,CAAA;QACvE,IAAI,CAAChC,UAAU,CAAC+B,UAAU,CAAC,SAAWX,EAAAA,GAAAA,CAAII,cAAc,EAAEQ,YAAa,CAAA,cAAA,CAAA,CAAA;AACvE,QAAA,IAAI,CAAChC,UAAU,CAAC+B,UAAU,CAAC,UAAA,EAAYT,mBAAmBU,YAAa,CAAA,qBAAA,CAAA,CAAA;AACvE,QAAA,IAAI,CAAChC,UAAU,CAACiC,QAAQ,CAAC,iBAAiB,IAAIC,OAAAA,CAAQd,GAAIe,CAAAA,MAAM,CAACC,YAAY,EAAA,EAAIhB,GAAIe,CAAAA,MAAM,CAACE,WAAW,EAAA,CAAA,CAAA;AACvG,QAAA,IAAI,CAACrC,UAAU,CAACiC,QAAQ,CACtB,YAAA,EACA,IAAIK,OAAQjB,CAAAA,iBAAAA,CAAkBkB,KAAK,EAAElB,kBAAkBmB,MAAM,EAAEnB,kBAAkBkB,KAAK,EAAElB,kBAAkBmB,MAAM,CAAA,CAAA;QAElH,IAAI,CAACxC,UAAU,CAACiC,QAAQ,CAAC,UAAY,EAAA,IAAI,CAAChC,SAAS,CAAA;QACnD,IAAI,CAACD,UAAU,CAACiC,QAAQ,CAAC,SAAW,EAAA,IAAI,CAAC/B,QAAQ,CAAA;QACjD,IAAI,CAACF,UAAU,CAACiC,QAAQ,CAAC,YAAc,EAAA,IAAI,CAAC9B,WAAW,CAAA;QACvD,IAAI,CAACH,UAAU,CAACiC,QAAQ,CAAC,YAAc,EAAA,IAAI,CAAC7B,WAAW,CAAA;QACvD,IAAI,CAACJ,UAAU,CAACiC,QAAQ,CAAC,YAAc,EAAA,IAAI,CAAC5B,WAAW,CAAA;QACvD,IAAI,CAACL,UAAU,CAACiC,QAAQ,CAAC,MAAQ,EAAA,IAAI,CAACQ,QAAQ,CAACf,MAAAA,CAAAA,GAAU,CAAI,GAAA,CAAA,CAAA;AAC7D,QAAA,IAAI,CAAC1B,UAAU,CAACiC,QAAQ,CAAC,SAAA,EAAWV,aAAa,CAAI,GAAA,CAAA,CAAA;AACrDG,QAAAA,MAAAA,CAAOgB,UAAU,CAACf,OAAAA,CAAAA;AAClBD,QAAAA,MAAAA,CAAOiB,YAAY,CAAC,CAAG,EAAA,IAAI,CAAC3C,UAAU,CAAA;AACtC,QAAA,IAAI,CAAC4C,kBAAkB,EAAA;AACzB;AAEQhB,IAAAA,aAAAA,CAAcR,GAAgB,EAAE;AACtC,QAAA,MAAMO,OAAUP,GAAAA,GAAAA,CAAIM,MAAM,CAACmB,kBAAkB,CAAC;AAC5CC,YAAAA,MAAAA,CAAAA,CAAOC,EAAE,EAAA;AACP,gBAAA,IAAI,CAACC,IAAI,GAAGD,GAAGE,GAAG,EAAA,CAAGC,OAAO,CAAC,CAAA,CAAA;gBAC7B,IAAI,CAACC,OAAO,CAACC,GAAG,GAAGL,EAAGM,CAAAA,IAAI,EAAGC,CAAAA,MAAM,CAAC,UAAA,CAAA;AACpC,gBAAA,IAAI,CAACC,QAAQ,CAACC,EAAE,GAAGT,GAAGM,IAAI,EAAA;AAC1BN,gBAAAA,EAAAA,CAAGU,IAAI,CAAC,WAAA;AACN,oBAAA,IAAI,CAACC,SAAS,CAACC,QAAQ,GAAGZ,EAAGa,CAAAA,IAAI,CAAC,IAAI,CAACT,OAAO,CAACC,GAAG,EAAE,CAAG,EAAA,CAAA,CAAA;oBACvD,IAAI,CAACG,QAAQ,CAACC,EAAE,GAAGT,EAAGc,CAAAA,GAAG,CAACd,EAAAA,CAAGe,GAAG,CAAC,IAAI,CAACX,OAAO,CAACC,GAAG,CAACW,EAAE,EAAE,GAAA,CAAA,EAAMhB,EAAGM,CAAAA,IAAI,CAAC,GAAA,CAAA,CAAA;oBACpE,IAAI,CAACW,GAAG,CAACjB,EAAGkB,CAAAA,QAAQ,CAAC,IAAI,CAACjB,IAAI,EAAE,CAAI,CAAA,EAAA,WAAA;AAClC,wBAAA,IAAI,CAACU,SAAS,CAACC,QAAQ,CAACO,CAAC,GAAGnB,EAAAA,CAAGoB,GAAG,CAAC,IAAI,CAACT,SAAS,CAACC,QAAQ,CAACO,CAAC,CAAA;AAC9D,qBAAA,CAAA;AACF,iBAAA,CAAA;AACF,aAAA;AACAE,YAAAA,QAAAA,CAAAA,CAASrB,EAAE,EAAA;AACT,gBAAA,IAAI,CAACsB,QAAQ,GAAGtB,GAAGuB,KAAK,EAAA,CAAGpB,OAAO,CAAC,CAAA,CAAA;AACnC,gBAAA,IAAI,CAACqB,OAAO,GAAGxB,GAAGuB,KAAK,EAAA,CAAGpB,OAAO,CAAC,CAAA,CAAA;AAClC,gBAAA,IAAI,CAACsB,QAAQ,GAAGzB,GAAGuB,KAAK,EAAA,CAAGpB,OAAO,CAAC,CAAA,CAAA;AACnC,gBAAA,IAAI,CAACuB,aAAa,GAAG1B,GAAGM,IAAI,EAAA,CAAGH,OAAO,CAAC,CAAA,CAAA;AACvC,gBAAA,IAAI,CAACwB,UAAU,GAAG3B,GAAGa,IAAI,EAAA,CAAGV,OAAO,CAAC,CAAA,CAAA;AACpC,gBAAA,IAAI,CAACzC,QAAQ,GAAGsC,GAAG4B,KAAK,EAAA,CAAGzB,OAAO,CAAC,CAAA,CAAA;AACnC,gBAAA,IAAI,CAACrC,OAAO,GAAGkC,GAAG4B,KAAK,EAAA,CAAGzB,OAAO,CAAC,CAAA,CAAA;AAClC,gBAAA,IAAI,CAACnC,UAAU,GAAGgC,GAAG4B,KAAK,EAAA,CAAGzB,OAAO,CAAC,CAAA,CAAA;AACrC,gBAAA,IAAI,CAAClC,UAAU,GAAG+B,GAAG4B,KAAK,EAAA,CAAGzB,OAAO,CAAC,CAAA,CAAA;AACrC,gBAAA,IAAI,CAACjC,UAAU,GAAG8B,GAAG4B,KAAK,EAAA,CAAGzB,OAAO,CAAC,CAAA,CAAA;AACrC,gBAAA,IAAI,CAAC0B,OAAO,GAAG7B,GAAGE,GAAG,EAAA,CAAGC,OAAO,CAAC,CAAA,CAAA;AAChC,gBAAA,IAAI,CAACK,QAAQ,CAACsB,QAAQ,GAAG9B,GAAGa,IAAI,EAAA;gBAChCb,EAAG+B,CAAAA,IAAI,CAAC,aAAe,EAAA;AAAC/B,oBAAAA,EAAAA,CAAGM,IAAI,CAAC,IAAA;iBAAM,EAAE,WAAA;AACtC,oBAAA,IAAI,CAAC0B,OAAO,CAACC,YAAAA,CAAaC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAACT,QAAQ,EAAE,IAAI,CAAChB,EAAE,EAAE,CAAA,CAAA,CAAA;AAC5E,iBAAA,CAAA;AACAT,gBAAAA,EAAAA,CAAGU,IAAI,CAAC,WAAA;oBACN,IAAI,CAACyB,EAAE,CAAC1B,EAAE,GAAG,IAAI,CAACL,OAAO,CAACK,EAAE;AAC5B,oBAAA,IAAI,CAAC0B,EAAE,CAACC,SAAS,GAAGpC,EAAGqC,CAAAA,kBAAkB,CAAC,IAAI,CAACf,QAAQ,EAAE,IAAI,CAACb,EAAE,EAAE,CAAA,CAAA;oBAClE,IAAI,CAAC0B,EAAE,CAACG,MAAM,GAAG,IAAI,CAACF,SAAS,CAACG,GAAG;oBACnC,IAAI,CAACJ,EAAE,CAACK,aAAa,GAAG,IAAI,CAACC,WAAW,CAAC,IAAI,CAAChC,EAAE,CAAA;oBAChD,IAAI,CAACQ,GAAG,CAACjB,EAAG0C,CAAAA,QAAQ,CAAC,IAAI,CAACF,aAAa,EAAE,CAAI,CAAA,EAAA,WAAA;wBAC3C,IAAI,CAACL,EAAE,CAACQ,WAAW,GAAG3C,EAAGnC,CAAAA,GAAG,CAACmC,EAAGe,CAAAA,GAAG,CAAC,IAAI,CAACyB,aAAa,EAAE,IAAI,CAACd,aAAa,CAACP,CAAC,CAAG,EAAA,IAAA,CAAA;AAC/E,wBAAA,IAAI,CAACgB,EAAE,CAACS,GAAG,GAAG5C,EAAAA,CAAGa,IAAI,CAAC,CAAA,CAAA;AACtB,wBAAA,IAAI,CAACsB,EAAE,CAACU,SAAS,GAAG7C,EAAAA,CAAG4B,KAAK,CAAC,CAAA,CAAA;wBAC7B,IAAI,CAACkB,IAAI,CAAC9C,EAAAA,CAAGE,GAAG,CAAC,GAAA,CAAA,EAAM,EAAC,EAAG,CAAG,EAAA,WAAA;4BAC5B,IAAI,CAAC4C,IAAI,CAAC9C,EAAAA,CAAGE,GAAG,CAAC,GAAA,CAAA,EAAM,EAAC,EAAG,CAAG,EAAA,WAAA;gCAC5B,IAAI,CAACiC,EAAE,CAACY,QAAQ,GAAG/C,EAAGe,CAAAA,GAAG,CAACf,EAAAA,CAAGM,IAAI,CAACN,EAAG4B,CAAAA,KAAK,CAAC,IAAI,CAACoB,CAAC,CAAGhD,EAAAA,EAAAA,CAAG4B,KAAK,CAAC,IAAI,CAACT,CAAC,CAAA,CAAA,EAAI,IAAI,CAACnD,UAAU,CAAA;AACtF,gCAAA,IAAI,CAACmE,EAAE,CAACc,QAAQ,GAAGjD,EAAGkD,CAAAA,KAAK,CACzBlD,EAAAA,CAAGc,GAAG,CAAC,IAAI,CAACL,EAAE,EAAET,EAAGmD,CAAAA,GAAG,CAAC,IAAI,CAACJ,QAAQ,EAAE,IAAI,CAACpB,UAAU,CAACX,EAAE,CAAA,CAAA,EACxDhB,GAAGM,IAAI,CAAC,CACRN,CAAAA,EAAAA,EAAAA,CAAGM,IAAI,CAAC,CAAA,CAAA,CAAA;AAEV,gCAAA,IAAI,CAAC6B,EAAE,CAACiB,UAAU,GAAGpD,EAAGqC,CAAAA,kBAAkB,CAAC,IAAI,CAACb,OAAO,EAAE,IAAI,CAACyB,QAAQ,EAAE,CAAA,CAAA;AACxE,gCAAA,IAAI,CAAChC,GAAG,CAACjB,EAAAA,CAAGqD,aAAa,CAAC,IAAI,CAACD,UAAU,CAACE,CAAC,EAAE,IAAO,CAAA,EAAA,WAAA;oCAClD,IAAI,CAACF,UAAU,GAAGpD,EAAGa,CAAAA,IAAI,CAAC,CAAA,EAAG,CAAG,EAAA,CAAA,EAAG,IAAI,CAAC/C,OAAO,CAAA;AACjD,iCAAA,CAAA;gCACA,IAAI,CAACqE,EAAE,CAACoB,aAAa,GAAG,IAAI,CAACd,WAAW,CAAC,IAAI,CAACQ,QAAQ,CAAA;gCACtD,IAAI,CAACd,EAAE,CAACqB,WAAW,GAAGxD,EAAGnC,CAAAA,GAAG,CAACmC,EAAGe,CAAAA,GAAG,CAAC,IAAI,CAACwC,aAAa,EAAE,IAAI,CAAC7B,aAAa,CAACP,CAAC,CAAG,EAAA,IAAA,CAAA;AAC/E,gCAAA,IAAI,CAACgB,EAAE,CAACsB,WAAW,GAAGzD,EAAAA,CAAGkD,KAAK,CAC5BlD,EAAAA,CAAG0D,GAAG,CACJ,GACA1D,EAAGmD,CAAAA,GAAG,CACJnD,EAAGe,CAAAA,GAAG,CAACf,EAAG2D,CAAAA,GAAG,CAAC3D,EAAAA,CAAG0D,GAAG,CAAC,IAAI,CAACf,WAAW,EAAE,IAAI,CAACa,WAAW,CAAI,CAAA,EAAA,IAAI,CAACvF,UAAU,CAAA,EAC1E,IAAI,CAAC0E,WAAW,IAGpB,CACA,EAAA,CAAA,CAAA;gCAEF,IAAI,CAACc,WAAW,GAAGzD,EAAGe,CAAAA,GAAG,CACvB,IAAI,CAAC0C,WAAW,EAChB,IAAI,CAACA,WAAW,EAChBzD,EAAAA,CAAG0D,GAAG,CAAC,CAAG1D,EAAAA,EAAAA,CAAGe,GAAG,CAAC,IAAI,CAAC0C,WAAW,EAAE,CAAA,CAAA,CAAA,CAAA;AAErC,gCAAA,IAAI,CAACb,GAAG,GAAG5C,GAAGc,GAAG,CAAC,IAAI,CAAC8B,GAAG,EAAE5C,EAAGe,CAAAA,GAAG,CAAC,IAAI,CAACqC,UAAU,EAAE,IAAI,CAACK,WAAW,CAAA,CAAA;AACpE,gCAAA,IAAI,CAACZ,SAAS,GAAG7C,EAAAA,CAAGc,GAAG,CAAC,IAAI,CAAC+B,SAAS,EAAE,IAAI,CAACY,WAAW,CAAA;AAC1D,6BAAA,CAAA;AACF,yBAAA,CAAA;wBACA,IAAI,CAACxC,GAAG,CAACjB,EAAG4D,CAAAA,WAAW,CAAC,IAAI,CAACf,SAAS,EAAE,IAAO,CAAA,EAAA,WAAA;AAC7C,4BAAA,IAAI,CAACV,EAAE,CAAC0B,WAAW,GAAG7D,EAAGmD,CAAAA,GAAG,CAAC,IAAI,CAACP,GAAG,EAAE,IAAI,CAACC,SAAS,CAAA;AACrD,4BAAA,IAAI,CAACV,EAAE,CAAC2B,UAAU,GAAG9D,GAAG0D,GAAG,CAAC,IAAI,CAACG,WAAW,CAACP,CAAC,EAAE,IAAI,CAACxF,OAAO,CAAA;4BAC5D,IAAI,CAACqE,EAAE,CAAC4B,YAAY,GAAG/D,EAAGe,CAAAA,GAAG,CAC3B,IAAI,CAACqB,SAAS,CAACG,GAAG,EAClBvC,EAAGc,CAAAA,GAAG,CACJd,EAAAA,CAAGgE,IAAI,CAAChE,EAAAA,CAAG0D,GAAG,CAAC,CAAG,EAAA,IAAI,CAACI,UAAU,CAAA,CAAA,EACjC9D,EAAGe,CAAAA,GAAG,CAAC,IAAI,CAAC8C,WAAW,CAACtB,GAAG,EAAEvC,EAAGnC,CAAAA,GAAG,CAACmC,EAAG0D,CAAAA,GAAG,CAAC,CAAA,EAAG,IAAI,CAAC5F,OAAO,CAAG,EAAA,CAAA,CAAA,EAAI,IAAI,CAACI,UAAU,CAAA,CAAA,CAAA;AAGpF,4BAAA,IAAI,CAACoE,MAAM,GAAGtC,EAAAA,CAAGc,GAAG,CAClB,IAAI,CAACsB,SAAS,CAACG,GAAG,EAClBvC,GAAGe,GAAG,CAACf,EAAG0D,CAAAA,GAAG,CAAC,IAAI,CAACK,YAAY,EAAE,IAAI,CAAC3B,SAAS,CAACG,GAAG,CAAG,EAAA,IAAI,CAAC7E,QAAQ,CAAA,CAAA;AAEvE,yBAAA,CAAA;AACF,qBAAA,CAAA;oBACA,IAAI,CAACuD,GAAG,CAACjB,EAAGiE,CAAAA,KAAK,CAAC,IAAI,CAACpC,OAAO,EAAE,CAAI,CAAA,EAAA,WAAA;AAClC,wBAAA,IAAI,CAACrB,QAAQ,CAACsB,QAAQ,GAAG9B,GAAGa,IAAI,CAAC,IAAI,CAACyB,MAAM,EAAE,IAAI,CAACF,SAAS,CAACkB,CAAC,CAAA;AAChE,qBAAA,CAAA,CAAGY,KAAK,CAAC,WAAA;AACP,wBAAA,IAAI,CAAC1D,QAAQ,CAACsB,QAAQ,GAAG9B,EAAAA,CAAGa,IAAI,CAACsD,aAAAA,CAAc,IAAI,EAAE,IAAI,CAAC7B,MAAM,CAAA,EAAG,IAAI,CAACF,SAAS,CAACkB,CAAC,CAAA;AACrF,qBAAA,CAAA;AACF,iBAAA,CAAA;AACF;AACF,SAAA,CAAA;AACA1E,QAAAA,OAAAA,CAAQwF,IAAI,GAAG,UAAA;QACf,OAAOxF,OAAAA;AACT;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"skinsss.js","sources":["../../src/posteffect/skinsss.ts"],"sourcesContent":["import { Vector2, Vector4 } from '@zephyr3d/base';\r\nimport type { BindGroup, GPUProgram, Texture2D } from '@zephyr3d/device';\r\nimport type { DrawContext } from '../render';\r\nimport { ShaderHelper } from '../material';\r\nimport { linearToGamma } from '../shaders/misc';\r\nimport { fetchSampler } from '../utility/misc';\r\nimport { AbstractPostEffect, PostEffectLayer } from './posteffect';\r\n\r\n/**\r\n * Stylized screen-space skin scattering pass.\r\n *\r\n * @remarks\r\n * This is intentionally separate from the profile-based {@link SSS} pass. It follows the simpler\r\n * depth-aware blur used by many character renderers: a skin material writes a lighting multiplier\r\n * into a side buffer, then this pass performs a fixed 9x9 depth-aware blur and composites it back\r\n * over the opaque color.\r\n *\r\n * @public\r\n */\r\nexport class SkinSSS extends AbstractPostEffect {\r\n private static _program: GPUProgram | null = null;\r\n private _bindGroup: BindGroup | null;\r\n private _strength: number;\r\n private _opacity: number;\r\n private _sampleStep: number;\r\n private _depthScale: number;\r\n private _colorBoost: number;\r\n\r\n constructor() {\r\n super();\r\n this._layer = PostEffectLayer.opaque;\r\n this._bindGroup = null;\r\n this._strength = 1;\r\n this._opacity = 0.18;\r\n this._sampleStep = 2;\r\n this._depthScale = 80;\r\n this._colorBoost = 1;\r\n }\r\n\r\n /** Final blend strength. */\r\n get strength() {\r\n return this._strength;\r\n }\r\n set strength(val) {\r\n this._strength = Math.max(0, val ?? 0);\r\n }\r\n\r\n /** Bias subtracted from the blurred skin mask before compositing. */\r\n get opacity() {\r\n return this._opacity;\r\n }\r\n set opacity(val) {\r\n this._opacity = Math.max(0, Math.min(1, val ?? 0));\r\n }\r\n\r\n /** Pixel spacing between blur taps. The reference shader uses 2. */\r\n get sampleStep() {\r\n return this._sampleStep;\r\n }\r\n set sampleStep(val) {\r\n this._sampleStep = Math.max(0.25, val ?? 0.25);\r\n }\r\n\r\n /** Depth rejection scale. The reference shader uses 80. */\r\n get depthScale() {\r\n return this._depthScale;\r\n }\r\n set depthScale(val) {\r\n this._depthScale = Math.max(0, val ?? 0);\r\n }\r\n\r\n /** Multiplier applied to the blurred skin lighting multiplier before compositing. */\r\n get colorBoost() {\r\n return this._colorBoost;\r\n }\r\n set colorBoost(val) {\r\n this._colorBoost = Math.max(0, val ?? 0);\r\n }\r\n\r\n requireLinearDepthTexture() {\r\n return true;\r\n }\r\n\r\n apply(ctx: DrawContext, inputColorTexture: Texture2D, sceneDepthTexture: Texture2D, srgbOutput: boolean) {\r\n if (!ctx.SkinSSSTexture || this._strength <= 0) {\r\n this.passThrough(ctx, inputColorTexture, srgbOutput);\r\n return;\r\n }\r\n const device = ctx.device;\r\n let program = SkinSSS._program;\r\n if (!program) {\r\n program = this.createProgram(ctx);\r\n SkinSSS._program = program;\r\n }\r\n if (!this._bindGroup) {\r\n this._bindGroup = device.createBindGroup(program.bindGroupLayouts[0]);\r\n }\r\n this._bindGroup.setTexture('colorTex', inputColorTexture, fetchSampler('clamp_linear'));\r\n this._bindGroup.setTexture('skinTex', ctx.SkinSSSTexture, fetchSampler('clamp_linear'));\r\n this._bindGroup.setTexture('depthTex', sceneDepthTexture, fetchSampler('clamp_nearest_nomip'));\r\n this._bindGroup.setValue(\r\n 'cameraNearFar',\r\n new Vector2(ctx.camera.getNearPlane(), ctx.camera.getFarPlane())\r\n );\r\n this._bindGroup.setValue(\r\n 'targetSize',\r\n new Vector4(\r\n inputColorTexture.width,\r\n inputColorTexture.height,\r\n inputColorTexture.width,\r\n inputColorTexture.height\r\n )\r\n );\r\n this._bindGroup.setValue('strength', this._strength);\r\n this._bindGroup.setValue('opacity', this._opacity);\r\n this._bindGroup.setValue('sampleStep', this._sampleStep);\r\n this._bindGroup.setValue('depthScale', this._depthScale);\r\n this._bindGroup.setValue('colorBoost', this._colorBoost);\r\n this._bindGroup.setValue('flip', this.needFlip(device) ? 1 : 0);\r\n this._bindGroup.setValue('srgbOut', srgbOutput ? 1 : 0);\r\n device.setProgram(program);\r\n device.setBindGroup(0, this._bindGroup);\r\n this.drawFullscreenQuad();\r\n }\r\n\r\n private createProgram(ctx: DrawContext) {\r\n const program = ctx.device.buildRenderProgram({\r\n vertex(pb) {\r\n this.flip = pb.int().uniform(0);\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 this.$if(pb.notEqual(this.flip, 0), function () {\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.colorTex = pb.tex2D().uniform(0);\r\n this.skinTex = pb.tex2D().uniform(0);\r\n this.depthTex = pb.tex2D().uniform(0);\r\n this.cameraNearFar = pb.vec2().uniform(0);\r\n this.targetSize = pb.vec4().uniform(0);\r\n this.strength = pb.float().uniform(0);\r\n this.opacity = pb.float().uniform(0);\r\n this.sampleStep = pb.float().uniform(0);\r\n this.depthScale = pb.float().uniform(0);\r\n this.colorBoost = pb.float().uniform(0);\r\n this.srgbOut = pb.int().uniform(0);\r\n this.$outputs.outColor = pb.vec4();\r\n pb.func('readDepth01', [pb.vec2('uv')], function () {\r\n this.$return(ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0));\r\n });\r\n pb.main(function () {\r\n this.$l.uv = this.$inputs.uv;\r\n this.$l.baseColor = pb.textureSampleLevel(this.colorTex, this.uv, 0);\r\n this.$l.result = this.baseColor.rgb;\r\n this.$l.centerDepth01 = this.readDepth01(this.uv);\r\n this.$if(pb.lessThan(this.centerDepth01, 1), function () {\r\n this.$l.centerDepth = pb.max(pb.mul(this.centerDepth01, this.cameraNearFar.y), 1e-4);\r\n this.$l.sum = pb.vec4(0);\r\n this.$l.weightSum = pb.float(0);\r\n this.$for(pb.int('y'), -4, 5, function () {\r\n this.$for(pb.int('x'), -4, 5, function () {\r\n this.$l.offsetPx = pb.mul(pb.vec2(pb.float(this.x), pb.float(this.y)), this.sampleStep);\r\n this.$l.sampleUV = pb.clamp(\r\n pb.add(this.uv, pb.div(this.offsetPx, this.targetSize.xy)),\r\n pb.vec2(0),\r\n pb.vec2(1)\r\n );\r\n this.$l.skinSample = pb.textureSampleLevel(this.skinTex, this.sampleUV, 0);\r\n this.$if(pb.lessThanEqual(this.skinSample.a, 1e-4), function () {\r\n this.skinSample = pb.vec4(0, 0, 0, this.opacity);\r\n });\r\n this.$l.sampleDepth01 = this.readDepth01(this.sampleUV);\r\n this.$l.sampleDepth = pb.max(pb.mul(this.sampleDepth01, this.cameraNearFar.y), 1e-4);\r\n this.$l.depthWeight = pb.clamp(\r\n pb.sub(\r\n 1,\r\n pb.div(\r\n pb.mul(pb.abs(pb.sub(this.centerDepth, this.sampleDepth)), this.depthScale),\r\n this.centerDepth\r\n )\r\n ),\r\n 0,\r\n 1\r\n );\r\n this.depthWeight = pb.mul(\r\n this.depthWeight,\r\n this.depthWeight,\r\n pb.sub(3, pb.mul(this.depthWeight, 2))\r\n );\r\n this.sum = pb.add(this.sum, pb.mul(this.skinSample, this.depthWeight));\r\n this.weightSum = pb.add(this.weightSum, this.depthWeight);\r\n });\r\n });\r\n this.$if(pb.greaterThan(this.weightSum, 1e-4), function () {\r\n this.$l.blurredSkin = pb.div(this.sum, this.weightSum);\r\n this.$l.alphaDelta = pb.sub(this.blurredSkin.a, this.opacity);\r\n this.$l.referenceLit = pb.mul(\r\n this.baseColor.rgb,\r\n pb.add(\r\n pb.vec3(pb.sub(1, this.alphaDelta)),\r\n pb.mul(this.blurredSkin.rgb, pb.max(pb.sub(1, this.opacity), 0), this.colorBoost)\r\n )\r\n );\r\n this.result = pb.add(\r\n this.baseColor.rgb,\r\n pb.mul(pb.sub(this.referenceLit, this.baseColor.rgb), this.strength)\r\n );\r\n });\r\n });\r\n this.$if(pb.equal(this.srgbOut, 0), function () {\r\n this.$outputs.outColor = pb.vec4(this.result, this.baseColor.a);\r\n }).$else(function () {\r\n this.$outputs.outColor = pb.vec4(linearToGamma(this, this.result), this.baseColor.a);\r\n });\r\n });\r\n }\r\n })!;\r\n program.name = '@SkinSSS';\r\n return program;\r\n }\r\n}\r\n"],"names":["SkinSSS","AbstractPostEffect","_program","_bindGroup","_strength","_opacity","_sampleStep","_depthScale","_colorBoost","_layer","PostEffectLayer","opaque","strength","val","Math","max","opacity","min","sampleStep","depthScale","colorBoost","requireLinearDepthTexture","apply","ctx","inputColorTexture","sceneDepthTexture","srgbOutput","SkinSSSTexture","passThrough","device","program","createProgram","createBindGroup","bindGroupLayouts","setTexture","fetchSampler","setValue","Vector2","camera","getNearPlane","getFarPlane","Vector4","width","height","needFlip","setProgram","setBindGroup","drawFullscreenQuad","buildRenderProgram","vertex","pb","flip","int","uniform","$inputs","pos","vec2","attrib","$outputs","uv","main","$builtins","position","vec4","add","mul","xy","$if","notEqual","y","neg","fragment","colorTex","tex2D","skinTex","depthTex","cameraNearFar","targetSize","float","srgbOut","outColor","func","$return","ShaderHelper","sampleLinearDepth","$l","baseColor","textureSampleLevel","result","rgb","centerDepth01","readDepth01","lessThan","centerDepth","sum","weightSum","$for","offsetPx","x","sampleUV","clamp","div","skinSample","lessThanEqual","a","sampleDepth01","sampleDepth","depthWeight","sub","abs","greaterThan","blurredSkin","alphaDelta","referenceLit","vec3","equal","$else","linearToGamma","name"],"mappings":"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"}
|
package/dist/posteffect/ssr.js
CHANGED
|
@@ -3,7 +3,7 @@ import { linearToGamma } from '../shaders/misc.js';
|
|
|
3
3
|
import { SSR_calcJitter, screenSpaceRayTracing_HiZ, screenSpaceRayTracing_Linear2D } from '../shaders/ssr.js';
|
|
4
4
|
import { temporalResolve } from '../shaders/temporal.js';
|
|
5
5
|
import { Vector2, Matrix4x4, Vector4 } from '@zephyr3d/base';
|
|
6
|
-
import {
|
|
6
|
+
import { copyTexture, fetchSampler } from '../utility/misc.js';
|
|
7
7
|
import { getGGXLUT } from '../utility/textures/ggxlut.js';
|
|
8
8
|
import { BilateralBlurBlitter } from '../blitter/bilateralblur.js';
|
|
9
9
|
import { ShaderHelper } from '../material/shader/helper.js';
|
|
@@ -26,6 +26,7 @@ import '../material/sprite.js';
|
|
|
26
26
|
import '../material/sprite_std.js';
|
|
27
27
|
import '../utility/blueprint/material/texture.js';
|
|
28
28
|
import { RGHistoryResources } from '../render/rendergraph/history_resources.js';
|
|
29
|
+
import { FrameResources } from '../render/rendergraph/blackboard.js';
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* SSR post effect
|
|
@@ -61,8 +62,238 @@ import { RGHistoryResources } from '../render/rendergraph/history_resources.js';
|
|
|
61
62
|
/** {@inheritDoc AbstractPostEffect.requireDepthAttachment} */ requireDepthAttachment() {
|
|
62
63
|
return true;
|
|
63
64
|
}
|
|
64
|
-
/** @
|
|
65
|
-
|
|
65
|
+
/** {@inheritDoc AbstractPostEffect.requireMotionVectorTexture} */ requireMotionVectorTexture(ctx) {
|
|
66
|
+
return !!ctx.camera.ssrTemporal;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Declares SSR's internal steps (intersect, resolve, optional bilateral
|
|
70
|
+
* blur, optional temporal resolve, combine) as individual render graph
|
|
71
|
+
* passes, mirroring the sequence of {@link SSR.apply}.
|
|
72
|
+
*/ setup(s) {
|
|
73
|
+
const { graph, ctx, history } = s;
|
|
74
|
+
const linearDepthHandle = s.blackboard.get(FrameResources.LinearDepth);
|
|
75
|
+
const texDesc = {
|
|
76
|
+
format: 'rgba16f',
|
|
77
|
+
sizeMode: 'absolute',
|
|
78
|
+
width: s.width,
|
|
79
|
+
height: s.height
|
|
80
|
+
};
|
|
81
|
+
const readCommon = (builder)=>{
|
|
82
|
+
if (linearDepthHandle) {
|
|
83
|
+
builder.read(linearDepthHandle);
|
|
84
|
+
}
|
|
85
|
+
// Roughness/normal MRT outputs, HiZ and the scene color copy are reached
|
|
86
|
+
// through DrawContext fields; the dependency list carries their handles.
|
|
87
|
+
for (const dep of s.dependencies){
|
|
88
|
+
builder.read(dep);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const getLinearDepth = (rg)=>linearDepthHandle ? rg.getTexture(linearDepthHandle) : ctx.linearDepthTexture;
|
|
92
|
+
// 1. Ray march the scene (HiZ or linear 2D) into the intersect texture.
|
|
93
|
+
const intersectHandle = graph.addPass('SSR:Intersect', (builder)=>{
|
|
94
|
+
builder.read(s.input);
|
|
95
|
+
readCommon(builder);
|
|
96
|
+
const out = builder.createTexture({
|
|
97
|
+
...texDesc,
|
|
98
|
+
label: 'SSR:intersect'
|
|
99
|
+
});
|
|
100
|
+
const fb = builder.createFramebuffer({
|
|
101
|
+
label: 'SSR:intersectFB',
|
|
102
|
+
width: s.width,
|
|
103
|
+
height: s.height,
|
|
104
|
+
colorAttachments: out,
|
|
105
|
+
depthAttachment: s.sceneDepthAttachment,
|
|
106
|
+
ignoreDepthStencil: false
|
|
107
|
+
});
|
|
108
|
+
builder.setExecute((rg)=>{
|
|
109
|
+
const device = ctx.device;
|
|
110
|
+
device.pushDeviceStates();
|
|
111
|
+
try {
|
|
112
|
+
device.setFramebuffer(rg.getFramebuffer(fb));
|
|
113
|
+
this.intersect(ctx, rg.getTexture(s.input), getLinearDepth(rg), true, false);
|
|
114
|
+
} finally{
|
|
115
|
+
device.popDeviceStates();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return out;
|
|
119
|
+
});
|
|
120
|
+
// 2. Resolve reflection color from the intersect result.
|
|
121
|
+
const resolveHandle = graph.addPass('SSR:Resolve', (builder)=>{
|
|
122
|
+
builder.read(s.input);
|
|
123
|
+
builder.read(intersectHandle);
|
|
124
|
+
readCommon(builder);
|
|
125
|
+
const out = builder.createTexture({
|
|
126
|
+
...texDesc,
|
|
127
|
+
label: 'SSR:resolve'
|
|
128
|
+
});
|
|
129
|
+
const fb = builder.createFramebuffer({
|
|
130
|
+
label: 'SSR:resolveFB',
|
|
131
|
+
width: s.width,
|
|
132
|
+
height: s.height,
|
|
133
|
+
colorAttachments: out,
|
|
134
|
+
depthAttachment: s.sceneDepthAttachment,
|
|
135
|
+
ignoreDepthStencil: false
|
|
136
|
+
});
|
|
137
|
+
builder.setExecute((rg)=>{
|
|
138
|
+
const device = ctx.device;
|
|
139
|
+
device.pushDeviceStates();
|
|
140
|
+
try {
|
|
141
|
+
device.setFramebuffer(rg.getFramebuffer(fb));
|
|
142
|
+
const inputTex = rg.getTexture(s.input);
|
|
143
|
+
this.resolve(ctx, ctx.sceneColorTexture ?? inputTex, getLinearDepth(rg), rg.getTexture(intersectHandle));
|
|
144
|
+
} finally{
|
|
145
|
+
device.popDeviceStates();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
return out;
|
|
149
|
+
});
|
|
150
|
+
// 3. Optional bilateral blur (horizontal + vertical), guided by the
|
|
151
|
+
// per-pixel blur size stored in the intersect texture.
|
|
152
|
+
let reflectHandle = resolveHandle;
|
|
153
|
+
if (ctx.camera.ssrBlurScale > 0 && ctx.camera.ssrBlurKernelSize > 0) {
|
|
154
|
+
reflectHandle = graph.addPass('SSR:Blur', (builder)=>{
|
|
155
|
+
builder.read(resolveHandle);
|
|
156
|
+
builder.read(intersectHandle);
|
|
157
|
+
readCommon(builder);
|
|
158
|
+
const middle = builder.createTexture({
|
|
159
|
+
...texDesc,
|
|
160
|
+
label: 'SSR:blurH'
|
|
161
|
+
});
|
|
162
|
+
const out = builder.createTexture({
|
|
163
|
+
...texDesc,
|
|
164
|
+
label: 'SSR:blur'
|
|
165
|
+
});
|
|
166
|
+
const middleFB = builder.createFramebuffer({
|
|
167
|
+
label: 'SSR:blurHFB',
|
|
168
|
+
width: s.width,
|
|
169
|
+
height: s.height,
|
|
170
|
+
colorAttachments: middle,
|
|
171
|
+
depthAttachment: s.sceneDepthAttachment,
|
|
172
|
+
ignoreDepthStencil: false
|
|
173
|
+
});
|
|
174
|
+
const outFB = builder.createFramebuffer({
|
|
175
|
+
label: 'SSR:blurFB',
|
|
176
|
+
width: s.width,
|
|
177
|
+
height: s.height,
|
|
178
|
+
colorAttachments: out,
|
|
179
|
+
depthAttachment: s.sceneDepthAttachment,
|
|
180
|
+
ignoreDepthStencil: false
|
|
181
|
+
});
|
|
182
|
+
builder.setExecute((rg)=>{
|
|
183
|
+
const device = ctx.device;
|
|
184
|
+
device.pushDeviceStates();
|
|
185
|
+
try {
|
|
186
|
+
const intersectTex = rg.getTexture(intersectHandle);
|
|
187
|
+
const blurSizeScale = 255 * ctx.camera.ssrBlurScale;
|
|
188
|
+
const kernelRadius = Math.max(1, ctx.camera.ssrBlurKernelSize >> 0) - 1 >> 1;
|
|
189
|
+
const stdDev = ctx.camera.ssrBlurStdDev;
|
|
190
|
+
const depthCutoff = ctx.camera.ssrBlurDepthCutoff;
|
|
191
|
+
const blitterH = SSR._blurBlitterH = SSR._blurBlitterH ?? new BilateralBlurBlitter(false);
|
|
192
|
+
blitterH.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, 'gt');
|
|
193
|
+
this.blurPass(ctx, blitterH, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, rg.getTexture(resolveHandle), rg.getFramebuffer(middleFB));
|
|
194
|
+
const blitterV = SSR._blurBlitterV = SSR._blurBlitterV ?? new BilateralBlurBlitter(true);
|
|
195
|
+
blitterV.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, 'gt');
|
|
196
|
+
this.blurPass(ctx, blitterV, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, rg.getTexture(middle), rg.getFramebuffer(outFB));
|
|
197
|
+
} finally{
|
|
198
|
+
device.popDeviceStates();
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
return out;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// 4. Optional temporal resolve against last frame's reflection.
|
|
205
|
+
const wantTemporal = !!ctx.camera.ssrTemporal;
|
|
206
|
+
const motionVectorHandle = wantTemporal ? s.blackboard.get(FrameResources.MotionVector) : null;
|
|
207
|
+
const historySize = {
|
|
208
|
+
width: s.width,
|
|
209
|
+
height: s.height
|
|
210
|
+
};
|
|
211
|
+
const prevReflectHandle = wantTemporal && history && motionVectorHandle ? history.importPreviousIfCompatible(graph, RGHistoryResources.SSR_REFLECT, texDesc, historySize) : null;
|
|
212
|
+
const prevMotionVectorHandle = wantTemporal && history && motionVectorHandle ? history.importPreviousIfCompatible(graph, RGHistoryResources.SSR_MOTION_VECTOR, texDesc, historySize) : null;
|
|
213
|
+
if (motionVectorHandle && prevReflectHandle && prevMotionVectorHandle) {
|
|
214
|
+
const blurredHandle = reflectHandle;
|
|
215
|
+
reflectHandle = graph.addPass('SSR:Temporal', (builder)=>{
|
|
216
|
+
builder.read(blurredHandle);
|
|
217
|
+
builder.read(prevReflectHandle);
|
|
218
|
+
builder.read(prevMotionVectorHandle);
|
|
219
|
+
builder.read(motionVectorHandle);
|
|
220
|
+
readCommon(builder);
|
|
221
|
+
const out = builder.createTexture({
|
|
222
|
+
...texDesc,
|
|
223
|
+
label: 'SSR:temporal'
|
|
224
|
+
});
|
|
225
|
+
const fb = builder.createFramebuffer({
|
|
226
|
+
label: 'SSR:temporalFB',
|
|
227
|
+
width: s.width,
|
|
228
|
+
height: s.height,
|
|
229
|
+
colorAttachments: out,
|
|
230
|
+
depthAttachment: s.sceneDepthAttachment,
|
|
231
|
+
ignoreDepthStencil: false
|
|
232
|
+
});
|
|
233
|
+
builder.setExecute((rg)=>{
|
|
234
|
+
const device = ctx.device;
|
|
235
|
+
device.pushDeviceStates();
|
|
236
|
+
try {
|
|
237
|
+
this.temporal(ctx, rg.getTexture(blurredHandle), getLinearDepth(rg), rg.getTexture(prevReflectHandle), rg.getTexture(prevMotionVectorHandle), rg.getFramebuffer(fb));
|
|
238
|
+
} finally{
|
|
239
|
+
device.popDeviceStates();
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
return out;
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
// 5. Combine reflections with the scene color and queue history commits.
|
|
246
|
+
const finalReflectHandle = reflectHandle;
|
|
247
|
+
return graph.addPass('PostEffect:SSR', (builder)=>{
|
|
248
|
+
builder.read(s.input);
|
|
249
|
+
builder.read(finalReflectHandle);
|
|
250
|
+
if (motionVectorHandle) {
|
|
251
|
+
builder.read(motionVectorHandle);
|
|
252
|
+
}
|
|
253
|
+
readCommon(builder);
|
|
254
|
+
const output = s.createOutput(builder, {
|
|
255
|
+
needDepthAttachment: true
|
|
256
|
+
});
|
|
257
|
+
builder.setExecute((rg)=>{
|
|
258
|
+
const device = ctx.device;
|
|
259
|
+
device.pushDeviceStates();
|
|
260
|
+
try {
|
|
261
|
+
device.setFramebuffer(output.framebuffer ? rg.getFramebuffer(output.framebuffer) : null);
|
|
262
|
+
const inputTex = rg.getTexture(s.input);
|
|
263
|
+
const reflectanceTex = rg.getTexture(finalReflectHandle);
|
|
264
|
+
copyTexture(inputTex, device.getFramebuffer(), fetchSampler('clamp_nearest_nomip'), AbstractPostEffect.getDefaultRenderState(ctx, 'eq'));
|
|
265
|
+
this.combine(ctx, inputTex, reflectanceTex, output.srgbOutput);
|
|
266
|
+
if (wantTemporal && history) {
|
|
267
|
+
history.queueRetainedCommit(RGHistoryResources.SSR_REFLECT, {
|
|
268
|
+
format: reflectanceTex.format,
|
|
269
|
+
sizeMode: 'absolute',
|
|
270
|
+
width: reflectanceTex.width,
|
|
271
|
+
height: reflectanceTex.height
|
|
272
|
+
}, {
|
|
273
|
+
width: reflectanceTex.width,
|
|
274
|
+
height: reflectanceTex.height
|
|
275
|
+
}, reflectanceTex);
|
|
276
|
+
if (ctx.motionVectorTexture) {
|
|
277
|
+
history.queueRetainedCommit(RGHistoryResources.SSR_MOTION_VECTOR, {
|
|
278
|
+
format: ctx.motionVectorTexture.format,
|
|
279
|
+
sizeMode: 'absolute',
|
|
280
|
+
width: ctx.motionVectorTexture.width,
|
|
281
|
+
height: ctx.motionVectorTexture.height
|
|
282
|
+
}, {
|
|
283
|
+
width: ctx.motionVectorTexture.width,
|
|
284
|
+
height: ctx.motionVectorTexture.height
|
|
285
|
+
}, ctx.motionVectorTexture);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
} finally{
|
|
289
|
+
device.popDeviceStates();
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
return output.color;
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
/** @internal */ blurPass(ctx, blitter, blurSizeTex, blurSizeIndex, blurSizeScale, kernelRadius, stdDev, depthCutoff, srcTex, fbTo) {
|
|
296
|
+
const size = new Vector2(srcTex.width, srcTex.height);
|
|
66
297
|
blitter.kernelRadius = kernelRadius;
|
|
67
298
|
blitter.stdDev = stdDev;
|
|
68
299
|
blitter.size = size;
|
|
@@ -74,7 +305,7 @@ import { RGHistoryResources } from '../render/rendergraph/history_resources.js';
|
|
|
74
305
|
blitter.sampler = fetchSampler('clamp_nearest_nomip');
|
|
75
306
|
blitter.cameraNearFar.setXY(ctx.camera.getNearPlane(), ctx.camera.getFarPlane());
|
|
76
307
|
blitter.srgbOut = false;
|
|
77
|
-
blitter.blit(
|
|
308
|
+
blitter.blit(srcTex, fbTo, fetchSampler('clamp_linear_nomip'));
|
|
78
309
|
}
|
|
79
310
|
/** @internal */ combine(ctx, inputColorTexture, reflectanceTex, srgbOut) {
|
|
80
311
|
const device = ctx.device;
|
|
@@ -256,10 +487,10 @@ import { RGHistoryResources } from '../render/rendergraph/history_resources.js';
|
|
|
256
487
|
const depthCutoff = ctx.camera.ssrBlurDepthCutoff;
|
|
257
488
|
const blitterH = SSR._blurBlitterH = SSR._blurBlitterH ?? new BilateralBlurBlitter(false);
|
|
258
489
|
blitterH.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, 'gt');
|
|
259
|
-
this.blurPass(ctx, blitterH, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, pingpongFramebuffer[0], pingpongFramebuffer[1]);
|
|
490
|
+
this.blurPass(ctx, blitterH, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, pingpongFramebuffer[0].getColorAttachments()[0], pingpongFramebuffer[1]);
|
|
260
491
|
const blitterV = SSR._blurBlitterV = SSR._blurBlitterV ?? new BilateralBlurBlitter(true);
|
|
261
492
|
blitterV.renderStates = AbstractPostEffect.getDefaultRenderState(ctx, 'gt');
|
|
262
|
-
this.blurPass(ctx, blitterV, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, pingpongFramebuffer[1], pingpongFramebuffer[0]);
|
|
493
|
+
this.blurPass(ctx, blitterV, intersectTex, 2, blurSizeScale, kernelRadius, stdDev, depthCutoff, pingpongFramebuffer[1].getColorAttachments()[0], pingpongFramebuffer[0]);
|
|
263
494
|
}
|
|
264
495
|
const historyManager = ctx.camera.getHistoryResourceManager();
|
|
265
496
|
let reflectanceTex = pingpongFramebuffer[0].getColorAttachments()[0];
|
|
@@ -738,7 +969,7 @@ import { RGHistoryResources } from '../render/rendergraph/history_resources.js';
|
|
|
738
969
|
this.$l.reflectVec = pb.add(pb.reflect(this.viewVec, this.viewNormal), SSR_calcJitter(this, this.viewPos, this.roughness));
|
|
739
970
|
this.$l.hitInfo = pb.vec4(0);
|
|
740
971
|
if (ctx.HiZTexture) {
|
|
741
|
-
this.hitInfo = screenSpaceRayTracing_HiZ(this, this.viewPos, this.reflectVec, this.viewMatrix, this.projMatrix, this.invProjMatrix, this.cameraNearFar, this.depthMipLevels, this.ssrParams.y, this.ssrParams.z, this.targetSize, this.hizTex, this.normalTex);
|
|
972
|
+
this.hitInfo = screenSpaceRayTracing_HiZ(this, this.viewPos, this.reflectVec, this.viewMatrix, this.projMatrix, this.invProjMatrix, this.cameraNearFar, this.depthMipLevels, this.ssrParams.y, this.ssrParams.x, this.ssrParams.z, this.targetSize, this.hizTex, this.normalTex);
|
|
742
973
|
} else {
|
|
743
974
|
this.hitInfo = screenSpaceRayTracing_Linear2D(this, this.viewPos, this.reflectVec, this.viewMatrix, this.projMatrix, this.invProjMatrix, this.cameraNearFar, this.ssrParams.x, this.ssrParams.y, this.ssrParams.z, this.ssrStride, this.targetSize, this.depthTex, this.normalTex, !!ctx.camera.ssrCalcThickness);
|
|
744
975
|
}
|