-
-
Notifications
You must be signed in to change notification settings - Fork 132
/
shaders.py
212 lines (178 loc) · 5.99 KB
/
shaders.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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import gpu
from gpu.types import GPUShader, GPUShaderCreateInfo, GPUStageInterfaceInfo
from gpu.shader import create_from_info
from bpy import app
import sys
if sys.version_info >= (3, 9):
from functools import cache
else:
from functools import lru_cache
cache = lru_cache(maxsize=None)
class Shaders:
base_vertex_shader_3d = """
void main() {
gl_Position = ModelViewProjectionMatrix * vec4(pos.xyz, 1.0f);
vec2 ssPos = vec2(gl_Position.xy / gl_Position.w);
segment_start = stipple_pos = ssPos;
}
"""
base_fragment_shader_3d = """
void main() {
vec2 delta = stipple_pos - segment_start;
vec2 stipple_start;
if (abs(delta.x) > abs(delta.y)) {
stipple_start.x = 0;
float t = -segment_start.x / delta.x;
stipple_start.y = segment_start.y + t * delta.y;
}
else {
stipple_start.y = 0;
float t = -segment_start.y / delta.y;
stipple_start.x = segment_start.x + t * delta.x;
}
float distance_along_line = distance(stipple_pos, stipple_start);
float normalized_distance = fract(distance_along_line / dash_width);
if (dashed == true) {
if (normalized_distance <= dash_factor) {
discard;
}
else {
fragColor = color;
}
}
else {
fragColor = color;
}
}
"""
@classmethod
def get_base_shader_3d_info(cls):
vert_out = GPUStageInterfaceInfo("stipple_pos_interface")
vert_out.no_perspective("VEC2", "stipple_pos")
vert_out.flat("VEC2", "segment_start")
# NOTE: How to set default values?
shader_info = GPUShaderCreateInfo()
shader_info.push_constant("MAT4", "ModelViewProjectionMatrix")
shader_info.push_constant("VEC4", "color")
shader_info.push_constant("FLOAT", "dash_width")
shader_info.push_constant("FLOAT", "dash_factor")
# shader_info.push_constant("VEC2", "Viewport")
shader_info.push_constant("BOOL", "dashed")
shader_info.vertex_in(0, "VEC3", "pos")
shader_info.vertex_out(vert_out)
shader_info.fragment_out(0, "VEC4", "fragColor")
shader_info.vertex_source(cls.base_vertex_shader_3d)
shader_info.fragment_source(cls.base_fragment_shader_3d)
return shader_info
@staticmethod
@cache
def uniform_color_3d():
if app.version < (3, 5):
return gpu.shader.from_builtin("3D_UNIFORM_COLOR")
return gpu.shader.from_builtin("UNIFORM_COLOR")
@classmethod
@cache
def uniform_color_image_2d(cls):
vert_out = GPUStageInterfaceInfo("uniform_color_image_2d_interface")
vert_out.smooth("VEC2", "v_texCoord")
shader_info = GPUShaderCreateInfo()
shader_info.define("blender_srgb_to_framebuffer_space(a)", "a")
shader_info.push_constant("MAT4", "ModelViewProjectionMatrix")
shader_info.push_constant("VEC4", "color")
shader_info.vertex_in(0, "VEC2", "pos")
shader_info.vertex_in(1, "VEC2", "texCoord")
shader_info.sampler(0, "FLOAT_2D", "image")
shader_info.vertex_out(vert_out)
shader_info.fragment_out(0, "VEC4", "fragColor")
shader_info.vertex_source(
"""
void main()
{
gl_Position = (
ModelViewProjectionMatrix * vec4(pos.xy, 0.0f, 1.0f)
);
v_texCoord = texCoord;
}
"""
)
shader_info.fragment_source(
"""
void main()
{
fragColor = blender_srgb_to_framebuffer_space(
texture(image, v_texCoord) * color
);
}
"""
)
shader = create_from_info(shader_info)
del vert_out
del shader_info
return shader
@classmethod
@cache
def id_line_3d(cls):
shader = cls.uniform_color_line_3d()
return shader
@classmethod
@cache
def uniform_color_line_3d(cls):
shader_info = cls.get_base_shader_3d_info()
shader = create_from_info(shader_info)
del shader_info
return shader
@staticmethod
@cache
def id_shader_3d():
shader_info = GPUShaderCreateInfo()
shader_info.push_constant("MAT4", "ModelViewProjectionMatrix")
shader_info.push_constant("VEC4", "color")
shader_info.vertex_in(0, "VEC3", "pos")
shader_info.fragment_out(0, "VEC4", "fragColor")
shader_info.vertex_source(
"""
void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
}
"""
)
shader_info.fragment_source(
"""
void main()
{
fragColor = color;
}
"""
)
shader = create_from_info(shader_info)
del shader_info
return shader
@staticmethod
@cache
def dashed_uniform_color_3d():
vertex_shader = """
uniform mat4 ModelViewProjectionMatrix;
in vec3 pos;
in float arcLength;
out float v_ArcLength;
vec4 project = ModelViewProjectionMatrix * vec4(pos, 1.0f);
vec4 offset = vec4(0,0,-0.001,0);
void main()
{
v_ArcLength = arcLength;
gl_Position = project + offset;
}
"""
fragment_shader = """
uniform float u_Scale;
uniform vec4 color;
in float v_ArcLength;
out vec4 fragColor;
void main()
{
if (step(sin(v_ArcLength * u_Scale), 0.7) == 0) discard;
fragColor = color;
}
"""
return GPUShader(vertex_shader, fragment_shader)