【3.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入门指南》

时间: 2024-07-31 23:14:31

【3.js探寻八】——法向材质与材质的纹理贴图的相关文章

原生js获得八种方式,事件操作

08.17自我总结 关于js 一.原生js获得八种方式 通过ID获取(getElementById) 通过name属性(getElementsByName) 通过标签名(getElementsByTagName) 通过类名(getElementsByClassName) 通过选择器获取一个元素(querySelector) 通过选择器获取一组元素(querySelectorAll) 获取html的方法(document.documentElement) document.documentElem

材质与材质脚本

材质与材质脚本 一.基本概念 (一)Ogre的材质(Material) 为了优化渲染,必须把渲染状态的变化减少到最小.而最频繁的渲染状态改变是材料的变化(大多是纹理的变化). Ogre的Material类封装了物体的所有材料属性,类似于3D Studio中material的概念.平时不被认为是属于材料的属性,像culling模式和深度缓存设置等,也被Material包含近来了.因为这些属性同样影响了物体的外观,把它们放到Material类里可以集中设置所有影响物体的属性.这和D3D中只保存颜色组

js 科学计数法 转换为 数字字符 突破幂数正数21位,负数7位的自动转换限制

前天工作中要转换后台返回的一个数据,返回是的科学计算的数字字符,用网上能搜索到的常用两种方法转换会有倍数的限制,然后又搜索了很久,还是没有找到好的方法,虽然也有一些自己写的方法,可还是不能像下面两种方法一样能正常转换各种正负科学计数,且突破幂数正数21位,负数7位的自动转换限制.所以对比了下,花一下午修改测试,基本通用了,只是传入的参数必须为字符串的科学计数. var num = new Number('3.54545E-3'); // 3.54545e-7var sBalance = pars

js科学计数法问题

//科学计数法转换function getFullNum(num) { //处理非数字 if (isNaN(num)) { return num }; //处理不需要转换的数字 var str = '' + num; if (!/e/i.test(str)) { return num; }; return (num).toFixed(18).replace(/\.?0+$/, "");} 原文地址:https://www.cnblogs.com/lindaCai/p/8695791.h

block本质探寻八之循环引用

说明:阅读本文,请参照之前的block文章加以理解: 一.循环引用的本质 //代码——ARC环境 void test1() { Person *per = [[Person alloc] init]; per.age = 10; per.block = ^{ NSLog(@"-------1"); }; } int main(int argc, const char * argv[]) { @autoreleasepool { test1(); // test2(); } NSLog(

js 二分查找法之每日一更

<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html"/> <meta name="keywords" content="二分查找算法" /> <meta name="description" content="二分查找算法&

Ionic Js十八:滑动框

ion-slide-box 滑动框是一个包含多页容器的组件,每页滑动或拖动切换: 效果图如下: ? ? 用法 <ion-slide-box on-slide-changed="slideHasChanged($index)"> <ion-slide> <div class="box blue"><h1>BLUE</h1></div> </ion-slide> <ion-slid

js基础八

10个div点击一个div变绿色,其他都为红色,立即执行函数包裹代码防止全局变量产生选取对象集合如何实现,给每个div添加事件,循环这个对象集合 (在点击的这个div的时候做判断,判断当前的这个div是否是红色,如果是红色就变为绿色, 把所有div变成绿色,再把当前点击的这个div变成红色(所有div的点颜色赋值为绿色,点击的style的背景颜色赋值为红色) 再点击红色的时候把红色再次变为绿色,把当前div变成绿色 方法二:添加类名的方式 操作元素内容:innerHTML 设置或获取标签当中的内

JS 设计模式八 -- 发布订阅者模式

概念 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多(一个发布,多个观察)的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 优点 1.支持简单的广播通信,当对象状态发生改变时,会自动通知已经订阅过的对象. 2.发布者与订阅者耦合性降低 缺点 创建订阅者需要消耗一定的时间和内存. 如果过度使用的话,反而使代码不好理解及代码不好维护. 代码实现 var Event = (function(){ var list = {}, // 缓