Small World Engine API Reference - v0.78.00
    Preparing search index...

    Class WebGPURenderer

    Modern WebGPU implementation with dynamic vertex updates and memory management.

    Hierarchy (View Summary)

    Index
    _activeCubeFace: number = 0
    _adapter: GPUAdapter | undefined = undefined
    _clearColor: Color = ...

    The clear color of the renderer.

    _frameCount: number = 0
    _gpuInstanceBuffers: WeakMap<InstancedMesh, GPUBuffer> = ...
    _gpuInstanceDataBuffers: WeakMap<InstancedMesh, GPUBuffer> = ...
    _lightData: LightDataInterface = ...

    Cached light data to avoid GC pressure.

    _materialBindGroups: Map<string, { bg: GPUBindGroup; resources: unknown[] }> = ...
    _opaqueTextures: WeakMap<
        object,
        { height: number; tex: GPUTexture; view: GPUTextureView; width: number },
    > = ...
    _passes: RenderPass[] = []
    _quality: QualityConfig = ...

    Global quality settings.

    _renderTargetCubeTextures: Map<
        RenderTargetCube,
        {
            cubeView: GPUTextureView;
            depth?: GPUTexture;
            depthView?: GPUTextureView;
            faceViews: GPUTextureView[];
            tex: GPUTexture;
        },
    > = ...
    _renderTargetTextures: Map<
        RenderTarget,
        {
            depth?: GPUTexture;
            depthView?: GPUTextureView;
            tex: GPUTexture;
            view: GPUTextureView;
        },
    > = ...
    _scratchAreaLightData: Float32Array<ArrayBuffer> = ...
    _scratchColorArray: Float32Array<ArrayBuffer> = ...
    _scratchModelMatrix: Float32Array<ArrayBuffer> = ...
    _scratchObjBufferData: Float32Array<ArrayBuffer> = ...
    _scratchPointLightData: Float32Array<ArrayBuffer> = ...
    _scratchSpotLightData: Float32Array<ArrayBuffer> = ...
    _scratchUniformValues: Record<string, unknown> = {}
    _screenOpaqueTexture?: {
        height: number;
        tex: GPUTexture;
        view: GPUTextureView;
        width: number;
    }

    Per-instance bundle of DeviceCaps/ShaderRegistry/AssetManager -- see RendererContext.

    onContextLost?: (info: { message?: string; reason?: string }) => void

    Optional callback triggered when the GPU context is lost.

    postProcessing: PostProcessingGroup = ...

    The global post processing volume/group.

    type: RendererType = RendererType.WEB_GPU

    The type of the renderer.

    • get currentColorTargetFormat(): GPUTextureFormat

      The color-target format any RenderPipeline drawing into the CURRENTLY bound target must be built for -- i.e. whatever render()'s own view resolution (see the isOffscreen block around _activeRenderTarget) will actually bind this frame. A custom offscreen RenderTarget (e.g. PlanarReflectionNode.renderTarget) is always backed by a this._format texture, regardless of postProcessing.enabled -- only the main scene pass (no active render target) targets the "rgba16float" HDR intermediate buffer when post-processing is on. Single source of truth for this decision: anything that needs to match the pipeline format _renderSubgroup() will request in the current context (e.g. a shadow pass's own throwaway dummy color attachment) must read this getter too, rather than re-deriving the same decision from postProcessing.enabled alone and silently drifting out of sync with it whenever something renders into a custom RenderTarget (see CascadedShadowPassGPU/SpotShadowPassGPU, which used to do exactly that).

      Returns GPUTextureFormat

    • get defaultDirShadowTextureView(): GPUTextureView

      Read by the fragment shader's global bind group; reassigned once by CascadedShadowPassGPU when a real cascaded shadow map first exists.

      Returns GPUTextureView

    • set defaultDirShadowTextureView(view: GPUTextureView): void

      Parameters

      • view: GPUTextureView

      Returns void

    • get defaultSpotShadowTextureView(): GPUTextureView

      Read by the fragment shader's global bind group; reassigned once by SpotShadowPassGPU when a real spot shadow map first exists.

      Returns GPUTextureView

    • set defaultSpotShadowTextureView(view: GPUTextureView): void

      Parameters

      • view: GPUTextureView

      Returns void

    • get globalBindGroup(): GPUBindGroup

      Rebuilt once (not per-frame) by a shadow pass, the first time a real shadow map for that light type exists -- see CascadedShadowPassGPU/SpotShadowPassGPU.

      Returns GPUBindGroup

    • set globalBindGroup(bindGroup: GPUBindGroup): void

      Parameters

      • bindGroup: GPUBindGroup

      Returns void

    • get gpuCanvasContext(): GPUCanvasContext

      Satisfies RenderPass-consuming passes, which have no other way to reach this.

      Returns GPUCanvasContext

    • Builds this frame's HZB pyramid: mip 0 seeded from _depthTexture (this frame's just-finished opaque depth, already written by DepthPrePassGPU earlier in _passes), then mips 1..N max-reduced from the level below, one dispatch per level -- see hzb_copy_depth.wgsl/hzb_downsample_max.wgsl. Recorded into the frame's shared command encoder: unlike GPUTextureResourceCache's texture mip generation (which needs its own throwaway encoder+submit since callers run it mid-frame while a render pass may already be open), this runs between two whole passes, never inside one. No-ops for offscreen render targets -- see docs/adr/0008-hzb-occlusion-culling-webgpu-only.md's main-canvas-only scope.

      Parameters

      • ce: GPUCommandEncoder

      Returns void

    • Packs this frame's frustum-visible objects into _hzbAabbBuffer as world-space bounding spheres, dispatches the visibility test compute shader against the pyramid _buildHzbPyramid() just built, and copies the results into whichever staging buffer slot isn't still waiting on a previous mapAsync().

      The candidate list is derived from scene.lastFrustumVisibleObjects (isVisible && inFrustum, same condition FrustumCuller's own fallback path uses -- see _collectHzbCandidates()) rather than reading any of FrustumCuller's output fields: this renderer only holds a scene, not the owning SmallWorld's private culler instance. Reading scene's own per-instance list keeps the candidate list scoped to the scene actually being rendered, without coupling the renderer to whichever culler instance drove this frame.

      Only one slot is ever in flight at a time (the two alternate every frame -- see _hzbStagingBuffers's doc comment); if THAT slot is still pending, this frame's test is skipped entirely rather than stalling on it. Objects simply keep last frame's occlusionCulled value one frame longer -- never blocking, matches the same "skip and self-correct next frame" pattern _getObjectSlotOffset()'s ring-buffer overflow clamp uses.

      Parameters

      • ce: GPUCommandEncoder
      • scene: Scene

      Returns void

    • Returns the byte offset into the object ring buffer holding obj's ObjectUniforms for this draw. Packs + uploads at most once per (object, material) per frame -- e.g. the same shadow caster drawn across 4 CSM cascades (all sharing one DepthMaterial matUuid) reuses the same slot instead of repacking. Sprites are excluded: their model matrix is billboarded towards vMat (camera vs. light view differ per pass), so they always get a fresh slot.

      Parameters

      Returns number

    • Packs obj's ObjectUniforms into _scratchObjBufferData. Returns false (leaving the scratch buffer untouched) if m.shaderId isn't registered -- caller then skips the upload, matching the previous per-object-buffer behavior of leaving the slot's prior contents alone.

      Parameters

      Returns boolean

    • Parameters

      • rp: GPURenderPassEncoder
      • batch: RenderBatch
      • OptionalvMat: Float32Array<ArrayBufferLike>

      Returns void

    • Parameters

      • rp: GPURenderPassEncoder
      • objects: Object3D[]
      • isInstanced: boolean
      • matUuid: string
      • manifest: RenderManifest
      • viewOffset: number
      • OptionalvMat: Float32Array<ArrayBufferLike>
      • topology: GPUPrimitiveTopology = Topology.DEFAULT
      • OptionalwireframeMode: "structural" | "triangles"

      Returns void

    • Writes rawVp (a raw, not-yet-ZO-corrected view-projection matrix) into the per-draw view buffer at slot and returns the byte offset to pass as setBindGroup(3, viewBindGroup, [offset]). Used by CascadedShadowPassGPU/SpotShadowPassGPU for their shadow cameras -- the main camera's slot 0 is kept up to date by _updateGlobalBuffers() instead, once per frame, since every draw needs it regardless of pass.

      Parameters

      • slot: number
      • rawVp: Float32Array

      Returns number

    • Parameters

      Returns void

      buffer.mapState === "mapped" on each pending slot directly, rather than reacting to mapAsync()'s own promise resolving -- deliberately, not as a simplification. That promise is only guaranteed to resolve eventually; nothing requires it to fire within any bounded number of frames, and if it's ever delayed or dropped (slow GPU, a throttled/backgrounded tab, or any other reason) a promise-driven design gets stuck: _hzbStagingSlot only ever advances on a new successful dispatch, and dispatch itself refuses to touch a slot that's still marked pending -- so a lost callback wedges that slot, and therefore the whole ping-pong, forever. Reading mapState (the GPU's own ground truth for whether the buffer is actually readable right now) sidesteps that dependency entirely: whichever slot's mapping has genuinely completed gets consumed on the very next call, no matter what happened to its promise.

    • Tracks that obj currently depends on the textures in textures (typically material.getRenderManifest().textures). Called once per object per frame from the render loop. textures is diffed key-by-key against obj's last-known snapshot rather than by container reference, since a material's manifest object is created once and mutated in place on every getRenderManifest() call.

      Parameters

      • scene: Scene
      • vp: Float32Array
      • camPos: Vector3D = Vector3D.ZERO
      • OptionalvMat: Float32Array<ArrayBufferLike>
      • near: number = 0.1
      • far: number = 1000
      • OptionalprojMatrix: Float32Array<ArrayBufferLike>

      Returns void