Project
Loading...
Searching...
No Matches
GPUDisplayShaders.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#ifndef GPUDISPLAYSHADERS_H
16#define GPUDISPLAYSHADERS_H
17
18#include "GPUCommonDef.h"
19namespace o2::gpu
20{
21
23 static constexpr const char* vertexShader = R"(
24#version 450 core
25layout (location = 0) in vec3 pos;
26uniform mat4 ModelViewProj;
27
28void main()
29{
30 gl_Position = ModelViewProj * vec4(pos.x, pos.y, pos.z, 1.0);
31}
32)";
33
34 static constexpr const char* fragmentShader = R"(
35#version 450 core
36out vec4 fragColor;
37uniform vec4 color;
38
39void main()
40{
41 fragColor = vec4(color.x, color.y, color.z, 1.f);
42}
43)";
44
45 static constexpr const char* vertexShaderTexture = R"(
46#version 450 core
47layout (location = 0) in vec4 vertex;
48out vec2 TexCoords;
49
50uniform mat4 projection;
51
52void main()
53{
54 gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
55 TexCoords = vertex.zw;
56}
57)";
58
59 static constexpr const char* fragmentShaderTexture = R"(
60#version 450 core
61in vec2 TexCoords;
62out vec4 color;
63
64uniform sampler2D tex;
65uniform float alpha;
66
67void main()
68{
69 color = vec4(texture(tex, TexCoords).rgb, alpha);
70}
71)";
72
73 static constexpr const char* fragmentShaderText = R"(
74#version 450 core
75in vec2 TexCoords;
76out vec4 color;
77
78uniform sampler2D text;
79uniform vec4 textColor;
80
81void main()
82{
83 vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
84 color = textColor * sampled;
85}
86)";
87
88 static constexpr const char* vertexShaderPassthrough = R"(
89#version 450 core
90layout (location = 0) in vec3 pos;
91void main()
92{
93 gl_Position = vec4(pos, 1.0);
94}
95)";
96
97 static constexpr const char* geometryShaderP1 = R"(
98 #version 450 core
99)";
101 static constexpr const char* fieldModelShaderConstants = R"(
102#define DIMENSIONS {dimensions}
103
104#define SOL_Z_SEGS {solZSegs}
105#define SOL_P_SEGS {solPSegs}
106#define SOL_R_SEGS {solRSegs}
107
108#define SOL_PARAMS {solParams}
109#define SOL_ROWS {solRows}
110#define SOL_COLUMNS {solColumns}
111#define SOL_COEFFS {solCoeffs}
112
113#define DIP_Z_SEGS {dipZSegs}
114#define DIP_Y_SEGS {dipYSegs}
115#define DIP_X_SEGS {dipXSegs}
116
117#define DIP_PARAMS {dipParams}
118#define DIP_ROWS {dipRows}
119#define DIP_COLUMNS {dipColumns}
120#define DIP_COEFFS {dipCoeffs}
121
122#define MAX_CHEB_ORDER {maxChebOrder}
123)";
125 static constexpr const char* fieldModelShaderCode = R"(
126layout(std430, binding = 0) restrict readonly buffer field_config_ssbo {
127 uint32_t StepCount;
128 float StepSize;
129} field_config;
130
131layout(std430, binding = 1) restrict readonly buffer sol_segment_ssbo {
132 float MinZ;
133 float MaxZ;
134 float MultiplicativeFactor;
135
136 int32_t ZSegments;
137
138 float SegZSol[SOL_Z_SEGS];
139
140 int32_t BegSegPSol[SOL_Z_SEGS];
141 int32_t NSegPSol[SOL_Z_SEGS];
142
143 float SegPSol[SOL_P_SEGS];
144 int32_t BegSegRSol[SOL_P_SEGS];
145 int32_t NSegRSol[SOL_P_SEGS];
146
147 float SegRSol[SOL_R_SEGS];
148 int32_t SegIDSol[SOL_R_SEGS];
149} sol_segment;
150
151layout(std430, binding = 2) restrict readonly buffer dip_segment_ssbo {
152 float MinZ;
153 float MaxZ;
154 float MultiplicativeFactor;
155
156 int32_t ZSegments;
157
158 float SegZDip[DIP_Z_SEGS];
159
160 int32_t BegSegYDip[DIP_Z_SEGS];
161 int32_t NSegYDip[DIP_Z_SEGS];
162
163 float SegYDip[DIP_Y_SEGS];
164 int32_t BegSegXDip[DIP_Y_SEGS];
165 int32_t NSegXDip[DIP_Y_SEGS];
166
167 float SegXDip[DIP_X_SEGS];
168 int32_t SegIDDip[DIP_X_SEGS];
169} dip_segment;
170
171layout(std430, binding = 3) restrict readonly buffer sol_params_ssbo {
172 float BOffsets[DIMENSIONS*SOL_PARAMS];
173 float BScales[DIMENSIONS*SOL_PARAMS];
174 float BMin[DIMENSIONS*SOL_PARAMS];
175 float BMax[DIMENSIONS*SOL_PARAMS];
176 int32_t NRows[DIMENSIONS*SOL_PARAMS];
177 int32_t ColsAtRowOffset[DIMENSIONS*SOL_PARAMS];
178 int32_t CofsAtRowOffset[DIMENSIONS*SOL_PARAMS];
179
180 int32_t NColsAtRow[SOL_ROWS];
181 int32_t CofsAtColOffset[SOL_ROWS];
182
183 int32_t NCofsAtCol[SOL_COLUMNS];
184 int32_t AtColCoefOffset[SOL_COLUMNS];
185
186 float Coeffs[SOL_COEFFS];
187} sol_params;
188
189layout(std430, binding = 4) restrict readonly buffer dip_params_ssbo {
190 float BOffsets[DIMENSIONS*DIP_PARAMS];
191 float BScales[DIMENSIONS*DIP_PARAMS];
192 float BMin[DIMENSIONS*DIP_PARAMS];
193 float BMax[DIMENSIONS*DIP_PARAMS];
194 int32_t NRows[DIMENSIONS*DIP_PARAMS];
195 int32_t ColsAtRowOffset[DIMENSIONS*DIP_PARAMS];
196 int32_t CofsAtRowOffset[DIMENSIONS*DIP_PARAMS];
197
198 int32_t NColsAtRow[DIP_ROWS];
199 int32_t CofsAtColOffset[DIP_ROWS];
200
201 int32_t NCofsAtCol[DIP_COLUMNS];
202 int32_t AtColCoefOffset[DIP_COLUMNS];
203
204 float Coeffs[DIP_COEFFS];
205} dip_params;
206
207float tmpCfs1[MAX_CHEB_ORDER];
208float tmpCfs0[MAX_CHEB_ORDER];
209
210vec3 CarttoCyl(vec3 pos) {
211 return vec3(length(pos.xy), atan(pos.y, pos.x), pos.z);
212}
213
214int32_t findSolSegment(vec3 pos) {
215 int32_t rid,pid,zid;
216
217 for(zid=0; zid < sol_segment.ZSegments; zid++) if(pos.z<sol_segment.SegZSol[zid]) break;
218 if(--zid < 0) zid = 0;
219
220 const int32_t psegBeg = sol_segment.BegSegPSol[zid];
221 for(pid=0; pid<sol_segment.NSegPSol[zid]; pid++) if(pos.y<sol_segment.SegPSol[psegBeg+pid]) break;
222 if(--pid < 0) pid = 0;
223 pid += psegBeg;
224
225 const int32_t rsegBeg = sol_segment.BegSegRSol[pid];
226 for(rid=0; rid<sol_segment.NSegRSol[pid]; rid++) if(pos.x<sol_segment.SegRSol[rsegBeg+rid]) break;
227 if(--rid < 0) rid = 0;
228 rid += rsegBeg;
229
230 return sol_segment.SegIDSol[rid];
231}
232
233int32_t findDipSegment(vec3 pos) {
234 int32_t xid,yid,zid;
235
236 for(zid=0; zid < dip_segment.ZSegments; zid++) if(pos.z<dip_segment.SegZDip[zid]) break;
237 if(--zid < 0) zid = 0;
238
239 const int32_t ysegBeg = dip_segment.BegSegYDip[zid];
240 for(yid=0; yid<dip_segment.NSegYDip[zid]; yid++) if(pos.y<dip_segment.SegYDip[ysegBeg+yid]) break;
241 if(--yid < 0) yid = 0;
242 yid += ysegBeg;
243
244 const int32_t xsegBeg = dip_segment.BegSegXDip[yid];
245 for(xid=0; xid<dip_segment.NSegXDip[yid]; xid++) if(pos.x<dip_segment.SegXDip[xsegBeg+xid]) break;
246 if(--xid < 0) xid = 0;
247 xid += xsegBeg;
248
249 return dip_segment.SegIDDip[xid];
250}
251
252vec3 mapToInternalSol(int32_t segID, vec3 rphiz) {
253 const int32_t index = DIMENSIONS*segID;
254 vec3 offsets = vec3(sol_params.BOffsets[index+0], sol_params.BOffsets[index+1], sol_params.BOffsets[index+2]);
255 vec3 scales = vec3(sol_params.BScales[index+0], sol_params.BScales[index+1], sol_params.BScales[index+2]);
256
257 return (rphiz-offsets)*scales;
258}
259
260vec3 mapToInternalDip(int32_t segID, vec3 pos) {
261 const int32_t index = DIMENSIONS*segID;
262 const vec3 offsets = vec3(dip_params.BOffsets[index+0], dip_params.BOffsets[index+1], dip_params.BOffsets[index+2]);
263 const vec3 scales = vec3(dip_params.BScales[index+0], dip_params.BScales[index+1], dip_params.BScales[index+2]);
264
265 return (pos-offsets)*scales;
266}
267
268float cheb1DArray(float x, float arr[MAX_CHEB_ORDER], int32_t ncf) {
269 if(ncf <= 0) return 0.0f;
270
271 const float x2 = 2*x;
272
273 vec3 b = vec3(arr[--ncf], 0, 0);
274 --ncf;
275
276 const vec3 t1 = vec3(1, x2, -1);
277
278 for (int32_t i=ncf;i>=0;i--) {
279 b.zy = b.yx;
280 b.x = arr[i];
281 b.x = dot(t1, b);
282 }
283
284 const vec3 t = vec3(1, -x, 0);
285 return dot(t, b);
286}
287
288float cheb1DParamsSol(float x, int32_t coeff_offset, int32_t ncf) {
289 if(ncf <= 0) return 0.0f;
290
291 const float x2 = 2*x;
292
293 vec3 b = vec3(sol_params.Coeffs[coeff_offset + (--ncf)], 0, 0);
294 --ncf;
295
296 const vec3 t1 = vec3(1, x2, -1);
297
298 for (int32_t i=ncf;i>=0;i--) {
299 b.zy = b.yx;
300 b.x = sol_params.Coeffs[coeff_offset + i];
301 b.x = dot(t1, b);
302 }
303
304 const vec3 t = vec3(1, -x, 0);
305 return dot(t, b);
306}
307
308float cheb1DParamsDip(float x, int32_t coeff_offset, int32_t ncf) {
309 if(ncf <= 0) return 0.0f;
310
311 const float x2 = 2*x;
312
313 vec3 b = vec3(dip_params.Coeffs[coeff_offset + (--ncf)], 0, 0);
314 --ncf;
315
316 const vec3 t1 = vec3(1, x2, -1);
317
318 for (int32_t i=ncf;i>=0;i--) {
319 b.zy = b.yx;
320 b.x = dip_params.Coeffs[coeff_offset + i];
321 b.x = dot(t1, b);
322 }
323
324 const vec3 t = vec3(1, -x, 0);
325 return dot(t, b);
326}
327
328bool IsBetween(vec3 sMin, vec3 val, vec3 sMax) {
329 return all(lessThanEqual(sMin, val)) && all(lessThanEqual(val, sMax));
330}
331
332bool IsInsideSol(int32_t segID, vec3 rphiz) {
333 const int32_t index = DIMENSIONS*segID;
334
335 const vec3 seg_min = vec3(sol_params.BMin[index+0], sol_params.BMin[index+1], sol_params.BMin[index+2]);
336 const vec3 seg_max = vec3(sol_params.BMax[index+0], sol_params.BMax[index+1], sol_params.BMax[index+2]);
337
338 return IsBetween(seg_min, rphiz, seg_max);
339}
340
341bool IsInsideDip(int32_t segID, vec3 pos) {
342 const int32_t index = DIMENSIONS*segID;
343
344 const vec3 seg_min = vec3(dip_params.BMin[index+0], dip_params.BMin[index+1], dip_params.BMin[index+2]);
345 const vec3 seg_max = vec3(dip_params.BMax[index+0], dip_params.BMax[index+1], dip_params.BMax[index+2]);
346
347 return IsBetween(seg_min, pos, seg_max);
348}
349
350float Eval3DSol(int32_t segID, int32_t dim, vec3 internal) {
351 const int32_t index = DIMENSIONS*segID;
352 const int32_t n_rows = sol_params.NRows[index+dim];
353 const int32_t cols_at_row_offset = sol_params.ColsAtRowOffset[index+dim];
354 const int32_t coeffs_at_row_offset = sol_params.CofsAtRowOffset[index+dim];
355
356 for(int32_t row = 0; row < n_rows; row++) {
357 const int32_t n_cols = sol_params.NColsAtRow[cols_at_row_offset+row];
358 const int32_t coeff_at_col_offset = sol_params.CofsAtColOffset[cols_at_row_offset+row];
359
360 for(int32_t col = 0; col < n_cols; col++) {
361 const int32_t n_coeffs = sol_params.NCofsAtCol[coeff_at_col_offset+col];
362 const int32_t per_col_coeff_offset = sol_params.AtColCoefOffset[coeff_at_col_offset+col];
363
364 const int32_t coeffs_offset = coeffs_at_row_offset + per_col_coeff_offset;
365
366 tmpCfs1[col] = cheb1DParamsSol(internal.z, coeffs_offset,n_coeffs);
367 }
368 tmpCfs0[row] = cheb1DArray(internal.y, tmpCfs1, n_cols);
369 }
370
371 return cheb1DArray(internal.x, tmpCfs0, n_rows);
372}
373
374vec3 EvalSol(int32_t segID, vec3 rphiz) {
375 const vec3 internal = mapToInternalSol(segID, rphiz);
376 return vec3(Eval3DSol(segID, 0, internal), Eval3DSol(segID, 1, internal), Eval3DSol(segID, 2, internal));
377}
378
379float Eval3DDip(int32_t segID, int32_t dim, vec3 internal) {
380 const int32_t index = DIMENSIONS*segID;
381 const int32_t n_rows = dip_params.NRows[index+dim];
382 const int32_t cols_at_row_offset = dip_params.ColsAtRowOffset[index+dim];
383 const int32_t coeffs_at_row_offset = dip_params.CofsAtRowOffset[index+dim];
384
385 for(int32_t row = 0; row < n_rows; row++) {
386 const int32_t n_cols = dip_params.NColsAtRow[cols_at_row_offset+row];
387 const int32_t coeff_at_col_offset = dip_params.CofsAtColOffset[cols_at_row_offset+row];
388
389 for(int32_t col = 0; col < n_cols; col++) {
390 const int32_t n_coeffs = dip_params.NCofsAtCol[coeff_at_col_offset+col];
391 const int32_t per_col_coeff_offset = dip_params.AtColCoefOffset[coeff_at_col_offset+col];
392
393 const int32_t coeffs_offset = coeffs_at_row_offset + per_col_coeff_offset;
394
395 tmpCfs1[col] = cheb1DParamsDip(internal.z, coeffs_offset, n_coeffs);
396 }
397 tmpCfs0[row] = cheb1DArray(internal.y, tmpCfs1, n_cols);
398 }
399
400 return cheb1DArray(internal.x, tmpCfs0, n_rows);
401}
402
403vec3 EvalDip(int32_t segID, vec3 pos) {
404 const vec3 internal = mapToInternalDip(segID, pos);
405 return vec3(Eval3DDip(segID, 0, internal), Eval3DDip(segID, 1, internal), Eval3DDip(segID, 2, internal));
406}
407
408vec3 CyltoCartCylB(vec3 rphiz, vec3 brphiz) {
409 const float btr = length(brphiz.xy);
410 const float psiPLUSphi = atan(brphiz.y, brphiz.x) + rphiz.y;
411
412 return vec3(btr*cos(psiPLUSphi), btr*sin(psiPLUSphi), brphiz.z);
413}
414
415vec3 MachineField(vec3 pos) {
416 return vec3(0);
417}
418
419vec3 SolDipField(vec3 pos) {
420 if(pos.z > sol_segment.MinZ) {
421 const vec3 rphiz = CarttoCyl(pos);
422 const int32_t segID = findSolSegment(rphiz);
423 if(segID >=0 && IsInsideSol(segID, rphiz)) {
424 const vec3 brphiz = EvalSol(segID, rphiz);
425 return CyltoCartCylB(rphiz, brphiz) * sol_segment.MultiplicativeFactor;
426 }
427 }
428
429 const int32_t segID = findDipSegment(pos);
430 if(segID >= 0 && IsInsideDip(segID, pos)) {
431 return EvalDip(segID, pos) * dip_segment.MultiplicativeFactor;
432 }
433
434 return vec3(0);
435}
436
437const float MinZ = dip_segment.MinZ;
438const float MaxZ = sol_segment.MaxZ;
439
440vec3 Field(vec3 pos) {
441 if(pos.z > MinZ && pos.z < MaxZ) {
442 return SolDipField(pos);
443 }
444 return vec3(0);
445}
446)";
448 static constexpr const char* geometryShaderP2 = R"(
449layout (points) in;
450layout (line_strip, max_vertices = 256) out;
451
452layout (binding = 0) uniform uniformMatrix { mat4 ModelViewProj; } um;
453
454const float positionScale = 100.0f;
455
456void main() {
457 vec3 position = gl_in[0].gl_Position.xyz;
458
459 for(uint32_t i = 0; i < field_config.StepCount; i++) {
460 gl_Position = um.ModelViewProj * vec4(position/positionScale, 1.0f);
461 EmitVertex();
462 const vec3 b_vec = Field(position);
463 position -= b_vec * field_config.StepSize;
464 }
465 EndPrimitive();
466}
467)";
468};
469} // namespace o2::gpu
470
471#endif
static constexpr const char * vertexShaderTexture
static constexpr const char * vertexShaderPassthrough
static constexpr const char * geometryShaderP2
static constexpr const char * fieldModelShaderConstants
static constexpr const char * vertexShader
static constexpr const char * geometryShaderP1
static constexpr const char * fragmentShaderText
static constexpr const char * fieldModelShaderCode
static constexpr const char * fragmentShader
static constexpr const char * fragmentShaderTexture