15#ifndef GPUDISPLAYSHADERS_H
16#define GPUDISPLAYSHADERS_H
25layout (location = 0) in vec3 pos;
26uniform mat4 ModelViewProj;
30 gl_Position = ModelViewProj * vec4(pos.x, pos.y, pos.z, 1.0);
41 fragColor = vec4(color.x, color.y, color.z, 1.f);
47layout (location = 0) in vec4 vertex;
50uniform mat4 projection;
54 gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
55 TexCoords = vertex.zw;
69 color = vec4(texture(tex, TexCoords).rgb, alpha);
78uniform sampler2D text;
79uniform vec4 textColor;
83 vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
84 color = textColor * sampled;
90layout (location = 0) in vec3 pos;
93 gl_Position = vec4(pos, 1.0);
102#define DIMENSIONS {dimensions}
104#define SOL_Z_SEGS {solZSegs}
105#define SOL_P_SEGS {solPSegs}
106#define SOL_R_SEGS {solRSegs}
108#define SOL_PARAMS {solParams}
109#define SOL_ROWS {solRows}
110#define SOL_COLUMNS {solColumns}
111#define SOL_COEFFS {solCoeffs}
113#define DIP_Z_SEGS {dipZSegs}
114#define DIP_Y_SEGS {dipYSegs}
115#define DIP_X_SEGS {dipXSegs}
117#define DIP_PARAMS {dipParams}
118#define DIP_ROWS {dipRows}
119#define DIP_COLUMNS {dipColumns}
120#define DIP_COEFFS {dipCoeffs}
122#define MAX_CHEB_ORDER {maxChebOrder}
126layout(std430, binding = 0) restrict readonly buffer field_config_ssbo {
131layout(std430, binding = 1) restrict readonly buffer sol_segment_ssbo {
134 float MultiplicativeFactor;
138 float SegZSol[SOL_Z_SEGS];
140 int32_t BegSegPSol[SOL_Z_SEGS];
141 int32_t NSegPSol[SOL_Z_SEGS];
143 float SegPSol[SOL_P_SEGS];
144 int32_t BegSegRSol[SOL_P_SEGS];
145 int32_t NSegRSol[SOL_P_SEGS];
147 float SegRSol[SOL_R_SEGS];
148 int32_t SegIDSol[SOL_R_SEGS];
151layout(std430, binding = 2) restrict readonly buffer dip_segment_ssbo {
154 float MultiplicativeFactor;
158 float SegZDip[DIP_Z_SEGS];
160 int32_t BegSegYDip[DIP_Z_SEGS];
161 int32_t NSegYDip[DIP_Z_SEGS];
163 float SegYDip[DIP_Y_SEGS];
164 int32_t BegSegXDip[DIP_Y_SEGS];
165 int32_t NSegXDip[DIP_Y_SEGS];
167 float SegXDip[DIP_X_SEGS];
168 int32_t SegIDDip[DIP_X_SEGS];
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];
180 int32_t NColsAtRow[SOL_ROWS];
181 int32_t CofsAtColOffset[SOL_ROWS];
183 int32_t NCofsAtCol[SOL_COLUMNS];
184 int32_t AtColCoefOffset[SOL_COLUMNS];
186 float Coeffs[SOL_COEFFS];
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];
198 int32_t NColsAtRow[DIP_ROWS];
199 int32_t CofsAtColOffset[DIP_ROWS];
201 int32_t NCofsAtCol[DIP_COLUMNS];
202 int32_t AtColCoefOffset[DIP_COLUMNS];
204 float Coeffs[DIP_COEFFS];
207float tmpCfs1[MAX_CHEB_ORDER];
208float tmpCfs0[MAX_CHEB_ORDER];
210vec3 CarttoCyl(vec3 pos) {
211 return vec3(length(pos.xy), atan(pos.y, pos.x), pos.z);
214int32_t findSolSegment(vec3 pos) {
217 for(zid=0; zid < sol_segment.ZSegments; zid++) if(pos.z<sol_segment.SegZSol[zid]) break;
218 if(--zid < 0) zid = 0;
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;
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;
230 return sol_segment.SegIDSol[rid];
233int32_t findDipSegment(vec3 pos) {
236 for(zid=0; zid < dip_segment.ZSegments; zid++) if(pos.z<dip_segment.SegZDip[zid]) break;
237 if(--zid < 0) zid = 0;
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;
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;
249 return dip_segment.SegIDDip[xid];
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]);
257 return (rphiz-offsets)*scales;
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]);
265 return (pos-offsets)*scales;
268float cheb1DArray(float x, float arr[MAX_CHEB_ORDER], int32_t ncf) {
269 if(ncf <= 0) return 0.0f;
271 const float x2 = 2*x;
273 vec3 b = vec3(arr[--ncf], 0, 0);
276 const vec3 t1 = vec3(1, x2, -1);
278 for (int32_t i=ncf;i>=0;i--) {
284 const vec3 t = vec3(1, -x, 0);
288float cheb1DParamsSol(float x, int32_t coeff_offset, int32_t ncf) {
289 if(ncf <= 0) return 0.0f;
291 const float x2 = 2*x;
293 vec3 b = vec3(sol_params.Coeffs[coeff_offset + (--ncf)], 0, 0);
296 const vec3 t1 = vec3(1, x2, -1);
298 for (int32_t i=ncf;i>=0;i--) {
300 b.x = sol_params.Coeffs[coeff_offset + i];
304 const vec3 t = vec3(1, -x, 0);
308float cheb1DParamsDip(float x, int32_t coeff_offset, int32_t ncf) {
309 if(ncf <= 0) return 0.0f;
311 const float x2 = 2*x;
313 vec3 b = vec3(dip_params.Coeffs[coeff_offset + (--ncf)], 0, 0);
316 const vec3 t1 = vec3(1, x2, -1);
318 for (int32_t i=ncf;i>=0;i--) {
320 b.x = dip_params.Coeffs[coeff_offset + i];
324 const vec3 t = vec3(1, -x, 0);
328bool IsBetween(vec3 sMin, vec3 val, vec3 sMax) {
329 return all(lessThanEqual(sMin, val)) && all(lessThanEqual(val, sMax));
332bool IsInsideSol(int32_t segID, vec3 rphiz) {
333 const int32_t index = DIMENSIONS*segID;
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]);
338 return IsBetween(seg_min, rphiz, seg_max);
341bool IsInsideDip(int32_t segID, vec3 pos) {
342 const int32_t index = DIMENSIONS*segID;
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]);
347 return IsBetween(seg_min, pos, seg_max);
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];
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];
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];
364 const int32_t coeffs_offset = coeffs_at_row_offset + per_col_coeff_offset;
366 tmpCfs1[col] = cheb1DParamsSol(internal.z, coeffs_offset,n_coeffs);
368 tmpCfs0[row] = cheb1DArray(internal.y, tmpCfs1, n_cols);
371 return cheb1DArray(internal.x, tmpCfs0, n_rows);
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));
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];
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];
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];
393 const int32_t coeffs_offset = coeffs_at_row_offset + per_col_coeff_offset;
395 tmpCfs1[col] = cheb1DParamsDip(internal.z, coeffs_offset, n_coeffs);
397 tmpCfs0[row] = cheb1DArray(internal.y, tmpCfs1, n_cols);
400 return cheb1DArray(internal.x, tmpCfs0, n_rows);
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));
408vec3 CyltoCartCylB(vec3 rphiz, vec3 brphiz) {
409 const float btr = length(brphiz.xy);
410 const float psiPLUSphi = atan(brphiz.y, brphiz.x) + rphiz.y;
412 return vec3(btr*cos(psiPLUSphi), btr*sin(psiPLUSphi), brphiz.z);
415vec3 MachineField(vec3 pos) {
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;
429 const int32_t segID = findDipSegment(pos);
430 if(segID >= 0 && IsInsideDip(segID, pos)) {
431 return EvalDip(segID, pos) * dip_segment.MultiplicativeFactor;
437const float MinZ = dip_segment.MinZ;
438const float MaxZ = sol_segment.MaxZ;
440vec3 Field(vec3 pos) {
441 if(pos.z > MinZ && pos.z < MaxZ) {
442 return SolDipField(pos);
450layout (line_strip, max_vertices = 256) out;
452layout (binding = 0) uniform uniformMatrix { mat4 ModelViewProj; } um;
454const float positionScale = 100.0f;
457 vec3 position = gl_in[0].gl_Position.xyz;
459 for(uint32_t i = 0; i < field_config.StepCount; i++) {
460 gl_Position = um.ModelViewProj * vec4(position/positionScale, 1.0f);
462 const vec3 b_vec = Field(position);
463 position -= b_vec * field_config.StepSize;
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