@zephyr3d/scene 0.9.0 → 0.9.2
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/animationset.js +135 -133
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/cloth/gpu_cloth_system.js +9 -1
- package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
- package/dist/animation/fixed_geometry_cache_track.js +5 -1
- package/dist/animation/fixed_geometry_cache_track.js.map +1 -1
- package/dist/animation/geometry_cache_utils.js +20 -4
- package/dist/animation/geometry_cache_utils.js.map +1 -1
- package/dist/animation/ik/ik_angle_constraint.js +2 -6
- package/dist/animation/ik/ik_angle_constraint.js.map +1 -1
- package/dist/animation/ik/two_bone_ik_solver.js +2 -6
- package/dist/animation/ik/two_bone_ik_solver.js.map +1 -1
- package/dist/animation/joint_dynamics/collision.js +60 -12
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/constraints.js +20 -4
- package/dist/animation/joint_dynamics/constraints.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +151 -103
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +21 -11
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js +15 -3
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/pca_geometry_cache_track.js +5 -1
- package/dist/animation/pca_geometry_cache_track.js.map +1 -1
- package/dist/animation/skeleton.js +2 -2
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skeleton_modifier.js +2 -6
- package/dist/animation/skeleton_modifier.js.map +1 -1
- package/dist/animation/spring/spring_system.js +87 -114
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +1 -1
- package/dist/app/engine.js.map +1 -1
- package/dist/app/screen.js +4 -4
- package/dist/app/screen.js.map +1 -1
- package/dist/app/scriptingsystem.js +24 -1
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +165 -144
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +2 -2
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/model.js +3 -3
- package/dist/asset/model.js.map +1 -1
- package/dist/camera/camera.js +185 -185
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +794 -261
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/material/material.js +290 -288
- package/dist/material/material.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +13 -26
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/pbrmr.js +1 -11
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/sprite.js +6 -6
- package/dist/material/sprite.js.map +1 -1
- package/dist/material/terrain-cm.js +2 -2
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/posteffect/taa.js +31 -39
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/drawable.js +5 -1
- package/dist/render/drawable.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js +29 -3
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +283 -33
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +338 -108
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/history_resource_manager.js +236 -156
- package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +10 -0
- package/dist/render/rendergraph/history_resources.js.map +1 -0
- package/dist/render/rendergraph/rendergraph.js +162 -35
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/types.js +36 -16
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/rendertarget.js +5 -1
- package/dist/render/rendertarget.js.map +1 -1
- package/dist/render/screenrendertarget.js +5 -1
- package/dist/render/screenrendertarget.js.map +1 -1
- package/dist/render/sky.js +4 -4
- package/dist/render/sky.js.map +1 -1
- package/dist/scene/basesprite.js +2 -2
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/graph_node.js +1 -1
- package/dist/scene/graph_node.js.map +1 -1
- package/dist/scene/mesh.js +4 -20
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/particlesys.js +1 -1
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene_node.js +2 -2
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/script_attachment.js +15 -3
- package/dist/scene/script_attachment.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +3 -3
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shapes/box.js +1 -1
- package/dist/shapes/box.js.map +1 -1
- package/dist/shapes/capsule.js +0 -3
- package/dist/shapes/capsule.js.map +1 -1
- package/dist/shapes/cylinder.js +0 -3
- package/dist/shapes/cylinder.js.map +1 -1
- package/dist/shapes/plane.js +0 -3
- package/dist/shapes/plane.js.map +1 -1
- package/dist/shapes/tetrahedron.js +3 -9
- package/dist/shapes/tetrahedron.js.map +1 -1
- package/dist/shapes/torus.js +4 -7
- package/dist/shapes/torus.js.map +1 -1
- package/dist/utility/blueprint/material/inputs.js +3 -3
- package/dist/utility/blueprint/material/inputs.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +493 -493
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/serialization/manager.js +34 -3
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +45 -0
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +53 -0
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +10 -0
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +30 -0
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +63 -0
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +11 -0
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/misc.js +2 -0
- package/dist/utility/serialization/scene/misc.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +19 -0
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +22 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +33 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +39 -0
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/script.js +2 -0
- package/dist/utility/serialization/scene/script.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +6 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +9 -0
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +21 -0
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js +5 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/package.json +2 -2
|
@@ -14,6 +14,7 @@ import { RenderGraph } from './rendergraph.js';
|
|
|
14
14
|
import { RenderGraphExecutor } from './executor.js';
|
|
15
15
|
import { DevicePoolAllocator } from './device_pool_allocator.js';
|
|
16
16
|
import { HistoryResourceManager } from './history_resource_manager.js';
|
|
17
|
+
import { RGHistoryResources } from './history_resources.js';
|
|
17
18
|
import { renderObjectColors } from '../gpu_picking.js';
|
|
18
19
|
import { BoxShape } from '../../shapes/box.js';
|
|
19
20
|
import '../../shapes/capsule.js';
|
|
@@ -58,7 +59,7 @@ function freeClusteredLight(cl) {
|
|
|
58
59
|
*
|
|
59
60
|
* Each step in the existing `SceneRenderer._renderScene` becomes a graph pass.
|
|
60
61
|
* Execute callbacks delegate to the existing rendering code, sharing a mutable
|
|
61
|
-
*
|
|
62
|
+
* `FrameState`.
|
|
62
63
|
*
|
|
63
64
|
* @param graph - The render graph to populate.
|
|
64
65
|
* @param ctx - The draw context for this frame.
|
|
@@ -68,6 +69,9 @@ function freeClusteredLight(cl) {
|
|
|
68
69
|
*
|
|
69
70
|
* @public
|
|
70
71
|
*/ function buildForwardPlusGraph(graph, ctx, renderQueue, options) {
|
|
72
|
+
return buildForwardPlusGraphInternal(graph, ctx, renderQueue, options).backbuffer;
|
|
73
|
+
}
|
|
74
|
+
function buildForwardPlusGraphInternal(graph, ctx, renderQueue, options) {
|
|
71
75
|
const backbuffer = graph.importTexture('backbuffer');
|
|
72
76
|
// Shared mutable frame state
|
|
73
77
|
const frame = {
|
|
@@ -75,26 +79,37 @@ function freeClusteredLight(cl) {
|
|
|
75
79
|
renderQueue,
|
|
76
80
|
depthFramebuffer: null,
|
|
77
81
|
sunLightColor: null,
|
|
78
|
-
options
|
|
82
|
+
options,
|
|
83
|
+
intermediateDeviceStatePushed: false,
|
|
84
|
+
renderQueueDisposed: false,
|
|
85
|
+
clusteredLightReleased: false,
|
|
86
|
+
sunLightRestored: false
|
|
79
87
|
};
|
|
80
88
|
// ── 1. Sky Update ─────────────────────────────────────────────────
|
|
81
|
-
graph.addPass('SkyUpdate', (builder)=>{
|
|
89
|
+
let orderToken = graph.addPass('SkyUpdate', (builder)=>{
|
|
90
|
+
const done = builder.createToken('SkyUpdateDone');
|
|
82
91
|
builder.sideEffect();
|
|
83
92
|
builder.setExecute(()=>{
|
|
84
93
|
frame.sunLightColor = ctx.scene.env.sky.update(ctx);
|
|
85
94
|
});
|
|
95
|
+
return done;
|
|
86
96
|
});
|
|
87
97
|
// ── 2. Clustered Light Setup ──────────────────────────────────────
|
|
88
|
-
graph.addPass('ClusterLights', (builder)=>{
|
|
98
|
+
orderToken = graph.addPass('ClusterLights', (builder)=>{
|
|
99
|
+
builder.read(orderToken);
|
|
100
|
+
const done = builder.createToken('ClusterLightsDone');
|
|
89
101
|
builder.sideEffect();
|
|
90
102
|
builder.setExecute(()=>{
|
|
91
103
|
ctx.clusteredLight = getClusteredLight();
|
|
92
104
|
ctx.clusteredLight.calculateLightIndex(ctx.camera, renderQueue);
|
|
93
105
|
});
|
|
106
|
+
return done;
|
|
94
107
|
});
|
|
95
108
|
// ── 3. GPU Picking (optional, sideEffect) ─────────────────────────
|
|
96
109
|
if (options.gpuPicking) {
|
|
97
|
-
graph.addPass('GPUPicking', (builder)=>{
|
|
110
|
+
orderToken = graph.addPass('GPUPicking', (builder)=>{
|
|
111
|
+
builder.read(orderToken);
|
|
112
|
+
const done = builder.createToken('GPUPickingDone');
|
|
98
113
|
builder.sideEffect();
|
|
99
114
|
builder.setExecute(()=>{
|
|
100
115
|
const pickResolveFunc = ctx.camera.getPickResultResolveFunc();
|
|
@@ -102,21 +117,26 @@ function freeClusteredLight(cl) {
|
|
|
102
117
|
renderObjectColors(ctx, pickResolveFunc, renderQueue);
|
|
103
118
|
}
|
|
104
119
|
});
|
|
120
|
+
return done;
|
|
105
121
|
});
|
|
106
122
|
}
|
|
107
123
|
// ── 4. Shadow Maps ────────────────────────────────────────────────
|
|
108
124
|
// Shadow maps are managed internally by lights, mark as side effect
|
|
109
125
|
if (renderQueue.shadowedLights.length > 0) {
|
|
110
|
-
graph.addPass('ShadowMaps', (builder)=>{
|
|
126
|
+
orderToken = graph.addPass('ShadowMaps', (builder)=>{
|
|
127
|
+
builder.read(orderToken);
|
|
128
|
+
const done = builder.createToken('ShadowMapsDone');
|
|
111
129
|
builder.sideEffect();
|
|
112
130
|
builder.setExecute(()=>{
|
|
113
131
|
renderShadowMaps(ctx, renderQueue.shadowedLights);
|
|
114
132
|
});
|
|
133
|
+
return done;
|
|
115
134
|
});
|
|
116
135
|
}
|
|
117
136
|
// ── 5. Depth Prepass ──────────────────────────────────────────────
|
|
118
137
|
// Declare transient depth and motion vector textures
|
|
119
138
|
const depthPassResult = graph.addPass('DepthPrepass', (builder)=>{
|
|
139
|
+
builder.read(orderToken);
|
|
120
140
|
const format = ctx.device.type === 'webgl' ? ctx.SSRCalcThickness ? 'rgba16f' : 'rgba8unorm' : ctx.SSRCalcThickness ? 'rg32f' : 'r32f';
|
|
121
141
|
const mvFormat = 'rgba16f';
|
|
122
142
|
const depthHandle = builder.createTexture({
|
|
@@ -127,28 +147,67 @@ function freeClusteredLight(cl) {
|
|
|
127
147
|
format: mvFormat,
|
|
128
148
|
label: 'motionVector'
|
|
129
149
|
}) : undefined;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
150
|
+
const finalDepthAttachment = ctx.finalFramebuffer?.getDepthAttachment();
|
|
151
|
+
const externalDepthAttachment = finalDepthAttachment?.isTexture2D() ? finalDepthAttachment : null;
|
|
152
|
+
const graphDepthAttachmentHandle = externalDepthAttachment ? undefined : builder.createTexture({
|
|
153
|
+
format: ctx.depthFormat,
|
|
154
|
+
label: 'sceneDepth'
|
|
155
|
+
});
|
|
156
|
+
const depthAttachmentOrFormat = externalDepthAttachment ?? graphDepthAttachmentHandle ?? ctx.depthFormat;
|
|
157
|
+
const depthFramebufferHandle = builder.createFramebuffer({
|
|
158
|
+
label: 'DepthPrepassFramebuffer',
|
|
159
|
+
width: ctx.renderWidth,
|
|
160
|
+
height: ctx.renderHeight,
|
|
161
|
+
colorAttachments: motionVectorHandle ? [
|
|
162
|
+
depthHandle,
|
|
163
|
+
motionVectorHandle
|
|
164
|
+
] : depthHandle,
|
|
165
|
+
depthAttachment: depthAttachmentOrFormat,
|
|
166
|
+
ignoreDepthStencil: false
|
|
167
|
+
});
|
|
168
|
+
const skyMotionVectorFramebufferHandle = motionVectorHandle ? builder.createFramebuffer({
|
|
169
|
+
label: 'SkyMotionVectorFramebuffer',
|
|
170
|
+
width: ctx.renderWidth,
|
|
171
|
+
height: ctx.renderHeight,
|
|
172
|
+
colorAttachments: motionVectorHandle,
|
|
173
|
+
depthAttachment: depthAttachmentOrFormat
|
|
174
|
+
}) : undefined;
|
|
175
|
+
builder.addSubpass('SceneDepth', (rgCtx)=>{
|
|
176
|
+
const depthFramebuffer = rgCtx.getFramebuffer(depthFramebufferHandle);
|
|
177
|
+
frame.depthFramebuffer = renderSceneDepth(frame, depthFramebuffer, rgCtx, undefined, undefined, false);
|
|
134
178
|
});
|
|
179
|
+
if (skyMotionVectorFramebufferHandle) {
|
|
180
|
+
builder.addSubpass('SkyMotionVectors', (rgCtx)=>{
|
|
181
|
+
renderSkyMotionVectors(ctx, rgCtx, skyMotionVectorFramebufferHandle);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
135
184
|
return {
|
|
136
185
|
depthHandle,
|
|
137
|
-
motionVectorHandle
|
|
186
|
+
motionVectorHandle,
|
|
187
|
+
graphDepthAttachmentHandle,
|
|
188
|
+
externalDepthAttachment,
|
|
189
|
+
depthFramebufferHandle
|
|
138
190
|
};
|
|
139
191
|
});
|
|
140
192
|
const depthHandle = depthPassResult.depthHandle;
|
|
141
193
|
const motionVectorHandle = depthPassResult.motionVectorHandle;
|
|
194
|
+
const renderDepthAttachment = depthPassResult.graphDepthAttachmentHandle ?? depthPassResult.externalDepthAttachment ?? null;
|
|
142
195
|
// ── 6. Hi-Z (optional) ───────────────────────────────────────────
|
|
143
196
|
let hiZHandle;
|
|
144
197
|
if (options.hiZ) {
|
|
145
198
|
graph.addPass('HiZ', (builder)=>{
|
|
146
199
|
builder.read(depthHandle);
|
|
200
|
+
builder.read(depthPassResult.depthFramebufferHandle);
|
|
147
201
|
hiZHandle = builder.createTexture({
|
|
148
202
|
format: 'r32f',
|
|
149
203
|
label: 'hiZ',
|
|
150
204
|
mipLevels: 10
|
|
151
205
|
});
|
|
206
|
+
const hiZFramebufferHandle = builder.createFramebuffer({
|
|
207
|
+
label: 'HiZFramebuffer',
|
|
208
|
+
colorAttachments: hiZHandle,
|
|
209
|
+
depthAttachment: null
|
|
210
|
+
});
|
|
152
211
|
builder.setExecute((rgCtx)=>{
|
|
153
212
|
const ctx = frame.ctx;
|
|
154
213
|
// Use the depth texture from the framebuffer (which contains the RenderGraph texture)
|
|
@@ -156,12 +215,9 @@ function freeClusteredLight(cl) {
|
|
|
156
215
|
if (depthTex) {
|
|
157
216
|
// Get the HiZ texture allocated by the executor
|
|
158
217
|
const hiZTex = rgCtx.getTexture(hiZHandle);
|
|
159
|
-
const
|
|
160
|
-
const h = hiZTex.height;
|
|
161
|
-
const HiZFrameBuffer = ctx.device.pool.fetchTemporalFramebuffer(false, w, h, hiZTex, null, false);
|
|
218
|
+
const HiZFrameBuffer = rgCtx.getFramebuffer(hiZFramebufferHandle);
|
|
162
219
|
buildHiZ(depthTex, HiZFrameBuffer);
|
|
163
220
|
ctx.HiZTexture = hiZTex;
|
|
164
|
-
ctx.device.pool.releaseFrameBuffer(HiZFrameBuffer);
|
|
165
221
|
}
|
|
166
222
|
});
|
|
167
223
|
});
|
|
@@ -169,6 +225,7 @@ function freeClusteredLight(cl) {
|
|
|
169
225
|
// ── 7. Main Light Pass ────────────────────────────────────────────
|
|
170
226
|
const lightPassResult = graph.addPass('LightPass', (builder)=>{
|
|
171
227
|
builder.read(depthHandle);
|
|
228
|
+
builder.read(depthPassResult.depthFramebufferHandle);
|
|
172
229
|
if (hiZHandle) {
|
|
173
230
|
builder.read(hiZHandle);
|
|
174
231
|
}
|
|
@@ -185,29 +242,118 @@ function freeClusteredLight(cl) {
|
|
|
185
242
|
label: 'sceneColorCopy'
|
|
186
243
|
});
|
|
187
244
|
}
|
|
245
|
+
const useFinalFramebufferAsIntermediate = !!depthPassResult.externalDepthAttachment && depthPassResult.externalDepthAttachment === ctx.finalFramebuffer?.getDepthAttachment();
|
|
246
|
+
const sceneColorFramebufferHandle = useFinalFramebufferAsIntermediate ? undefined : builder.createFramebuffer({
|
|
247
|
+
label: 'SceneColorFramebuffer',
|
|
248
|
+
width: ctx.renderWidth,
|
|
249
|
+
height: ctx.renderHeight,
|
|
250
|
+
colorAttachments: sceneColorHandle,
|
|
251
|
+
depthAttachment: renderDepthAttachment
|
|
252
|
+
});
|
|
253
|
+
const sceneColorCopyFramebufferHandle = sceneColorCopyHandle ? builder.createFramebuffer({
|
|
254
|
+
label: 'SceneColorCopyFramebuffer',
|
|
255
|
+
width: ctx.renderWidth,
|
|
256
|
+
height: ctx.renderHeight,
|
|
257
|
+
colorAttachments: sceneColorCopyHandle,
|
|
258
|
+
depthAttachment: renderDepthAttachment,
|
|
259
|
+
ignoreDepthStencil: false
|
|
260
|
+
}) : undefined;
|
|
188
261
|
builder.setExecute((rgCtx)=>{
|
|
189
262
|
const sceneColorTex = rgCtx.getTexture(sceneColorHandle);
|
|
190
263
|
const sceneColorCopyTex = sceneColorCopyHandle ? rgCtx.getTexture(sceneColorCopyHandle) : null;
|
|
191
|
-
renderMainLightPass(frame, sceneColorTex, sceneColorCopyTex);
|
|
264
|
+
renderMainLightPass(frame, sceneColorTex, sceneColorCopyTex, rgCtx, sceneColorFramebufferHandle, sceneColorCopyFramebufferHandle);
|
|
192
265
|
});
|
|
193
266
|
return {
|
|
194
267
|
sceneColorHandle,
|
|
195
|
-
sceneColorCopyHandle
|
|
268
|
+
sceneColorCopyHandle,
|
|
269
|
+
sceneColorFramebufferHandle
|
|
196
270
|
};
|
|
197
271
|
});
|
|
198
272
|
const sceneColorHandle = lightPassResult.sceneColorHandle;
|
|
199
|
-
|
|
200
|
-
|
|
273
|
+
const historyManager = ctx.camera?.getHistoryResourceManager?.() ?? null;
|
|
274
|
+
const historyReadBindings = [];
|
|
275
|
+
if (historyManager && ctx.camera?.TAA && options.motionVectors) {
|
|
276
|
+
const historySize = {
|
|
277
|
+
width: ctx.renderWidth,
|
|
278
|
+
height: ctx.renderHeight
|
|
279
|
+
};
|
|
280
|
+
const colorHistoryHandle = historyManager.importPreviousIfCompatible(graph, RGHistoryResources.TAA_COLOR, {
|
|
281
|
+
format: ctx.colorFormat,
|
|
282
|
+
sizeMode: 'absolute',
|
|
283
|
+
width: ctx.renderWidth,
|
|
284
|
+
height: ctx.renderHeight
|
|
285
|
+
}, historySize);
|
|
286
|
+
const motionVectorHistoryHandle = historyManager.importPreviousIfCompatible(graph, RGHistoryResources.TAA_MOTION_VECTOR, {
|
|
287
|
+
format: 'rgba16f',
|
|
288
|
+
sizeMode: 'absolute',
|
|
289
|
+
width: ctx.renderWidth,
|
|
290
|
+
height: ctx.renderHeight
|
|
291
|
+
}, historySize);
|
|
292
|
+
if (colorHistoryHandle && motionVectorHistoryHandle) {
|
|
293
|
+
historyReadBindings.push({
|
|
294
|
+
name: RGHistoryResources.TAA_COLOR,
|
|
295
|
+
handle: colorHistoryHandle
|
|
296
|
+
}, {
|
|
297
|
+
name: RGHistoryResources.TAA_MOTION_VECTOR,
|
|
298
|
+
handle: motionVectorHistoryHandle
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// 8. Transmission depth pass (optional)
|
|
303
|
+
let transmissionDepthToken;
|
|
304
|
+
if (options.needSceneColor) {
|
|
305
|
+
transmissionDepthToken = graph.addPass('TransmissionDepth', (builder)=>{
|
|
306
|
+
builder.read(sceneColorHandle);
|
|
307
|
+
builder.read(depthPassResult.depthFramebufferHandle);
|
|
308
|
+
const done = builder.createToken('TransmissionDepthDone');
|
|
309
|
+
builder.sideEffect();
|
|
310
|
+
builder.setExecute((rgCtx)=>{
|
|
311
|
+
renderTransmissionDepthPass(frame, rgCtx);
|
|
312
|
+
});
|
|
313
|
+
return done;
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
// 9. Post effects + final composite
|
|
317
|
+
const presentedBackbuffer = graph.addPass('Composite', (builder)=>{
|
|
201
318
|
builder.read(sceneColorHandle);
|
|
319
|
+
builder.read(depthHandle);
|
|
320
|
+
if (hiZHandle) {
|
|
321
|
+
builder.read(hiZHandle);
|
|
322
|
+
}
|
|
202
323
|
if (motionVectorHandle) {
|
|
203
324
|
builder.read(motionVectorHandle);
|
|
204
325
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
326
|
+
if (lightPassResult.sceneColorFramebufferHandle) {
|
|
327
|
+
builder.read(lightPassResult.sceneColorFramebufferHandle);
|
|
328
|
+
}
|
|
329
|
+
if (transmissionDepthToken) {
|
|
330
|
+
builder.read(transmissionDepthToken);
|
|
331
|
+
}
|
|
332
|
+
for (const binding of historyReadBindings){
|
|
333
|
+
builder.read(binding.handle);
|
|
334
|
+
}
|
|
335
|
+
const outputBackbuffer = builder.write(backbuffer);
|
|
336
|
+
builder.setExecute((rgCtx)=>{
|
|
337
|
+
if (historyManager && historyReadBindings.length > 0) {
|
|
338
|
+
historyManager.beginReadScope(historyReadBindings.map((binding)=>({
|
|
339
|
+
name: binding.name,
|
|
340
|
+
texture: rgCtx.getTexture(binding.handle)
|
|
341
|
+
})));
|
|
342
|
+
try {
|
|
343
|
+
renderComposite(frame);
|
|
344
|
+
} finally{
|
|
345
|
+
historyManager.endReadScope();
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
renderComposite(frame);
|
|
349
|
+
}
|
|
208
350
|
});
|
|
351
|
+
return outputBackbuffer;
|
|
209
352
|
});
|
|
210
|
-
return
|
|
353
|
+
return {
|
|
354
|
+
backbuffer: presentedBackbuffer,
|
|
355
|
+
frame
|
|
356
|
+
};
|
|
211
357
|
}
|
|
212
358
|
// ─── Pass Implementation Helpers ────────────────────────────────────
|
|
213
359
|
// These wrap the existing SceneRenderer static methods, adapted to work
|
|
@@ -216,82 +362,140 @@ function freeClusteredLight(cl) {
|
|
|
216
362
|
/** @internal */ function renderShadowMaps(ctx, lights) {
|
|
217
363
|
ctx.renderPass = _shadowMapPass;
|
|
218
364
|
ctx.device.pushDeviceStates();
|
|
219
|
-
|
|
220
|
-
|
|
365
|
+
try {
|
|
366
|
+
for (const light of lights){
|
|
367
|
+
light.shadow.render(ctx, _shadowMapPass);
|
|
368
|
+
}
|
|
369
|
+
} finally{
|
|
370
|
+
ctx.device.popDeviceStates();
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
function releaseIntermediateFramebuffer(frame) {
|
|
374
|
+
const { ctx } = frame;
|
|
375
|
+
if (frame.intermediateDeviceStatePushed) {
|
|
376
|
+
ctx.device.popDeviceStates();
|
|
377
|
+
frame.intermediateDeviceStatePushed = false;
|
|
221
378
|
}
|
|
222
|
-
ctx.
|
|
379
|
+
ctx.intermediateFramebuffer = null;
|
|
223
380
|
}
|
|
224
|
-
|
|
381
|
+
function releaseDepthFramebuffer(frame) {
|
|
382
|
+
frame.depthFramebuffer = null;
|
|
383
|
+
}
|
|
384
|
+
function disposeRenderQueue(frame) {
|
|
385
|
+
if (!frame.renderQueueDisposed) {
|
|
386
|
+
frame.renderQueue.dispose();
|
|
387
|
+
frame.renderQueueDisposed = true;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function releaseClusteredLight(frame) {
|
|
391
|
+
if (!frame.clusteredLightReleased && frame.ctx.clusteredLight) {
|
|
392
|
+
freeClusteredLight(frame.ctx.clusteredLight);
|
|
393
|
+
frame.ctx.clusteredLight = undefined;
|
|
394
|
+
frame.clusteredLightReleased = true;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function restoreSunLight(frame) {
|
|
398
|
+
if (!frame.sunLightRestored && frame.sunLightColor && frame.ctx.sunLight) {
|
|
399
|
+
frame.ctx.sunLight.color = frame.sunLightColor;
|
|
400
|
+
frame.sunLightRestored = true;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
function cleanupFrame(frame) {
|
|
404
|
+
releaseIntermediateFramebuffer(frame);
|
|
405
|
+
releaseDepthFramebuffer(frame);
|
|
406
|
+
releaseClusteredLight(frame);
|
|
407
|
+
disposeRenderQueue(frame);
|
|
408
|
+
restoreSunLight(frame);
|
|
409
|
+
}
|
|
410
|
+
/** @internal */ function renderSceneDepth(frame, existingDepthFb, rgCtx, depthTex, motionVectorTex, transmissionOverride) {
|
|
225
411
|
const ctx = frame.ctx;
|
|
226
412
|
const renderQueue = frame.renderQueue;
|
|
227
|
-
const transmission = !!existingDepthFb;
|
|
413
|
+
const transmission = transmissionOverride ?? !!existingDepthFb;
|
|
228
414
|
let depthFramebuffer = existingDepthFb;
|
|
229
415
|
if (!depthFramebuffer) {
|
|
230
416
|
// Use RenderGraph-allocated textures if provided
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
depthTex,
|
|
234
|
-
motionVectorTex
|
|
235
|
-
] : depthTex;
|
|
236
|
-
const depthAttachment = ctx.finalFramebuffer?.getDepthAttachment();
|
|
237
|
-
const depthTexOrFormat = depthAttachment?.isTexture2D() ? depthAttachment : ctx.depthFormat;
|
|
238
|
-
depthFramebuffer = ctx.device.pool.fetchTemporalFramebuffer(true, depthTex.width, depthTex.height, colorAttachments, depthTexOrFormat, false);
|
|
239
|
-
} else {
|
|
240
|
-
// Fallback: allocate from pool (legacy path)
|
|
417
|
+
{
|
|
418
|
+
// Allocate through RenderGraph so framebuffer lifetime is owned by the executor.
|
|
241
419
|
const format = ctx.device.type === 'webgl' ? ctx.SSRCalcThickness ? 'rgba16f' : 'rgba8unorm' : ctx.SSRCalcThickness ? 'rg32f' : 'r32f';
|
|
242
420
|
const mvFormat = 'rgba16f';
|
|
243
421
|
if (!ctx.finalFramebuffer) {
|
|
244
|
-
depthFramebuffer =
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
422
|
+
depthFramebuffer = rgCtx.createFramebuffer({
|
|
423
|
+
width: ctx.renderWidth,
|
|
424
|
+
height: ctx.renderHeight,
|
|
425
|
+
colorAttachments: ctx.motionVectors ? [
|
|
426
|
+
format,
|
|
427
|
+
mvFormat
|
|
428
|
+
] : format,
|
|
429
|
+
depthAttachment: ctx.depthFormat,
|
|
430
|
+
ignoreDepthStencil: false
|
|
431
|
+
});
|
|
248
432
|
} else {
|
|
249
433
|
const originDepth = ctx.finalFramebuffer?.getDepthAttachment();
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
434
|
+
if (originDepth?.isTexture2D()) {
|
|
435
|
+
depthFramebuffer = rgCtx.createFramebuffer({
|
|
436
|
+
width: originDepth.width,
|
|
437
|
+
height: originDepth.height,
|
|
438
|
+
colorAttachments: ctx.motionVectors ? [
|
|
439
|
+
format,
|
|
440
|
+
mvFormat
|
|
441
|
+
] : format,
|
|
442
|
+
depthAttachment: originDepth,
|
|
443
|
+
ignoreDepthStencil: false
|
|
444
|
+
});
|
|
445
|
+
} else {
|
|
446
|
+
depthFramebuffer = rgCtx.createFramebuffer({
|
|
447
|
+
width: ctx.renderWidth,
|
|
448
|
+
height: ctx.renderHeight,
|
|
449
|
+
colorAttachments: ctx.motionVectors ? [
|
|
450
|
+
format,
|
|
451
|
+
mvFormat
|
|
452
|
+
] : format,
|
|
453
|
+
depthAttachment: ctx.depthFormat,
|
|
454
|
+
ignoreDepthStencil: false
|
|
455
|
+
});
|
|
456
|
+
}
|
|
257
457
|
}
|
|
258
458
|
}
|
|
259
459
|
}
|
|
460
|
+
if (!transmission) {
|
|
461
|
+
frame.depthFramebuffer = depthFramebuffer;
|
|
462
|
+
}
|
|
260
463
|
ctx.device.pushDeviceStates();
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (!
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
464
|
+
try {
|
|
465
|
+
ctx.device.setFramebuffer(depthFramebuffer);
|
|
466
|
+
_depthPass.encodeDepth = depthFramebuffer.getColorAttachments()[0].format === 'rgba8unorm';
|
|
467
|
+
_depthPass.clearColor = transmission ? null : _depthPass.encodeDepth ? new Vector4(0, 0, 0, 1) : new Vector4(1, 1, 1, 1);
|
|
468
|
+
_depthPass.clearDepth = transmission ? null : 1;
|
|
469
|
+
_depthPass.clearStencil = null;
|
|
470
|
+
_depthPass.transmission = transmission;
|
|
471
|
+
if (ctx.SSRCalcThickness && !transmission) {
|
|
472
|
+
if (!_backDepthColorState) {
|
|
473
|
+
_backDepthColorState = ctx.device.createColorState().setColorMask(false, true, false, false);
|
|
474
|
+
}
|
|
475
|
+
if (!_frontDepthColorState) {
|
|
476
|
+
_frontDepthColorState = ctx.device.createColorState().setColorMask(true, false, false, false);
|
|
477
|
+
}
|
|
478
|
+
ctx.forceColorState = _backDepthColorState;
|
|
479
|
+
ctx.forceCullMode = 'front';
|
|
480
|
+
_depthPass.renderBackface = true;
|
|
481
|
+
_depthPass.transmission = false;
|
|
482
|
+
_depthPass.render(ctx, null, null, renderQueue);
|
|
483
|
+
_depthPass.clearColor = null;
|
|
484
|
+
_depthPass.renderBackface = false;
|
|
485
|
+
ctx.forceColorState = _frontDepthColorState;
|
|
486
|
+
ctx.forceCullMode = null;
|
|
273
487
|
}
|
|
274
|
-
ctx.forceColorState = _backDepthColorState;
|
|
275
|
-
ctx.forceCullMode = 'front';
|
|
276
|
-
_depthPass.renderBackface = true;
|
|
277
|
-
_depthPass.transmission = false;
|
|
278
488
|
_depthPass.render(ctx, null, null, renderQueue);
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
ctx.forceColorState = _frontDepthColorState;
|
|
489
|
+
} finally{
|
|
490
|
+
ctx.forceColorState = null;
|
|
282
491
|
ctx.forceCullMode = null;
|
|
492
|
+
_depthPass.renderBackface = false;
|
|
493
|
+
ctx.device.popDeviceStates();
|
|
283
494
|
}
|
|
284
|
-
_depthPass.render(ctx, null, null, renderQueue);
|
|
285
|
-
ctx.forceColorState = null;
|
|
286
|
-
ctx.device.popDeviceStates();
|
|
287
495
|
if (!transmission) {
|
|
288
496
|
ctx.motionVectorTexture = ctx.motionVectors ? depthFramebuffer.getColorAttachments()[1] : null;
|
|
289
497
|
ctx.linearDepthTexture = depthFramebuffer.getColorAttachments()[0];
|
|
290
498
|
ctx.depthTexture = depthFramebuffer.getDepthAttachment();
|
|
291
|
-
if (ctx.motionVectorTexture) {
|
|
292
|
-
// Sky motion vectors rendering is handled inline
|
|
293
|
-
renderSkyMotionVectors(ctx);
|
|
294
|
-
}
|
|
295
499
|
// HiZ is now built in the dedicated HiZ pass
|
|
296
500
|
}
|
|
297
501
|
return depthFramebuffer;
|
|
@@ -300,12 +504,15 @@ function freeClusteredLight(cl) {
|
|
|
300
504
|
let _skyMVProgram = null;
|
|
301
505
|
let _skyMVBindGroup = null;
|
|
302
506
|
let _skyMVBox = null;
|
|
303
|
-
/** @internal */ function renderSkyMotionVectors(ctx) {
|
|
507
|
+
/** @internal */ function renderSkyMotionVectors(ctx, rgCtx, framebufferHandle) {
|
|
304
508
|
if (!ctx.motionVectorTexture) {
|
|
305
509
|
return;
|
|
306
510
|
}
|
|
307
511
|
const device = ctx.device;
|
|
308
|
-
const fb =
|
|
512
|
+
const fb = framebufferHandle ? rgCtx.getFramebuffer(framebufferHandle) : rgCtx.createFramebuffer({
|
|
513
|
+
colorAttachments: ctx.motionVectorTexture,
|
|
514
|
+
depthAttachment: ctx.depthTexture
|
|
515
|
+
});
|
|
309
516
|
if (!_skyMVProgram) {
|
|
310
517
|
_skyMVProgram = device.buildRenderProgram({
|
|
311
518
|
vertex (pb) {
|
|
@@ -356,20 +563,27 @@ let _skyMVBox = null;
|
|
|
356
563
|
device.setFramebuffer(fb);
|
|
357
564
|
_skyMVBox.draw();
|
|
358
565
|
device.popDeviceStates();
|
|
359
|
-
device.pool.releaseFrameBuffer(fb);
|
|
360
566
|
}
|
|
361
|
-
/** @internal */ function renderMainLightPass(frame, sceneColorTex, sceneColorCopyTex) {
|
|
567
|
+
/** @internal */ function renderMainLightPass(frame, sceneColorTex, sceneColorCopyTex, rgCtx, sceneColorFramebufferHandle, sceneColorCopyFramebufferHandle) {
|
|
362
568
|
const { ctx, renderQueue } = frame;
|
|
363
569
|
const device = ctx.device;
|
|
364
570
|
// Use RenderGraph-allocated scene color texture
|
|
365
571
|
const depthTex = frame.depthFramebuffer?.getDepthAttachment();
|
|
366
572
|
if (depthTex === ctx.finalFramebuffer?.getDepthAttachment()) {
|
|
367
573
|
ctx.intermediateFramebuffer = ctx.finalFramebuffer;
|
|
574
|
+
} else if (sceneColorFramebufferHandle) {
|
|
575
|
+
ctx.intermediateFramebuffer = rgCtx.getFramebuffer(sceneColorFramebufferHandle);
|
|
368
576
|
} else {
|
|
369
|
-
ctx.intermediateFramebuffer =
|
|
577
|
+
ctx.intermediateFramebuffer = rgCtx.createFramebuffer({
|
|
578
|
+
width: sceneColorTex.width,
|
|
579
|
+
height: sceneColorTex.height,
|
|
580
|
+
colorAttachments: sceneColorTex,
|
|
581
|
+
depthAttachment: depthTex
|
|
582
|
+
});
|
|
370
583
|
}
|
|
371
584
|
if (ctx.intermediateFramebuffer && ctx.intermediateFramebuffer !== ctx.finalFramebuffer) {
|
|
372
585
|
device.pushDeviceStates();
|
|
586
|
+
frame.intermediateDeviceStatePushed = true;
|
|
373
587
|
device.setFramebuffer(ctx.intermediateFramebuffer);
|
|
374
588
|
} else {
|
|
375
589
|
device.setViewport(null);
|
|
@@ -386,48 +600,58 @@ let _skyMVBox = null;
|
|
|
386
600
|
const compositor = ctx.compositor;
|
|
387
601
|
ctx.compositor = null;
|
|
388
602
|
// Use RenderGraph-allocated sceneColorCopy texture
|
|
389
|
-
const sceneColorFramebuffer =
|
|
390
|
-
sceneColorCopyTex,
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
603
|
+
const sceneColorFramebuffer = sceneColorCopyFramebufferHandle && !(ctx.materialFlags & MaterialVaryingFlags.SSR_STORE_ROUGHNESS) ? rgCtx.getFramebuffer(sceneColorCopyFramebufferHandle) : rgCtx.createFramebuffer({
|
|
604
|
+
width: sceneColorCopyTex.width,
|
|
605
|
+
height: sceneColorCopyTex.height,
|
|
606
|
+
colorAttachments: ctx.materialFlags & MaterialVaryingFlags.SSR_STORE_ROUGHNESS ? [
|
|
607
|
+
sceneColorCopyTex,
|
|
608
|
+
device.getFramebuffer().getColorAttachments()[1],
|
|
609
|
+
device.getFramebuffer().getColorAttachments()[2]
|
|
610
|
+
] : sceneColorCopyTex,
|
|
611
|
+
depthAttachment: depthTex,
|
|
612
|
+
ignoreDepthStencil: false
|
|
613
|
+
});
|
|
614
|
+
let sceneColorStatePushed = false;
|
|
615
|
+
try {
|
|
616
|
+
device.pushDeviceStates();
|
|
617
|
+
sceneColorStatePushed = true;
|
|
618
|
+
device.setFramebuffer(sceneColorFramebuffer);
|
|
619
|
+
_scenePass.transmission = false;
|
|
620
|
+
_scenePass.render(ctx, null, null, renderQueue);
|
|
621
|
+
} finally{
|
|
622
|
+
if (sceneColorStatePushed) {
|
|
623
|
+
device.popDeviceStates();
|
|
624
|
+
}
|
|
625
|
+
ctx.compositor = compositor;
|
|
626
|
+
}
|
|
399
627
|
ctx.sceneColorTexture = sceneColorCopyTex;
|
|
400
628
|
new CopyBlitter().blit(ctx.sceneColorTexture, device.getFramebuffer() ?? null, fetchSampler('clamp_nearest_nomip'));
|
|
401
629
|
_scenePass.transmission = true;
|
|
402
630
|
_scenePass.clearColor = null;
|
|
403
631
|
_scenePass.clearDepth = null;
|
|
404
632
|
_scenePass.clearStencil = null;
|
|
405
|
-
ctx.compositor = compositor;
|
|
406
633
|
}
|
|
407
634
|
_scenePass.render(ctx, null, null, renderQueue);
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
635
|
+
}
|
|
636
|
+
/** @internal */ function renderTransmissionDepthPass(frame, rgCtx) {
|
|
637
|
+
renderSceneDepth(frame, frame.depthFramebuffer, rgCtx);
|
|
411
638
|
}
|
|
412
639
|
/** @internal */ function renderComposite(frame) {
|
|
413
|
-
const { ctx
|
|
414
|
-
const device = ctx.device;
|
|
640
|
+
const { ctx } = frame;
|
|
415
641
|
ctx.compositor?.drawPostEffects(ctx, PostEffectLayer.end, ctx.linearDepthTexture);
|
|
416
642
|
ctx.compositor?.end(ctx);
|
|
417
|
-
|
|
643
|
+
disposeRenderQueue(frame);
|
|
418
644
|
ctx.materialFlags &= ~MaterialVaryingFlags.SSR_STORE_ROUGHNESS;
|
|
419
645
|
if (ctx.intermediateFramebuffer && ctx.intermediateFramebuffer !== ctx.finalFramebuffer) {
|
|
420
646
|
const blitter = new CopyBlitter();
|
|
421
647
|
blitter.srgbOut = !ctx.finalFramebuffer;
|
|
422
648
|
const srcTex = ctx.intermediateFramebuffer.getColorAttachments()[0];
|
|
423
649
|
blitter.blit(srcTex, ctx.finalFramebuffer ?? null, fetchSampler('clamp_nearest_nomip'));
|
|
424
|
-
device.popDeviceStates();
|
|
425
|
-
device.pool.releaseFrameBuffer(ctx.intermediateFramebuffer);
|
|
426
|
-
}
|
|
427
|
-
freeClusteredLight(ctx.clusteredLight);
|
|
428
|
-
if (frame.sunLightColor) {
|
|
429
|
-
ctx.sunLight.color = frame.sunLightColor;
|
|
430
650
|
}
|
|
651
|
+
releaseIntermediateFramebuffer(frame);
|
|
652
|
+
releaseDepthFramebuffer(frame);
|
|
653
|
+
releaseClusteredLight(frame);
|
|
654
|
+
restoreSunLight(frame);
|
|
431
655
|
}
|
|
432
656
|
// ─── Convenience: Execute Full Pipeline ─────────────────────────────
|
|
433
657
|
/**
|
|
@@ -449,7 +673,8 @@ let _skyMVBox = null;
|
|
|
449
673
|
historyManager = new HistoryResourceManager(_devicePoolAllocator);
|
|
450
674
|
ctx.camera.setHistoryResourceManager(historyManager);
|
|
451
675
|
}
|
|
452
|
-
|
|
676
|
+
historyManager.beginFrame();
|
|
677
|
+
const { backbuffer, frame } = buildForwardPlusGraphInternal(graph, ctx, renderQueue, options);
|
|
453
678
|
const compiled = graph.compile([
|
|
454
679
|
backbuffer
|
|
455
680
|
]);
|
|
@@ -460,10 +685,15 @@ let _skyMVBox = null;
|
|
|
460
685
|
const backbufferTex = ctx.finalFramebuffer.getColorAttachments()[0];
|
|
461
686
|
executor.setImportedTexture(backbuffer, backbufferTex);
|
|
462
687
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
688
|
+
historyManager.bindImportedTextures(executor);
|
|
689
|
+
try {
|
|
690
|
+
executor.execute(compiled);
|
|
691
|
+
historyManager.commitFrame();
|
|
692
|
+
} finally{
|
|
693
|
+
historyManager.discardFrame();
|
|
694
|
+
cleanupFrame(frame);
|
|
695
|
+
executor.reset();
|
|
696
|
+
}
|
|
467
697
|
}
|
|
468
698
|
|
|
469
699
|
export { buildForwardPlusGraph, deriveForwardPlusOptions, executeForwardPlusGraph };
|