mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
Have separate notions of gloss and reflectiveness
This commit is contained in:
parent
61b04079f5
commit
81c3ae3037
12 changed files with 108 additions and 41 deletions
|
@ -43,10 +43,13 @@ class Mobject(object):
|
|||
"opacity": 1,
|
||||
"dim": 3, # TODO, get rid of this
|
||||
# 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
|
||||
# ...
|
||||
# Larger reflectiveness makes things brighter when facing the light
|
||||
"reflectiveness": 0.0,
|
||||
# Larger shadow makes faces opposite the light darker
|
||||
"shadow": 0.0,
|
||||
# Makes parts bright where light gets reflected toward the camera
|
||||
"gloss": 0.0,
|
||||
# For shaders
|
||||
"shader_folder": "",
|
||||
"render_primitive": moderngl.TRIANGLE_STRIP,
|
||||
|
@ -82,11 +85,11 @@ class Mobject(object):
|
|||
def __str__(self):
|
||||
return self.__class__.__name__
|
||||
|
||||
def __add__(self, other : 'Mobject') -> 'Mobject':
|
||||
def __add__(self, other: 'Mobject') -> 'Mobject':
|
||||
assert(isinstance(other, Mobject))
|
||||
return self.get_group_class()(self, other)
|
||||
|
||||
def __mul__(self, other : 'int') -> 'Mobject':
|
||||
def __mul__(self, other: 'int') -> 'Mobject':
|
||||
assert(isinstance(other, int))
|
||||
return self.replicate(other)
|
||||
|
||||
|
@ -102,6 +105,7 @@ class Mobject(object):
|
|||
"is_fixed_in_frame": float(self.is_fixed_in_frame),
|
||||
"gloss": self.gloss,
|
||||
"shadow": self.shadow,
|
||||
"reflectiveness": self.reflectiveness,
|
||||
}
|
||||
|
||||
def init_colors(self):
|
||||
|
@ -394,6 +398,7 @@ class Mobject(object):
|
|||
self.submobjects.sort(key=submob_func)
|
||||
else:
|
||||
self.submobjects.sort(key=lambda m: point_to_num_func(m.get_center()))
|
||||
self.assemble_family()
|
||||
return self
|
||||
|
||||
def shuffle(self, recurse=False):
|
||||
|
@ -401,6 +406,7 @@ class Mobject(object):
|
|||
for submob in self.submobjects:
|
||||
submob.shuffle(recurse=True)
|
||||
random.shuffle(self.submobjects)
|
||||
self.assemble_family()
|
||||
return self
|
||||
|
||||
# Copying
|
||||
|
@ -974,12 +980,12 @@ class Mobject(object):
|
|||
def fade(self, darkness=0.5, recurse=True):
|
||||
self.set_opacity(1.0 - darkness, recurse=recurse)
|
||||
|
||||
def get_gloss(self):
|
||||
return self.uniforms["gloss"]
|
||||
def get_reflectiveness(self):
|
||||
return self.uniforms["reflectiveness"]
|
||||
|
||||
def set_gloss(self, gloss, recurse=True):
|
||||
def set_reflectiveness(self, reflectiveness, recurse=True):
|
||||
for mob in self.get_family(recurse):
|
||||
mob.uniforms["gloss"] = gloss
|
||||
mob.uniforms["reflectiveness"] = reflectiveness
|
||||
return self
|
||||
|
||||
def get_shadow(self):
|
||||
|
@ -990,6 +996,14 @@ class Mobject(object):
|
|||
mob.uniforms["shadow"] = shadow
|
||||
return self
|
||||
|
||||
def get_gloss(self):
|
||||
return self.uniforms["gloss"]
|
||||
|
||||
def set_gloss(self, gloss, recurse=True):
|
||||
for mob in self.get_family(recurse):
|
||||
mob.uniforms["gloss"] = gloss
|
||||
return self
|
||||
|
||||
# Background rectangle
|
||||
|
||||
def add_background_rectangle(self, color=None, opacity=0.75, **kwargs):
|
||||
|
@ -1617,8 +1631,8 @@ class Group(Mobject):
|
|||
raise Exception("All submobjects must be of type Mobject")
|
||||
Mobject.__init__(self, **kwargs)
|
||||
self.add(*mobjects)
|
||||
|
||||
def __add__(self, other : 'Mobject' or 'Group'):
|
||||
|
||||
def __add__(self, other: 'Mobject' or 'Group'):
|
||||
assert(isinstance(other, Mobject))
|
||||
return self.add(other)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
uniform vec2 frame_shape;
|
||||
uniform float anti_alias_width;
|
||||
uniform vec3 camera_center;
|
||||
uniform vec3 camera_offset;
|
||||
uniform mat3 camera_rotation;
|
||||
uniform float is_fixed_in_frame;
|
||||
uniform float focal_distance;
|
|
@ -13,39 +13,56 @@ vec4 add_light(vec4 color,
|
|||
vec3 point,
|
||||
vec3 unit_normal,
|
||||
vec3 light_coords,
|
||||
vec3 cam_coords,
|
||||
float reflectiveness,
|
||||
float gloss,
|
||||
float shadow){
|
||||
if(gloss == 0.0 && shadow == 0.0) return color;
|
||||
if(reflectiveness == 0.0 && gloss == 0.0 && shadow == 0.0) return color;
|
||||
|
||||
float camera_distance = focal_distance;
|
||||
vec4 result = color;
|
||||
// Assume everything has already been rotated such that camera is in the z-direction
|
||||
vec3 to_camera = vec3(0, 0, camera_distance) - point;
|
||||
vec3 to_light = light_coords - point;
|
||||
// cam_coords = vec3(0, 0, focal_distance);
|
||||
vec3 to_camera = normalize(cam_coords - point);
|
||||
vec3 to_light = normalize(light_coords - point);
|
||||
|
||||
// TODO, do we actually want this? It effectively treats surfaces as two-sided
|
||||
if(dot(to_camera,unit_normal) < 0){
|
||||
unit_normal *= -1;
|
||||
}
|
||||
// Note, this effectively treats surfaces as two-sided
|
||||
// if(dot(to_camera, unit_normal) < 0) unit_normal *= -1;
|
||||
|
||||
float light_to_normal = dot(to_light, unit_normal);
|
||||
// When unit normal points towards light, brighten
|
||||
float bright_factor = max(light_to_normal, 0) * reflectiveness;
|
||||
// For glossy surface, add extra shine if light beam go towards camera
|
||||
vec3 light_reflection = -to_light + 2 * unit_normal * dot(to_light, unit_normal);
|
||||
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 darkening = mix(1, max(dp2, 0), shadow);
|
||||
return vec4(
|
||||
darkening * mix(color.rgb, vec3(1.0), shine),
|
||||
color.a
|
||||
);
|
||||
float light_to_cam = dot(light_reflection, to_camera);
|
||||
float shine = gloss * exp(-3 * pow(1 - light_to_cam, 2));
|
||||
bright_factor += shine;
|
||||
|
||||
result.rgb = mix(result.rgb, vec3(1.0), bright_factor);
|
||||
if (light_to_normal < 0){
|
||||
// Darken
|
||||
result.rgb = mix(result.rgb, vec3(0.0), -light_to_normal * shadow);
|
||||
}
|
||||
// float darkening = mix(1, max(light_to_normal, 0), shadow);
|
||||
// return vec4(
|
||||
// darkening * mix(color.rgb, vec3(1.0), shine),
|
||||
// color.a
|
||||
// );
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 finalize_color(vec4 color,
|
||||
vec3 point,
|
||||
vec3 unit_normal,
|
||||
vec3 light_coords,
|
||||
vec3 cam_coords,
|
||||
float reflectiveness,
|
||||
float gloss,
|
||||
float shadow){
|
||||
///// INSERT COLOR FUNCTION HERE /////
|
||||
// The line above may be replaced by arbitrary code snippets, as per
|
||||
// the method Mobject.set_color_by_code
|
||||
return add_light(color, point, unit_normal, light_coords, gloss, shadow);
|
||||
return add_light(
|
||||
color, point, unit_normal, light_coords, cam_coords,
|
||||
reflectiveness, gloss, shadow
|
||||
);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// Assumes the following uniforms exist in the surrounding context:
|
||||
// uniform vec3 camera_center;
|
||||
// uniform vec3 camera_offset;
|
||||
// uniform mat3 camera_rotation;
|
||||
|
||||
vec3 get_rotated_surface_unit_normal_vector(vec3 point, vec3 du_point, vec3 dv_point){
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Assumes the following uniforms exist in the surrounding context:
|
||||
// uniform float is_fixed_in_frame;
|
||||
// uniform vec3 camera_center;
|
||||
// uniform vec3 camera_offset;
|
||||
// uniform mat3 camera_rotation;
|
||||
|
||||
vec3 rotate_point_into_frame(vec3 point){
|
||||
|
@ -15,5 +15,5 @@ vec3 position_point_into_frame(vec3 point){
|
|||
if(bool(is_fixed_in_frame)){
|
||||
return point;
|
||||
}
|
||||
return rotate_point_into_frame(point - camera_center);
|
||||
return rotate_point_into_frame(point - camera_offset);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#version 330
|
||||
|
||||
uniform vec3 light_source_position;
|
||||
uniform vec3 camera_position;
|
||||
uniform float reflectiveness;
|
||||
uniform float gloss;
|
||||
uniform float shadow;
|
||||
uniform float focal_distance;
|
||||
|
@ -71,6 +73,8 @@ void main() {
|
|||
xyz_coords,
|
||||
vec3(0.0, 0.0, 1.0),
|
||||
light_source_position,
|
||||
camera_position,
|
||||
reflectiveness,
|
||||
gloss,
|
||||
shadow
|
||||
);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#version 330
|
||||
|
||||
uniform vec3 light_source_position;
|
||||
uniform vec3 camera_position;
|
||||
uniform float reflectiveness;
|
||||
uniform float gloss;
|
||||
uniform float shadow;
|
||||
uniform float focal_distance;
|
||||
|
@ -151,6 +153,8 @@ void main() {
|
|||
xyz_coords,
|
||||
vec3(0.0, 0.0, 1.0),
|
||||
light_source_position,
|
||||
camera_position,
|
||||
reflectiveness,
|
||||
gloss,
|
||||
shadow
|
||||
);
|
||||
|
|
|
@ -11,6 +11,8 @@ uniform float focal_distance;
|
|||
uniform float is_fixed_in_frame;
|
||||
// Needed for finalize_color
|
||||
uniform vec3 light_source_position;
|
||||
uniform vec3 camera_position;
|
||||
uniform float reflectiveness;
|
||||
uniform float gloss;
|
||||
uniform float shadow;
|
||||
|
||||
|
@ -44,6 +46,8 @@ void emit_vertex_wrapper(vec3 point, int index){
|
|||
point,
|
||||
v_global_unit_normal[index],
|
||||
light_source_position,
|
||||
camera_position,
|
||||
reflectiveness,
|
||||
gloss,
|
||||
shadow
|
||||
);
|
||||
|
|
|
@ -13,7 +13,9 @@ uniform float flat_stroke;
|
|||
|
||||
//Needed for lighting
|
||||
uniform vec3 light_source_position;
|
||||
uniform vec3 camera_position;
|
||||
uniform float joint_type;
|
||||
uniform float reflectiveness;
|
||||
uniform float gloss;
|
||||
uniform float shadow;
|
||||
|
||||
|
@ -259,6 +261,8 @@ void main() {
|
|||
xyz_coords,
|
||||
v_global_unit_normal[index_map[i]],
|
||||
light_source_position,
|
||||
camera_position,
|
||||
reflectiveness,
|
||||
gloss,
|
||||
shadow
|
||||
);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#version 330
|
||||
|
||||
uniform vec3 light_source_position;
|
||||
uniform vec3 camera_position;
|
||||
uniform float reflectiveness;
|
||||
uniform float gloss;
|
||||
uniform float shadow;
|
||||
uniform float focal_distance;
|
||||
|
@ -19,6 +21,8 @@ void main() {
|
|||
xyz_coords,
|
||||
normalize(v_normal),
|
||||
light_source_position,
|
||||
camera_position,
|
||||
reflectiveness,
|
||||
gloss,
|
||||
shadow
|
||||
);
|
||||
|
|
|
@ -4,6 +4,8 @@ uniform sampler2D LightTexture;
|
|||
uniform sampler2D DarkTexture;
|
||||
uniform float num_textures;
|
||||
uniform vec3 light_source_position;
|
||||
uniform vec3 camera_position;
|
||||
uniform float reflectiveness;
|
||||
uniform float gloss;
|
||||
uniform float shadow;
|
||||
uniform float focal_distance;
|
||||
|
@ -36,6 +38,8 @@ void main() {
|
|||
xyz_coords,
|
||||
normalize(v_normal),
|
||||
light_source_position,
|
||||
camera_position,
|
||||
reflectiveness,
|
||||
gloss,
|
||||
shadow
|
||||
);
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#version 330
|
||||
|
||||
uniform vec3 light_source_position;
|
||||
uniform vec3 camera_position;
|
||||
uniform float reflectiveness;
|
||||
uniform float gloss;
|
||||
uniform float shadow;
|
||||
uniform float anti_alias_width;
|
||||
uniform float focal_distance;
|
||||
uniform float glow_factor;
|
||||
|
||||
in vec4 color;
|
||||
in float radius;
|
||||
|
@ -22,14 +25,23 @@ void main() {
|
|||
if (signed_dist > 0.5 * anti_alias_width){
|
||||
discard;
|
||||
}
|
||||
vec3 normal = vec3(diff / radius, sqrt(1 - (dist * dist) / (radius * radius)));
|
||||
frag_color = finalize_color(
|
||||
color,
|
||||
vec3(point.xy, 0.0),
|
||||
normal,
|
||||
light_source_position,
|
||||
gloss,
|
||||
shadow
|
||||
);
|
||||
frag_color = color;
|
||||
if(gloss > 0 || shadow > 0){
|
||||
vec3 normal = vec3(diff / radius, sqrt(1 - (dist * dist) / (radius * radius)));
|
||||
frag_color = finalize_color(
|
||||
frag_color,
|
||||
vec3(point.xy, 0.0),
|
||||
normal,
|
||||
light_source_position,
|
||||
camera_position,
|
||||
reflectiveness,
|
||||
gloss,
|
||||
shadow
|
||||
);
|
||||
}
|
||||
if(glow_factor > 0){
|
||||
frag_color.a *= pow(1 - dist / radius, glow_factor);
|
||||
}
|
||||
|
||||
frag_color.a *= smoothstep(0.5, -0.5, signed_dist / anti_alias_width);
|
||||
}
|
Loading…
Add table
Reference in a new issue