Remove use of dv_points and du_points, pass unit normals to shader instead

This commit is contained in:
Grant Sanderson 2023-01-30 20:49:32 -08:00
parent c469c6b009
commit 55da5d5d03
2 changed files with 38 additions and 27 deletions

View file

@ -12,6 +12,7 @@ from manimlib.utils.images import get_full_raster_image_path
from manimlib.utils.iterables import listify from manimlib.utils.iterables import listify
from manimlib.utils.iterables import resize_with_interpolation from manimlib.utils.iterables import resize_with_interpolation
from manimlib.utils.space_ops import normalize_along_axis from manimlib.utils.space_ops import normalize_along_axis
from manimlib.utils.space_ops import cross
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -27,11 +28,9 @@ class Surface(Mobject):
shader_folder: str = "surface" shader_folder: str = "surface"
shader_dtype: np.dtype = np.dtype([ shader_dtype: np.dtype = np.dtype([
('point', np.float32, (3,)), ('point', np.float32, (3,)),
('du_point', np.float32, (3,)), ('normal', np.float32, (3,)),
('dv_point', np.float32, (3,)),
('rgba', np.float32, (4,)), ('rgba', np.float32, (4,)),
]) ])
pointlike_data_keys = ['point', 'du_point', 'dv_point']
def __init__( def __init__(
self, self,
@ -96,8 +95,14 @@ class Surface(Mobject):
for grid in (uv_grid, uv_plus_du, uv_plus_dv) for grid in (uv_grid, uv_plus_du, uv_plus_dv)
] ]
self.set_points(points) self.set_points(points)
self.data["du_point"][:] = du_points self.data["normal"] = normalize_along_axis(cross(
self.data["dv_point"][:] = dv_points du_points - points,
dv_points - points,
), 1)
def apply_points_function(self, *args, **kwargs):
super().apply_points_function(*args, **kwargs)
self.get_unit_normals()
def compute_triangle_indices(self): def compute_triangle_indices(self):
# TODO, if there is an event which changes # TODO, if there is an event which changes
@ -120,16 +125,27 @@ class Surface(Mobject):
def get_triangle_indices(self) -> np.ndarray: def get_triangle_indices(self) -> np.ndarray:
return self.triangle_indices return self.triangle_indices
def get_surface_points_and_nudged_points(self) -> tuple[Vect3Array, Vect3Array, Vect3Array]:
return (self.data['point'], self.data['du_point'], self.data['dv_point'])
def get_unit_normals(self) -> Vect3Array: def get_unit_normals(self) -> Vect3Array:
s_points, du_points, dv_points = self.get_surface_points_and_nudged_points() nu, nv = self.resolution
normals = np.cross( indices = np.arange(nu * nv)
(du_points - s_points) / self.epsilon,
(dv_points - s_points) / self.epsilon, left = indices - 1
right = indices + 1
up = indices - nv
down = indices + nv
left[0] = indices[0]
right[-1] = indices[-1]
up[:nv] = indices[:nv]
down[-nv:] = indices[-nv:]
points = self.get_points()
crosses = cross(
points[right] - points[left],
points[up] - points[down],
) )
return normalize_along_axis(normals, 1) self.data["normal"] = normalize_along_axis(crosses, 1)
return self.data["normal"]
@Mobject.affects_data @Mobject.affects_data
def pointwise_become_partial( def pointwise_become_partial(
@ -147,9 +163,8 @@ class Surface(Mobject):
return self return self
nu, nv = smobject.resolution nu, nv = smobject.resolution
for key in ['point', 'du_point', 'dv_point']: self.data['point'][:] = self.get_partial_points_array(
self.data[key][:] = self.get_partial_points_array( self.data['point'], a, b,
self.data[key], a, b,
(nu, nv, 3), (nu, nv, 3),
axis=axis axis=axis
) )
@ -263,8 +278,7 @@ class TexturedSurface(Surface):
shader_folder: str = "textured_surface" shader_folder: str = "textured_surface"
shader_dtype: Sequence[Tuple[str, type, Tuple[int]]] = [ shader_dtype: Sequence[Tuple[str, type, Tuple[int]]] = [
('point', np.float32, (3,)), ('point', np.float32, (3,)),
('du_point', np.float32, (3,)), ('normal', np.float32, (3,)),
('dv_point', np.float32, (3,)),
('im_coords', np.float32, (2,)), ('im_coords', np.float32, (2,)),
('opacity', np.float32, (1,)), ('opacity', np.float32, (1,)),
] ]
@ -306,8 +320,7 @@ class TexturedSurface(Surface):
surf = self.uv_surface surf = self.uv_surface
nu, nv = surf.resolution nu, nv = surf.resolution
self.resize_points(surf.get_num_points()) self.resize_points(surf.get_num_points())
for key in ['point', 'du_point', 'dv_point']: self.data['point'][:] = surf.data['point']
self.data[key][:] = surf.data[key]
self.data['opacity'][:, 0] = surf.data["rgba"][:, 3] self.data['opacity'][:, 0] = surf.data["rgba"][:, 3]
self.data["im_coords"] = np.array([ self.data["im_coords"] = np.array([
[u, v] [u, v]

View file

@ -3,8 +3,7 @@
uniform vec4 clip_plane; uniform vec4 clip_plane;
in vec3 point; in vec3 point;
in vec3 du_point; in vec3 normal;
in vec3 dv_point;
in vec4 rgba; in vec4 rgba;
out vec4 v_color; out vec4 v_color;
@ -15,8 +14,7 @@ out vec4 v_color;
void main(){ void main(){
emit_gl_Position(point); emit_gl_Position(point);
vec3 normal = get_unit_normal(point, du_point, dv_point); v_color = finalize_color(rgba, point, normalize(normal));
v_color = finalize_color(rgba, point, normal);
if(clip_plane.xyz != vec3(0.0, 0.0, 0.0)){ if(clip_plane.xyz != vec3(0.0, 0.0, 0.0)){
gl_ClipDistance[0] = dot(vec4(point, 1.0), clip_plane); gl_ClipDistance[0] = dot(vec4(point, 1.0), clip_plane);