Quellcode durchsuchen

Add RootScene.autoGPUInstanceMeshes, GLTFMeshGpuInstancingExporter extension to GLTFExporter2, add shadow map type to render manager ui

master
Palash Bansal vor 1 Jahr
Ursprung
Commit
5a318d9182
Es ist kein Account mit der E-Mail-Adresse des Committers verbunden

+ 2
- 0
src/assetmanager/export/GLTFExporter2.ts Datei anzeigen

GLTFObject3DExtrasExtension, GLTFObject3DExtrasExtension,
GLTFViewerConfigExtension, GLTFViewerConfigExtension,
} from '../gltf' } from '../gltf'
import {GLTFMeshGpuInstancingExporter} from '../../three/utils/gpu-instancing'


export interface GLTFExporter2Options { export interface GLTFExporter2Options {
/** /**
GLTFMaterialsDisplacementMapExtension.Export, GLTFMaterialsDisplacementMapExtension.Export,
GLTFMaterialsLightMapExtension.Export, GLTFMaterialsLightMapExtension.Export,
GLTFMaterialsAlphaMapExtension.Export, GLTFMaterialsAlphaMapExtension.Export,
(w)=>new GLTFMeshGpuInstancingExporter(w),
] ]


setup(viewer: ThreeViewer, extraExtensions?: ((parser: GLTFWriter2) => GLTFExporterPlugin)[]): this { setup(viewer: ThreeViewer, extraExtensions?: ((parser: GLTFWriter2) => GLTFExporterPlugin)[]): this {

+ 10
- 2
src/core/object/RootScene.ts Datei anzeigen

import { import {
BufferGeometry,
Color, Color,
EquirectangularReflectionMapping, EquirectangularReflectionMapping,
EventListener, EventListener,
} from 'three' } from 'three'
import type {IObject3D, IObjectProcessor} from '../IObject' import type {IObject3D, IObjectProcessor} from '../IObject'
import {type ICamera} from '../ICamera' import {type ICamera} from '../ICamera'
import {bindToValue, Box3B} from '../../three'
import {autoGPUInstanceMeshes, bindToValue, Box3B} from '../../three'
import {AnyOptions, onChange2, onChange3, serialize} from 'ts-browser-helpers' import {AnyOptions, onChange2, onChange3, serialize} from 'ts-browser-helpers'
import {PerspectiveCamera2} from '../camera/PerspectiveCamera2' import {PerspectiveCamera2} from '../camera/PerspectiveCamera2'
import {ThreeSerialization} from '../../utils' import {ThreeSerialization} from '../../utils'
this.setDirty({refreshScene: true}) this.setDirty({refreshScene: true})
} }


@uiButton(undefined, {sendArgs: false})
@uiButton('Center All Geometries', {sendArgs: false})
centerAllGeometries(keepPosition = true, obj?: IObject3D) { centerAllGeometries(keepPosition = true, obj?: IObject3D) {
const geoms = new Set<IGeometry>() const geoms = new Set<IGeometry>()
;(obj ?? this.modelRoot).traverse((o) => o.geometry && geoms.add(o.geometry)) ;(obj ?? this.modelRoot).traverse((o) => o.geometry && geoms.add(o.geometry))
}) })
} }


@uiButton('Auto GPU Instance Meshes')
autoGPUInstanceMeshes() {
const geoms = new Set<BufferGeometry>()
this.modelRoot.traverse((o) => o.geometry && geoms.add(o.geometry))
geoms.forEach((g: any) => autoGPUInstanceMeshes(g))
}

private _v1 = new Vector3() private _v1 = new Vector3()
private _v2 = new Vector3() private _v2 = new Vector3()



+ 17
- 3
src/rendering/RenderManager.ts Datei anzeigen

NormalBlending, NormalBlending,
NoToneMapping, NoToneMapping,
PCFShadowMap, PCFShadowMap,
ShadowMapType,
Texture, Texture,
Vector2, Vector2,
Vector4, Vector4,
WebGLMultipleRenderTargets, WebGLMultipleRenderTargets,
WebGLRenderer, WebGLRenderer,
WebGLRenderTarget, WebGLRenderTarget,
WebGLRenderTargetOptions,
WebGLRenderTargetOptions, WebGLShadowMap,
} from 'three' } from 'three'
import {EffectComposer2, IPassID, IPipelinePass, sortPasses} from '../postprocessing' import {EffectComposer2, IPassID, IPipelinePass, sortPasses} from '../postprocessing'
import {IRenderTarget} from './RenderTarget' import {IRenderTarget} from './RenderTarget'
serialize, serialize,
ValOrArr, ValOrArr,
} from 'ts-browser-helpers' } from 'ts-browser-helpers'
import {uiButton, uiConfig, uiFolderContainer, uiMonitor, uiSlider, uiToggle} from 'uiconfig.js'
import {generateUUID, textureDataToImageData} from '../three'
import {uiButton, uiConfig, uiDropdown, uiFolderContainer, uiMonitor, uiSlider, uiToggle} from 'uiconfig.js'
import {bindToValue, generateUUID, textureDataToImageData} from '../three'
import {BlobExt, EXRExporter2} from '../assetmanager' import {BlobExt, EXRExporter2} from '../assetmanager'
import {RendererBlitOptions} from '../core/IRenderer' import {RendererBlitOptions} from '../core/IRenderer'


} }
} }


@serialize()
@uiDropdown('Shadow Map Type', ['BasicShadowMap', 'PCFShadowMap', 'PCFSoftShadowMap', 'VSMShadowMap'].map((v, i) => ({label: v, value: i})))
@bindToValue({obj: 'shadowMap', key: 'type', onChange: RenderManager.prototype._shadowMapTypeChanged})
shadowMapType: ShadowMapType

@bindToValue({obj: 'renderer', key: 'shadowMap'})
shadowMap: WebGLShadowMap

private _shadowMapTypeChanged() {
this.resetShadows()
this.reset()
}

@uiConfig(undefined, {label: 'Passes'}) @uiConfig(undefined, {label: 'Passes'})
private _passes: IPipelinePass[] = [] private _passes: IPipelinePass[] = []
private _pipeline: IPassID[] = [] private _pipeline: IPassID[] = []

+ 61
- 1
src/three/utils/gpu-instancing.ts Datei anzeigen

import {IGeometry, IMaterial, IObject3D} from '../../core' import {IGeometry, IMaterial, IObject3D} from '../../core'
import {BufferAttribute, InstancedMesh} from 'three'
import {BufferAttribute, InstancedMesh, Matrix4, Quaternion, Vector3} from 'three'
// noinspection ES6PreferShortImport // noinspection ES6PreferShortImport
import {copyObject3DUserData} from '../../utils/serialization' import {copyObject3DUserData} from '../../utils/serialization'
import {GLTFWriter2} from '../../assetmanager'
import {GLTFExporterPlugin} from 'three/examples/jsm/exporters/GLTFExporter'


export function autoGPUInstanceMeshes(matOrGeom: IMaterial|IGeometry) { export function autoGPUInstanceMeshes(matOrGeom: IMaterial|IGeometry) {
if (!(<IMaterial>matOrGeom).isMaterial && !(<IGeometry>matOrGeom).isBufferGeometry) return if (!(<IMaterial>matOrGeom).isMaterial && !(<IGeometry>matOrGeom).isBufferGeometry) return
;(parent as any).setDirty() ;(parent as any).setDirty()
} }
} }

export class GLTFMeshGpuInstancingExporter implements GLTFExporterPlugin {
name = 'EXT_mesh_gpu_instancing'
constructor(public writer: GLTFWriter2) {
}

writeNode(object: any, nodeDef: any): void {
if (!object.isInstancedMesh) return

const writer = this.writer

const mesh = object as InstancedMesh

// @ts-expect-error not in ts
let attributes: any = mesh.sourceTrs
if (!attributes) {
const translationAttr = new Float32Array(mesh.count * 3)
const rotationAttr = new Float32Array(mesh.count * 4)
const scaleAttr = new Float32Array(mesh.count * 3)

const matrix = new Matrix4()
const position = new Vector3()
const quaternion = new Quaternion()
const scale = new Vector3()

for (let i = 0; i < mesh.count; i++) {
mesh.getMatrixAt(i, matrix)
matrix.decompose(position, quaternion, scale)

position.toArray(translationAttr, i * 3)
quaternion.toArray(rotationAttr, i * 4)
scale.toArray(scaleAttr, i * 3)
}
attributes = {
TRANSLATION: new BufferAttribute(translationAttr, 3),
ROTATION: new BufferAttribute(rotationAttr, 4),
SCALE: new BufferAttribute(scaleAttr, 3),
}
}

attributes = {
// @ts-expect-error todo add to ts
TRANSLATION: writer.processAccessor(attributes.TRANSLATION),
ROTATION: (writer as any).processAccessor(attributes.ROTATION),
SCALE: (writer as any).processAccessor(attributes.SCALE),
}

if (mesh.instanceColor)
attributes._COLOR_0 = (writer as any).processAccessor(mesh.instanceColor)

writer.extensionsUsed[ this.name ] = true
// @ts-expect-error todo add to ts
writer.extensionsRequired[ this.name ] = true

nodeDef.extensions = nodeDef.extensions || {}
nodeDef.extensions[ this.name ] = {attributes}
}
}

+ 2
- 0
src/utils/browser-helpers.ts Datei anzeigen

export type {Serializer} from 'ts-browser-helpers' export type {Serializer} from 'ts-browser-helpers'


export {PointerDragHelper} from 'ts-browser-helpers' export {PointerDragHelper} from 'ts-browser-helpers'
export {JSUndoManager} from 'ts-browser-helpers'
export type {JSUndoManagerCommand2, JSUndoManagerCommand, JSUndoManagerOptions, JSUndoManagerCommand1} from 'ts-browser-helpers'
export {Damper} from 'ts-browser-helpers' export {Damper} from 'ts-browser-helpers'
export {SimpleEventDispatcher} from 'ts-browser-helpers' export {SimpleEventDispatcher} from 'ts-browser-helpers'



Laden…
Abbrechen
Speichern