Last active
January 18, 2021 09:33
-
-
Save chicio/af13397f22c21a05b6ac007c83f84403 to your computer and use it in GitHub Desktop.
Physically based scene using three.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Create main scene light. | |
* | |
* @returns a point light scene. | |
*/ | |
function createLight() { | |
var lightGeometry = new THREE.SphereGeometry(0); | |
var lightMaterial = new THREE.MeshStandardMaterial({ | |
emissive: 0xffffee, | |
emissiveIntensity: 1, | |
color: 0x000000 | |
}); | |
var light = new THREE.PointLight(0xffffff, 1, 20, 2); | |
light.power = 1700; | |
light.castShadow = true; | |
light.shadow.mapSize.width = 512; | |
light.shadow.mapSize.height = 512; | |
light.shadow.radius = 1.5; | |
light.add(new THREE.Mesh(lightGeometry, lightMaterial)); | |
light.position.set(0, 5, 3); | |
return light; | |
} | |
/** | |
* Create scene camera. | |
* | |
* @returns the scene camera. | |
*/ | |
function createCamera() { | |
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); | |
camera.position.z = 8; | |
camera.position.y = 0; | |
camera.position.x = 0; | |
return camera; | |
} | |
/** | |
* Create scene hemispere light. | |
* | |
* @returns the scene hemisphere light. | |
*/ | |
function createHemisphereLight() { | |
return new THREE.HemisphereLight(0x303F9F, 0x000000, 1); | |
} | |
/** | |
* Load sky stars. | |
* | |
* @param textureLoader the texture loader. | |
* @param completeLoad the load complete function. | |
*/ | |
function loadStars(textureLoader, completeLoad) { | |
textureLoader.load("assets/models/textures/circle.png", function (texture) { | |
var starsGeometry = new THREE.Geometry(); | |
for (var i = 0; i < 10000; i++) { | |
var star = new THREE.Vector3(); | |
star.x = 2000 * Math.random() - 1000; | |
star.y = 2000 * Math.random(); | |
star.z = 2000 * Math.random() - 1000; | |
starsGeometry.vertices.push(star) | |
} | |
var starsMaterial = new THREE.PointsMaterial({ | |
color: 0x888888, | |
map: texture, | |
transparent: true, | |
}); | |
var stars = new THREE.Points(starsGeometry, starsMaterial); | |
completeLoad(stars); | |
}); | |
} | |
/** | |
* Load ply model. | |
* | |
* @param plyLoader ply loader. | |
* @param path path to ply file. | |
* @param parameters mesh parameters. | |
* @param position vector3 with position. | |
* @param rotation vector3 with rotation. | |
* @param completeLoad load complete function. | |
*/ | |
function loadPlyModelUsingPhysicalMaterial(plyLoader, path, parameters, position, rotation, completeLoad) { | |
plyLoader.load(path, function (geometry) { | |
var material = new THREE.MeshPhysicalMaterial(parameters); | |
var mesh = new THREE.Mesh(geometry, material); | |
mesh.position.set(position.x, position.y, position.z); | |
mesh.rotation.set(rotation.x, rotation.y, rotation.z); | |
mesh.castShadow = true; | |
mesh.matrixAutoUpdate = false; | |
mesh.updateMatrix(); | |
completeLoad(mesh); | |
}); | |
} | |
/** | |
* Load floor. | |
* | |
* @param textureLoader texture loader. | |
* @param completionFunction load complete function. | |
*/ | |
function loadFloor(textureLoader, completionFunction) { | |
textureLoader.load("assets/models/textures/marble.jpg", function (texture) { | |
texture.wrapS = THREE.RepeatWrapping; | |
texture.wrapT = THREE.RepeatWrapping; | |
texture.repeat.set(100, 100); | |
var floorMat = new THREE.MeshStandardMaterial({ | |
roughness: 0.7, | |
metalness: 0.1, | |
map: texture | |
}); | |
var floorGeometry = new THREE.PlaneGeometry(1000, 1000); | |
var floorMesh = new THREE.Mesh(floorGeometry, floorMat); | |
floorMesh.receiveShadow = true; | |
floorMesh.rotation.x = -Math.PI / 2.0; | |
floorMesh.position.y = -3; | |
floorMesh.matrixAutoUpdate = false; | |
floorMesh.updateMatrix(); | |
completionFunction(floorMesh); | |
}); | |
} | |
/** | |
* Create orbits controls. | |
* | |
* @param camera the scene camera. | |
* @param renderer the renderer. | |
* | |
* @returns the orbits control. | |
*/ | |
function createOrbitsControls(camera, renderer) { | |
var controls = new THREE.OrbitControls(camera, renderer.domElement); | |
controls.enableZoom = false; | |
controls.autoRotate = true; | |
controls.enablePan = false; | |
controls.keyPanSpeed = 7.0; | |
controls.enableKeys = false; | |
controls.target = new THREE.Vector3(0, 0, 0); | |
controls.mouseButtons = {}; | |
controls.dispose(); | |
return controls; | |
} | |
/** | |
* Create a threejs WebGL renderer. | |
* | |
* @returns a WebGLRenderer. | |
*/ | |
function createRenderer() { | |
var renderer = new THREE.WebGLRenderer({alpha: true}); | |
renderer.physicallyCorrectLights = true; | |
renderer.gammaInput = true; | |
renderer.gammaOutput = true; | |
renderer.shadowMap.enabled = true; | |
renderer.shadowMap.type = THREE.PCFSoftShadowMap; | |
renderer.setSize($(window).width(), $(window).height()); | |
return renderer; | |
} | |
/** | |
* Threejs Scene. | |
* | |
*/ | |
function sceneThreeJS() { | |
var scene = new THREE.Scene(); | |
var camera = createCamera(); | |
var textureLoader = new THREE.TextureLoader(); | |
var plyLoader = new THREE.PLYLoader(); | |
var renderer = createRenderer(); | |
var controls = createOrbitsControls(camera, renderer); | |
//Add rendering dom element to page. | |
document.getElementById("rendering-surface").appendChild(renderer.domElement); | |
//Setup scene. | |
scene.background = new THREE.Color(0x303F9F); | |
scene.add(createLight()); | |
scene.add(createHemisphereLight()); | |
//Load models. | |
loadStars(textureLoader, function (stars) { | |
scene.add(stars); | |
}); | |
loadPlyModelUsingPhysicalMaterial( | |
plyLoader, | |
'assets/models/lucy.ply', | |
{ | |
color: 0x3F51B5, | |
roughness: 0.5, | |
metalness: 0.7, | |
clearCoat: 0.5, | |
clearCoatRoughness: 0.5, | |
reflectivity: 0.7 | |
}, | |
new THREE.Vector3(3, -3, 0), | |
new THREE.Vector3(0, -Math.PI / 3.0, 0), | |
function (mesh) { | |
scene.add(mesh); | |
} | |
); | |
loadPlyModelUsingPhysicalMaterial( | |
plyLoader, | |
'assets/models/dragon.ply', | |
{ | |
color: 0x448AFF, | |
roughness: 0.1, | |
metalness: 0.9, | |
clearCoat: 0.0, | |
clearCoatRoughness: 0.2, | |
reflectivity: 1 | |
}, | |
new THREE.Vector3(-3, -3, 0), | |
new THREE.Vector3(0, -Math.PI, 0), | |
function (mesh) { | |
scene.add(mesh); | |
} | |
); | |
loadPlyModelUsingPhysicalMaterial( | |
plyLoader, | |
'assets/models/bunny.ply', | |
{ | |
color: 0xCCFFFF, | |
roughness: 0.9, | |
metalness: 0.1, | |
clearCoat: 0.0, | |
clearCoatRoughness: 0.5, | |
reflectivity: 0.1 | |
}, | |
new THREE.Vector3(0, -3, 1.5), | |
new THREE.Vector3(0, -Math.PI, 0), | |
function (mesh) { | |
scene.add(mesh); | |
} | |
); | |
loadFloor(textureLoader, function (mesh) { | |
scene.add(mesh); | |
}); | |
//Setup rendering function. | |
var render = function () { | |
requestAnimationFrame(render); | |
controls.update(); | |
renderer.render(scene, camera); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment