Fix Potential Division-by-Zero Issues #88
+33
−10
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary of Potential Division-by-Zero Fixes
This document explains the root causes of potential division-by-zero errors fixed in the
diff_gaussian_rasterization
library for improved usability. While the original code functions correctly under typical conditions, certain edge cases (e.g., Gaussians exactly at the camera center, projected Gaussians becoming degenerate) could lead to floating-point exceptions (FPEs) and crashes.1. View Direction Normalization (Forward & Backward)
computeColorFromSH
(Forward),dnormvdv
helper used inpreprocessCUDA
(Backward)(Gaussian Position - Camera Position)
. If a Gaussian's 3D position (pos
) is exactly identical to the camera position (campos
), this vector becomes the zero vector. Attempting to normalize it (dividing by its magnitude) results in division by zero.2. 2D Covariance Calculation (Forward & Backward)
computeCov2D
(Forward),computeCov2DCUDA
(Backward)1 / t.z
and1 / (t.z * t.z)
, wheret.z
is the Gaussian's depth in view space. If a Gaussian lies exactly on the camera plane (after view transformation), itst.z
will be zero, leading to division by zero.3. 2D Covariance Inversion (Forward)
preprocessCUDA
kernel (Forward)1 / determinant
. If the projected 2D Gaussian is degenerate (e.g., forms a line), its 2D covariance matrix becomes singular, and its determinant (det
) is zero, resulting in division by zero.4. 2D Covariance Inversion Gradient (Backward)
computeCov2DCUDA
kernel (Backward)dL_da
,dL_db
,dL_dc
), the formulas involve dividing by the squared determinant (denom * denom
). Similar to the forward pass, if the determinant is zero, this leads to division by zero.5. Quaternion Normalization Derivative (Backward)
computeCov3D
callingdnormvdv
helper (Backward)rot
). The helper functiondnormvdv
implicitly divides by the magnitude of the vector during gradient calculation. If the inputrotations
tensor contains a zero vector[0, 0, 0, 0]
, its magnitude is zero, causing division by zero when computing the gradient contribution from the (implicitly handled) normalization.These fixes primarily focus on usability by adding small epsilon checks before potentially problematic divisions, preventing unexpected crashes for users who might encounter these edge cases inadvertently during experimentation or training. This makes the rasterizer more robust to unusual inputs.