Skip to content

Commit fffe69b

Browse files
committed
FIX: improved billboard sphere implementation
- Fixed typo and sphere intersection calculations - Cleaned up sphere function and tests - Better array handling and documentation
1 parent e831af2 commit fffe69b

File tree

3 files changed

+13
-11
lines changed

3 files changed

+13
-11
lines changed

fury/actor/curved.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ def sphere(
6767
Whether to create a smooth sphere or a faceted sphere.
6868
impostor : bool, optional
6969
Render spheres as billboard impostors instead of geometry when ``True``.
70-
Defaults to ``False``.
7170
7271
Returns
7372
-------
@@ -115,7 +114,7 @@ def sphere(
115114
obj.billboard_radii = radii_arr.copy()
116115
return obj
117116

118-
scales = radii
117+
scales = radii_arr
119118
directions = (1, 0, 0)
120119

121120
vertices, faces = fp.prim_sphere(phi=phi, theta=theta)
@@ -131,8 +130,6 @@ def sphere(
131130
smooth=smooth,
132131
enable_picking=enable_picking,
133132
)
134-
obj.billboard_radii = radii_arr.copy()
135-
obj.billboard_mode = "mesh"
136133
return obj
137134

138135

fury/tests/test_billboard.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,6 @@ def test_billboard_sphere(interactive: bool = False):
140140

141141
assert isinstance(mesh_spheres.material, MeshPhongMaterial)
142142
assert not isinstance(mesh_spheres.material, BillboardSphereMaterial)
143-
npt.assert_allclose(mesh_spheres.billboard_radii, radii)
144-
assert getattr(mesh_spheres, "billboard_mode", None) == "mesh"
145143

146144
impostor_spheres = actor.sphere(
147145
centers,

fury/wgsl/billboard_sphere_render.wgsl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,22 @@ fn fs_main(varyings: Varyings, @builtin(front_facing) is_front: bool) -> Fragmen
106106
let oc = ray_origin - center;
107107
let b = dot(ray_dir, oc);
108108
let c = dot(oc, oc) - radius * radius;
109-
let discriminant = b * b - c;
109+
var discriminant = b * b - c;
110110
if (discriminant < 0.0) {
111-
discard;
111+
if (discriminant > -1e-4) {
112+
discriminant = 0.0;
113+
} else {
114+
discard;
115+
}
112116
}
113117
let sqrt_disc = sqrt(discriminant);
114118
var t = -b - sqrt_disc;
115119
if (t < 0.0) {
116120
t = -b + sqrt_disc;
117121
}
122+
if (t < 0.0) {
123+
discard;
124+
}
118125
let world_pos = ray_origin + ray_dir * t;
119126
var world_normal = normalize(world_pos - center);
120127
if (!is_front) {
@@ -132,7 +139,7 @@ fn fs_main(varyings: Varyings, @builtin(front_facing) is_front: bool) -> Fragmen
132139
diffuse_color.a *= u_material.opacity * mask;
133140
do_alpha_test(diffuse_color.a);
134141

135-
let physical_albeido = diffuse_color.rgb;
142+
let physical_albedo = diffuse_color.rgb;
136143
let specular_strength = 1.0;
137144

138145
var reflected_light: ReflectedLight = ReflectedLight(
@@ -148,7 +155,7 @@ fn fs_main(varyings: Varyings, @builtin(front_facing) is_front: bool) -> Fragmen
148155
geometry.view_dir = view_dir;
149156

150157
var material: BlinnPhongMaterial;
151-
material.diffuse_color = physical_albeido;
158+
material.diffuse_color = physical_albedo;
152159
material.specular_color = srgb2physical(u_material.specular_color.rgb);
153160
material.specular_shininess = u_material.shininess;
154161
material.specular_strength = specular_strength;
@@ -170,7 +177,7 @@ fn fs_main(varyings: Varyings, @builtin(front_facing) is_front: bool) -> Fragmen
170177
if (all(physical_color == vec3<f32>(0.0))) {
171178
let fallback_light = normalize(vec3<f32>(0.3, 0.5, 0.8));
172179
let fallback_diffuse = max(dot(world_normal, fallback_light), 0.0);
173-
physical_color = physical_albeido * clamp(0.3 + 0.7 * fallback_diffuse, 0.0, 1.0);
180+
physical_color = physical_albedo * clamp(0.3 + 0.7 * fallback_diffuse, 0.0, 1.0);
174181
}
175182

176183
var out: FragmentOutput;

0 commit comments

Comments
 (0)