playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
317 lines (316 loc) • 8.67 kB
JavaScript
import {
PIXELFORMAT_R32U,
PIXELFORMAT_RGBA16F,
PIXELFORMAT_RGBA16U,
PIXELFORMAT_RGBA32U,
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_COMPUTE,
GSPLAT_RENDERER_RASTER_GPU_SORT,
GSPLAT_DEBUG_NONE,
GSPLAT_DEBUG_LOD,
GSPLAT_DEBUG_SH_UPDATE,
GSPLAT_DEBUG_HEATMAP,
GSPLAT_DEBUG_AABBS,
GSPLAT_DEBUG_NODE_AABBS
} 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 {
_material = new ShaderMaterial();
_format;
_device;
_dataFormat = GSPLATDATA_COMPACT;
constructor(device) {
this._device = device;
this._format = this._createFormat(GSPLATDATA_COMPACT);
this._material.setParameter("alphaClip", 0.3);
this._material.setParameter("alphaClipForward", 1 / 255);
this._material.setParameter("minPixelSize", 2);
this._material.setParameter("minContribution", 3);
}
_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;
}
radialSorting = false;
_renderer = GSPLAT_RENDERER_AUTO;
_currentRenderer = GSPLAT_RENDERER_RASTER_CPU_SORT;
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_COMPUTE || value === GSPLAT_RENDERER_RASTER_GPU_SORT) && !this._device.isWebGPU) {
this._currentRenderer = GSPLAT_RENDERER_RASTER_CPU_SORT;
} else {
this._currentRenderer = value;
}
}
}
get renderer() {
return this._renderer;
}
get currentRenderer() {
return this._currentRenderer;
}
dirty = false;
_debug = GSPLAT_DEBUG_NONE;
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 debugAabbs(value) {
this.debug = value ? GSPLAT_DEBUG_AABBS : GSPLAT_DEBUG_NONE;
}
get debugAabbs() {
return this._debug === GSPLAT_DEBUG_AABBS;
}
set debugNodeAabbs(value) {
this.debug = value ? GSPLAT_DEBUG_NODE_AABBS : GSPLAT_DEBUG_NONE;
}
get debugNodeAabbs() {
return this._debug === GSPLAT_DEBUG_NODE_AABBS;
}
_enableIds = false;
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;
}
lodUpdateDistance = 1;
lodUpdateAngle = 0;
_lodBehindPenalty = 1;
set lodBehindPenalty(value) {
if (this._lodBehindPenalty !== value) {
this._lodBehindPenalty = value;
this.dirty = true;
}
}
get lodBehindPenalty() {
return this._lodBehindPenalty;
}
_lodRangeMin = 0;
set lodRangeMin(value) {
if (this._lodRangeMin !== value) {
this._lodRangeMin = value;
this.dirty = true;
}
}
get lodRangeMin() {
return this._lodRangeMin;
}
_lodRangeMax = 10;
set lodRangeMax(value) {
if (this._lodRangeMax !== value) {
this._lodRangeMax = value;
this.dirty = true;
}
}
get lodRangeMax() {
return this._lodRangeMax;
}
_lodUnderfillLimit = 0;
set lodUnderfillLimit(value) {
if (this._lodUnderfillLimit !== value) {
this._lodUnderfillLimit = value;
this.dirty = true;
}
}
get lodUnderfillLimit() {
return this._lodUnderfillLimit;
}
_splatBudget = 0;
set splatBudget(value) {
if (this._splatBudget !== value) {
this._splatBudget = value;
this.dirty = true;
}
}
get splatBudget() {
return this._splatBudget;
}
_colorRamp = null;
set colorRamp(value) {
if (this._colorRamp !== value) {
this._colorRamp = value;
this.dirty = true;
}
}
get colorRamp() {
return this._colorRamp;
}
colorRampIntensity = 1;
useFog = true;
set colorizeColorUpdate(value) {
this.debug = value ? GSPLAT_DEBUG_SH_UPDATE : GSPLAT_DEBUG_NONE;
}
get colorizeColorUpdate() {
return this._debug === GSPLAT_DEBUG_SH_UPDATE;
}
colorUpdateAngle = 10;
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 alphaClipForward(value) {
this._material.setParameter("alphaClipForward", value);
this._material.update();
}
get alphaClipForward() {
return this._material.getParameter("alphaClipForward")?.data ?? 1 / 255;
}
set minPixelSize(value) {
this._material.setParameter("minPixelSize", value);
this._material.update();
}
get minPixelSize() {
return this._material.getParameter("minPixelSize")?.data ?? 2;
}
set minContribution(value) {
this._material.setParameter("minContribution", value);
this._material.update();
}
get minContribution() {
return this._material.getParameter("minContribution")?.data ?? 3;
}
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");
}
_fisheye = 0;
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;
}
cooldownTicks = 100;
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;
}
}
export {
GSplatParams
};