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
12 changes: 6 additions & 6 deletions src/scene/shader-lib/chunks-wgsl/chunks-wgsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ import gammaPS from './common/frag/gamma.js';
import glossPS from './standard/frag/gloss.js';
// import gsplatCenterVS from './gsplat/vert/gsplatCenter.js';
// import gsplatColorVS from './gsplat/vert/gsplatColor.js';
// import gsplatCommonVS from './gsplat/vert/gsplatCommon.js';
import gsplatCommonVS from './gsplat/vert/gsplatCommon.js';
// import gsplatCompressedDataVS from './gsplat/vert/gsplatCompressedData.js';
// import gsplatCompressedSHVS from './gsplat/vert/gsplatCompressedSH.js';
// import gsplatCornerVS from './gsplat/vert/gsplatCorner.js';
// import gsplatDataVS from './gsplat/vert/gsplatData.js';
// import gsplatOutputVS from './gsplat/vert/gsplatOutput.js';
// import gsplatPS from './gsplat/frag/gsplat.js';
import gsplatPS from './gsplat/frag/gsplat.js';
// import gsplatSHVS from './gsplat/vert/gsplatSH.js';
// import gsplatSourceVS from './gsplat/vert/gsplatSource.js';
// import gsplatVS from './gsplat/vert/gsplat.js';
import gsplatVS from './gsplat/vert/gsplat.js';
import immediateLinePS from './internal/frag/immediateLine.js';
import immediateLineVS from './internal/vert/immediateLine.js';
import iridescenceDiffractionPS from './lit/frag/iridescenceDiffraction.js';
Expand Down Expand Up @@ -262,15 +262,15 @@ const shaderChunksWGSL = {
// gsplatCenterVS,
// gsplatCornerVS,
// gsplatColorVS,
// gsplatCommonVS,
gsplatCommonVS,
// gsplatCompressedDataVS,
// gsplatCompressedSHVS,
// gsplatDataVS,
// gsplatOutputVS,
// gsplatPS,
gsplatPS,
// gsplatSHVS,
// gsplatSourceVS,
// gsplatVS,
gsplatVS,
immediateLinePS,
immediateLineVS,
iridescenceDiffractionPS,
Expand Down
72 changes: 72 additions & 0 deletions src/scene/shader-lib/chunks-wgsl/gsplat/frag/gsplat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
export default /* wgsl */`

#ifndef DITHER_NONE
#include "bayerPS"
#include "opacityDitherPS"
varying id: f32;
#endif

#ifdef PICK_PASS
#include "pickPS"
#endif

#if defined(SHADOW_PASS) || defined(PICK_PASS) || defined(PREPASS_PASS)
uniform alphaClip: f32;
#endif

#ifdef PREPASS_PASS
varying vLinearDepth: f32;
#include "floatAsUintPS"
#endif

varying gaussianUV: vec2f;
varying gaussianColor: vec4f;

@fragment
fn fragmentMain(input: FragmentInput) -> FragmentOutput {
var output: FragmentOutput;

let A: f32 = dot(gaussianUV, gaussianUV);
if (A > 1.0) {
discard;
return output;
}

// evaluate alpha
var alpha: f32 = exp(-A * 4.0) * gaussianColor.a;

#if defined(SHADOW_PASS) || defined(PICK_PASS) || defined(PREPASS_PASS)
if (alpha < uniform.alphaClip) {
discard;
return output;
}
#endif

#ifdef PICK_PASS

output.color = getPickOutput();

#elif SHADOW_PASS

output.color = vec4f(0.0, 0.0, 0.0, 1.0);

#elif PREPASS_PASS

output.color = float2vec4(vLinearDepth);

#else

if (alpha < (1.0 / 255.0)) {
discard;
return output;
}

#ifndef DITHER_NONE
opacityDither(&alpha, id * 0.013);
#endif

output.color = vec4f(input.gaussianColor.xyz * alpha, alpha);
#endif

return output;
}`;
76 changes: 76 additions & 0 deletions src/scene/shader-lib/chunks-wgsl/gsplat/vert/gsplat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
export default /* wgsl */`
#include "gsplatCommonVS"

varying gaussianUV: vec2f;
varying gaussianColor: vec4f;

#ifndef DITHER_NONE
varying id: f32;
#endif

const discardVec: vec4f = vec4f(0.0, 0.0, 2.0, 1.0);

#ifdef PREPASS_PASS
varying vLinearDepth: f32;
#endif

@vertex
fn vertexMain(input: VertexInput) -> VertexOutput {
var output: VertexOutput;

// read gaussian details
var source: SplatSource;
if (!initSource(&source)) {
output.position = discardVec;
return output;
}

let modelCenter: vec3f = readCenter(&source);

var center: SplatCenter;
if (!initCenter(modelCenter, &center)) {
output.position = discardVec;
return output;
}

// project center to screen space
var corner: SplatCorner;
if (!initCorner(&source, &center, &corner)) {
output.position = discardVec;
return output;
}

// read color
var clr: vec4f = readColor(&source);

#if GSPLAT_AA
// apply AA compensation
clr.a = clr.a * corner.aaFactor;
#endif

// evaluate spherical harmonics
#if SH_BANDS > 0
// calculate the model-space view direction
let modelView3x3 = mat3x3f(center.modelView[0].xyz, center.modelView[1].xyz, center.modelView[2].xyz);
let dir = normalize(modelView3x3 * center.view);
clr = vec4f(clr.xyz + evalSH(&source, dir), clr.a);
#endif

clipCorner(&corner, clr.w);

// write output
output.position = center.proj + vec4f(corner.offset, 0.0, 0.0);
output.gaussianUV = corner.uv;
output.gaussianColor = vec4f(prepareOutputFromGamma(max(clr.xyz, vec3f(0.0))), clr.w);

#ifndef DITHER_NONE
output.id = f32(source.id);
#endif

#ifdef PREPASS_PASS
output.vLinearDepth = -center.view.z;
#endif

return output;
}
`;
133 changes: 133 additions & 0 deletions src/scene/shader-lib/chunks-wgsl/gsplat/vert/gsplatCommon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
export default /* wgsl */`

// stores the source UV and order of the splat
struct SplatSource {
order: u32, // render order
id: u32, // splat id
uv: vec2<i32>, // splat uv
cornerUV: vec2f, // corner coordinates for this vertex of the gaussian (-1, -1)..(1, 1)
}

// stores the camera and clip space position of the gaussian center
struct SplatCenter {
view: vec3f, // center in view space
proj: vec4f, // center in clip space
modelView: mat4x4f, // model-view matrix
projMat00: f32, // elememt [0][0] of the projection matrix
}

// stores the offset from center for the current gaussian
struct SplatCorner {
offset: vec2f, // corner offset from center in clip space
uv: vec2f, // corner uv
#if GSPLAT_AA
aaFactor: f32, // for scenes generated with antialiasing
#endif
}

#if GSPLAT_COMPRESSED_DATA == true
#include "gsplatCompressedDataVS"
#include "gsplatCompressedSHVS"
#elif GSPLAT_SOGS_DATA == true
#include "gsplatSogsDataVS"
#include "gsplatSogsColorVS"
#include "gsplatSogsSHVS"
#else
#include "gsplatDataVS"
#include "gsplatColorVS"
#include "gsplatSHVS"
#endif

#include "gsplatSourceVS"
#include "gsplatCenterVS"
#include "gsplatCornerVS"
#include "gsplatOutputVS"

// modify the gaussian corner so it excludes gaussian regions with alpha less than 1/255
fn clipCorner(corner: ptr<function, SplatCorner>, alpha: f32) {
let clip: f32 = min(1.0, sqrt(-log(1.0 / (255.0 * alpha))) / 2.0);
corner.offset = corner.offset * clip;
corner.uv = corner.uv * clip;
}

// spherical Harmonics

#if SH_BANDS > 0
const SH_C1: f32 = 0.4886025119029199;

#if SH_BANDS > 1
const SH_C2_0: f32 = 1.0925484305920792;
const SH_C2_1: f32 = -1.0925484305920792;
const SH_C2_2: f32 = 0.31539156525252005;
const SH_C2_3: f32 = -1.0925484305920792;
const SH_C2_4: f32 = 0.5462742152960396;
#endif

#if SH_BANDS > 2
const SH_C3_0: f32 = -0.5900435899266435;
const SH_C3_1: f32 = 2.890611442640554;
const SH_C3_2: f32 = -0.4570457994644658;
const SH_C3_3: f32 = 0.3731763325901154;
const SH_C3_4: f32 = -0.4570457994644658;
const SH_C3_5: f32 = 1.445305721320277;
const SH_C3_6: f32 = -0.5900435899266435;
#endif

// see https://github.com/graphdeco-inria/gaussian-splatting/blob/main/utils/sh_utils.py
fn evalSH(source: ptr<function, SplatSource>, dir: vec3f) -> vec3f {

#if SH_BANDS > 0
#if SH_BANDS == 1
var sh: array<vec3f, 3>;
#elif SH_BANDS == 2
var sh: array<vec3f, 8>;
#elif SH_BANDS == 3
var sh: array<vec3f, 15>;
#endif
#endif

var scale: f32;
readSHData(source, &sh, &scale);

let x = dir.x;
let y = dir.y;
let z = dir.z;

// 1st degree
var result = SH_C1 * (-sh[0] * y + sh[1] * z - sh[2] * x);

#if SH_BANDS > 1
// 2nd degree
let xx = x * x;
let yy = y * y;
let zz = z * z;
let xy = x * y;
let yz = y * z;
let xz = x * z;

result = result + (
sh[3] * (SH_C2_0 * xy) +
sh[4] * (SH_C2_1 * yz) +
sh[5] * (SH_C2_2 * (2.0 * zz - xx - yy)) +
sh[6] * (SH_C2_3 * xz) +
sh[7] * (SH_C2_4 * (xx - yy))
);
#endif

#if SH_BANDS > 2
// 3rd degree
result = result + (
sh[8] * (SH_C3_0 * y * (3.0 * xx - yy)) +
sh[9] * (SH_C3_1 * xy * z) +
sh[10] * (SH_C3_2 * y * (4.0 * zz - xx - yy)) +
sh[11] * (SH_C3_3 * z * (2.0 * zz - 3.0 * xx - 3.0 * yy)) +
sh[12] * (SH_C3_4 * x * (4.0 * zz - xx - yy)) +
sh[13] * (SH_C3_5 * z * (xx - yy)) +
sh[14] * (SH_C3_6 * x * (xx - 3.0 * yy))
);
#endif

return result * scale;
}
#endif
`;
Loading