Three.js基础探寻八——法向材质与材质的纹理贴图
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基础探寻八——法向材质与材质的纹理贴图的更多相关文章
- Three.js基础探寻一
1.webGL 一种网络标准,定义了一些较底层的图形接口. 2.Three.js 一个3Djs库,webGL开源框架中比较优秀的一个.除了webGL以外,Three.js还提供了基于Canvas.SV ...
- Three.js基础探寻二——正交投影照相机
本篇主要介绍照相机中的正交投影照相机. 第一篇传送门:Three.js基础探寻一 1.照相机 图形学中的照相机定义了三维空间到二维屏幕的投影方式. 针对投影方式照相机分为正交投影照相机和透视投影照相机 ...
- Three.js基础探寻七——Lamber材质与Phong材质
材质(Material)是独立于物体顶点信息之外的与渲染效果相关的属性.通过设置材质可以改变物体的颜色.纹理贴图.光照模式等. 本篇将介绍基本材质以及两种基于光照模型的材质(Lamber与Phong) ...
- Three.js基础探寻九——网格
在学习了几何形状和材质之后,我们就能使用他们来创建物体了.最常用的一种物体就是网格(Mesh),网格是由顶点.边.面等组成的物体:其他物体包括线段(Line).骨骼(Bone).粒子系统(Partic ...
- Three.js基础探寻四——立方体、平面与球体
前面简单介绍了webGL和Three.js的背景以及照相机的设定,接下来介绍一些Three.js中的几何形状. 1.立方体 虽然这一形状的名字叫立方体(CubeGeometry),但它其实是长方体,也 ...
- Three.js基础探寻五——正二十面体、圆环面等
除了立方体.平面.球体,Three.js还提供了很多其他几何形状. 1.圆形 CircleGeometry可以创建圆形或者扇形: THREE.CircleGeometry(radius, segmen ...
- Three.js基础探寻六——文字形状与自定义形状
1.文字形状 说起3d文字想起了早年word里的一些艺术字: 时间真快. 那么TextGeometry可以用来创建三维的文字形状. 使用文字形状需要下载和引用额外的字体库.这里,我们以 helveti ...
- Three.js基础探寻十——动画
本篇将介绍如果使用Three.js进行动态画面的渲染.此外,将会介绍一个Three.js作者写的另外一个库stat.js,用来观测每秒帧数(FPS). 1.实现动画效果 1.1 动画原理 对于Thre ...
- Three.js基础探寻三——透视投影照相机
本篇主要介绍Three.js照相机中的透视投影照相机. 上一篇:正交投影照相机 5.透视投影照相机构造函数 透视投影照相机(Perspective Camera)的构造函数是: THREE.Persp ...
随机推荐
- Meeting HDU - 5521 虚点建图
Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer John ...
- bzoj 1510 [POI2006]Kra-The Disks 二分
1510: [POI2006]Kra-The Disks Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 466 Solved: 272[Submit][ ...
- Java常量池详解之Integer缓存
一个Java question,求输出结果 public class IntegerTest { public static void main(String[] args) { objPoolT ...
- centos7 网络问题
1虚拟机网卡设置--网卡设置模式为NET模式(正常情况是可以直接上网的)2“cd /etc/sysconfig/network-scripts/3使用命令“sudo vi ifcfg-ens33”进入 ...
- jdbc:oracle:thin:@localhost:1521:orcl和jdbc:oracle:thin:@localhost:1521/orcl的区别
Oracle Thin JDBC Driver 驱动程序包名:ojdbc14.jar.ojdbc6.jar 驱动程序类名: oracle.jdbc.driver.OracleDriver JDBC ...
- CF839 D 容斥
求$gcd>1$的所有$gcd(a_i,a_{i+1}…a_{n})*(n-i+1)$的和 首先先标记所有出现的数.从高到低枚举一个数k,记录它的倍数出现次数cnt,那么当前所有组合的答案就是$ ...
- POJ 3304 Segments 基础线段交判断
LINK 题意:询问是否存在直线,使得所有线段在其上的投影拥有公共点 思路:如果投影拥有公共区域,那么从投影的公共区域作垂线,显然能够与所有线段相交,那么题目转换为询问是否存在直线与所有线段相交.判断 ...
- [php]数组建立方式
1.$a[0]=..; $a[1]=..; $a[2]=..; $a[3]=..; 2.$a=array(1,2,3,4,5); 3.自定义数组 $a['logo']="qq"; ...
- 51nod1471 小S的兴趣
题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 320 小S喜欢有趣的事.但是,每个人的兴趣都是独特的.小S热衷于自问自答.有一天,小S想出了一个问题 ...
- 【BZOJ做题记录】07.07~?
在NOI一周前重开一个坑 最后更新时间:7.08 07:38 7.06 下午做的几道CQOI题: BZOJ1257: [CQOI2007]余数之和sum:把k mod i写成k-k/i*i然后分段求后 ...