mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Add depth shader to handle winding fill depth test.
This commit is contained in:
parent
4cb16dfc0b
commit
3b5d63d2fa
5 changed files with 100 additions and 16 deletions
|
@ -277,7 +277,7 @@ class VShaderWrapper(ShaderWrapper):
|
||||||
f"{vtype}_{name}": get_shader_code_from_file(
|
f"{vtype}_{name}": get_shader_code_from_file(
|
||||||
os.path.join(f"quadratic_bezier_{vtype}", f"{name}.glsl")
|
os.path.join(f"quadratic_bezier_{vtype}", f"{name}.glsl")
|
||||||
)
|
)
|
||||||
for vtype in ["stroke", "fill"]
|
for vtype in ["stroke", "fill", "depth"]
|
||||||
for name in ["vert", "geom", "frag"]
|
for name in ["vert", "geom", "frag"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,7 +294,13 @@ class VShaderWrapper(ShaderWrapper):
|
||||||
geometry_shader=self.program_code["fill_geom"],
|
geometry_shader=self.program_code["fill_geom"],
|
||||||
fragment_shader=self.program_code["fill_frag"],
|
fragment_shader=self.program_code["fill_frag"],
|
||||||
)
|
)
|
||||||
self.programs = [self.stroke_program, self.fill_program]
|
self.fill_depth_program = get_shader_program(
|
||||||
|
self.ctx,
|
||||||
|
vertex_shader=self.program_code["depth_vert"],
|
||||||
|
geometry_shader=self.program_code["depth_geom"],
|
||||||
|
fragment_shader=self.program_code["depth_frag"],
|
||||||
|
)
|
||||||
|
self.programs = [self.stroke_program, self.fill_program, self.fill_depth_program]
|
||||||
|
|
||||||
# Full vert format looks like this (total of 4x23 = 92 bytes):
|
# Full vert format looks like this (total of 4x23 = 92 bytes):
|
||||||
# point 3
|
# point 3
|
||||||
|
@ -314,6 +320,9 @@ class VShaderWrapper(ShaderWrapper):
|
||||||
self.fill_border_vert_format = '3f 20x 4f 4f 24x 1f'
|
self.fill_border_vert_format = '3f 20x 4f 4f 24x 1f'
|
||||||
self.fill_border_vert_attributes = ['point', 'joint_product', 'stroke_rgba', 'stroke_width']
|
self.fill_border_vert_attributes = ['point', 'joint_product', 'stroke_rgba', 'stroke_width']
|
||||||
|
|
||||||
|
self.fill_depth_vert_format = '3f 52x 3f 16x'
|
||||||
|
self.fill_depth_vert_attributes = ['point', 'base_point']
|
||||||
|
|
||||||
def init_vertex_objects(self):
|
def init_vertex_objects(self):
|
||||||
self.vbo = None
|
self.vbo = None
|
||||||
self.stroke_vao = None
|
self.stroke_vao = None
|
||||||
|
@ -337,7 +346,12 @@ class VShaderWrapper(ShaderWrapper):
|
||||||
content=[(self.vbo, self.fill_border_vert_format, *self.fill_border_vert_attributes)],
|
content=[(self.vbo, self.fill_border_vert_format, *self.fill_border_vert_attributes)],
|
||||||
mode=self.render_primitive,
|
mode=self.render_primitive,
|
||||||
)
|
)
|
||||||
self.vaos = [self.stroke_vao, self.fill_vao, self.fill_border_vao]
|
self.fill_depth_vao = self.ctx.vertex_array(
|
||||||
|
program=self.fill_depth_program,
|
||||||
|
content=[(self.vbo, self.fill_depth_vert_format, *self.fill_depth_vert_attributes)],
|
||||||
|
mode=self.render_primitive,
|
||||||
|
)
|
||||||
|
self.vaos = [self.stroke_vao, self.fill_vao, self.fill_border_vao, self.fill_depth_vao]
|
||||||
|
|
||||||
def set_backstroke(self, value: bool = True):
|
def set_backstroke(self, value: bool = True):
|
||||||
self.stroke_behind = value
|
self.stroke_behind = value
|
||||||
|
@ -366,7 +380,7 @@ class VShaderWrapper(ShaderWrapper):
|
||||||
return
|
return
|
||||||
|
|
||||||
original_fbo = self.ctx.fbo
|
original_fbo = self.ctx.fbo
|
||||||
texture_fbo, texture_vao = self.fill_canvas
|
texture_fbo, depth_texture_fbo, texture_vao = self.fill_canvas
|
||||||
|
|
||||||
texture_fbo.clear()
|
texture_fbo.clear()
|
||||||
texture_fbo.use()
|
texture_fbo.use()
|
||||||
|
@ -384,17 +398,27 @@ class VShaderWrapper(ShaderWrapper):
|
||||||
self.ctx.disable(moderngl.DEPTH_TEST)
|
self.ctx.disable(moderngl.DEPTH_TEST)
|
||||||
self.fill_vao.render()
|
self.fill_vao.render()
|
||||||
if apply_depth_test:
|
if apply_depth_test:
|
||||||
|
depth_texture_fbo.clear(1.0)
|
||||||
|
depth_texture_fbo.use()
|
||||||
|
gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE)
|
||||||
|
gl.glBlendEquation(gl.GL_MIN)
|
||||||
|
self.fill_depth_vao.render()
|
||||||
self.ctx.enable(moderngl.DEPTH_TEST)
|
self.ctx.enable(moderngl.DEPTH_TEST)
|
||||||
|
|
||||||
original_fbo.use()
|
# Border width is used for antialiasing. Take the maximum between these
|
||||||
gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
|
# two alphas, before compositing back to the rest of the scene
|
||||||
|
gl.glBlendFuncSeparate(
|
||||||
texture_vao.render()
|
gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA,
|
||||||
|
gl.GL_ONE, gl.GL_ZERO
|
||||||
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
|
)
|
||||||
|
gl.glBlendEquationSeparate(gl.GL_FUNC_ADD, gl.GL_MAX)
|
||||||
self.fill_border_vao.render()
|
self.fill_border_vao.render()
|
||||||
|
|
||||||
|
original_fbo.use()
|
||||||
|
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
gl.glBlendEquation(gl.GL_FUNC_ADD)
|
||||||
|
texture_vao.render()
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
if self.stroke_behind:
|
if self.stroke_behind:
|
||||||
self.render_stroke()
|
self.render_stroke()
|
||||||
|
|
7
manimlib/shaders/quadratic_bezier_depth/frag.glsl
Normal file
7
manimlib/shaders/quadratic_bezier_depth/frag.glsl
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
out float frag_depth;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_depth = gl_FragCoord.z;
|
||||||
|
}
|
39
manimlib/shaders/quadratic_bezier_depth/geom.glsl
Normal file
39
manimlib/shaders/quadratic_bezier_depth/geom.glsl
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
layout (triangles) in;
|
||||||
|
layout (triangle_strip, max_vertices = 6) out;
|
||||||
|
|
||||||
|
in vec3 verts[3];
|
||||||
|
in vec3 v_base_point[3];
|
||||||
|
in int v_vert_index[3];
|
||||||
|
|
||||||
|
out float depth;
|
||||||
|
|
||||||
|
#INSERT emit_gl_Position.glsl
|
||||||
|
|
||||||
|
|
||||||
|
void emit_triangle(vec3 points[3]){
|
||||||
|
for(int i = 0; i < 3; i++){
|
||||||
|
emit_gl_Position(points[i]);
|
||||||
|
// float z = gl_Position.z / gl_Position.w;
|
||||||
|
// depth = 0.5 * z + 0.5;
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
// Vector graphic shaders use TRIANGLE_STRIP, but only
|
||||||
|
// every other one needs to be rendered
|
||||||
|
if (v_vert_index[0] % 2 != 0) return;
|
||||||
|
|
||||||
|
// Curves are marked as ended when the handle after
|
||||||
|
// the first anchor is set equal to that anchor
|
||||||
|
if (verts[0] == verts[1]) return;
|
||||||
|
|
||||||
|
// Emit main triangle
|
||||||
|
emit_triangle(vec3[3](v_base_point[0], verts[0], verts[2]));
|
||||||
|
emit_triangle(vec3[3](verts[0], verts[1], verts[2]));
|
||||||
|
}
|
||||||
|
|
14
manimlib/shaders/quadratic_bezier_depth/vert.glsl
Normal file
14
manimlib/shaders/quadratic_bezier_depth/vert.glsl
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec3 point;
|
||||||
|
in vec3 base_point;
|
||||||
|
|
||||||
|
out vec3 verts;
|
||||||
|
out vec3 v_base_point;
|
||||||
|
out int v_vert_index;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
verts = point;
|
||||||
|
v_base_point = base_point;
|
||||||
|
v_vert_index = gl_VertexID;
|
||||||
|
}
|
|
@ -148,14 +148,14 @@ def get_fill_canvas(ctx: moderngl.Context) -> Tuple[Framebuffer, VertexArray]:
|
||||||
along with the rgb value which is meant to be discarded.
|
along with the rgb value which is meant to be discarded.
|
||||||
"""
|
"""
|
||||||
cam_config = get_configuration(parse_cli())['camera_config']
|
cam_config = get_configuration(parse_cli())['camera_config']
|
||||||
# Double the size so as to effectively to 4x multi-sample antialiasing
|
size = (cam_config['pixel_width'], cam_config['pixel_height'])
|
||||||
size = (2 * cam_config['pixel_width'], 2 * cam_config['pixel_height'])
|
|
||||||
|
|
||||||
# Important to make sure dtype is floating point (not fixed point)
|
# Important to make sure dtype is floating point (not fixed point)
|
||||||
# so that alpha values can be negative and are not clipped
|
# so that alpha values can be negative and are not clipped
|
||||||
texture = ctx.texture(size=size, components=4, dtype='f2')
|
texture = ctx.texture(size=size, components=4, dtype='f2')
|
||||||
depth_texture = ctx.depth_texture(size=size)
|
depth_texture = ctx.texture(size=size, components=1, dtype='f4')
|
||||||
texture_fbo = ctx.framebuffer(texture, depth_texture)
|
texture_fbo = ctx.framebuffer(texture)
|
||||||
|
depth_texture_fbo = ctx.framebuffer(depth_texture)
|
||||||
|
|
||||||
simple_program = ctx.program(
|
simple_program = ctx.program(
|
||||||
vertex_shader='''
|
vertex_shader='''
|
||||||
|
@ -200,4 +200,4 @@ def get_fill_canvas(ctx: moderngl.Context) -> Tuple[Framebuffer, VertexArray]:
|
||||||
'texcoord',
|
'texcoord',
|
||||||
mode=moderngl.TRIANGLE_STRIP
|
mode=moderngl.TRIANGLE_STRIP
|
||||||
)
|
)
|
||||||
return (texture_fbo, fill_texture_vao)
|
return (texture_fbo, depth_texture_fbo, fill_texture_vao)
|
||||||
|
|
Loading…
Add table
Reference in a new issue