Skip to content
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

GS WebGPU + NME ui fixes #15778

Merged
merged 9 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ export class GaussianSplattingBlock extends NodeMaterialBlock {
const projection = this.projection;
const output = this.splatVertex;

let splatScaleParameter = "vec2(1.,1.)";
const addF = state.fSuffix;
let splatScaleParameter = `vec2${addF}(1.,1.)`;
if (splatScale.isConnected) {
splatScaleParameter = splatScale.associatedVariableName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ export class SplatReaderBlock extends NodeMaterialBlock {
const splatVariablename = state._getFreeVariableName("splat");
state.compilationString += `Splat ${splatVariablename} = readSplat(${splatIndex.associatedVariableName});\n`;

state.compilationString += "vec3 covA = splat.covA.xyz; vec3 covB = vec3(splat.covA.w, splat.covB.xy);\n";
state.compilationString += "vPosition = position;";
const addF = state.fSuffix;
state.compilationString += `vec3${addF} covA = splat.covA.xyz; vec3${addF} covB = vec3${addF}(splat.covA.w, splat.covB.xy);\n`;
state.compilationString += "vPosition = position;\n";
state.compilationString += `${state._declareOutput(splatPosition)} = ${splatVariablename}.center.xyz;\n`;
state.compilationString += `${state._declareOutput(splatColor)} = ${splatVariablename}.color;\n`;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
fn getDataUV(index: i32, textureSize: vec2f) -> vec2<i32> {
let y = index / i32(textureSize.x);
let x = index % i32(textureSize.x);
return vec2<i32>(x, y);
}

struct Splat {
center: vec4f,
color: vec4f,
covA: vec4f,
covB: vec4f,
};

fn readSplat(splatIndex: f32, textureSize: vec2f) -> Splat {
var splat: Splat;
let splatUV = getDataUV(i32(splatIndex), textureSize);
splat.center = textureLoad(centersTexture, splatUV, 0);
splat.color = textureLoad(colorsTexture, splatUV, 0);
splat.covA = textureLoad(covariancesATexture, splatUV, 0) * splat.center.w;
splat.covB = textureLoad(covariancesBTexture, splatUV, 0) * splat.center.w;

return splat;
}

fn gaussianSplatting(
meshPos: vec2<f32>,
worldPos: vec3<f32>,
scale: vec2<f32>,
covA: vec3<f32>,
covB: vec3<f32>,
worldMatrix: mat4x4<f32>,
viewMatrix: mat4x4<f32>,
projectionMatrix: mat4x4<f32>,
focal: vec2<f32>,
invViewport: vec2<f32>
) -> vec4f {
let modelView = viewMatrix * worldMatrix;
let camspace = viewMatrix * vec4f(worldPos, 1.0);
let pos2d = projectionMatrix * camspace;

let bounds = 1.2 * pos2d.w;
if (pos2d.z < -pos2d.w || pos2d.x < -bounds || pos2d.x > bounds || pos2d.y < -bounds || pos2d.y > bounds) {
return vec4f(0.0, 0.0, 2.0, 1.0);
}

let Vrk = mat3x3<f32>(
covA.x, covA.y, covA.z,
covA.y, covB.x, covB.y,
covA.z, covB.y, covB.z
);

let J = mat3x3<f32>(
focal.x / camspace.z, 0.0, -(focal.x * camspace.x) / (camspace.z * camspace.z),
0.0, focal.y / camspace.z, -(focal.y * camspace.y) / (camspace.z * camspace.z),
0.0, 0.0, 0.0
);

let invy = mat3x3<f32>(
1.0, 0.0, 0.0,
0.0, -1.0, 0.0,
0.0, 0.0, 1.0
);

let T = invy * transpose(mat3x3<f32>(
modelView[0].xyz,
modelView[1].xyz,
modelView[2].xyz)) * J;
let cov2d = transpose(T) * Vrk * T;

let mid = (cov2d[0][0] + cov2d[1][1]) / 2.0;
let radius = length(vec2<f32>((cov2d[0][0] - cov2d[1][1]) / 2.0, cov2d[0][1]));
let lambda1 = mid + radius;
let lambda2 = mid - radius;

if (lambda2 < 0.0) {
return vec4f(0.0, 0.0, 2.0, 1.0);
}

let diagonalVector = normalize(vec2<f32>(cov2d[0][1], lambda1 - cov2d[0][0]));
let majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;
let minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2<f32>(diagonalVector.y, -diagonalVector.x);

let vCenter = vec2<f32>(pos2d.x, pos2d.y);
return vec4f(
vCenter + ((meshPos.x * majorAxis + meshPos.y * minorAxis) * invViewport * pos2d.w) * scale,
pos2d.z,
pos2d.w
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
fn gaussianColor(inColor: vec4f, inPosition: vec2f) -> vec4f
{
var A : f32 = -dot(inPosition, inPosition);
if (A > -4.0)
{
var B: f32 = exp(A) * inColor.a;

#include<logDepthFragment>

var color: vec3f = inColor.rgb;

#ifdef FOG
#include<fogFragment>
#endif

return vec4f(color, B);
} else {
return vec4f(0.0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include<sceneUboDeclaration>
#include<meshUboDeclaration>

attribute position: vec2f;
15 changes: 15 additions & 0 deletions packages/dev/core/src/ShadersWGSL/gaussianSplatting.fragment.fx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include<clipPlaneFragmentDeclaration>
#include<logDepthDeclaration>
#include<fogFragmentDeclaration>

varying vColor: vec4f;
varying vPosition: vec2f;

#include<gaussianSplattingFragmentDeclaration>

@fragment
fn main(input: FragmentInputs) -> FragmentOutputs {
#include<clipPlaneFragment>

fragmentOutputs.color = gaussianColor(input.vColor, input.vPosition);
}
48 changes: 48 additions & 0 deletions packages/dev/core/src/ShadersWGSL/gaussianSplatting.vertex.fx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include<clipPlaneVertexDeclaration>
#include<fogVertexDeclaration>
#include<logDepthDeclaration>

// Attributes
attribute splatIndex: f32;
attribute position: vec2f;

// Uniforms
uniform invViewport: vec2f;
uniform textureSize: vec2f;
uniform focal: vec2f;

uniform view: mat4x4f;
uniform projection: mat4x4f;
uniform world: mat4x4f;

// textures
var covariancesATexture: texture_2d<f32>;
var covariancesBTexture: texture_2d<f32>;
var centersTexture: texture_2d<f32>;
var colorsTexture: texture_2d<f32>;

// Output
varying vColor: vec4f;
varying vPosition: vec2f;

#include<gaussianSplatting>

@vertex
fn main(input : VertexInputs) -> FragmentInputs {

var splat: Splat = readSplat(input.splatIndex, uniforms.textureSize);
var covA: vec3f = splat.covA.xyz;
var covB: vec3f = vec3f(splat.covA.w, splat.covB.xy);

let worldPos: vec4f = uniforms.world * vec4f(splat.center.xyz, 1.0);

vertexOutputs.vColor = splat.color;
vertexOutputs.vPosition = input.position;
vertexOutputs.position = gaussianSplatting(input.position, worldPos.xyz, vec2f(1.0, 1.0), covA, covB, uniforms.world, uniforms.view, uniforms.projection, uniforms.focal, uniforms.textureSize);

#include<clipPlaneVertex>
#include<fogVertex>
#include<logDepthVertex>

return vertexOutputs;
}
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,9 @@ export class PreviewManager {
this._prepareScene();
});
break;
case PreviewType.Custom:
this._globalState.filesInput.loadFiles({ target: { files: this._globalState.listOfCustomPreviewFiles } });
return;
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions packages/tools/nodeEditor/src/components/preview/previewType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ export enum PreviewType {
Explosion,
Fire,

Custom,

// Env
Room,

// Gaussian Splatting
Parrot,
BricksSkull,
Plants,

Custom,

// Env
Room,
}
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
case NodeMaterialModes.Particle:
this.props.globalState.previewType = PreviewType.Bubbles;
break;
case NodeMaterialModes.GaussianSplatting:
this.props.globalState.previewType = PreviewType.BricksSkull;
break;
}

this.props.globalState.listOfCustomPreviewFiles = [];
Expand Down