用three.js渲染上海外滩模型
记录一下用three.js加载并渲染上海外滩的BIM模型的小demo
<!DOCTYPE html>
<html lang="en"><head><style>body {margin: 0;}p {position: fixed;top: 0;}
</style><script src="lib/three.js"></script><script src="lib/OrbitControls.js"></script><script src="lib/GLTFLoader.js"></script><script src="lib/Water.js"></script></head><body><script src="index.js"></script><p>天空:<input type="checkbox" onchange="skyToggle()" /></p></body>
</html>
用到的three官方库:
three.min.js:THREE.js WebGL引擎
OrbitControls.js:轨道控制,鼠标控制视角变幻
GLTFLoader.js:gltf加载库
Water.js:水面效果,纯glsl实现
天空的实现:
天空的实现有多种方式,最常见的是一个包围全部的天空球,通常是UV球,也叫经纬球,其UV很方便映射到一张天空图片,比如:
天空球的所有面的法线必须朝向圆心(默认是朝外),或者渲染的时候采用背面渲染。
第二种方式是天空盒,即将上述的天空球变成一个正方体盒子,好处是减少了许多三角面片,只剩12个面,但通常要准备上下左右前后6张图片来贴合天空盒。比如这样:
与这2种方法相比,性能最好的方案是静态天空球(盒),即理想情况下的宇宙背景,天空球的半径无限大,导致渲染的时候,天空不会因为相机的移动而变化,只随旋转而变化,这样减少了许多计算量。
静态天空球就是360度全景摄像机的原理,它和墨卡托投影有点类似,但是正轴等距圆柱投影,想象一个经纬球,它的经纬线自然展开,UV坐标如下:
可以看到,图中每个矩形的宽高比是1:2,应该把它们都拉伸成正方形,因为赤道:经线=2:1,这样UV贴图的宽高比就是2:1,比如:
图中红线是赤道(圆周),每条竖线是经线(一半圆周),每条纬线都被拉伸至赤道长度。可以看到两极地区被拉伸严重,靠近赤道地区比例正常。
然后将它通过圆柱投影到球面上,或者转换成6张图作为正方体,作为静态天空,代码如下:
async function skyToggle() {if (scene.bgURL === "light.png") {scene.bgURL = "dark.png";} else {scene.bgURL = "light.png";}const texture = await new THREE.TextureLoader().loadAsync(scene.bgURL);const rt = new THREE.WebGLCubeRenderTarget(texture.image.height);rt.fromEquirectangularTexture(renderer, texture);scene.background = rt.texture;
}
然后是加载gltf模型:
const loader = new THREE.GLTFLoader();
const modelLoaded = loader.loadAsync("shanghai.glb", function (xhr) {console.log((xhr.loaded / xhr.total) * 100 + "% loaded");}).then(function (gltf) {console.log("shanghai model:", gltf);const { min, max } = new THREE.Box3().setFromObject(gltf.scene);gltf.scene.position.sub(new THREE.Vector3((min.x + max.x) / 2, min.y, (min.z + max.z) / 2));scene.add(gltf.scene);gltf.scene.getObjectByName("castShadow").traverse((x) => x.isMesh && (x.castShadow = true));gltf.scene.getObjectByName("ground").traverse((x) => x.isMesh && (x.receiveShadow = true));}).catch(function (error) {console.error(error);});
其中让所有的大厦投影,让地面接收投影,实现真实的效果,又避免了所有物体都投影。
其中增加了一个视频plane,作为震旦大厦的大屏动画,plane的4个顶点的UV就是图片的4个角:
const video = document.createElement("video");video.src = "test2.mp4";video.loop = true;video.muted = true;video.playbackRate = 0.6;video.play();const videoPlane = gltf.scene.getObjectByName("video");videoPlane.material = new THREE.MeshBasicMaterial({map: new THREE.VideoTexture(video),});videoPlane.geometry.attributes.uv = new THREE.BufferAttribute(new Uint8Array([0, 0, 1, 0, 0, 1, 1, 1]),2);
视频:
增加海水:
new THREE.TextureLoader().loadAsync("waternormals.jpg").then((waterNormals) => {waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping;const water = new THREE.Water(new THREE.PlaneGeometry(1000, 1000), {textureWidth: 512,textureHeight: 512,waterNormals,sunDirection: new THREE.Vector3(),sunColor: 0xffffff,waterColor: 0x001e0f,distortionScale: 3.7,fog: !!scene.fog,});water.material.uniforms.size.value = 10;water.rotation.x = -Math.PI / 2;scene.add(water);tasks.push(() => {water.material.uniforms.time.value += 0.005;});
});
海水法线贴图:
最后再加1个环境光,开启环境光遮蔽,再加一个平行光就好了:
视频来源:https://blog.csdn.net/goodriver1
用three.js渲染上海外滩模型相关推荐
- 解决three.js渲染gltf 模型与gltfViewer网站效果不一致问题 krpano发黑问题 three.js gltf模型渲染发黑问题
解决使用three.js渲染gltf模型与gltfViewer网站上预览不一致的问题: 原因 灯光和环境贴图 直接上代码 function init(e) { //声明初始化函数$("#pr ...
- WebGL笔记(六)_Three.js渲染obj模型并同时渲染全景图
基本思路简述:一个模型的渲染的流程是,创建一个场景,并将模型和相机放到场景中合适的位置:然后就会呈现出一个3D模型在屏幕上.全景图的呈现其实就是在创建一个场景.相机.几何球.模型和全景同时被呈现在屏幕 ...
- three.js实现3D模型展示
开头说明下 文章是转载我同事一个 哥们的.怕自己 以后会用 拿过来 方便以后使用 three.js实现3D模型展示 由于项目需要展示3d模型,所以对three做了点研究,分享出来 希望能帮到大家 ...
- three.js使用外部模型创建动画,使用GLTF格式文件动画创建动画(vue中使用three.js71)
使用GLTF格式文件动画创建动画 1.demo效果 2. 实现要点 2.1 加载GLTF文件 2.2 创建AnimationMixer动画 2.3 render中更新动画 3. demo代码 1.de ...
- three.js渲染带动画的glb文件(内附源码,保姆级)
今日份的下午格外的懒惰,本来不想写辣么长长的一串文字了和解释说明的, 但是发文助手提醒我篇幅较短,曝光比较少,该说不说,这有点过分了. 那就一步步来吧哎 最底下附带了案例源文件 1.准备好three. ...
- 【Three.js】解决使用Three.js导入obj模型不可见问题详细记录
问题描述: 近期在做三维重建项目,需要把最终生成的obj文件导入到web端浏览,这里使用的是three.js(另一个是babylon.js),但博主发现导入meshlab生成的obj时无法显示模型,但 ...
- Three.js 点击模型,高亮发光模型外轮廓
最近在开发一个功能,在三维场景里有很多模型,需要点击模型,高亮对应的模型,代表选中了该模型.做起来还是稍微麻烦一些的. 具体效果 实现流程 主要的流程还是, Created with Raphaël ...
- Three.js学习六——模型动画
目录 Three.js动画系统(Animation system) 实现流程 基本流程 工程文件 场景搭建 添加模型 模型动画 动画实现的基本流程 相关对象方法和代码 完整代码和实现效果 Three. ...
- 【问题探讨】H5 UI渲染心智模型
目标 探讨H5 UI渲染心智模型,即阐述数据是依据什么样的逻辑渲染到界面上的. 本文思路 先通过一个示例讲述不同的数据渲染逻辑,然后讲两个延伸DEMO来着重说明CLASS和FUNCTION的特点: 示 ...
- QT实现Qt Quick和three.js渲染和实现QML3D控件
QT实现Qt Quick和three.js渲染和实现QML3D控件 项目简介 项目技术 项目展示 主要源码片段解析 获取完整项目源码传送门 项目简介 结合Qt Quick和three.js渲染. 演示 ...
最新文章
- Linux之获取管理员权限的相关命令
- spring bean作用域_Srping中Bean的三种装配方式:大魏Java记10
- CodeForces - 817D Imbalanced Array(单调栈)
- 廖雪峰 练习 把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字...
- DNS解析原理与Bind部署DNS服务
- 使用php自动将文章标题或内容进行分词,添加和删除标签功能实例!
- python 测试开发请关注这个新框架
- Oracle 10g升级之--PSU 升级(续)
- iOS应用开发模板 iOS Boilerplate
- 8)Thymeleaf 基本对象表达式
- java小球碰撞界面设计_JavaScript实现小球碰撞特效
- 计算机网络冲突窗口,计算机网络基础试题及答案
- UML类图画法全程解析
- VB编程:SelectCase多分支选择结构实例测试生肖运势-13
- .net写加密的com组件给ASP,VB,VC等其他语言调用
- 用HTML和CSS3做个鱼,如何使用CSS和D3实现小鱼游动的交互动画(附代码)
- 天球坐标系和地球坐标系
- 机电信息杂志机电信息杂志社机电信息编辑部2022年第13期目录
- 计算机可爱的企鹅教案,北师大版数学一年级上册可爱的企鹅教案
- 职业规划与发展部_3D成像原理
热门文章
- 项目总结报告(小米商城)
- 【修真院“善良”系列之二】产品经理应该懂哪些术语?
- 对比Ruby和Python的垃圾回收
- python编写程序实现货币转换_使用Tkinter的Python实时货币转换器
- 人生若梦,神马都是浮云,,,,,,,
- 【NOI2017模拟3.30】原谅
- 5G核心网技术基础自学系列 | 与EPC互通
- WIN10下 搭建golang+vscode开发环境(图文并茂,傻瓜式教程)
- 大数据-Flume(二)
- Google Analytics SEO 实时 网站 访问量 统计