在这个课程里主要完成讲解两个demo:

一个是电视墙:用视频做纹理

一,用视频做纹理

首先我们用video标签把视频源引入:

<video id="video" autoplay loop style="display:none">
<source src="http://10.1.26.29:84/assets/video/sintel_trailer-480p.ogv" type="video/ogg">
<source src="http://10.1.26.29:84/assets/video/sintel_trailer-480p.mp4" type="video/mp4">
<source src="http://10.1.26.29:84/assets/video/sintel_trailer-480p.webm" type="video/webm">
</video>  

设置视频纹理

在这里引入一个概念mipmap:一个mipmap是一组纹理图片,每个图片的尺寸都是前一张图片的一半。这些图片实在加载纹理时创建的,可以生成较平滑的过滤效果。

注意:
1.由于我们的视频不是正方形,所以要保证材质不会生成mipmap。
2.由于材质变化得很频繁,所以我们需要设置简单高效的过滤器。LinearFilter 线性过滤

var video = document.getElementById('video');   //获取页面dom元素

videoTexture = new THREE.Texture(video);

//minFilter属性:指定纹理如何缩小。默认值:THREE.LinearMipMapLinearFilter
videoTexture.minFilter = THREE.LinearFilter;
//magFilter属性:指定纹理如何放大。默认值:THREE.LinearFilter
videoTexture.magFilter = THREE.LinearFilter; videoTexture.format = THREE.RGBFormat;
videoTexture.generateMipmaps = false;

THREE.Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy )

Image:这是一个图片类型,基本上它有ImageUtils来加载,如下代码
var image = THREE.ImageUtils.loadTexture(url); // url 是一个http://xxxx/aaa.jpg 的类似地址,javascript没有从本地加载数据的能力,所以没有办法从您电脑的C盘加载数据。

Mapping:是一个THREE.UVMapping()类型,它表示的是纹理坐标。下一节,我们将说说纹理坐标。

wrapS:表示x轴的纹理的回环方式,就是当纹理的宽度小于需要贴图的平面的宽度的时候,平面剩下的部分应该p以何种方式贴图的问题。

wrapT:表示y轴的纹理回环方式。

magFilterminFilter表示过滤的方式,这是OpenGL的基本概念。当您不设置的时候,它会取默认值。

format:表示加载的图片的格式,这个参数可以取值THREE.RGBAFormat,RGBFormat等。THREE.RGBAFormat表示每个像素点要使用四个分量表示,分别是红、绿、蓝、透明来表示。RGBFormat则不使用透明,也就是说纹理不会有透明的效果。

type:表示存储纹理的内存的每一个字节的格式,是有符号,还是没有符号,是整形,还是浮点型。不过这里默认是无符号型(THREE.UnsignedByteType)。暂时就解释到这里,有需要时,我们在仔细分析,或者给作者留言询问。

anisotropy:各向异性过滤。使用各向异性过滤能够使纹理的效果更好,但是会消耗更多的内存、CPU、GPU时间。

 添加一个长方体作为电视墙,设置纹理时,我们采用两种纹理,有四面是纯色的,有两面是视频纹理,我们这里用数组materials存放六个面的纹理,然后通过THREE.MeshFaceMaterial()设置每个面的纹理,你也可以自己设置,六个面都是视频纹理

var cubeGeometry = new THREE.BoxGeometry(1, 10, 20);
var cubeMaterial = new THREE.MeshBasicMaterial({map: videoTexture}); var materials = [];
materials.push(cubeMaterial);
materials.push(cubeMaterial);
for (var i = 1; i < 5; i++) {
materials.push(new THREE.MeshLambertMaterial({color: 0xff0000}));
}
//MeshFaceMaterial这是一种容器,可以在该容器中为物体的各个表面上设置不同的颜色
var cube = new THREE.Mesh(cubeGeometry, new THREE.MeshFaceMaterial(materials));
cube.position.set(-10.05,0,0);
cube.rotation.x = -0.3;
cube.rotation.y = 23.5;
cube.name = 'cube';
scene.add(cube);

MeshFaceMaterial方法根据参数materials创建mesh(网格)的复合材质类型,参数material是一个Material类型的数组对象,网格中的三角面属性materialindex定义了该三角面使用的参数material中材质对象的索引号. 

添加控制器:

  我们之前已经使用过一个可以缩放的控制器,这里我们使用一个可以旋转的控制器

  用script标签引入一个库文件 OrbitControls.js

  创建一个实例对象,就可以使用了。

orbit = new THREE.OrbitControls(camera);

   完整代码下载:github(threejs-five)  如果你觉得我写的对你有帮助的话,请给个star,谢谢

二,玻璃质感反射一个空间环境

首先我们从原理上进行分析,这种可以表现立体空间环境的实现,实际上是构造了一个大的正方体,(skybox)正方体的六个面的背景是符合实际场景的六张图片,在这个demo里,就是汽车内部的前后左右上下,然后我们在正方体的内部进行观看,从而达到立体环绕的效果;

使用ShaderMaterial(共享材质)实现漫光反射,根据参数parameters创建为自定义着色器创建材质类型,这样的材质对象让用户扩充材质类型,有了无限的可能.

参数的格式:
parameters = {
defines: { "label" : "value" },
uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } }, fragmentShader: <string>,
vertexShader: <string>, shading: THREE.SmoothShading,
blending: THREE.NormalBlending,
depthTest: <bool>,
depthWrite: <bool>, wireframe: <boolean>,
wireframeLinewidth: <float>, lights: <bool>, vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, skinning: <bool>,
morphTargets: <bool>,
morphNormals: <bool>, fog: <bool>
}

 接下来我们从代码进行分析:

首先我们先引入正方体六个面的图片,依然是异步引入

var urls = [
'http://10.1.26.29:84/assets/cubemap/car/right.png',
'http://10.1.26.29:84/assets/cubemap/car/left.png',
'http://10.1.26.29:84/assets/cubemap/car/top.png',
'http://10.1.26.29:84/assets/cubemap/car/bottom.png',
'http://10.1.26.29:84/assets/cubemap/car/front.png',
'http://10.1.26.29:84/assets/cubemap/car/back.png'
];

 用THREE.ImageUtils.loadTextureCube()方法载入纹理

定义一个着色器,基于THREE.ShaderLib来创建自定义的ShaderMaterial材质

var cubemap = THREE.ImageUtils.loadTextureCube(urls);
cubemap.format = THREE.RGBFormat;
//一个特别的着色器(Three.ShaderLib[“cube”]),结合THREE.ShaderMaterial类,我们可以基于CubeMap对象创建一个环境
var shader = THREE.ShaderLib["cube"];
shader.uniforms["tCube"].value = cubemap;
  //ShaderMaterial创建自己的着色器,要使用ShaderMaterial,必须传入两个着色器:fragmentShader,vertexShader
var material = new THREE.ShaderMaterial({
fragmentShader: shader.fragmentShader, //定义每个传入的像素的颜色
vertexShader: shader.vertexShader, //允许你修改每一个传入的顶点的位置
uniforms: shader.uniforms, //该属性可以向你的着色器发送消息,将同样的消息发送到每个顶点和片段
depthWrite: false,
side: THREE.DoubleSide         //实现一个立体双面的效果
});  

接下来,我们就可以创建天空盒子

var skybox = new THREE.Mesh(new THREE.BoxGeometry(10000, 10000, 10000), material);
scene.add(skybox);

 

CubeCamera方法根据 near, far ,cubeResolution 生成立方体相机.CubeCamera对象的功能函数采用 定义构造的函数原型对象来实现. CubeCamera经常用来创建天空盒子.由六张图片拼接成一个场景.

near 指明相对于深度剪切面的近的距离,必须为正数,可选参数,如果未指定,初始化为0.1

far 指明相对于深度剪切面的远的距离,必须为正数,可选参数,如果未指定,初始化为2000

cubeResolution 设置立方体的宽度

Matrix4 返回PerspectiveCamera,透视投影相机

cubeCamera = new THREE.CubeCamera(0.1, 20000, 256);
cubeCamera.renderTarget.minFilter = THREE.LinearMipMapLinearFilter;
scene.add(cubeCamera);

  接下来,我们可以创建镜面反射的立体图形

先以球体为例,

我们用立体相机的渲染目标,cubeCamera.renderTarget,也就是整个环境

var sphereGeometry = new THREE.SphereGeometry(4, 15, 15);
////envMap 设置环境贴图,默认是null
var dynamicEnvMaterial = new THREE.MeshBasicMaterial({envMap: cubeCamera.renderTarget, side: THREE.DoubleSide});
sphere = new THREE.Mesh(sphereGeometry, dynamicEnvMaterial);
sphere.name = 'sphere';
scene.add(sphere);

  再添加一个旋转立方体,可以显示变化的环境

用 cubemap作为纹理贴图,就是上面加载的六张图片

var cubeGeometry = new THREE.BoxGeometry(5, 5, 5);
var envMaterial = new THREE.MeshBasicMaterial({envMap: cubemap, side: THREE.DoubleSide});
var cube = new THREE.Mesh(cubeGeometry, envMaterial);
cube.name = 'cube';
scene.add(cube);
cube.position.set(-10, 0, 0);

 最后,同样使用上面提到的控制器:OrbitControls

orbit = new THREE.OrbitControls(camera);

  

完整代码下载: github(threejs-six)  如果你觉得我写的对你有帮助的话,请给我个star,

 

 

threejs深入纹理,立体场景cubeResolution(四)的更多相关文章

  1. 君子性非异也,善假于物也 - Threejs 引入TrackballControls 查看场景

    君子性非异也,善假于物也 - Threejs 引入TrackballControls 查看场景 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循" ...

  2. 我用Cocos2d-x模拟《Love Live!学院偶像祭》的Live场景(四)

    [前言和思路整理] 千呼万唤Shǐ出来!最近莫名被基友忽悠着进舰坑了,加上要肝LL活动,又碰上公司项目紧张经常加班,这一章发得比以往时候来得更晚一些,抱歉啊. 上一章我们实现了BeatObjectMa ...

  3. RunLoop总结:RunLoop的应用场景(四)

    今天要介绍的RunLoop使用场景很有意思,在做长期项目,需要跟踪解决用户问题非常有用. 使用RunLoop 监测主线程的卡顿,并将卡顿时的线程堆栈信息保存下来,下次上传到服务器. 参考资料 关于今天 ...

  4. THREE.js代码备份——webgl - materials - cube refraction [balls](以上下左右前后6张图片构成立体场景、透明球体效果)

    <!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - ma ...

  5. Hadoop源码学习笔记之NameNode启动场景流程四:rpc server初始化及启动

    老规矩,还是分三步走,分别为源码调用分析.伪代码核心梳理.调用关系图解. 一.源码调用分析 根据上篇的梳理,直接从initialize()方法着手.源码如下,部分代码的功能以及说明,已经在注释阐述了. ...

  6. 新手立体四子棋AI教程(2)——价值评估函数

    上一篇我们完成了整个程序的基础框架,那么在讲到真正的搜索算法前,我们先来看看五子棋如何评估当前局势,以及如何计算某个位置的价值. 一.五子棋 在五子棋中,包括成五,活三,活二等定势,下图为山东师范大学 ...

  7. Android:图解四种启动模式 及 实际应用场景解说

    在一个项目中会包括着多个Activity,系统中使用任务栈来存储创建的Activity实例,任务栈是一种“后进先出”的栈结构.举个栗子,若我们多次启动同一个Activity.系统会创建多个实例依次放入 ...

  8. 白盒-CNN纹理深度可视化: 使用MIT Place 场景预训练模型

    MIT发文:深度视觉的量化表示................ Places2 是一个场景图像数据集,包含 1千万张 图片,400多个不同类型的场景环境,可用于以场景和环境为应用内容的视觉认知任务. ...

  9. webgl图库研究(包括BabylonJS、Threejs、LayaboxJS、SceneJS、ThingJS等框架的特性、适用范围、支持格式、优缺点、相关网址)

    3D图库框架范围与示例 摘要: 为实现企业80%以上的生产数据进行智能转化,在烟草.造纸.能源.电力.机床.化肥等行业,赢得领袖企业青睐,助力企业构建AI赋能中心,实现智能化转型升级.“远舢文龙数据处 ...

随机推荐

  1. WIN7远程桌面连接--“发生身份验证错误。要求的函数不受支持”

    故障现象:WIN7发现远程桌面无法连接了,报“发生身份验证错误.要求的函数不受支持”的错误: 解决办法:开始菜单->运行gpedit.msc 打开配置项:计算机配置>管理模板>系统& ...

  2. pdf下载速度

  3. 2018-2019-2 网络对抗技术 20165321 Exp6 信息搜集与漏洞扫描

    1.实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 百度查找IP地址: 查了一下kali的IP地址 https://fofa.so/的使用: 查询了一 ...

  4. JavaScript 判断当前设备是否是移动端还是PC

    if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)){ alert('移动端')}else { alert('PC端') }

  5. HTML5的优点与缺点?

    优点:a.网络标准统一.HTML5本身是由W3C推荐出来的. b.多设备.跨平台 c.即时更新,提高可用性和改进用户的友好体验: d.有几个新的标签,这将有助于开发人员定义重要的内容: e.可以给站点 ...

  6. UIManager

    创建UIManager,管理所有UI面板 准备工作: 1. 创建Canvas并设置Tag为Main Canvas 2. 在Canvas下新建五个层级节点,因为UGUI显示层级越往下越靠前 using ...

  7. 消息中间件之一:RabbitMQ

    RabbitMQ 是一个实现了AMQP(高级消息队列协议)的消息队列,最初起源于金融系统,主要用来实现应用程序间的异步和解耦,可用于在分布式系统中做消息的存储转发 相比于传统的队列服务概念(消息发送者 ...

  8. 大兄dei,早点看清this吧

    说道this,可以说是前端中很重要的问题之一了,也是面试或者笔试常考的问题.所以还是早点看清this吧,大兄dei. this是什么?为什么要存在? this关键字是js中最最复杂的机制之一.他被自动 ...

  9. SQL中内连接和外连接的区别

    数据表的连接有: 1.内连接(自然连接): 只有两个表相匹配的行才能在结果集中出现 2.外连接: 包括 (1)左外连接(左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表 ...

  10. uva 10123 - No Tipping dp 记忆化搜索

    这题的题意是 在双脚天平上有N块东西,依次从上面取走一些,最后使得这个天平保持平衡! 解题: 逆着来依次放入,如果可行那就可以,记得得有木板自身的重量. /********************** ...