当前位置: 首页 > news >正文

【threejs】每天一个小案例讲解:创建基本的3D场景

代码仓

GitHub - TiffanyHoo/three_practices: Learning three.js together!

可自行clone,无需安装依赖,直接liver-server运行/直接打开chapter01中的html文件

运行效果图

知识要点

核心运行代码

<!DOCTYPE html><html><head><title>Example 03.02 - point Light</title><script type="text/javascript" src="../libs/three.js"></script><script type="text/javascript" src="../libs/stats.js"></script><script type="text/javascript" src="../libs/dat.gui.js"></script><style>body {/* set margin to 0 and overflow to hidden, to go fullscreen */margin: 0;overflow: hidden;}</style>
</head><body><div id="Stats-output"></div><!-- Div which will hold the Output --><div id="WebGL-output"></div><!-- Javascript code that runs our Three.js examples --><script type="text/javascript">// once everything is loaded, we run our Three.js stuff.function init() {// create a scene, that will hold all our elements such as objects, cameras and lights.var scene = new THREE.Scene();// create a camera, which defines where we're looking at.var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);// create a render and set the sizevar renderer = new THREE.WebGLRenderer();// var renderer = new THREE.WebGLRenderer({alpha: true});/*** alpha: true 启用透明度支持* !!!透明度没有生效* 1.因为没有启用渲染器透明度支持* 2.没有正确使用setClearColor方法两个参数*   renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));*   透明度 (0-1) 0 完全透明 1完全不透明**/renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));renderer.setSize(window.innerWidth, window.innerHeight);// renderer.shadowMapEnabled = true;// 启用阴影贴图:用于在3D场景中生成和渲染物体的阴影// create the ground planevar planeGeometry = new THREE.PlaneGeometry(60, 20, 20, 20);var planeMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff });var plane = new THREE.Mesh(planeGeometry, planeMaterial);plane.receiveShadow = true; // 接收阴影// rotate and position the planeplane.rotation.x = -0.5 * Math.PI;plane.position.x = 15;plane.position.y = 0;plane.position.z = 0;// add the plane to the scenescene.add(plane);// create a cubevar cubeGeometry = new THREE.BoxGeometry(4, 4, 4);var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xff7777 });// MeshLambertMaterial 基于Lambert反射模型的材质,适用于不发光且没有高光的物体(表面粗糙、没有明显反光)。它支持颜色、贴图、透明度等属性。var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);cube.castShadow = true; // 投射阴影// position the cubecube.position.x = -4;cube.position.y = 3;cube.position.z = 0;// add the cube to the scenescene.add(cube);var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0x7777ff });var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);// position the spheresphere.position.x = 20;sphere.position.y = 0;sphere.position.z = 2;sphere.castShadow = true;// add the sphere to the scenescene.add(sphere);// position and point the camera to the center of the scenecamera.position.x = -25;camera.position.y = 30;camera.position.z = 25;camera.lookAt(new THREE.Vector3(10, 0, 0));// 添加光源// add subtle ambient lightingvar ambiColor = "#0c0c0c";var ambientLight = new THREE.AmbientLight(ambiColor);scene.add(ambientLight);// add spotlight for the shadowsvar spotLight = new THREE.SpotLight(0xffffff);console.log(spotLight.position);spotLight.position.set(-40, 60, -10);spotLight.castShadow = true;console.log(spotLight);console.log(spotLight.target); // 默认(0,0,0)console.log(spotLight.shadow); // undefined shadow属性是在r128之后引入的// scene.add( spotLight );var pointColor = "#ccffcc";var pointLight = new THREE.PointLight(pointColor); // 无阴影pointLight.distance = 100; // 0 无限远 光线强度不随距离增加而减弱scene.add(pointLight);// add a small sphere simulating the pointlightvar sphereLight = new THREE.SphereGeometry(0.2);var sphereLightMaterial = new THREE.MeshBasicMaterial({ color: 0xac6c25 });var sphereLightMesh = new THREE.Mesh(sphereLight, sphereLightMaterial);sphereLightMesh.castShadow = true;sphereLightMesh.position = new THREE.Vector3(3, 0, 3);scene.add(sphereLightMesh);// const directionalLight = new THREE.DirectionalLight(0xffffff, 1);// directionalLight.position.set(-40, 60, -10);// directionalLight.castShadow = true;// scene.add(directionalLight);// add the output of the renderer to the html elementdocument.getElementById("WebGL-output").appendChild(renderer.domElement);// call the render functionvar step = 0;// used to determine the switch point for the light animationvar invert = 1;var phase = 0;var controls = new function () {this.rotationSpeed = 0.03;this.bouncingSpeed = 0.03;this.ambientColor = ambiColor;this.pointColor = pointColor;this.intensity = 1;this.distance = 100;};var gui = new dat.GUI();gui.addColor(controls, 'ambientColor').onChange(function (e) {ambientLight.color = new THREE.Color(e);});gui.addColor(controls, 'pointColor').onChange(function (e) {pointLight.color = new THREE.Color(e);});gui.add(controls, 'intensity', 0, 3).onChange(function (e) {pointLight.intensity = e;});gui.add(controls, 'distance', 0, 100).onChange(function (e) {pointLight.distance = e;});var stats = initStats();render();function render() {stats.update();// rotate the cube around its axescube.rotation.x += controls.rotationSpeed;cube.rotation.y += controls.rotationSpeed;cube.rotation.z += controls.rotationSpeed;// bounce the sphere up and downstep += controls.bouncingSpeed;sphere.position.x = 20 + (10 * (Math.cos(step)));sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));// move the light simulationif (phase > 2 * Math.PI) {invert = invert * -1;phase -= 2 * Math.PI;} else {phase += controls.rotationSpeed;}sphereLightMesh.position.z = +(7 * (Math.sin(phase)));sphereLightMesh.position.x = +(14 * (Math.cos(phase)));sphereLightMesh.position.y = 5;if (invert < 0) {var pivot = 14;sphereLightMesh.position.x = (invert * (sphereLightMesh.position.x - pivot)) + pivot;}pointLight.position.copy(sphereLightMesh.position);// render using requestAnimationFramerequestAnimationFrame(render);renderer.render(scene, camera);}function initStats() {var stats = new Stats();stats.setMode(0); // 0: fps, 1: ms// Align top-leftstats.domElement.style.position = 'absolute';stats.domElement.style.left = '0px';stats.domElement.style.top = '0px';document.getElementById("Stats-output").appendChild(stats.domElement);return stats;}}window.onload = init</script>
</body></html>

相关文章:

  • 【Go语言基础【18】】Map基础
  • 利用pandas gradio实现简单的项目子项拆解及排期
  • idea 启动jar程序并调试
  • HTML前端开发:JavaScript 常用事件详解
  • JS的传统写法 vs 简写形式
  • Spring框架的设计模式
  • 打卡第39天:Dataset 和 Dataloader类
  • Spring Cloud 微服务架构实战指南 -- SpringCLoud概述
  • BeckHoff_FB --> SET_SNB 功能块
  • Halcon案例(三):C#联合Halcon识别排线
  • 【RAG召回】bge实现向量相似度索引
  • 四.抽象工厂模式
  • 如何在Spring Boot中使用注解动态切换实现
  • Kubernetes 节点资源驱逐策略详解:evictionHard 与 evictionSoft
  • remote display server is not supported (e.g. Wayland)
  • Vue中虚拟DOM的原理与作用
  • 【RTP】Intra-Refresh模式下的 H.264 输出,RTP打包的方式和普通 H.264 流并没有本质区别
  • python批量将文件夹下的excel转word文件
  • 海思Hi3798MV310_V39_HMS DDR3_安卓9.0_外贸盒update升级包
  • 深入了解NIO的优化实现原理
  • 扬州做公司网站的公司/百度推广后台登陆
  • 网站限时抢购怎么做/一个完整的营销策划案范文
  • 网站建设服务费怎么做会计分录/聊城优化seo
  • 甘肃 政府 网站建设/电商网站建设
  • 江门网站制作培训/2023推广平台
  • 聊城企业做网站推广/常见的网站推广方法有哪些