graphdeco-inria / gaussian-splatting

Original reference implementation of "3D Gaussian Splatting for Real-Time Radiance Field Rendering"
https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/
Other
14.48k stars 1.89k forks source link

Question about `render.py` #408

Open hyoseok1223 opened 1 year ago

hyoseok1223 commented 1 year ago

Thank you for great work, I have some questions in render.py

https://github.com/graphdeco-inria/gaussian-splatting/blob/f11001b46c5c73a0a7d553353c898efd68412abe/gaussian_renderer/__init__.py#L95C5-L100C28

    # Those Gaussians that were frustum culled or had a radius of 0 were not visible.
    # They will be excluded from value updates used in the splitting criteria.
    return {"render": rendered_image,
            "viewspace_points": screenspace_points,
            "visibility_filter" : radii > 0,
            "radii": radii}
kwea123 commented 1 year ago
  1. yes culling is done during rasterization
  2. z values are in euclidean space
  3. screenspace_points is passed to rasterizer function which fills this variable with the image coordinates (uv) of the gaussians
MobiusLqm commented 10 months ago

@kwea123 Hi, Thank your for your explanation. But Why the elements in varible 'screenspace_points' after rendered are still all with zero? Could you explain it more clearly?I'm still confused. Thank you!

kwea123 commented 10 months ago

@MobiusLqm oh sorry, that variable is only used to keep the gradient w.r.t. uv, the content itself is still zero. The values are stored in this variable https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L265 but with this code it is very hard to extract them. You need to compute the correct offset from https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L158-L165 then get it from the variable geomBuffer on this line https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/diff_gaussian_rasterization/__init__.py#L86

MobiusLqm commented 10 months ago

@MobiusLqm oh sorry, that variable is only used to keep the gradient w.r.t. uv, the content itself is still zero. The values are stored in this variable https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L265 but with this code it is very hard to extract them. You need to compute the correct offset from https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L158-L165 then get it from the variable geomBuffer on this line https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/diff_gaussian_rasterization/__init__.py#L86

@kwea123 Greate thanks for your explanation, I really appreciate it. I will check it later.

ShaySheng commented 8 months ago

@MobiusLqm oh sorry, that variable is only used to keep the gradient w.r.t. uv, the content itself is still zero. The values are stored in this variable https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L265 but with this code it is very hard to extract them. You need to compute the correct offset from https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L158-L165 then get it from the variable geomBuffer on this line https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/diff_gaussian_rasterization/__init__.py#L86

How exactly does it "retain the gradient with respect to uv"? I was under the impression that means2D is ultimately passed to this section of the code. However, it appears that it isn't utilized there at all. Could you guide me on how to further trace its usage or impact?

ShaohuaL commented 8 months ago
  1. yes culling is done during rasterization
  2. z values are in euclidean space
  3. screenspace_points is passed to rasterizer function which fills this variable with the image coordinates (uv) of the gaussians

Hi!Thank your good tutorials about 3D GS ^-^! I think means2D stores gradients about NDC space, but not image space.

atomicAdd(&dL_dmean2D[global_id].x, dL_dG * dG_ddelx * ddelx_dx); atomicAdd(&dL_dmean2D[global_id].y, dL_dG * dG_ddely * ddely_dy);

JerryPW commented 7 months ago

@MobiusLqm oh sorry, that variable is only used to keep the gradient w.r.t. uv, the content itself is still zero. The values are stored in this variable https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L265 but with this code it is very hard to extract them. You need to compute the correct offset from https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L158-L165 then get it from the variable geomBuffer on this line https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/diff_gaussian_rasterization/__init__.py#L86

How exactly does it "retain the gradient with respect to uv"? I was under the impression that means2D is ultimately passed to this section of the code. However, it appears that it isn't utilized there at all. Could you guide me on how to further trace its usage or impact?

I have the same question with you. Have you figured it out?

MobiusLqm commented 7 months ago

@MobiusLqm oh sorry, that variable is only used to keep the gradient w.r.t. uv, the content itself is still zero. The values are stored in this variable https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L265 but with this code it is very hard to extract them. You need to compute the correct offset from https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L158-L165 then get it from the variable geomBuffer on this line https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/diff_gaussian_rasterization/__init__.py#L86

How exactly does it "retain the gradient with respect to uv"? I was under the impression that means2D is ultimately passed to this section of the code. However, it appears that it isn't utilized there at all. Could you guide me on how to further trace its usage or impact?

I have the same question with you. Have you figured it out?

sorry. I didn't figure it out. this issue is not related with my current project .

Erhushenshou commented 2 weeks ago

@MobiusLqm oh sorry, that variable is only used to keep the gradient w.r.t. uv, the content itself is still zero. The values are stored in this variable https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L265 but with this code it is very hard to extract them. You need to compute the correct offset from https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L158-L165 then get it from the variable geomBuffer on this line https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/diff_gaussian_rasterization/__init__.py#L86

How exactly does it "retain the gradient with respect to uv"? I was under the impression that means2D is ultimately passed to this section of the code. However, it appears that it isn't utilized there at all. Could you guide me on how to further trace its usage or impact?

I have the same problem. means2D is never used again after passing into the render function.

FanYaning commented 2 weeks ago

@MobiusLqm oh sorry, that variable is only used to keep the gradient w.r.t. uv, the content itself is still zero. The values are stored in this variable https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L265 but with this code it is very hard to extract them. You need to compute the correct offset from https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/rasterizer_impl.cu#L158-L165 then get it from the variable geomBuffer on this line https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/diff_gaussian_rasterization/__init__.py#L86

How exactly does it "retain the gradient with respect to uv"? I was under the impression that means2D is ultimately passed to this section of the code. However, it appears that it isn't utilized there at all. Could you guide me on how to further trace its usage or impact?

I have the same problem. means2D is never used again after passing into the render function.

means2D is not used in the forward function, but _RasterizeGaussians 's backward return grad values as follows:

        grads = (
            grad_means3D,
            grad_means2D,
            grad_sh,
            grad_colors_precomp,
            grad_opacities,
            grad_scales,
            grad_rotations,
            grad_cov3Ds_precomp,
            None,
        ) 

so means2D.grad=grad_means2D.

You can try this example:

import torch

class Exp(torch.autograd.Function):
    @staticmethod
    def forward(ctx, i, j):
        result = i.exp()
        ctx.save_for_backward(result)
        return result

    @staticmethod
    def backward(ctx, grad_output):
        result, = ctx.saved_tensors 
        return (grad_output * result, grad_output * result * 2)

if __name__ == "__main__":
    x = torch.ones(1, requires_grad = True)
    y = torch.ones(1, requires_grad = True)
    y.retain_grad()

    output = Exp.apply(x, y)
    print(output) # tensor([2.7183]

    output.backward((torch.ones(1)))
    print(y.grad)