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.use()
|
||||
self.ctx.blend_func = (moderngl.ONE, moderngl.ONE)
|
||||
vao.render(self.render_primitive)
|
||||
vao.render()
|
||||
|
||||
self.ctx.blend_func = (moderngl.ONE, moderngl.ONE_MINUS_SRC_ALPHA)
|
||||
original_fbo.use()
|
||||
self.ctx.blend_func = (moderngl.ONE, moderngl.ONE_MINUS_SRC_ALPHA)
|
||||
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;
|
||||
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
|
||||
// additive blending cancels as needed
|
||||
if(winding && orientation < 0) frag_color *= -1;
|
||||
(1 - alpha) * dst + alpha * src
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -36,6 +36,11 @@ void emit_triangle(vec3 points[3], vec4 v_color[3]){
|
|||
for(int i = 0; i < 3; i++){
|
||||
uv_coords = SIMPLE_QUADRATIC[i];
|
||||
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]);
|
||||
EmitVertex();
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ def get_fill_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
|||
size = (2 * DEFAULT_PIXEL_WIDTH, 2 * DEFAULT_PIXEL_HEIGHT)
|
||||
# Important to make sure dtype is floating point (not fixed point)
|
||||
# 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
|
||||
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, tc2) +
|
||||
0.25 * texture(Texture, tc3);
|
||||
if(frag_color.a == 0) discard;
|
||||
frag_color = abs(frag_color);
|
||||
if(distance(frag_color.rgb, vec3(0.0)) < 1e-3) discard;
|
||||
//TODO, set gl_FragDepth;
|
||||
}
|
||||
''',
|
||||
|
|
Loading…
Add table
Reference in a new issue