@@ -58,13 +58,23 @@ import {
5858 Marker ,
5959 VectorNetwork ,
6060} from '../components' ;
61- import { paddingMat3 } from '../utils' ;
61+ import { paddingMat3 , SerializedNode } from '../utils' ;
6262import { GridRenderer } from './GridRenderer' ;
6363import { BatchManager } from './BatchManager' ;
6464import { getSceneRoot } from './Transform' ;
6565import { safeAddComponent } from '../history' ;
66+ import { SetupDevice } from './SetupDevice' ;
67+
68+ type GPURenderer = {
69+ uniformBuffer : Buffer ;
70+ uniformLegacyObject : Record < string , unknown > ;
71+ gridRenderer : GridRenderer ;
72+ batchManager : BatchManager ;
73+ } ;
6674
6775export class MeshPipeline extends System {
76+ private setupDevice = this . attach ( SetupDevice ) ;
77+
6878 private canvases = this . query ( ( q ) => q . current . with ( Canvas ) . read ) ;
6979
7080 private cameras = this . query (
@@ -163,7 +173,7 @@ export class MeshPipeline extends System {
163173 ( q ) => q . addedChangedOrRemoved . with ( Marker ) . trackWrites ,
164174 ) ;
165175
166- gpuResources : Map <
176+ renderers : Map <
167177 Entity ,
168178 {
169179 uniformBuffer : Buffer ;
@@ -253,64 +263,73 @@ export class MeshPipeline extends System {
253263 canvas . remove ( RasterScreenshotRequest ) ;
254264 }
255265
266+ private createRenderer ( gpuResource : GPUResource ) {
267+ const { device, renderCache, texturePool } = gpuResource ;
268+ return {
269+ uniformBuffer : device . createBuffer ( {
270+ viewOrSize : ( 16 * 3 + 4 * 5 ) * Float32Array . BYTES_PER_ELEMENT ,
271+ usage : BufferUsage . UNIFORM ,
272+ hint : BufferFrequencyHint . DYNAMIC ,
273+ } ) ,
274+ uniformLegacyObject : null ,
275+ gridRenderer : new GridRenderer ( ) ,
276+ batchManager : new BatchManager ( device , renderCache , texturePool ) ,
277+ } ;
278+ }
279+
256280 private renderCamera ( canvas : Entity , camera : Entity , sort = false ) {
257281 if ( ! canvas . has ( GPUResource ) ) {
258282 return ;
259283 }
260284
261- const {
262- swapChain,
263- device,
264- renderTarget,
265- depthRenderTarget,
266- renderCache,
267- texturePool,
268- } = canvas . read ( GPUResource ) ;
269-
270285 const request = canvas . has ( RasterScreenshotRequest )
271286 ? canvas . read ( RasterScreenshotRequest )
272287 : null ;
273-
274- const { type, encoderOptions, grid, download } = request ?? {
288+ const { type, encoderOptions, grid, download, nodes } = request ?? {
275289 type : 'image/png' ,
276290 encoderOptions : 1 ,
277291 grid : false ,
292+ nodes : [ ] ,
278293 } ;
294+ const shouldRenderGrid = ! request || grid ;
295+ const shouldRenderPartially = nodes . length > 0 ;
296+
297+ let renderer : GPURenderer ;
298+ let gpuResource : GPUResource ;
299+ if ( shouldRenderPartially ) {
300+ // Render to offscreen canvas.
301+ gpuResource = this . setupDevice . getOffscreenGPUResource ( ) ;
302+ renderer = this . createRenderer ( gpuResource ) ;
303+ } else {
304+ gpuResource = canvas . read ( GPUResource ) ;
305+ if ( ! this . renderers . get ( camera ) ) {
306+ this . renderers . set ( camera , this . createRenderer ( gpuResource ) ) ;
307+ }
308+ renderer = this . renderers . get ( camera ) ;
309+ const { batchManager } = renderer ;
310+ if ( request ) {
311+ batchManager . hideUIs ( ) ;
312+ }
313+ }
314+
315+ const { swapChain, device, renderTarget, depthRenderTarget } = gpuResource ;
316+ const { uniformBuffer, uniformLegacyObject, gridRenderer, batchManager } =
317+ renderer ;
279318
280319 const { width, height } = swapChain . getCanvas ( ) ;
281320 const onscreenTexture = swapChain . getOnscreenTexture ( ) ;
282321
283- const shouldRenderGrid = ! request || grid ;
284-
285- // console.log(request, grid);
286-
287- if ( ! this . gpuResources . get ( camera ) ) {
288- this . gpuResources . set ( camera , {
289- uniformBuffer : device . createBuffer ( {
290- viewOrSize : ( 16 * 3 + 4 * 5 ) * Float32Array . BYTES_PER_ELEMENT ,
291- usage : BufferUsage . UNIFORM ,
292- hint : BufferFrequencyHint . DYNAMIC ,
293- } ) ,
294- uniformLegacyObject : null ,
295- gridRenderer : new GridRenderer ( ) ,
296- batchManager : new BatchManager ( device , renderCache , texturePool ) ,
297- } ) ;
298- }
299-
300322 const [ buffer , legacyObject ] = this . updateUniform (
301323 canvas ,
302324 camera ,
303325 shouldRenderGrid ,
304326 swapChain ,
305327 ) ;
306- this . gpuResources . set ( camera , {
307- ...this . gpuResources . get ( camera ) ,
328+ this . renderers . set ( camera , {
329+ ...this . renderers . get ( camera ) ,
308330 uniformLegacyObject : legacyObject ,
309331 } ) ;
310332
311- const { uniformBuffer, uniformLegacyObject, gridRenderer, batchManager } =
312- this . gpuResources . get ( camera ) ;
313-
314333 uniformBuffer . setSubData ( 0 , new Uint8Array ( buffer . buffer ) ) ;
315334
316335 device . beginFrame ( ) ;
@@ -326,15 +345,23 @@ export class MeshPipeline extends System {
326345
327346 gridRenderer . render ( device , renderPass , uniformBuffer , uniformLegacyObject ) ;
328347
329- if ( this . pendingRenderables . has ( camera ) ) {
330- this . pendingRenderables . get ( camera ) . forEach ( ( { type, entity } ) => {
331- if ( type === 'remove' ) {
332- batchManager . remove ( entity , ! entity . has ( Culled ) ) ;
333- } else {
334- batchManager . add ( entity ) ;
335- }
348+ if ( shouldRenderPartially ) {
349+ const { api } = canvas . read ( Canvas ) ;
350+ nodes . forEach ( ( node : SerializedNode ) => {
351+ const entity = api . getEntity ( node ) ;
352+ batchManager . add ( entity ) ;
336353 } ) ;
337- this . pendingRenderables . delete ( camera ) ;
354+ } else {
355+ if ( this . pendingRenderables . has ( camera ) ) {
356+ this . pendingRenderables . get ( camera ) . forEach ( ( { type, entity } ) => {
357+ if ( type === 'remove' ) {
358+ batchManager . remove ( entity , ! entity . has ( Culled ) ) ;
359+ } else {
360+ batchManager . add ( entity ) ;
361+ }
362+ } ) ;
363+ this . pendingRenderables . delete ( camera ) ;
364+ }
338365 }
339366
340367 if ( sort ) {
@@ -351,6 +378,7 @@ export class MeshPipeline extends System {
351378 encoderOptions ,
352379 ) ;
353380 this . setScreenshotTrigger ( canvas , dataURL , download ) ;
381+ batchManager . showUIs ( ) ;
354382 }
355383 }
356384
@@ -476,7 +504,7 @@ export class MeshPipeline extends System {
476504 }
477505
478506 finalize ( ) {
479- this . gpuResources . forEach ( ( { gridRenderer, batchManager } ) => {
507+ this . renderers . forEach ( ( { gridRenderer, batchManager } ) => {
480508 gridRenderer . destroy ( ) ;
481509 batchManager . clear ( ) ;
482510 batchManager . destroy ( ) ;
0 commit comments