Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion src/scene/renderer/renderer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Debug, DebugHelper } from '../../core/debug.js';
import { now } from '../../core/time.js';
import { BlueNoise } from '../../core/math/blue-noise.js';
import { FloatPacking } from '../../core/math/float-packing.js';
import { Vec2 } from '../../core/math/vec2.js';
import { Vec3 } from '../../core/math/vec3.js';
import { Vec4 } from '../../core/math/vec4.js';
Expand All @@ -13,7 +14,10 @@ import {
UNIFORMTYPE_MAT4, UNIFORMTYPE_MAT3, UNIFORMTYPE_VEC3, UNIFORMTYPE_VEC2, UNIFORMTYPE_FLOAT, UNIFORMTYPE_INT,
SHADERSTAGE_VERTEX, SHADERSTAGE_FRAGMENT,
CULLFACE_BACK, CULLFACE_FRONT, CULLFACE_NONE,
BINDGROUP_MESH_UB
BINDGROUP_MESH_UB,
PIXELFORMAT_R16F,
FILTER_LINEAR,
ADDRESS_CLAMP_TO_EDGE
} from '../../platform/graphics/constants.js';
import { DebugGraphics } from '../../platform/graphics/debug-graphics.js';
import { UniformBuffer } from '../../platform/graphics/uniform-buffer.js';
Expand All @@ -28,6 +32,7 @@ import {
} from '../constants.js';
import { LightCube } from '../graphics/light-cube.js';
import { getBlueNoiseTexture } from '../graphics/noise-textures.js';
import { Texture } from '../../platform/graphics/texture.js';
import { LightTextureAtlas } from '../lighting/light-texture-atlas.js';
import { Material } from '../materials/material.js';
import { ShadowMapCache } from './shadow-map-cache.js';
Expand Down Expand Up @@ -99,6 +104,30 @@ const _tempSet = new Set();
const _tempMeshInstances = [];
const _tempMeshInstancesSkinned = [];

// construct the exponent lookup table used in gaussian splat rendering
const createExpTableTexture = (device) => {
const expTableSize = 32;
const expTable = new Uint16Array(expTableSize);
for (let i = 0; i < expTableSize; ++i) {
const value = Math.exp(-4.0 * i / (expTableSize - 1));
const nvalue = (value - Math.exp(-4.0)) / (1.0 - Math.exp(-4.0));
expTable[i] = FloatPacking.float2Half(nvalue);
}

return new Texture(device, {
name: 'internal-expTable',
width: expTableSize,
height: 1,
format: PIXELFORMAT_R16F,
mipmaps: false,
minFilter: FILTER_LINEAR,
magFilter: FILTER_LINEAR,
addressU: ADDRESS_CLAMP_TO_EDGE,
addressV: ADDRESS_CLAMP_TO_EDGE,
levels: [expTable]
});
};

/**
* The base renderer functionality to allow implementation of specialized renderers.
*
Expand Down Expand Up @@ -244,6 +273,7 @@ class Renderer {
this.blueNoiseJitterData = new Float32Array(4);
this.blueNoiseJitterId = scope.resolve('blueNoiseJitter');
this.blueNoiseTextureId = scope.resolve('blueNoiseTex32');
this.expTableTextureId = scope.resolve('expTable');

this.alphaTestId = scope.resolve('alpha_ref');
this.opacityMapId = scope.resolve('texture_opacityMap');
Expand All @@ -259,6 +289,8 @@ class Renderer {
// a single instance of light cube
this.lightCube = new LightCube();
this.constantLightCube = scope.resolve('lightCube[0]');

this.expTableTexture = createExpTableTexture(this.device);
}

destroy() {
Expand All @@ -277,6 +309,9 @@ class Renderer {

this.gsplatDirector?.destroy();
this.gsplatDirector = null;

this.expTableTexture?.destroy();
this.expTableTexture = null;
}

/**
Expand Down Expand Up @@ -1197,6 +1232,7 @@ class Renderer {
updateFrameUniforms() {
// blue noise texture
this.blueNoiseTextureId.setValue(getBlueNoiseTexture(this.device));
this.expTableTextureId.setValue(this.expTableTexture);
}

/**
Expand Down
6 changes: 2 additions & 4 deletions src/scene/shader-lib/glsl/chunks/gsplat/frag/gsplat.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,15 @@ export default /* glsl */`
varying mediump vec2 gaussianUV;
varying mediump vec4 gaussianColor;

// e^-4
#define EXP4 0.0183156388887
uniform sampler2D expTable;

void main(void) {
mediump float A = dot(gaussianUV, gaussianUV);
if (A > 1.0) {
discard;
}

// evaluate alpha
mediump float alpha = (exp(-A * 4.0) - EXP4) / (1.0 - EXP4) * gaussianColor.a;
mediump float alpha = texture2DLod(expTable, vec2(A, 0.5), 0.0).r * gaussianColor.a;

#if defined(SHADOW_PASS) || defined(PICK_PASS) || defined(PREPASS_PASS)
if (alpha < alphaClip) {
Expand Down
6 changes: 3 additions & 3 deletions src/scene/shader-lib/wgsl/chunks/gsplat/frag/gsplat.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export default /* wgsl */`
varying gaussianUV: vec2f;
varying gaussianColor: vec4f;

// e^-4
const EXP4: f32 = 0.0183156388887;
var expTable: texture_2d<f32>;
var expTableSampler: sampler;

@fragment
fn fragmentMain(input: FragmentInput) -> FragmentOutput {
Expand All @@ -36,7 +36,7 @@ fn fragmentMain(input: FragmentInput) -> FragmentOutput {
}

// evaluate alpha
var alpha: f32 = (exp(-A * 4.0) - EXP4) / (1.0 - EXP4) * gaussianColor.a;
var alpha = textureSampleLevel(expTable, expTableSampler, vec2f(A, 0.5), 0).r * gaussianColor.a;

#if defined(SHADOW_PASS) || defined(PICK_PASS) || defined(PREPASS_PASS)
if (alpha < uniform.alphaClip) {
Expand Down