diff --git a/manimlib/camera/camera.py b/manimlib/camera/camera.py index 875d3250..098e4e5a 100644 --- a/manimlib/camera/camera.py +++ b/manimlib/camera/camera.py @@ -14,6 +14,7 @@ from manimlib.utils.bezier import interpolate from manimlib.utils.iterables import batch_by_property from manimlib.utils.simple_functions import fdiv from manimlib.utils.shaders import shader_info_to_id +from manimlib.utils.shaders import shader_info_program_id from manimlib.utils.shaders import shader_info_to_program_code from manimlib.utils.simple_functions import clip from manimlib.utils.space_ops import angle_of_vector @@ -332,11 +333,6 @@ class Camera(object): def capture(self, *mobjects, **kwargs): self.refresh_perspective_uniforms() - - # shader_infos = it.chain(*[mob.get_shader_info_list() for mob in mobjects]) - # batches = batch_by_property(shader_infos, shader_info_to_id) - - # for shader_info_group, sid in batches: for mobject in mobjects: try: info_list = self.static_mobjects_to_shader_info_list[id(mobject)] @@ -354,7 +350,6 @@ class Camera(object): shader = self.get_shader(shader_info) if shader is None: return - self.set_perspective_uniforms(shader) if shader_info["depth_test"]: self.ctx.enable(moderngl.DEPTH_TEST) @@ -377,18 +372,22 @@ class Camera(object): self.id_to_shader = {"": None} def get_shader(self, shader_info): - sid = shader_info_to_id(shader_info) + sid = shader_info_program_id(shader_info) if sid not in self.id_to_shader: # Create shader program for the first time, then cache # in the id_to_shader dictionary - shader = self.ctx.program(**shader_info_to_program_code(shader_info)) - for name, path in shader_info["texture_paths"].items(): - tid = self.get_texture_id(path) - shader[name].value = tid - for name, value in shader_info["uniforms"].items(): - shader[name].value = value - self.id_to_shader[sid] = shader - return self.id_to_shader[sid] + self.id_to_shader[sid] = self.ctx.program( + **shader_info_to_program_code(shader_info) + ) + shader = self.id_to_shader[sid] + # Set uniforms + self.set_perspective_uniforms(shader) + for name, path in shader_info["texture_paths"].items(): + tid = self.get_texture_id(path) + shader[name].value = tid + for name, value in shader_info["uniforms"].items(): + shader[name].value = value + return shader def set_perspective_uniforms(self, shader): for key, value in self.perspective_uniforms.items(): @@ -432,6 +431,7 @@ class Camera(object): return self.path_to_texture_id[path] +# Mostly just defined so old scenes don't break class ThreeDCamera(Camera): CONFIG = { "samples": 8, diff --git a/manimlib/mobject/mobject.py b/manimlib/mobject/mobject.py index 228af584..3f45a6a0 100644 --- a/manimlib/mobject/mobject.py +++ b/manimlib/mobject/mobject.py @@ -22,6 +22,7 @@ from manimlib.utils.simple_functions import get_parameters from manimlib.utils.space_ops import angle_of_vector from manimlib.utils.space_ops import get_norm from manimlib.utils.space_ops import rotation_matrix_transpose +from manimlib.utils.shaders import create_shader_info_id from manimlib.utils.shaders import get_shader_info from manimlib.utils.shaders import shader_info_to_id from manimlib.utils.shaders import is_valid_shader_info @@ -1244,6 +1245,7 @@ class Mobject(Container): shader_info["raw_data"] = data.tobytes() shader_info["attributes"] = data.dtype.names shader_info["uniforms"] = self.get_shader_uniforms() + shader_info["id"] = create_shader_info_id(shader_info) return shader_info def get_shader_uniforms(self): diff --git a/manimlib/mobject/types/vectorized_mobject.py b/manimlib/mobject/types/vectorized_mobject.py index e61aeed3..35833b17 100644 --- a/manimlib/mobject/types/vectorized_mobject.py +++ b/manimlib/mobject/types/vectorized_mobject.py @@ -26,6 +26,7 @@ from manimlib.utils.space_ops import earclip_triangulation from manimlib.utils.space_ops import get_norm from manimlib.utils.space_ops import get_unit_normal from manimlib.utils.space_ops import z_to_vector +from manimlib.utils.shaders import create_shader_info_id from manimlib.utils.shaders import get_shader_info @@ -868,8 +869,9 @@ class VMobject(Mobject): stroke_info = dict(self.stroke_shader_info_template) fill_info["uniforms"] = self.get_shader_uniforms() stroke_info["uniforms"] = self.get_stroke_uniforms() - fill_info["depth_test"] = self.depth_test - stroke_info["depth_test"] = self.depth_test + for info in fill_info, stroke_info: + info["depth_test"] = self.depth_test + info["id"] = create_shader_info_id(info) back_stroke_data = [] stroke_data = [] diff --git a/manimlib/utils/shaders.py b/manimlib/utils/shaders.py index 299e7886..acc1ad1c 100644 --- a/manimlib/utils/shaders.py +++ b/manimlib/utils/shaders.py @@ -12,6 +12,15 @@ from manimlib.constants import SHADER_DIR # to that shader +# TODO, this should all be treated as an object +# This object a shader program instead of the vert, +# geom and frag file names, and it should cache those +# programs in the way currently handled by Camera +# It should replace the Camera.get_shader method with +# its own get_shader_program method, which will take +# in the camera's perspective_uniforms. + + SHADER_INFO_KEYS = [ # A structred array caring all of the points/color/lighting/etc. information # needed for the shader. @@ -60,8 +69,7 @@ def get_shader_info(raw_data=None, "depth_test": depth_test, "render_primative": str(render_primative), } - # # A unique id for a shader - # result["id"] = "|".join([str(result[key]) for key in SHADER_KEYS_FOR_ID]) + result["id"] = create_shader_info_id(result) return result @@ -75,15 +83,20 @@ def is_valid_shader_info(shader_info): def shader_info_to_id(shader_info): + return shader_info["id"] + + +def create_shader_info_id(shader_info): # A unique id for a shader return "|".join([str(shader_info[key]) for key in SHADER_KEYS_FOR_ID]) +def shader_info_program_id(shader_info): + return "|".join([str(shader_info[key]) for key in ["vert", "geom", "frag"]]) + + def same_shader_type(info1, info2): - return all([ - info1[key] == info2[key] - for key in SHADER_KEYS_FOR_ID - ]) + return info1["id"] == info2["id"] def shader_info_to_program_code(shader_info):