Skip to content

Instantly share code, notes, and snippets.

@chicio
Last active January 18, 2021 09:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save chicio/af13397f22c21a05b6ac007c83f84403 to your computer and use it in GitHub Desktop.
Save chicio/af13397f22c21a05b6ac007c83f84403 to your computer and use it in GitHub Desktop.
Physically based scene using three.js
/**
* 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