playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
301 lines (298 loc) • 8.91 kB
JavaScript
import { PIXELFORMAT_R32U, PIXELFORMAT_RGBA32U, PIXELFORMAT_RGBA16F, PIXELFORMAT_RGBA16U, PIXELFORMAT_RG32U } from '../../platform/graphics/constants.js';
import { ShaderMaterial } from '../materials/shader-material.js';
import { GSplatFormat } from '../gsplat/gsplat-format.js';
import { GSPLATDATA_COMPACT, GSPLAT_RENDERER_AUTO, GSPLAT_RENDERER_RASTER_CPU_SORT, GSPLAT_RENDERER_RASTER_GPU_SORT, GSPLAT_RENDERER_COMPUTE, GSPLAT_DEBUG_LOD, GSPLAT_DEBUG_HEATMAP, GSPLAT_DEBUG_NONE, GSPLAT_DEBUG_SH_UPDATE } from '../constants.js';
import glslCompactRead from '../shader-lib/glsl/chunks/gsplat/vert/formats/containerCompactRead.js';
import glslCompactWrite from '../shader-lib/glsl/chunks/gsplat/frag/formats/containerCompactWrite.js';
import glslPackedRead from '../shader-lib/glsl/chunks/gsplat/vert/formats/containerPackedRead.js';
import glslPackedWrite from '../shader-lib/glsl/chunks/gsplat/frag/formats/containerPackedWrite.js';
import wgslCompactRead from '../shader-lib/wgsl/chunks/gsplat/vert/formats/containerCompactRead.js';
import wgslCompactWrite from '../shader-lib/wgsl/chunks/gsplat/frag/formats/containerCompactWrite.js';
import wgslPackedRead from '../shader-lib/wgsl/chunks/gsplat/vert/formats/containerPackedRead.js';
import wgslPackedWrite from '../shader-lib/wgsl/chunks/gsplat/frag/formats/containerPackedWrite.js';
class GSplatParams {
_createFormat(dataFormat) {
let format;
if (dataFormat === GSPLATDATA_COMPACT) {
format = new GSplatFormat(this._device, [
{
name: 'dataColor',
format: PIXELFORMAT_R32U
},
{
name: 'dataTransformA',
format: PIXELFORMAT_RGBA32U
},
{
name: 'dataTransformB',
format: PIXELFORMAT_R32U
}
], {
readGLSL: glslCompactRead,
readWGSL: wgslCompactRead
});
format.setWriteCode(glslCompactWrite, wgslCompactWrite);
} else {
const colorFormat = this._device.getRenderableHdrFormat([
PIXELFORMAT_RGBA16F
]) || PIXELFORMAT_RGBA16U;
format = new GSplatFormat(this._device, [
{
name: 'dataColor',
format: colorFormat
},
{
name: 'dataTransformA',
format: PIXELFORMAT_RGBA32U
},
{
name: 'dataTransformB',
format: PIXELFORMAT_RG32U
}
], {
readGLSL: glslPackedRead,
readWGSL: wgslPackedRead
});
format.setWriteCode(glslPackedWrite, wgslPackedWrite);
}
format.allowStreamRemoval = true;
return format;
}
set renderer(value) {
if (this._renderer !== value) {
this._renderer = value;
if (value === GSPLAT_RENDERER_AUTO) {
this._currentRenderer = GSPLAT_RENDERER_RASTER_CPU_SORT;
} else if ((value === GSPLAT_RENDERER_RASTER_GPU_SORT || value === GSPLAT_RENDERER_COMPUTE) && !this._device.isWebGPU) {
this._currentRenderer = GSPLAT_RENDERER_RASTER_CPU_SORT;
} else {
this._currentRenderer = value;
}
}
}
get renderer() {
return this._renderer;
}
get currentRenderer() {
return this._currentRenderer;
}
set debug(value) {
if (this._debug !== value) {
const prev = this._debug;
this._debug = value;
if (value === GSPLAT_DEBUG_LOD || prev === GSPLAT_DEBUG_LOD || value === GSPLAT_DEBUG_HEATMAP || prev === GSPLAT_DEBUG_HEATMAP) {
this.dirty = true;
}
}
}
get debug() {
return this._debug;
}
set colorizeLod(value) {
this.debug = value ? GSPLAT_DEBUG_LOD : GSPLAT_DEBUG_NONE;
}
get colorizeLod() {
return this._debug === GSPLAT_DEBUG_LOD;
}
set enableIds(value) {
if (value && !this._enableIds) {
this._enableIds = true;
if (!this._format.getStream('pcId')) {
this._format.addExtraStreams([
{
name: 'pcId',
format: PIXELFORMAT_R32U
}
]);
}
} else if (!value && this._enableIds) {
this._enableIds = false;
this._format.removeExtraStreams([
'pcId'
]);
}
}
get enableIds() {
return this._enableIds;
}
set lodBehindPenalty(value) {
if (this._lodBehindPenalty !== value) {
this._lodBehindPenalty = value;
this.dirty = true;
}
}
get lodBehindPenalty() {
return this._lodBehindPenalty;
}
set lodRangeMin(value) {
if (this._lodRangeMin !== value) {
this._lodRangeMin = value;
this.dirty = true;
}
}
get lodRangeMin() {
return this._lodRangeMin;
}
set lodRangeMax(value) {
if (this._lodRangeMax !== value) {
this._lodRangeMax = value;
this.dirty = true;
}
}
get lodRangeMax() {
return this._lodRangeMax;
}
set lodUnderfillLimit(value) {
if (this._lodUnderfillLimit !== value) {
this._lodUnderfillLimit = value;
this.dirty = true;
}
}
get lodUnderfillLimit() {
return this._lodUnderfillLimit;
}
set splatBudget(value) {
if (this._splatBudget !== value) {
this._splatBudget = value;
this.dirty = true;
}
}
get splatBudget() {
return this._splatBudget;
}
set colorRamp(value) {
if (this._colorRamp !== value) {
this._colorRamp = value;
this.dirty = true;
}
}
get colorRamp() {
return this._colorRamp;
}
set colorizeColorUpdate(value) {
this.debug = value ? GSPLAT_DEBUG_SH_UPDATE : GSPLAT_DEBUG_NONE;
}
get colorizeColorUpdate() {
return this._debug === GSPLAT_DEBUG_SH_UPDATE;
}
set colorUpdateDistance(value) {}
get colorUpdateDistance() {
return 0;
}
set colorUpdateDistanceLodScale(value) {}
get colorUpdateDistanceLodScale() {
return 0;
}
set colorUpdateAngleLodScale(value) {}
get colorUpdateAngleLodScale() {
return 0;
}
set alphaClip(value) {
this._material.setParameter('alphaClip', value);
this._material.update();
}
get alphaClip() {
return this._material.getParameter('alphaClip')?.data ?? 0.3;
}
set minPixelSize(value) {
this._material.setParameter('minPixelSize', value);
this._material.update();
}
get minPixelSize() {
return this._material.getParameter('minPixelSize')?.data ?? 2.0;
}
set minContribution(value) {
this._material.setParameter('minContribution', value);
this._material.update();
}
get minContribution() {
return this._material.getParameter('minContribution')?.data ?? 3.0;
}
set antiAlias(value) {
this._material.setDefine('GSPLAT_AA', value);
this._material.update();
}
get antiAlias() {
return !!this._material.getDefine('GSPLAT_AA');
}
set twoDimensional(value) {
this._material.setDefine('GSPLAT_2DGS', value);
this._material.update();
}
get twoDimensional() {
return !!this._material.getDefine('GSPLAT_2DGS');
}
set fisheye(value) {
if (this._fisheye !== value) {
const wasEnabled = this._fisheye > 0;
this._fisheye = value;
const isEnabled = value > 0;
if (wasEnabled !== isEnabled) {
this._material.setDefine('GSPLAT_FISHEYE', isEnabled);
this._material.update();
}
}
}
get fisheye() {
return this._fisheye;
}
set dataFormat(value) {
if (this._dataFormat !== value) {
this._dataFormat = value;
const extraStreams = this._format.extraStreams.map((s)=>({
name: s.name,
format: s.format,
storage: s.storage
}));
this._format = this._createFormat(value);
if (extraStreams.length > 0) {
this._format.addExtraStreams(extraStreams);
}
this.dirty = true;
}
}
get dataFormat() {
return this._dataFormat;
}
get material() {
return this._material;
}
get format() {
return this._format;
}
frameEnd() {
this._material.dirty = false;
this.dirty = false;
}
constructor(device){
this._material = new ShaderMaterial();
this._dataFormat = GSPLATDATA_COMPACT;
this.debugAabbs = false;
this.radialSorting = false;
this._renderer = GSPLAT_RENDERER_AUTO;
this._currentRenderer = GSPLAT_RENDERER_RASTER_CPU_SORT;
this.debugNodeAabbs = false;
this.dirty = false;
this._debug = GSPLAT_DEBUG_NONE;
this._enableIds = false;
this.lodUpdateDistance = 1;
this.lodUpdateAngle = 0;
this._lodBehindPenalty = 1;
this._lodRangeMin = 0;
this._lodRangeMax = 10;
this._lodUnderfillLimit = 0;
this._splatBudget = 0;
this._colorRamp = null;
this.colorRampIntensity = 1;
this.useFog = true;
this.colorUpdateAngle = 10;
this._fisheye = 0;
this.cooldownTicks = 100;
this._device = device;
this._format = this._createFormat(GSPLATDATA_COMPACT);
this._material.setParameter('alphaClip', 0.3);
this._material.setParameter('minPixelSize', 2.0);
this._material.setParameter('minContribution', 3.0);
}
}
export { GSplatParams };