mkkellogg / GaussianSplats3D

Three.js-based implementation of 3D Gaussian splatting
MIT License
1.53k stars 198 forks source link

Can I support ply export splat files #332

Open chaoyang915506 opened 2 months ago

chaoyang915506 commented 2 months ago

I saw downloadFile under ksplatloader. js file to download ksplat file directly. SplatLoader.js I tried to add downloadFile method under KSplatLoader and found that the exported splat could not be used. I want to export a splat file.

mkkellogg commented 2 months ago

Currently I don't have any way to export to .splat format in my viewer. What is your source format? You can always use the antimatter15 viewer or SuperSplat to export to .splat.

chaoyang915506 commented 2 months ago

https://huggingface.co/spaces/dylanebert/gsplat-editor
Ok, my source data is ply format files, it would be great if I could export ply and splat based on the rendered content just like the site in the link.

gotoeasy commented 2 months ago

https://huggingface.co/spaces/dylanebert/gsplat-editor Ok, my source data is ply format files, it would be great if I could export ply and splat based on the rendered content just like the site in the link.

# 3dgs ply to splat
gsbox -i /path/to/input.ply -o /path/to/output.splat

# splat to 3dgs ply
gsbox -i /path/to/input.splat -o /path/to/output.ply

https://github.com/gotoeasy/gsbox

FanYaning commented 2 months ago
from plyfile import PlyData
import numpy as np
from io import BytesIO
def process_ply_to_splat(ply_file_path, splat_file_path):
    plydata = PlyData.read(ply_file_path)
    vert = plydata["vertex"]
    buffer = BytesIO()
    SH_C0 = 0.28209479177387814
    for v in vert:
        position = np.array([v["x"], v["y"], v["z"]], dtype=np.float32)
        scales = np.exp(
            np.array(
                [v["scale_0"], v["scale_1"], v["scale_2"]],
                dtype=np.float32,
            )
        )
        rot = np.array(
            [v["rot_0"], v["rot_1"], v["rot_2"], v["rot_3"]],
            dtype=np.float32,
        )
        color = np.array(
            [
                0.5 + SH_C0 * v["f_dc_0"],
                0.5 + SH_C0 * v["f_dc_1"],
                0.5 + SH_C0 * v["f_dc_2"],
                1 / (1 + np.exp(-v["opacity"])),
            ]
        )
        buffer.write(position.tobytes())
        buffer.write(scales.tobytes())
        buffer.write((color * 255).clip(0, 255).astype(np.uint8).tobytes())
        buffer.write(
            ((rot / np.linalg.norm(rot)) * 128 + 128)
            .clip(0, 255)
            .astype(np.uint8)
            .tobytes()
        )
        with open(splat_file_path, "wb") as f:
            f.write(buffer.getvalue())
        buffer.close()