-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[BREAKING] Update gsplat component material API #7749
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
d737abc
b4f94b4
bb6194f
1750ecd
585b632
6726594
5dba3d2
e845b06
2b3b499
3e48bbf
13d0b9f
658f71a
0a8d741
87c4591
4c62ea5
74012e2
90a8ffb
a4c4245
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,16 @@ | ||
import { Mat4 } from '../../core/math/mat4.js'; | ||
import { Vec3 } from '../../core/math/vec3.js'; | ||
import { PIXELFORMAT_R32U } from '../../platform/graphics/constants.js'; | ||
import { DITHER_NONE } from '../constants.js'; | ||
import { SEMANTIC_ATTR13, SEMANTIC_POSITION, PIXELFORMAT_R32U } from '../../platform/graphics/constants.js'; | ||
import { MeshInstance } from '../mesh-instance.js'; | ||
import { GSplatSorter } from './gsplat-sorter.js'; | ||
import { ShaderMaterial } from '../materials/shader-material.js'; | ||
import { BLEND_NONE, BLEND_PREMULTIPLIED } from '../constants.js'; | ||
import { CULLFACE_NONE } from '../../platform/graphics/constants.js'; | ||
Check warning on line 8 in src/scene/gsplat/gsplat-instance.js
|
||
|
||
/** | ||
* @import { Camera } from '../camera.js' | ||
* @import { GSplatResourceBase } from './gsplat-resource-base.js' | ||
* @import { GraphNode } from '../graph-node.js' | ||
* @import { Material } from '../materials/material.js' | ||
* @import { SplatMaterialOptions } from './gsplat-material.js' | ||
* @import { Texture } from '../../platform/graphics/texture.js' | ||
*/ | ||
|
||
|
@@ -24,15 +24,15 @@ | |
/** @type {GSplatResourceBase} */ | ||
resource; | ||
|
||
/** @type {MeshInstance} */ | ||
meshInstance; | ||
|
||
/** @type {Material} */ | ||
material; | ||
|
||
/** @type {Texture} */ | ||
orderTexture; | ||
|
||
/** @type {ShaderMaterial} */ | ||
_material; | ||
|
||
/** @type {MeshInstance} */ | ||
meshInstance; | ||
|
||
options = {}; | ||
|
||
/** @type {GSplatSorter | null} */ | ||
|
@@ -52,25 +52,43 @@ | |
|
||
/** | ||
* @param {GSplatResourceBase} resource - The splat instance. | ||
* @param {SplatMaterialOptions} options - The options. | ||
* @param {ShaderMaterial|null} material - The material instance. | ||
*/ | ||
constructor(resource, options) { | ||
constructor(resource, material) { | ||
this.resource = resource; | ||
|
||
// clone options object | ||
options = Object.assign(this.options, options); | ||
|
||
// create the order texture | ||
this.orderTexture = resource.createTexture( | ||
'splatOrder', | ||
PIXELFORMAT_R32U, | ||
resource.evalTextureSize(resource.numSplats) | ||
); | ||
|
||
// material | ||
this.createMaterial(options); | ||
if (material) { | ||
// material is provided | ||
this._material = material; | ||
} else { | ||
// construct the material | ||
this._material = new ShaderMaterial({ | ||
uniqueName: 'SplatMaterial', | ||
vertexGLSL: '#include "gsplatVS"', | ||
fragmentGLSL: '#include "gsplatPS"', | ||
vertexWGSL: '#include "gsplatVS"', | ||
fragmentWGSL: '#include "gsplatPS"', | ||
attributes: { | ||
vertex_position: SEMANTIC_POSITION, | ||
vertex_id_attrib: SEMANTIC_ATTR13 | ||
} | ||
}); | ||
|
||
// default configure | ||
this.configureMaterial(this._material); | ||
|
||
// update | ||
this._material.update(); | ||
} | ||
|
||
this.meshInstance = new MeshInstance(resource.mesh, this.material); | ||
this.meshInstance = new MeshInstance(resource.mesh, this._material); | ||
this.meshInstance.setInstancing(resource.instanceIndices, true); | ||
this.meshInstance.gsplatInstance = this; | ||
|
||
|
@@ -82,17 +100,15 @@ | |
const chunks = resource.chunks?.slice(); | ||
|
||
// create sorter | ||
if (!options.dither || options.dither === DITHER_NONE) { | ||
this.sorter = new GSplatSorter(); | ||
this.sorter.init(this.orderTexture, centers, chunks); | ||
this.sorter.on('updated', (count) => { | ||
// limit splat render count to exclude those behind the camera | ||
this.meshInstance.instancingCount = Math.ceil(count / resource.instanceSize); | ||
|
||
// update splat count on the material | ||
this.material.setParameter('numSplats', count); | ||
}); | ||
} | ||
this.sorter = new GSplatSorter(); | ||
slimbuck marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this.sorter.init(this.orderTexture, centers, chunks); | ||
this.sorter.on('updated', (count) => { | ||
// limit splat render count to exclude those behind the camera | ||
this.meshInstance.instancingCount = Math.ceil(count / resource.instanceSize); | ||
|
||
// update splat count on the material | ||
this.material.setParameter('numSplats', count); | ||
}); | ||
} | ||
|
||
destroy() { | ||
|
@@ -105,15 +121,43 @@ | |
return new GSplatInstance(this.resource, this.options); | ||
} | ||
|
||
createMaterial(options) { | ||
this.material = this.resource.createMaterial(options); | ||
this.material.setParameter('splatOrder', this.orderTexture); | ||
this.material.setParameter('alphaClip', 0.3); | ||
if (this.meshInstance) { | ||
this.meshInstance.material = this.material; | ||
/** | ||
* @param {ShaderMaterial} value - The material instance. | ||
*/ | ||
set material(value) { | ||
if (this.material !== value) { | ||
// set the new material | ||
this.material = value; | ||
slimbuck marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if (this.meshInstance) { | ||
this.meshInstance.material = value; | ||
} | ||
} | ||
} | ||
|
||
get material() { | ||
return this._material; | ||
} | ||
|
||
/** | ||
* Configure the material with gsplat instance and resource properties. | ||
* | ||
* @param {ShaderMaterial} material | ||
Check failure on line 145 in src/scene/gsplat/gsplat-instance.js
|
||
* @param {boolean} dither | ||
Check failure on line 146 in src/scene/gsplat/gsplat-instance.js
|
||
*/ | ||
configureMaterial(material, dither = false) { | ||
// allow resource to configure the material | ||
this.resource.configureMaterial(material); | ||
|
||
// set instance properties | ||
material.setParameter('splatOrder', this.orderTexture); | ||
material.setParameter('alphaClip', 0.3); | ||
material.setDefine(`DITHER_${dither ? 'BLUENOISE' : 'NONE'}`, ''); | ||
material.cull = CULLFACE_NONE; | ||
material.blendType = dither ? BLEND_NONE : BLEND_PREMULTIPLIED; | ||
material.depthWrite = dither; | ||
} | ||
|
||
updateViewport(cameraNode) { | ||
const camera = cameraNode?.camera; | ||
const renderTarget = camera?.renderTarget; | ||
|
Uh oh!
There was an error while loading. Please reload this page.