mirror of
https://github.com/3b1b/manim.git
synced 2025-11-14 17:27:48 +00:00
Add shadow, and pull out lighting information to Mobject
This commit is contained in:
parent
b32c2937ae
commit
ba7a51931d
14 changed files with 94 additions and 44 deletions
|
|
@ -382,5 +382,7 @@ class Camera(object):
|
|||
|
||||
|
||||
class ThreeDCamera(Camera):
|
||||
# Purely here to keep old scenes happy
|
||||
pass
|
||||
CONFIG = {
|
||||
"apply_depth_test": True,
|
||||
# TODO, default to do some multisampling?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@ class Mobject(Container):
|
|||
"color": WHITE,
|
||||
"name": None,
|
||||
"dim": 3,
|
||||
# Lighting parameters
|
||||
# Positive gloss up to 1 makes it reflect the light.
|
||||
"gloss": 0.0,
|
||||
# Positive shadow up to 1 makes a side opposite the light darker
|
||||
"shadow": 0.0,
|
||||
# For shaders
|
||||
"vert_shader_file": "",
|
||||
"geom_shader_file": "",
|
||||
|
|
@ -735,6 +740,26 @@ class Mobject(Container):
|
|||
def get_color(self):
|
||||
return self.color
|
||||
|
||||
def get_gloss(self):
|
||||
return self.gloss
|
||||
|
||||
def set_gloss(self, gloss, family=True):
|
||||
self.gloss = gloss
|
||||
if family:
|
||||
for submob in self.submobjects:
|
||||
submob.set_gloss(gloss, family)
|
||||
return self
|
||||
|
||||
def get_shadow(self):
|
||||
return self.shadow
|
||||
|
||||
def set_shadow(self, shadow, family=True):
|
||||
self.shadow = shadow
|
||||
if family:
|
||||
for submob in self.submobjects:
|
||||
submob.set_shadow(shadow, family)
|
||||
return self
|
||||
|
||||
##
|
||||
|
||||
def save_state(self, use_deepcopy=False):
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@ class ParametricSurface(Mobject):
|
|||
CONFIG = {
|
||||
"u_range": (0, 1),
|
||||
"v_range": (0, 1),
|
||||
# Resolution counts number of points sampled, which is off by
|
||||
# 1 from the number of actual approximating squares seen
|
||||
# Resolution counts number of points sampled, which for
|
||||
# each coordinate is one more than the the number of rows/columns
|
||||
# of approximating squares
|
||||
"resolution": (101, 101),
|
||||
"color": GREY,
|
||||
"opacity": 1.0,
|
||||
"gloss": 0.3,
|
||||
"shadow": 0.4,
|
||||
# For du and dv steps. Much smaller and numerical error
|
||||
# can crop up in the shaders.
|
||||
"epsilon": 1e-5,
|
||||
|
|
@ -32,6 +34,7 @@ class ParametricSurface(Mobject):
|
|||
('dv_point', np.float32, (3,)),
|
||||
('color', np.float32, (4,)),
|
||||
('gloss', np.float32, (1,)),
|
||||
('shadow', np.float32, (1,)),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -114,13 +117,6 @@ class ParametricSurface(Mobject):
|
|||
sm.set_opacity(opacity, family)
|
||||
return self
|
||||
|
||||
def set_gloss(self, gloss, family=True):
|
||||
self.gloss = gloss
|
||||
if family:
|
||||
for sm in self.submobjects:
|
||||
sm.set_gloss(gloss, family)
|
||||
return self
|
||||
|
||||
def get_shader_data(self):
|
||||
s_points, du_points, dv_points = [
|
||||
self.get_triangle_ready_array(array)
|
||||
|
|
@ -130,12 +126,13 @@ class ParametricSurface(Mobject):
|
|||
data["point"] = s_points
|
||||
data["du_point"] = du_points
|
||||
data["dv_point"] = dv_points
|
||||
data["gloss"] = self.gloss
|
||||
data["shadow"] = self.shadow
|
||||
self.fill_in_shader_color_info(data)
|
||||
return data
|
||||
|
||||
def fill_in_shader_color_info(self, data):
|
||||
data["color"] = self.rgbas
|
||||
data["gloss"] = self.gloss
|
||||
return data
|
||||
|
||||
|
||||
|
|
@ -159,6 +156,7 @@ class TexturedSurface(ParametricSurface):
|
|||
('im_coords', np.float32, (2,)),
|
||||
('opacity', np.float32, (1,)),
|
||||
('gloss', np.float32, (1,)),
|
||||
('shadow', np.float32, (1,)),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -199,5 +197,4 @@ class TexturedSurface(ParametricSurface):
|
|||
def fill_in_shader_color_info(self, data):
|
||||
data["im_coords"] = self.get_triangle_ready_array(self.im_coords)
|
||||
data["opacity"] = self.opacity
|
||||
data["gloss"] = self.gloss
|
||||
return data
|
||||
|
|
|
|||
|
|
@ -57,8 +57,6 @@ class VMobject(Mobject):
|
|||
"fill_frag_shader_file": "quadratic_bezier_fill_frag.glsl",
|
||||
# Could also be Bevel, Miter, Round
|
||||
"joint_type": "auto",
|
||||
# Positive gloss up to 1 makes it reflect the light.
|
||||
"gloss": 0.2,
|
||||
"render_primative": moderngl.TRIANGLES,
|
||||
"triangulation_locked": False,
|
||||
"fill_dtype": [
|
||||
|
|
@ -67,6 +65,7 @@ class VMobject(Mobject):
|
|||
('color', np.float32, (4,)),
|
||||
('fill_all', np.float32, (1,)),
|
||||
('gloss', np.float32, (1,)),
|
||||
('shadow', np.float32, (1,)),
|
||||
],
|
||||
"stroke_dtype": [
|
||||
("point", np.float32, (3,)),
|
||||
|
|
@ -77,6 +76,7 @@ class VMobject(Mobject):
|
|||
("color", np.float32, (4,)),
|
||||
("joint_type", np.float32, (1,)),
|
||||
("gloss", np.float32, (1,)),
|
||||
("shadow", np.float32, (1,)),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -155,6 +155,7 @@ class VMobject(Mobject):
|
|||
stroke_width=None,
|
||||
stroke_opacity=None,
|
||||
gloss=None,
|
||||
shadow=None,
|
||||
background_image_file=None,
|
||||
family=True):
|
||||
self.set_fill(
|
||||
|
|
@ -168,8 +169,10 @@ class VMobject(Mobject):
|
|||
opacity=stroke_opacity,
|
||||
family=family,
|
||||
)
|
||||
if gloss:
|
||||
if gloss is not None:
|
||||
self.set_gloss(gloss, family=family)
|
||||
if shadow is not None:
|
||||
self.set_shadow(shadow, family=family)
|
||||
if background_image_file:
|
||||
self.color_using_background_image(background_image_file)
|
||||
return self
|
||||
|
|
@ -223,17 +226,6 @@ class VMobject(Mobject):
|
|||
super().fade(darkness, family)
|
||||
return self
|
||||
|
||||
def set_gloss(self, gloss, family=True):
|
||||
if family:
|
||||
for sm in self.get_family():
|
||||
sm.gloss = gloss
|
||||
else:
|
||||
self.gloss = gloss
|
||||
return self
|
||||
|
||||
def get_gloss(self):
|
||||
return self.gloss
|
||||
|
||||
def get_fill_rgbas(self):
|
||||
try:
|
||||
return self.fill_rgbas
|
||||
|
|
@ -908,6 +900,7 @@ class VMobject(Mobject):
|
|||
data["color"] = rgbas
|
||||
data["joint_type"] = joint_type_to_code[self.joint_type]
|
||||
data["gloss"] = self.gloss
|
||||
data["shadow"] = self.shadow
|
||||
return data
|
||||
|
||||
def lock_triangulation(self, family=True):
|
||||
|
|
@ -994,6 +987,7 @@ class VMobject(Mobject):
|
|||
data["fill_all"][:len(points)] = 0
|
||||
data["fill_all"][len(points):] = 1
|
||||
data["gloss"] = self.gloss
|
||||
data["shadow"] = self.shadow
|
||||
return data
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
vec4 add_light(vec4 raw_color, vec3 point, vec3 unit_normal, vec3 light_coords, float gloss){
|
||||
if(gloss == 0.0) return raw_color;
|
||||
vec4 add_light(vec4 raw_color, vec3 point, vec3 unit_normal, vec3 light_coords, float gloss, float shadow){
|
||||
if(gloss == 0.0 && shadow == 0.0) return raw_color;
|
||||
|
||||
// TODO, do we actually want this? It effectively treats surfaces as two-sided
|
||||
if(unit_normal.z < 0){
|
||||
|
|
@ -14,9 +14,9 @@ vec4 add_light(vec4 raw_color, vec3 point, vec3 unit_normal, vec3 light_coords,
|
|||
float dot_prod = dot(normalize(light_reflection), normalize(to_camera));
|
||||
float shine = gloss * exp(-3 * pow(1 - dot_prod, 2));
|
||||
float dp2 = dot(normalize(to_light), unit_normal);
|
||||
float shadow = ((dp2 + 2.0) / 3.0); // TODO, this should come from the mobject in some way
|
||||
float darkening = mix(1, max(dp2, 0), shadow);
|
||||
return vec4(
|
||||
shadow * mix(raw_color.rgb, vec3(1.0), shine),
|
||||
darkening * mix(raw_color.rgb, vec3(1.0), shine),
|
||||
raw_color.a
|
||||
);
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
#version 330
|
||||
|
||||
uniform vec3 light_source_position;
|
||||
uniform mat4 to_screen_space;
|
||||
|
||||
in vec4 color;
|
||||
|
|
@ -8,12 +7,10 @@ in float fill_all; // Either 0 or 1e
|
|||
in float uv_anti_alias_width;
|
||||
|
||||
in vec3 xyz_coords;
|
||||
in vec3 global_unit_normal;
|
||||
in float orientation;
|
||||
in vec2 uv_coords;
|
||||
in vec2 uv_b2;
|
||||
in float bezier_degree;
|
||||
in float gloss;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
|
|
@ -26,7 +23,6 @@ float modify_distance_for_endpoints(vec2 p, float dist, float t){
|
|||
// so to share functionality between this and others, the caller
|
||||
// replaces this line with the contents of quadratic_bezier_sdf.glsl
|
||||
#INSERT quadratic_bezier_distance.glsl
|
||||
#INSERT add_light.glsl
|
||||
|
||||
|
||||
float sdf(){
|
||||
|
|
@ -67,7 +63,7 @@ float sdf(){
|
|||
|
||||
void main() {
|
||||
if (color.a == 0) discard;
|
||||
frag_color = add_light(color, xyz_coords, global_unit_normal, light_source_position, gloss);
|
||||
frag_color = color;
|
||||
if (fill_all == 1.0) return;
|
||||
frag_color.a *= smoothstep(1, 0, sdf() / uv_anti_alias_width);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,20 @@ uniform float anti_alias_width;
|
|||
// Needed for get_gl_Position
|
||||
uniform float aspect_ratio;
|
||||
uniform float focal_distance;
|
||||
uniform vec3 light_source_position;
|
||||
|
||||
in vec3 bp[3];
|
||||
in vec3 v_global_unit_normal[3];
|
||||
in vec4 v_color[3];
|
||||
in float v_fill_all[3];
|
||||
in float v_gloss[3];
|
||||
in float v_shadow[3];
|
||||
|
||||
out vec4 color;
|
||||
out float gloss;
|
||||
out float fill_all;
|
||||
out float uv_anti_alias_width;
|
||||
|
||||
out vec3 xyz_coords;
|
||||
out vec3 global_unit_normal;
|
||||
out float orientation;
|
||||
// uv space is where b0 = (0, 0), b1 = (1, 0), and transform is orthogonal
|
||||
out vec2 uv_coords;
|
||||
|
|
@ -33,12 +33,18 @@ out float bezier_degree;
|
|||
#INSERT quadratic_bezier_geometry_functions.glsl
|
||||
#INSERT get_gl_Position.glsl
|
||||
#INSERT get_unit_normal.glsl
|
||||
#INSERT add_light.glsl
|
||||
|
||||
|
||||
void emit_vertex_wrapper(vec3 point, int index){
|
||||
color = v_color[index];
|
||||
gloss = v_gloss[index];
|
||||
global_unit_normal = v_global_unit_normal[index];
|
||||
color = add_light(
|
||||
v_color[index],
|
||||
point,
|
||||
v_global_unit_normal[index],
|
||||
light_source_position,
|
||||
v_gloss[index],
|
||||
v_shadow[index]
|
||||
);
|
||||
xyz_coords = point;
|
||||
gl_Position = get_gl_Position(xyz_coords);
|
||||
EmitVertex();
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ in vec3 unit_normal;
|
|||
in vec4 color;
|
||||
in float fill_all; // Either 0 or 1
|
||||
in float gloss;
|
||||
in float shadow;
|
||||
|
||||
out vec3 bp; // Bezier control point
|
||||
out vec3 v_global_unit_normal;
|
||||
out vec4 v_color;
|
||||
out float v_fill_all;
|
||||
out float v_gloss;
|
||||
out float v_shadow;
|
||||
|
||||
// To my knowledge, there is no notion of #include for shaders,
|
||||
// so to share functionality between this and others, the caller
|
||||
|
|
@ -25,4 +27,5 @@ void main(){
|
|||
v_color = color;
|
||||
v_fill_all = fill_all;
|
||||
v_gloss = gloss;
|
||||
v_shadow = shadow;
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ in vec4 v_color[3];
|
|||
in float v_stroke_width[3];
|
||||
in float v_joint_type[3];
|
||||
in float v_gloss[3];
|
||||
in float v_shadow[3];
|
||||
|
||||
out vec4 color;
|
||||
out float uv_stroke_width;
|
||||
|
|
@ -256,7 +257,8 @@ void main() {
|
|||
xyz_coords,
|
||||
v_global_unit_normal[index_map[i]],
|
||||
light_source_position,
|
||||
v_gloss[index_map[i]]
|
||||
v_gloss[index_map[i]],
|
||||
v_shadow[index_map[i]]
|
||||
);
|
||||
gl_Position = get_gl_Position(xyz_coords);
|
||||
EmitVertex();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ in float stroke_width;
|
|||
in vec4 color;
|
||||
in float joint_type;
|
||||
in float gloss;
|
||||
in float shadow;
|
||||
|
||||
// Bezier control point
|
||||
out vec3 bp;
|
||||
|
|
@ -23,6 +24,7 @@ out float v_stroke_width;
|
|||
out vec4 v_color;
|
||||
out float v_joint_type;
|
||||
out float v_gloss;
|
||||
out float v_shadow;
|
||||
|
||||
const float STROKE_WIDTH_CONVERSION = 0.0025;
|
||||
|
||||
|
|
@ -41,4 +43,5 @@ void main(){
|
|||
v_color = color;
|
||||
v_joint_type = joint_type;
|
||||
v_gloss = gloss;
|
||||
v_shadow = shadow;
|
||||
}
|
||||
|
|
@ -9,11 +9,19 @@ in vec3 xyz_coords;
|
|||
in vec3 v_normal;
|
||||
in vec4 v_color;
|
||||
in float v_gloss;
|
||||
in float v_shadow;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
#INSERT add_light.glsl
|
||||
|
||||
void main() {
|
||||
frag_color = add_light(v_color, xyz_coords, normalize(v_normal), light_source_position, v_gloss);
|
||||
frag_color = add_light(
|
||||
v_color,
|
||||
xyz_coords,
|
||||
normalize(v_normal),
|
||||
light_source_position,
|
||||
v_gloss,
|
||||
v_shadow
|
||||
);
|
||||
}
|
||||
|
|
@ -11,11 +11,13 @@ in vec3 du_point;
|
|||
in vec3 dv_point;
|
||||
in vec4 color;
|
||||
in float gloss;
|
||||
in float shadow;
|
||||
|
||||
out vec3 xyz_coords;
|
||||
out vec3 v_normal;
|
||||
out vec4 v_color;
|
||||
out float v_gloss;
|
||||
out float v_shadow;
|
||||
|
||||
// These lines will get replaced
|
||||
#INSERT position_point_into_frame.glsl
|
||||
|
|
@ -27,5 +29,6 @@ void main(){
|
|||
v_normal = get_rotated_surface_unit_normal_vector(point, du_point, dv_point);
|
||||
v_color = color;
|
||||
v_gloss = gloss;
|
||||
v_shadow = shadow;
|
||||
gl_Position = get_gl_Position(xyz_coords);
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ in vec3 v_normal;
|
|||
in vec2 v_im_coords;
|
||||
in float v_opacity;
|
||||
in float v_gloss;
|
||||
in float v_shadow;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
|
|
@ -15,6 +16,13 @@ out vec4 frag_color;
|
|||
|
||||
void main() {
|
||||
vec4 im_color = texture(Texture, v_im_coords);
|
||||
frag_color = add_light(im_color, xyz_coords, normalize(v_normal), light_source_position, v_gloss);
|
||||
frag_color = add_light(
|
||||
im_color,
|
||||
xyz_coords,
|
||||
normalize(v_normal),
|
||||
light_source_position,
|
||||
v_gloss,
|
||||
v_shadow
|
||||
);
|
||||
frag_color.a = v_opacity;
|
||||
}
|
||||
|
|
@ -14,12 +14,14 @@ in vec3 dv_point;
|
|||
in vec2 im_coords;
|
||||
in float opacity;
|
||||
in float gloss;
|
||||
in float shadow;
|
||||
|
||||
out vec3 xyz_coords;
|
||||
out vec3 v_normal;
|
||||
out vec2 v_im_coords;
|
||||
out float v_opacity;
|
||||
out float v_gloss;
|
||||
out float v_shadow;
|
||||
|
||||
// These lines will get replaced
|
||||
#INSERT position_point_into_frame.glsl
|
||||
|
|
@ -32,5 +34,6 @@ void main(){
|
|||
v_im_coords = im_coords;
|
||||
v_opacity = opacity;
|
||||
v_gloss = gloss;
|
||||
v_shadow = shadow;
|
||||
gl_Position = get_gl_Position(xyz_coords);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue