Three.js纹理(一)

一、概念

3D世界的纹理由图片组成。将纹理以一定的规则映射到几何体上,一般是三角形上,那么这个几何体就有纹理皮肤了。

那么在threejs中,或者任何3D引擎中,纹理应该怎么来实现呢?首先应该有一个纹理类,其次是有一个加载图片的方法,将这张图片和这个纹理类捆绑起来。

在threejs中,纹理类由THREE.Texture表示,其构造函数如下所示:

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轴的纹理的回环方式,就是当纹理的宽度小于需要贴图的平面的宽度的时候,平面剩下的部分应该以何种方式贴图的问题。
  • wrapT:表示y轴的纹理回环方式。 magFilter和minFilter表示过滤的方式,这是OpenGL的基本概念。
  • format:表示加载的图片的格式,这个参数可以取值THREE.RGBAFormat,RGBFormat等。THREE.RGBAFormat表示每个像素点要使用四个分量表示,分别是红、绿、蓝、透明来表示。RGBFormat则不使用透明,也就是说纹理不会有透明的效果。
  • type:表示存储纹理的内存的每一个字节的格式,是有符号,还是没有符号,是整形,还是浮点型。不过这里默认是无符号型(THREE.UnsignedByteType)。
  • anisotropy:各向异性过滤。使用各向异性过滤能够使纹理的效果更好,但是会消耗更多的内存、CPU、GPU时间。

纹理坐标:

在正常的情况下,你在0.0到1.0的范围内指定纹理坐标。我们来简单看一下纹理坐标如下图:

当我们用一幅图来做纹理的时候,那么这幅图就隐示的被赋予了如图一样的纹理坐标,这个纹理坐标将被对应到一个形状上。

二、实例

<!DOCTYPE html>
<html lang="en">
<head>
    <title></title>
    <meta charset="utf-8">
    <style>
        body {
            margin: 0px;
            background-color: #000000;
            overflow: hidden;
        }
    </style>
</head>
<body>

<script src="../js/three.js"></script>

<script>

    var camera, scene, renderer;
    var mesh;

    init();
    animate();

    function init() {

        renderer = new THREE.WebGLRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );
        //
        camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
        camera.position.z = 400;
        scene = new THREE.Scene();


        var geometry = new THREE.PlaneGeometry( 500, 300, 1, 1 );
        geometry.vertices[0].uv = new THREE.Vector2(0,0);
        geometry.vertices[1].uv = new THREE.Vector2(2,0);
        geometry.vertices[2].uv = new THREE.Vector2(2,2);
        geometry.vertices[3].uv = new THREE.Vector2(0,2);
        // 纹理坐标怎么弄
        var texture = THREE.ImageUtils.loadTexture("textures/a.jpg",null,function(t)
        {
        });
        var material = new THREE.MeshBasicMaterial({map:texture});
        var mesh = new THREE.Mesh( geometry,material );
        scene.add( mesh );

        //
        window.addEventListener( 'resize', onWindowResize, false );

    }

    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );
    }

    function animate() {
        requestAnimationFrame( animate );
        renderer.render( scene, camera );
    }

</script>

</body>
</html>

上面的代码,一共完成了4件事情:

  1. 画一个平面
  2. 为平面赋予纹理坐标
  3. 加载纹理
  4. 将纹理应用于材质

1.画一个平面

 var geometry = new THREE.PlaneGeometry( 500, 300, 1, 1 );

2.为平面赋予纹理坐标

  平面有4个顶点,所以我们只需要指定4个纹理坐标就行了。纹理坐标由顶点的uv成员来表示,uv被定义为一个二维向量THREE.Vector2(),我们可以通过如下代码来为平面定义纹理:

geometry.vertices[0].uv = new THREE.Vector2(0,0);
geometry.vertices[1].uv = new THREE.Vector2(1,0);
geometry.vertices[2].uv = new THREE.Vector2(1,1);
geometry.vertices[3].uv = new THREE.Vector2(0,1);

  注意,4个顶点分别对应了纹理的4个顶点。还要注意(0,0),(1,0),(1,1),(0,1)他们之间的顺序是逆时针方向。大家在给平面赋纹理坐标的时候也要注意方向,不然three.js是分不清楚的。

3.加载纹理

  纹理作为一张图片,可以来源于互联网,或者本地服务器,但是就是不能来源于类似C:\pic\a.jpg这样的本地路径。这是因为javascript没有加载本地路径文件的权限。

  这里加载纹理使用了上面介绍的loadTexture函数,代码如下:

var texture=THREE.ImageUtils.loadTexture("textures/a.jpg",null,function(t)
{
});

  这个函数的第一个参数是一个相对路径,表示与您的网页之间的相对路径。相对路径对应了一个纹理图片textures/a.jpg。

  第二个参数为null,表示时候要传入一个纹理坐标参数,来覆盖前面在geometry中的参数。

  第三个表示一个回调函数,表示成功加载纹理后需要执行的函数,参数t是传入的texture。

4.将纹理应用于材质

  加载好纹理,万事俱备了,只需要将纹理映射到材质就可以了。我们这里使用了一个普通的材质THREE.MeshBasicMaterial,材质中有一个map属性,可以直接接受纹理,我们可以这样定义一个带纹理的材质:

var material = new THREE.MeshBasicMaterial({map:texture});

ok,接下来的事情就简单了,直接将纹理甩给Mesh,同时也别忘了Mesh也需要geometry,他们暧昧的关系如下:

var mesh = new THREE.Mesh( geometry,material );

最后的最后,将这个mesh加入场景中:

scene.add( mesh );

猜你喜欢

转载自www.cnblogs.com/shenjie0507/p/9077399.html