Have separate notions of gloss and reflectiveness

This commit is contained in:
Grant Sanderson 2021-11-08 21:43:57 -08:00
parent 61b04079f5
commit 81c3ae3037
12 changed files with 108 additions and 41 deletions

View file

@ -43,10 +43,13 @@ class Mobject(object):
"opacity": 1, "opacity": 1,
"dim": 3, # TODO, get rid of this "dim": 3, # TODO, get rid of this
# Lighting parameters # Lighting parameters
# Positive gloss up to 1 makes it reflect the light. # ...
"gloss": 0.0, # Larger reflectiveness makes things brighter when facing the light
# Positive shadow up to 1 makes a side opposite the light darker "reflectiveness": 0.0,
# Larger shadow makes faces opposite the light darker
"shadow": 0.0, "shadow": 0.0,
# Makes parts bright where light gets reflected toward the camera
"gloss": 0.0,
# For shaders # For shaders
"shader_folder": "", "shader_folder": "",
"render_primitive": moderngl.TRIANGLE_STRIP, "render_primitive": moderngl.TRIANGLE_STRIP,
@ -82,11 +85,11 @@ class Mobject(object):
def __str__(self): def __str__(self):
return self.__class__.__name__ return self.__class__.__name__
def __add__(self, other : 'Mobject') -> 'Mobject': def __add__(self, other: 'Mobject') -> 'Mobject':
assert(isinstance(other, Mobject)) assert(isinstance(other, Mobject))
return self.get_group_class()(self, other) return self.get_group_class()(self, other)
def __mul__(self, other : 'int') -> 'Mobject': def __mul__(self, other: 'int') -> 'Mobject':
assert(isinstance(other, int)) assert(isinstance(other, int))
return self.replicate(other) return self.replicate(other)
@ -102,6 +105,7 @@ class Mobject(object):
"is_fixed_in_frame": float(self.is_fixed_in_frame), "is_fixed_in_frame": float(self.is_fixed_in_frame),
"gloss": self.gloss, "gloss": self.gloss,
"shadow": self.shadow, "shadow": self.shadow,
"reflectiveness": self.reflectiveness,
} }
def init_colors(self): def init_colors(self):
@ -394,6 +398,7 @@ class Mobject(object):
self.submobjects.sort(key=submob_func) self.submobjects.sort(key=submob_func)
else: else:
self.submobjects.sort(key=lambda m: point_to_num_func(m.get_center())) self.submobjects.sort(key=lambda m: point_to_num_func(m.get_center()))
self.assemble_family()
return self return self
def shuffle(self, recurse=False): def shuffle(self, recurse=False):
@ -401,6 +406,7 @@ class Mobject(object):
for submob in self.submobjects: for submob in self.submobjects:
submob.shuffle(recurse=True) submob.shuffle(recurse=True)
random.shuffle(self.submobjects) random.shuffle(self.submobjects)
self.assemble_family()
return self return self
# Copying # Copying
@ -974,12 +980,12 @@ class Mobject(object):
def fade(self, darkness=0.5, recurse=True): def fade(self, darkness=0.5, recurse=True):
self.set_opacity(1.0 - darkness, recurse=recurse) self.set_opacity(1.0 - darkness, recurse=recurse)
def get_gloss(self): def get_reflectiveness(self):
return self.uniforms["gloss"] 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): for mob in self.get_family(recurse):
mob.uniforms["gloss"] = gloss mob.uniforms["reflectiveness"] = reflectiveness
return self return self
def get_shadow(self): def get_shadow(self):
@ -990,6 +996,14 @@ class Mobject(object):
mob.uniforms["shadow"] = shadow mob.uniforms["shadow"] = shadow
return self 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 # Background rectangle
def add_background_rectangle(self, color=None, opacity=0.75, **kwargs): def add_background_rectangle(self, color=None, opacity=0.75, **kwargs):
@ -1618,7 +1632,7 @@ class Group(Mobject):
Mobject.__init__(self, **kwargs) Mobject.__init__(self, **kwargs)
self.add(*mobjects) self.add(*mobjects)
def __add__(self, other : 'Mobject' or 'Group'): def __add__(self, other: 'Mobject' or 'Group'):
assert(isinstance(other, Mobject)) assert(isinstance(other, Mobject))
return self.add(other) return self.add(other)

View file

@ -1,6 +1,6 @@
uniform vec2 frame_shape; uniform vec2 frame_shape;
uniform float anti_alias_width; uniform float anti_alias_width;
uniform vec3 camera_center; uniform vec3 camera_offset;
uniform mat3 camera_rotation; uniform mat3 camera_rotation;
uniform float is_fixed_in_frame; uniform float is_fixed_in_frame;
uniform float focal_distance; uniform float focal_distance;

View file

@ -13,39 +13,56 @@ vec4 add_light(vec4 color,
vec3 point, vec3 point,
vec3 unit_normal, vec3 unit_normal,
vec3 light_coords, vec3 light_coords,
vec3 cam_coords,
float reflectiveness,
float gloss, float gloss,
float shadow){ 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 // Assume everything has already been rotated such that camera is in the z-direction
vec3 to_camera = vec3(0, 0, camera_distance) - point; // cam_coords = vec3(0, 0, focal_distance);
vec3 to_light = light_coords - point; 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 // Note, this effectively treats surfaces as two-sided
if(dot(to_camera,unit_normal) < 0){ // if(dot(to_camera, unit_normal) < 0) unit_normal *= -1;
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); vec3 light_reflection = -to_light + 2 * unit_normal * dot(to_light, unit_normal);
float dot_prod = dot(normalize(light_reflection), normalize(to_camera)); float light_to_cam = dot(light_reflection, to_camera);
float shine = gloss * exp(-3 * pow(1 - dot_prod, 2)); float shine = gloss * exp(-3 * pow(1 - light_to_cam, 2));
float dp2 = dot(normalize(to_light), unit_normal); bright_factor += shine;
float darkening = mix(1, max(dp2, 0), shadow);
return vec4( result.rgb = mix(result.rgb, vec3(1.0), bright_factor);
darkening * mix(color.rgb, vec3(1.0), shine), if (light_to_normal < 0){
color.a // 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, vec4 finalize_color(vec4 color,
vec3 point, vec3 point,
vec3 unit_normal, vec3 unit_normal,
vec3 light_coords, vec3 light_coords,
vec3 cam_coords,
float reflectiveness,
float gloss, float gloss,
float shadow){ float shadow){
///// INSERT COLOR FUNCTION HERE ///// ///// INSERT COLOR FUNCTION HERE /////
// The line above may be replaced by arbitrary code snippets, as per // The line above may be replaced by arbitrary code snippets, as per
// the method Mobject.set_color_by_code // 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
);
} }

View file

@ -1,5 +1,5 @@
// Assumes the following uniforms exist in the surrounding context: // Assumes the following uniforms exist in the surrounding context:
// uniform vec3 camera_center; // uniform vec3 camera_offset;
// uniform mat3 camera_rotation; // uniform mat3 camera_rotation;
vec3 get_rotated_surface_unit_normal_vector(vec3 point, vec3 du_point, vec3 dv_point){ vec3 get_rotated_surface_unit_normal_vector(vec3 point, vec3 du_point, vec3 dv_point){

View file

@ -1,6 +1,6 @@
// Assumes the following uniforms exist in the surrounding context: // Assumes the following uniforms exist in the surrounding context:
// uniform float is_fixed_in_frame; // uniform float is_fixed_in_frame;
// uniform vec3 camera_center; // uniform vec3 camera_offset;
// uniform mat3 camera_rotation; // uniform mat3 camera_rotation;
vec3 rotate_point_into_frame(vec3 point){ vec3 rotate_point_into_frame(vec3 point){
@ -15,5 +15,5 @@ vec3 position_point_into_frame(vec3 point){
if(bool(is_fixed_in_frame)){ if(bool(is_fixed_in_frame)){
return point; return point;
} }
return rotate_point_into_frame(point - camera_center); return rotate_point_into_frame(point - camera_offset);
} }

View file

@ -1,6 +1,8 @@
#version 330 #version 330
uniform vec3 light_source_position; uniform vec3 light_source_position;
uniform vec3 camera_position;
uniform float reflectiveness;
uniform float gloss; uniform float gloss;
uniform float shadow; uniform float shadow;
uniform float focal_distance; uniform float focal_distance;
@ -71,6 +73,8 @@ void main() {
xyz_coords, xyz_coords,
vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, 1.0),
light_source_position, light_source_position,
camera_position,
reflectiveness,
gloss, gloss,
shadow shadow
); );

View file

@ -1,6 +1,8 @@
#version 330 #version 330
uniform vec3 light_source_position; uniform vec3 light_source_position;
uniform vec3 camera_position;
uniform float reflectiveness;
uniform float gloss; uniform float gloss;
uniform float shadow; uniform float shadow;
uniform float focal_distance; uniform float focal_distance;
@ -151,6 +153,8 @@ void main() {
xyz_coords, xyz_coords,
vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, 1.0),
light_source_position, light_source_position,
camera_position,
reflectiveness,
gloss, gloss,
shadow shadow
); );

View file

@ -11,6 +11,8 @@ uniform float focal_distance;
uniform float is_fixed_in_frame; uniform float is_fixed_in_frame;
// Needed for finalize_color // Needed for finalize_color
uniform vec3 light_source_position; uniform vec3 light_source_position;
uniform vec3 camera_position;
uniform float reflectiveness;
uniform float gloss; uniform float gloss;
uniform float shadow; uniform float shadow;
@ -44,6 +46,8 @@ void emit_vertex_wrapper(vec3 point, int index){
point, point,
v_global_unit_normal[index], v_global_unit_normal[index],
light_source_position, light_source_position,
camera_position,
reflectiveness,
gloss, gloss,
shadow shadow
); );

View file

@ -13,7 +13,9 @@ uniform float flat_stroke;
//Needed for lighting //Needed for lighting
uniform vec3 light_source_position; uniform vec3 light_source_position;
uniform vec3 camera_position;
uniform float joint_type; uniform float joint_type;
uniform float reflectiveness;
uniform float gloss; uniform float gloss;
uniform float shadow; uniform float shadow;
@ -259,6 +261,8 @@ void main() {
xyz_coords, xyz_coords,
v_global_unit_normal[index_map[i]], v_global_unit_normal[index_map[i]],
light_source_position, light_source_position,
camera_position,
reflectiveness,
gloss, gloss,
shadow shadow
); );

View file

@ -1,6 +1,8 @@
#version 330 #version 330
uniform vec3 light_source_position; uniform vec3 light_source_position;
uniform vec3 camera_position;
uniform float reflectiveness;
uniform float gloss; uniform float gloss;
uniform float shadow; uniform float shadow;
uniform float focal_distance; uniform float focal_distance;
@ -19,6 +21,8 @@ void main() {
xyz_coords, xyz_coords,
normalize(v_normal), normalize(v_normal),
light_source_position, light_source_position,
camera_position,
reflectiveness,
gloss, gloss,
shadow shadow
); );

View file

@ -4,6 +4,8 @@ uniform sampler2D LightTexture;
uniform sampler2D DarkTexture; uniform sampler2D DarkTexture;
uniform float num_textures; uniform float num_textures;
uniform vec3 light_source_position; uniform vec3 light_source_position;
uniform vec3 camera_position;
uniform float reflectiveness;
uniform float gloss; uniform float gloss;
uniform float shadow; uniform float shadow;
uniform float focal_distance; uniform float focal_distance;
@ -36,6 +38,8 @@ void main() {
xyz_coords, xyz_coords,
normalize(v_normal), normalize(v_normal),
light_source_position, light_source_position,
camera_position,
reflectiveness,
gloss, gloss,
shadow shadow
); );

View file

@ -1,10 +1,13 @@
#version 330 #version 330
uniform vec3 light_source_position; uniform vec3 light_source_position;
uniform vec3 camera_position;
uniform float reflectiveness;
uniform float gloss; uniform float gloss;
uniform float shadow; uniform float shadow;
uniform float anti_alias_width; uniform float anti_alias_width;
uniform float focal_distance; uniform float focal_distance;
uniform float glow_factor;
in vec4 color; in vec4 color;
in float radius; in float radius;
@ -22,14 +25,23 @@ void main() {
if (signed_dist > 0.5 * anti_alias_width){ if (signed_dist > 0.5 * anti_alias_width){
discard; discard;
} }
frag_color = color;
if(gloss > 0 || shadow > 0){
vec3 normal = vec3(diff / radius, sqrt(1 - (dist * dist) / (radius * radius))); vec3 normal = vec3(diff / radius, sqrt(1 - (dist * dist) / (radius * radius)));
frag_color = finalize_color( frag_color = finalize_color(
color, frag_color,
vec3(point.xy, 0.0), vec3(point.xy, 0.0),
normal, normal,
light_source_position, light_source_position,
camera_position,
reflectiveness,
gloss, gloss,
shadow 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); frag_color.a *= smoothstep(0.5, -0.5, signed_dist / anti_alias_width);
} }