@mcolabs/threebox-plugin 4.0.0 → 4.0.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/dist/threebox.cjs +1 -1
- package/dist/threebox.cjs.map +1 -1
- package/dist/threebox.iife.js +1 -1
- package/dist/threebox.iife.js.map +1 -1
- package/dist/threebox.js +114 -43
- package/dist/threebox.js.map +1 -1
- package/package.json +2 -2
- package/src/Threebox.js +68 -20
- package/src/animation/AnimationManager.js +6 -6
- package/src/camera/CameraSync.js +4 -1
- package/src/objects/effects/BuildingShadows.js +36 -10
- package/src/objects/loadObj.js +54 -9
- package/src/objects/objects.js +3 -2
package/dist/threebox.js
CHANGED
|
@@ -498,7 +498,7 @@ CameraSync.prototype = {
|
|
|
498
498
|
}
|
|
499
499
|
this.cameraTranslateZ = new THREE.Matrix4().makeTranslation(0, 0, this.cameraToCenterDistance);
|
|
500
500
|
const nz = t.height / 50;
|
|
501
|
-
|
|
501
|
+
let nearZ = Math.max(nz * pitchAngle, nz);
|
|
502
502
|
const h = t.height;
|
|
503
503
|
const w = t.width;
|
|
504
504
|
if (this.camera instanceof THREE.OrthographicCamera) {
|
|
@@ -906,7 +906,7 @@ AnimationManager.prototype = {
|
|
|
906
906
|
parameters: options2
|
|
907
907
|
};
|
|
908
908
|
this.animationQueue.push(entry);
|
|
909
|
-
|
|
909
|
+
this.threebox.map.repaint = true;
|
|
910
910
|
} else {
|
|
911
911
|
this.stop();
|
|
912
912
|
options2.rotation = utils.radify(options2.rotation);
|
|
@@ -940,7 +940,7 @@ AnimationManager.prototype = {
|
|
|
940
940
|
}
|
|
941
941
|
);
|
|
942
942
|
this.animationQueue.push(entry);
|
|
943
|
-
|
|
943
|
+
this.threebox.map.repaint = true;
|
|
944
944
|
return this;
|
|
945
945
|
};
|
|
946
946
|
obj._setObject = function(options2) {
|
|
@@ -990,7 +990,7 @@ AnimationManager.prototype = {
|
|
|
990
990
|
this.setBoundingBoxShadowFloor();
|
|
991
991
|
this.setReceiveShadowFloor();
|
|
992
992
|
this.updateMatrixWorld();
|
|
993
|
-
|
|
993
|
+
this.threebox.map.repaint = true;
|
|
994
994
|
let e2 = { type: "ObjectChanged", detail: { object: this, action: { position: options2.position, rotation: options2.rotation, scale: options2.scale } } };
|
|
995
995
|
this.dispatchEvent(e2);
|
|
996
996
|
};
|
|
@@ -1008,7 +1008,7 @@ AnimationManager.prototype = {
|
|
|
1008
1008
|
parameters: options2
|
|
1009
1009
|
};
|
|
1010
1010
|
this.animationQueue.push(entry);
|
|
1011
|
-
|
|
1011
|
+
this.threebox.map.repaint = true;
|
|
1012
1012
|
return this;
|
|
1013
1013
|
}
|
|
1014
1014
|
};
|
|
@@ -1052,7 +1052,7 @@ AnimationManager.prototype = {
|
|
|
1052
1052
|
if (obj.mixer) {
|
|
1053
1053
|
obj.mixer.update(0.01);
|
|
1054
1054
|
}
|
|
1055
|
-
|
|
1055
|
+
this.threebox.map.repaint = true;
|
|
1056
1056
|
return this;
|
|
1057
1057
|
};
|
|
1058
1058
|
},
|
|
@@ -1115,7 +1115,7 @@ AnimationManager.prototype = {
|
|
|
1115
1115
|
object.isPlaying = true;
|
|
1116
1116
|
object.animationMethod = requestAnimationFrame(this.update);
|
|
1117
1117
|
object.mixer.update(object.clock.getDelta());
|
|
1118
|
-
|
|
1118
|
+
object.threebox.map.repaint = true;
|
|
1119
1119
|
}
|
|
1120
1120
|
}
|
|
1121
1121
|
}
|
|
@@ -1310,7 +1310,7 @@ Objects.prototype = {
|
|
|
1310
1310
|
model.position.applyAxisAngle(axis, theta);
|
|
1311
1311
|
model.position.add(point);
|
|
1312
1312
|
model.rotateOnAxis(axis, theta);
|
|
1313
|
-
|
|
1313
|
+
obj.threebox.map.repaint = true;
|
|
1314
1314
|
}, zoomScale = function(zoom) {
|
|
1315
1315
|
return Math.pow(2, zoom);
|
|
1316
1316
|
};
|
|
@@ -1921,10 +1921,11 @@ Objects.prototype = {
|
|
|
1921
1921
|
if (m.dispose) m.dispose();
|
|
1922
1922
|
});
|
|
1923
1923
|
obj.scaleGroup.remove(o2);
|
|
1924
|
-
|
|
1924
|
+
obj.threebox.map.repaint = true;
|
|
1925
1925
|
};
|
|
1926
1926
|
obj.duplicate = function(options2) {
|
|
1927
1927
|
let dupe = obj.clone(true);
|
|
1928
|
+
dupe.threebox = obj.threebox;
|
|
1928
1929
|
dupe.getObjectByName("model").animations = obj.animations;
|
|
1929
1930
|
if (dupe.userData.feature) {
|
|
1930
1931
|
if (options2 && options2.feature) dupe.userData.feature = options2.feature;
|
|
@@ -2264,10 +2265,15 @@ function loadObj(options2, cb, promise) {
|
|
|
2264
2265
|
loader = daeLoader;
|
|
2265
2266
|
break;
|
|
2266
2267
|
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2268
|
+
if (options2.mtl) {
|
|
2269
|
+
materialLoader.withCredentials = options2.withCredentials;
|
|
2270
|
+
materialLoader.load(options2.mtl, loadObject, () => null, (error) => {
|
|
2271
|
+
console.warn("No material file found " + error.stack);
|
|
2272
|
+
loadObject(null);
|
|
2273
|
+
});
|
|
2274
|
+
} else {
|
|
2275
|
+
loadObject(null);
|
|
2276
|
+
}
|
|
2271
2277
|
function loadObject(materials) {
|
|
2272
2278
|
if (materials && options2.type == "mtl") {
|
|
2273
2279
|
materials.preload();
|
|
@@ -2319,15 +2325,15 @@ function loadObj(options2, cb, promise) {
|
|
|
2319
2325
|
let specularColor;
|
|
2320
2326
|
if (c.material.type == "MeshStandardMaterial") {
|
|
2321
2327
|
if (c.material.metalness) {
|
|
2322
|
-
c.material.metalness *= 0.
|
|
2328
|
+
c.material.metalness *= 0.3;
|
|
2323
2329
|
}
|
|
2324
2330
|
if (c.material.glossiness) {
|
|
2325
|
-
c.material.glossiness *= 0.
|
|
2331
|
+
c.material.glossiness *= 0.5;
|
|
2326
2332
|
}
|
|
2327
|
-
specularColor = new THREE.Color(
|
|
2333
|
+
specularColor = new THREE.Color(789516);
|
|
2328
2334
|
} else if (c.material.type == "MeshPhongMaterial") {
|
|
2329
|
-
c.material.shininess = 0.
|
|
2330
|
-
specularColor = new THREE.Color(
|
|
2335
|
+
c.material.shininess = 0.3;
|
|
2336
|
+
specularColor = new THREE.Color(1315860);
|
|
2331
2337
|
}
|
|
2332
2338
|
if (c.material.specular && c.material.specular.isColor) {
|
|
2333
2339
|
c.material.specular = specularColor;
|
|
@@ -2431,11 +2437,13 @@ class BuildingShadows {
|
|
|
2431
2437
|
this.tb = threebox;
|
|
2432
2438
|
}
|
|
2433
2439
|
onAdd(map, gl) {
|
|
2440
|
+
var _a2, _b2, _c;
|
|
2434
2441
|
this.map = map;
|
|
2435
2442
|
const sourceName = this.map.getLayer(this.buildingsLayerId).source;
|
|
2436
|
-
|
|
2443
|
+
const style = this.map.style;
|
|
2444
|
+
this.source = ((_a2 = style.sourceCaches) == null ? void 0 : _a2[sourceName]) || ((_b2 = style._otherSourceCaches) == null ? void 0 : _b2[sourceName]) || ((_c = style._sourceCaches) == null ? void 0 : _c[sourceName]);
|
|
2437
2445
|
if (!this.source) {
|
|
2438
|
-
console.warn(`Can't find layer ${this.buildingsLayerId}'s source.`);
|
|
2446
|
+
console.warn(`BuildingShadows: Can't find layer ${this.buildingsLayerId}'s source.`);
|
|
2439
2447
|
}
|
|
2440
2448
|
const vertexSource = this._getVertexSource();
|
|
2441
2449
|
const fragmentSource = `
|
|
@@ -2446,13 +2454,22 @@ class BuildingShadows {
|
|
|
2446
2454
|
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
2447
2455
|
gl.shaderSource(vertexShader, vertexSource);
|
|
2448
2456
|
gl.compileShader(vertexShader);
|
|
2457
|
+
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
|
|
2458
|
+
console.error("BuildingShadows vertex shader error:", gl.getShaderInfoLog(vertexShader));
|
|
2459
|
+
}
|
|
2449
2460
|
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
2450
2461
|
gl.shaderSource(fragmentShader, fragmentSource);
|
|
2451
2462
|
gl.compileShader(fragmentShader);
|
|
2463
|
+
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
|
|
2464
|
+
console.error("BuildingShadows fragment shader error:", gl.getShaderInfoLog(fragmentShader));
|
|
2465
|
+
}
|
|
2452
2466
|
this.program = gl.createProgram();
|
|
2453
2467
|
gl.attachShader(this.program, vertexShader);
|
|
2454
2468
|
gl.attachShader(this.program, fragmentShader);
|
|
2455
2469
|
gl.linkProgram(this.program);
|
|
2470
|
+
if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) {
|
|
2471
|
+
console.error("BuildingShadows program link error:", gl.getProgramInfoLog(this.program));
|
|
2472
|
+
}
|
|
2456
2473
|
gl.validateProgram(this.program);
|
|
2457
2474
|
this.uMatrix = gl.getUniformLocation(this.program, "u_matrix");
|
|
2458
2475
|
this.uHeightFactor = gl.getUniformLocation(this.program, "u_height_factor");
|
|
@@ -2468,6 +2485,7 @@ class BuildingShadows {
|
|
|
2468
2485
|
this.aHeight = gl.getAttribLocation(this.program, "a_height");
|
|
2469
2486
|
}
|
|
2470
2487
|
render(gl, matrix) {
|
|
2488
|
+
var _a2, _b2;
|
|
2471
2489
|
if (!this.source) return;
|
|
2472
2490
|
gl.useProgram(this.program);
|
|
2473
2491
|
const coords = this.source.getVisibleCoordinates().reverse();
|
|
@@ -2479,13 +2497,25 @@ class BuildingShadows {
|
|
|
2479
2497
|
gl.uniform1f(this.uAzimuth, pos.azimuth + 3 * Math.PI / 2);
|
|
2480
2498
|
gl.enable(gl.BLEND);
|
|
2481
2499
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
2482
|
-
gl.getExtension("EXT_blend_minmax");
|
|
2483
2500
|
gl.disable(gl.DEPTH_TEST);
|
|
2484
2501
|
for (const coord of coords) {
|
|
2485
2502
|
const tile = this.source.getTile(coord);
|
|
2486
|
-
|
|
2503
|
+
let bucket = tile.getBucket(buildingsLayer);
|
|
2504
|
+
if (!bucket && tile.buckets) {
|
|
2505
|
+
bucket = tile.buckets[this.buildingsLayerId];
|
|
2506
|
+
}
|
|
2487
2507
|
if (!bucket) continue;
|
|
2488
|
-
|
|
2508
|
+
let heightBuffer, baseBuffer;
|
|
2509
|
+
const programConfig = (_b2 = (_a2 = bucket.programConfigurations) == null ? void 0 : _a2.programConfigurations) == null ? void 0 : _b2[this.buildingsLayerId];
|
|
2510
|
+
if (programConfig == null ? void 0 : programConfig._buffers) {
|
|
2511
|
+
[heightBuffer, baseBuffer] = programConfig._buffers;
|
|
2512
|
+
} else if (programConfig == null ? void 0 : programConfig.getBuffers) {
|
|
2513
|
+
const buffers = programConfig.getBuffers();
|
|
2514
|
+
heightBuffer = buffers[0];
|
|
2515
|
+
baseBuffer = buffers[1];
|
|
2516
|
+
} else {
|
|
2517
|
+
continue;
|
|
2518
|
+
}
|
|
2489
2519
|
gl.uniformMatrix4fv(this.uMatrix, false, coord.posMatrix || coord.projMatrix);
|
|
2490
2520
|
gl.uniform1f(this.uHeightFactor, Math.pow(2, coord.overscaledZ) / tile.tileSize / 8);
|
|
2491
2521
|
for (const segment of bucket.segments.get()) {
|
|
@@ -2633,10 +2663,17 @@ Threebox.prototype = {
|
|
|
2633
2663
|
this.enableHelpTooltips = this.options.enableHelpTooltips || false;
|
|
2634
2664
|
this.map.on("style.load", function() {
|
|
2635
2665
|
this.tb.zoomLayers = [];
|
|
2636
|
-
if (this.tb.options.multiLayer) this.addLayer({
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2666
|
+
if (this.tb.options.multiLayer) this.addLayer({
|
|
2667
|
+
id: "threebox_layer",
|
|
2668
|
+
type: "custom",
|
|
2669
|
+
renderingMode: "3d",
|
|
2670
|
+
map: this,
|
|
2671
|
+
onAdd: function(map2, gl) {
|
|
2672
|
+
},
|
|
2673
|
+
render: function(gl, matrix) {
|
|
2674
|
+
this.map.tb.update();
|
|
2675
|
+
}
|
|
2676
|
+
});
|
|
2640
2677
|
this.once("idle", () => {
|
|
2641
2678
|
this.tb.setObjectsScale();
|
|
2642
2679
|
});
|
|
@@ -3081,29 +3118,51 @@ Threebox.prototype = {
|
|
|
3081
3118
|
// Objects
|
|
3082
3119
|
sphere: function(options2) {
|
|
3083
3120
|
this.setDefaultView(options2, this.options);
|
|
3084
|
-
|
|
3121
|
+
let obj = Sphere(options2, this.world);
|
|
3122
|
+
obj.threebox = this;
|
|
3123
|
+
return obj;
|
|
3124
|
+
},
|
|
3125
|
+
line: function(options2) {
|
|
3126
|
+
let obj = line(options2);
|
|
3127
|
+
obj.threebox = this;
|
|
3128
|
+
return obj;
|
|
3129
|
+
},
|
|
3130
|
+
label: function(options2) {
|
|
3131
|
+
let obj = Label(options2);
|
|
3132
|
+
obj.threebox = this;
|
|
3133
|
+
return obj;
|
|
3134
|
+
},
|
|
3135
|
+
tooltip: function(options2) {
|
|
3136
|
+
let obj = Tooltip(options2);
|
|
3137
|
+
obj.threebox = this;
|
|
3138
|
+
return obj;
|
|
3085
3139
|
},
|
|
3086
|
-
line,
|
|
3087
|
-
label: Label,
|
|
3088
|
-
tooltip: Tooltip,
|
|
3089
3140
|
tube: function(options2) {
|
|
3090
3141
|
this.setDefaultView(options2, this.options);
|
|
3091
|
-
|
|
3142
|
+
let obj = tube(options2, this.world);
|
|
3143
|
+
obj.threebox = this;
|
|
3144
|
+
return obj;
|
|
3092
3145
|
},
|
|
3093
3146
|
extrusion: function(options2) {
|
|
3094
3147
|
this.setDefaultView(options2, this.options);
|
|
3095
|
-
|
|
3148
|
+
let obj = extrusion(options2);
|
|
3149
|
+
obj.threebox = this;
|
|
3150
|
+
return obj;
|
|
3096
3151
|
},
|
|
3097
3152
|
Object3D: function(options2) {
|
|
3098
3153
|
this.setDefaultView(options2, this.options);
|
|
3099
|
-
|
|
3154
|
+
let obj = Object3D(options2);
|
|
3155
|
+
obj.threebox = this;
|
|
3156
|
+
return obj;
|
|
3100
3157
|
},
|
|
3101
3158
|
loadObj: async function loadObj$1(options2, cb) {
|
|
3102
3159
|
this.setDefaultView(options2, this.options);
|
|
3160
|
+
const tb = this;
|
|
3103
3161
|
if (options2.clone === false) {
|
|
3104
3162
|
return new Promise(
|
|
3105
3163
|
async (resolve) => {
|
|
3106
3164
|
loadObj(options2, cb, async (obj) => {
|
|
3165
|
+
obj.threebox = tb;
|
|
3107
3166
|
resolve(obj);
|
|
3108
3167
|
});
|
|
3109
3168
|
}
|
|
@@ -3112,7 +3171,9 @@ Threebox.prototype = {
|
|
|
3112
3171
|
let cache = this.objectsCache.get(options2.obj);
|
|
3113
3172
|
if (cache) {
|
|
3114
3173
|
cache.promise.then((obj) => {
|
|
3115
|
-
|
|
3174
|
+
let dupe = obj.duplicate(options2);
|
|
3175
|
+
dupe.threebox = tb;
|
|
3176
|
+
cb(dupe);
|
|
3116
3177
|
}).catch((err) => {
|
|
3117
3178
|
this.objectsCache.delete(options2.obj);
|
|
3118
3179
|
console.error("Could not load model file: " + options2.obj);
|
|
@@ -3122,6 +3183,7 @@ Threebox.prototype = {
|
|
|
3122
3183
|
promise: new Promise(
|
|
3123
3184
|
async (resolve, reject) => {
|
|
3124
3185
|
loadObj(options2, cb, async (obj) => {
|
|
3186
|
+
obj.threebox = tb;
|
|
3125
3187
|
if (obj.duplicate) {
|
|
3126
3188
|
resolve(obj.duplicate());
|
|
3127
3189
|
} else {
|
|
@@ -3262,12 +3324,20 @@ Threebox.prototype = {
|
|
|
3262
3324
|
this.setLayoutProperty(layerId, "visibility", visible ? "visible" : "none");
|
|
3263
3325
|
this.labelRenderer.toggleLabels(layerId, visible);
|
|
3264
3326
|
},
|
|
3265
|
-
update: function() {
|
|
3327
|
+
update: function(matrix) {
|
|
3266
3328
|
if (this.map.repaint) this.map.repaint = false;
|
|
3267
3329
|
var timestamp = Date.now();
|
|
3268
3330
|
this.objects.animationManager.update(timestamp);
|
|
3269
3331
|
this.updateLightHelper();
|
|
3270
3332
|
this.renderer.resetState();
|
|
3333
|
+
const gl = this.renderer.getContext();
|
|
3334
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
3335
|
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
3336
|
+
if (this.mapboxVersion >= 3) {
|
|
3337
|
+
gl.enable(gl.DEPTH_TEST);
|
|
3338
|
+
gl.depthFunc(gl.LESS);
|
|
3339
|
+
gl.depthMask(true);
|
|
3340
|
+
}
|
|
3271
3341
|
this.renderer.render(this.scene, this.camera);
|
|
3272
3342
|
this.labelRenderer.render(this.scene, this.camera);
|
|
3273
3343
|
if (this.options.passiveRendering === false) this.map.triggerRepaint();
|
|
@@ -3276,6 +3346,7 @@ Threebox.prototype = {
|
|
|
3276
3346
|
if (!this.enableTooltips && obj.tooltip) {
|
|
3277
3347
|
obj.tooltip.visibility = false;
|
|
3278
3348
|
}
|
|
3349
|
+
obj.threebox = this;
|
|
3279
3350
|
this.world.add(obj);
|
|
3280
3351
|
if (layerId) {
|
|
3281
3352
|
obj.layer = layerId;
|
|
@@ -3375,8 +3446,8 @@ Threebox.prototype = {
|
|
|
3375
3446
|
let azSin = Math.sin(azimuth2) * altRadius;
|
|
3376
3447
|
this.lights.dirLight.position.set(azSin, azCos, alt);
|
|
3377
3448
|
this.lights.dirLight.position.multiplyScalar(radius);
|
|
3378
|
-
this.lights.dirLight.intensity = Math.max(alt, 0);
|
|
3379
|
-
this.lights.hemiLight.intensity = Math.max(alt * 1, 0.1);
|
|
3449
|
+
this.lights.dirLight.intensity = Math.max(alt, 0) * 5;
|
|
3450
|
+
this.lights.hemiLight.intensity = Math.max(alt * 1, 0.1) * 3;
|
|
3380
3451
|
this.lights.dirLight.updateMatrixWorld();
|
|
3381
3452
|
this.updateLightHelper();
|
|
3382
3453
|
if (this.map.loaded()) {
|
|
@@ -3444,18 +3515,18 @@ Threebox.prototype = {
|
|
|
3444
3515
|
});
|
|
3445
3516
|
},
|
|
3446
3517
|
defaultLights: function() {
|
|
3447
|
-
this.lights.ambientLight = new THREE.AmbientLight(new THREE.Color("hsl(0, 0%, 100%)"),
|
|
3518
|
+
this.lights.ambientLight = new THREE.AmbientLight(new THREE.Color("hsl(0, 0%, 100%)"), 3);
|
|
3448
3519
|
this.scene.add(this.lights.ambientLight);
|
|
3449
|
-
this.lights.dirLightBack = new THREE.DirectionalLight(new THREE.Color("hsl(0, 0%, 100%)"),
|
|
3520
|
+
this.lights.dirLightBack = new THREE.DirectionalLight(new THREE.Color("hsl(0, 0%, 100%)"), 1);
|
|
3450
3521
|
this.lights.dirLightBack.position.set(30, 100, 100);
|
|
3451
3522
|
this.scene.add(this.lights.dirLightBack);
|
|
3452
|
-
this.lights.dirLight = new THREE.DirectionalLight(new THREE.Color("hsl(0, 0%, 100%)"),
|
|
3523
|
+
this.lights.dirLight = new THREE.DirectionalLight(new THREE.Color("hsl(0, 0%, 100%)"), 1);
|
|
3453
3524
|
this.lights.dirLight.position.set(-30, 100, -100);
|
|
3454
3525
|
this.scene.add(this.lights.dirLight);
|
|
3455
3526
|
},
|
|
3456
3527
|
realSunlight: function(helper = false) {
|
|
3457
3528
|
this.renderer.shadowMap.enabled = true;
|
|
3458
|
-
this.lights.dirLight = new THREE.DirectionalLight(16777215,
|
|
3529
|
+
this.lights.dirLight = new THREE.DirectionalLight(16777215, 5);
|
|
3459
3530
|
this.scene.add(this.lights.dirLight);
|
|
3460
3531
|
if (helper) {
|
|
3461
3532
|
this.lights.dirLightHelper = new THREE.DirectionalLightHelper(this.lights.dirLight, 5);
|
|
@@ -3473,7 +3544,7 @@ Threebox.prototype = {
|
|
|
3473
3544
|
this.lights.dirLight.shadow.camera.near = 1;
|
|
3474
3545
|
this.lights.dirLight.shadow.camera.visible = true;
|
|
3475
3546
|
this.lights.dirLight.shadow.camera.far = 4e8;
|
|
3476
|
-
this.lights.hemiLight = new THREE.HemisphereLight(new THREE.Color(16777215), new THREE.Color(16777215),
|
|
3547
|
+
this.lights.hemiLight = new THREE.HemisphereLight(new THREE.Color(16777215), new THREE.Color(16777215), 3);
|
|
3477
3548
|
this.lights.hemiLight.color.setHSL(0.661, 0.96, 0.12);
|
|
3478
3549
|
this.lights.hemiLight.groundColor.setHSL(0.11, 0.96, 0.14);
|
|
3479
3550
|
this.lights.hemiLight.position.set(0, 0, 50);
|