mirror of
https://github.com/3b1b/manim.git
synced 2025-07-28 20:43:56 +08:00
Have FillShaders all share the same texture used for intermediary rendering
This commit is contained in:
@ -7,14 +7,14 @@ import re
|
|||||||
import OpenGL.GL as gl
|
import OpenGL.GL as gl
|
||||||
import moderngl
|
import moderngl
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from functools import lru_cache
|
||||||
|
|
||||||
from manimlib.constants import DEFAULT_PIXEL_HEIGHT
|
|
||||||
from manimlib.constants import DEFAULT_PIXEL_WIDTH
|
|
||||||
from manimlib.utils.iterables import resize_array
|
from manimlib.utils.iterables import resize_array
|
||||||
from manimlib.utils.shaders import get_shader_code_from_file
|
from manimlib.utils.shaders import get_shader_code_from_file
|
||||||
from manimlib.utils.shaders import get_shader_program
|
from manimlib.utils.shaders import get_shader_program
|
||||||
from manimlib.utils.shaders import image_path_to_texture
|
from manimlib.utils.shaders import image_path_to_texture
|
||||||
from manimlib.utils.shaders import get_texture_id
|
from manimlib.utils.shaders import get_texture_id
|
||||||
|
from manimlib.utils.shaders import get_intermediary_palette
|
||||||
from manimlib.utils.shaders import release_texture
|
from manimlib.utils.shaders import release_texture
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
@ -274,68 +274,6 @@ class FillShaderWrapper(ShaderWrapper):
|
|||||||
):
|
):
|
||||||
super().__init__(ctx, *args, **kwargs)
|
super().__init__(ctx, *args, **kwargs)
|
||||||
|
|
||||||
size = (2 * DEFAULT_PIXEL_WIDTH, 2 * DEFAULT_PIXEL_HEIGHT)
|
|
||||||
texture = ctx.texture(
|
|
||||||
size=size,
|
|
||||||
components=4,
|
|
||||||
# Important to make sure floating point (not fixed point) is
|
|
||||||
# used so that alpha values are not clipped
|
|
||||||
dtype='f2',
|
|
||||||
)
|
|
||||||
depth_buffer = ctx.depth_renderbuffer(size) # TODO, currently not used
|
|
||||||
self.texture_fbo = ctx.framebuffer(texture, depth_buffer)
|
|
||||||
|
|
||||||
simple_program = ctx.program(
|
|
||||||
vertex_shader='''
|
|
||||||
#version 330
|
|
||||||
|
|
||||||
in vec2 texcoord;
|
|
||||||
out vec2 v_textcoord;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4((2.0 * texcoord - 1.0), 0.0, 1.0);
|
|
||||||
v_textcoord = texcoord;
|
|
||||||
}
|
|
||||||
''',
|
|
||||||
fragment_shader='''
|
|
||||||
#version 330
|
|
||||||
|
|
||||||
uniform sampler2D Texture;
|
|
||||||
uniform sampler2D DepthTexture;
|
|
||||||
uniform float v_nudge;
|
|
||||||
uniform float h_nudge;
|
|
||||||
|
|
||||||
in vec2 v_textcoord;
|
|
||||||
out vec4 frag_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
// Apply poor man's anti-aliasing
|
|
||||||
vec2 tc0 = v_textcoord + vec2(v_nudge, h_nudge);
|
|
||||||
vec2 tc1 = v_textcoord + vec2(v_nudge, -h_nudge);
|
|
||||||
vec2 tc2 = v_textcoord + vec2(-v_nudge, h_nudge);
|
|
||||||
vec2 tc3 = v_textcoord + vec2(-v_nudge, -h_nudge);
|
|
||||||
frag_color =
|
|
||||||
0.25 * abs(texture(Texture, tc0)) +
|
|
||||||
0.25 * abs(texture(Texture, tc1)) +
|
|
||||||
0.25 * abs(texture(Texture, tc2)) +
|
|
||||||
0.25 * abs(texture(Texture, tc3));
|
|
||||||
if(frag_color.a == 0) discard;
|
|
||||||
//TODO, set gl_FragDepth;
|
|
||||||
}
|
|
||||||
''',
|
|
||||||
)
|
|
||||||
|
|
||||||
simple_program['Texture'].value = get_texture_id(texture)
|
|
||||||
# Quarter pixel width/height
|
|
||||||
simple_program['h_nudge'].value = 0.25 / size[0]
|
|
||||||
simple_program['v_nudge'].value = 0.25 / size[1]
|
|
||||||
|
|
||||||
verts = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
|
|
||||||
self.fill_texture_vao = ctx.simple_vertex_array(
|
|
||||||
simple_program,
|
|
||||||
ctx.buffer(verts.astype('f4').tobytes()),
|
|
||||||
'texcoord',
|
|
||||||
)
|
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
vao = self.vao
|
vao = self.vao
|
||||||
@ -345,11 +283,14 @@ class FillShaderWrapper(ShaderWrapper):
|
|||||||
if not winding:
|
if not winding:
|
||||||
vao.render(moderngl.TRIANGLES)
|
vao.render(moderngl.TRIANGLES)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
texture_fbo, texture_vao = get_intermediary_palette(self.ctx)
|
||||||
|
|
||||||
original_fbo = self.ctx.fbo
|
original_fbo = self.ctx.fbo
|
||||||
self.texture_fbo.clear()
|
texture_fbo.clear()
|
||||||
self.texture_fbo.use()
|
texture_fbo.use()
|
||||||
self.ctx.blend_func = (moderngl.ONE, moderngl.ONE)
|
self.ctx.blend_func = (moderngl.ONE, moderngl.ONE)
|
||||||
vao.render(self.render_primitive)
|
vao.render(self.render_primitive)
|
||||||
self.ctx.blend_func = moderngl.DEFAULT_BLENDING
|
self.ctx.blend_func = moderngl.DEFAULT_BLENDING
|
||||||
original_fbo.use()
|
original_fbo.use()
|
||||||
self.fill_texture_vao.render(moderngl.TRIANGLE_STRIP)
|
texture_vao.render(moderngl.TRIANGLE_STRIP)
|
||||||
|
@ -6,13 +6,17 @@ from functools import lru_cache
|
|||||||
import moderngl
|
import moderngl
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
from manimlib.constants import DEFAULT_PIXEL_HEIGHT
|
||||||
|
from manimlib.constants import DEFAULT_PIXEL_WIDTH
|
||||||
from manimlib.utils.directories import get_shader_dir
|
from manimlib.utils.directories import get_shader_dir
|
||||||
from manimlib.utils.file_ops import find_file
|
from manimlib.utils.file_ops import find_file
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Sequence, Optional
|
from typing import Sequence, Optional, Tuple
|
||||||
|
from moderngl.vertex_array import VertexArray
|
||||||
|
from moderngl.framebuffer import Framebuffer
|
||||||
|
|
||||||
|
|
||||||
ID_TO_TEXTURE: dict[int, moderngl.Texture] = dict()
|
ID_TO_TEXTURE: dict[int, moderngl.Texture] = dict()
|
||||||
@ -93,3 +97,75 @@ def get_colormap_code(rgb_list: Sequence[float]) -> str:
|
|||||||
for rgb in rgb_list
|
for rgb in rgb_list
|
||||||
)
|
)
|
||||||
return f"vec3[{len(rgb_list)}]({data})"
|
return f"vec3[{len(rgb_list)}]({data})"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache()
|
||||||
|
def get_intermediary_palette(ctx) -> Tuple[Framebuffer, VertexArray]:
|
||||||
|
"""
|
||||||
|
Creates a texture, loaded into a frame buffer, and a vao
|
||||||
|
which can display that texture as a simple quad onto a screen.
|
||||||
|
"""
|
||||||
|
size = (2 * DEFAULT_PIXEL_WIDTH, 2 * DEFAULT_PIXEL_HEIGHT)
|
||||||
|
texture = ctx.texture(
|
||||||
|
size=size,
|
||||||
|
components=4,
|
||||||
|
# Important to make sure floating point (not fixed point) is
|
||||||
|
# used so that alpha values are not clipped
|
||||||
|
dtype='f2',
|
||||||
|
)
|
||||||
|
depth_buffer = ctx.depth_renderbuffer(size) # TODO, currently not used
|
||||||
|
texture_fbo = ctx.framebuffer(texture, depth_buffer)
|
||||||
|
|
||||||
|
simple_program = ctx.program(
|
||||||
|
vertex_shader='''
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec2 texcoord;
|
||||||
|
out vec2 v_textcoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4((2.0 * texcoord - 1.0), 0.0, 1.0);
|
||||||
|
v_textcoord = texcoord;
|
||||||
|
}
|
||||||
|
''',
|
||||||
|
fragment_shader='''
|
||||||
|
#version 330
|
||||||
|
|
||||||
|
uniform sampler2D Texture;
|
||||||
|
uniform sampler2D DepthTexture;
|
||||||
|
uniform float v_nudge;
|
||||||
|
uniform float h_nudge;
|
||||||
|
|
||||||
|
in vec2 v_textcoord;
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Apply poor man's anti-aliasing
|
||||||
|
vec2 tc0 = v_textcoord + vec2(v_nudge, h_nudge);
|
||||||
|
vec2 tc1 = v_textcoord + vec2(v_nudge, -h_nudge);
|
||||||
|
vec2 tc2 = v_textcoord + vec2(-v_nudge, h_nudge);
|
||||||
|
vec2 tc3 = v_textcoord + vec2(-v_nudge, -h_nudge);
|
||||||
|
frag_color =
|
||||||
|
0.25 * abs(texture(Texture, tc0)) +
|
||||||
|
0.25 * abs(texture(Texture, tc1)) +
|
||||||
|
0.25 * abs(texture(Texture, tc2)) +
|
||||||
|
0.25 * abs(texture(Texture, tc3));
|
||||||
|
if(frag_color.a == 0) discard;
|
||||||
|
//TODO, set gl_FragDepth;
|
||||||
|
}
|
||||||
|
''',
|
||||||
|
)
|
||||||
|
|
||||||
|
simple_program['Texture'].value = get_texture_id(texture)
|
||||||
|
# Quarter pixel width/height
|
||||||
|
simple_program['h_nudge'].value = 0.25 / size[0]
|
||||||
|
simple_program['v_nudge'].value = 0.25 / size[1]
|
||||||
|
|
||||||
|
verts = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
|
||||||
|
fill_texture_vao = ctx.simple_vertex_array(
|
||||||
|
simple_program,
|
||||||
|
ctx.buffer(verts.astype('f4').tobytes()),
|
||||||
|
'texcoord',
|
||||||
|
)
|
||||||
|
return (texture_fbo, fill_texture_vao)
|
||||||
|
Reference in New Issue
Block a user