4.法向材质

  法向材质可以将材质的颜色设置为其法向量的方向,有时候对于调试很有帮助。

  法向材质的设定很简单,甚至不用设置任何参数:

new THREE.MeshNormalMaterial()

  材质的颜色与照相机与该物体的角度相关,下面我们只改变照相机位置,观察两个角度的颜色变化:

  camera.position.set(5, 25, 25);的效果:

  camera.position.set(25, 25, 25);的效果:

  我们观察的是同样的三个面,但是由于观察的角度不同,物体的颜色就不同了。因此,在调试时,要知道物体的法向量,使用法向材质就很有效。

  源码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>3.js测试8.1</title>
</head>
<body onload="init()">
<canvas id="mainCanvas" width="400px" height="300px" ></canvas>
</body>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript">
function init() {
var renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas')
});
renderer.setClearColor(0x000000);
var scene = new THREE.Scene(); // camera
var camera = new THREE.OrthographicCamera(-5, 5, 3.75, -3.75, 0.1, 100);
camera.position.set(25, 25, 25);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera); // light
var light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(10, 15, 5);
scene.add(light); var material = new THREE.MeshNormalMaterial(); var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5), material);
scene.add(cube); renderer.render(scene, camera);
}
</script>
</html>

5.材质的纹理贴图

  在此之前,我们使用的材质都是单一颜色的,有时候,我们却希望使用图像作为材质。这时候,就需要导入图像作为纹理贴图,并添加到相应的材质中。下面,我们介绍具体的做法。

  5.1 单张图像应用于长方体

  首先,我们选择一张长宽均为128像素的图像:

  将其导入纹理中:

var texture = THREE.ImageUtils.loadTexture('img/0.png');

  然后,将材质的map属性设置为texture:

var material = new THREE.MeshLambertMaterial({

    map: texture

});

  这样就完成了将图片应用于材质的基本步骤。但是由于现在我们还没使用动画,画面只被渲染了一次,而在导入纹理之前,已经完成了这次渲染,因此看到的只是一片黑。所以,如果没有重绘函数(将在下一篇介绍),就需要在完成导入纹理的步骤后,重新绘制画面,这是在回调函数中实现的:

var texture = THREE.ImageUtils.loadTexture('img/0.png', {}, function() {

    renderer.render(scene, camera);

});

var material = new THREE.MeshLambertMaterial({

    map: texture

});

  现在,就能看到这样的效果了:

  类似地,如果将其应用于球体,将会把整个球体应用该图像:

  源码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>3.js测试8.2</title>
</head>
<body onload="init()">
<canvas id="mainCanvas" width="400px" height="300px" ></canvas>
</body>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript">
function init() {
var renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas')
});
renderer.setClearColor(0x000000);
var scene = new THREE.Scene(); // camera
var camera = new THREE.OrthographicCamera(-10, 10, 7.5, -7.5, 0.1, 100);
camera.position.set(25, 25, 25);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera); // light
var light = new THREE.PointLight(0xffffff, 1, 1000);
light.position.set(10, 15, 20);
scene.add(light); var texture = THREE.ImageUtils.loadTexture('img/0.png', {}, function() {
renderer.render(scene, camera);
});
var material = new THREE.MeshLambertMaterial({
map: texture
}); // var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5), material);
// scene.add(cube);
var sphere = new THREE.Mesh(new THREE.SphereGeometry(5, 25, 15), material);
scene.add(sphere); renderer.render(scene, camera);
}
</script>
</html>

  5.2 六张图像应用于长方体

  有时候,我们希望长方体的六面各种的贴图都不同。因此,我们首先准备了六张颜色各异的图像,分别写了数字0到5。然后,分别导入图像到六个纹理,并设置到六个材质中:

var materials = [];

for (var i = 0; i < 6; ++i) {

  materials.push(new THREE.MeshBasicMaterial({

    map: THREE.ImageUtils.loadTexture('img/' + i + '.png',

      {}, function() {

        renderer.render(scene, camera);

      }),

    overdraw: true

  }));

}

var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5),

  new THREE.MeshFaceMaterial(materials));

scene.add(cube);

  效果为:

  源码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>3.js测试8.3</title>
</head>
<body onload="init()">
<canvas id="mainCanvas" width="400px" height="300px" ></canvas>
</body>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript">
function init() {
var renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas')
});
renderer.setClearColor(0x000000);
var scene = new THREE.Scene(); // camera
var camera = new THREE.OrthographicCamera(-10, 10, 7.5, -7.5, 0.1, 100);
camera.position.set(25, 25, 25);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera); // light
var light = new THREE.PointLight(0xffffff, 1, 1000);
light.position.set(10, 15, 20);
scene.add(light); var materials = [];
for (var i = 0; i < 6; ++i) {
materials.push(new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture('img/' + i + '.png', {}, function() {
renderer.render(scene, camera);
}),
overdraw: true
}));
} var cube = new THREE.Mesh(new THREE.CubeGeometry(5, 5, 5),
new THREE.MeshFaceMaterial(materials));
scene.add(cube); renderer.render(scene, camera);
}
</script>
</html>

  5.3 棋盘格

  现在,我们有一个黑白相间的图像:

  我们希望用它填满一个屏幕。按照之前的做法依法炮制:

var texture = THREE.ImageUtils.loadTexture('img/chess.png', {}, function() {

  renderer.render(scene, camera);

});

  效果是:

  可是,棋盘格是8横8纵64个小方格组成的,那应该怎么办呢?

  首先,我们需要指定重复方式为两个方向(wrapS和wrapT)都重复:

texture.wrapS = texture.wrapT = THREE.RepeatWrapping;

  然后,设置两个方向上都重复4次,由于我们的图像本来是有2行2列,所以重复4次即为8行8列:

texture.repeat.set(4, 4);

  最终就得到了棋盘格:

  源码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>3.js测试8.4</title>
</head>
<body onload="init()">
<canvas id="mainCanvas" width="400px" height="300px" ></canvas>
</body>
<script type="text/javascript" src="js/three.min.js"></script>
<script type="text/javascript">
function init() {
var renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas')
});
//renderer.setClearColor(0x666666);
var scene = new THREE.Scene(); // camera
var camera = new THREE.OrthographicCamera(-10, 10, 7.5, -7.5, 0.1, 100);
camera.position.set(0, 0, 25);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera); // light
var light = new THREE.PointLight(0xffffff, 1, 1000);
light.position.set(10, 15, 20);
scene.add(light); var texture = THREE.ImageUtils.loadTexture('img/chess.png', {}, function() {
renderer.render(scene, camera);
});
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(4, 4);
var material = new THREE.MeshLambertMaterial({
map: texture
}); var plane = new THREE.Mesh(new THREE.PlaneGeometry(12, 12), material);
scene.add(plane); renderer.render(scene, camera);
}
</script>
</html>

整理自张雯莉《Three.js入门指南》

Three.js基础探寻八——法向材质与材质的纹理贴图的更多相关文章

  1. Three.js基础探寻一

    1.webGL 一种网络标准,定义了一些较底层的图形接口. 2.Three.js 一个3Djs库,webGL开源框架中比较优秀的一个.除了webGL以外,Three.js还提供了基于Canvas.SV ...

  2. Three.js基础探寻二——正交投影照相机

    本篇主要介绍照相机中的正交投影照相机. 第一篇传送门:Three.js基础探寻一 1.照相机 图形学中的照相机定义了三维空间到二维屏幕的投影方式. 针对投影方式照相机分为正交投影照相机和透视投影照相机 ...

  3. Three.js基础探寻七——Lamber材质与Phong材质

    材质(Material)是独立于物体顶点信息之外的与渲染效果相关的属性.通过设置材质可以改变物体的颜色.纹理贴图.光照模式等. 本篇将介绍基本材质以及两种基于光照模型的材质(Lamber与Phong) ...

  4. Three.js基础探寻九——网格

    在学习了几何形状和材质之后,我们就能使用他们来创建物体了.最常用的一种物体就是网格(Mesh),网格是由顶点.边.面等组成的物体:其他物体包括线段(Line).骨骼(Bone).粒子系统(Partic ...

  5. Three.js基础探寻四——立方体、平面与球体

    前面简单介绍了webGL和Three.js的背景以及照相机的设定,接下来介绍一些Three.js中的几何形状. 1.立方体 虽然这一形状的名字叫立方体(CubeGeometry),但它其实是长方体,也 ...

  6. Three.js基础探寻五——正二十面体、圆环面等

    除了立方体.平面.球体,Three.js还提供了很多其他几何形状. 1.圆形 CircleGeometry可以创建圆形或者扇形: THREE.CircleGeometry(radius, segmen ...

  7. Three.js基础探寻六——文字形状与自定义形状

    1.文字形状 说起3d文字想起了早年word里的一些艺术字: 时间真快. 那么TextGeometry可以用来创建三维的文字形状. 使用文字形状需要下载和引用额外的字体库.这里,我们以 helveti ...

  8. Three.js基础探寻十——动画

    本篇将介绍如果使用Three.js进行动态画面的渲染.此外,将会介绍一个Three.js作者写的另外一个库stat.js,用来观测每秒帧数(FPS). 1.实现动画效果 1.1 动画原理 对于Thre ...

  9. Three.js基础探寻三——透视投影照相机

    本篇主要介绍Three.js照相机中的透视投影照相机. 上一篇:正交投影照相机 5.透视投影照相机构造函数 透视投影照相机(Perspective Camera)的构造函数是: THREE.Persp ...

随机推荐

  1. selenium - switch_to.frame()- 内嵌表单的切换

    表单嵌套frame/iframe webDriver只能在一个页面上对元素识别和定位,对于frame/iframe表单内嵌页面上的元素无法直接定位,此时就需要通过switch_to.frame()方法 ...

  2. Hdu5693 D Game

    D Game Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  3. Idea安装findbugs插件,以及findbugs安装find security bugs插件

    第一:先讲述Idea怎么安装findbugs插件 具体操作如下面的图所示: 然后就可以安装findbugs 第二:findbugs怎么安装find security bugs这个find bugs的插 ...

  4. python自学笔记(二)

    通过前文介绍,大体上可以用学过的知识做一些东西了. 这里简单介绍下python参数解析argparse命令. 使用argparse需要引用  import argparse 然后调用 parser = ...

  5. std::sort运行出core(segment fault)

    http://note.youdao.com/noteshare?id=6aae09345e85ab55fe24ac959118a747

  6. bzoj 1070 费用流

    //可以网络流,但是要怎么分配每辆车让谁维修以及维修顺序呢.可以考虑每辆车维修时间对总结果的贡献,把每个修车人拆成n个点共n*m个点, //n辆车连向这n*m个点,流量1,费用k*修车时间,其中k(1 ...

  7. select、poll和epoll多路I/O复用

    一.三者的区别 select  select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被 ...

  8. SpringCloud学习(4)——Ribbon负载均衡

    Ribbon概述 SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具. 简单的说, Ribbon是Netflix发布的开源项目, 主要功能是提供客户端软 ...

  9. Ant Design Upload 组件上传文件到云服务器 - 七牛云、腾讯云和阿里云的分别实现

    在前端项目中经常遇到上传文件的需求,ant design 作为 react 的前端框架,提供的 upload 组件为上传文件提供了很大的方便,官方提供的各种形式的上传基本上可以覆盖大多数的场景,但是对 ...

  10. NOIP模拟1

    期望得分:100+100+100=300 实际得分:94+96+97=287 T1  #6090. 「Codeforces Round #418」尘封思绪 #include<cstdio> ...