Billboard.scaleByDistance does not scale linearly
- Dominant language
- JavaScript
- Stars
- 15.7k
- Forks
- 3.9k
- Avg merge
- 4d 6h
- Merged PRs (30d)
- 34
Description
Using the property Billboard.scaleByDistance I have seen a strange behaviour: the size of the billboard should change linearly with the distance to the camera between the near and far distances, but the size change does not seem to be linear.
This is implemented in the function czm_nearFarScalar at Shaders\Builtin\Functions\nearFarScalar.glsl. In this function the returned value is calculated as proportional to the square of the distance and then a pow(x, 0.2) is applied. I don't understand why this formula is this way.
Since the angular size of an object is proportional to the inverse of the distance, I think the formula should interpolate using the inverse distance instead the squared distance (probably this is why the current implementation needs the pow(x,0.2)).
I propose to use this implementation:
```
float czm_nearFarScalar(vec4 nearFarScalar, float cameraDistSq)
{
float valueAtMin = nearFarScalar.y;
float valueAtMax = nearFarScalar.w;
float nearDistInv = 1.0 / nearFarScalar.x;
float farDistInv = 1.0 / nearFarScalar.z;
float cameraDistInv = 1.0 / sqrt(cameraDistSq);
float t = (cameraDistInv - nearDistInv) / (farDistInv - nearDistInv);
t = clamp(t, 0.0, 1.0);
return mix(valueAtMin, valueAtMax, t);
}
```
I have tested this function in my application and I get much smoother results.
Contributor guide
Research direction
Start with Shaders\Builtin\Functions\nearFarScalar.glsl and inspect how czm_nearFarScalar is used for Billboard.scaleByDistance. Compare the current distance interpolation with the proposed inverse-distance interpolation and verify the intended linear behavior between near and far distances. Done means the billboard size changes as expected across that range without breaking the existing shader behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100