mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Clean up fill shader a bit
This commit is contained in:
parent
746b52cda5
commit
1707958e0f
4 changed files with 41 additions and 26 deletions
|
@ -13,7 +13,7 @@ from manimlib.utils.shaders import get_shader_code_from_file
|
||||||
from manimlib.utils.shaders import get_shader_program
|
from manimlib.utils.shaders import get_shader_program
|
||||||
from manimlib.utils.shaders import image_path_to_texture
|
from manimlib.utils.shaders import image_path_to_texture
|
||||||
from manimlib.utils.shaders import get_texture_id
|
from manimlib.utils.shaders import get_texture_id
|
||||||
from manimlib.utils.shaders import get_fill_palette
|
from manimlib.utils.shaders import get_fill_canvas
|
||||||
from manimlib.utils.shaders import release_texture
|
from manimlib.utils.shaders import release_texture
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -275,7 +275,7 @@ class FillShaderWrapper(ShaderWrapper):
|
||||||
**kwargs
|
**kwargs
|
||||||
):
|
):
|
||||||
super().__init__(ctx, *args, **kwargs)
|
super().__init__(ctx, *args, **kwargs)
|
||||||
self.texture_fbo, self.texture_vao = get_fill_palette(self.ctx)
|
self.fill_canvas = get_fill_canvas(self.ctx)
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
vao = self.vao
|
vao = self.vao
|
||||||
|
@ -287,9 +287,10 @@ class FillShaderWrapper(ShaderWrapper):
|
||||||
return
|
return
|
||||||
|
|
||||||
original_fbo = self.ctx.fbo
|
original_fbo = self.ctx.fbo
|
||||||
|
texture_fbo, texture_vao, null_rgb = self.fill_canvas
|
||||||
|
|
||||||
self.texture_fbo.clear()
|
texture_fbo.clear(*null_rgb, 0.0)
|
||||||
self.texture_fbo.use()
|
texture_fbo.use()
|
||||||
gl.glBlendFuncSeparate(
|
gl.glBlendFuncSeparate(
|
||||||
# Ordinary blending for colors
|
# Ordinary blending for colors
|
||||||
gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA,
|
gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA,
|
||||||
|
@ -306,6 +307,6 @@ class FillShaderWrapper(ShaderWrapper):
|
||||||
gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
|
gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||||
gl.glBlendEquation(gl.GL_FUNC_ADD)
|
gl.glBlendEquation(gl.GL_FUNC_ADD)
|
||||||
|
|
||||||
self.texture_vao.render(moderngl.TRIANGLE_STRIP)
|
texture_vao.render(moderngl.TRIANGLE_STRIP)
|
||||||
|
|
||||||
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
|
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
|
|
@ -32,7 +32,7 @@ void main() {
|
||||||
cap is to make sure the original fragment color can be recovered even after
|
cap is to make sure the original fragment color can be recovered even after
|
||||||
blending with an (alpha = 1) color.
|
blending with an (alpha = 1) color.
|
||||||
*/
|
*/
|
||||||
float a = 0.98 * frag_color.a;
|
float a = 0.99 * frag_color.a;
|
||||||
if(winding && orientation < 0) a = -a / (1 - a);
|
if(winding && orientation < 0) a = -a / (1 - a);
|
||||||
frag_color.a = a;
|
frag_color.a = a;
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,6 @@ void emit_triangle(vec3 points[3], vec4 v_color[3]){
|
||||||
uv_coords = SIMPLE_QUADRATIC[i];
|
uv_coords = SIMPLE_QUADRATIC[i];
|
||||||
color = v_color[i];
|
color = v_color[i];
|
||||||
point = points[i];
|
point = points[i];
|
||||||
// Pure black will be used to discard fragments later
|
|
||||||
if(winding && color.rgb == vec3(0.0)) color.rgb += vec3(3.0 / 256);
|
|
||||||
gl_Position = get_gl_Position(points[i]);
|
gl_Position = get_gl_Position(points[i]);
|
||||||
EmitVertex();
|
EmitVertex();
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,10 +103,16 @@ def get_colormap_code(rgb_list: Sequence[float]) -> str:
|
||||||
|
|
||||||
|
|
||||||
@lru_cache()
|
@lru_cache()
|
||||||
def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
def get_fill_canvas(ctx) -> Tuple[Framebuffer, VertexArray, Tuple[float, float, float]]:
|
||||||
"""
|
"""
|
||||||
Creates a texture, loaded into a frame buffer, and a vao
|
Because VMobjects with fill are rendered in a funny way, using
|
||||||
which can display that texture as a simple quad onto a screen.
|
alpha blending to effectively compute the winding number around
|
||||||
|
each pixel, they need to be rendered to a separate texture, which
|
||||||
|
is then composited onto the ordinary frame buffer.
|
||||||
|
|
||||||
|
This returns a texture, loaded into a frame buffer, and a vao
|
||||||
|
which can display that texture as a simple quad onto a screen,
|
||||||
|
along with the rgb value which is meant to be discarded.
|
||||||
"""
|
"""
|
||||||
cam_config = get_customization()['camera_resolutions']
|
cam_config = get_customization()['camera_resolutions']
|
||||||
res_name = cam_config['default_resolution']
|
res_name = cam_config['default_resolution']
|
||||||
|
@ -118,6 +124,12 @@ def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
||||||
depth_buffer = ctx.depth_renderbuffer(size) # TODO, currently not used
|
depth_buffer = ctx.depth_renderbuffer(size) # TODO, currently not used
|
||||||
texture_fbo = ctx.framebuffer(texture, depth_buffer)
|
texture_fbo = ctx.framebuffer(texture, depth_buffer)
|
||||||
|
|
||||||
|
# We'll paint onto a canvas with initially negative rgbs, and
|
||||||
|
# discard any pixels remaining close to this value. This is
|
||||||
|
# because alphas are effectively being used for another purpose,
|
||||||
|
# and
|
||||||
|
null_rgb = (-0.25, -0.25, -0.25)
|
||||||
|
|
||||||
simple_program = ctx.program(
|
simple_program = ctx.program(
|
||||||
vertex_shader='''
|
vertex_shader='''
|
||||||
#version 330
|
#version 330
|
||||||
|
@ -136,27 +148,30 @@ def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
||||||
uniform sampler2D Texture;
|
uniform sampler2D Texture;
|
||||||
uniform float v_nudge;
|
uniform float v_nudge;
|
||||||
uniform float h_nudge;
|
uniform float h_nudge;
|
||||||
|
uniform vec3 null_rgb;
|
||||||
|
|
||||||
in vec2 v_textcoord;
|
in vec2 v_textcoord;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
const float MIN_RGB = 3.0 / 256;
|
const float MIN_DIST_TO_NULL = 0.2;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Apply poor man's anti-aliasing
|
// Apply poor man's anti-aliasing
|
||||||
vec2 tc0 = v_textcoord + vec2(0, 0);
|
vec2 nudges[4] = vec2[4](
|
||||||
vec2 tc1 = v_textcoord + vec2(0, h_nudge);
|
vec2(0, 0),
|
||||||
vec2 tc2 = v_textcoord + vec2(v_nudge, 0);
|
vec2(0, h_nudge),
|
||||||
vec2 tc3 = v_textcoord + vec2(v_nudge, h_nudge);
|
vec2(v_nudge, 0),
|
||||||
color =
|
vec2(v_nudge, h_nudge)
|
||||||
0.25 * texture(Texture, tc0) +
|
);
|
||||||
0.25 * texture(Texture, tc1) +
|
color = vec4(0.0);
|
||||||
0.25 * texture(Texture, tc2) +
|
for(int i = 0; i < 4; i++){
|
||||||
0.25 * texture(Texture, tc3);
|
color += 0.25 * texture(Texture, v_textcoord + nudges[i]);
|
||||||
if(abs(color.r) < MIN_RGB && abs(color.g) < MIN_RGB && abs(color.b) < MIN_RGB)
|
}
|
||||||
discard;
|
if(distance(color.rgb, null_rgb) < MIN_DIST_TO_NULL) discard;
|
||||||
// Counteract scaling in quadratic_bezier_frag
|
|
||||||
color = color / 0.98;
|
// Un-blend from the null value
|
||||||
|
color.rgb -= (1 - color.a) * null_rgb;
|
||||||
|
|
||||||
//TODO, set gl_FragDepth;
|
//TODO, set gl_FragDepth;
|
||||||
}
|
}
|
||||||
''',
|
''',
|
||||||
|
@ -166,6 +181,7 @@ def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
||||||
# Half pixel width/height
|
# Half pixel width/height
|
||||||
simple_program['h_nudge'].value = 0.5 / size[0]
|
simple_program['h_nudge'].value = 0.5 / size[0]
|
||||||
simple_program['v_nudge'].value = 0.5 / size[1]
|
simple_program['v_nudge'].value = 0.5 / size[1]
|
||||||
|
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]])
|
||||||
fill_texture_vao = ctx.simple_vertex_array(
|
fill_texture_vao = ctx.simple_vertex_array(
|
||||||
|
@ -173,4 +189,4 @@ def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
||||||
ctx.buffer(verts.astype('f4').tobytes()),
|
ctx.buffer(verts.astype('f4').tobytes()),
|
||||||
'texcoord',
|
'texcoord',
|
||||||
)
|
)
|
||||||
return (texture_fbo, fill_texture_vao)
|
return (texture_fbo, fill_texture_vao, null_rgb)
|
||||||
|
|
Loading…
Add table
Reference in a new issue