playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
135 lines (106 loc) • 4.28 kB
JavaScript
var gsplatCopyToWorkbuffer_default = (
/* glsl */
`
// pre-computed model matrix decomposition (declared before includes, used by
// gsplatWorkBufferGeometryPS)
uniform vec3 model_scale;
uniform vec4 model_rotation; // (x,y,z,w) format
// Packed sub-draw params: (sourceBase, colStart, rowWidth, rowStart)
flat varying ivec4 vSubDraw;
uniform vec3 uColorMultiply;
uniform uint uId;
void main(void) {
// Compute source index from packed sub-draw varying: (sourceBase, colStart, rowWidth, rowStart)
int localRow = int(gl_FragCoord.y) - vSubDraw.w;
int localCol = int(gl_FragCoord.x) - vSubDraw.y;
uint originalIndex = uint(vSubDraw.x + localRow * vSubDraw.z + localCol);
// Initialize global splat for format read functions
setSplat(originalIndex);
// World-space geometry to store. Rotation/scale default to identity and are only computed on
// the full-render path; under GSPLAT_COLOR_ONLY they are ignored by writeSplat (DCE'd).
vec3 worldCenter;
vec4 worldRotation = vec4(0.0, 0.0, 0.0, 1.0);
vec3 worldScale = vec3(1.0);
vec3 dir; // model-space view direction
// Color-only update sourcing geometry from previously written work buffer data at this
// destination pixel. The stored center already includes the model transform and
// modifySplatCenter / modifySplatRotationScale, so neither is re-applied here.
initWorkBufferGeometry(ivec2(gl_FragCoord.xy));
worldCenter = workBufferWorldCenter();
// model-space view direction (matches the source path up to non-uniform model scale)
dir = normalize(quatRotateInv(model_rotation, worldCenter - uCameraPosition));
// read center in local space
vec3 modelCenter = getCenter();
// compute world-space center for storage
worldCenter = (matrix_model * vec4(modelCenter, 1.0)).xyz;
SplatCenter center;
initCenter(modelCenter, center);
// Get source rotation and scale
// getRotation() returns (w,x,y,z) format, convert to (x,y,z,w) for quatMul
vec4 srcRotation = getRotation().yzwx;
vec3 srcScale = getScale();
// Combine: world = model * source (both in x,y,z,w format)
worldRotation = quatMul(model_rotation, srcRotation);
// Ensure w is positive so sqrt() reconstruction works correctly
// (quaternions q and -q represent the same rotation)
if (worldRotation.w < 0.0) {
worldRotation = -worldRotation;
}
worldScale = model_scale * srcScale;
// Apply custom center modification
vec3 originalCenter = worldCenter;
modifySplatCenter(worldCenter);
// Apply custom rotation/scale modification
modifySplatRotationScale(originalCenter, worldCenter, worldRotation, worldScale);
// calculate the model-space view direction
dir = normalize(center.view * mat3(center.modelView));
// read color
vec4 color = getColor();
// evaluate spherical harmonics
// read sh coefficients
vec3 sh[SH_COEFFS];
float scale;
readSHData(sh, scale);
// evaluate
color.xyz += evalSH(sh, dir) * scale;
// Apply custom color modification
modifySplatColor(worldCenter, color);
color.xyz *= uColorMultiply;
// write color + transform using format-specific encoding (rotation/scale ignored under
// GSPLAT_COLOR_ONLY)
writeSplat(worldCenter, worldRotation, worldScale, color);
writePcId(uvec4(uId, 0u, 0u, 0u));
}
`
);
export {
gsplatCopyToWorkbuffer_default as default
};