ForgeViewpoint
A ForgeViewpoint
is created from and tied to a ForgeRenderer
, and represents an independent viewpoint of all the scene splats and their sort order. Making these viewpoints explicit allows us to have multiple, simultaneous viewpoint renders, for example for camera preview panes or overhead map views.
When creating a ForgeRenderer
it automatically creates a default viewpoint .defaultView
that is used in the normal render loop when drawing to the canvas, and is automatically updated whenever the camera moves. Additional viewpoints can be created and configured separately:
Creating a ForgeViewpoint
const viewpoint = forge.newViewpoint({
autoUpdate?: boolean;
camera?: THREE.Camera;
viewToWorld?: THREE.Matrix4;
target?: {
width: number;
height: number;
doubleBuffer?: boolean;
superXY?: number;
};
onTextureUpdated?: (texture: THREE.Texture) => void;
sortRadial?: boolean;
sortDistance?: number;
sortCoorient?: boolean;
depthBias?: number;
sort360?: boolean;
});
Optional parameters
Parameter | Description |
---|---|
autoUpdate | Controls whether to auto-update its sort order whenever the ForgeRenderer updates the splats. If you expect to render/display from this viewpoint most frames, set this to true . (default: false ) |
camera | Set a THREE.Camera for this viewpoint to follow. (default: undefined ) |
viewToWorld | Set an explicit view-to-world transformation matrix for this viewpoint (equivalent to camera.matrixWorld ), overrides any camera setting. (default: undefined ) |
target | Configure viewpoint with an off-screen render target. (default: undefined ) |
target.width | Width of the render target in pixels. |
target.height | Height of the render target in pixels. |
target.doubleBuffer | If you want to be able to render a scene that depends on this target's output (for example, a recursive viewport), set this to true to enable double buffering. (default: false ) |
target.superXY | Super-sampling factor for the render target. Values 1-4 are supported. Note that re-sampling back down to .width x .height is done on the CPU with simple averaging only when calling readTarget() . (default: 1 ) |
onTextureUpdated | Callback function that is called when the render target texture is updated. Receives the texture as a parameter. Use this to update a viewport with the latest viewpoint render each frame. (default: undefined ) |
sortRadial | Whether to sort splats radially (geometric distance) from the viewpoint (true) or by Z-depth (false). Most scenes are trained with the Z-depth sort metric and will render more accurately at certain viewpoints. However, radial sorting is more stable under viewpoint rotations. (default: true ) |
sortDistance | Distance threshold for re-sorting splats. If the viewpoint moves more than this distance, splats will be re-sorted. (default: 0.01 units) |
sortCoorient | View direction dot product threshold for re-sorting splats. For sortRadial: true it defaults to 0.99 while sortRadial: false uses 0.999 because it is more sensitive to view direction. (default: 0.99 if sortRadial else 0.999 ) |
depthBias | Constant added to Z-depth to bias values into the positive range for sortRadial: false , but also used for culling splats "well behind" the viewpoint origin (default: 1.0 ) |
sort360 | Set this to true if rendering a 360 to disable "behind the viewpoint" culling during sorting. This is set automatically when rendering 360 envMaps using the ForgeRenderer.renderEnvMap() utility function. (default: false ) |
dispose()
Call this when you are done with the ForgeViewpoint
and want to free up its resources (GPU targets, pixel buffers, etc.)
setAutoUpdate(autoUpdate: boolean)
Use this function to change whether this viewpoint will auto-update its sort order whenever the attached ForgeRenderer
updates the splats. Turn this on or off depending on whether you expect to do renders from this viewpoint for most frames.
async prepareRenderPixels({ scene, camera?, viewToWorld?, update?, forceOrigin? })
Render out a viewpoint as a Uint8Array of RGBA values for the provided scene and any camera
/viewToWorld
viewpoint overrides. By default update
is true
, which triggers its ForgeRenderer
to check and potentially update the splats. Setting update
to false
disables this and sorts the splats as they are. Setting forceOrigin
(default: false
) to true
forces the view update to recalculate the splats with this view origin, potentially altering any view-dependent effects. If you expect view-dependent effects to play a role in the rendering quality, enable this.
Underneath, prepareRenderPixels()
simply calls await this.prepare(...)
, this.renderTarget(...)
, and finally returns the result of this.readTarget()
, a Promise to a Uint8Array with RGBA values for all the pixels (potentially downsampled if the superXY
parameter was used). These steps can also be called manually, for example if you need to alter the scene before and after this.renderTarget(...)
to hide UI elements from being rendered.
async prepare({ scene, camera?, viewToWorld?, update?, forceOrigin? })
See above async prepareRenderPixels()
for explanation of parameters. Awaiting this method updates the splats in the scene and performs a sort of the splats from this viewpoint, preparing it for a subsequent this.renderTarget()
call in the same tick.
renderTarget({ scene, camera? })
Render out the viewpoint to the view target RGBA buffer. Swaps buffers if doubleBuffer: true
was set. Calls onTextureUpdated(texture)
with the resulting texture.
async readTarget()
Read back the previously rendered target image as a Uint8Array of packed RGBA values (in that order). If superXY
was set greater than 1
than downsampling is performed in the target pixel array with simple averaging to derive the returned pixel values. Subsequent calls to this.readTarget()
will reuse the same buffers to minimize memory allocations.
autoPoll()
This is called automatically by ForgeRenderer
, there is no need to call it! The method cannot be private because then ForgeRenderer would not be able to call it.
ForgeViewpoint.EMPTY_TEXTURE
If you need an empty THREE.Texture
to use to initialize a uniform that is updated via onTextureUpdated(texture)
, this static texture can be handy.