Make anti_alias_width a Mobject uniform, rather than a camera attribute

This commit is contained in:
Grant Sanderson
2022-12-28 18:52:05 -08:00
parent 1180932026
commit 8fc243e398
6 changed files with 27 additions and 18 deletions

View File

@ -189,8 +189,6 @@ class Camera(object):
n_channels: int = 4,
pixel_array_dtype: type = np.uint8,
light_source_position: Vect3 = np.array([-10, 10, 10]),
# Measured in pixel widths, used for vector graphics
anti_alias_width: float = 1.5,
# Although vector graphics handle antialiasing fine
# without multisampling, for 3d scenes one might want
# to set samples to be greater than 0.
@ -205,7 +203,6 @@ class Camera(object):
self.n_channels = n_channels
self.pixel_array_dtype = pixel_array_dtype
self.light_source_position = light_source_position
self.anti_alias_width = anti_alias_width
self.samples = samples
self.rgb_max_val: float = np.iinfo(self.pixel_array_dtype).max
@ -475,11 +472,6 @@ class Camera(object):
def refresh_perspective_uniforms(self) -> None:
frame = self.frame
pw, ph = self.get_pixel_shape()
fw, fh = frame.get_shape()
# TODO, this should probably be a mobject uniform, with
# the camera taking care of the conversion factor
anti_alias_width = self.anti_alias_width / (ph / fh)
# Orient light
rotation = frame.get_inverse_camera_rotation_matrix()
offset = frame.get_center()
@ -490,7 +482,7 @@ class Camera(object):
self.perspective_uniforms = {
"frame_shape": frame.get_shape(),
"anti_alias_width": anti_alias_width,
"pixel_shape": self.get_pixel_shape(),
"camera_offset": tuple(offset),
"camera_rotation": tuple(np.array(rotation).T.flatten()),
"camera_position": tuple(cam_pos),
@ -529,5 +521,5 @@ class Camera(object):
# Mostly just defined so old scenes don't break
class ThreeDCamera(Camera):
def __init__(self, samples: int = 4, anti_alias_width: float = 0, **kwargs):
super().__init__(samples=samples, anti_alias_width=anti_alias_width, **kwargs)
def __init__(self, samples: int = 4, **kwargs):
super().__init__(samples=samples, **kwargs)

View File

@ -37,10 +37,12 @@ class DotCloud(PMobject):
opacity: float = 1.0,
radius: float = DEFAULT_DOT_RADIUS,
glow_factor: float = 0.0,
anti_alias_width: float = 1.0,
**kwargs
):
self.radius = radius
self.glow_factor = glow_factor
self.anti_alias_width = anti_alias_width
super().__init__(
color=color,
@ -59,6 +61,7 @@ class DotCloud(PMobject):
def init_uniforms(self) -> None:
super().init_uniforms()
self.uniforms["glow_factor"] = self.glow_factor
self.uniforms["anti_alias_width"] = self.anti_alias_width
def to_grid(
self,

View File

@ -85,6 +85,8 @@ class VMobject(Mobject):
# Could also be "bevel", "miter", "round"
joint_type: str = "auto",
flat_stroke: bool = False,
# Measured in pixel widths
anti_alias_width: float = 1.0,
**kwargs
):
self.fill_color = fill_color or color or DEFAULT_FILL_COLOR
@ -97,6 +99,7 @@ class VMobject(Mobject):
self.long_lines = long_lines
self.joint_type = joint_type
self.flat_stroke = flat_stroke
self.anti_alias_width = anti_alias_width
self.needs_new_triangulation = True
self.triangulation = np.zeros(0, dtype='i4')
@ -116,6 +119,10 @@ class VMobject(Mobject):
"orientation": np.ones((1, 1)),
})
def init_uniforms(self):
super().init_uniforms()
self.uniforms["anti_alias_width"] = self.anti_alias_width
# These are here just to make type checkers happy
def get_family(self, recurse: bool = True) -> list[VMobject]:
return super().get_family(recurse)
@ -1053,11 +1060,13 @@ class VMobject(Mobject):
self.fill_shader_wrapper = ShaderWrapper(
vert_data=self.fill_data,
vert_indices=np.zeros(0, dtype='i4'),
uniforms=self.uniforms,
shader_folder=self.fill_shader_folder,
render_primitive=self.render_primitive,
)
self.stroke_shader_wrapper = ShaderWrapper(
vert_data=self.stroke_data,
uniforms=self.get_stroke_uniforms(),
shader_folder=self.stroke_shader_folder,
render_primitive=self.render_primitive,
)
@ -1100,11 +1109,14 @@ class VMobject(Mobject):
stroke_shader_wrappers.append(ssw)
# Combine data lists
return list(filter(lambda sw: len(sw.vert_data) > 0, [
result = [
self.meta_back_stroke_shader_wrapper.read_in(*back_stroke_shader_wrappers),
self.meta_fill_shader_wrapper.read_in(*fill_shader_wrappers),
self.meta_stroke_shader_wrapper.read_in(*stroke_shader_wrappers),
]))
]
for i, sw in enumerate(result):
sw.depth_test = self.depth_test
return list(filter(lambda sw: len(sw.vert_data) > 0, result))
def get_stroke_uniforms(self) -> dict[str, float]:
result = dict(super().get_shader_uniforms())

View File

@ -1,5 +1,5 @@
uniform vec2 frame_shape;
uniform float anti_alias_width;
uniform vec2 pixel_shape;
uniform vec3 camera_offset;
uniform mat3 camera_rotation;
uniform float is_fixed_in_frame;

View File

@ -7,6 +7,7 @@ uniform float anti_alias_width;
// Needed for get_gl_Position
uniform vec2 frame_shape;
uniform vec2 pixel_shape;
uniform float focal_distance;
uniform float is_fixed_in_frame;
// Needed for finalize_color
@ -79,7 +80,7 @@ void emit_pentagon(vec3[3] points, vec3 normal){
vec3 p2_perp = cross(t12, normal);
bool fill_inside = orientation > 0.0;
float aaw = anti_alias_width;
float aaw = anti_alias_width * frame_shape.y / pixel_shape.y;
vec3 corners[5];
if(bezier_degree == 1.0){
// For straight lines, buff out in both directions
@ -111,7 +112,7 @@ void emit_pentagon(vec3[3] points, vec3 normal){
mat4 xyz_to_uv = get_xyz_to_uv(p0, p1, normal);
uv_b2 = (xyz_to_uv * vec4(p2, 1)).xy;
uv_anti_alias_width = anti_alias_width / length(p1 - p0);
uv_anti_alias_width = aaw / length(p1 - p0);
for(int i = 0; i < 5; i++){
vec3 corner = corners[i];

View File

@ -5,6 +5,7 @@ layout (triangle_strip, max_vertices = 5) out;
// Needed for get_gl_Position
uniform vec2 frame_shape;
uniform vec2 pixel_shape;
uniform float focal_distance;
uniform float is_fixed_in_frame;
@ -128,7 +129,7 @@ int get_corners(vec2 controls[3], int degree, float stroke_widths[3], out vec2 c
// aaw is the added width given around the polygon for antialiasing.
// In case the normal is faced away from (0, 0, 1), the vector to the
// camera, this is scaled up.
float aaw = anti_alias_width;
float aaw = anti_alias_width * frame_shape.y / pixel_shape.y;
float buff0 = 0.5 * stroke_widths[0] + aaw;
float buff2 = 0.5 * stroke_widths[2] + aaw;
float aaw0 = (1 - has_prev) * aaw;
@ -248,7 +249,7 @@ void main() {
// Find uv conversion matrix
mat3 xy_to_uv = get_xy_to_uv(flat_controls[0], flat_controls[1]);
float scale_factor = length(flat_controls[1] - flat_controls[0]);
uv_anti_alias_width = anti_alias_width / scale_factor;
uv_anti_alias_width = anti_alias_width * frame_shape.y / pixel_shape.y / scale_factor;
uv_b2 = (xy_to_uv * vec3(flat_controls[2], 1.0)).xy;
// Emit each corner