Slight tweaks to how shader_info id is found and stored

This commit is contained in:
Grant Sanderson 2020-06-26 23:05:25 -07:00
parent 661b81ab17
commit 60e1c88eb4
4 changed files with 40 additions and 23 deletions

View file

@ -14,6 +14,7 @@ from manimlib.utils.bezier import interpolate
from manimlib.utils.iterables import batch_by_property from manimlib.utils.iterables import batch_by_property
from manimlib.utils.simple_functions import fdiv from manimlib.utils.simple_functions import fdiv
from manimlib.utils.shaders import shader_info_to_id 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.shaders import shader_info_to_program_code
from manimlib.utils.simple_functions import clip from manimlib.utils.simple_functions import clip
from manimlib.utils.space_ops import angle_of_vector from manimlib.utils.space_ops import angle_of_vector
@ -332,11 +333,6 @@ class Camera(object):
def capture(self, *mobjects, **kwargs): def capture(self, *mobjects, **kwargs):
self.refresh_perspective_uniforms() 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: for mobject in mobjects:
try: try:
info_list = self.static_mobjects_to_shader_info_list[id(mobject)] info_list = self.static_mobjects_to_shader_info_list[id(mobject)]
@ -354,7 +350,6 @@ class Camera(object):
shader = self.get_shader(shader_info) shader = self.get_shader(shader_info)
if shader is None: if shader is None:
return return
self.set_perspective_uniforms(shader)
if shader_info["depth_test"]: if shader_info["depth_test"]:
self.ctx.enable(moderngl.DEPTH_TEST) self.ctx.enable(moderngl.DEPTH_TEST)
@ -377,18 +372,22 @@ class Camera(object):
self.id_to_shader = {"": None} self.id_to_shader = {"": None}
def get_shader(self, shader_info): 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: if sid not in self.id_to_shader:
# Create shader program for the first time, then cache # Create shader program for the first time, then cache
# in the id_to_shader dictionary # in the id_to_shader dictionary
shader = self.ctx.program(**shader_info_to_program_code(shader_info)) self.id_to_shader[sid] = self.ctx.program(
for name, path in shader_info["texture_paths"].items(): **shader_info_to_program_code(shader_info)
tid = self.get_texture_id(path) )
shader[name].value = tid shader = self.id_to_shader[sid]
for name, value in shader_info["uniforms"].items(): # Set uniforms
shader[name].value = value self.set_perspective_uniforms(shader)
self.id_to_shader[sid] = shader for name, path in shader_info["texture_paths"].items():
return self.id_to_shader[sid] 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): def set_perspective_uniforms(self, shader):
for key, value in self.perspective_uniforms.items(): for key, value in self.perspective_uniforms.items():
@ -432,6 +431,7 @@ class Camera(object):
return self.path_to_texture_id[path] return self.path_to_texture_id[path]
# Mostly just defined so old scenes don't break
class ThreeDCamera(Camera): class ThreeDCamera(Camera):
CONFIG = { CONFIG = {
"samples": 8, "samples": 8,

View file

@ -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 angle_of_vector
from manimlib.utils.space_ops import get_norm from manimlib.utils.space_ops import get_norm
from manimlib.utils.space_ops import rotation_matrix_transpose 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 get_shader_info
from manimlib.utils.shaders import shader_info_to_id from manimlib.utils.shaders import shader_info_to_id
from manimlib.utils.shaders import is_valid_shader_info from manimlib.utils.shaders import is_valid_shader_info
@ -1244,6 +1245,7 @@ class Mobject(Container):
shader_info["raw_data"] = data.tobytes() shader_info["raw_data"] = data.tobytes()
shader_info["attributes"] = data.dtype.names shader_info["attributes"] = data.dtype.names
shader_info["uniforms"] = self.get_shader_uniforms() shader_info["uniforms"] = self.get_shader_uniforms()
shader_info["id"] = create_shader_info_id(shader_info)
return shader_info return shader_info
def get_shader_uniforms(self): def get_shader_uniforms(self):

View file

@ -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_norm
from manimlib.utils.space_ops import get_unit_normal from manimlib.utils.space_ops import get_unit_normal
from manimlib.utils.space_ops import z_to_vector 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 from manimlib.utils.shaders import get_shader_info
@ -868,8 +869,9 @@ class VMobject(Mobject):
stroke_info = dict(self.stroke_shader_info_template) stroke_info = dict(self.stroke_shader_info_template)
fill_info["uniforms"] = self.get_shader_uniforms() fill_info["uniforms"] = self.get_shader_uniforms()
stroke_info["uniforms"] = self.get_stroke_uniforms() stroke_info["uniforms"] = self.get_stroke_uniforms()
fill_info["depth_test"] = self.depth_test for info in fill_info, stroke_info:
stroke_info["depth_test"] = self.depth_test info["depth_test"] = self.depth_test
info["id"] = create_shader_info_id(info)
back_stroke_data = [] back_stroke_data = []
stroke_data = [] stroke_data = []

View file

@ -12,6 +12,15 @@ from manimlib.constants import SHADER_DIR
# to that shader # 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 = [ SHADER_INFO_KEYS = [
# A structred array caring all of the points/color/lighting/etc. information # A structred array caring all of the points/color/lighting/etc. information
# needed for the shader. # needed for the shader.
@ -60,8 +69,7 @@ def get_shader_info(raw_data=None,
"depth_test": depth_test, "depth_test": depth_test,
"render_primative": str(render_primative), "render_primative": str(render_primative),
} }
# # A unique id for a shader result["id"] = create_shader_info_id(result)
# result["id"] = "|".join([str(result[key]) for key in SHADER_KEYS_FOR_ID])
return result return result
@ -75,15 +83,20 @@ def is_valid_shader_info(shader_info):
def shader_info_to_id(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 # A unique id for a shader
return "|".join([str(shader_info[key]) for key in SHADER_KEYS_FOR_ID]) 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): def same_shader_type(info1, info2):
return all([ return info1["id"] == info2["id"]
info1[key] == info2[key]
for key in SHADER_KEYS_FOR_ID
])
def shader_info_to_program_code(shader_info): def shader_info_to_program_code(shader_info):