@zephyr3d/scene 0.9.21 → 0.9.22
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/index.d.ts +9 -0
- package/dist/posteffect/posteffect.js +16 -0
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/ssgi.js +644 -0
- package/dist/posteffect/ssgi.js.map +1 -0
- package/dist/posteffect/sss.js +121 -36
- package/dist/posteffect/sss.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/shadow_mask_pass.js +3 -0
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/shaders/ssgi.js +63 -0
- package/dist/shaders/ssgi.js.map +1 -0
- package/dist/shadow/esm.js +3 -1
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +4 -1
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +4 -1
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +2 -0
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadowmapper.js +5 -1
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +4 -1
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +3 -1
- package/dist/shadow/vsm.js.map +1 -1
- package/package.json +1 -1
- package/dist/animation/joint_dynamics/convex_collider.js +0 -320
- package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -8366,6 +8366,15 @@ declare class AbstractPostEffect extends Disposable {
|
|
|
8366
8366
|
* @returns true if the motion vector texture is required.
|
|
8367
8367
|
*/
|
|
8368
8368
|
requireMotionVectorTexture(_ctx: DrawContext): boolean;
|
|
8369
|
+
/**
|
|
8370
|
+
* Checks whether this post effect requires the screen-space shadow mask.
|
|
8371
|
+
*
|
|
8372
|
+
* When true and the mask was produced this frame, the effect can sample
|
|
8373
|
+
* `DrawContext.shadowMaskTexture` in its apply() body; the graph keeps the
|
|
8374
|
+
* mask alive for the effect's pass.
|
|
8375
|
+
* @returns true if the shadow mask is required.
|
|
8376
|
+
*/
|
|
8377
|
+
requireShadowMask(_ctx: DrawContext): boolean;
|
|
8369
8378
|
/**
|
|
8370
8379
|
* Apply the post effect
|
|
8371
8380
|
* @param camera - Camera used the render the scene
|
|
@@ -63,6 +63,16 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
|
|
|
63
63
|
return false;
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
|
+
* Checks whether this post effect requires the screen-space shadow mask.
|
|
67
|
+
*
|
|
68
|
+
* When true and the mask was produced this frame, the effect can sample
|
|
69
|
+
* `DrawContext.shadowMaskTexture` in its apply() body; the graph keeps the
|
|
70
|
+
* mask alive for the effect's pass.
|
|
71
|
+
* @returns true if the shadow mask is required.
|
|
72
|
+
*/ requireShadowMask(_ctx) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
66
76
|
* Apply the post effect
|
|
67
77
|
* @param camera - Camera used the render the scene
|
|
68
78
|
* @param inputColorTexture - The previous scene color texture
|
|
@@ -113,6 +123,12 @@ import { FrameResources } from '../render/rendergraph/blackboard.js';
|
|
|
113
123
|
if (motionVectorHandle) {
|
|
114
124
|
builder.read(motionVectorHandle);
|
|
115
125
|
}
|
|
126
|
+
// Keep the screen-space shadow mask alive for effects that sample it
|
|
127
|
+
// (via DrawContext.shadowMaskTexture) instead of recomputing shadows.
|
|
128
|
+
const shadowMaskHandle = this.requireShadowMask(s.ctx) ? s.blackboard.get(FrameResources.ShadowMask) : null;
|
|
129
|
+
if (shadowMaskHandle) {
|
|
130
|
+
builder.read(shadowMaskHandle);
|
|
131
|
+
}
|
|
116
132
|
const output = s.createOutput(builder, {
|
|
117
133
|
needDepthAttachment: this.requireDepthAttachment(s.ctx)
|
|
118
134
|
});
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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 * Checks whether this post effect requires the screen-space shadow mask.\r\n *\r\n * When true and the mask was produced this frame, the effect can sample\r\n * `DrawContext.shadowMaskTexture` in its apply() body; the graph keeps the\r\n * mask alive for the effect's pass.\r\n * @returns true if the shadow mask is required.\r\n */\r\n requireShadowMask(_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 // Keep the screen-space shadow mask alive for effects that sample it\r\n // (via DrawContext.shadowMaskTexture) instead of recomputing shadows.\r\n const shadowMaskHandle = this.requireShadowMask(s.ctx)\r\n ? s.blackboard.get(FrameResources.ShadowMask)\r\n : null;\r\n if (shadowMaskHandle) {\r\n builder.read(shadowMaskHandle);\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","requireShadowMask","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","shadowMaskHandle","ShadowMask","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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"}
|