UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

132 lines (131 loc) 4.27 kB
var gsplatHybrid_default = ` #include "gsplatHelpersVS" #include "gsplatOutputVS" #ifdef GSPLAT_USER_VARYINGS #include "gsplatUserVaryingsVS" #endif attribute vertex_position: vec3f; uniform viewport_size: vec4f; uniform clipToViewZ: vec4f; #ifdef GSPLAT_XR uniform view_index: u32; uniform matrix_projection: mat4x4f; #endif #if defined(SHADOW_PASS) || defined(PICK_PASS) || defined(PREPASS_PASS) uniform alphaClip: f32; #else uniform alphaClipForward: f32; #endif var<storage, read> sortedIndices: array<u32>; var<storage, read> projCache: array<u32>; var<storage, read> numSplatsStorage: array<u32>; varying gaussianUV: half2; varying gaussianColor: half4; #ifndef DITHER_NONE varying id: f32; #endif #ifdef PREPASS_PASS varying vLinearDepth: f32; #endif #if defined(GSPLAT_UNIFIED_ID) && defined(PICK_PASS) varying @interpolate(flat) vPickId: u32; #endif #ifdef GSPLAT_OVERDRAW uniform colorRampIntensity: f32; var colorRamp: texture_2d<f32>; var colorRampSampler: sampler; #endif const discardVec: vec4f = vec4f(0.0, 0.0, 2.0, 1.0); @vertex fn vertexMain(input: VertexInput) -> VertexOutput { var output: VertexOutput; let order = pcInstanceIndex * {GSPLAT_INSTANCE_SIZE}u + u32(vertex_position.z); let numSplats = numSplatsStorage[0]; if (order >= numSplats) { output.position = discardVec; return output; } let cacheIdx = sortedIndices[order]; let base = cacheIdx * {CACHE_STRIDE}u; #ifdef GSPLAT_XR let off = uniform.view_index * 2u; let ndc = vec2f( bitcast<f32>(projCache[base + off + 0u]), bitcast<f32>(projCache[base + off + 1u]) ); let w = bitcast<f32>(projCache[base + 4u]); let pz = (uniform.matrix_projection[2][2] / uniform.matrix_projection[2][3]) * w + uniform.matrix_projection[3][2]; let proj = vec4f(ndc * w, clamp(pz, 0.0, abs(w)), w); let v1 = unpack2x16float(projCache[base + 5u]); let v2 = unpack2x16float(projCache[base + 6u]); let rgba = unpack4x8unorm(projCache[base + 7u]); let alpha = half(rgba.a); var clr: half4 = half4(half(rgba.r), half(rgba.g), half(rgba.b), alpha); #else let proj = vec4f( bitcast<f32>(projCache[base + 0u]), bitcast<f32>(projCache[base + 1u]), bitcast<f32>(projCache[base + 2u]), bitcast<f32>(projCache[base + 3u]) ); let v1 = unpack2x16float(projCache[base + 4u]); let v2 = unpack2x16float(projCache[base + 5u]); let ba = unpack2x16float(projCache[base + 7u]); let alpha = half(ba.y); #if defined(GSPLAT_UNIFIED_ID) && defined(PICK_PASS) let pickId = projCache[base + 6u]; #endif #ifdef PICK_PASS var clr: half4 = half4(half(0.0), half(0.0), half(0.0), alpha); #else let rg = unpack2x16float(projCache[base + 6u]); var clr: half4 = half4(half(rg.x), half(rg.y), half(ba.x), alpha); #endif #endif let cornerUV = vec2f(vertex_position.xy); #if defined(SHADOW_PASS) || defined(PICK_PASS) || defined(PREPASS_PASS) let alphaClipValue = half(uniform.alphaClip); #else let alphaClipValue = half(uniform.alphaClipForward); #endif let clip = min(half(1.0), sqrt(max(half(0.0), log(alpha / alphaClipValue))) * half(0.5)); let cornerClipped = cornerUV * f32(clip); let c = vec2f(proj.w) * uniform.viewport_size.zw; let pixelOffset = cornerClipped.x * v1 + cornerClipped.y * v2; let clipOffset = pixelOffset * c; output.position = proj + vec4f(clipOffset, 0.0, 0.0); output.gaussianUV = half2(cornerClipped); #ifdef GSPLAT_USER_VARYINGS #include "gsplatUserCacheReadVS" #endif #ifdef GSPLAT_XR let viewDepth = proj.w; #else let viewDepth = dot(uniform.clipToViewZ, proj); #endif #ifdef GSPLAT_OVERDRAW let t: f32 = clamp(viewDepth / 20.0, 0.0, 1.0); let rampColor: vec3f = textureSampleLevel(colorRamp, colorRampSampler, vec2f(t, 0.5), 0.0).rgb; let outAlpha = alpha * half(1.0 / 32.0) * half(uniform.colorRampIntensity); output.gaussianColor = half4(half3(rampColor), outAlpha); #else output.gaussianColor = half4( half3(prepareOutputFromGamma(max(vec3f(clr.xyz), vec3f(0.0)), viewDepth)), alpha ); #endif #ifndef DITHER_NONE output.id = f32(cacheIdx); #endif #ifdef PREPASS_PASS output.vLinearDepth = viewDepth; #endif #if defined(GSPLAT_UNIFIED_ID) && defined(PICK_PASS) output.vPickId = pickId; #endif return output; } `; export { gsplatHybrid_default as default };