fix water

This commit is contained in:
Vincent van der Wal
2026-07-18 22:26:14 +02:00
parent bc9bd578d7
commit 25595d8281
7 changed files with 5088 additions and 262 deletions
+1
View File
@@ -2,3 +2,4 @@ node_modules/
yarn.lock
dist/
build/
check-*.png
+4771
View File
File diff suppressed because it is too large Load Diff
+9 -14
View File
@@ -1,19 +1,14 @@
{
"dependencies": {
"@babel/core": "^7.20.5",
"@babel/preset-env": "^7.20.2",
"babel-loader": "^9.1.0",
"css-loader": "^6.7.3",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"moment": "^2.29.4",
"sass": "^1.57.1",
"sass-loader": "^13.2.0",
"style-loader": "^3.3.1",
"three": "^0.147.0",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
"css-loader": "^7.1.4",
"html-webpack-plugin": "^5.6.7",
"sass": "^1.101.0",
"sass-loader": "^17.0.0",
"style-loader": "^4.0.0",
"three": "^0.185.1",
"webpack": "^5.108.4",
"webpack-cli": "^7.2.1",
"webpack-dev-server": "^6.0.0"
},
"scripts": {
"start": "webpack serve --env mode=development",
+12 -12
View File
@@ -18,19 +18,21 @@ camera.position.x = 10;
camera.position.y = 4;
const renderer = new THREE.WebGLRenderer();
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( Math.min( window.devicePixelRatio, 2 ) );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.gammaFactor = 2.2;
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
renderer.physicallyCorrectLights
document.body.appendChild( renderer.domElement );
window.addEventListener( 'resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
} );
const controls = new OrbitControls( camera, renderer.domElement );
controls.target.set( -4, 0, 0 );
@@ -321,14 +323,12 @@ let renderFlower = (size = 3, radius = 1) => {
renderFlower()
// const spotLight = new THREE.SpotLight( 0xffffff );
const spotLight = new THREE.DirectionalLight( 0xeaa7a7, 1.5);
// legacy lighting was removed in three r155: intensities need the old value times pi
const spotLight = new THREE.DirectionalLight( 0xeaa7a7, 1.5 * Math.PI );
spotLight.position.set( 10, 0, 0 );
spotLight.castShadow = true;
// spotLight.shadow.mapSize.width = 8182;
// spotLight.shadow.mapSize.height = 8182;
spotLight.shadow.mapSize.width = 4096;
spotLight.shadow.mapSize.height = 4096;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.shadow.camera.far = 21;
spotLight.shadow.camera.left = -10;
spotLight.shadow.camera.right = 10;
+229 -157
View File
@@ -16,17 +16,24 @@ camera.position.z = 12;
camera.position.x = 10;
camera.position.y = 4;
const renderer = new THREE.WebGLRenderer();
// debug switches to bisect driver issues: ?noaa disables MSAA, ?noshadow disables shadow maps
const debugFlags = new URLSearchParams( window.location.search );
const renderer = new THREE.WebGLRenderer( { antialias: !debugFlags.has( 'noaa' ) } );
renderer.setPixelRatio( Math.min( window.devicePixelRatio, 2 ) );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.shadowMap.enabled = !debugFlags.has( 'noshadow' );
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.gammaFactor = 2.2;
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
renderer.physicallyCorrectLights
document.body.appendChild( renderer.domElement );
window.addEventListener( 'resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
} );
const controls = new OrbitControls( camera, renderer.domElement );
controls.target.set( -4, 0, 0 );
@@ -170,12 +177,42 @@ function rotatePoint3D(px, py, pz, pitch, roll, yaw) {
return [x, y, z]
}
// WebGL draws lines at 1px regardless of linewidth, so the shape edges are built
// from real cylinder tubes instead - same 0.03 thickness as the circle tori
function makeEdgeTubes( geometry, color, tubeRadius = 0.03 ) {
const edges = new THREE.EdgesGeometry( geometry );
const positions = edges.attributes.position;
const group = new THREE.Group();
const material = new THREE.MeshBasicMaterial( { color } );
const up = new THREE.Vector3( 0, 1, 0 );
const start = new THREE.Vector3();
const end = new THREE.Vector3();
for ( let i = 0; i < positions.count; i += 2 ) {
start.fromBufferAttribute( positions, i );
end.fromBufferAttribute( positions, i + 1 );
const direction = new THREE.Vector3().subVectors( end, start );
const length = direction.length();
const cylinder = new THREE.CylinderGeometry( tubeRadius, tubeRadius, length, 12 );
cylinder.translate( 0, length / 2, 0 );
const tube = new THREE.Mesh( cylinder, material );
tube.position.copy( start );
tube.quaternion.setFromUnitVectors( up, direction.normalize() );
tube.castShadow = true;
group.add( tube );
}
return group;
}
const params = {
xangle: 45,
yangle: 0,
zangle: 54.72972973,
size: 5,
radius: 1,
tube: 0.03,
};
// const params = {
@@ -189,65 +226,40 @@ const params = {
let sphere, circleCircum, cube, cubeLines;
let spheres = [];
let spheresLines = [];
let gui;
let solids = [];
let renderFlower = (size = 5, radius = 1) => {
let renderFlower = (radius = 1) => {
spheres = [];
spheresLines = [];
let x_count, y_count, z_count;
x_count = 1;
for (let x of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) {
y_count = 1;
x = x - ((size - 1) * (0.612 * (radius * 2))) / 2
// tear down the previous render's shapes and GUI so re-rendering never stacks duplicates
if ( gui ) gui.destroy();
for ( let obj of solids ) scene.remove( obj );
solids = [];
// 3D fruit of life: a circle on the centre, on every cube corner and on
// every cube edge midpoint (the inner ring of the 2D pattern)
const d = 4 * 0.612 * radius;
const points = [ [ 0, 0, 0 ] ];
for (let y of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) {
z_count = 1;
y = y - ((size - 1) * (0.612 * (radius * 2))) / 2
for (let z of Array.from(Array(size), (_, i) => i * 0.612 * (radius * 2))) {
z = z - ((size - 1) * (0.612 * (radius * 2))) / 2
if (x_count % 2 == 0 || y_count % 2 == 0 || z_count % 2 == 0) {
z_count++;
continue;
for ( let sx of [ -1, 1 ] ) {
for ( let sy of [ -1, 1 ] ) {
for ( let sz of [ -1, 1 ] ) {
points.push( [ sx * d, sy * d, sz * d ] );
}
}
}
if (x_count % 5 == 0 && y_count % 3 == 0 ) {
z_count++;
continue;
// only the edge midpoints whose coordinates share a sign: the other six sit on
// the projection equator and would add circles between the two rings
for ( let s of [ -1, 1 ] ) {
points.push( [ s * d, s * d, 0 ] );
points.push( [ s * d, 0, s * d ] );
points.push( [ 0, s * d, s * d ] );
}
if (x_count % 5 == 0 && z_count % 3 == 0 ) {
z_count++;
continue;
}
if (y_count % 5 == 0 && x_count % 3 == 0 ) {
z_count++;
continue;
}
if (y_count % 5 == 0 && z_count % 3 == 0 ) {
z_count++;
continue;
}
if (z_count % 5 == 0 && x_count % 3 == 0 ) {
z_count++;
continue;
}
if (z_count % 5 == 0 && y_count % 3 == 0 ) {
z_count++;
continue;
}
const addCircleAt = ( x, y, z, parent ) => {
let xtemp, ytemp, ztemp;
[xtemp, ytemp, ztemp] = rotatePoint3D(x, y, z, params['yangle'], params['xangle'], params['zangle'])
@@ -264,21 +276,21 @@ let renderFlower = (size = 5, radius = 1) => {
sphere.position.x = xtemp;
sphere.position.y = ytemp;
sphere.position.z = ztemp;
scene.add( sphere );
parent.add( sphere );
let circleGeometry = new THREE.TorusGeometry( radius, 0.03, 64, 64 );
let circleGeometry = new THREE.TorusGeometry( radius, params['tube'], 64, 64 );
let circleMaterial = new THREE.MeshBasicMaterial( {
color: 0x000000,
opacity: 0.1,
transparent: true
} );
circleCircum = new THREE.Mesh( circleGeometry, circleMaterial );
circleCircum.castShadow = true;
circleCircum.rotation.y = Math.PI / 2;
circleCircum.position.x = xtemp;
circleCircum.position.y = ytemp;
circleCircum.position.z = ztemp;
scene.add( circleCircum );
let ring = new THREE.Mesh( circleGeometry, circleMaterial );
ring.castShadow = true;
ring.rotation.y = Math.PI / 2;
ring.position.x = xtemp;
ring.position.y = ytemp;
ring.position.z = ztemp;
parent.add( ring );
circleGeometry = new THREE.TorusGeometry( 0.01, 0.01, 64, 64 );
circleMaterial = new THREE.MeshBasicMaterial( {
@@ -292,28 +304,82 @@ let renderFlower = (size = 5, radius = 1) => {
circleCircum.position.x = xtemp;
circleCircum.position.y = ytemp;
circleCircum.position.z = ztemp;
scene.add( circleCircum );
parent.add( circleCircum );
sphere.start_x = x;
sphere.start_y = y;
sphere.start_z = z;
ring.start_x = x;
ring.start_y = y;
ring.start_z = z;
circleCircum.start_x = x;
circleCircum.start_y = y;
circleCircum.start_z = z;
spheres.push(sphere)
spheresLines.push(ring)
spheresLines.push(circleCircum)
};
z_count++;
}
y_count++;
}
x_count++;
for ( let point of points ) {
addCircleAt( ...point, scene );
}
// the remaining cube circles: the six equatorial edge midpoints and the six
// face centres, hidden behind the "allCubeCircles" toggle
const extraCircles = new THREE.Group();
extraCircles.visible = false;
// earth
const boxGeometry = new THREE.BoxGeometry( 5 * radius, 5 * radius, 5 * radius );
for ( let s of [ -1, 1 ] ) {
for ( let extraPoint of [
[ s * d, -s * d, 0 ], [ s * d, 0, -s * d ], [ 0, s * d, -s * d ],
[ s * d, 0, 0 ], [ 0, s * d, 0 ], [ 0, 0, s * d ],
] ) {
addCircleAt( ...extraPoint, extraCircles );
}
}
scene.add( extraCircles );
// Metatron's web: every circle centre connected to every other one
let web = new THREE.Group();
const webMaterial = new THREE.MeshBasicMaterial( { color: 0x000000, opacity: 0.5, transparent: true } );
const webUp = new THREE.Vector3( 0, 1, 0 );
for ( let i = 0; i < points.length; i++ ) {
for ( let j = i + 1; j < points.length; j++ ) {
const [ ax, ay, az ] = rotatePoint3D( ...points[ i ], params[ 'yangle' ], params[ 'xangle' ], params[ 'zangle' ] );
const [ bx, by, bz ] = rotatePoint3D( ...points[ j ], params[ 'yangle' ], params[ 'xangle' ], params[ 'zangle' ] );
const a = new THREE.Vector3( ax, ay, az );
const b = new THREE.Vector3( bx, by, bz );
const direction = new THREE.Vector3().subVectors( b, a );
const length = direction.length();
const webTube = params['tube'] * 0.4;
const cylinder = new THREE.CylinderGeometry( webTube, webTube, length, 6 );
cylinder.translate( 0, length / 2, 0 );
const strand = new THREE.Mesh( cylinder, webMaterial );
strand.position.copy( a );
strand.quaternion.setFromUnitVectors( webUp, direction.clone().normalize() );
web.add( strand );
}
}
web.visible = false;
scene.add( web );
// the exact rotation the circle grid uses, as a matrix - solids aligned with
// this coincide with the dots instead of approximating them with tuned angles
const gridRotation = new THREE.Matrix4().makeBasis(
new THREE.Vector3( ...rotatePoint3D( 1, 0, 0, params['yangle'], params['xangle'], params['zangle'] ) ),
new THREE.Vector3( ...rotatePoint3D( 0, 1, 0, params['yangle'], params['xangle'], params['zangle'] ) ),
new THREE.Vector3( ...rotatePoint3D( 0, 0, 1, params['yangle'], params['xangle'], params['zangle'] ) )
);
// earth - width 2d puts every corner exactly on a corner dot
const boxGeometry = new THREE.BoxGeometry( 2 * d, 2 * d, 2 * d );
const boxMaterial = new THREE.MeshStandardMaterial( {
color: 0x994f28,
metalness: 0.7,
@@ -323,22 +389,17 @@ let renderFlower = (size = 5, radius = 1) => {
// wireframe: true,
} );
cube = new THREE.Mesh( boxGeometry, boxMaterial );
cube.rotation.x = 30 * (Math.PI / 180)
cube.rotation.y = 144.75 * (Math.PI / 180)
cube.rotation.z = 45 * (Math.PI / 180)
cube.setRotationFromMatrix( gridRotation );
let cubeEdges = new THREE.EdgesGeometry( boxGeometry );
cubeLines = new THREE.LineSegments( cubeEdges, new THREE.LineBasicMaterial( { color: 0x1b0a02, linewidth: 50000 } ) );
cubeLines.rotation.x = 30 * (Math.PI / 180)
cubeLines.rotation.y = 144.8 * (Math.PI / 180)
cubeLines.rotation.z = 45 * (Math.PI / 180)
cubeLines = makeEdgeTubes( boxGeometry, 0x1b0a02, params['tube'] );
cubeLines.setRotationFromMatrix( gridRotation );
cubeLines.castShadow = true;
scene.add( cubeLines );
scene.add( cube );
// fire
const tetraGeometry = new THREE.TetrahedronGeometry( (5 - 2 / 3) * radius )
// fire - radius sqrt(3)d puts every vertex exactly on a corner dot
const tetraGeometry = new THREE.TetrahedronGeometry( Math.sqrt( 3 ) * d )
const tetraMaterial = new THREE.MeshStandardMaterial( {
color: 0xdb1212,
metalness: 0.7,
@@ -348,24 +409,32 @@ let renderFlower = (size = 5, radius = 1) => {
} );
let tetra = new THREE.Mesh( tetraGeometry, tetraMaterial );
let tetraEdges = new THREE.EdgesGeometry( tetraGeometry );
let tetraLines = new THREE.LineSegments( tetraEdges, new THREE.LineBasicMaterial( { color: 0x140101, linewidth: 50000 } ) );
let tetraLines = makeEdgeTubes( tetraGeometry, 0x140101, params['tube'] );
tetraLines.rotation.x = 90 * (Math.PI / 180)
tetraLines.rotation.y = 35.26530612 * (Math.PI / 180)
tetraLines.rotation.z = 45 * (Math.PI / 180)
tetra.rotation.x = 90 * (Math.PI / 180)
tetra.rotation.y = 35.26530612 * (Math.PI / 180)
tetra.rotation.z = 45 * (Math.PI / 180)
tetraLines.setRotationFromMatrix( gridRotation );
tetra.setRotationFromMatrix( gridRotation );
tetraLines.castShadow = true;
scene.add( tetraLines );
scene.add( tetra );
const octaGeometry = new THREE.OctahedronGeometry( 5 * radius )
// second tetrahedron of the star tetrahedron (Merkaba): the same shape
// rotated a quarter turn so it interlocks with the first
const tetraGeometry2 = new THREE.TetrahedronGeometry( Math.sqrt( 3 ) * d );
tetraGeometry2.rotateZ( Math.PI / 2 );
let tetra2 = new THREE.Mesh( tetraGeometry2, tetraMaterial );
let tetraLines2 = makeEdgeTubes( tetraGeometry2, 0x140101, params['tube'] );
tetra2.rotation.copy( tetra.rotation );
tetraLines2.rotation.copy( tetraLines.rotation );
scene.add( tetraLines2 );
scene.add( tetra2 );
// radius 2d puts the projected corners exactly on the outer circle centres
const octaGeometry = new THREE.OctahedronGeometry( 2 * d )
const octaMaterial = new THREE.MeshStandardMaterial( {
color: 0x9dedf6,
metalness: 0.7,
@@ -375,22 +444,17 @@ let renderFlower = (size = 5, radius = 1) => {
} );
let octa = new THREE.Mesh( octaGeometry, octaMaterial );
let octaEdges = new THREE.EdgesGeometry( octaGeometry );
let octaLines = new THREE.LineSegments( octaEdges, new THREE.LineBasicMaterial( { color: 0x0a2528, linewidth: 50000 } ) );
let octaLines = makeEdgeTubes( octaGeometry, 0x0a2528, params['tube'] );
octaLines.rotation.x = 90 * (Math.PI / 180)
octaLines.rotation.y = 35.26530612 * (Math.PI / 180)
octaLines.rotation.z = 45 * (Math.PI / 180)
octa.rotation.x = 90 * (Math.PI / 180)
octa.rotation.y = 35.26530612 * (Math.PI / 180)
octa.rotation.z = 45 * (Math.PI / 180)
octaLines.setRotationFromMatrix( gridRotation );
octa.setRotationFromMatrix( gridRotation );
octaLines.castShadow = true;
scene.add( octaLines );
scene.add( octa );
const icosaGeometry = new THREE.IcosahedronGeometry( (3 + 1 / 3 + 0.028) * radius )
// radius 1.663d puts the projected corners on the outer circle centres
const icosaGeometry = new THREE.IcosahedronGeometry( 1.663 * d )
const icosaMaterial = new THREE.MeshStandardMaterial( {
color: 0x0063e4,
metalness: 0.7,
@@ -400,25 +464,26 @@ let renderFlower = (size = 5, radius = 1) => {
} );
let icosa = new THREE.Mesh( icosaGeometry, icosaMaterial );
let icosaEdges = new THREE.EdgesGeometry( icosaGeometry );
let icosaLines = new THREE.LineSegments( icosaEdges, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 50000 } ) );
let icosaLines = makeEdgeTubes( icosaGeometry, 0x000000, params['tube'] );
icosaLines.rotation.x = 30 * (Math.PI / 180)
icosaLines.rotation.y = 159.1 * (Math.PI / 180)
icosaLines.rotation.z = 90 * (Math.PI / 180)
// a grid-aligned icosahedron projects its corners 22.2 degrees off the dot
// hexagon, so it gets an extra twist about the view diagonal to meet the dots
const PHI = ( 1 + Math.sqrt( 5 ) ) / 2;
const icosaTwist = Math.PI / 6 - Math.atan( ( PHI + 2 ) / ( Math.sqrt( 3 ) * PHI ) );
const icosaRotation = new THREE.Matrix4().multiplyMatrices(
gridRotation,
new THREE.Matrix4().makeRotationAxis( new THREE.Vector3( 1, 1, 1 ).normalize(), icosaTwist )
);
icosa.rotation.x = 30 * (Math.PI / 180)
icosa.rotation.y = 159.1 * (Math.PI / 180)
icosa.rotation.z = 90 * (Math.PI / 180)
icosaLines.setRotationFromMatrix( icosaRotation );
icosa.setRotationFromMatrix( icosaRotation );
icosaLines.castShadow = true;
scene.add( icosaLines );
scene.add( icosa );
icosa.visible = false;
icosaLines.visible = false;
const dodecaGeometry = new THREE.DodecahedronGeometry( (2 + 1 / 3 + 0.005) * radius )
// 2.29 * 1.003: tuned against the circle pattern
const dodecaGeometry = new THREE.DodecahedronGeometry( 2.297 * radius )
const dodecaMaterial = new THREE.MeshStandardMaterial( {
color: 0x0063e4,
metalness: 0.7,
@@ -428,42 +493,42 @@ let renderFlower = (size = 5, radius = 1) => {
} );
let dodeca = new THREE.Mesh( dodecaGeometry, dodecaMaterial );
let dodecaEdges = new THREE.EdgesGeometry( dodecaGeometry );
let dodecaLines = new THREE.LineSegments( dodecaEdges, new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 50000 } ) );
let dodecaLines = makeEdgeTubes( dodecaGeometry, 0x000000, params['tube'] );
dodecaLines.rotation.x = 90 * (Math.PI / 180)
dodecaLines.rotation.y = 111 * (Math.PI / 180)
dodecaLines.rotation.z = 90 * (Math.PI / 180)
dodeca.rotation.x = 90 * (Math.PI / 180)
dodeca.rotation.y = 111 * (Math.PI / 180)
dodeca.rotation.z = 90 * (Math.PI / 180)
// aether: a dodecahedron vertex sits on the cube diagonal, so the plain grid
// rotation points a vertex straight at the light and shares the cube's frame,
// with a tuned x-angle on top
dodecaLines.setRotationFromMatrix( gridRotation );
dodeca.setRotationFromMatrix( gridRotation );
dodecaLines.rotation.x = 52.25 * (Math.PI / 180);
dodeca.rotation.x = 52.25 * (Math.PI / 180);
dodecaLines.castShadow = true;
scene.add( dodecaLines );
scene.add( dodeca );
// Big circle
let circleGeometry = new THREE.TorusGeometry( 5 * radius, 0.02, 64, 64);
let circleMaterial = new THREE.MeshBasicMaterial( {
color: 0x000000,
opacity: 0,
transparent: true
} );
// Big circle: visible as a solid tube, same thickness as the shape edges
let circleGeometry = new THREE.TorusGeometry( 5 * radius, params['tube'], 64, 64);
let circleMaterial = new THREE.MeshBasicMaterial( { color: 0x000000 } );
circleCircum = new THREE.Mesh( circleGeometry, circleMaterial );
circleCircum.rotation.y = Math.PI / 2;
circleCircum.castShadow = true;
scene.add( circleCircum );
solids.push( cube, cubeLines, tetra, tetraLines, tetra2, tetraLines2, octa, octaLines, icosa, icosaLines, dodeca, dodecaLines, circleCircum, web, extraCircles );
const gui = new GUI();
gui = new GUI();
let guiDict = {};
let fire = gui.addFolder('Fire');
guiDict['fire'] = {'folder': fire, 'object': tetra, 'objectLines': tetraLines};
let fire2 = gui.addFolder('Fire 2');
guiDict['fire2'] = {'folder': fire2, 'object': tetra2, 'objectLines': tetraLines2};
let air = gui.addFolder('Air');
guiDict['air'] = {'folder': air, 'object': octa, 'objectLines': octaLines};
@@ -479,6 +544,14 @@ let renderFlower = (size = 5, radius = 1) => {
let circles = gui.addFolder('Circles')
guiDict['circles'] = {'folder': circles};
circles.add( { web: false }, 'web' ).onChange( ( value ) => {
web.visible = value;
} );
circles.add( { allCubeCircles: false }, 'allCubeCircles' ).onChange( ( value ) => {
extraCircles.visible = value;
} );
let folderStandard = {
show: true,
fill: true,
@@ -514,11 +587,7 @@ let renderFlower = (size = 5, radius = 1) => {
if (fld === "circles") {
continue
}
if (fld === "water") {
folderStandard.show = false;
} else {
folderStandard.show = true;
}
folderStandard.xAngle = guiDict[fld]['object'].rotation.x / (Math.PI / 180);
folderStandard.yAngle = guiDict[fld]['object'].rotation.y / (Math.PI / 180);
@@ -597,18 +666,6 @@ let renderFlower = (size = 5, radius = 1) => {
[sphereLine.position.x, sphereLine.position.y, sphereLine.position.z] = rotatePoint3D(sphereLine.start_x, sphereLine.start_y, sphereLine.start_z, params['yangle'], params['xangle'], value)
}
});
gui.add( params, 'size', 2, 5).step(1).onChange( (value) => {
for (let sphere of spheres) {
scene.remove(sphere)
}
for (let sphereLine of spheresLines) {
scene.remove(sphereLine)
}
scene.remove(cube)
scene.remove(cubeLines)
scene.remove(circleCircum)
renderFlower (value, params['radius'])
});
gui.add( params, 'radius', 0.5, 1.5).onChange( (value) => {
for (let sphere of spheres) {
scene.remove(sphere)
@@ -616,25 +673,40 @@ let renderFlower = (size = 5, radius = 1) => {
for (let sphereLine of spheresLines) {
scene.remove(sphereLine)
}
scene.remove(cube)
scene.remove(cubeLines)
scene.remove(circleCircum)
renderFlower (params['size'], value)
renderFlower (value)
});
gui.add( params, 'tube', 0.01, 0.1 ).step( 0.005 ).onChange( () => {
for (let sphere of spheres) {
scene.remove(sphere)
}
for (let sphereLine of spheresLines) {
scene.remove(sphereLine)
}
renderFlower (params['radius'])
});
// ?only=<fire|fire2|air|earth|water|aether> hides the other solids, for
// checking a single shape against the reference
const only = debugFlags.get( 'only' );
if ( only && guiDict[ only ] ) {
for ( let fld of Object.keys( guiDict ) ) {
if ( fld === only || ! guiDict[ fld ][ 'object' ] ) continue;
guiDict[ fld ][ 'object' ].visible = false;
guiDict[ fld ][ 'objectLines' ].visible = false;
}
}
gui.close();
}
renderFlower()
// const spotLight = new THREE.SpotLight( 0xffffff );
const spotLight = new THREE.DirectionalLight( 0xeaa7a7, 1.5);
// legacy lighting was removed in three r155: intensities need the old value times pi
const spotLight = new THREE.DirectionalLight( 0xeaa7a7, 1.5 * Math.PI );
spotLight.position.set( 10, 0, 0 );
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 8182;
spotLight.shadow.mapSize.height = 8182;
// spotLight.shadow.mapSize.width = 4096;
// spotLight.shadow.mapSize.height = 4096;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.shadow.camera.far = 21;
spotLight.shadow.camera.left = -10;
spotLight.shadow.camera.right = 10;
+12 -12
View File
@@ -18,19 +18,21 @@ camera.position.x = 10;
camera.position.y = 4;
const renderer = new THREE.WebGLRenderer();
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( Math.min( window.devicePixelRatio, 2 ) );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.gammaFactor = 2.2;
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
renderer.physicallyCorrectLights
document.body.appendChild( renderer.domElement );
window.addEventListener( 'resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
} );
const controls = new OrbitControls( camera, renderer.domElement );
controls.target.set( -4, 0, 0 );
@@ -322,14 +324,12 @@ for (let x_angle of Array.from(Array(4), (_, i) => 360 / 4 * i)) {
}
}
// const spotLight = new THREE.SpotLight( 0xffffff );
const spotLight = new THREE.DirectionalLight( 0xeaa7a7, 1.5);
// legacy lighting was removed in three r155: intensities need the old value times pi
const spotLight = new THREE.DirectionalLight( 0xeaa7a7, 1.5 * Math.PI );
spotLight.position.set( 10, 0, 0 );
spotLight.castShadow = true;
// spotLight.shadow.mapSize.width = 8182;
// spotLight.shadow.mapSize.height = 8182;
spotLight.shadow.mapSize.width = 4096;
spotLight.shadow.mapSize.height = 4096;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
spotLight.shadow.camera.far = 21;
spotLight.shadow.camera.left = -10;
spotLight.shadow.camera.right = 10;
+3 -16
View File
@@ -31,24 +31,11 @@ module.exports = (env) => {
"sass-loader",
],
},
// {
// test: /\.m?js$/,
// exclude: /node_modules/,
// use: {
// loader: 'babel-loader',
// options: {
// presets: [
// ['@babel/preset-env', { targets: { chrome: "58", ie: "11" }}]
// ]
// }
// }
// }
// For newer versions of Webpack it should be
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader',
options: {
name: 'public/icons/[name].[ext]'
type: 'asset/resource',
generator: {
filename: 'public/icons/[name][ext]'
}
}
],