mirror of
https://github.com/3b1b/manim.git
synced 2025-11-14 13:37:45 +00:00
Better handling of textures, now letting multiple get passed in to a textured surface
This commit is contained in:
parent
596b7c0112
commit
39230a805c
7 changed files with 52 additions and 40 deletions
|
|
@ -367,11 +367,10 @@ class Camera(object):
|
||||||
geometry_shader=get_shader_code_from_file(info["geom"]),
|
geometry_shader=get_shader_code_from_file(info["geom"]),
|
||||||
fragment_shader=get_shader_code_from_file(info["frag"]),
|
fragment_shader=get_shader_code_from_file(info["frag"]),
|
||||||
)
|
)
|
||||||
if info["texture_path"]:
|
if info["texture_paths"]:
|
||||||
# TODO, this currently assumes that the uniform Sampler2D
|
for name, path in info["texture_paths"].items():
|
||||||
# is named Texture, and that there's only one of them
|
tid = self.get_texture_id(path)
|
||||||
tid = self.get_texture_id(info["texture_path"])
|
shader[name].value = tid
|
||||||
shader["Texture"].value = tid
|
|
||||||
|
|
||||||
self.set_shader_uniforms(shader)
|
self.set_shader_uniforms(shader)
|
||||||
self.id_to_shader[sid] = shader
|
self.id_to_shader[sid] = shader
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class Mobject(Container):
|
||||||
"geom_shader_file": "",
|
"geom_shader_file": "",
|
||||||
"frag_shader_file": "",
|
"frag_shader_file": "",
|
||||||
"render_primative": moderngl.TRIANGLE_STRIP,
|
"render_primative": moderngl.TRIANGLE_STRIP,
|
||||||
"texture_path": "",
|
"texture_paths": None,
|
||||||
# Must match in attributes of vert shader
|
# Must match in attributes of vert shader
|
||||||
"shader_dtype": [
|
"shader_dtype": [
|
||||||
('point', np.float32, (3,)),
|
('point', np.float32, (3,)),
|
||||||
|
|
@ -1215,8 +1215,8 @@ 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,
|
||||||
texture_path=self.texture_path,
|
|
||||||
render_primative=self.render_primative,
|
render_primative=self.render_primative,
|
||||||
|
texture_paths=self.texture_paths,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_shader_data(self):
|
def get_shader_data(self):
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class ImageMobject(Mobject):
|
||||||
def __init__(self, filename, **kwargs):
|
def __init__(self, filename, **kwargs):
|
||||||
path = get_full_raster_image_path(filename)
|
path = get_full_raster_image_path(filename)
|
||||||
self.image = Image.open(path)
|
self.image = Image.open(path)
|
||||||
self.texture_path = path
|
self.texture_paths = {"Texture": path}
|
||||||
Mobject.__init__(self, **kwargs)
|
Mobject.__init__(self, **kwargs)
|
||||||
|
|
||||||
def init_points(self):
|
def init_points(self):
|
||||||
|
|
|
||||||
|
|
@ -167,12 +167,15 @@ class TexturedSurface(ParametricSurface):
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, uv_surface, filename, **kwargs):
|
def __init__(self, uv_surface, image_file, dark_image_file=None, **kwargs):
|
||||||
if not isinstance(uv_surface, ParametricSurface):
|
if not isinstance(uv_surface, ParametricSurface):
|
||||||
raise Exception("uv_surface must be of type ParametricSurface")
|
raise Exception("uv_surface must be of type ParametricSurface")
|
||||||
path = get_full_raster_image_path(filename)
|
if dark_image_file is None:
|
||||||
self.image = Image.open(path)
|
dark_image_file = image_file
|
||||||
self.texture_path = path
|
self.texture_paths = {
|
||||||
|
"LightTexture": get_full_raster_image_path(image_file),
|
||||||
|
"DarkTexture": get_full_raster_image_path(dark_image_file),
|
||||||
|
}
|
||||||
|
|
||||||
self.uv_surface = uv_surface
|
self.uv_surface = uv_surface
|
||||||
self.uv_func = uv_surface.uv_func
|
self.uv_func = uv_surface.uv_func
|
||||||
|
|
|
||||||
|
|
@ -827,14 +827,12 @@ 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,
|
||||||
texture_path=self.texture_path,
|
|
||||||
render_primative=self.render_primative,
|
render_primative=self.render_primative,
|
||||||
)
|
)
|
||||||
fill_info = get_shader_info(
|
fill_info = get_shader_info(
|
||||||
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,
|
||||||
texture_path=self.texture_path,
|
|
||||||
render_primative=self.render_primative,
|
render_primative=self.render_primative,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
uniform sampler2D Texture;
|
uniform sampler2D LightTexture;
|
||||||
|
uniform sampler2D DarkTexture;
|
||||||
uniform vec3 light_source_position;
|
uniform vec3 light_source_position;
|
||||||
|
|
||||||
in vec3 xyz_coords;
|
in vec3 xyz_coords;
|
||||||
|
|
@ -15,9 +16,17 @@ out vec4 frag_color;
|
||||||
#INSERT add_light.glsl
|
#INSERT add_light.glsl
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 im_color = texture(Texture, v_im_coords);
|
vec4 light_color = texture(LightTexture, v_im_coords);
|
||||||
|
vec4 dark_color = texture(DarkTexture, v_im_coords);
|
||||||
|
float dp = dot(
|
||||||
|
normalize(light_source_position - xyz_coords),
|
||||||
|
normalize(v_normal)
|
||||||
|
);
|
||||||
|
float alpha = smoothstep(-0.1, 0.1, dp);
|
||||||
|
vec4 color = mix(dark_color, light_color, alpha);
|
||||||
|
|
||||||
frag_color = add_light(
|
frag_color = add_light(
|
||||||
im_color,
|
color,
|
||||||
xyz_coords,
|
xyz_coords,
|
||||||
normalize(v_normal),
|
normalize(v_normal),
|
||||||
light_source_position,
|
light_source_position,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import os
|
||||||
import warnings
|
import warnings
|
||||||
import re
|
import re
|
||||||
import moderngl
|
import moderngl
|
||||||
|
import json
|
||||||
|
|
||||||
from manimlib.constants import SHADER_DIR
|
from manimlib.constants import SHADER_DIR
|
||||||
|
|
||||||
|
|
@ -13,11 +14,19 @@ from manimlib.constants import SHADER_DIR
|
||||||
|
|
||||||
|
|
||||||
SHADER_INFO_KEYS = [
|
SHADER_INFO_KEYS = [
|
||||||
|
# A structred array caring all of the points/color/lighting/etc. information
|
||||||
|
# needed for the shader.
|
||||||
"data",
|
"data",
|
||||||
|
# Filename of vetex shader
|
||||||
"vert",
|
"vert",
|
||||||
|
# Filename of geometry shader, if there is one
|
||||||
"geom",
|
"geom",
|
||||||
|
# Filename of fragment shader
|
||||||
"frag",
|
"frag",
|
||||||
"texture_path",
|
# A dictionary mapping names (as they show up in)
|
||||||
|
# the shader to filepaths for textures.
|
||||||
|
"texture_paths",
|
||||||
|
# E.g. moderngl.TRIANGLE_STRIP
|
||||||
"render_primative",
|
"render_primative",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -26,15 +35,18 @@ def get_shader_info(data=None,
|
||||||
vert_file=None,
|
vert_file=None,
|
||||||
geom_file=None,
|
geom_file=None,
|
||||||
frag_file=None,
|
frag_file=None,
|
||||||
texture_path=None,
|
render_primative=moderngl.TRIANGLE_STRIP,
|
||||||
render_primative=moderngl.TRIANGLE_STRIP):
|
texture_paths=None,
|
||||||
|
):
|
||||||
return {
|
return {
|
||||||
key: value
|
key: value
|
||||||
for key, value in zip(
|
for key, value in zip(
|
||||||
SHADER_INFO_KEYS,
|
SHADER_INFO_KEYS,
|
||||||
[
|
[
|
||||||
data, vert_file, geom_file, frag_file,
|
data,
|
||||||
texture_path, str(render_primative)
|
vert_file, geom_file, frag_file,
|
||||||
|
texture_paths or {},
|
||||||
|
str(render_primative)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -52,32 +64,23 @@ def is_valid_shader_info(shader_info):
|
||||||
def shader_info_to_id(shader_info):
|
def shader_info_to_id(shader_info):
|
||||||
# A unique id for a shader based on the
|
# A unique id for a shader based on the
|
||||||
# files holding its code and texture
|
# files holding its code and texture
|
||||||
return "|".join([
|
tuples = [
|
||||||
shader_info.get(key, "") or ""
|
(key, shader_info[key])
|
||||||
for key in SHADER_INFO_KEYS[1:]
|
for key in SHADER_INFO_KEYS[1:] # Skip data
|
||||||
])
|
]
|
||||||
|
return json.dumps(tuples)
|
||||||
|
|
||||||
|
|
||||||
def shader_id_to_info(sid):
|
def shader_id_to_info(sid):
|
||||||
return {
|
result = dict(json.loads(sid))
|
||||||
key: (value or None)
|
result["data"] = None
|
||||||
for key, value in zip(
|
return result
|
||||||
SHADER_INFO_KEYS,
|
|
||||||
[None, *sid.split("|")]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def same_shader_type(info1, info2):
|
def same_shader_type(info1, info2):
|
||||||
return all([
|
return all([
|
||||||
info1[key] == info2[key]
|
info1[key] == info2[key]
|
||||||
for key in [
|
for key in SHADER_INFO_KEYS[1:] # Skip data
|
||||||
"vert",
|
|
||||||
"geom",
|
|
||||||
"frag",
|
|
||||||
"texture_path",
|
|
||||||
"render_primative",
|
|
||||||
]
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue