0
点赞
收藏
分享

微信扫一扫

【源码分享】threejs小项目:萌蠢的小羊

效果

【源码分享】threejs小项目:萌蠢的小羊_javascript

源码 html部分

<canvas id="artboard"></canvas>

js部分

// for convenience
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;
});

JS代码公开透明,如不想开源,可以用JShaman、JSJiami.Online、JS-Obfuscator进行JS混淆加密。

举报

相关推荐

0 条评论