What’s on our mind?

Collection of articles, design, site, and resources made by designers and publisher @Menu View


var pi = Math.PI;

var scene = new THREE.Scene();
var h = window.innerHeight,
    w = window.innerWidth;
var aspectRatio = w / h,
    fieldOfView = 45,
    nearPlane = 1,
    farPlane = 1000;
var camera = new THREE.PerspectiveCamera(
    fieldOfView,
    aspectRatio,
    nearPlane,
    farPlane
);
var renderer = new THREE.WebGLRenderer({
    canvas: artboard,
    alpha: true,
    antialias: true
});

const dpi = window.devicePixelRatio;
renderer.setSize(w * dpi, h * dpi);
const theCanvas = document.getElementById("artboard");
theCanvas.style.width = `${w}px`;
theCanvas.style.height = `${h}px`;

renderer.shadowMapEnabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);

//camera
camera.position.set(25, 5, 0);
camera.lookAt(new THREE.Vector3(0, 4, 0));

//lights, 3 point lighting
var col_light = 0xffffff; // set

var light = new THREE.AmbientLight(col_light, 0.6);

var keyLight = new THREE.DirectionalLight(col_light, 0.6);
keyLight.position.set(20, 30, 10);
keyLight.castShadow = true;
keyLight.shadow.camera.top = 20;

// var shadowHelper = new THREE.CameraHelper( keyLight.shadow.camera );
// scene.add( shadowHelper );

var fillLight = new THREE.DirectionalLight(col_light, 0.3);
fillLight.position.set(-20, 20, 20);

var backLight = new THREE.DirectionalLight(col_light, 0.1);
backLight.position.set(10, 0, -20);

scene.add(light);
scene.add(keyLight);
scene.add(fillLight);
scene.add(backLight);

// axis
// var axesHelper = new THREE.AxesHelper(50);
// scene.add(axesHelper);

//materials
var mat_orange = new THREE.MeshLambertMaterial({
    color: 0xff8c75
});
var mat_grey = new THREE.MeshLambertMaterial({
    color: 0xf3f2f7
});
var mat_yellow = new THREE.MeshLambertMaterial({
    color: 0xfeb42b
});
var mat_dark = new THREE.MeshLambertMaterial({
    color: 0x5a6e6c
});
var mat_brown = new THREE.MeshLambertMaterial({
    color: 0xa3785f
});
var mat_stone = new THREE.MeshLambertMaterial({
    color: 0x9eaeac
});
//-------------------------------------ground-------------------------------------
var layers = [];
var ground = new THREE.Group();
for (var i = 0; i < 5; i++) {
    var h = 0.1;
    var geometry = new THREE.CylinderGeometry(8 - i - 0.01, 8 - i, h, 9);
    layers.push(new THREE.Mesh(geometry, mat_orange));
    layers[i].position.y = h * i;
    layers[i].receiveShadow = true;
    ground.add(layers[i]);
}
layers[0].scale.x = 0.8;
layers[1].scale.set(0.77, 1, 0.91);
layers[1].rotation.y = ((2 * pi) / 9) * 0.6;
layers[2].scale.set(0.8, 1, 0.91);
layers[2].rotation.y = ((2 * pi) / 9) * 0.3;
layers[3].scale.set(0.75, 1, 0.92);
layers[3].rotation.y = ((2 * pi) / 9) * 0.7;
layers[4].scale.set(0.7, 1, 0.93);
layers[4].rotation.y = ((2 * pi) / 9) * 0.9;

var geo_base = new THREE.CylinderGeometry(8, 1, 10, 9);
var base = new THREE.Mesh(geo_base, mat_dark);
base.scale.x = layers[0].scale.x;
base.position.y = -5;
ground.add(base);

scene.add(ground);

//-------------------------------------trees-------------------------------------
var tree = new THREE.Group();

//trunk
var geo_trunk = new THREE.IcosahedronGeometry(9, 0);
var trunk = new THREE.Mesh(geo_trunk, mat_grey);
var a = new THREE.Vector3(1, 0, 10);
trunk.rotation.x = pi / 2;
trunk.position.y = 5;
trunk.scale.set(0.03, 0.03, 1);
trunk.castShadow = true;
trunk.receiveShadow = true;
tree.add(trunk);

//crown
var geo_crown = new THREE.IcosahedronGeometry(2.5, 0);
var crown = new THREE.Mesh(geo_crown, mat_yellow);
crown.scale.y = 0.4;
crown.rotation.z = -0.5;
crown.rotation.x = -0.2;
crown.position.set(trunk.position.x, 12, trunk.position.z);
crown.castShadow = true;
tree.add(crown);

//leaf
var leaf = new THREE.Group();
var mainStem = new THREE.Mesh(geo_trunk, mat_grey);
mainStem.scale.set(0.007, 0.007, 0.16);
mainStem.rotation.x = pi / 2;
mainStem.castShadow = true;
leaf.add(mainStem);

var geo_blade = new THREE.CylinderGeometry(0.7, 0.7, 0.05, 12);
var blade = new THREE.Mesh(geo_blade, mat_yellow);
blade.rotation.z = pi / 2;
blade.scale.x = 1.2;
blade.position.set(-0.05, 0.4, 0);
blade.castShadow = true;
leaf.add(blade);

var subStems = [];
for (var i = 0; i < 8; i++) {
    subStems[i] = mainStem.clone();
    subStems[i].scale.set(0.0055, 0.0055, 0.01);
    subStems[i].castShadow = true;
    leaf.add(subStems[i]);
}
subStems[0].rotation.x = -pi / 4;
subStems[0].scale.z = 0.04;
subStems[0].position.set(0, 0.8, 0.2);

subStems[2].rotation.x = -pi / 6;
subStems[2].scale.z = 0.05;
subStems[2].position.set(0, 0.5, 0.25);

subStems[4].rotation.x = -pi / 8;
subStems[4].scale.z = 0.055;
subStems[4].position.set(0, 0.2, 0.3);

subStems[6].rotation.x = -pi / 10;
subStems[6].scale.z = 0.045;
subStems[6].position.set(0, -0.1, 0.26);

for (var i = 1; i < 8; i += 2) {
    subStems[i].rotation.x = -subStems[i - 1].rotation.x;
    subStems[i].scale.z = subStems[i - 1].scale.z;
    subStems[i].position.set(
        0,
        subStems[i - 1].position.y,
        -subStems[i - 1].position.z
    );
}
leaf.rotation.x = pi / 3;
leaf.rotation.z = 0.2;
leaf.position.set(trunk.position.x - 0.2, 5, trunk.position.z + 1);
tree.add(leaf);

var leaf_1 = leaf.clone();
leaf_1.rotation.x = -pi / 3;
leaf_1.position.set(trunk.position.x - 0.2, 6, trunk.position.z - 1);
tree.add(leaf_1);
tree.rotation.y = -pi / 12;
tree.position.set(-2, 0, -2);
scene.add(tree);

var tree_1 = tree.clone();
tree_1.scale.set(0.8, 0.8, 0.8);
tree_1.position.set(-1, 0, -5);
tree_1.rotation.y = -pi / 5;
scene.add(tree_1);

var tree_2 = tree.clone();
tree_2.scale.set(0.7, 0.7, 0.7);
tree_2.position.set(-2, 0, 0.5);
tree_2.rotation.y = -pi / 12;
tree_2.children[2].rotation.x = -pi / 3;
tree_2.children[2].position.z = trunk.position.z - 1;
tree_2.children[3].rotation.x = pi / 3;
tree_2.children[3].position.z = trunk.position.z + 1;
scene.add(tree_2);

//-------------------------------------stone-------------------------------------
var geo_stone = new THREE.DodecahedronGeometry(1, 0);
var stone = [];
for (var i = 0; i < 2; i++) {
    stone[i] = new THREE.Mesh(geo_stone, mat_stone);
    scene.add(stone[i]);
    stone[i].castShadow = true;
}
stone[0].rotation.set(0, 12, pi / 2);
stone[0].scale.set(3, 1, 1);
stone[0].position.set(-1, 1, 4.6);

stone[1].rotation.set(0, 0, pi / 2);
stone[1].scale.set(1, 1, 1);
stone[1].position.set(0, 0.7, 5.3);

//-------------------------------------sheep-------------------------------------
//sheep body
var sheep = new THREE.Group();
// var geo_sheepHead=new THREE.SphereGeometry(.5,8,6);
var geo_sheepHead = new THREE.IcosahedronGeometry(1, 0);
var sheepHead = new THREE.Mesh(geo_sheepHead, mat_dark);
sheepHead.scale.z = 0.6;
sheepHead.scale.y = 1.1;
sheepHead.position.y = 2.5;
sheepHead.rotation.x = -0.2;
sheepHead.castShadow = true;
sheep.add(sheepHead);

var geo_sheepBody = new THREE.IcosahedronGeometry(3.5, 0);
var sheepBody = new THREE.Mesh(geo_sheepBody, mat_grey);
sheepBody.position.set(0, sheepHead.position.y, -2.2);
sheepBody.scale.set(0.5, 0.5, 0.6);
sheepBody.rotation.set(0, 0, pi / 3);
sheepBody.castShadow = true;
sheep.add(sheepBody);

var geo_tail = new THREE.IcosahedronGeometry(0.5, 0);
var tail = new THREE.Mesh(geo_tail, mat_grey);
tail.position.set(sheepHead.position.x, sheepHead.position.y + 1.2, -3.8);
tail.castShadow = true;
sheep.add(tail);

var hair = [];
var geo_hair = new THREE.IcosahedronGeometry(0.4, 0);
for (var i = 0; i < 5; i++) {
    hair[i] = new THREE.Mesh(geo_hair, mat_grey);
    hair[i].castShadow = true;
    sheep.add(hair[i]);
}

hair[0].position.set(-0.4, sheepHead.position.y + 0.9, -0.1);
hair[1].position.set(0, sheepHead.position.y + 1, -0.1);
hair[2].position.set(0.4, sheepHead.position.y + 0.9, -0.1);
hair[3].position.set(-0.1, sheepHead.position.y + 0.9, -0.4);
hair[4].position.set(0.12, sheepHead.position.y + 0.9, -0.4);

hair[0].rotation.set(pi / 12, 0, pi / 3);
hair[1].rotation.set(pi / 12, pi / 6, pi / 3);
hair[2].rotation.set(pi / 12, 0, pi / 3);
hair[3].rotation.set(pi / 12, 0, pi / 3);
hair[4].rotation.set(pi / 12, pi / 6, pi / 3);

hair[0].scale.set(0.6, 0.6, 0.6);
hair[2].scale.set(0.8, 0.8, 0.8);
hair[3].scale.set(0.7, 0.7, 0.7);
hair[4].scale.set(0.6, 0.6, 0.6);

var legs = [];
var geo_leg = new THREE.CylinderGeometry(0.15, 0.1, 1, 5);
for (var i = 0; i < 4; i++) {
    legs[i] = new THREE.Mesh(geo_leg, mat_dark);
    legs[i].castShadow = true;
    legs[i].receiveShadow = true;
    sheep.add(legs[i]);
}
legs[0].position.set(0.5, 1.1, -1.5);
legs[1].position.set(-0.5, 1.1, -1.5);
legs[2].position.set(0.8, 1.1, -3);
legs[3].position.set(-0.8, 1.1, -3);

var feet = [];
var geo_foot = new THREE.DodecahedronGeometry(0.2, 0);
for (var i = 0; i < legs.length; i++) {
    feet[i] = new THREE.Mesh(geo_foot, mat_dark);
    sheep.add(feet[i]);
    feet[i].scale.set(1, 0.8, 1);
    feet[i].castShadow = true;
    feet[i].receiveShadow = true;
    feet[i].position.set(legs[i].position.x, 0, legs[i].position.z + 0.09);
}
feet[0].position.y = 0.56;
feet[1].position.y = 0.66;
feet[2].position.y = 0.7;
feet[3].position.y = 0.7;

//eyes
var geo_eye = new THREE.CylinderGeometry(0.3, 0.2, 0.05, 8);
var eyes = [];
for (var i = 0; i < 2; i++) {
    eyes[i] = new THREE.Mesh(geo_eye, mat_grey);
    sheep.add(eyes[i]);
    eyes[i].castShadow = true;
    eyes[i].position.set(0, sheepHead.position.y + 0.1, 0.5);
    eyes[i].rotation.x = pi / 2 - pi / 15;
}
eyes[0].position.x = 0.3;
eyes[1].position.x = -eyes[0].position.x;

eyes[0].rotation.z = -pi / 15;
eyes[1].rotation.z = -eyes[0].rotation.z;

//eyeballs
var geo_eyeball = new THREE.SphereGeometry(0.11, 8, 8);
eyeballs = [];
for (var i = 0; i < 2; i++) {
    eyeballs[i] = new THREE.Mesh(geo_eyeball, mat_dark);
    sheep.add(eyeballs[i]);
    eyeballs[i].castShadow = true;
    eyeballs[i].position.set(
        eyes[i].position.x,
        eyes[i].position.y,
        eyes[i].position.z + 0.02
    );
}

sheep.position.set(4.8, -0.2, -1);
sheep.scale.set(0.8, 0.8, 0.8);
sheep.rotation.set(0, pi / 4, 0);
scene.add(sheep);

//fence
var fence = new THREE.Group();
var wood = [];
var geo_wood = new THREE.BoxGeometry(1, 1, 1);
for (var i = 0; i < 4; i++) {
    wood[i] = new THREE.Mesh(geo_wood, mat_brown);
    fence.add(wood[i]);
    wood[i].castShadow = true;
    wood[i].receiveShadow = true;
}
wood[0].scale.set(0.15, 1.7, 0.4);
wood[1].scale.set(0.15, 1.8, 0.4);
wood[2].scale.set(0.1, 0.3, 3.2);
wood[3].scale.set(0.1, 0.3, 3.2);

wood[0].position.set(0, 1.2, -1);
wood[1].position.set(0, 1, 1);
// wood[2].position.set(.12,1.5,0);
wood[2].position.set(0, 1.5, 0);
wood[3].position.set(0.12, 0.9, 0);

wood[3].rotation.x = pi / 32;
wood[2].rotation.x = -pi / 32;
wood[2].rotation.y = pi / 32;

fence.position.set(3, 0, 2);
fence.rotation.y = pi / 5;
scene.add(fence);

//render
var render = function () {
    requestAnimationFrame(render);
    renderer.render(scene, camera);
};
render();

//mouse control
var context = theCanvas.getContext("2d");
theCanvas.addEventListener("mousemove", function (evt) {
    var rect = theCanvas.getBoundingClientRect();
    var mouseX = evt.clientX - rect.left;
    var mouseY = evt.clientY - rect.top;

    var offsetX = 0.2 / rect.width * (mouseX - rect.width / 2);
    // var offsetY = 0.001 * (mouseY - h / 2);
    var offsetY = 0.3 / rect.height * (mouseY - (rect.height * 2) / 5);
    eyeballs[0].position.x = eyes[0].position.x + offsetX;
    eyeballs[0].position.y = eyes[0].position.y - offsetY;
    eyeballs[1].position.x = eyes[1].position.x + offsetX;
    eyeballs[1].position.y = eyes[1].position.y - offsetY;
});

// 출처 https://codepen.io/yitliu