mirror of
https://github.com/3b1b/manim.git
synced 2025-09-01 00:48:45 +00:00
Remove "poor man's anti-aliasing" for Fill and instead render a small border width for fill
This commit is contained in:
parent
3a01eb31bd
commit
71ef39ea5b
2 changed files with 28 additions and 25 deletions
|
@ -63,6 +63,7 @@ class VMobject(Mobject):
|
||||||
('fill_rgba', np.float32, (4,)),
|
('fill_rgba', np.float32, (4,)),
|
||||||
('base_point', np.float32, (3,)),
|
('base_point', np.float32, (3,)),
|
||||||
('unit_normal', np.float32, (3,)),
|
('unit_normal', np.float32, (3,)),
|
||||||
|
('fill_border_width', np.float32, (1,)),
|
||||||
])
|
])
|
||||||
fill_data_names = ['point', 'fill_rgba', 'base_point', 'unit_normal']
|
fill_data_names = ['point', 'fill_rgba', 'base_point', 'unit_normal']
|
||||||
stroke_data_names = ['point', 'stroke_rgba', 'stroke_width', 'joint_product']
|
stroke_data_names = ['point', 'stroke_rgba', 'stroke_width', 'joint_product']
|
||||||
|
@ -92,6 +93,7 @@ class VMobject(Mobject):
|
||||||
use_simple_quadratic_approx: bool = False,
|
use_simple_quadratic_approx: bool = False,
|
||||||
# Measured in pixel widths
|
# Measured in pixel widths
|
||||||
anti_alias_width: float = 1.0,
|
anti_alias_width: float = 1.0,
|
||||||
|
fill_border_width: float = 0.5,
|
||||||
use_winding_fill: bool = True,
|
use_winding_fill: bool = True,
|
||||||
**kwargs
|
**kwargs
|
||||||
):
|
):
|
||||||
|
@ -107,6 +109,7 @@ class VMobject(Mobject):
|
||||||
self.flat_stroke = flat_stroke
|
self.flat_stroke = flat_stroke
|
||||||
self.use_simple_quadratic_approx = use_simple_quadratic_approx
|
self.use_simple_quadratic_approx = use_simple_quadratic_approx
|
||||||
self.anti_alias_width = anti_alias_width
|
self.anti_alias_width = anti_alias_width
|
||||||
|
self.fill_border_width = fill_border_width
|
||||||
self._use_winding_fill = use_winding_fill
|
self._use_winding_fill = use_winding_fill
|
||||||
|
|
||||||
self.needs_new_triangulation = True
|
self.needs_new_triangulation = True
|
||||||
|
@ -164,6 +167,7 @@ class VMobject(Mobject):
|
||||||
self.set_fill(
|
self.set_fill(
|
||||||
color=self.fill_color,
|
color=self.fill_color,
|
||||||
opacity=self.fill_opacity,
|
opacity=self.fill_opacity,
|
||||||
|
border_width=self.fill_border_width,
|
||||||
)
|
)
|
||||||
self.set_stroke(
|
self.set_stroke(
|
||||||
color=self.stroke_color,
|
color=self.stroke_color,
|
||||||
|
@ -195,9 +199,13 @@ class VMobject(Mobject):
|
||||||
self,
|
self,
|
||||||
color: ManimColor | Iterable[ManimColor] = None,
|
color: ManimColor | Iterable[ManimColor] = None,
|
||||||
opacity: float | Iterable[float] | None = None,
|
opacity: float | Iterable[float] | None = None,
|
||||||
|
border_width: float | None = None,
|
||||||
recurse: bool = True
|
recurse: bool = True
|
||||||
):
|
):
|
||||||
self.set_rgba_array_by_color(color, opacity, 'fill_rgba', recurse)
|
self.set_rgba_array_by_color(color, opacity, 'fill_rgba', recurse)
|
||||||
|
if border_width is not None:
|
||||||
|
for mob in self.get_family(recurse):
|
||||||
|
mob.data["fill_border_width"] = border_width
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def set_stroke(
|
def set_stroke(
|
||||||
|
@ -1258,11 +1266,15 @@ class VMobject(Mobject):
|
||||||
|
|
||||||
# Build up data lists
|
# Build up data lists
|
||||||
fill_datas = []
|
fill_datas = []
|
||||||
|
fill_border_datas = []
|
||||||
fill_indices = []
|
fill_indices = []
|
||||||
stroke_datas = []
|
stroke_datas = []
|
||||||
back_stroke_data = []
|
back_stroke_datas = []
|
||||||
for submob in family:
|
for submob in family:
|
||||||
if submob.has_fill():
|
submob.get_joint_products()
|
||||||
|
has_fill = submob.has_fill()
|
||||||
|
has_stroke = submob.has_stroke()
|
||||||
|
if has_fill:
|
||||||
data = submob.data[fill_names]
|
data = submob.data[fill_names]
|
||||||
data["base_point"][:] = data["point"][0]
|
data["base_point"][:] = data["point"][0]
|
||||||
fill_datas.append(data)
|
fill_datas.append(data)
|
||||||
|
@ -1271,12 +1283,16 @@ class VMobject(Mobject):
|
||||||
fill_datas.append(data[-1:])
|
fill_datas.append(data[-1:])
|
||||||
else:
|
else:
|
||||||
fill_indices.append(submob.get_triangulation())
|
fill_indices.append(submob.get_triangulation())
|
||||||
if submob.has_stroke():
|
# Add fill border
|
||||||
submob.get_joint_products()
|
if not has_stroke:
|
||||||
if submob.stroke_behind:
|
names = list(stroke_names)
|
||||||
lst = back_stroke_data
|
names[names.index('stroke_rgba')] = 'fill_rgba'
|
||||||
else:
|
names[names.index('stroke_width')] = 'fill_border_width'
|
||||||
lst = stroke_datas
|
border_stroke_data = submob.data[names]
|
||||||
|
fill_border_datas.append(border_stroke_data)
|
||||||
|
fill_border_datas.append(border_stroke_data[-1:])
|
||||||
|
if has_stroke:
|
||||||
|
lst = back_stroke_datas if submob.stroke_behind else stroke_datas
|
||||||
lst.append(submob.data[stroke_names])
|
lst.append(submob.data[stroke_names])
|
||||||
# Set data array to be one longer than number of points,
|
# Set data array to be one longer than number of points,
|
||||||
# with a dummy vertex added at the end. This is to ensure
|
# with a dummy vertex added at the end. This is to ensure
|
||||||
|
@ -1284,7 +1300,9 @@ class VMobject(Mobject):
|
||||||
lst.append(submob.data[stroke_names][-1:])
|
lst.append(submob.data[stroke_names][-1:])
|
||||||
|
|
||||||
shader_wrappers = [
|
shader_wrappers = [
|
||||||
self.back_stroke_shader_wrapper.read_in(back_stroke_data),
|
self.back_stroke_shader_wrapper.read_in(
|
||||||
|
[*back_stroke_datas, *fill_border_datas]
|
||||||
|
),
|
||||||
self.fill_shader_wrapper.read_in(fill_datas, fill_indices or None),
|
self.fill_shader_wrapper.read_in(fill_datas, fill_indices or None),
|
||||||
self.stroke_shader_wrapper.read_in(stroke_datas),
|
self.stroke_shader_wrapper.read_in(stroke_datas),
|
||||||
]
|
]
|
||||||
|
|
|
@ -150,8 +150,6 @@ def get_fill_canvas(ctx) -> Tuple[Framebuffer, VertexArray, Tuple[float, float,
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
uniform sampler2D Texture;
|
uniform sampler2D Texture;
|
||||||
uniform float v_nudge;
|
|
||||||
uniform float h_nudge;
|
|
||||||
uniform vec3 null_rgb;
|
uniform vec3 null_rgb;
|
||||||
|
|
||||||
in vec2 v_textcoord;
|
in vec2 v_textcoord;
|
||||||
|
@ -160,17 +158,7 @@ def get_fill_canvas(ctx) -> Tuple[Framebuffer, VertexArray, Tuple[float, float,
|
||||||
const float MIN_DIST_TO_NULL = 0.2;
|
const float MIN_DIST_TO_NULL = 0.2;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Apply poor man's anti-aliasing
|
color = texture(Texture, v_textcoord);
|
||||||
vec2 nudges[4] = vec2[4](
|
|
||||||
vec2(0, 0),
|
|
||||||
vec2(0, h_nudge),
|
|
||||||
vec2(v_nudge, 0),
|
|
||||||
vec2(v_nudge, h_nudge)
|
|
||||||
);
|
|
||||||
color = vec4(0.0);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
color += 0.25 * texture(Texture, v_textcoord + nudges[i]);
|
|
||||||
}
|
|
||||||
if(distance(color.rgb, null_rgb) < MIN_DIST_TO_NULL) discard;
|
if(distance(color.rgb, null_rgb) < MIN_DIST_TO_NULL) discard;
|
||||||
|
|
||||||
// Un-blend from the null value
|
// Un-blend from the null value
|
||||||
|
@ -182,9 +170,6 @@ def get_fill_canvas(ctx) -> Tuple[Framebuffer, VertexArray, Tuple[float, float,
|
||||||
)
|
)
|
||||||
|
|
||||||
simple_program['Texture'].value = get_texture_id(texture)
|
simple_program['Texture'].value = get_texture_id(texture)
|
||||||
# Half pixel width/height
|
|
||||||
simple_program['h_nudge'].value = 0.5 / size[0]
|
|
||||||
simple_program['v_nudge'].value = 0.5 / size[1]
|
|
||||||
simple_program['null_rgb'].value = null_rgb
|
simple_program['null_rgb'].value = null_rgb
|
||||||
|
|
||||||
verts = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
|
verts = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
|
||||||
|
|
Loading…
Add table
Reference in a new issue