Note
Go to the end to download the full example code
Varying Color#
This example shows how to use shaders to generate a shaded output. We will demonstrate how to load polydata then use a custom shader calls to render a custom shaded model. First, let’s import FURY
import fury
Let’s download and load the model
fury.data.fetch_viz_models()
model = fury.data.read_viz_models("utah.obj")
Dataset is already in place. If you want to fetch it again please first remove the folder /Users/skoudoro/.fury/models
Let’s start by loading the polydata of choice. For this example we use the standard utah teapot model. currently supported formats include OBJ, VTK, FIB, PLY, STL and XML
utah = fury.io.load_polydata(model)
utah = fury.utils.get_polymapper_from_polydata(utah)
utah = fury.utils.get_actor_from_polymapper(utah)
mapper = utah.GetMapper()
To change the default shader we add a shader replacement. Specify vertex shader using vtkShader.Vertex Specify fragment shader using vtkShader.Fragment
vertex_shader_code_decl = """
out vec4 myVertexVC;
"""
vertex_shader_code_impl = """
myVertexVC = vertexMC;
"""
fragment_shader_code_decl = """
uniform float time;
varying vec4 myVertexVC;
"""
fragment_shader_code_impl = """
vec2 iResolution = vec2(1024,720);
vec2 uv = myVertexVC.xy/iResolution;
vec3 col = 0.5 + 0.5 * cos((time/30) + uv.xyx + vec3(0, 2, 4));
fragOutput0 = vec4(col, fragOutput0.a);
"""
fury.shaders.shader_to_actor(
utah, "vertex", impl_code=vertex_shader_code_impl, decl_code=vertex_shader_code_decl
)
fury.shaders.shader_to_actor(utah, "fragment", decl_code=fragment_shader_code_decl)
fury.shaders.shader_to_actor(
utah, "fragment", impl_code=fragment_shader_code_impl, block="light"
)
Let’s create a scene.
The timer will call this user defined callback every 30 milliseconds.
The shader callback will update the color of our utah pot via the update of the timer variable.
1
Let’s add a textblock to the scene with a custom message
tb = fury.ui.TextBlock2D()
tb.message = "Hello Shaders"
Show Manager
Now that all the elements have been initialised, we add them to the show manager.
current_size = (1024, 720)
showm = fury.window.ShowManager(scene, size=current_size, reset_camera=False)
showm.add_timer_callback(True, 30, timer_callback)
scene.add(utah)
scene.add(tb)
interactive = False
if interactive:
showm.start()
fury.window.record(showm.scene, size=current_size, out_path="viz_shader.png")
/opt/homebrew/Caskroom/miniforge/base/envs/py39/lib/python3.9/site-packages/sphinx_gallery/gen_rst.py:722: UserWarning: We'll no longer accept the way you call the __init__ function in future versions of FURY.
Here's how to call the Function __init__: __init__(self_value, scene='value', title='value', size='value', png_magnify='value', reset_camera='value', order_transparent='value', interactor_style='value', stereo='value', multi_samples='value', max_peels='value', occlusion_ratio='value')
exec(self.code, self.fake_main.__dict__)
/opt/homebrew/Caskroom/miniforge/base/envs/py39/lib/python3.9/site-packages/sphinx_gallery/gen_rst.py:722: UserWarning: We'll no longer accept the way you call the record function in future versions of FURY.
Here's how to call the Function record: record(scene='value', cam_pos='value', cam_focal='value', cam_view='value', out_path='value', path_numbering='value', n_frames='value', az_ang='value', magnification='value', size='value', reset_camera='value', screen_clip='value', stereo='value', verbose='value')
exec(self.code, self.fake_main.__dict__)
Total running time of the script: (0 minutes 0.144 seconds)