PBR Materials
BIN
img/angled-blocks-vegetation_albedo.png
Normal file
After Width: | Height: | Size: 7.2 MiB |
BIN
img/angled-blocks-vegetation_ao.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
img/angled-blocks-vegetation_height.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
img/angled-blocks-vegetation_metallic.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
img/angled-blocks-vegetation_normal-dx.png
Normal file
After Width: | Height: | Size: 9.1 MiB |
BIN
img/angled-blocks-vegetation_roughness.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
img/pavement.jpg
Before Width: | Height: | Size: 501 KiB |
BIN
img/stonewall-albedo.png
Normal file
After Width: | Height: | Size: 7.0 MiB |
BIN
img/stonewall-ao.png
Normal file
After Width: | Height: | Size: 556 KiB |
BIN
img/stonewall-height2.png
Normal file
After Width: | Height: | Size: 5.6 MiB |
BIN
img/stonewall-metalness.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
img/stonewall-normal.png
Normal file
After Width: | Height: | Size: 9.6 MiB |
BIN
img/stonewall-roughness.png
Normal file
After Width: | Height: | Size: 2.4 MiB |
BIN
img/wall.jpg
Before Width: | Height: | Size: 2.1 MiB |
@ -12,8 +12,8 @@
|
|||||||
<script type="importmap">
|
<script type="importmap">
|
||||||
{
|
{
|
||||||
"imports": {
|
"imports": {
|
||||||
"three": "https://unpkg.com/three@0.152.2/build/three.module.js?module",
|
"three": "https://unpkg.com/three@0.153/build/three.module.js?module",
|
||||||
"three/addons/": "https://unpkg.com/three@0.152.2/examples/jsm/"
|
"three/addons/": "https://unpkg.com/three@0.153/examples/jsm/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
143
main.js
@ -39,7 +39,7 @@ loadMngr.onStart = function (url, itemsLoaded, itemsTotal) {
|
|||||||
message.innerHTML = 'Chargement : 0%...'
|
message.innerHTML = 'Chargement : 0%...'
|
||||||
}
|
}
|
||||||
loadMngr.onProgress = function (url, itemsLoaded, itemsTotal) {
|
loadMngr.onProgress = function (url, itemsLoaded, itemsTotal) {
|
||||||
message.innerHTML = 'Chargement : ' + 100 * itemsLoaded / itemsTotal + '%...'
|
message.innerHTML = 'Chargement : ' + Math.floor(100 * itemsLoaded / itemsTotal) + '%...'
|
||||||
}
|
}
|
||||||
loadMngr.onError = function (url) {
|
loadMngr.onError = function (url) {
|
||||||
message.innerHTML = 'Erreur de chargement'
|
message.innerHTML = 'Erreur de chargement'
|
||||||
@ -79,17 +79,13 @@ const raftOctree = new Octree();
|
|||||||
// Maze
|
// Maze
|
||||||
|
|
||||||
const wallTexture = loader.load('img/wall.jpg');
|
const wallTexture = loader.load('img/wall.jpg');
|
||||||
const wallMaterial = new THREE.MeshPhongMaterial({
|
const wallMaterial = new THREE.MeshStandardMaterial({
|
||||||
map: wallTexture,
|
map: loader.load('img/stonewall-albedo.png'),
|
||||||
color: 0xFCF8E5,
|
normalMap: loader.load('img/stonewall-normal.png'),
|
||||||
emissive: 0,
|
metalnessMap: loader.load('img/stonewall-metalness.png'),
|
||||||
specular: 0x505050,
|
aoMap: loader.load('img/stonewall-ao.png'),
|
||||||
shininess: 4,
|
roughnessMap: loader.load('img/stonewall-roughness.png'),
|
||||||
bumpMap: wallTexture,
|
|
||||||
bumpScale: .005,
|
|
||||||
depthFunc: 3,
|
|
||||||
depthTest: true,
|
|
||||||
depthWrite: true
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const maze = new MazeMesh(mazeWidth, mazeWidth, wallMaterial);
|
const maze = new MazeMesh(mazeWidth, mazeWidth, wallMaterial);
|
||||||
@ -112,7 +108,7 @@ for (let i = 0; i < maze.count; i++) {
|
|||||||
// Ground
|
// Ground
|
||||||
|
|
||||||
const pavementTexture = loader.load(
|
const pavementTexture = loader.load(
|
||||||
'img/pavement.jpg',
|
'img/angled-blocks-vegetation_albedo.png',
|
||||||
texture => {
|
texture => {
|
||||||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
|
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
|
||||||
texture.repeat.set(mazeWidth / 2, mazeWidth / 2)
|
texture.repeat.set(mazeWidth / 2, mazeWidth / 2)
|
||||||
@ -120,32 +116,59 @@ const pavementTexture = loader.load(
|
|||||||
);
|
);
|
||||||
const groundGeometry = new THREE.BoxGeometry(mazeWidth, mazeWidth, 1)
|
const groundGeometry = new THREE.BoxGeometry(mazeWidth, mazeWidth, 1)
|
||||||
const groundMaterial = new THREE.MeshPhongMaterial({
|
const groundMaterial = new THREE.MeshPhongMaterial({
|
||||||
map: pavementTexture,
|
map: loader.load(
|
||||||
color: 0xFFFFFF,
|
'img/angled-blocks-vegetation_albedo.png',
|
||||||
emissive: 0,
|
texture => {
|
||||||
specular: 0x000000,
|
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
|
||||||
shininess: 5,
|
texture.repeat.set(mazeWidth / 2, mazeWidth / 2)
|
||||||
bumpMap: pavementTexture,
|
}
|
||||||
bumpScale: .02,
|
),
|
||||||
depthFunc: 3,
|
aoMap: loader.load(
|
||||||
depthTest: true,
|
'img/angled-blocks-vegetation_ao.png',
|
||||||
depthWrite: true
|
texture => {
|
||||||
})
|
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
|
||||||
const sideGroundTexture = wallTexture.clone()
|
texture.repeat.set(mazeWidth / 2, mazeWidth / 2)
|
||||||
sideGroundTexture.wrapS = sideGroundTexture.wrapT = THREE.RepeatWrapping
|
}
|
||||||
sideGroundTexture.repeat.set(mazeWidth, 1)
|
),
|
||||||
const sideGroundMaterial = new THREE.MeshPhongMaterial({
|
metalnessMap: loader.load(
|
||||||
map: sideGroundTexture,
|
'img/angled-blocks-vegetation_metallic.png',
|
||||||
color: 0xFCF8E5,
|
texture => {
|
||||||
emissive: 0,
|
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
|
||||||
specular: 0x505050,
|
texture.repeat.set(mazeWidth / 2, mazeWidth / 2)
|
||||||
shininess: 4,
|
}
|
||||||
bumpMap: sideGroundTexture,
|
),
|
||||||
bumpScale: .01,
|
normalMap: loader.load(
|
||||||
depthFunc: 3,
|
'img/angled-blocks-vegetation_normal-dx.png',
|
||||||
depthTest: true,
|
texture => {
|
||||||
depthWrite: true
|
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
|
||||||
|
texture.repeat.set(mazeWidth / 2, mazeWidth / 2)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
roughnessMap: loader.load(
|
||||||
|
'img/angled-blocks-vegetation_roughness.png',
|
||||||
|
texture => {
|
||||||
|
texture.wrapS = texture.wrapT = THREE.RepeatWrapping
|
||||||
|
texture.repeat.set(mazeWidth / 2, mazeWidth / 2)
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
const sideGroundMaterial = new THREE.MeshStandardMaterial()
|
||||||
|
sideGroundMaterial.map = wallMaterial.map.clone()
|
||||||
|
sideGroundMaterial.map.wrapS = sideGroundMaterial.map.wrapT = THREE.RepeatWrapping
|
||||||
|
sideGroundMaterial.map.repeat.set(mazeWidth, 1)
|
||||||
|
sideGroundMaterial.normalMap = wallMaterial.normalMap.clone()
|
||||||
|
sideGroundMaterial.normalMap.wrapS = sideGroundMaterial.normalMap.wrapT = THREE.RepeatWrapping
|
||||||
|
sideGroundMaterial.normalMap.repeat.set(mazeWidth, 1)
|
||||||
|
sideGroundMaterial.metalnessMap = wallMaterial.map.clone()
|
||||||
|
sideGroundMaterial.metalnessMap.wrapS = sideGroundMaterial.normalMap.wrapT = THREE.RepeatWrapping
|
||||||
|
sideGroundMaterial.metalnessMap.repeat.set(mazeWidth, 1)
|
||||||
|
sideGroundMaterial.aoMap = wallMaterial.map.clone()
|
||||||
|
sideGroundMaterial.aoMap.wrapS = sideGroundMaterial.aoMap.wrapT = THREE.RepeatWrapping
|
||||||
|
sideGroundMaterial.aoMap.repeat.set(mazeWidth, 1)
|
||||||
|
sideGroundMaterial.roughnessMap = wallMaterial.map.clone()
|
||||||
|
sideGroundMaterial.roughnessMap.wrapS = sideGroundMaterial.roughnessMap.wrapT = THREE.RepeatWrapping
|
||||||
|
sideGroundMaterial.roughnessMap.repeat.set(mazeWidth, 1)
|
||||||
|
|
||||||
const ground = new THREE.Mesh(
|
const ground = new THREE.Mesh(
|
||||||
groundGeometry,
|
groundGeometry,
|
||||||
[
|
[
|
||||||
@ -244,14 +267,14 @@ skyUniforms['rayleigh'].value = 2;
|
|||||||
skyUniforms['mieCoefficient'].value = 0.005;
|
skyUniforms['mieCoefficient'].value = 0.005;
|
||||||
skyUniforms['mieDirectionalG'].value = 0.8;
|
skyUniforms['mieDirectionalG'].value = 0.8;
|
||||||
|
|
||||||
const pmremGenerator = new THREE.PMREMGenerator(renderer);
|
//const pmremGenerator = new THREE.PMREMGenerator(renderer);
|
||||||
|
|
||||||
// Lights
|
// Lights
|
||||||
|
|
||||||
const ambientLight = new THREE.AmbientLight(0x888888, 1); // soft white light
|
const ambientLight = new THREE.AmbientLight(0x404040, 6);
|
||||||
scene.add(ambientLight);
|
scene.add(ambientLight);
|
||||||
|
|
||||||
const sunLight = new THREE.DirectionalLight(0xffffff, 0.3);
|
const sunLight = new THREE.DirectionalLight(0xffffff, 2);
|
||||||
sunLight.castShadow = true;
|
sunLight.castShadow = true;
|
||||||
sunLight.shadow.camera.near = 50;
|
sunLight.shadow.camera.near = 50;
|
||||||
sunLight.shadow.camera.far = 300;
|
sunLight.shadow.camera.far = 300;
|
||||||
@ -267,12 +290,32 @@ scene.add(sunLight);
|
|||||||
|
|
||||||
updateSun();
|
updateSun();
|
||||||
|
|
||||||
|
function updateSun() {
|
||||||
|
|
||||||
|
const phi = THREE.MathUtils.degToRad(90 - parameters.elevation);
|
||||||
|
const theta = THREE.MathUtils.degToRad(parameters.azimuth);
|
||||||
|
|
||||||
|
sun.setFromSphericalCoords(100, phi, theta);
|
||||||
|
|
||||||
|
sky.material.uniforms['sunPosition'].value.copy(sun);
|
||||||
|
ocean.material.uniforms['sunDirection'].value.copy(sun).normalize();
|
||||||
|
|
||||||
|
sunLight.position.copy(sun)
|
||||||
|
|
||||||
|
ambientLight.intensity = 2 + 5 * Math.sin(Math.max(THREE.MathUtils.degToRad(parameters.elevation), 0));
|
||||||
|
|
||||||
|
//scene.environment = pmremGenerator.fromScene(sky).texture;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Raft
|
// Raft
|
||||||
|
|
||||||
const raftGeometry = new THREE.BoxGeometry(1.8, .1, .9, 1, 1, 8)
|
const raftGeometry = new THREE.BoxGeometry(1.8, .1, .9, 1, 1, 8)
|
||||||
const woodTexture = loader.load('img/wood.jpg');
|
const woodTexture = loader.load('img/wood.jpg');
|
||||||
const raftMaterial = new THREE.MeshPhongMaterial({
|
const raftMaterial = new THREE.MeshPhongMaterial({
|
||||||
map: woodTexture,
|
map: woodTexture,
|
||||||
|
aoMap: woodTexture,
|
||||||
|
roughnessMap: woodTexture,
|
||||||
color: 0xFFFFFF,
|
color: 0xFFFFFF,
|
||||||
emissive: 0,
|
emissive: 0,
|
||||||
specular: 0x505050,
|
specular: 0x505050,
|
||||||
@ -679,24 +722,6 @@ function updateRaft(delta) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSun() {
|
|
||||||
|
|
||||||
const phi = THREE.MathUtils.degToRad(90 - parameters.elevation);
|
|
||||||
const theta = THREE.MathUtils.degToRad(parameters.azimuth);
|
|
||||||
|
|
||||||
sun.setFromSphericalCoords(100, phi, theta);
|
|
||||||
|
|
||||||
sky.material.uniforms['sunPosition'].value.copy(sun);
|
|
||||||
ocean.material.uniforms['sunDirection'].value.copy(sun).normalize();
|
|
||||||
|
|
||||||
sunLight.position.copy(sun)
|
|
||||||
|
|
||||||
ambientLight.intensity = 0.5 + Math.sin(Math.max(THREE.MathUtils.degToRad(parameters.elevation), 0));
|
|
||||||
|
|
||||||
scene.environment = pmremGenerator.fromScene(sky).texture;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('resize', onWindowResize);
|
window.addEventListener('resize', onWindowResize);
|
||||||
|
|
||||||
function onWindowResize() {
|
function onWindowResize() {
|
||||||
|