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 image_path_to_texture
|
||||
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 typing import TYPE_CHECKING
|
||||
|
@ -275,7 +275,7 @@ class FillShaderWrapper(ShaderWrapper):
|
|||
**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):
|
||||
vao = self.vao
|
||||
|
@ -287,9 +287,10 @@ class FillShaderWrapper(ShaderWrapper):
|
|||
return
|
||||
|
||||
original_fbo = self.ctx.fbo
|
||||
texture_fbo, texture_vao, null_rgb = self.fill_canvas
|
||||
|
||||
self.texture_fbo.clear()
|
||||
self.texture_fbo.use()
|
||||
texture_fbo.clear(*null_rgb, 0.0)
|
||||
texture_fbo.use()
|
||||
gl.glBlendFuncSeparate(
|
||||
# Ordinary blending for colors
|
||||
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.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)
|
||||
|
|
|
@ -32,7 +32,7 @@ void main() {
|
|||
cap is to make sure the original fragment color can be recovered even after
|
||||
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);
|
||||
frag_color.a = a;
|
||||
|
||||
|
|
|
@ -37,8 +37,6 @@ void emit_triangle(vec3 points[3], vec4 v_color[3]){
|
|||
uv_coords = SIMPLE_QUADRATIC[i];
|
||||
color = v_color[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]);
|
||||
EmitVertex();
|
||||
}
|
||||
|
|
|
@ -103,10 +103,16 @@ def get_colormap_code(rgb_list: Sequence[float]) -> str:
|
|||
|
||||
|
||||
@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
|
||||
which can display that texture as a simple quad onto a screen.
|
||||
Because VMobjects with fill are rendered in a funny way, using
|
||||
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']
|
||||
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
|
||||
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(
|
||||
vertex_shader='''
|
||||
#version 330
|
||||
|
@ -136,27 +148,30 @@ def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
|||
uniform sampler2D Texture;
|
||||
uniform float v_nudge;
|
||||
uniform float h_nudge;
|
||||
uniform vec3 null_rgb;
|
||||
|
||||
in vec2 v_textcoord;
|
||||
out vec4 color;
|
||||
|
||||
const float MIN_RGB = 3.0 / 256;
|
||||
const float MIN_DIST_TO_NULL = 0.2;
|
||||
|
||||
void main() {
|
||||
// Apply poor man's anti-aliasing
|
||||
vec2 tc0 = v_textcoord + vec2(0, 0);
|
||||
vec2 tc1 = v_textcoord + vec2(0, h_nudge);
|
||||
vec2 tc2 = v_textcoord + vec2(v_nudge, 0);
|
||||
vec2 tc3 = v_textcoord + vec2(v_nudge, h_nudge);
|
||||
color =
|
||||
0.25 * texture(Texture, tc0) +
|
||||
0.25 * texture(Texture, tc1) +
|
||||
0.25 * texture(Texture, tc2) +
|
||||
0.25 * texture(Texture, tc3);
|
||||
if(abs(color.r) < MIN_RGB && abs(color.g) < MIN_RGB && abs(color.b) < MIN_RGB)
|
||||
discard;
|
||||
// Counteract scaling in quadratic_bezier_frag
|
||||
color = color / 0.98;
|
||||
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;
|
||||
|
||||
// Un-blend from the null value
|
||||
color.rgb -= (1 - color.a) * null_rgb;
|
||||
|
||||
//TODO, set gl_FragDepth;
|
||||
}
|
||||
''',
|
||||
|
@ -166,6 +181,7 @@ def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
|||
# 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
|
||||
|
||||
verts = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
|
||||
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()),
|
||||
'texcoord',
|
||||
)
|
||||
return (texture_fbo, fill_texture_vao)
|
||||
return (texture_fbo, fill_texture_vao, null_rgb)
|
||||
|
|
Loading…
Add table
Reference in a new issue