/
viz_shader.py
164 lines (123 loc) · 3.91 KB
/
viz_shader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# -*- coding: utf-8 -*-
"""
=============
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, a bunch of imports.
"""
from fury import window, ui, io, utils
import vtk
###############################################################################
# Let's download and load the model
from fury.data.fetcher import fetch_viz_models, read_viz_models
fetch_viz_models()
model = read_viz_models('utah.obj')
###############################################################################
#
# Let's start by loading the polydata of choice.
# For this example we use the standard utah teapot model.
# currently supported formats include OBJ, VKT, FIB, PLY, STL and XML
utah = io.load_polydata(model)
utah = utils.get_polymapper_from_polydata(utah)
utah = 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
mapper.AddShaderReplacement(
vtk.vtkShader.Vertex,
"//VTK::ValuePass::Dec",
True,
"""
//VTK::ValuePass::Dec
out vec4 myVertexVC;
""",
False
)
mapper.AddShaderReplacement(
vtk.vtkShader.Vertex,
"//VTK::ValuePass::Impl",
True,
"""
//VTK::ValuePass::Impl
myVertexVC = vertexMC;
""",
False
)
mapper.AddShaderReplacement(
vtk.vtkShader.Fragment,
"//VTK::Light::Dec",
True,
"""
//VTK::Light::Dec
uniform float time;
varying vec4 myVertexVC;
""",
False
)
mapper.AddShaderReplacement(
vtk.vtkShader.Fragment,
'//VTK::Light::Impl',
True,
"""
//VTK::Light::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, 1.0);
""",
False
)
###############################################################################
# Let's create a scene.
scene = window.Scene()
global timer
timer = 0
##############################################################################
# The timer will call this user defined callback every 30 milliseconds.
def timer_callback(obj, event):
global timer
timer += 1.0
showm.render()
scene.azimuth(5)
###############################################################################
# We can use a decorator to callback to the shader.
@window.vtk.calldata_type(window.vtk.VTK_OBJECT)
def vtk_shader_callback(caller, event, calldata=None):
program = calldata
global timer
if program is not None:
try:
program.SetUniformf("time", timer)
except ValueError:
pass
###############################################################################
# Let's add a textblock to the scene with a custom message
tb = ui.TextBlock2D()
tb.message = "Hello Shaders"
###############################################################################
# Change the property of the actor
utah.GetProperty().SetOpacity(0.5)
###############################################################################
# Invoke callbacks to any VTK object
mapper.AddObserver(window.vtk.vtkCommand.UpdateShaderEvent,
vtk_shader_callback)
###############################################################################
# Show Manager
#
# Now that all the elements have been initialised, we add them to the show
# manager.
current_size = (1024, 720)
showm = window.ShowManager(scene, size=current_size, reset_camera=False)
showm.initialize()
showm.add_timer_callback(True, 30, timer_callback)
scene.add(utah)
scene.add(tb)
interactive = False
if interactive:
showm.start()
window.record(showm.scene, size=current_size, out_path="viz_shader.png")