您的位置:首页 > Web前端 > JavaScript

three.js伪入门教程之旋转的九尾妖狐

2014-03-03 22:07 861 查看
WebGL是一项利用JavaScript API呈现3D计算机图形的技术,其原生API灵活且高性能,但是这些优点的代价就是入门困难,在后续文章我会慢慢和大家分享我学习WebGL的感悟和心得。three.js是一个封装了WebGL API的轻量级库,官方称是其为傻瓜而生的(难道我连傻瓜都不如么……,学习起来略吃力丫)。本文将通过介绍使用three.js在浏览器里渲染一只旋转的九尾妖狐模型引导大家入门three.js。

目标读者

熟悉javascript,无图形编程经验的开发人员。

示例下载

示例的源代码,模型,纹理都可以在这里下载(访问密码58a5)。

效果预览

gif录制设置为10帧/s,实际效果更流畅。




获取模型和纹理文件

本小节可跳过,如果你的电脑上没有安装英雄联盟,maya,photoshop的话……
如果你天生爱折腾,那么我们一步一步来获取英雄联盟游戏里英雄的模型和纹理吧。

打开英雄联盟安装目录,比如C:/Program Files/腾讯游戏/英雄联盟体验服,打开目录下的Game文件夹,里面你会发现很多压缩包,所有英雄的模型和纹理就在这些压缩包里。比如本文使用的是九尾妖狐模型是CharacterSkins.zip解压后的DATA/Characters/Ahri/Skins/Skin04/Ahri_Skin04.skn文件,而纹理是CharacterTextures.zip解压后的DATA/Characters/ahri/skins/skin04/Ahri_Skin04_TX_CM.dds。如果你想提取其他英雄的,可以到其他相似的路径里寻找。好,现在你已经找到了skn和dds文件,把它们拷贝到你喜欢的文件夹里去。
点击这个链接下载maya插件riotfiletranslator。这个插件允许你将skn格式文件导入到maya中去。如果你安装的是maya2014,或许你应该使用这个链接来下载插件。
如果你安装的是maya2011~2013,解压压缩包,将MayaFolder里的icons和scripts文件夹复制到maya安装目录下。将plugin文件夹里和你版本相符的mll文件复制到maya安装目录下的bin/plug-ins里。打开maya,点击菜单栏里的窗口——设置/首选项——插件管理器,将riotfiletranslator.mll和objExport.mll的已加载和自动加载勾选起来。
maya菜单栏点击文件——导入,导入你喜欢英雄的skn文件。将状态栏上的模块选择器修改为多边形模块。选中你的模型,菜单栏点击法线——反向。OK,现在可以导出你的模型了。选中你的模型,菜单栏点击文件——导出当前选择,文件名随意,文件格式改为OBJexport,可以保存了。
点击这个链接(32位)或这个链接(64位)下载并安装photoshop插件NVIDIA
Texture Tools。这个插件允许你将dds格式文件导入到ps中去。用ps打开你喜欢英雄的dds文件,将图像大小修改为2048px*2048px。最后将图像导出为jpg格式。
如果你坚持完成了以上步骤,恭喜你,你获得了你喜欢英雄的obj模型文件和jpg图像纹理。如果你懒的动手,示例下载里已经包含了九尾妖狐的模型和纹理。

three.js伪入门

为了能显示出物体,three.js需要三种东西:场景(scene),摄像机(camera)和渲染器(renderer)(或许这就是three.js名称的由来,谁知道呢)。创建了场景后你就可以往场景里添加物品,比如在场景里放一个白炽灯(点光源),放一个箱子(由六面网格构成),然后由摄像机实时记录,最后渲染器渲染出摄像机拍下的画面。
下面我们来看看怎么让九尾妖狐显现在我们的浏览器里。
//在形成完整的DOM树后触发函数
addEventListener("DOMContentLoaded", function () {
//创建场景
var scene = new THREE.Scene(),
//创建透视摄像机,参数分别代表视场角,屏幕宽高比,视锥近截面,视锥远截面
camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 2000),
//创建渲染器
renderer = new THREE.WebGLRenderer(),
//创建纹理
texture = new THREE.Texture(),
//创建环境光,参数为十六进制的颜色
ambientLight = new THREE.AmbientLight(0xaaaaaa),
//创建定向光源,参数为十六进制的颜色
directionalLight = new THREE.DirectionalLight(0xffeedd),
imgURL = "ahri.jpg",
objURL = "ahri.obj",
obj = null;
//将摄像机向z轴(屏幕外)移动260
camera.position.z = 260;
//设置视口大小
renderer.setSize(innerWidth, innerHeight);
//指定定向光源由z正半轴射向原点(平行光从屏幕外射向屏幕中心)
directionalLight.position.set(0, 0, 1);
//承诺在图片纹理和模型加载完后调用函数,values[0]为图片对象,values[1]为模型对象
Promise.all([loadImage(), loadObject()]).then(function (values) {
//指定纹理使用的图片
texture.image = values[0];
//纹理在创建后发生了改变(由上一语句引发),必须设置needsUpdate属性为true
texture.needsUpdate = true;
obj = values[1];
//遍历模型对象的属性,指定纹理
obj.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material.map = texture;
}
});
//将模型下移一些,使其能居中
obj.position.y = -70;
//将模型,环境光,定向光源添加入场景
scene.add(obj);
scene.add(ambientLight);
scene.add(directionalLight);
document.body.appendChild(renderer.domElement);
//开始渲染
render();
function render() {
//高性能循环渲染
requestAnimationFrame(render);
//每次渲染前将模型沿Y轴旋转0.05
obj.rotation.y += 0.05;
//渲染
renderer.render(scene, camera);
}
});
//图片加载函数
function loadImage() {
//承诺加载完成后返回图片对象
return new Promise(function (resolve) {
new THREE.ImageLoader().load(imgURL, resolve);
});
}
//模型加载函数
function loadObject() {
//承诺加载完成后返回模型对象
return new Promise(function (resolve) {
new THREE.OBJLoader().load(objURL, resolve);
});
}
});


或许你可以这么想象,在一个漆黑的夜里,阿狸在山上冷得在不停的转圈,月亮刚爬上山头,月光从正前方照亮阿狸……
好吧,以上都是我无聊的想象。你可以下载示例然后在chrome浏览器里观看。如果你有任何疑问或发现错误请在下面留言评论。如果你从中受益请期待博主的webgl系列,下个webgl系列文章将不使用three.js,从webgl基础说起……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息