Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with OpenGLSurface.color_by_code() and color_by_xyz_func() #4176

Open
Synchrones opened this issue Feb 22, 2025 · 1 comment
Open

Comments

@Synchrones
Copy link

Description of bug / unexpected behavior

I'm trying to color an OpenGLSurface based on coordinates and I noticed multiple issues with the differents methods :

  • the color_by_code() function can't do anything. Looking at the implementation, it seems that it's editing the shader_wrapper.program_code attribute to change the surface shader but the shader_wrapper attached to the mobject is re-initialised by the get_shader_wrapper() method of OpengGLSurface each time the mobject is rendered. This means that the shaders in the program_code attribute are reloaded from the files each frame which make it impossible to edit them.

  • editing directly the finalize_color.glsl shader file can effectively modify the surface color but the coordinates passed in the function seem to be screen space coordinates. Maybe it would be more usefull to put the "///// INSERT COLOR FUNCTION HERE /////" comment which is replaced by the users code in a function that has access to world space coordinates.

  • the color_by_xyz_func() method is using the get_colormap_list() method that does not exists

Expected behavior

How to reproduce the issue

Code for reproducing the problem
from manim import *
from manim.opengl import *
import numpy as np
class Test(Scene):
    def construct(self):
        surface = OpenGLSurface(lambda u, v: (u, v, np.cos(u) + np.sin(v)),
                                u_range=(-5, 5),
                                v_range=(-5, 5),
                                color=BLUE,
                                )
        self.play(Create(surface))
        surface.set_color_by_code("color = vec4(point.x, point.y, point.z, 1);")
        print(surface.get_shader_wrapper().program_code["fragment_shader"])
        self.interactive_embed()

Additional media files

Images/GIFs

Editing the finalize_color.glsl file is working but the coordinates are screen space coordinates :
Image

Logs

Terminal output

Part of printed program_code after modifying the shader with color_by_code(), the comment should have been replaced :

vec4 finalize_color(vec4 color,
                    vec3 point,
                    vec3 unit_normal,
                    vec3 light_coords,
                    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);
}

System specifications

System Details
  • OS (with version, e.g., Windows 10 v2004 or macOS 10.15 (Catalina)): Windows 10
  • RAM: 4Go
  • Python version (python/py/python3 --version): 3.9
  • Installed modules (provide output from pip list):
Package            Version
------------------ -----------
asttokens          3.0.0
av                 13.1.0
beautifulsoup4     4.13.3
click              8.1.8
cloup              3.0.5
colorama           0.4.6
decorator          5.1.1
exceptiongroup     1.2.2
executing          2.2.0
glcontext          3.0.0
importlib_metadata 8.6.1
ipython            8.18.1
isosurfaces        0.1.2
jedi               0.19.2
manim              0.19.0
ManimPango         0.6.0
mapbox_earcut      1.0.3
markdown-it-py     3.0.0
matplotlib-inline  0.1.7
mdurl              0.1.2
moderngl           5.12.0
moderngl-window    3.1.1
networkx           3.2.1
numpy              2.0.2
parso              0.8.4
pillow             11.1.0
pip                23.2.1
prompt_toolkit     3.0.50
pure_eval          0.2.3
pycairo            1.27.0
pydub              0.25.1
pyglet             2.1.2
pyglm              2.8.0
Pygments           2.19.1
rich               13.9.4
scipy              1.13.1
screeninfo         0.8.1
setuptools         68.2.0
skia-pathops       0.8.0.post2
soupsieve          2.6
srt                3.5.3
stack-data         0.6.3
svgelements        1.9.6
tqdm               4.67.1
traitlets          5.14.3
typing_extensions  4.12.2
watchdog           6.0.0
wcwidth            0.2.13
wheel              0.41.2
zipp               3.21.0

LaTeX details
  • LaTeX distribution (e.g. TeX Live 2020):
  • Installed LaTeX packages:

Additional comments

@Synchrones
Copy link
Author

Synchrones commented Mar 2, 2025

I looked bit more at the code and it seems that the program_code attribute is not used in the rendering process. The only thing that could be modified in the shader_wrapper to change the color of the surface is the shader_folder attribute because the shaders attached to the surfaces are reloaded from a cache with the shader folder name each frame.
I also noticed that the get_shader_wrapper method has this commented code :
if hasattr(self, "__shader_wrapper"): return self.__shader_wrapper
It would prevent the shader_wrapper from being reloaded each time the method is called but uncommenting it cause the surface to render incorrectly.
I ended up adding a reload_shader_wrapper method to reload the shader_wrapper of the surface after creating it which is working. I then modify the shader_folder attribute to redirect the renderer to a custom folder containing my shaders. It's a temporary solution but I don't know how else to do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant