@eturnity/eturnity_3d 8.16.0 → 8.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/Overlay/ImageOverlay.js +16 -139
- package/src/Overlay/Overlay.js +115 -14
- package/src/Overlay/OverlayFactory.js +3 -0
- package/src/Overlay/OverlayLayer.js +6 -0
- package/src/Overlay/ThreeDModelOverlay.js +16 -122
- package/src/Overlay/YearlySunShadingOverlay.js +368 -0
- package/src/helper/render/imageOverlay.js +23 -9
- package/src/helper/render/moduleField.js +12 -2
- package/src/helper/render/overlay.js +61 -5
- package/src/helper/render/projectionMaterial.js +2 -0
- package/src/helper/render/roof.js +0 -1
- package/src/helper/render/shadingMaterial/ShadingImageGenerator.js +241 -0
- package/src/helper/render/shadingMaterial/helper.js +109 -0
- package/src/helper/render/shadingMaterial/yearlySunShaderMaterial.js +389 -0
- package/src/helper/renderMixin.js +17 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import * as THREE from 'three'
|
|
2
|
+
import { getOptimizedGHI } from '@eturnity/eturnity_maths'
|
|
3
|
+
export default class yearlySunShaderMaterial extends THREE.MeshPhysicalMaterial {
|
|
4
|
+
constructor(parameters) {
|
|
5
|
+
const {
|
|
6
|
+
lat,
|
|
7
|
+
lng,
|
|
8
|
+
dataGrids,
|
|
9
|
+
normalVector,
|
|
10
|
+
colorfull = true,
|
|
11
|
+
// Default grayscale colormap
|
|
12
|
+
colorMap = [
|
|
13
|
+
{ value: 0, color: { r: 255, g: 255, b: 255 } },
|
|
14
|
+
{ value: 1.0, color: { r: 0, g: 0, b: 0 } },
|
|
15
|
+
],
|
|
16
|
+
isShadingFactor = false,
|
|
17
|
+
edges = [],
|
|
18
|
+
...otherParameters
|
|
19
|
+
} = parameters
|
|
20
|
+
super(otherParameters)
|
|
21
|
+
this.normalVector = normalVector
|
|
22
|
+
this.MAX_EDGES_LENGTH = 500
|
|
23
|
+
this.needsUpdate = true
|
|
24
|
+
this.horizonResolution = this.dataGrids?.horizon?.length || 36
|
|
25
|
+
this.latitude = lat
|
|
26
|
+
this.longitude = lng
|
|
27
|
+
this.colorfull = colorfull
|
|
28
|
+
this.isShadingFactor = isShadingFactor
|
|
29
|
+
this.dataGrids = dataGrids
|
|
30
|
+
this.edges = edges
|
|
31
|
+
this.colorMap = [...colorMap].sort((a, b) => a.value - b.value)
|
|
32
|
+
let maxDNI = 0
|
|
33
|
+
this.dataGrids.dni_grid.forEach((dni_row) =>
|
|
34
|
+
dni_row.forEach((dni) => {
|
|
35
|
+
if (dni > maxDNI) {
|
|
36
|
+
maxDNI = dni
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
)
|
|
40
|
+
let maxDHI = 0
|
|
41
|
+
this.dataGrids.dhi_grid.forEach((dhi_row) =>
|
|
42
|
+
dhi_row.forEach((dhi) => (maxDHI = maxDHI > dhi ? maxDHI : dhi))
|
|
43
|
+
)
|
|
44
|
+
// Normalize DNI values using maxDNI
|
|
45
|
+
const normalizedDNIGrid = this.dataGrids.dni_grid.map((row) =>
|
|
46
|
+
row.map((dni) => dni / maxDNI)
|
|
47
|
+
)
|
|
48
|
+
const normalizedDHIGrid = this.dataGrids.dhi_grid.map((row) =>
|
|
49
|
+
row.map((dhi) => dhi / maxDHI)
|
|
50
|
+
)
|
|
51
|
+
const dniTexture = new THREE.DataTexture(
|
|
52
|
+
new Float32Array(normalizedDNIGrid.flat()),
|
|
53
|
+
this.dataGrids.dni_grid[0].length,
|
|
54
|
+
this.dataGrids.dni_grid.length,
|
|
55
|
+
THREE.RedFormat,
|
|
56
|
+
THREE.FloatType
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
const dhiTexture = new THREE.DataTexture(
|
|
60
|
+
new Float32Array(normalizedDHIGrid.flat()),
|
|
61
|
+
this.dataGrids.dhi_grid[0].length,
|
|
62
|
+
this.dataGrids.dhi_grid.length,
|
|
63
|
+
THREE.RedFormat,
|
|
64
|
+
THREE.FloatType
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
const horizonTexture = new THREE.DataTexture(
|
|
68
|
+
new Float32Array(this.dataGrids.horizon),
|
|
69
|
+
this.horizonResolution,
|
|
70
|
+
1,
|
|
71
|
+
THREE.RedFormat,
|
|
72
|
+
THREE.FloatType
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
dniTexture.needsUpdate = true
|
|
76
|
+
dhiTexture.needsUpdate = true
|
|
77
|
+
horizonTexture.needsUpdate = true
|
|
78
|
+
|
|
79
|
+
// Compute highest GHI
|
|
80
|
+
let highestGHI = getOptimizedGHI({
|
|
81
|
+
dataGrids: this.dataGrids,
|
|
82
|
+
lat,
|
|
83
|
+
lng,
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const flattenedEdges = this.edges.flat().flatMap((v) => [v.x, v.y, v.z])
|
|
87
|
+
|
|
88
|
+
const stopValues = this.colorMap.map((stop) => stop.value)
|
|
89
|
+
const colorStops = this.colorMap
|
|
90
|
+
.map((stop) => {
|
|
91
|
+
const { r, g, b } = stop.color
|
|
92
|
+
return [r / 255, g / 255, b / 255]
|
|
93
|
+
})
|
|
94
|
+
.flat()
|
|
95
|
+
|
|
96
|
+
this.uniforms = {
|
|
97
|
+
gridsDNI: { value: dniTexture },
|
|
98
|
+
gridsDHI: { value: dhiTexture },
|
|
99
|
+
maxDNI: { value: maxDNI },
|
|
100
|
+
maxDHI: { value: maxDHI },
|
|
101
|
+
highestGHI: { value: highestGHI },
|
|
102
|
+
hasNormalVector: { value: this.normalVector ? 1 : 0 },
|
|
103
|
+
normalVector: {
|
|
104
|
+
value: this.normalVector ? this.normalVector : [0, 0, 0],
|
|
105
|
+
},
|
|
106
|
+
edges: { value: new Float32Array(flattenedEdges) },
|
|
107
|
+
horizon: { value: horizonTexture },
|
|
108
|
+
edgesLength: { value: this.edges.length },
|
|
109
|
+
colorfull: { value: this.colorfull ? 1 : 0 },
|
|
110
|
+
stopValues: { value: new Float32Array(stopValues) },
|
|
111
|
+
colorStops: {
|
|
112
|
+
value: new Float32Array(colorStops),
|
|
113
|
+
},
|
|
114
|
+
stopCount: { value: this.colorMap.length },
|
|
115
|
+
isShadingFactor: { value: this.isShadingFactor ? 1 : 0 },
|
|
116
|
+
}
|
|
117
|
+
this.count = 0
|
|
118
|
+
this.onBeforeCompile = this.onBeforeCompile.bind(this)
|
|
119
|
+
}
|
|
120
|
+
updateEdges(newEdges) {
|
|
121
|
+
if (newEdges.length == 0) {
|
|
122
|
+
newEdges = [
|
|
123
|
+
[
|
|
124
|
+
{ x: 0, y: 0, z: 0 },
|
|
125
|
+
{ x: 0, y: 0, z: 0 },
|
|
126
|
+
],
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
if (this.MAX_EDGES_LENGTH < newEdges.length) {
|
|
130
|
+
console.warn(
|
|
131
|
+
`Reduced edges from ${this.edges.length} to ${newEdges.length} to fit within MAX_EDGES_LENGTH (${this.MAX_EDGES_LENGTH})`
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
// Ensure we don't exceed MAX_EDGES_LENGTH
|
|
135
|
+
if (newEdges.length > this.MAX_EDGES_LENGTH) {
|
|
136
|
+
newEdges = newEdges.slice(0, this.MAX_EDGES_LENGTH)
|
|
137
|
+
}
|
|
138
|
+
this.edges = [...newEdges]
|
|
139
|
+
const flattenedEdges = newEdges.flat().flatMap((v) => [v.x, v.y, v.z])
|
|
140
|
+
this.uniforms.edges = { value: new Float32Array(flattenedEdges) }
|
|
141
|
+
this.uniforms.edgesLength = { value: newEdges.length }
|
|
142
|
+
this.needsUpdate = true
|
|
143
|
+
// Manually trigger recompilation
|
|
144
|
+
}
|
|
145
|
+
onBeforeCompile(shader) {
|
|
146
|
+
this.needsUpdate = true
|
|
147
|
+
Object.assign(this.uniforms, shader.uniforms)
|
|
148
|
+
shader.uniforms = this.uniforms
|
|
149
|
+
const flattenedEdges = this.edges.flat().flatMap((v) => [v.x, v.y, v.z])
|
|
150
|
+
shader.uniforms.edges = {
|
|
151
|
+
value: new Float32Array(flattenedEdges),
|
|
152
|
+
}
|
|
153
|
+
shader.uniforms.edgesLength = { value: this.edges.length }
|
|
154
|
+
this.compiledEdgesLength = this.edges.length
|
|
155
|
+
const vertexShader = `
|
|
156
|
+
varying vec4 vPosition;
|
|
157
|
+
varying vec2 screenPosition;
|
|
158
|
+
varying vec3 vNormal;
|
|
159
|
+
uniform int hasNormalVector;
|
|
160
|
+
uniform vec3 normalVector;
|
|
161
|
+
void main() {
|
|
162
|
+
vPosition = modelMatrix * vec4(position, 1.0);
|
|
163
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
164
|
+
screenPosition = gl_Position.xy;
|
|
165
|
+
vNormal = normalize((modelMatrix * vec4(normal, 0.0)).xyz);
|
|
166
|
+
if(hasNormalVector == 1){
|
|
167
|
+
vNormal = normalize(normalVector);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
`
|
|
172
|
+
const fragmentShader = `
|
|
173
|
+
uniform sampler2D gridsDNI;
|
|
174
|
+
uniform sampler2D gridsDHI;
|
|
175
|
+
uniform float maxDNI;
|
|
176
|
+
uniform float maxDHI;
|
|
177
|
+
uniform float highestGHI;
|
|
178
|
+
uniform vec3 edges[${this.MAX_EDGES_LENGTH * 2}];
|
|
179
|
+
uniform sampler2D horizon;
|
|
180
|
+
uniform int edgesLength;
|
|
181
|
+
uniform int colorfull;
|
|
182
|
+
uniform int isShadingFactor;
|
|
183
|
+
uniform int stopCount;
|
|
184
|
+
uniform float stopValues[${this.colorMap.length}];
|
|
185
|
+
uniform vec3 colorStops[${this.colorMap.length}];
|
|
186
|
+
varying vec3 vNormal;
|
|
187
|
+
varying vec2 screenPosition;
|
|
188
|
+
varying vec4 vPosition;
|
|
189
|
+
int horizonResolution = ${this.horizonResolution};
|
|
190
|
+
float GROUND_ALBEDO = 0.2;
|
|
191
|
+
|
|
192
|
+
// Function to convert Cartesian to spherical coordinates
|
|
193
|
+
vec3 cartesianToSpherical(vec3 cartesian) {
|
|
194
|
+
float r = length(cartesian);
|
|
195
|
+
float cotheta = acos(cartesian.z / r);
|
|
196
|
+
float theta = 3.14159 / 2.0 - cotheta;
|
|
197
|
+
float phi = atan(cartesian.x, cartesian.y);
|
|
198
|
+
phi = mod(phi + 6.28318, 6.28318);
|
|
199
|
+
return vec3(r, theta, phi);
|
|
200
|
+
}
|
|
201
|
+
int getHorizonIndexFromPhiAngle(float phi) {
|
|
202
|
+
// Ensure phi is within [0, 2π]
|
|
203
|
+
phi = mod(phi, 6.28318);
|
|
204
|
+
|
|
205
|
+
// Convert phi to degrees and scale to horizon resolution
|
|
206
|
+
float scaledPhi = (phi / (6.28318)) * float(horizonResolution);
|
|
207
|
+
|
|
208
|
+
// Convert to integer and ensure it's within valid range
|
|
209
|
+
return clamp(int(scaledPhi), 0, horizonResolution - 1);
|
|
210
|
+
}
|
|
211
|
+
// Function to calculate the horizon from edges with resolution
|
|
212
|
+
void calculateHorizon(
|
|
213
|
+
out float horizonThetas[${this.horizonResolution}],
|
|
214
|
+
out float horizonMountainThetas[${this.horizonResolution}]
|
|
215
|
+
) {
|
|
216
|
+
for (int i = 0; i < ${this.horizonResolution}; i++) {
|
|
217
|
+
float horizonValue = texture2D(horizon, vec2(float(i) / float(horizonResolution), 0.0)).r;
|
|
218
|
+
horizonThetas[i] = horizonValue;
|
|
219
|
+
horizonMountainThetas[i] = horizonValue;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
for (int i = 0; i < ${this.MAX_EDGES_LENGTH}; i++) {
|
|
223
|
+
if (i > edgesLength) break;
|
|
224
|
+
vec3 edgeStart = cartesianToSpherical(edges[i*2] - vPosition.xyz);
|
|
225
|
+
vec3 edgeEnd = cartesianToSpherical(edges[i*2+1] - vPosition.xyz);
|
|
226
|
+
vec3 eStart=edges[i*2] - vPosition.xyz;
|
|
227
|
+
vec3 eEnd=edges[i*2 + 1] - vPosition.xyz;
|
|
228
|
+
bool flipEdges = false;
|
|
229
|
+
float phiDiff = mod(edgeEnd.z - edgeStart.z + 6.28318, 6.28318);
|
|
230
|
+
if (phiDiff > 3.14159) {
|
|
231
|
+
flipEdges = true;
|
|
232
|
+
}
|
|
233
|
+
if(flipEdges){
|
|
234
|
+
vec3 edgeTmp = edgeStart;
|
|
235
|
+
edgeStart = edgeEnd;
|
|
236
|
+
edgeEnd = edgeTmp;
|
|
237
|
+
vec3 eTmp = eStart;
|
|
238
|
+
eStart = eEnd;
|
|
239
|
+
eEnd = eTmp;
|
|
240
|
+
}
|
|
241
|
+
int startPhiIndex = getHorizonIndexFromPhiAngle(edgeStart.z);
|
|
242
|
+
int endPhiIndex = getHorizonIndexFromPhiAngle(edgeEnd.z);
|
|
243
|
+
if(startPhiIndex > endPhiIndex){
|
|
244
|
+
endPhiIndex += horizonResolution;
|
|
245
|
+
}
|
|
246
|
+
for (int j = startPhiIndex; j <= endPhiIndex; j++) {
|
|
247
|
+
int index = j % horizonResolution;
|
|
248
|
+
float phi = 2.0 * 3.14159 * float(index) / float(horizonResolution);
|
|
249
|
+
vec3 u = eEnd - eStart;
|
|
250
|
+
|
|
251
|
+
float denominator=u.x*cos(phi)-u.y*sin(phi);
|
|
252
|
+
if(denominator==0.0){
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
float numerator=eStart.y*sin(phi)-eStart.x*cos(phi);
|
|
256
|
+
float t = numerator/denominator;
|
|
257
|
+
if(t<0.0 || t>1.0){
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
// Interpolate the Cartesian position
|
|
261
|
+
vec3 interpolatedCartesian = mix(eStart, eEnd, t);
|
|
262
|
+
// Convert interpolated Cartesian to spherical
|
|
263
|
+
vec3 interpolatedSpherical = cartesianToSpherical(interpolatedCartesian);
|
|
264
|
+
// Use the theta (y) component of the spherical coordinates
|
|
265
|
+
float interpolatedTheta = interpolatedSpherical.y;
|
|
266
|
+
horizonThetas[index] = max(horizonThetas[index], interpolatedTheta);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
vec3 mapValueToColor(float value) {
|
|
272
|
+
for (int i = 0; i < stopCount; i++) {
|
|
273
|
+
float stop1 = stopValues[i];
|
|
274
|
+
float stop2 = stopValues[i + 1];
|
|
275
|
+
|
|
276
|
+
if (value >= stop1 && value <= stop2) {
|
|
277
|
+
float t = (value - stop1) / (stop2 - stop1);
|
|
278
|
+
return mix(colorStops[i], colorStops[i + 1], t);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return (value <= stopValues[0]) ? colorStops[0] : colorStops[stopCount - 1];
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
void main() {
|
|
285
|
+
float plane_theta = acos(vNormal.z);
|
|
286
|
+
float plane_phi = atan(vNormal.x, vNormal.y);
|
|
287
|
+
plane_phi = mod(plane_phi + 6.28318, 6.28318);
|
|
288
|
+
|
|
289
|
+
vec2 uv = vec2(
|
|
290
|
+
plane_phi / 6.28318, // Normalize phi to [0, 1]
|
|
291
|
+
plane_theta < 1.570795 ? 1.0-(plane_theta / 1.570795) : 0.0 // Normalize theta to [0, 1]
|
|
292
|
+
);
|
|
293
|
+
// Initialize sum
|
|
294
|
+
float totalGHI = 0.0;
|
|
295
|
+
|
|
296
|
+
// Get resolution from texture size
|
|
297
|
+
vec2 resolution = vec2(1.0) / vec2(textureSize(gridsDNI, 0));
|
|
298
|
+
|
|
299
|
+
// Calculate horizon with resolution
|
|
300
|
+
float horizonThetas[${this.horizonResolution}];
|
|
301
|
+
float horizonMountainThetas[${this.horizonResolution}];
|
|
302
|
+
calculateHorizon(horizonThetas, horizonMountainThetas);
|
|
303
|
+
|
|
304
|
+
// Loop through all possible sun positions
|
|
305
|
+
float enlightedArea = 0.0;
|
|
306
|
+
float enlightedAreaWithoutObstacles = 0.0;
|
|
307
|
+
float enlightedAreaWithoutHorizon = 0.0;
|
|
308
|
+
float referenceGHI = 0.0;
|
|
309
|
+
float totalDNIWithoutHorizon = 0.0;
|
|
310
|
+
float totalDNIWithoutObstacles = 0.0;
|
|
311
|
+
float totalDNI = 0.0;
|
|
312
|
+
float totalDHI = 0.0;
|
|
313
|
+
for (float phi = 0.0; phi <= 1.0; phi += resolution.x) {
|
|
314
|
+
for (float theta = 0.0; theta <= 1.0; theta += resolution.y) {
|
|
315
|
+
vec2 sunUV = vec2(phi, theta);
|
|
316
|
+
|
|
317
|
+
// Sample DNI and DHI from textures
|
|
318
|
+
float dni = texture2D(gridsDNI, sunUV).r * maxDNI;
|
|
319
|
+
float dhi = texture2D(gridsDHI, sunUV).r * maxDHI;
|
|
320
|
+
|
|
321
|
+
// Calculate sun direction vector
|
|
322
|
+
float phiRad = phi * 6.28318;
|
|
323
|
+
float thetaRad = theta * 1.57079;
|
|
324
|
+
vec3 sunDir = vec3(
|
|
325
|
+
cos(thetaRad) * sin(phiRad),
|
|
326
|
+
cos(thetaRad) * cos(phiRad),
|
|
327
|
+
sin(thetaRad)
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
// Check if sun is blocked by the horizon
|
|
331
|
+
int phiIndex = getHorizonIndexFromPhiAngle(phiRad);
|
|
332
|
+
bool isBlocked = thetaRad <= horizonThetas[phiIndex];
|
|
333
|
+
bool isBlockedByMountain = thetaRad <= horizonMountainThetas[phiIndex];
|
|
334
|
+
|
|
335
|
+
// Add to total GHI if not blocked
|
|
336
|
+
// Calculate cos_angle using normalVector
|
|
337
|
+
float cos_angle = max(dot(vNormal, sunDir), 0.0);
|
|
338
|
+
referenceGHI += dni * cos_angle + dhi;
|
|
339
|
+
totalDNIWithoutHorizon += dni * cos_angle;
|
|
340
|
+
if(cos_angle > 0.0){
|
|
341
|
+
if (!isBlocked) {
|
|
342
|
+
totalDNI += dni * cos_angle;
|
|
343
|
+
enlightedArea += 2.0 * cos(thetaRad) * sin(thetaRad) * pow((6.28318 * resolution.x) , 2.0);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if(!isBlockedByMountain) {
|
|
347
|
+
totalDNIWithoutObstacles += dni * cos_angle;
|
|
348
|
+
enlightedAreaWithoutObstacles += 2.0 * cos(thetaRad) * sin(thetaRad) * pow((6.28318 * resolution.x) , 2.0);
|
|
349
|
+
}
|
|
350
|
+
enlightedAreaWithoutHorizon += 2.0 * cos(thetaRad) * sin(thetaRad) * pow((6.28318 * resolution.x) , 2.0);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
//compute of Ineichen diffuse
|
|
354
|
+
float F = 1.0 - pow(dhi / max(dni * cos_angle + dhi, 1e-6), 2.0);
|
|
355
|
+
float diffusion_Ineichen = dhi * (1.0 + cos(plane_theta) / 2.0) *
|
|
356
|
+
(1.0 + F * pow(sin(plane_theta / 2.0), 3.0)) *
|
|
357
|
+
(1.0 + F * pow(cos_angle, 2.0) * pow(cos(thetaRad), 3.0));
|
|
358
|
+
totalDHI += diffusion_Ineichen;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
float ground_reflection = GROUND_ALBEDO * referenceGHI * (1.0 - cos(plane_theta)) / 2.0;
|
|
362
|
+
totalGHI = totalDNI + totalDHI * (enlightedArea / enlightedAreaWithoutHorizon) + ground_reflection;
|
|
363
|
+
float totalGHIWithoutHorizon = totalDNIWithoutHorizon + totalDHI + ground_reflection;
|
|
364
|
+
|
|
365
|
+
float totalDHIWithoutObstacles = totalDHI * (enlightedAreaWithoutObstacles / enlightedAreaWithoutHorizon);
|
|
366
|
+
float totalGHIWithoutObstacles = totalDNIWithoutObstacles + totalDHIWithoutObstacles + ground_reflection;
|
|
367
|
+
|
|
368
|
+
// Normalize the total for visualization
|
|
369
|
+
float result = 0.0;
|
|
370
|
+
|
|
371
|
+
if(isShadingFactor == 1) {
|
|
372
|
+
result = 1.0 - (totalGHI / totalGHIWithoutObstacles);
|
|
373
|
+
} else {
|
|
374
|
+
result = totalGHI / (highestGHI);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
vec3 color;
|
|
378
|
+
if (colorfull == 0) {
|
|
379
|
+
color = vec3(result, result, result);
|
|
380
|
+
} else {
|
|
381
|
+
color = mapValueToColor(result);
|
|
382
|
+
}
|
|
383
|
+
gl_FragColor = vec4(color, 1.0);
|
|
384
|
+
}
|
|
385
|
+
`
|
|
386
|
+
shader.vertexShader = vertexShader
|
|
387
|
+
shader.fragmentShader = fragmentShader
|
|
388
|
+
}
|
|
389
|
+
}
|
|
@@ -159,6 +159,16 @@ export default {
|
|
|
159
159
|
method: this.renderEdges,
|
|
160
160
|
arg: [],
|
|
161
161
|
})
|
|
162
|
+
methodList.push({
|
|
163
|
+
name: 'renderOverlays',
|
|
164
|
+
method: this.renderOverlays,
|
|
165
|
+
arg: [],
|
|
166
|
+
})
|
|
167
|
+
methodList.push({
|
|
168
|
+
name: 'updateProjectionMaterials',
|
|
169
|
+
method: this.updateProjectionMaterials,
|
|
170
|
+
arg: [],
|
|
171
|
+
})
|
|
162
172
|
case 'marginIsSameChange': //params.polygon
|
|
163
173
|
case 'marginDifferentChange': //params.polygon,index
|
|
164
174
|
case 'marginSameChange': //params.polygon
|
|
@@ -410,6 +420,13 @@ export default {
|
|
|
410
420
|
arg: [],
|
|
411
421
|
})
|
|
412
422
|
break
|
|
423
|
+
case 'updateIsYearlyShadingHeatmapActive':
|
|
424
|
+
methodList.push({
|
|
425
|
+
name: 'setModuleFieldsVisibility',
|
|
426
|
+
method: this.setModuleFieldsVisibility,
|
|
427
|
+
arg: [!params.value],
|
|
428
|
+
})
|
|
429
|
+
break
|
|
413
430
|
case 'selectedPanelChange':
|
|
414
431
|
methodList.push({
|
|
415
432
|
name: 'renderModuleFields',
|