hyperlogic / splatapult

A 3d gaussian splatting renderer in C++ and OpenGL
MIT License
89 stars 12 forks source link

[Bug] This implementation will introduce some color shift in some case. #16

Closed 543877815 closed 3 months ago

543877815 commented 3 months ago

Hello, hyperlogic I wanted to reach out to you regarding an issue I've encountered with your implementation. I appreciate the excellent work you've done, but I've come across something that seems like a bug.

I have trained the "coffee" dataset from Ref-NeRF, using the default training parameters provided on 3dgs. I proceeded to use the PLY model from the final step of 30,000 as the input for your implementation. Upon doing so, I noticed some unexpected color artifacts in the output. There appear to be small patches of green and purple color that weren't present here. image In contrast, when I view the "ground truth" using SIBR viewers, the model appears clean and smooth, without any of the aforementioned color discrepancies. image

I would be grateful if you could provide some guidance or insight into this matter. Thank you for your attention to this issue, and I look forward to your response.

Best regards。

hyperlogic commented 3 months ago

Hmm, interesting, this looks like it could be due to accumulated error during alpha blending. By default, Splatapult uses a 32-bit color frame buffer (8 bits per component) during back to front rendering. It might be possible to change the code to pick a different bit-depth if the hardware supports it, for example fp16 per component, but higher bit depths would likely affect performance.

I'll take a look at the SIBR renderer to see what bit-depth it uses.

543877815 commented 3 months ago

Cool, I think it's a reasonable insight, but it seems very difficult to implement in a traditional graphics pipeline. By the way, is the following logic related to “T” in the CUDA implementation also hard to implement without a full compute shader?

float T = 1.0f;
... // loop
    float test_T = T * (1 - alpha); 
    if (test_T < 0.0001f)  
    {
        done = true;
        continue;
    }
    ...
    T = test_T;
... // end loop
hyperlogic commented 3 months ago

I think CUDA implementation can do because it has a full list of of all Gaussians in the tile and can run thru them in front to back order and stop when it is fully opaque. From the original 3DGS paper Appendix C:

Finally, before a Gaussian is included in the forward rasterization
pass, we compute the accumulated opacity if we were to include it
and stop front-to-back blending before it can exceed 0.9999

Splatapult is dumb brute force, it just renders all splats in back to front order.

hyperlogic commented 3 months ago

I included an option to render into a half-float or float frame buffer, --fp16 and --fp32 respectively. This eliminates the banding artifacts.

22ff61759ec4911296e4f1b0ba37db86c53e0e68