Push depth test decision to the mobject level, as opposed to the camera

This commit is contained in:
Grant Sanderson 2020-06-14 17:41:47 -07:00
parent 145c6a7e78
commit 222b6d1220
5 changed files with 41 additions and 14 deletions

View file

@ -149,7 +149,6 @@ class Camera(object):
"n_channels": 4, "n_channels": 4,
"pixel_array_dtype": 'uint8', "pixel_array_dtype": 'uint8',
"light_source_position": [-10, 10, 10], "light_source_position": [-10, 10, 10],
"apply_depth_test": False,
# Measured in pixel widths, used for vector graphics # Measured in pixel widths, used for vector graphics
"anti_alias_width": 1.5, "anti_alias_width": 1.5,
# Although vector graphics handle antialiasing fine # Although vector graphics handle antialiasing fine
@ -185,9 +184,6 @@ class Camera(object):
fbo_msaa = self.get_fbo(ctx, self.samples) fbo_msaa = self.get_fbo(ctx, self.samples)
fbo_msaa.use() fbo_msaa.use()
if self.apply_depth_test:
ctx.enable(moderngl.BLEND | moderngl.DEPTH_TEST)
else:
ctx.enable(moderngl.BLEND) ctx.enable(moderngl.BLEND)
ctx.blend_func = ( ctx.blend_func = (
moderngl.SRC_ALPHA, moderngl.ONE_MINUS_SRC_ALPHA, moderngl.SRC_ALPHA, moderngl.ONE_MINUS_SRC_ALPHA,
@ -329,20 +325,24 @@ class Camera(object):
for mob in mobjects for mob in mobjects
]) ])
batches = batch_by_property(shader_infos, shader_info_to_id) batches = batch_by_property(shader_infos, shader_info_to_id)
# TODO, if apply_depth_test, don't worry about order.
# Maybe rewrite batch_by_property to have a "preserve_order" argument
for info_group, sid in batches: for info_group, sid in batches:
data = np.hstack([info["data"] for info in info_group]) data = np.hstack([info["data"] for info in info_group])
shader = self.get_shader(info_group[0]) shader = self.get_shader(info_group[0])
render_primative = int(info_group[0]["render_primative"]) render_primative = int(info_group[0]["render_primative"])
self.render(shader, data, render_primative) depth_test = info_group[0]["depth_test"]
self.render(shader, data, render_primative, depth_test)
def render(self, shader, data, render_primative): def render(self, shader, data, render_primative, depth_test=False):
if data is None or len(data) == 0: if data is None or len(data) == 0:
return return
if shader is None: if shader is None:
return return
if depth_test:
self.ctx.enable(moderngl.DEPTH_TEST)
else:
self.ctx.disable(moderngl.DEPTH_TEST)
vbo = self.ctx.buffer(data.tobytes()) vbo = self.ctx.buffer(data.tobytes())
vao = self.ctx.simple_vertex_array(shader, vbo, *data.dtype.names) vao = self.ctx.simple_vertex_array(shader, vbo, *data.dtype.names)
vao.render(render_primative) vao.render(render_primative)
@ -418,6 +418,5 @@ class Camera(object):
class ThreeDCamera(Camera): class ThreeDCamera(Camera):
CONFIG = { CONFIG = {
"apply_depth_test": True,
"samples": 8, "samples": 8,
} }

View file

@ -50,6 +50,7 @@ class Mobject(Container):
"frag_shader_file": "", "frag_shader_file": "",
"render_primative": moderngl.TRIANGLE_STRIP, "render_primative": moderngl.TRIANGLE_STRIP,
"texture_paths": None, "texture_paths": None,
"depth_test": False,
# If true, the mobject will not get rotated according to camera position # If true, the mobject will not get rotated according to camera position
"is_fixed_in_frame": False, "is_fixed_in_frame": False,
# Must match in attributes of vert shader # Must match in attributes of vert shader
@ -470,6 +471,20 @@ class Mobject(Container):
submob.unfix_from_frame(family) submob.unfix_from_frame(family)
return self return self
def apply_depth_test(self, family=True):
self.depth_test = True
if family:
for submob in self.submobjects:
submob.apply_depth_test(family)
return self
def deactivate_depth_test(self, family=True):
self.depth_test = False
if family:
for submob in self.submobjects:
submob.deactivate_depth_test(family)
return self
# Positioning methods # Positioning methods
def center(self): def center(self):
@ -1203,7 +1218,6 @@ class Mobject(Container):
def get_shader_info_list(self): def get_shader_info_list(self):
if self.shader_data_is_locked: if self.shader_data_is_locked:
return self.saved_shader_info_list return self.saved_shader_info_list
shader_infos = it.chain( shader_infos = it.chain(
[self.get_shader_info()], [self.get_shader_info()],
*[ *[
@ -1228,8 +1242,9 @@ class Mobject(Container):
vert_file=self.vert_shader_file, vert_file=self.vert_shader_file,
geom_file=self.geom_shader_file, geom_file=self.geom_shader_file,
frag_file=self.frag_shader_file, frag_file=self.frag_shader_file,
render_primative=self.render_primative,
texture_paths=self.texture_paths, texture_paths=self.texture_paths,
depth_test=self.depth_test,
render_primative=self.render_primative,
) )
def get_shader_uniforms(self): def get_shader_uniforms(self):

View file

@ -26,6 +26,7 @@ class ParametricSurface(Mobject):
# can crop up in the shaders. # can crop up in the shaders.
"epsilon": 1e-5, "epsilon": 1e-5,
"render_primative": moderngl.TRIANGLES, "render_primative": moderngl.TRIANGLES,
"depth_test": True,
"vert_shader_file": "surface_vert.glsl", "vert_shader_file": "surface_vert.glsl",
"frag_shader_file": "surface_frag.glsl", "frag_shader_file": "surface_frag.glsl",
"shader_dtype": [ "shader_dtype": [

View file

@ -522,6 +522,7 @@ class VMobject(Mobject):
def flip(self, *args, **kwargs): def flip(self, *args, **kwargs):
super().flip(*args, **kwargs) super().flip(*args, **kwargs)
self.refresh_unit_normal()
self.refresh_triangulation() self.refresh_triangulation()
# #
@ -674,6 +675,9 @@ class VMobject(Mobject):
self.unit_normal_locked = False self.unit_normal_locked = False
return self return self
def refresh_unit_normal(self):
self.lock_unit_normal()
# Alignment # Alignment
def align_points(self, vmobject): def align_points(self, vmobject):
self.align_rgbas(vmobject) self.align_rgbas(vmobject)
@ -848,6 +852,7 @@ class VMobject(Mobject):
vert_file=self.stroke_vert_shader_file, vert_file=self.stroke_vert_shader_file,
geom_file=self.stroke_geom_shader_file, geom_file=self.stroke_geom_shader_file,
frag_file=self.stroke_frag_shader_file, frag_file=self.stroke_frag_shader_file,
depth_test=self.depth_test,
render_primative=self.render_primative, render_primative=self.render_primative,
) )
fill_info = get_shader_info( fill_info = get_shader_info(
@ -855,6 +860,7 @@ class VMobject(Mobject):
vert_file=self.fill_vert_shader_file, vert_file=self.fill_vert_shader_file,
geom_file=self.fill_geom_shader_file, geom_file=self.fill_geom_shader_file,
frag_file=self.fill_frag_shader_file, frag_file=self.fill_frag_shader_file,
depth_test=self.depth_test,
render_primative=self.render_primative, render_primative=self.render_primative,
) )

View file

@ -28,6 +28,8 @@ SHADER_INFO_KEYS = [
# A dictionary mapping names (as they show up in) # A dictionary mapping names (as they show up in)
# the shader to filepaths for textures. # the shader to filepaths for textures.
"texture_paths", "texture_paths",
# Whether or not to apply depth test
"depth_test",
# E.g. moderngl.TRIANGLE_STRIP # E.g. moderngl.TRIANGLE_STRIP
"render_primative", "render_primative",
] ]
@ -41,8 +43,9 @@ def get_shader_info(data=None,
vert_file=None, vert_file=None,
geom_file=None, geom_file=None,
frag_file=None, frag_file=None,
render_primative=moderngl.TRIANGLE_STRIP,
texture_paths=None, texture_paths=None,
depth_test=False,
render_primative=moderngl.TRIANGLE_STRIP,
): ):
return { return {
key: value key: value
@ -51,8 +54,11 @@ def get_shader_info(data=None,
[ [
data, data,
uniforms, uniforms,
vert_file, geom_file, frag_file, vert_file,
geom_file,
frag_file,
texture_paths or {}, texture_paths or {},
depth_test,
str(render_primative) str(render_primative)
] ]
) )