八戒引流脚本注册码是真的吗?

模型的基础知识既然在讲3D世界,那么我们这里提到的模型就是3D模型。我不想将一些书上的定义摘抄给大家,那些概念对大家的理解帮助并不大,而接下来,我会将我最直接通俗的理解告诉大家。
我们知道,在3DMAX,MAYA等软件(这是一些三维编辑软件)中,可以制作出3D模型。这些模型可用于室内设计,三维影视,三维游戏等领域。那么3D模型是怎么定义的呢?看看下面我的定义:
3D模型由顶点(vertex)组成,顶点之间连成三角形或四边形(在一个平面上),多个三角形或者四边形就能够组成复杂的立体模型.
如下图所示:
上图就是一辆汽车的3D模型(立体模型),因为是由一个个网格组成,所以,我们也叫其为网格模型。
网格模型很像我们小时候学习的素描,想想我们画素描是不是先描点,然后画线,由线组成面,最后由面组成现实生活中的物体呢?
在这里,概念总是那么难以理解,我们不做深抠概念的学究,我们需要感性的去认识3D模型。
首先,我们来欣赏一些3D模型,这里收集了的一些3D模型,当然其中一些因为加上了纹理,非常诱人。除此之外,你可以在google的3D模型库找到更多的模型,网址是:
图片纹理我们来想一想,3D世界的纹理,由什么组成呢?3D世界的纹理由图片组成。
是的,就这么简单,如果下次谁问你什么是纹理,那么你告诉它是图片,或者贴图就完了。将纹理以一定的规则映射到几何体上,一般是三角形上,那么这个几何体就有纹理皮肤了。
那么在threejs中,或者任何3D引擎中,纹理应该怎么来实现呢?首先应该有一个纹理类,其次是有一个加载图片的方法,将这张图片和这个纹理类捆绑起来。
在threejs中,纹理类由THREE.Texture表示,其构造函数如下所示:1THREE.Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy )
各个参数的意义是:
Image:这是一个图片类型,基本上它有ImageUtils来加载,如下代码1var image = THREE.ImageUtils.loadTexture(url); // url 是一个http://xxxx/aaa.jpg 的类似地址,javascript没有从本地加载数据的能力,所以没有办法从您电脑的C盘加载数据。
Mapping:是一个THREE.UVMapping()类型,它表示的是纹理坐标。下一节,我们将说说纹理坐标。
wrapS:表示x轴的纹理的回环方式,就是当纹理的宽度小于需要贴图的平面的宽度的时候,平面剩下的部分应该p以何种方式贴图的问题。
wrapT:表示y轴的纹理回环方式。 magFilter和minFilter表示过滤的方式,这是OpenGL的基本概念,我将在下面讲一下,目前你不用担心它的使用。当您不设置的时候,它会取默认值,所以,我们这里暂时不理睬他。
format:表示加载的图片的格式,这个参数可以取值THREE.RGBAFormat,RGBFormat等。THREE.RGBAFormat表示每个像素点要使用四个分量表示,分别是红、绿、蓝、透明来表示。RGBFormat则不使用透明,也就是说纹理不会有透明的效果。
type:表示存储纹理的内存的每一个字节的格式,是有符号,还是没有符号,是整形,还是浮点型。不过这里默认是无符号型(THREE.UnsignedByteType)。暂时就解释到这里,有需要时,我们在仔细分析,或者给作者留言询问。
anisotropy:各向异性过滤。使用各向异性过滤能够使纹理的效果更好,但是会消耗更多的内存、CPU、GPU时间,暂时就了解到这里吧。
ok,各个参数介绍完了。我们接下来看纹理坐标。
纹理坐标在正常的情况下,你在0.0到1.0的范围内指定纹理坐标。我们来简单看一下纹理坐标如下图:当我们用一幅图来做纹理的时候,那么这幅图就隐示的被赋予了如图一样的纹理坐标,这个纹理坐标将被对应到一个形状上。ok,我们来看一下例子,这个例子很简单,就是在平面上贴上一张美女的图片。首先,来看看效果。123456789101112131415161718192021222324252627282930313233343536373839404142434445464748var camera, scene,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();
// A begin
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);
// B begin
// 纹理坐标怎么弄
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.innerH
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );}function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );}
仔细阅读上面的代码,一共完成了4件事情:
a:画一个平面
b:为平面赋予纹理坐标
c:加载纹理
d:将纹理应用于材质
做了这四件事,我们的工作就可以大功告成了。还是让我们来详细解释一下吧。
画一个平面通过PlaneGemotry可以画一个平面,代码如下:1var geometry = new THREE.PlaneGeometry( 500, 300, 1, 1 );
这个平面的宽度是500,高度是300.
为平面赋予纹理坐标平面有4个顶点,所以我们只需要指定4个纹理坐标就行了。纹理坐标由顶点的uv成员来表示,uv被定义为一个二维向量THREE.Vector2(),我们可以通过如下代码来为平面定义纹理:1234567geometry.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是分不清楚的。
加载纹理纹理作为一张图片,可以来源于互联网,或者本地服务器,但是就是不能来源于类似C:\pic\a.jpg这样的本地路径。这是因为javascript没有加载本地路径文件的权限。如果你尝试这么做,会报如下的错误:
所以务必在你的电脑上搭建一个tomcat,apache,iis等服务器中的一种,并把图片资源放到服务器中,并通过
这里加载纹理使用了上面介绍的loadTexture函数,代码如下:12345var texture = THREE.ImageUtils.loadTexture(&textures/a.jpg&,null,function(t){});
这个函数的第一个参数是一个相对路径,表示与您的网页之间的相对路径。相对路径对应了一个纹理图片textures/a.jpg。
第二个参数为null,表示时候要传入一个纹理坐标参数,来覆盖前面在geometry中的参数。
第三个表示一个回调函数,表示成功加载纹理后需要执行的函数,参数t是传入的texture。
最后,这个函数的返回值是加载的纹理。
将纹理应用于材质加载好纹理,万事俱备了,只需要将纹理映射到材质就可以了。我们这里使用了一个普通的材质THREE.MeshBasicMaterial,材质中有一个map属性,可以直接接受纹理,我们可以这样定义一个带纹理的材质:1var material = new THREE.MeshBasicMaterial({map:texture});
ok,接下来的事情就简单了,直接将纹理甩给Mesh,同时也别忘了Mesh也需要geometry,他们暧昧的关系如下:1var mesh = new THREE.Mesh( geometry,material );
最后的最后,将这个mesh加入场景中:1scene.add( mesh );
行了,打开你的浏览器,输入你服务器的网址吧,结果就在你眼前。这只是纹理的一个简单入门,也许你还想知道怎么加载立体纹理、为非光滑的平面贴纹理、甚至为人脸贴纹理,那么就关注后面的课程吧。我们无法在一课把这些知识讲完,但后面的课程会陆续告诉你这些知识的,敬请期待,非常感谢您的阅读。
谢谢!转载请注明出处:部分内容转载于网络,若侵犯版权,请告知!谢谢。T_T
皓眸大前端开发学习使用Three.js + Blender构建在浏览器端显示的3D模型
共有1篇评论
前言前端3D效果的展示方法很多,如果简单的显示一个立方体,我们可以用六块div,每块div结合CSS的旋转特性,旋转出不同的角度组装出来一个盒子。当我们拖拽这个盒子的时候,可以用JS根据鼠标新的坐标点刷新那六个div新的旋转角度参数,让六个面始终同步旋转,始终是闭合的,所以视觉效果来看是3D的。上述方法适用于简单的3D模型,比如立方体、长方体等。其特点是,各种控件都支持这种css旋转,比如我们可以把一个iframe做出3D的旋转效果,同时不影响iframe上网页内容的操作,这是比较酷的。但是对于一些更注重细节的3D模型,则很难用css特性来实现。也许我们可以用更多的,粒度更小的div来组装,但缺乏配合这种方法的3D建模工具,只凭经验去拼凑,注定很难适应各种需求。所以我们选择Three.js来实现对3D模型的展示。Three.js提供了一些API,能够在场景里创建一些常见的几何体,比如长方体、球体等。但实际应用的时候,我们更多的是结合一些3D建模软件生成定制的3D模型,然后用Three.js加载显示。3D建模软件选择blender是因为这是一个开源免费的软件,官网:www.blender.org。 Thee.js 当然也是一个开源项目,项目位置:/mrdoob/three.js/第一章 Three.js初体验从github上下载three.js解压进入文件夹后,几个比较有用的文件夹有:build:存放编译生成的Three.js库文件,压缩和未压缩的版本都有;examples:存放各种实例,数量非常多,打开后直接能运行看到效果,是很棒的学习材料; utils:存放各种工具,和blender结合的关键就在这里:utils\exporters\blender,这里我使用2.63\scripts\addons 下面的io_mesh_threejs文件夹,拷贝到我安装的blender目录:C:\Program Files (x86)\Blender Foundation\Blender\2.63\scripts\addons下面,然后在blender里面,点击主窗体显示模式选择图标,选择“User Preference”,在搜索框里输入“three”,找到我们刚刚拷贝过去的addon,勾选安装。这时候,当我们重新切换主窗体选择模式到“info”,在菜单项中选择“File/Export”时就出现了“Three.js(.js)”这一项了,就可以把我们创建的3D文件导出为Three.js支持的json格式的文件了。
按照Three.js官网项目首页的最少代码示例,一个Three.js的工程大致是这样的:var camera, scene,var geometry, material,&init();animate();&function init() {&&&&&camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );&&&&camera.position.z = 1000;&&&&&scene = new THREE.Scene();&&&&&geometry = new THREE.CubeGeometry( 200, 200, 200 );&&&&material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );&&&&&mesh = new THREE.Mesh( geometry, material );&&&&scene.add( mesh );&&&&&renderer = new THREE.CanvasRenderer();&&&&renderer.setSize( window.innerWidth, window.innerHeight );&&&&&document.body.appendChild( renderer.domElement );}&function animate() {&&&&&&&&&requestAnimationFrame( animate );&&&&&mesh.rotation.x += 0.01;&&&&mesh.rotation.y += 0.02;&&&&&renderer.render( scene, camera );&}  Three.js绘制3D模型需要这些基本元素:1,一个camera。 代码中是这样的:camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 ); camera存在透视投影和正视投影两种,透视投影比较符合我们日常习惯,也是常见的选择。创建完camera之后,一般需要设置camera的三维位置等等。2,一个场景。scene = new THREE.Scene(); 场景是用来加载3D模型的三维空间。3,光源。示例中没有设置。4,3D的object。示例中是自己创建的:geometry = new THREE.CubeGeometry( 200, 200, 200 ); &material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );&mesh = new THREE.Mesh( geometry, material );&scene.add( mesh );5,渲染,即执行绘制。在示例中是由一个canvas的render执行的:renderer = new THREE.CanvasRenderer();renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );另外, 为了更好地展示3D模型,代码中使用了animation,这也是Three.js的API,用户自定义每一帧时3D模型不同的状态,然后再render,就能够自动播放了。第二章 Blender的使用blender最快的学习方法就是看视频教程了,这里要感谢一位台湾大哥,制作了一整套的适合初学者的视频教程:因为我也是初学者,所以这里我把自己学习过程中遇到的一些问题列出来,想必会对其他初学者有所帮助。1,Blender极其灵活的窗口系统。初学软件,我一般习惯胡乱点开各种菜单功能,先随意转悠转悠。但玩到最后好几个重要的菜单都丢了,只剩下一个乱七八糟的模型在画面中央摆着,让我好不丧气。比如下图的这个拥有一堆工具按钮,包含无数神奇功能的入口的视窗,如果弄没了会导致视频教程中的纹理设置部分都没法跟随下去了。这个问题的解决需要领悟blender软件的两个基本特征,那就是,任何的窗口地位都是平等的,是可以互相置换的;任何的窗口都可以copy出一个一模一样的窗口来。所以,只要你的界面里面还有一个窗口是打开状态,那么就一定有办法达到任何的窗口状态。这两个特征的关键点就在于窗口的左上角和右上角,分别如下:a. 当点击左上角的时候,会有如下弹出窗,这是对当前窗体属性的选择,所有的窗体主要属性都包括在这里面了。上面看到的窗体是“Properties”。如果我们切换到“Info”,嘿,这个包含一堆工具图标的窗体瞬间变成了只包含“File”,“Add”,“Render”和“Help”四个选项的窗体了。当然,如果我们想把模型导出为Three.js支持的json格式时,正是需要“File”这个菜单了。b. 当鼠标放置到右上角时,鼠标变成了十字星装,这时候可以向左下角拖拽,于是奇迹出现了,一个和当前窗体一模一样的窗体在拖拽形成的区域出现了!配合上面两个基本特性,所有的工具条,可以用鼠标拖动把它们收起隐藏掉;当鼠标放置两个窗体中缝线上点击鼠标右键时,可以选择“join area”把两个窗体再合并为一个。如果不能合并,就把工具条先都收起来。这些在视频教程里都有讲。2,在视频教程的马克杯制作时,我们在制作被子把柄时需要按k键用刻刀刻出一条线。这里2.63里的用法似乎和视频上不一致。我们可以按下k键,然后不用一直按下鼠标左键,只需逐点点击,会自动连接点击点形成刻线。鼠标点击完成后按下回车键就会把线刻上。但是这种方法刻的线不能自动环绕,我们可以在按下k键后按下z键,然后再切,能够自动环绕。3,贡献一下我在看视频教程时记录的三十多个快捷键:鼠标右键:点选a:解除点选鼠标中键按下不放:旋转模型鼠标中间 + shift:移动模型鼠标左键:移动准星shift + c:让准星回到场景中央数字键1:前视图数字键3:侧视图数字键5:平视图数字键7:上视图t:收拉左侧视窗Ctrl + u:保存用户设置Ctrl + 左右方向键:切换设置Ctrl + 上方向键:当前窗口最大化鼠标位于工具条上方时中键按住不放:左右移动可以左右移动工具条上的项目工具条上点右键:Flip to top可将其放置于窗口上方鼠标左键点击模型箭头:可按箭头方向移动物体Ctrl + Tab:可选择vertex/edge/face,用于点选、线选或面选模型z:表面模式和线图模式切换tab:object mode和edit mode间切换Shift + a:调出增加模型的菜单m:把某个物件移动到其它图层b:出现十字准星后鼠标左键拖拽可框选Ctrl + 鼠标左键:复制当前模型到新的位置e:extrude功能,增加新的表面x:删除物件s:缩放g:移动r:旋转F12:预览数字0:摄影机角度看模型k:刻刀,k然后z为环切f:使用选中的3个或4个点建立表面第三章 使用three.js加载blender生成的马克杯模型先看看效果图,这是在firefox里面加载的代码如下: 1 var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight,
windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2,
container, camera, scene, loaded,
renderer, mouseX = 0, mouseY = 0;
8 //记录鼠标位置在动画中使用
9 document.addEventListener( 'mousemove', function (event) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
12 }, false );
14 init();
16 function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
//使用WebGL去渲染,如果用Canvas渲染,浏览器会不堪重负
renderer = new THREE.WebGLRenderer();
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
renderer.domElement.style.position = &relative&;
container.appendChild( renderer.domElement );
//使用场景加载,就能够利用blender建模时设置的相机和光源等,无需我们再定义
var loader = new THREE.SceneLoader();
loader.load( &./cup.js&, function( result ) {
camera = loaded.currentC
camera.aspect = window.innerWidth / window.innerH
camera.updateProjectionMatrix();
scene = loaded.
renderer.setClearColor( loaded.bgColor, loaded.bgAlpha );
animate();
40 //通过实时改变相机的位置达到动画效果
41 function animate() {
requestAnimationFrame( animate );
camera.position.x += ( mouseX - camera.position.x ) * 0.001;
camera.position.y += ( - mouseY - camera.position.y ) * 0.002;
camera.lookAt( scene.position );
renderer.render( scene, camera );
47 }与之对应的html代码如下: 1 &!DOCTYPE html&
2 &html lang=&en&&
&title&three.js webgl - io - scene loader [blender]&/title&
&meta charset=&utf-8&&
&meta name=&viewport& content=&width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0&&
&script src=&/three.js/build/three.min.js&&&/script&
16 &/html&其中cup.js是按照第一节所述,从blender中导出的js文件。这里我们需要加以注意的是,我们这里导出的文件是scen文件,包括摄像机、光源等参数的,点击“Export/Three.js(.js)”后出现的面板上,需要注意这部分:默认情况下“Scene”,“Lights”和“Cameras”是没有勾选的,我们把它们都勾选上。另外,请选用FireFox浏览器加载我们的html文件。因为这里使用了WebGl的render,而webGL默认是不能跨域访问的,所以在Chrome里面如果没做任何配置是不能加载本地的模型文件加以显示的。当然来自服务器的文件是可以的。使用FireFox则不受这个限制。&至此教程完成了基本的3D模型的制作以及在浏览器端的加载。代码来自于Three.js的例程,但特地做了极度的简化,整个js代码不到50行。在后续的教程中,我们将以此为基础,针对不同的任务需求,结合Three.js的API来完成。&第四章 使用three.js加载以图片为纹理的模型(上)在前言中我们介绍过,我们一般不用three.js自带的三维模型创建函数去拼凑我们想要的三维模型,而是使用类似Blender一样的三维建模工具去定制三维模型,然后导出为three.js可以识别的jason格式,加载显示。通过这种方式,我们可以构建较为原始的三维模型在浏览器端显示,比如我们前面看到的马克杯模型。如果单纯依靠三维建模去逼近现实世界中的形体外观是很难的,细节的修缮将给3D建模带来巨大的工作量,同时也会导致模型的加载器计算量巨大,不仅对人还是机器都是巨大的挑战。好在我们可以另辟蹊径,不去追求模型的精细度,而在模型的纹理上做文章,尤其当我们用真实物体的照片作为模型纹理的时候,3D模型的效果立刻就得到了极大的提高,比如这个箱体模型:如果不考虑外表图片纹理,它只是一个简单的立方体模型。加上纹理之后,几乎和我们在一些制作精良的3D游戏中见到的箱体所差无几了。下面我们来分析它的代码: 1 //兼容各种浏览器的animation函数
2 window.requestAnimFrame = (function(callback){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
13 // 实现旋转的动画函数
14 function animate(lastTime, angularSpeed, three){
// 动画更新时以时间为基准
var date = new Date();
var time = date.getTime();
var timeDiff = time - lastT
// 角度以弧度为单位
var angleChange = angularSpeed * timeDiff * 2 * Math.PI / 1000;
three.cube.rotation.y += angleC
lastTime =
// 重新渲染
three.renderer.render(three.scene, three.camera);
// 角度参数在第一次调用时设定
requestAnimFrame(function(){
animate(lastTime, angularSpeed, three);
33 window.onload = function(){
var angularSpeed = 0.2;
var lastTime = 0;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 700;
var scene = new THREE.Scene();
// 以图片为纹理的材质,这是关键点
var material = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture(&crate.jpg&)
// 立方体模型
var cube = new THREE.Mesh(new THREE.CubeGeometry(300, 300, 300), material);
cube.overdraw = true;
scene.add(cube);
// 加入环境光
var ambientLight = new THREE.AmbientLight(0x555555);
scene.add(ambientLight);
// 加入方向光
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
// 把以上创建3D模型的要素都包装成一个对象
var three = {
renderer: renderer,
camera: camera,
scene: scene,
cube: cube
// 使用onload回调函数启动动画,这样能保证图片被完全加载后才开始旋转
var textureImg = new Image();
textureImg.onload = function(){
animate(lastTime, angularSpeed, three, this);
textureImg.src = &crate.jpg&;
82 };与之对应的html代码如下: 1 &!DOCTYPE HTML&
2 &html lang=&en&&
margin: 0px;
overflow: hidden;
&script src=&/three.js/build/three.min.js&&&/script&
&script src=&LoadCrate.js&&&/script&
15 &/html&这个纹理图片可以在这里下载:这篇文章也参考自:作为一个系列中的一篇,相信这篇文章能够让初学者有效的向前推进一步,迈向three.js自由应用的大门!在下一篇里,我们将分析如何给一个用Blender制作的,较为复杂的模型贴图显示在浏览器端。&另外,实践中我们发现,可以使用Chrome浏览器加载本地的WebGL模型中的素材,只需要在启动Chrome的时候加上一下参数:--allow-file-access-from-files --disable-web-security或许只加--allow-file-access-from-files就足够了。方法如下图所示:这样以来我们就可以随意选择自己偏爱的浏览器去调试three.js程序了。第四章 使用three.js加载以图片为纹理的模型(下)在上一章里,为了演示的方便,我们选择了一个简单的模型。但是如前所述,在实际的生产环境中,一方面我们的模型更为复杂,另一方面我们的贴图也不是普通的照片,而是处理过的uv图。uv图就是xyz三维图通过变换形成的二维图,类似数学里面学的极坐标变换。UV图的制作可以借用一些软件工具完成,在blender里面也有UV图编辑器。这一节我们选用three.js官方例程中的一个加载头部模型的示例。原示例有三百多行代码,我把它精简到一百行多一点,包括扩了核心的uv图加载显示部分。而更多的处理代码则直接删掉,虽然显示效果因此差了一些,但精简的代码更适合说明和演示。效果图如下:对应的代码如下:var container,
var camera, scene,
var mesh, directionalL
var mouseX = 0, mouseY = 0;
var targetX = 0, targetY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
// 添加摄像机
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 900;
scene = new THREE.Scene();
// 添加光源
scene.add( new THREE.AmbientLight( 0x222222 ));
directionalLight = new THREE.DirectionalLight( 0xffeedd, 1 );
directionalLight.position.set( 1, -1, 1 ).normalize();
scene.add( directionalLight );
// 添加材质,其中包括uv图纹理
var ambient = 0x111111, diffuse = 0xbbbbbb, specular = 0x070707, shininess = 50;
specular = 0x555555;
var shader = THREE.ShaderSkin[ &skin& ];
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
// normal纹理,diffuse纹理,涉及3D建模知识,目前还不了解具体意义
uniforms[ &tNormal& ].value = THREE.ImageUtils.loadTexture( &leeperrysmith/Infinite-Level_02_Tangent_SmoothUV.jpg& );
uniforms[ &uNormalScale& ].value = 0.75;
uniforms[ &tDiffuse& ].value = THREE.ImageUtils.loadTexture( &leeperrysmith/Map-COL.jpg& );
uniforms[ &passID& ].value = 1;
// 设置一些颜色值
uniforms[ &uDiffuseColor& ].value.setHex( diffuse );
uniforms[ &uSpecularColor& ].value.setHex( specular );
uniforms[ &uAmbientColor& ].value.setHex( ambient );
uniforms[ &uRoughness& ].value = 0.185;
uniforms[ &uSpecularBrightness& ].value = 0.8;
var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true };
material = new THREE.ShaderMaterial( parameters );
// JSON加载器,需要自己指定uv贴图时一般都使用JSON加载器
loader = new THREE.JSONLoader( true );
document.body.appendChild( loader.statusDomElement );
// 回调中暴露加载的模型的形状
loader.load(&leeperrysmith/LeePerrySmith.js&, function( geometry ) {
puteTangents();
// 以加载的模型的geometry和代码创建的材质对象组建mesh对象加载到场景中显示
mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 50;
// scale参数一般是经验参数,自己调节获得
mesh.scale.set( 100, 100, 100 );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColorHex( 0x );
renderer.autoClear = false;
container.appendChild( renderer.domElement );
// 鼠标移动事件,用来移动头部转动
document.addEventListener( 'mousemove', function ( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
}, false );
function animate() {
requestAnimationFrame( animate );
targetX = mouseX * .001;
targetY = mouseY * .001;
// 通过mesh的rotation实现动画,和之前旋转摄像机实现动画不同
if ( mesh ) {
// 目前尚不清楚0.05的参数如何计算得到,或许也是经验值,调节获得?
mesh.rotation.y += 0.05 * ( targetX - mesh.rotation.y );
mesh.rotation.x += 0.05 * ( targetY - mesh.rotation.x );
renderer.clear();
renderer.render( scene, camera );
}对应的html代码如下:&!DOCTYPE html&
&html lang=&en&&
&title&three.js webgl - materials - skin [Lee Perry-Smith]&/title&
&meta charset=&utf-8&&
&meta name=&viewport& content=&width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0&&
background:#000;
&script src=&js/three.js&&&/script&
&script src=&js/ShaderSkin.js&&&/script&
&/html&工程中用到了一些资源,最主要的就是模型的JSON文件:, 然后是ShaderSkin.js的一个THREE扩展:,另外还有两个uv图片:&和&&自己去试试吧!&另,吐槽一些个人感受,仅供参考。在探索Three.js的过程中,深感文档的缺失,不仅中文文档少到可怜,英文文档也极少。对初学者来说这是很恼火的事情。在无望之际,只能反复研究它的示例代码,然后做一点反向工程,通过不断的试验去确定某些函数或API的具体作用。虽然最后结果还不错,但回头想想,如果文档中对API介绍细致,同时配合详尽的示例文档,我花掉这么多时间做的探索或许就可以浓缩成半天的文档阅读了,这样能节省多少时间哪。这个现象本身也说明three.js还处在发展的初期,还有非常多的工作要做。所以对那些打算使用three.js做产品的同仁,希望能慎之又慎,否则很有可能陷入泥沼不能自拔。当然,对那些本身以具备丰富的3D建模知识的同仁来说,很多困难都不值一提,我非常希望这样的牛人能关注three.js这个领域,做一些普及工作,让这个领域在中国能向前迈进一大步。
你尚未登录,无法评论!
技术支持:@信源联创

我要回帖

更多关于 八戒引流脚本制作 的文章

 

随机推荐