Web3D

来源:互联网 发布:svn迁移到linux 编辑:程序博客网 时间:2024/05/17 06:44

Web3D

sf2gis@163.com

2016年2月18日

 

1  目标:在浏览器上构建3D应用。

2 原理:使用WebGL构建javascript的3D应用。

WebGL是OpenGL ES的子类

3 流程:创建Canvas,构建WebGL对象并编写相应的逻辑(gl脚本、编译、链接,由JavaScript调用),绘制3D图形。

参见:http://blog.csdn.net/tiewen/article/details/6895582

4 方法three.js:WebGL库

参考:http://www.ituring.com.cn/minibook/792

官方文档:three.js-master/docs/index.html

4.1 目标:简单的,更加直观的3D绘制库。

4.2 原理:封装WebGL,提供直接的3D绘制功能,在canvas中绘制3D图形。

4.3 流程:安装three.js库,创建页面。

4.3.1安装three.js库:从three.js官网下载所有three.js,解压后到build中将three.js的copy到工程目录,在html中引入。

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

4.3.2创建页面:创建canvas,创建场景,创建3D内容,创建照相机,渲染

4.3.2.1  创建canvas:指定canvas的id和宽高,用于显示3D场景。

<canvas id="mainCanvas" width=200height=200/>

4.3.2.2  创建场景:表示所有3D图形的显示空间。

var scene = new THREE.Scene();

4.3.2.3  创建3D内容:所有3D物体,每个物体包括几何骨架和贴图材质。创建完成后要添加到场景中。

//rect

var rectGeo = newTHREE.BoxGeometry(1,1,1);

var material = newTHREE. MeshNormalMaterial ();

var rect = new THREE.Mesh(rectGeo, material);

scene.add(rect);

4.3.2.4  创建照相机:设置照相机参数,位置,目标视点

var camera = new THREE.OrthographicCamera(-2, 2,2,-2,0,20);

camera.position.set(-3,2, 10);//camera position

camera.lookAt(newTHREE.Vector3(0, 0, 0));//camera target pos

4.3.2.5  渲染:指定渲染显示的canvas,要渲染的场景和照相机(无内容的背景色默认为黑色)。

var renderer = new THREE.WebGLRenderer({

    canvas:document.getElementById('mainCanvas')

});

renderer.render(scene,camera);

4.3.3示例

//h5.html

<!DOCTYPE HTMLPUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

      <title>Html5</title>

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

</head>

<body>

HelloWorld!<br/>

<canvas id="mainCanvas" width=200height=200/>

<scripttype="text/javascript">

//scene

var scene = new THREE.Scene();

//rect

var rectGeo = newTHREE.BoxGeometry(1,1,1);

var material = newTHREE. MeshNormalMaterial ();

var rect = new THREE.Mesh(rectGeo, material);

scene.add(rect);

 

//camera

var camera = new THREE.OrthographicCamera(-2, 2,2,-2,0,20);

camera.position.set(-3,2, 10);//camera position

camera.lookAt(newTHREE.Vector3(0, 0, 0));//camera target pos

 

//render

var renderer = new THREE.WebGLRenderer({

    canvas:document.getElementById('mainCanvas')

});

renderer.render(scene,camera);

</script>

</body>

</html>

4.4 方法:照相机

4.4.1正交照相机OrthographicCamera:具有left,right,top,bottom,near,far六个属性,指明照相机能够看到的范围(坐标范围,以照相机为原点)。

照相机位置position:照相机所在的位置点。

照相机目标lookAt:照相机要看的位置点。

4.4.2透视照相机PerspectiveCamera:具有fov,aspect,near,far四个属性,指明透明的范围。

4.5 方法:3D对象

Vector3:3D点,所有顶点都是3D点。

Vector4:4D点,3D点带有一个测量值。

Vector2:2D点。

Object3D:3D图形基类,包括位置、旋转、缩放、可视性等属性。

Scene:Object3D子类,增加fog属性等,是3D物体的呈现空间。

Geometry:纯几何类型,包括顶点、面、顶点颜色等属性,决定3D物体的骨架。

Material:材质,决定3D物体的外观。

Mesh:Object3D子类,使用Geometry和Material构建3D物体。

立方体:BoxGeometry。

矩形:PlaneGeometry。

3D文字:TextGeometry。

4.6 方法:场景

场景是3D对象的子类。

 

4.7 方法:材质Material

基本材质BasicMaterial

渲染面side:可见FrontSide,不可见面BackSide,双面DoubleSide。

只渲染线wireframe:ture。

贴图map:指定图片。

漫反射材质LambertMaterial

自发光:ambient

环境光:emissive

镜面反射材质PhongMaterial

法向材质NormalMaterial

参考:

http://baike.baidu.com/link?url=AbMJbLJx0DpKadPuk6sNM0rjQq4SQhlJssvIq-hfoY8LBaP_GFFFfSSLTCLJnPRbfskIxccyfM2Qy-LPky4uxq

4.8 方法:动画

4.8.1目标:动态设置3D物体的位置、形状等。

4.8.2原理:使用javascript的setInterval()定时改变状态。或者使用requestAnimationFrame(draw)循环刷新。

4.8.3流程:创建3D页面,设置定时动作,定时刷新。

//h5.html

<!DOCTYPE HTMLPUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

      <title>Html5</title>

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

</head>

<body>

HelloWorld!<br/>

<canvasid="mainCanvas" width=200 height=200/>

<scripttype="text/javascript">

//scene

var scene = newTHREE.Scene();

 

//rect

var rectGeo = newTHREE.BoxGeometry(1,1,1);

var material = newTHREE.MeshNormalMaterial();

var rect = newTHREE.Mesh(rectGeo, material);

scene.add(rect);

 

//camera

var camera = newTHREE.OrthographicCamera(-2, 2, 2,-2,1,20);

camera.position.set(-3,2, 10);//camera position

camera.lookAt(newTHREE.Vector3(0, 0, 0));//camera target pos

 

//render

var renderer = newTHREE.WebGLRenderer({

    canvas:document.getElementById('mainCanvas')

});

renderer.render(scene,camera);

 

//animation

setInterval(draw,20);

function draw(){

      rect.rotation.y=(rect.rotation.y+0.01)%(Math.PI*2);

      renderer.render(scene,camera);

}

</script>

</body>

</html>

4.8.4方法:使用reqestAnimationFrame刷新。

requestAnimationFrame()每次将调用指定函数刷新一次,循环调用产生动画效果。

cancelAnimationFrame()将取消调用。

//h5.html

<!DOCTYPE HTMLPUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

      <title>Html5</title>

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

</head>

<body>

HelloWorld!<br/>

<buttononclick="stop()">stop</button>

<canvasid="mainCanvas" width=200 height=200/>

<scripttype="text/javascript">

//scene

var scene = newTHREE.Scene();

 

//rect

var rectGeo = newTHREE.BoxGeometry(1,1,1);

var material = newTHREE.MeshNormalMaterial();

var rect = newTHREE.Mesh(rectGeo, material);

scene.add(rect);

 

//camera

var camera = newTHREE.OrthographicCamera(-2, 2, 2,-2,1,20);

camera.position.set(-3,2, 10);//camera position

camera.lookAt(newTHREE.Vector3(0, 0, 0));//camera target pos

 

//render

var renderer = newTHREE.WebGLRenderer({

    canvas:document.getElementById('mainCanvas')

});

renderer.render(scene,camera);

 

//animation

var aniID=null;

draw();

function draw(){

      rect.rotation.y=(rect.rotation.y+0.01)%(Math.PI*2);

      renderer.render(scene,camera);

      aniID=requestAnimationFrame(draw);

      console.log(aniID);

}

function stop(){

      cancelAnimationFrame(aniID);

}

 

</script>

</body>

</html>

4.9 方法:光源

环境光AmbientLight:基础光,均匀,只影响前景。

点光源PointLight:灯光效果,越远越暗。

平行光源DirectionalLight:阳光效果,可见面光强度相同。

聚光灯SpotLight:光线集中。

阴影shadow:只有SpotLight和DirectionalLight,LamberMaterial和PangMaterial能够产生阴影。要设置发出阴影的物体和光源为cast,阴影显示的物体设置为receive。

4.10 着色器:使用GLSL脚本手动渲染3D。

参考:http://www.jb51.net/article/33519.htm

4.10.1目标:使用编程控制的3D场景渲染在2D屏幕上。

4.10.2原理:将3D场景投影到2D显示区域使用顶点着色器完成。确定每个顶点的颜色,然后进行插值渲染使用片段着色器完成。

4.10.3流程:创建顶点着色器,创建片段着色器,渲染。

4.10.3.1 创建顶点着色器:将3D投影到2D,使用默认的投影方法就OK。

<scriptid="vs" type="x-shader/x-vertex">

      void main(){

           gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0);

      }

</script>

4.10.3.2 创建片段着色器:指定最终的颜色(RGBA,0~1)。

<script id="fs"type="x-shader/x-vertex">

      void main(){

           gl_FragColor=vec4(1,0,0,1.0);

      }

</script>

4.10.3.3 渲染:创建ShaderMaterial并指定着色器。

var material = new THREE.ShaderMaterial({

    vertexShader: document.getElementById('vs').textContent,

    fragmentShader:document.getElementById('fs').textContent

});

4.10.3.4 示例

//h5.html

<!DOCTYPE HTMLPUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

      <title>Html5</title>

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

</head>

<body>

HelloWorld!<br/>

<canvasid="mainCanvas" width=200 height=200/>

<scriptid="vs" type="x-shader/x-vertex">

      void main(){

           gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0);

      }

</script>

<script id="fs"type="x-shader/x-vertex">

      void main(){

           gl_FragColor=vec4(1,0,0,1.0);

      }

</script>

<scripttype="text/javascript">

//scene

var scene = newTHREE.Scene();

 

//rect

var rectGeo = newTHREE.BoxGeometry(1,1,1);

var material = newTHREE.MeshNormalMaterial();

var material = new THREE.ShaderMaterial({

    vertexShader: document.getElementById('vs').textContent,

    fragmentShader:document.getElementById('fs').textContent

});

var rect = newTHREE.Mesh(rectGeo, material);

scene.add(rect);

 

//camera

var camera = newTHREE.OrthographicCamera(-2, 2, 2,-2,1,20);

camera.position.set(-3,2, 10);//camera position

camera.lookAt(newTHREE.Vector3(0, 0, 0));//camera target pos

 

//render

var renderer = newTHREE.WebGLRenderer({

    canvas:document.getElementById('mainCanvas')

});

renderer.render(scene,camera);

</script>

</body>

</html>

4.11 3D编辑器:从three.js目录editor中打开index.html,进行3D编辑器(推荐使用chrome,不支持IE)。

4.11.1创建新场景:File-》New。

4.11.2添加新图形:Add->Box。

4.11.3添加新光源:Add-》light

4.11.4设置3D图形参数:在右侧的Object中设置位置等参数。

4.11.5设置图形几何参数:在右侧的Geometry中设置长宽高等参数。

4.11.6设置材质参数:在Material中设置材质。

使用着色器:选择ShaderMaterial,选择Vetex编辑顶点着色器脚本,选择Fragment编辑片段着色器脚本。编辑完成后如果没有错误提示,则直接关闭自动保存。

//顶点着色器

varying vec2 vUv;

void main() {

      vUv=uv;

      gl_Position = projectionMatrix *modelViewMatrix * vec4( position, 1.0 );

}

//片段着色器

varying vec2 vUv;

void main() {

      gl_FragColor = vec4( vUv.x, 0.0, 0.0,0.2);

}

  

4.11.7预览:Play,关闭预览使用Stop(与Play同一位置)。

5 方法:3D基本概念

5.1 坐标系:右手展开,拇指为x,食指为y,其余三指与xy垂直为z,则此为右手坐标系统。左手坐标系统同理。

参考:http://baike.baidu.com/view/2939423.htm

5.2 场景Scene:表示所有的3D内容的呈现空间。

5.3 照相机Camera:3D投影系统,目标是将场景绘制到平面,包括正交(正射影像)和透视(人眼)两种。

正交照相机:具有left,right,top,bottom,near,far六个属性,指明照相机能够看到的范围(坐标范围,以照相机为原点)。

照相机位置:照相机所在的位置点。

照相机目标视点:照相机要看的位置点。

5.4 网格Mesh:表示一个3D物体,包括几何形状Geometry(骨架)和材质Material(贴图)。

5.5 渲染Renderer:使用GUI将照相机中2D图形绘制出来(需要指定场景和照相机)。针对每个3D物体的顶点和片段会有两种不同的渲染工具(着色器shader):顶点着色器和片段着色器。

5.6 相对单位:所有的单位都是相对的,基本单位由整个场景范围与canvas范围的比值确定。

5.7 元素位置:元素位置在默认以元素的中心点确定。中心点默认在(0,0,0)

 

0 0