Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

这篇具有很好参考价值的文章主要介绍了Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文 gihtub 地址: https://github.com/hua1995116/Fly-Three.js

最近元宇宙的概念很火,并且受到疫情的影响,我们的出行总是受限,电影院也总是关门,但是在家里又没有看大片的氛围,这个时候我们就可以通过自己来造一个宇宙,并在 VR 设备(Oculus 、cardboard)中来观看。

今天我打算用 Three.js 来实现个人 VR 电影展厅,整个过程非常的简单,哪怕不会编程都可以轻易掌握。

想要顶级的视觉盛宴,最重要的肯定是得要一块大屏幕,首先我们就先来实现一块大屏幕。

大屏幕的实现主要有两种几何体,一种是 PlaneGeometry 和 BoxGeometry,一个是平面,一个是六面体。为了使得屏幕更加有立体感,我选择了 BoxGeometry。

老样子,在添加物体之前,我们先要初始化我们的相机、场景和灯光等一些基础的元件。

const scene = new THREE.Scene();

// 相机
const camera = new THREE.PerspectiveCamera(
    75,
    sizes.width / sizes.height,
    0.1,
    1000
)
camera.position.x = -5
camera.position.y = 5
camera.position.z = 5
scene.add(camera);

// 添加光照
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(ambientLight)

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
directionalLight.position.set(2, 2, -1)

scene.add(directionalLight)

// 控制器
const controls = new OrbitControls(camera, canvas);
scene.add(camera);

然后来写我们的核心代码,创建一个 5 * 5 的超薄长方体

const geometry = new THREE.BoxGeometry(5, 5, 0.2);
const cubeMaterial = new THREE.MeshStandardMaterial({
    color: '#ff0000'
});
const cubeMesh = new THREE.Mesh(geometry, cubeMaterial);
scene.add(cubeMesh);

效果如下:

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

然后紧接着加入我们的视频内容,想要把视频放入到3d场景中,需要用到两样东西,一个是 html 的 video 标签,另一个是 Three.js 中的视频纹理 VideoTexture

第一步将视频标签放入到 html 中,并设置自定播放以及不让他显示在屏幕中。

...
<canvas class="webgl"></canvas>
<video 
  id="video"
  src="./pikachu.mp4"
  playsinline
  webkit-playsinline
  autoplay
  loop
  style="display:none"
  ></video>
...

第二步,获取到 video 标签的内容将它传给 VideoTexture,并且纹理赋给我们的材质。

+const video = document.getElementById( 'video' );
+const texture = new THREE.VideoTexture( video );

const geometry = new THREE.BoxGeometry(5, 5, 0.2);
const cubeMaterial = new THREE.MeshStandardMaterial({
-    color: '#ff0000'
+    map: texture
});
const cubeMesh = new THREE.Mesh(geometry, cubeMaterial);
scene.add(cubeMesh);

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

我们看到皮神明显被拉伸了,这里就出现了一个问题就是纹理的拉伸。这也很好理解,我们的屏幕是 1 : 1 的,但是我们的视频却是 16:9 的。想要解决其实也很容易,要么就是让我们的屏幕大小更改,要么就是让我们的视频纹理渲染的时候更改比例。

第一种方案很简单

通过修改几何体的形状(也及时我们显示器的比例)

const geometry = new THREE.BoxGeometry(8, 4.5, 0.2);
const cubeMaterial = new THREE.MeshStandardMaterial({
    map: texture
});
const cubeMesh = new THREE.Mesh(geometry, cubeMaterial);
scene.add(cubeMesh);

第二种方案稍微有点复杂,需要知道一定的纹理贴图相关的知识

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

图1-1

首先我们先要知道纹理坐标是由 u 和 v 两个方向组成,并且取值都为 0 - 1。通过在 fragment shader 中,查询 uv 坐标来获取每个像素的像素值,从而渲染整个图。

因此如果纹理图是一张16:9 的,想要映射到一个长方形的面中,那么纹理图必要会被拉伸,就像我们上面的视频一样,上面的图为了表现出电视机的厚度所以没有那么明显,可以看一下的图。(第一张比较暗是因为 Three.js 默认贴图计算了光照,先忽略这一点)

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

我们先来捋一捋,假设我们的图片的映射是按照 图1-1,拉伸的情况下 (80,80,0) 映射的是 uv(1,1 ),但是其实我们期望的是点(80, 80 * 9/16, 0) 映射的是 uv(1,1),所以问题变成了像素点位 (80, 80 * 9/16, 0) 的uv值 如何变成 (80, 80, 0) 的uv 值,更加简单一些就是如何让 80 * 9 / 16 变成 80,答案显而易见,就是 让 80 * 9 / 16 像素点的 v 值 乘以 16 / 9,这样就能找到了 uv(1,1) 的像素值。然后我们就可以开始写 shader 了。

// 在顶点着色器传递 uv
const vshader = `
varying vec2 vUv;

void main() {
  vUv = uv;

  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`

// 核心逻辑就是 vec2 uv = vUv * acept; 
const fshader = `
varying vec2 vUv;

uniform sampler2D u_tex;
uniform vec2 acept;

void main()
{
  vec2 uv = vUv * acept;
  vec3 color = vec3(0.3);
  if (uv.x>=0.0 && uv.y>=0.0 && uv.x<1.0 && uv.y<1.0) color = texture2D(u_tex, uv).rgb;
  gl_FragColor = vec4(color, 1.0);
}
`

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

然后我们看到我们画面已经正常了,但是在整体屏幕的下方,所以还差一点点我们需要将它移动到屏幕的中央。

移动到中央的思路和上面差不多,我们只需要注重边界点,假设边界点 C 就是让 80 * ( 0.5 + 9/16 * 0.5 ) 变成 80 ,很快我们也可能得出算是 C * 16/9 - 16/9 * 0.5 + 0.5 = 80

然后来修改 shader,顶点着色器不用改,我们只需要修改片段着色器。

const fshader = `
varying vec2 vUv;

uniform sampler2D u_tex;
uniform vec2 acept;

void main()
{
  vec2 uv = vec2(0.5) + vUv * acept - acept*0.5;
  vec3 color = vec3(0.0);
  if (uv.x>=0.0 && uv.y>=0.0 && uv.x<1.0 && uv.y<1.0) color = texture2D(u_tex, uv).rgb;
  gl_FragColor = vec4(color, 1.0);
}
`

好了,到现在为止,我们的图像显示正常啦~

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

那么 Three.js 中的 textureVideo 到底是如何实现视频的播放的呢?

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

通过查看源码(https://github.com/mrdoob/three.js/blob/6e897f9a42d615403dfa812b45663149f2d2db3e/src/textures/VideoTexture.js)源码非常的少,VideoTexture 继承了 Texture ,最大的一点就是通过 **requestVideoFrameCallback 这个方法,**我们来看看它的定义,发现 mdn 没有相关的示例,我们来到了 w3c 规范中寻找 https://wicg.github.io/video-rvfc/

这个属性主要是获取每一帧的图形,可以通过以下的小 demo 来进行理解

<body>
  <video controls></video>
  <canvas width="640" height="360"></canvas>
  <span id="fps_text"/>
</body>

<script>
  function startDrawing() {
    var video = document.querySelector('video');
    var canvas = document.querySelector('canvas');
    var ctx = canvas.getContext('2d');

    var paint_count = 0;
    var start_time = 0.0;

    var updateCanvas = function(now) {
      if(start_time == 0.0)
        start_time = now;

      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

      var elapsed = (now - start_time) / 1000.0;
      var fps = (++paint_count / elapsed).toFixed(3);
      document.querySelector('#fps_text').innerText = 'video fps: ' + fps;

      video.requestVideoFrameCallback(updateCanvas);
    }

    video.requestVideoFrameCallback(updateCanvas);

    video.src = "http://example.com/foo.webm"
    video.play()
  }
</script>

通过以上的理解,可以很容易抽象出整个过程,通过 requestVideoFrameCallback 获取视频每一帧的画面,然后用 Texture 去渲染到物体上。

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

然后我们来加入 VR 代码, Three.js 默认给他们提供了建立 VR 的方法。

// step1 引入 VRButton
import { VRButton } from 'three/examples/jsm/webxr/VRButton.js';
// step2 将 VRButton 创造的dom添加进body 
document.body.appendChild( VRButton.createButton( renderer ) );
// step3 设置开启 xr
renderer.xr.enabled = true;
// step4 修改更新函数
renderer.setAnimationLoop( function () {
	renderer.render( scene, camera );
} );

由于 iphone 太拉胯不支持 webXR ,特地借了台安卓机(安卓机需要下载 Google Play、Chrome 、Google VR),添加以上步骤后,就会如下显示:

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

点击 ENTER XR 按钮后,即可进入 VR 场景。

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

然后我们我们可以再花20块钱就可以买个谷歌眼镜 cardboard。体验地址如下:

https://fly-three-js.vercel.app/lesson03/code/index4.html

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴

或者也可以像我一样买一个 Oculus 然后躺着看大片

Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴
系列其他文章:文章来源地址https://www.toymoban.com/news/detail-473498.html

  • Three.js系列: 写一个第一/三人称视角小游戏
  • Three.js系列:造个海洋球池来学习物理引擎

到了这里,关于Three.js系列: 在元宇宙看电影,享受 VR 视觉盛宴的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【python小知识】你会用爬虫吗?给大家分享几个爬虫小程序,看电影、看书、天气预报、找学校、挖段子、爬微博都可以哦~

    在这篇文章中,我们将分享7个Python爬虫的小案例,帮助大家更好地学习和了解Python爬虫的基础知识。以下是每个案例的简介和源代码: 这个案例使用BeautifulSoup库爬取豆瓣电影Top250的电影名称、评分和评价人数等信息,并将这些信息保存到CSV文件中。 这个案例使用正则表达式

    2024年01月22日
    浏览(53)
  • vue2+three.js实现宇宙(进阶版)

    2023.9.12今天我学习了vue2+three.js实现一个好看的动态效果: 首先是安装: npm install three 相关代码如下:

    2024年02月09日
    浏览(41)
  • Mixlab 在元宇宙盘了块 “地” 正式进军元宇宙

    Mix 「 据 2022-1-19 微软官方新闻稿 」 微软(纳斯达克股票代码:MSFT)宣布收购游戏开发和互动娱乐内容发行商公司动视暴雪 Activision Blizzard Inc.(ATVI)。微软以每股 95.00 USD 的价格收购动视暴雪,总收购额达 687 亿美元。交易完成后,微软将成为全球第三大游戏公司,仅次于腾

    2024年02月09日
    浏览(50)
  • 区块链在元宇宙中的作用(二)

    第一,解决数据信任问题 如果一个元宇宙没有区块链技术,那么可能会面临各种各样的数据信任问题,你的账号可以被随时平台禁封,你的“资产”价值完全受平台定价和发行量的影响、你的投诉意见可以被平台忽视、你的言论可以被平台屏蔽甚至删除等等一系列的问题将会

    2024年02月04日
    浏览(37)
  • 【元宇宙经济学】实现DC/EP在元宇宙经济中的法币地位

    博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 DC/EP(Digital Currency/Electronic Payment,数字货币/电子支付)不但是元宇宙金融体系的基础,更是整个数字经济的核心。元宇宙提供了典型的、大规模的消费级应用场景,这个场景是超越国界的

    2024年01月16日
    浏览(49)
  • three.js从入门到精通系列教程003 - three.js透视相机(PerspectiveCamera)

    透视相机(PerspectiveCamera) 它是用来模拟人眼所看到的景象,它也是3D场景的渲染中使用得最普遍的投影模式。呈现的效果,类似眼睛看东西,近大远小 源码下载地址: three.js从入门到精通系列教程002 - three.js透视相机(PerspectiveCamera)

    2024年01月19日
    浏览(50)
  • three.js从入门到精通系列教程002 - three.js正交相机OrthographicCamera

    正投影相机-OrthographicCamera,通过正投影相机渲染出来的物体的尺寸都一样,不会因为观察距离的远近而出现近大远小的情况 源码下载地址 three.js从入门到精通系列教程002 - three.js正交相机OrthographicCamera

    2024年01月20日
    浏览(45)
  • P2E游戏《西游降魔》站在元宇宙风口 打造高效、完整且可持续的GameFi2.0体系

    引言:当人类大步迈入元宇宙时代,链上P2E游戏《西游降魔》正与元宇宙生态相伴相生,带领人们开启Play to Earn的变革之旅。 区块链结合游戏组成新的 GameFi 赛道,在 2021 年迎来爆炸式增长。各大公链如:ETH、BSC、OKChain 等呈现出几何量级的数据,乘着热度迅速积累了众多资

    2023年04月08日
    浏览(41)
  • three.js从入门到精通系列教程004 - three.js透视相机(PerspectiveCamera)滚动浏览全景大图

    源码下载地址 three.js从入门到精通系列教程004 - three.js透视相机(PerspectiveCamera)滚动浏览全景大图

    2024年01月23日
    浏览(61)
  • Three.js一学就会系列:02 画线

    最近开始入坑前端3D建站,跟大家一起慢慢深入three.js做网站3D 这篇文章给大家讲下three.js 画线 官网,介绍 ,以及 引入库 ,参看文章片头系列文章:01 第一个3D网站 创建一个场景 创建一个透视摄像机 知识点: camera.position.set():三个参数固定透视摄像机的位置 camera.lookAt():

    2024年02月07日
    浏览(94)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包