Nodes/ComfyUI-TurntableGSViewer/Transform Gaussian
ComfyUI Node

Transform Gaussian

Rotate a gaussian splat without breaking its headlights

By PozzettiAndrea·Created 4 months ago·Updated 8 days ago· 6
Transform Gaussian
    • ply_path
    ply_path
    rotate_x0
    rotate_y0
    rotate_z0

    Your trained gaussian splat is lying on its side, or facing the wrong way, or doesn't line up with the camera path you want to fly through it. Rotating a mesh is a one-liner; rotating a gaussian splat is a trap. A splat isn't just points - every gaussian also has an orientation (a quaternion), and most carry view-dependent spherical-harmonic colors. Rotate the positions and ignore the rest, and you get a scene where specular highlights slide across surfaces like a broken lighthouse. TransformGaussian rotates the whole thing correctly.

    It's part of the GaussianPack family (GitHub repo ComfyUI-TurntableGSViewer, self-labeled "GaussianPack" - same author as ComfyUI's HyWorld2 and TRELLIS.2 wrappers). The rotation order deliberately matches GeometryPack's TransformMesh._rotate, so mesh and gaussian versions of the same scene behave identically for the same angle inputs.

    What "rotating a gaussian" actually means

    Under the hood it does four things at once:

    • rotates the (x, y, z) positions by the XYZ Euler rotation
    • composes each per-splat quaternion with the global rotation (Hamilton product)
    • rotates the surface normals, if the PLY carries them
    • rotates the view-dependent SH AC coefficients (f_rest_*) in the SH basis using Wigner D-matrices computed by Ivanic-Ruedenberg recursion

    The DC term (f_dc_*, the base color) is rotation-invariant, so it's left alone - that's mathematically correct, not an oversight. The result is a genuinely re-oriented scene: turn it 90° and the highlights rotate with the geometry instead of smearing.

    Inputs and output

    • ply_path - the 3DGS PLY to transform.
    • rotate_x, rotate_y, rotate_z - degrees around each axis, each −360 to +360, applied in X→Y→Z order. 0 means no rotation on that axis.

    The single output, ply_path, is the absolute path to a new PLY written into ComfyUI's output folder. The filename encodes the rotation plus a short hash of the inputs, so re-running with the same settings doesn't collide and two different rotations don't overwrite each other. Wire the result into PreviewGaussians or PreviewGaussianDual to check it, then on into a merge or export.

    Installing it

    cd ComfyUI/custom_nodes
    git clone https://github.com/PozzettiAndrea/ComfyUI-TurntableGSViewer.git
    cd ComfyUI-TurntableGSViewer
    pip install -r requirements.txt --upgrade
    python install.py
    

    Restart ComfyUI. Manager users: search "GaussianPack". The pack's requirements include the experimental comfy-env installer (it fetches the pixi package manager on first install - let it finish), plus plyfile and a NanoGS git dependency. No model weights to download.

    Gotchas

    The output is a full rewritten PLY, so on a large scene this is a read-everything, write-everything operation - not instant, and it'll eat disk with a second copy of the file. Use it once to fix orientation, not in a tight loop. And if you need to compare against the original after rotating, that's precisely what PreviewGaussianDual is for - wire the source into one side and the transform output into the other, and the synchronized camera will show you that the rotation is clean and the highlights stayed put.

    Categoryviewer

    Inputs (4)

    NameTypeDefaultDescription
    ply_pathSTRINGPath to a 3D Gaussian Splatting PLY file.
    rotate_xFLOAT0-360–360Rotation around X axis (degrees).
    rotate_yFLOAT0-360–360Rotation around Y axis (degrees).
    rotate_zFLOAT0-360–360Rotation around Z axis (degrees).

    Outputs (1)

    NameTypeDescription
    ply_pathSTRING