mirror of
https://github.com/3b1b/manim.git
synced 2025-09-01 00:48:45 +00:00
Fix winding fill blending
(Using somewhat of a hack)
This commit is contained in:
parent
3f5df432ce
commit
37f0bf8c11
4 changed files with 29 additions and 12 deletions
|
@ -289,10 +289,9 @@ class FillShaderWrapper(ShaderWrapper):
|
||||||
|
|
||||||
texture_fbo.clear()
|
texture_fbo.clear()
|
||||||
texture_fbo.use()
|
texture_fbo.use()
|
||||||
self.ctx.blend_func = (moderngl.ONE, moderngl.ONE)
|
vao.render()
|
||||||
vao.render(self.render_primitive)
|
|
||||||
|
|
||||||
self.ctx.blend_func = (moderngl.ONE, moderngl.ONE_MINUS_SRC_ALPHA)
|
|
||||||
original_fbo.use()
|
original_fbo.use()
|
||||||
|
self.ctx.blend_func = (moderngl.ONE, moderngl.ONE_MINUS_SRC_ALPHA)
|
||||||
texture_vao.render(moderngl.TRIANGLE_STRIP)
|
texture_vao.render(moderngl.TRIANGLE_STRIP)
|
||||||
self.ctx.blend_func = moderngl.DEFAULT_BLENDING
|
self.ctx.blend_func = (moderngl.DEFAULT_BLENDING)
|
||||||
|
|
|
@ -13,12 +13,26 @@ void main() {
|
||||||
if (color.a == 0) discard;
|
if (color.a == 0) discard;
|
||||||
frag_color = color;
|
frag_color = color;
|
||||||
|
|
||||||
// Pre-multiply alphas
|
/*
|
||||||
if(winding) frag_color *= frag_color.a;
|
We want negatively oriented triangles to be canceled with positively
|
||||||
|
oriented ones. The easiest way to do this is to give them negative alpha,
|
||||||
|
and change the blend function to just add them. However, this messes with
|
||||||
|
usual blending, so instead the following line is meant to let this canceling
|
||||||
|
work even for the normal blending equation:
|
||||||
|
|
||||||
// Give a sign based on orientation so that
|
(1 - alpha) * dst + alpha * src
|
||||||
// additive blending cancels as needed
|
|
||||||
if(winding && orientation < 0) frag_color *= -1;
|
We want the effect of blending with a positively oriented triangle followed
|
||||||
|
by a negatively oriented one to return to whatever the original frag value
|
||||||
|
was. You can work out this will work if the alpha for negative orientations
|
||||||
|
is changed to -alpha / (1 - alpha). This has a singularity at alpha = 1,
|
||||||
|
so we cap it at a value very close to 1. Effectively, the purpose of this
|
||||||
|
cap is to make sure the original fragment color can be recovered even after
|
||||||
|
blending with an alpha = 1 color.
|
||||||
|
*/
|
||||||
|
float a = 0.999 * frag_color.a;
|
||||||
|
if(winding && orientation < 0) a = -a / (1 - a);
|
||||||
|
frag_color.a = a;
|
||||||
|
|
||||||
if (bool(fill_all)) return;
|
if (bool(fill_all)) return;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,11 @@ void emit_triangle(vec3 points[3], vec4 v_color[3]){
|
||||||
for(int i = 0; i < 3; i++){
|
for(int i = 0; i < 3; i++){
|
||||||
uv_coords = SIMPLE_QUADRATIC[i];
|
uv_coords = SIMPLE_QUADRATIC[i];
|
||||||
color = finalize_color(v_color[i], points[i], unit_normal);
|
color = finalize_color(v_color[i], points[i], unit_normal);
|
||||||
|
if(winding){
|
||||||
|
// Pure black will be used to discard fragments later
|
||||||
|
if(color.rgb == vec3(0.0)) color.rgb += vec3(0.01);
|
||||||
|
// color.a = sqrt(color.a);
|
||||||
|
}
|
||||||
gl_Position = get_gl_Position(points[i]);
|
gl_Position = get_gl_Position(points[i]);
|
||||||
EmitVertex();
|
EmitVertex();
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
||||||
size = (2 * DEFAULT_PIXEL_WIDTH, 2 * DEFAULT_PIXEL_HEIGHT)
|
size = (2 * DEFAULT_PIXEL_WIDTH, 2 * DEFAULT_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='f4')
|
||||||
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)
|
||||||
|
|
||||||
|
@ -147,8 +147,7 @@ def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
||||||
0.25 * texture(Texture, tc1) +
|
0.25 * texture(Texture, tc1) +
|
||||||
0.25 * texture(Texture, tc2) +
|
0.25 * texture(Texture, tc2) +
|
||||||
0.25 * texture(Texture, tc3);
|
0.25 * texture(Texture, tc3);
|
||||||
if(frag_color.a == 0) discard;
|
if(distance(frag_color.rgb, vec3(0.0)) < 1e-3) discard;
|
||||||
frag_color = abs(frag_color);
|
|
||||||
//TODO, set gl_FragDepth;
|
//TODO, set gl_FragDepth;
|
||||||
}
|
}
|
||||||
''',
|
''',
|
||||||
|
|
Loading…
Add table
Reference in a new issue