"매 NeRF 의 후계자 — 매 3D scene 을 millions of anisotropic Gaussian 으로 표현, web 에서 60fps real-time render". 2023 SIGGRAPH (Kerbl et al.) 의 3DGS paper 가 NeRF 의 slow ray-marching 을 differentiable rasterization 으로 대체하면서 photorealistic 3D capture 가 commodity 가 되었다. 2026 현재 WebSplatter / antimatter15-splat / SuperSplat / gsplat.js 등이 매 browser 에서 native handling — Apple Vision Pro / Quest 3 immersive content 의 default format.
매 핵심
매 3DGS 본질
Representation: 매 scene = N개 (보통 1M-10M) 의 3D Gaussian — 매 Gaussian 은 (position μ, covariance Σ, opacity α, SH color coefficients) 로 parametrize.
Rendering: 매 differentiable rasterization — Gaussian 을 screen space ellipse 로 project 후 alpha-blend (front-to-back).
Training: 매 SfM (COLMAP) sparse cloud 로 init → photometric loss + densification/pruning heuristic 으로 optimize (~30min on RTX 4090 for one scene).
매 NeRF 대비
Speed: NeRF 매 second-per-frame, 3DGS 매 100+ fps (1080p, RTX 30 class).
Quality: 매 PSNR 비슷 (Mip-NeRF 360 기준 27.4 vs 27.5), 매 sharper detail in foreground.
Editability: 매 explicit primitive — 매 Gaussian 단위 select / delete / transform 가능 (NeRF 매 implicit MLP, edit 어려움).
매 Web 배포 challenge
File size: 1M Gaussian × 60 byte/Gaussian = 60MB raw. 매 SOG / SOGS / .ply quantize 로 ~5-10MB 까지 압축.
Sort cost: 매 frame 마다 view-dependent depth sort 필요 (correct alpha blend). 매 GPU radix sort 필수.
Browser GPU: WebGL2 매 instanced rendering hack 필요, WebGPU 매 compute shader 로 native sort.
매 응용
Real estate 3D walkthrough — 매 phone 으로 capture, 매 WebSplatter viewer 로 share.
E-commerce — 매 product 360 turntable.
VFX previz — 매 set scan 후 Unreal/Blender 로 import.
// depth-sort.wgsl — view-dependent radix sort
@group(0)@binding(0)var<storage,read>positions:array<vec4<f32>>;@group(0)@binding(1)var<storage,read_write>depths:array<u32>;@group(0)@binding(2)var<uniform>viewProj:mat4x4<f32>;@compute@workgroup_size(256)fncomputeDepth(@builtin(global_invocation_id)gid:vec3<u32>){leti=gid.x;if(i>=arrayLength(&positions)){return;}letclip=viewProj*vec4(positions[i].xyz,1.0);// negate so far → small key, near → large (back-to-front blending)
depths[i]=bitcast<u32>(-clip.z/clip.w);}
3. Splat instanced rendering (WebGL2)
// vertex shader — project 3D Gaussian to 2D ellipseinvec3a_quad;// unit quad corner [-1,1]invec3a_center;// Gaussian μinvec3a_cov_a;// covariance row 0invec3a_cov_b;// covariance row 1invec4a_color;// SH degree-0 + opacityuniformmat4u_viewProj;outvec2v_uv;outvec4v_color;voidmain(){vec4clip=u_viewProj*vec4(a_center,1.0);// project 3D covariance to 2D screen space (Zwicker EWA splatting)mat2cov2d=projectCovariance(a_cov_a,a_cov_b,clip);vec2axis=computeMajorAxis(cov2d);vec2offset=a_quad.x*axis+a_quad.y*perpendicular(axis);gl_Position=clip+vec4(offset,0.0,0.0);v_uv=a_quad.xy;v_color=a_color;}
4. Quantize (SOG format, 2025)
# self-organizing Gaussian — 90% size reductionimporttorchfromsogsimportSOGCompressorsplat=torch.load("scene.pt")# raw 3DGS statecompressor=SOGCompressor(position_bits=16,scale_bits=8,rotation_bits=8,sh_bits=6,)compressed=compressor.compress(splat)compressor.write("scene.sog",compressed)# ~6MB instead of 60MB
5. Train custom scene (gsplat library)
# Modern training pipeline (Nerfstudio + gsplat backend)fromnerfstudio.scripts.trainimportmainastraintrain(["splatfacto",# gsplat-based pipeline"--data","data/my_scene","--max-num-iterations","30000","--pipeline.model.cull-alpha-thresh","0.1","--pipeline.model.densify-grad-thresh","0.0002",])# Export: ns-export gaussian-splat --load-config outputs/.../config.yml
언제: 매 photo-realistic real-world scene 을 매 web/AR 에 deploy 하고 싶을 때. 매 capture-once-view-anywhere workflow.
언제 X: 매 procedurally generated content (game asset)는 매 mesh + PBR 가 여전히 우월. 매 dynamic deformable mesh, 매 physical simulation.
❌ 안티패턴
Quantize 안 하고 60MB raw 배포: 매 mobile 에서 OOM. 항상 SOG/SOGS 거쳐야.
CPU sort: 매 1M Gaussian sort 매 frame 매 100ms+. 매 GPU radix sort 필수.
Sparse SfM init 생략: 매 random init 매 converge 안 함. COLMAP step skip 금지.
Aggressive densification: 매 split threshold 너무 낮으면 매 30M Gaussians 폭발 → OOM.