Reorganize VShaderWrapper.render_fill

This commit is contained in:
Grant Sanderson 2024-08-19 20:51:37 -05:00
parent b288d5301e
commit 7217c9fca5
2 changed files with 49 additions and 46 deletions

View file

@ -327,8 +327,19 @@ class VShaderWrapper(ShaderWrapper):
original_fbo = self.ctx.fbo
texture_fbo, depth_texture_fbo, texture_vao = self.fill_canvas
# First, draw the border for antialiasing
self.fill_border_vao.render()
# Render to a separate texture, due to strange alpha compositing
# for the blended winding calculation
texture_fbo.clear()
texture_fbo.use()
# Be sure not to apply depth test while rendering fill
# but set it back to where it was after
apply_depth_test = bool(gl.glGetBooleanv(gl.GL_DEPTH_TEST))
self.ctx.disable(moderngl.DEPTH_TEST)
gl.glBlendFuncSeparate(
# Ordinary blending for colors
gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA,
@ -337,10 +348,6 @@ class VShaderWrapper(ShaderWrapper):
gl.GL_ONE_MINUS_DST_ALPHA, gl.GL_ONE,
)
# Be sure not to apply depth test while rendering fill
# but set it back to where it was after
apply_depth_test = bool(gl.glGetBooleanv(gl.GL_DEPTH_TEST))
self.ctx.disable(moderngl.DEPTH_TEST)
self.fill_vao.render()
if apply_depth_test:
depth_texture_fbo.clear(1.0)
@ -350,20 +357,15 @@ class VShaderWrapper(ShaderWrapper):
self.fill_depth_vao.render()
self.ctx.enable(moderngl.DEPTH_TEST)
# Border width is used for antialiasing. Take the maximum between these
# two alphas, before compositing back to the rest of the scene
gl.glBlendFuncSeparate(
gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA,
gl.GL_ONE, gl.GL_ZERO
)
gl.glBlendEquationSeparate(gl.GL_FUNC_ADD, gl.GL_MAX)
self.fill_border_vao.render()
original_fbo.use()
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glBlendEquation(gl.GL_FUNC_ADD)
texture_vao.render()
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
gl.glBlendEquation(gl.GL_FUNC_ADD)
def render(self):
if self.stroke_behind:
self.render_stroke()

View file

@ -157,47 +157,48 @@ def get_fill_canvas(ctx: moderngl.Context) -> Tuple[Framebuffer, VertexArray]:
texture_fbo = ctx.framebuffer(texture)
depth_texture_fbo = ctx.framebuffer(depth_texture)
simple_vert = '''
#version 330
in vec2 texcoord;
out vec2 uv;
void main() {
gl_Position = vec4((2.0 * texcoord - 1.0), 0.0, 1.0);
uv = texcoord;
}
'''
alpha_adjust_frag = '''
#version 330
uniform sampler2D Texture;
uniform sampler2D DepthTexture;
in vec2 uv;
out vec4 color;
void main() {
color = texture(Texture, uv);
if(color.a == 0) discard;
// Counteract scaling in fill frag
color.a *= 1.06;
gl_FragDepth = texture(DepthTexture, uv)[0];
}
'''
simple_program = ctx.program(
vertex_shader='''
#version 330
in vec2 texcoord;
out vec2 uv;
void main() {
gl_Position = vec4((2.0 * texcoord - 1.0), 0.0, 1.0);
uv = texcoord;
}
''',
fragment_shader='''
#version 330
uniform sampler2D Texture;
uniform sampler2D DepthTexture;
in vec2 uv;
out vec4 color;
void main() {
color = texture(Texture, uv);
if(color.a == 0) discard;
// Counteract scaling in fill frag
color *= 1.06;
gl_FragDepth = texture(DepthTexture, uv)[0];
}
''',
vertex_shader=simple_vert,
fragment_shader=alpha_adjust_frag,
)
simple_program['Texture'].value = get_texture_id(texture)
simple_program['DepthTexture'].value = get_texture_id(depth_texture)
verts = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
simple_vbo = ctx.buffer(verts.astype('f4').tobytes())
fill_texture_vao = ctx.simple_vertex_array(
simple_program,
ctx.buffer(verts.astype('f4').tobytes()),
'texcoord',
simple_program, simple_vbo, 'texcoord',
mode=moderngl.TRIANGLE_STRIP
)
return (texture_fbo, depth_texture_fbo, fill_texture_vao)