mirror of
https://github.com/3b1b/manim.git
synced 2025-09-19 04:41:56 +00:00
Add is_fixed_in_frame uniform which allows mobjects to not get rotated by the camera
This commit is contained in:
parent
5d34cee014
commit
ccefbc0dea
16 changed files with 73 additions and 33 deletions
|
@ -148,7 +148,7 @@ class Camera(object):
|
|||
"light_source_position": [-10, 10, 10],
|
||||
"apply_depth_test": False,
|
||||
# Measured in pixel widths, used for vector graphics
|
||||
"anti_alias_width": 1.5,
|
||||
"anti_alias_width": 3,
|
||||
# Although vector graphics handle antialiasing fine
|
||||
# without multisampling, for 3d scenes one might want
|
||||
# to set samples to be greater than 0.
|
||||
|
@ -362,14 +362,11 @@ class Camera(object):
|
|||
for name, path in info["texture_paths"].items():
|
||||
tid = self.get_texture_id(path)
|
||||
shader[name].value = tid
|
||||
for name, value in info["uniforms"].items():
|
||||
shader[name].value = value
|
||||
|
||||
self.set_shader_uniforms(shader)
|
||||
self.set_shader_uniforms(shader, sid)
|
||||
self.id_to_shader[sid] = shader
|
||||
return self.id_to_shader[sid]
|
||||
|
||||
def set_shader_uniforms(self, shader):
|
||||
def set_shader_uniforms(self, shader, sid):
|
||||
if shader is None:
|
||||
return
|
||||
|
||||
|
@ -378,13 +375,15 @@ class Camera(object):
|
|||
transform = self.frame.get_inverse_camera_position_matrix()
|
||||
light = self.light_source.get_location()
|
||||
transformed_light = np.dot(transform, [*light, 1])[:3]
|
||||
mapping = {
|
||||
'to_screen_space': tuple(transform.T.flatten()),
|
||||
'frame_shape': self.frame.get_shape(),
|
||||
'focal_distance': self.frame.get_focal_distance(),
|
||||
'anti_alias_width': anti_alias_width,
|
||||
'light_source_position': tuple(transformed_light),
|
||||
}
|
||||
mapping = dict()
|
||||
mapping['to_screen_space'] = tuple(transform.T.flatten())
|
||||
mapping['frame_shape'] = self.frame.get_shape()
|
||||
mapping['focal_distance'] = self.frame.get_focal_distance()
|
||||
mapping['anti_alias_width'] = anti_alias_width
|
||||
mapping['light_source_position'] = tuple(transformed_light)
|
||||
# Potentially overwrite with whatever came from the mobject
|
||||
mapping.update(shader_id_to_info(sid)["uniforms"])
|
||||
|
||||
for key, value in mapping.items():
|
||||
try:
|
||||
shader[key].value = value
|
||||
|
@ -393,7 +392,7 @@ class Camera(object):
|
|||
|
||||
def refresh_shader_uniforms(self):
|
||||
for sid, shader in self.id_to_shader.items():
|
||||
self.set_shader_uniforms(shader)
|
||||
self.set_shader_uniforms(shader, sid)
|
||||
|
||||
def init_textures(self):
|
||||
self.path_to_texture_id = {}
|
||||
|
|
|
@ -51,6 +51,8 @@ class Mobject(Container):
|
|||
"frag_shader_file": "",
|
||||
"render_primative": moderngl.TRIANGLE_STRIP,
|
||||
"texture_paths": None,
|
||||
# If true, the mobject will not get rotated according to camera position
|
||||
"is_fixed_in_frame": False,
|
||||
# Must match in attributes of vert shader
|
||||
"shader_dtype": [
|
||||
('point', np.float32, (3,)),
|
||||
|
@ -455,8 +457,19 @@ class Mobject(Container):
|
|||
# Redundant with default behavior of scale now.
|
||||
return self.scale(scale_factor, about_point=point)
|
||||
|
||||
def pose_at_angle(self, angle=TAU / 14, axis=UR, **kwargs):
|
||||
return self.rotate(angle, axis, **kwargs)
|
||||
def fix_in_frame(self, family=True):
|
||||
self.is_fixed_in_frame = True
|
||||
if family:
|
||||
for submob in self.submobjects:
|
||||
submob.fix_in_frame(family)
|
||||
return self
|
||||
|
||||
def unfix_from_frame(self, family=True):
|
||||
self.is_fixed_in_frame = False
|
||||
if family:
|
||||
for submob in self.submobjects:
|
||||
submob.unfix_from_frame(family)
|
||||
return self
|
||||
|
||||
# Positioning methods
|
||||
|
||||
|
@ -1221,7 +1234,9 @@ class Mobject(Container):
|
|||
)
|
||||
|
||||
def get_shader_uniforms(self):
|
||||
return {}
|
||||
return {
|
||||
"is_fixed_in_frame": float(self.is_fixed_in_frame),
|
||||
}
|
||||
|
||||
def get_shader_data(self):
|
||||
# Typically to be implemented by subclasses
|
||||
|
|
|
@ -214,7 +214,9 @@ class TexturedSurface(ParametricSurface):
|
|||
return self
|
||||
|
||||
def get_shader_uniforms(self):
|
||||
return {"num_textures": self.num_textures}
|
||||
result = super().get_shader_uniforms()
|
||||
result["num_textures"] = self.num_textures
|
||||
return result
|
||||
|
||||
def fill_in_shader_color_info(self, data):
|
||||
data["im_coords"] = self.get_triangle_ready_array(self.im_coords)
|
||||
|
|
|
@ -830,7 +830,7 @@ class VMobject(Mobject):
|
|||
render_primative=self.render_primative,
|
||||
)
|
||||
fill_info = get_shader_info(
|
||||
uniforms={},
|
||||
uniforms=self.get_shader_uniforms(),
|
||||
vert_file=self.fill_vert_shader_file,
|
||||
geom_file=self.fill_geom_shader_file,
|
||||
frag_file=self.fill_frag_shader_file,
|
||||
|
@ -870,13 +870,15 @@ class VMobject(Mobject):
|
|||
return result
|
||||
|
||||
def get_stroke_uniforms(self):
|
||||
joint_type_to_code = {
|
||||
j_map = {
|
||||
"auto": 0,
|
||||
"round": 1,
|
||||
"bevel": 2,
|
||||
"miter": 3,
|
||||
}
|
||||
return {"joint_type": joint_type_to_code[self.joint_type]}
|
||||
result = super().get_shader_uniforms()
|
||||
result["join_type"] = j_map[self.joint_type]
|
||||
return result
|
||||
|
||||
def get_stroke_shader_data(self):
|
||||
rgbas = self.get_stroke_rgbas()
|
||||
|
|
|
@ -1,15 +1,24 @@
|
|||
// Assumes the following uniforms exist in the surrounding context:
|
||||
// uniform vec2 frame_shape;
|
||||
// uniform float focal_distance;
|
||||
// uniform float is_fixed_in_frame;
|
||||
|
||||
const vec2 DEFAULT_FRAME_SHAPE = vec2(8 * 16 / 9, 8);
|
||||
|
||||
vec4 get_gl_Position(vec3 point){
|
||||
point.x *= 2 / frame_shape.x;
|
||||
point.y *= 2 / frame_shape.y;
|
||||
point.z /= focal_distance;
|
||||
point.xy /= max(1 - point.z, 0);
|
||||
// Todo, does this discontinuity add weirdness? Theoretically, by this point,
|
||||
// the z-coordiante of gl_Position only matter for z-indexing. The reason
|
||||
// for thie line is to avoid agressive clipping of distant points.
|
||||
if(point.z < 0) point.z *= 0.1;
|
||||
if(!bool(is_fixed_in_frame)){
|
||||
point.x *= 2 / frame_shape.x;
|
||||
point.y *= 2 / frame_shape.y;
|
||||
point.z /= focal_distance;
|
||||
point.xy /= max(1 - point.z, 0);
|
||||
// Todo, does this discontinuity add weirdness? Theoretically, by this point,
|
||||
// the z-coordiante of gl_Position only matter for z-indexing. The reason
|
||||
// for thie line is to avoid agressive clipping of distant points.
|
||||
if(point.z < 0) point.z *= 0.1;
|
||||
} else{
|
||||
point.x *= 2 / DEFAULT_FRAME_SHAPE.x;
|
||||
point.y *= 2 / DEFAULT_FRAME_SHAPE.y;
|
||||
|
||||
}
|
||||
return vec4(point.xy, -point.z, 1);
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
uniform vec2 frame_shape;
|
||||
uniform float anti_alias_width;
|
||||
uniform mat4 to_screen_space;
|
||||
uniform float is_fixed_in_frame;
|
||||
uniform float focal_distance;
|
||||
|
||||
uniform sampler2D Texture;
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
// Must be used in an environment with the following uniforms:
|
||||
// uniform mat4 to_screen_space;
|
||||
// uniform float is_fixed_in_frame;
|
||||
|
||||
vec3 position_point_into_frame(vec3 point){
|
||||
// Simply apply the pre-computed to_screen_space matrix.
|
||||
return (to_screen_space * vec4(point, 1)).xyz;
|
||||
if(bool(is_fixed_in_frame)){
|
||||
return point;
|
||||
}else{
|
||||
// Simply apply the pre-computed to_screen_space matrix.
|
||||
return (to_screen_space * vec4(point, 1)).xyz;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#version 330
|
||||
|
||||
uniform mat4 to_screen_space;
|
||||
uniform float is_fixed_in_frame;
|
||||
|
||||
in vec4 color;
|
||||
in float fill_all; // Either 0 or 1e
|
||||
|
|
|
@ -7,6 +7,7 @@ uniform float anti_alias_width;
|
|||
// Needed for get_gl_Position
|
||||
uniform vec2 frame_shape;
|
||||
uniform float focal_distance;
|
||||
uniform float is_fixed_in_frame;
|
||||
uniform vec3 light_source_position;
|
||||
|
||||
in vec3 bp[3];
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#version 330
|
||||
|
||||
uniform mat4 to_screen_space;
|
||||
uniform float is_fixed_in_frame;
|
||||
|
||||
in vec3 point;
|
||||
in vec3 unit_normal;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#version 330
|
||||
|
||||
uniform mat4 to_screen_space;
|
||||
uniform float is_fixed_in_frame;
|
||||
uniform vec3 light_source_position;
|
||||
|
||||
in vec2 uv_coords;
|
||||
|
|
|
@ -6,6 +6,7 @@ layout (triangle_strip, max_vertices = 5) out;
|
|||
// Needed for get_gl_Position
|
||||
uniform vec2 frame_shape;
|
||||
uniform float focal_distance;
|
||||
uniform float is_fixed_in_frame;
|
||||
uniform float anti_alias_width;
|
||||
uniform vec3 light_source_position;
|
||||
uniform float joint_type;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#version 330
|
||||
|
||||
uniform mat4 to_screen_space;
|
||||
uniform float is_fixed_in_frame;
|
||||
uniform float focal_distance;
|
||||
|
||||
in vec3 point;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
uniform vec2 frame_shape;
|
||||
uniform float anti_alias_width;
|
||||
uniform mat4 to_screen_space;
|
||||
uniform float is_fixed_in_frame;
|
||||
uniform float focal_distance;
|
||||
|
||||
in vec3 point;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#version 330
|
||||
|
||||
uniform vec2 frame_shape;
|
||||
uniform float anti_alias_width;
|
||||
uniform mat4 to_screen_space;
|
||||
uniform float is_fixed_in_frame;
|
||||
uniform float focal_distance;
|
||||
uniform vec3 light_source_position;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#version 330
|
||||
|
||||
uniform vec2 frame_shape;
|
||||
uniform float anti_alias_width;
|
||||
uniform mat4 to_screen_space;
|
||||
uniform float is_fixed_in_frame;
|
||||
uniform float focal_distance;
|
||||
uniform vec3 light_source_position;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue