冬奥快结束了还没有抢到冰墩墩?程序员一招让你不用排队不用愁!

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,内容安全 1000 次 1年
对象存储OSS,敏感数据保护2.0 200GB 1年
简介: 随着“2022北京冬奥会”的盛大开幕,冰墩墩的热度与日俱增,线上被抢空,线下排长龙,为购买冰墩墩苦恼的竟少了几根秀发!如今冬奥马上就要拉下帷幕,还没抢到“冰墩墩”不要紧,这款程序来帮忙,国内一位程序员dragonir用前端+建模的方式自己就实现了线上拥有“冰墩墩”,同时将代码开源到了GitHub上,不得不感叹科技的力量,程序员的伟大,让拥有“冰墩墩”变得如此简单!

错失冰墩墩,代码来补救!


随着“2022北京冬奥会”的盛大开幕,冰墩墩的热度与日俱增,线上被抢空,线下排长龙,为购买冰墩墩苦恼的竟少了几根秀发!如今冬奥马上就要拉下帷幕,还没抢到“冰墩墩”不要紧,这款程序来帮忙,国内一位程序员dragonir用前端+建模的方式自己就实现了线上拥有“冰墩墩”,同时将代码开源到了GitHub上,不得不感叹科技的力量,程序员的伟大,让拥有“冰墩墩”变得如此简单!



立体感的“冰墩墩”轻松实现


这一部分是不需要用户去自己去码代码,是小编让大家了解一些具体的实现逻辑。云开发平台可以将原Github项目直接fork到自己的仓库上,马上来看一下“冰墩墩”技术如何实现的吧!


1.引入资源

首先引入开发页面所需要的库和外部资源,OrbitControls 用于镜头轨道控制、TWEEN 用于补间动画实现、GLTFLoader 用于加载 glbgltf 格式的 3D 模型、以及一些其他模型、贴图等资源。

importReactfrom'react';
import { OrbitControls } from"three/examples/jsm/controls/OrbitControls";
import { TWEEN } from"three/examples/jsm/libs/tween.module.min.js";
import { GLTFLoader } from"three/examples/jsm/loaders/GLTFLoader";
importbingdundunModelfrom'./models/bingdundun.glb';
// ...


2.页面DOM结构

页面 DOM 结构非常简单,只有渲染 3D 元素的 #container 容器和显示加载进度的 .olympic_loading 元素。

<div><divid="container"></div>  {this.state.loadingProcess===100?'' : (
<divclassName="olympic_loading"><divclassName="box">{this.state.loadingProcess} %</div></div>  )}
</div>


3.场景初始化

初始化渲染容器、场景、相机。

container=document.getElementById('container');
renderer=newTHREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled=true;
container.appendChild(renderer.domElement);
scene=newTHREE.Scene();
scene.background=newTHREE.TextureLoader().load(skyTexture);
camera=newTHREE.PerspectiveCamera(60, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(0, 30, 100);
camera.lookAt(newTHREE.Vector3(0, 0, 0));


4.添加光源

本示例中主要添加了两种光源:DirectionalLight 用于产生阴影,调节页面亮度、AmbientLight 用于渲染环境氛围。

// 直射光constlight=newTHREE.DirectionalLight(0xffffff, 1);
light.intensity=1;
light.position.set(16, 16, 8);
light.castShadow=true;
light.shadow.mapSize.width=512*12;
light.shadow.mapSize.height=512*12;
light.shadow.camera.top=40;
light.shadow.camera.bottom=-40;
light.shadow.camera.left=-40;
light.shadow.camera.right=40;
scene.add(light);
// 环境光constambientLight=newTHREE.AmbientLight(0xcfffff);
ambientLight.intensity=1;
scene.add(ambientLight);


5.加载进度管理

使用 THREE.LoadingManager 管理页面模型加载进度,在它的回调函数中执行一些与加载进度相关的方法。本例中的页面加载进度就是在 onProgress 中完成的,当页面加载进度为 100% 时,执行 TWEEN 镜头补间动画。

constmanager=newTHREE.LoadingManager();
manager.onStart= (url, loaded, total) => {};
manager.onLoad= () => { console.log('Loading complete!')};
manager.onProgress= (url, loaded, total) => {
if (Math.floor(loaded/total*100) ===100) {
this.setState({ loadingProcess: Math.floor(loaded/total*100) });
// 镜头补间动画Animations.animateCamera(camera, controls, { x: 0, y: -1, z: 20 }, { x: 0, y: 0, z: 0 }, 3600, () => {});
  } else {
this.setState({ loadingProcess: Math.floor(loaded/total*100) });
  }
};


6.创建地面

本示例中凹凸起伏的地面是使用 Blender 构建模型,然后导出 glb 格式加载创建的。当然也可以只使用 Three.js自带平面网格加凹凸贴图也可以实现类似的效果。使用 Blender 自建模型的优点在于可以自由可视化地调整地面的起伏效果。

varloader=newTHREE.GLTFLoader(manager);
loader.load(landModel, function (mesh) {
mesh.scene.traverse(function (child) {
if (child.isMesh) {
child.material.metalness= .1;
child.material.roughness= .8;
// 地面if (child.name==='Mesh_2') {
child.material.metalness= .5;
child.receiveShadow=true;
      }
  });
mesh.scene.rotation.y=Math.PI/4;
mesh.scene.position.set(15, -20, 0);
mesh.scene.scale.set(.9, .9, .9);
land=mesh.scene;
scene.add(land);
});


7.添加“冰墩墩”

在添加之前,需要在「室内设计网」找到冰墩墩的原始模型,并且需要在 Blender中转换模型格式,还需要Blender调整模型的贴图法线,才能还原渲染图效果


透明塑料或玻璃质感实现代码:

loader.load(bingdundunModel, mesh=> {
mesh.scene.traverse(child=> {
if (child.isMesh) {
// 内部if (child.name==='oldtiger001') {
child.material.metalness= .5child.material.roughness= .8      }
// 半透明外壳if (child.name==='oldtiger002') {
child.material.transparent=true;
child.material.opacity= .5child.material.metalness= .2child.material.roughness=0child.material.refractionRatio=1child.castShadow=true;
      }
    }
  });
mesh.scene.rotation.y=Math.PI/24;
mesh.scene.position.set(-8, -12, 0);
mesh.scene.scale.set(24, 24, 24);
scene.add(mesh.scene);
});



云平台一键部署“冰墩墩”


1.创建环境

想要一键部署“冰墩墩”,需要以下账号和服务:


1644997127286-12139244-3f41-492a-90bd-243865953a4c.png


2.创建“冰墩墩”应用


1644997408287-3557c360-2782-4a32-8b84-05b14e38670d.png


  • 云资源访问授权。如果您之前没有使用过云开发平台,会出现云资源授权管理的选项,往下拉出现直至同意授权的字样,点击「同意授权」后出现授权成功,点击进入「下一步」。


1644997442687-29e1db35-2d25-4a46-8817-9329c6dfa42c.jpeg


  • 绑定Github账号。授权完成后选择来源仓库为Github,按照提示点击去绑定,绑定GitHub帐号,登录后并点击Authorize Aliyunworkben允许云开发平台构建、发布你的GitHub代码为可访问的网站。


1644997479429-b39c4453-ee16-427c-89fe-e6d2d9bccf7c.png


  • 选择fork好的“bingdundun”代码仓库。选择第一步中的代码仓库主干分支,并点击下一步。主干分支一般指的是代码的master或main等分支。


1644997827347-b30dddcf-e20c-4e2c-86a0-615390b57ce6.png


  • 填写基本信息,完成创建。填写基本信息并点击「完成」。成功后进入到应用详情和部署界面。


1644997900876-df29fe5e-3243-4e69-a57f-9ea8dd01c217.png


3.线上一键部署

  • 一键进行应用部署。在应用详情页面点击日常环境的「部署」按钮进行一键部署,部署状态变成绿色已部署以后可以点击访问部署网站查看效果。


1644998966985-307cb295-b52d-4172-9e29-ad08674a825e.png


收获线上“冰墩墩”


一段段复杂的代码汇聚成了冬奥顶流“冰墩墩”,让每一位关注冬奥盛况的人都能够在此刻圆梦,感谢dragonir将代码开源到Github。点击图片可以立即前往云开发平台开始获取你的专属墩了。


1644977628886-f83a04ac-039f-4387-ab13-061a950e3438.png



注:参考文章「牛批,「冰墩墩」代码,开源了!!」

作者源代码地址:https://github.com/dragonir/3d/tree/master/src/containers/Olympic

本文涉及奥运元素3D模型仅用于个人学习、研究和欣赏,请勿二次修改、非法传播、转载、出版、商用、及进行其他获利行为。

相关实践学习
通义万相文本绘图与人像美化
本解决方案展示了如何利用自研的通义万相AIGC技术在Web服务中实现先进的图像生成。
相关文章
|
存储 弹性计算 运维
【内含干货PPT下载】DTCC 2020 | 阿里云王涛:阿里巴巴电商数据库上云实践
第十一届中国数据库技术大会(DTCC2020),在北京隆重召开。大会以“架构革新 高效可控”为主题,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨。在数据库智能运维专场上,邀请了阿里云数据库高级技术专家王涛为大家介绍阿里巴巴电商数据库上云的选择、思考与实践。阿里巴巴电商数据库原先是在自己独立的IDC维护的,伴随着阿里巴巴上云项目,数据库轻松实现上云。阿里云云原生管控以及云原生数据库技术可以帮助业务实现平滑上云目标,进而实现资源最大化成本最优化的目标。阿里巴巴希望利用阿里云的技术体系,帮助客户大规模上云,打造自己的运维管控平台。
3224 0
【内含干货PPT下载】DTCC 2020 | 阿里云王涛:阿里巴巴电商数据库上云实践
|
SQL 消息中间件 负载均衡
Hologres+Flink实时数仓详解
本次内容将会介绍使用Flink和Hologres,实现可扩展的、高效的、云原生实时数仓。
29303 1
Hologres+Flink实时数仓详解
|
11月前
|
人工智能 Java API
ChatClient:探索与AI模型通信的Fluent API
【11月更文挑战第22天】随着人工智能(AI)技术的飞速发展,越来越多的应用场景开始融入AI技术以提升用户体验和系统效率。在Java开发中,与AI模型通信成为了一个重要而常见的需求。为了满足这一需求,Spring AI引入了ChatClient,一个提供流畅API(Fluent API)的客户端,用于与各种AI模型进行通信。本文将深入探讨ChatClient的底层原理、业务场景、概念、功能点,并通过Java代码示例展示如何使用Fluent API与AI模型进行通信。
302 8
|
Serverless SQL 容灾
实时数仓Hologres V2.2发布,Serverless Computing降本20%
实时数仓Hologres V2.2发布,Serverless Computing降本20%
实时数仓Hologres V2.2发布,Serverless Computing降本20%
|
11月前
|
开发者
ArkTS组件继承的高级用法
本文详细介绍了ArkTS中组件继承的高级用法,涵盖继承的概念、基本用法、多态、接口继承和抽象类的使用。通过具体示例,展示了如何在HarmonyOS应用开发中利用继承实现代码复用、功能扩展和模块化设计,提升开发效率和应用质量。
511 3
|
分布式计算 Java Hadoop
NameNode 处理线程配置(心跳并发)
NameNode线程池处理客户端和数据节点请求,如读写文件及心跳、块报告。通过调整`dfs.namenode.handler.count`(默认10,示例设为21)在`hdfs-site.xml`中可控制并发处理能力。线程数过多或过少都可能影响性能,需平衡资源使用并进行基准测试以确定最佳值。合理线程数可通过公式`int(math.log(N) * 20)`计算,N为服务器数量。例如,3台服务器的计算结果为21。
459 4
|
机器学习/深度学习 人工智能 并行计算
从LLM中完全消除矩阵乘法,效果出奇得好,10亿参数跑在FPGA上接近大脑功耗
【6月更文挑战第15天】`Scalable MatMul-free LMs提出了一种无需矩阵乘法的新方法,使用MLGRU和MatMul-free GLU在保持性能的同时降低计算成本。实验显示,这种模型在FPGA上运行时,能效接近人脑,且在多种任务中与传统模型相当甚至更优。尽管有挑战,但该模型为高效、低功耗的语言处理开辟了新途径。[arXiv:2406.02528]`
310 1
|
Web App开发 存储 数据可视化
LaTeX基础使用【系列五】
LaTeX基础使用【系列五】
|
Java API Spring
教程:Spring Boot中如何集成GraphQL
教程:Spring Boot中如何集成GraphQL
|
机器学习/深度学习 算法 PyTorch
在Python中使用LSTM和PyTorch进行时间序列预测
在Python中使用LSTM和PyTorch进行时间序列预测