用java在正方体上贴图片_THREE.js为正方体的6个面贴上图片

这篇博客展示了如何利用THREE.js库为一个三维正方体的六个面分别贴上不同的纹理图片。通过创建WebGL渲染器、场景、透视相机、立方体几何体和材质,结合纹理坐标映射,实现了3D正方体的贴图效果。文章还详细解释了纹理坐标、顶点顺序和三角形面的关系。
摘要由CSDN通过智能技术生成

##效果图

173765031_1_20191022035737846

173765031_2_20191022035738597

代码

three

//创建一个renderer ,

var renderer = new THREE.WebGLRenderer({antialias:true});

//设置清空颜色,每秒会渲染60次,渲染的时候会使用此颜色先清空

renderer.setClearColor( new THREE.Color(0xEEEEEE, 1.0) );

//设置渲染尺寸

renderer.setSize( window.innerWidth , window.innerHeight );

//设置阴影允许

renderer.shadowMapEnabled = true;

//将webgl元素添加到body中

document.body.appendChild( renderer.domElement );

//创建场景

var scene = new THREE.Scene();

//创建一个透视相机,45是相机的视角 , 宽高比是屏幕的宽高比 , 最近能看到0.1 , 最远能看到10000

var camera = new THREE.PerspectiveCamera(45 , window.innerWidth/window.innerHeight , 0.1 , 10000 );

//将相机放到x:1000 , y:1000 , z:1000的位置

camera.position.set( 1000 , 1000 , 1000 );

//设置相机的朝向,可以认为与相机镜头垂直的轴线应该和哪一个轴相交

camera.up.set( 0 , 1 , 0 );

//将相机的镜头对准x:0 , y:0 , z:0的位置 经过这个设置相机就被固定住了

camera.lookAt({x:0,y:0,z:0});

//将相机添加到场景中

scene.add( camera );

//创建一个自然光,自然光无处不在

var light1 = new THREE.AmbientLight(0xffffff);

//设置灯光的位置

light1.position.set( 1000 , 1000 , 1000 );

//将灯光加入场景

scene.add( light1 );

//创建一个长宽高600的立方体

var geometry = new THREE.CubeGeometry( 600 , 600 , 600 );

//创建一个phone材质并且用图片作为纹理

var material = new THREE.MeshPhongMaterial( { map: THREE.ImageUtils.loadTexture('./texture-atlas.jpg') } );

var bricks = [

new THREE.Vector2(0, .666) ,

new THREE.Vector2(.5, .666),

new THREE.Vector2(.5, 1),

new THREE.Vector2(0, 1)

];

var clouds = [

new THREE.Vector2(.5, .666),

new THREE.Vector2(1, .666),

new THREE.Vector2(1, 1),

new THREE.Vector2(.5, 1)

];

var crate = [

new THREE.Vector2(0, .333),

new THREE.Vector2(.5, .333),

new THREE.Vector2(.5, .666),

new THREE.Vector2(0, .666)

];

var stone = [

new THREE.Vector2(.5, .333),

new THREE.Vector2(1, .333),

new THREE.Vector2(1, .666),

new THREE.Vector2(.5, .666)

];

var water = [

new THREE.Vector2(0, 0),

new THREE.Vector2(.5, 0),

new THREE.Vector2(.5, .333),

new THREE.Vector2(0, .333)

];

var wood = [

new THREE.Vector2(.5, 0),

new THREE.Vector2(1, 0),

new THREE.Vector2(1, .333),

new THREE.Vector2(.5, .333)

];

// 清除现有的UV映射,geometry对象的faceVertexUvs属性包含该geometry各个面的坐标映射。

geometry.faceVertexUvs[0] = [];

// 立方体的每个面实际上是由2个三角形组成的。所以我们必须单独映射每个三角形

// 个面的顶点坐标的定义顺序必须遵循逆时针方向。为了映射底部三角形,我们需要使用的顶点指数0,1和3,

// 而要映射顶部三角形,我们需要使用索引1,2,和顶点的3。

geometry.faceVertexUvs[0][0] = [ bricks[0], bricks[1], bricks[3] ];

geometry.faceVertexUvs[0][1] = [ bricks[1], bricks[2], bricks[3] ];

geometry.faceVertexUvs[0][2] = [ clouds[0], clouds[1], clouds[3] ];

geometry.faceVertexUvs[0][3] = [ clouds[1], clouds[2], clouds[3] ];

geometry.faceVertexUvs[0][4] = [ crate[0], crate[1], crate[3] ];

geometry.faceVertexUvs[0][5] = [ crate[1], crate[2], crate[3] ];

geometry.faceVertexUvs[0][6] = [ stone[0], stone[1], stone[3] ];

geometry.faceVertexUvs[0][7] = [ stone[1], stone[2], stone[3] ];

geometry.faceVertexUvs[0][8] = [ water[0], water[1], water[3] ];

geometry.faceVertexUvs[0][9] = [ water[1], water[2], water[3] ];

geometry.faceVertexUvs[0][10] = [ wood[0], wood[1], wood[3] ];

geometry.faceVertexUvs[0][11] = [ wood[1], wood[2], wood[3] ];

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

scene.add( mesh );

var orbitCtl = new THREE.OrbitControls( camera );

orbitCtl.autoRotate = false ;

var clock = new THREE.Clock();

function threeStart(){

var delta = clock.getDelta();

orbitCtl.update( delta );

renderer.clear();

renderer.render( scene , camera );

requestAnimationFrame( threeStart );

};

threeStart();

注释

173765031_3_20191022035738737

//此代码所描述的就是上图中坐上角的那个图,坐标系的原点是左下角,(0 , 0.666)表示的是x轴是0y轴是距离原点2/3的地方

//(0.5 , 0.666)表示x轴是0.5 y轴是距离原点2/3的地方,也就是上图中左上那个图的右下方那个点,纹理坐标是逆时针

var bricks = [

new THREE.Vector2(0, .666),

new THREE.Vector2(.5, .666),

new THREE.Vector2(.5, 1),

new THREE.Vector2(0, 1)

];

geometry对象的faceVertexUvs属性包含该geometry各个面的坐标映射。既然我们映射到一个多维数据集,你可能会疑惑为什么数组中有12个面。原因是在ThreeJS模型中,立方体的每个面实际上是由2个三角形组成的。所以我们必须单独映射每个三角形。上述场景中,ThreeJS将为我们加载单一材料贴图,自动分拆成三角形并映射到每个面。

这里要注意每个面的顶点坐标的定义顺序必须遵循逆时针方向。为了映射底部三角形,我们需要使用的顶点指数0,1和3,而要映射顶部三角形,我们需要使用索引1,2,和顶点的3。

173765031_4_20191022035738862

geometry.faceVertexUvs[0] = []; //清除现有的UV映射

//重新设置UV映射

geometry.faceVertexUvs[0][0] = [ bricks[0], bricks[1], bricks[3] ];

geometry.faceVertexUvs[0][1] = [ bricks[1], bricks[2], bricks[3] ];

geometry.faceVertexUvs[0][2] = [ clouds[0], clouds[1], clouds[3] ];

geometry.faceVertexUvs[0][3] = [ clouds[1], clouds[2], clouds[3] ];

geometry.faceVertexUvs[0][4] = [ crate[0], crate[1], crate[3] ];

geometry.faceVertexUvs[0][5] = [ crate[1], crate[2], crate[3] ];

geometry.faceVertexUvs[0][6] = [ stone[0], stone[1], stone[3] ];

geometry.faceVertexUvs[0][7] = [ stone[1], stone[2], stone[3] ];

geometry.faceVertexUvs[0][8] = [ water[0], water[1], water[3] ];

geometry.faceVertexUvs[0][9] = [ water[1], water[2], water[3] ];

geometry.faceVertexUvs[0][10] = [ wood[0], wood[1], wood[3] ];

geometry.faceVertexUvs[0][11] = [ wood[1], wood[2], wood[3] ];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值