效果图

首页index.html

<!DOCTYPE html>
<html lang="en" ><head>
<meta charset="UTF-8">
<title>Three.js Mobile VR Sonic</title><link rel="stylesheet" href="css/style.css"></head><body><script src="js/jquery-1.12.4.min.js"></script>
<script src="js/d3.v4.min.js"></script>
<script src="js/three.min.js"></script>
<script src="js/GLTFLoader.js"></script><script src="js/TweenMax.min.js"></script>
<script src="js/CSSPlugin.min.js"></script>
<script src="js/EasePack.min.js"></script><script src='js/AssimpJSONLoader.js'></script>
<script src="js/DeviceOrientationControls.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/StereoEffect.js"></script>
<script src="js/tween.min.js"></script>
<script src="js/dat.gui.min.js"></script>
<!-- glowing effect scripts -->
<script src="js/EffectComposer.js"></script>
<script src="js/RenderPass.js"></script>
<script src="js/MaskPass.js"></script>
<script src="js/ShaderPass.js"></script>
<script src="js/CopyShader.js"></script>
<script src="js/FXAAShader.js"></script>
<script src="js/ConvolutionShader.js"></script>
<script src="js/LuminosityHighPassShader.js"></script>
<!-- unreal bloom -->
<script src="js/UnrealBloomPass.js"></script><!-- VR Button --><button id='VR' class='button toggleVR' onclick='toggleVR()' title='Toggle VR Mode for Mobile Devices Only'><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 62.7 52.375" enable-background="new 0 0 62.7 41.9" xml:space="preserve"><path d="M53.4,5.5h-44c-2.1,0-3.7,1.7-3.7,3.7v22.6c0,2.1,1.7,3.7,3.7,3.7h13.4c1.1,0,2.1-0.6,2.5-1.6l3-7.5c1.2-2.6,4.9-2.5,6,0.1  l2.6,7.3c0.4,1,1.4,1.7,2.5,1.7h13.9c2.1,0,3.7-1.7,3.7-3.7V9.3C57.2,7.2,55.5,5.5,53.4,5.5z M20.4,27c-3.2,0-5.7-2.6-5.7-5.7  s2.6-5.7,5.7-5.7s5.7,2.6,5.7,5.7S23.6,27,20.4,27z M42.4,27c-3.2,0-5.7-2.6-5.7-5.7s2.6-5.7,5.7-5.7s5.7,2.6,5.7,5.7  S45.6,27,42.4,27z"/><text x="0" y="56.9" fill="#000000" font-size="5px" font-weight="bold" font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif">Created by Nick Bluth</text><text x="0" y="61.9" fill="#000000" font-size="5px" font-weight="bold" font-family="'Helvetica Neue', Helvetica, Arial-Unicode, Arial, Sans-serif">from the Noun Project</text></svg></button><div id="info">SUPER!</div><audio id="bflat" src="sonic_ring_sound.mp3"></audio><script  src="js/index.js"></script></body></html>

核心代码js

//===================================================== full screen
var requestFullscreen = function(ele) {if (ele.requestFullscreen) {ele.requestFullscreen();} else if (ele.webkitRequestFullscreen) {ele.webkitRequestFullscreen();} else if (ele.mozRequestFullScreen) {ele.mozRequestFullScreen();} else if (ele.msRequestFullscreen) {ele.msRequestFullscreen();} else {console.log("Fullscreen API is not supported.");}
};
var exitFullscreen = function(ele) {if (ele.exitFullscreen) {ele.exitFullscreen();} else if (ele.webkitExitFullscreen) {ele.webkitExitFullscreen();} else if (ele.mozCancelFullScreen) {ele.mozCancelFullScreen();} else if (ele.msExitFullscreen) {ele.msExitFullscreen();} else {console.log("Fullscreen API is not supported.");}
};
//===================================================== add canvas
let renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xd8e7ff, 0);
document.body.appendChild(renderer.domElement);
//===================================================== resize
window.addEventListener("resize", function() {let width = window.innerWidth;let height = window.innerHeight;renderer.setSize(width, height);camera.aspect = width / height;camera.updateProjectionMatrix();
});
//===================================================== add Scene
let scene = new THREE.Scene();
//===================================================== add Camera
let camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,1,10000
);
let cameraTarget = new THREE.Vector3(0, 0, 0);
//===================================================== add Group
group = new THREE.Group();
scene.add(group);
//===================================================== add Controls
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
//How far you can orbit vertically, upper and lower limits. The maximum is Pi / 2 (90deg). You wont see below the below the line of the horizon
controls.maxPolarAngle = Math.PI / 2.1;
//===================================================== add VR
renderer.setPixelRatio(window.devicePixelRatio); //VR
effect = new THREE.StereoEffect(renderer); //VR
effect.setSize(window.innerWidth, window.innerHeight); //VRvar VR = false;
function toggleVR() {if (VR) {VR = false;controls = new THREE.OrbitControls(camera, renderer.domElement);} else {VR = true;controls = new THREE.DeviceOrientationControls(camera);requestFullscreen(document.documentElement);}renderer.setSize(window.innerWidth, window.innerHeight);
}
//===================================================== curve points exported from blender using python
var points = [/*[2.873088836669922, 1.886053442955017, 2.807666063308716] ,
[2.8677191734313965, 1.901498556137085, 0.9702248573303223] ,
[4.261392116546631, 1.1370995044708252, 2.199495315551758] ,
[5.4436726570129395, -0.46564579010009766, 1.1223225593566895] ,
[4.683673858642578, -5.823459148406982, 0.29172343015670776] ,
[4.683673858642578, -5.823459148406982, 0.29172343015670776] ,
[1.0320820808410645, -8.896514892578125, -0.25123584270477295] ,
[-6.009271621704102, -5.854086875915527, -1.619685411453247] ,
[-5.8719940185546875, 1.664353609085083, 1.4598760604858398] ,
[-3.664644718170166, 5.1350908279418945, 0.8891280889511108] ,
[0.3946661949157715, 9.023353576660156, 2.472759246826172] ,
[6.545413017272949, 7.975126266479492, 4.807941913604736] ,
[9.380702018737793, 3.8875434398651123, -1.2000198364257812] ,
[3.980130672454834, -3.3519601821899414, -1.5907882452011108] ,
[0.10054226964712143, -4.0724077224731445, -2.6255977153778076] ,
[0.11306309700012207, -4.062130451202393, -2.625786781311035] ,
[-1.5915921926498413, 2.2223830223083496, 1.9054492712020874] ,
[-0.7800552845001221, 2.729933738708496, 2.711679458618164] ,
[2.2788195610046387, 1.5061609745025635, 3.6167585849761963] ,
[3.330962896347046, -1.753382682800293, 3.5841569900512695] ,
[3.3268532752990723, -1.7394065856933594, 3.584031343460083] ,
[1.8003381490707397, -2.6099541187286377, 4.496334552764893] ,
[1.809736728668213, -2.6042258739471436, 4.490817546844482] ,
[-1.5139055252075195, -2.2446377277374268, 3.513293743133545] ,
[-1.5139055252075195, -2.2446377277374268, 3.513293743133545] ,
[-1.5139055252075195, -2.2446377277374268, 1.7960444688796997] ,
[-1.9393141269683838, -0.623103678226471, 1.3167498111724854] ,
[-1.5, 0.0, 0.0] ,
[-1.0, 1.0, 0.0] ,
[1.0, 1.0, 0.0] ,
[1.5, 0.0, 0.0] ,*/[1.8117204904556274, 5.987488269805908, 0.29106736183166504],[6.005367279052734, 1.7647128105163574, -1.5591322183609009],[1.435487985610962, -6.016839504241943, 2.1336286067962646],[-4.118395805358887, -6.886471271514893, -0.7294682264328003],[-4.732693195343018, 3.405961036682129, 3.1304938793182373],[8.304193496704102, 7.593861103057861, 0.3412821292877197],[8.038525581359863, -4.391696453094482, 2.687108278274536],[1.488401174545288, -9.993440628051758, -2.2956111431121826],[-5.277090549468994, -8.481210708618164, -0.719127893447876],[-7.250330448150635, -0.9653520584106445, -0.3089699447154999],[-6.526705741882324, 5.678538799285889, 0.15560221672058105],[-0.885545015335083, 6.678538799285889, 1.5724562406539917],[1.614454984664917, 5.678538799285889, 0.24559785425662994],[1.8117204904556274, 5.987488269805908, 0.29106736183166504]
];var scale = 5;//Convert the array of points into vertices
for (var i = 0; i < points.length; i++) {var x = points[i][0] * scale;var y = points[i][1] * scale;var z = points[i][2] * scale;points[i] = new THREE.Vector3(x, z, -y);
}//Create a path from the points
var carPath = new THREE.CatmullRomCurve3(points);
var radius = 0.25;var geometry = new THREE.TubeGeometry(carPath, 600, radius, 10, false);//Set a different color on each face
for (var i = 0, j = geometry.faces.length; i < j; i++) {geometry.faces[i].color = new THREE.Color("hsl(" + Math.floor(Math.random() * 290) + ",50%,50%)");
}var material = new THREE.MeshBasicMaterial({side: THREE.BackSide,vertexColors: THREE.FaceColors,side: THREE.DoubleSide,transparent: true,opacity: 1
});
var tube = new THREE.Mesh(geometry, material);
scene.add(tube);//===================================================== add lighta
var light = new THREE.DirectionalLight(0xefefff, 1.25);
light.position.set(1, 1, 1).normalize();
scene.add(light);
var light = new THREE.DirectionalLight(0xffefef, 1.25);
light.position.set(-1, -1, -1).normalize();
scene.add(light);//Create a point light in our scene. Makes everything gloomy
var light = new THREE.PointLight(0xffffff, 1, 100);
scene.add(light);//===================================================== particles
var mergedGeometry = new THREE.Geometry();var boxGeometry = new THREE.TetrahedronGeometry(0.25, 0);var material = new THREE.MeshNormalMaterial({color: new THREE.Color("white")
});for (var i = 0; i < 1000; i++) {var x = Math.random() * 125 - 75;var y = Math.random() * 125 - 75;var z = Math.random() * 125 - 75;boxGeometry.translate(x, y, z);mergedGeometry.merge(boxGeometry);boxGeometry.translate(-x, -y, -z);
}var cubes = new THREE.Mesh(mergedGeometry, material);
scene.add(cubes);//===================================================== Loader
//3d model from
var loader = new THREE.GLTFLoader();
var model;
loader.load("sky-island.glb",function(gltf) {gltf.scene.traverse(function(node) {if (node instanceof THREE.Mesh) {node.castShadow = true;node.material.side = THREE.DoubleSide;}});model = gltf.scene;model.scale.set(3, 3, 3);model.position.set(0, -20, -10);//model.rotateY(Math.PI);scene.add(model);}
);//===================================================== Loader
//3d model from https://3dwarehouse.sketchup.com/user/0438052632930067253040161/wingedkoopa67?nav=models
var clock = new THREE.Clock();
var mixer = null;
var firstObject;
var loader = new THREE.GLTFLoader();
loader.load("sonic.glb",function(gltf) {gltf.scene.traverse(function(node) {if (node instanceof THREE.Mesh) {node.castShadow = true;node.material.side = THREE.DoubleSide;}});firstObject = gltf.scene;firstObject.scale.set(0.65, 0.65, 0.65);group.add(firstObject);console.log(gltf.animations); //shows all animations imported into the dopesheet in blendermixer = new THREE.AnimationMixer(firstObject);mixer.clipAction(gltf.animations[0]).play();document.body.addEventListener("click", jump);function jump() {mixer.clipAction(gltf.animations[0]).stop();mixer.clipAction(gltf.animations[1]).play();setTimeout(function() {mixer.clipAction(gltf.animations[1]).stop();mixer.clipAction(gltf.animations[0]).play();}, 900);}}
);//===================================================== add model
var size = 0.05;
var meshList = [];for (var i = 0; i < carPath.points.length; i++) {var x = carPath.points[i].x;var y = carPath.points[i].y;var z = carPath.points[i].z;var geometry = new THREE.TorusGeometry(3, 0.5, 8, 50);var material = new THREE.MeshBasicMaterial({color: new THREE.Color("yellow")});var secondObject = new THREE.Mesh(geometry, material);secondObject.position.set(x, y + 0.75, z);secondObject.scale.set(size, size, size);meshList.push(secondObject);scene.add(secondObject);
}//===================================================== Collision Detection
function PlaySound() {bflat.play();
}//calculate distance of the main object
firstBB = new THREE.Box3().setFromObject(group);//calculate distance for all other objects
for (var i = 0; i < meshList.length; i++) {secondBB = new THREE.Box3().setFromObject(meshList[i]);
}var count = 0;
function hit() {//recalculate distance for the main objectfirstBB = new THREE.Box3().setFromObject(group);//recalcuate distance for all the other objectsfor (var i = 0; i < meshList.length; i++) {secondBB = new THREE.Box3().setFromObject(meshList[i]);if (firstBB.isIntersectionBox(secondBB)) {PlaySound();info.style.color = "hsl(" + Math.floor(Math.random() * 290) + ",50%,50%)";info.innerHTML =Math.random() > 0.25? "Superb!": Math.random() > 0.25 ? "Oustanding!" : "Awesome!";TweenLite.to(info, 0.75, {css: { fontSize: "50px", opacity: 1 },ease: Power4.easeOut,onComplete: function() {TweenLite.to(info, 0.75, {css: { fontSize: "14px", opacity: 0 },ease: Power4.easeOut}); //end tween} //end onComplete}); //end tween} //end if} //end for
} //end hit//===================================================== bloom
var renderScene = new THREE.RenderPass(scene, camera);
var shaderActive = "none";
var gui = new dat.GUI();
dat.GUI.toggleHide();
var composer;var parameters = {x: 0,y: 30,z: 0,bloomStrength: 1.0,bloomRadius: 1.0,bloomThreshold: 0.45,useShaderNone: function() {setupShaderNone();},useShaderBloom: function() {setupShaderBloom();}
};gui.add(parameters, "useShaderNone").name("Display Original Scene");var folderBloom = gui.addFolder("Bloom");
var bloomStrengthGUI = folderBloom.add(parameters, "bloomStrength").min(0.0).max(2.0).step(0.01).name("Strength").listen();
bloomStrengthGUI.onChange(function(value) {setupShaderBloom();
});
var bloomRadiusGUI = folderBloom.add(parameters, "bloomRadius").min(0.0).max(5.0).step(0.01).name("Radius").listen();
bloomRadiusGUI.onChange(function(value) {setupShaderBloom();
});
var bloomThresholdGUI = folderBloom.add(parameters, "bloomThreshold").min(0).max(0.99).step(0.01).name("Threshold").listen();
bloomThresholdGUI.onChange(function(value) {setupShaderBloom();
});
folderBloom.add(parameters, "useShaderBloom").name("Use Bloom Shader");
folderBloom.open();//===================================================== functionsfunction setupShaderNone() {shaderActive = "none";
}function setupShaderBloom() {composer = new THREE.EffectComposer(renderer);composer.addPass(new THREE.RenderPass(scene, camera));/*unreal bloom*/var effectFXAA = new THREE.ShaderPass(THREE.FXAAShader);effectFXAA.uniforms["resolution"].value.set(1 / window.innerWidth,1 / window.innerHeight);var copyShader = new THREE.ShaderPass(THREE.CopyShader);copyShader.renderToScreen = true;var bloomPass = new THREE.UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight),parameters.bloomStrength,parameters.bloomRadius,parameters.bloomThreshold);composer = new THREE.EffectComposer(renderer);composer.setSize(window.innerWidth, window.innerHeight);composer.addPass(renderScene);composer.addPass(effectFXAA);composer.addPass(bloomPass);composer.addPass(copyShader);shaderActive = "bloom";
}function isShaderActive() {if (shaderActive == "none") {renderer.render(scene, camera);} else {composer.render();}
}//active bloom on load
setupShaderBloom();//===================================================== Animate
var percentage = 0;
var prevTime = Date.now();
function POV() {percentage += 0.00045;var p1 = carPath.getPointAt(percentage % 1);var p2 = carPath.getPointAt((percentage + 0.01) % 1);var p3 = carPath.getPointAt((percentage + 0.01 / 2) % 1);var p4 = carPath.getPointAt((percentage + 0.01 / 4) % 1);camera.lookAt(p2);group.position.set(p3.x, p3.y + 0.25, p3.z);group.lookAt(p2);camera.position.x = p4.x + 2;camera.position.y = p4.y + 1;camera.position.z = p4.z + 2;camera.lookAt(group.position);
}function animate() {POV();hit();var delta = clock.getDelta();if (mixer != null) mixer.update(delta);//VRif (VR) {effect.render(scene, camera);} else {//renderer.render( scene, camera );isShaderActive();}requestAnimationFrame(animate);controls.update();
}
animate();//set camera position
camera.position.x = 40;
camera.position.y = 50;
camera.position.z = 50;

整个前端小玩意儿:用three.js开发的手机太空穿越VR游戏,特效非常猛相关推荐

  1. 用LayaAir引擎开发HTML5的3D与VR游戏(入门基础)【面向JS开发者】-赖圆圆-专题视频课程...

    用LayaAir引擎开发HTML5的3D与VR游戏(入门基础)[面向JS开发者]-4626人已学习 课程介绍         全面介绍LayaAir引擎的3D游戏开发基础.学习在3DMax与Unity ...

  2. 小程序使用node.js开发后台接口

    目录 灵感 寻找 操作步骤 1. 准备工作 2. 使用Express生成项目 3. 创建Router级别路由 4. 创建路由处理函数模块 5. 创建连接数据库的模块 6. 启动服务器 7. 小程序里面 ...

  3. mete20可以升级鸿蒙,从微信小程序到鸿蒙js开发【12】——storage缓存自动登录

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 正文: 在应用开发时,我们常需要将一些数据缓存到本地,以提升用户体验.比如在一个电商的app中,如果希望用户登录成功后,下次打 ...

  4. 前端小知识点(4):JS 运行机制和存储

    目录 被忽视的内存管理 JS工作原理 JS代码如何运行 JavaScript内存的生命周期 栈内存.堆内存 代码案例 运行结果 被忽视的内存管理 JavaScript不像C.C++等语言--程序员必须 ...

  5. 前端小奈叽须知---js/jquery(目前分不清)

    jQuery 父级,祖先,兄弟,等选择性操作 - 芸芸众生! - 博客园jQuery.parent(expr) 找父亲节点,可以传入expr进行过滤,比如$("span").par ...

  6. 小程序使用three.js开发VR场景漫游

    下载所需要文件,参考:GitHub - yannliao/threejs-example-for-miniprogram: 这是一个 three.js 在微信小程序里的使用示例 引入js文件 impo ...

  7. 鸿蒙系统如何添加桌面小程序,从微信小程序到鸿蒙js开发【04】——list组件

    1.可滚动区域 在许多场景中,页面会有一块区域是可滚动的,比如这样一个简单的每日新闻模块: 上面的新闻类型是一块可横向滚动的区域,下方新闻列表是一块可竖向滚动的区域.在微信小程序中,使用scroll- ...

  8. ajax调用java程序,从微信小程序到鸿蒙JS开发-JS调用Java

    除轻量级智能穿戴设备,现鸿蒙支持的手机.汽车.TV.手表.平板等属于富鸿蒙,在JS语言的项目中也有Java模块,并提供了JS跨语言调用Java方法的技术.现需要实现查看商品评论时,统计出长评.中评和短 ...

  9. 纯js写的手机版成语填空游戏

    前面用python的pygame版本做了一个成语填空游戏 https://blog.csdn.net/zhangenter/article/details/89807613 有朋友抱怨手机上用不了,现 ...

最新文章

  1. msicuu.exe (msizap.exe),程序的作用
  2. xfs文件系统下扩展lvm卷组
  3. java的framework_JAVA FRAMEWORK
  4. Redis的设计与实现之整数集合和压缩列表
  5. 搭建Vue.js环境,建立一个简单的Vue项目
  6. windows7电脑怎么永久关闭广告
  7. 选择大于努力!0基础学好C语言编程,首先要掌握的是什么?
  8. 去了家新公司,技术总监不让用 IntelliJ IDEA!!想离职了。。
  9. RWMutex的一道面试题
  10. 简单快速部署nexus3私服
  11. 【记录】搭建本地wordpress全过程
  12. plc组态编程需要学多少c语言,快速学习PLC编程,其实很简单!
  13. 深入理解JVM虚拟机读书笔记——类的加载机制
  14. java给链表赋值_Java链表操作代码
  15. WordCloud库的使用
  16. 计算机网络的静态路由配置中路由表里下一跳、路由条目等一些细节理解
  17. 一个简单的日内交易策略
  18. 计算机考研复习资料推荐(转载)
  19. Java线程池并发执行多个任务
  20. python列表查找整数_Python:找出整数列表是否为coheren

热门文章

  1. 更高的因子有效性评价标准
  2. 网站优化每天需要发几篇文章
  3. 凯撒加密解密(python)
  4. 2020.11.26课堂笔记(sparkGraphx算法之pregel)
  5. WordPress允许用户和游客收藏文章的插件WP Favorite Posts
  6. 树莓派使用:更换源(sources)
  7. python-shelve
  8. 分布式笔记(二)paxos协议与chubby
  9. AutoCAD 2023 (cad2023)
  10. Python希尔排序