-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathcanvas_camera_orthographic2.html
254 lines (219 loc) · 10.8 KB
/
canvas_camera_orthographic2.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - combo camera - orthographic + perspective</title>
<meta charset="utf-8">
<!--
如果没有设置viewport的width的话,网页很可能会超出手机屏幕宽度,具体多宽,要看浏览器定义的默认宽度是多少
user-scalable=no,规定了用户不能缩放网页,但有些浏览器对该项支持不是很好,故需要设置minimum-scale和maximum-scale相同来限制用户缩放
-->
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
color: purple;
}
/*
未访问 a:link {color:blue;}
已访问 a:visited {color:blue;}
鼠标悬停 a:hover {color:red;}
鼠标按下 a:active {color:yellow;}
*/
a {
color: red;
}
</style>
</head>
<body>
<script src="../build/three.js"></script>
<!-- 可以在透视和正交相机上切换,默认为透视相机 -->
<script src="js/cameras/CombinedCamera.js"></script>
<!--
想要使用CanvasRenderer,必须添加如下两个js文件
Projector.js顾名思义上将3d图像投影到Canvas("2d")上,如果没有该文件会报如下错误
THREE.Projector has been moved to /examples/js/renderers/Projector.js. three.js:42883:3
TypeError: THREE.RenderableVertex is not a constructor
-->
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/CanvasRenderer.js"></script>
<!--
统计插件(FPS,渲染时间,chrome内存使用率),min表示js代码经过压缩
-->
<script src="js/libs/stats.min.js"></script>
<div style="position: absolute; top: 10px; width: 100%; text-align: center; ">
<a href="http://threejs.org" target="_blank">three.js</a> - Combo Camera<br>
<!--
链接的onclick事件被先执行,其次是href属性下的动作(页面跳转,或 javascript 伪链接)
假设链接中同时存在href与onclick,如果想让href属性下的动作不执行,onclick必须得到一个false的返回值。
-->
View: <a href="#" onclick="setOrthographic();return false;"> Orthographic</a> |
<a href="#" onclick="setPerspective();return false;">Perspective</a><br>
(焦距)Lens: <a href="#" onclick="setLens(12);return false;">12mm</a> |
<a href="#" onclick="setLens(16);return false;">16mm</a> |
<a href="#" onclick="setLens(24);return false;">24mm</a> |
<a href="#" onclick="setLens(35);return false;">35mm</a> |
<a href="#" onclick="setLens(50);return false;">50mm</a> |
<a href="#" onclick="setLens(60);return false;">60mm</a> |
<a href="#" onclick="setLens(85);return false;">85mm</a> |
<a href="#" onclick="setLens(105);return false;">105mm</a><br>
(视场)Fov: <a href="#" onclick="setFov(30);return false;">30°</a> |
<a href="#" onclick="setFov(50);return false;">50°</a> |
<a href="#" onclick="setFov(70);return false;">70°</a> |
<a href="#" onclick="setFov(100);return false;">100°</a><br>
(缩放)Zoom: <a href="#" onclick="camera.setZoom(0.5);return false;">0.5x</a> |
<a href="#" onclick="camera.setZoom(1);return false;">1x</a> |
<a href="#" onclick="camera.setZoom(2);return false;">2x</a> |
<br/>
Views: <a href="#" onclick="camera.toTopView();lookAtScene=false;return false;">Top view</a> |
<a href="#" onclick="camera.toBottomView();lookAtScene=false;return false;">Bottom view</a> |
<a href="#" onclick="camera.toLeftView();lookAtScene=false;return false;">Left view</a> |
<a href="#" onclick="camera.toRightView();lookAtScene=false;return false;">Right view</a> |
<a href="#" onclick="camera.toFrontView();lookAtScene=false;return false;">Front view</a> |
<a href="#" onclick="camera.toBackView();lookAtScene=false;return false;">Back view</a> |
<a href="#" onclick="lookAtScene=true;return false;">Look at Scene</a>
<br/>
<div id="fov"></div>
</div>
<script>
var container, stats;
var camera, scene, renderer;
var lookAtScene = true;
init();
animate();
//Fov(Field of View,视场)
function setFov( fov ) {
camera.setFov( fov );
document.getElementById('fov').innerHTML = 'FOV '+ fov.toFixed(2) +'°' ;
}
//焦距(Focal Length)
function setLens( lens ) {
// try adding a tween effect while changing focal length, and it'd be even cooler!
// 尝试当改变焦距时,添加一个在两者之间的效果,这不是更酷
var fov = camera.setLens( lens );
document.getElementById('fov').innerHTML = 'Converted ' + lens + 'mm lens to FOV '+ fov.toFixed(2) +'°' ;
}
//切换为正交相机
function setOrthographic() {
camera.toOrthographic();
document.getElementById('fov').innerHTML = 'Orthographic mode' ;
}
//切换为透视相机
function setPerspective() {
camera.toPerspective();
document.getElementById('fov').innerHTML = 'Perspective mode' ;
}
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
//透视相机的near必须在相机位置前,而正交相机的near也可以在相机之后
camera = new THREE.CombinedCamera( window.innerWidth / 2, window.innerHeight / 2, 70, 1, 1000, - 500, 1000 );
//定义相机的位置,有如下两种方式。如果不设置的话,相机位置为默认的Vector3{x:0,y:0,z:0}
//camera.position.x = 200;
//camera.position.y = 100;
//camera.position.z = 200;
camera.position.set(200,100,200)
scene = new THREE.Scene();
// Grid,绘制网格
var size = 500, step = 50;
var geometry = new THREE.Geometry();
for ( var i = - size; i <= size; i += step ) {
//从左下角到右上角,先画横线,在画竖线
//绘制与X轴平行的横线
geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
geometry.vertices.push( new THREE.Vector3( size, 0, i ) );
//绘制与Z轴平行的竖线
geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
geometry.vertices.push( new THREE.Vector3( i, 0, size ) );
}
var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } );
/*
THREE.Line使用WebGL中的gl.LINE_STRIP(一系列的连续直线,即折线)渲染
THREE.LineSegments使用WebGL中的gl.LINES(每一对顶点被解释为一条直线,即线段)渲染
*/
var line = new THREE.LineSegments( geometry, material );
scene.add( line );
// Cubes
var geometry = new THREE.BoxGeometry( 50, 50, 50 );
/*
MeshLambertMaterial,这种材质会考虑光照的影响,可以用来创建颜色暗淡的、不光亮的物体
color: 即diffuse,漫射颜色,默认为0xffffff,白色
ambient: 环境色,默认为0xffffff, 白色, 乘以环境光得到对象的颜色
emissive: 自发光(荧光)颜色,默认为0x000000,黑色,实体颜色,不受其他灯光的影响.
overdraw: 过渡描绘。如果用THREE.CanvasRenderer对象,有缝隙时需设置该值。例如当前如果使用0.5以下的值,三角形的分界线就很明显。但是使用WebGLRenderer则不会有分割线
morphTargets: 表示是否启用变形
*/
var material = new THREE.MeshLambertMaterial( { color: 0xffffff, overdraw: 0.5 } );
for ( var i = 0; i < 100; i ++ ) {
var cube = new THREE.Mesh( geometry, material );
//对Y方向上的高度进行[1,2]的缩放
cube.scale.y = Math.floor( Math.random() * 2 + 1 );
//cube.position为立方体的中心
cube.position.x = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
cube.position.y = ( cube.scale.y * 50 ) / 2;
cube.position.z = Math.floor( ( Math.random() * 1000 - 500 ) / 50 ) * 50 + 25;
scene.add(cube);
}
// Lights
//环境光,提供的是在不同位置和方向上强度都相同的光源,相当于光照模型中各物体之间的反射光,因此通常用来表现光强中非常弱的那部分光
var ambientLight = new THREE.AmbientLight( Math.random() * 0x10 );
scene.add( ambientLight );
//平行光,也称作无限光,平行光光源就如同太阳,若在场景中添加了一个平行光,它可以影响场景中的所有物体,而无论平行光光源设置在任何位置。平行光的方向为它的位置指向场景中心。
var directionalLight = new THREE.DirectionalLight( Math.random() * 0xffffff );
directionalLight.position.x = Math.random() - 0.5;
directionalLight.position.y = Math.random() - 0.5;
directionalLight.position.z = Math.random() - 0.5;
//normalize(): 单位化向量,使其模长为1
directionalLight.position.normalize();
scene.add( directionalLight );
var directionalLight = new THREE.DirectionalLight( Math.random() * 0xffffff );
directionalLight.position.x = Math.random() - 0.5;
directionalLight.position.y = Math.random() - 0.5;
directionalLight.position.z = Math.random() - 0.5;
directionalLight.position.normalize();
scene.add( directionalLight );
renderer = new THREE.CanvasRenderer();
//设置渲染器的"清除色"和"透明度"
renderer.setClearColor( 0xf0f0f0 );
//设置屏幕像素比,与Android上的DIP相仿,作用是在所有设备上的显示效果都相近
renderer.setPixelRatio( window.devicePixelRatio );
//设置待渲染场景的大小
renderer.setSize( window.innerWidth, window.innerHeight );
//将渲染器的DOM元素(即Canvas)添加到HTML中
container.appendChild( renderer.domElement );
//统计插件(FPS,渲染时间,chrome内存使用率)
stats = new Stats();
//这里注意,统计插件的dom元素是"dom",而不是domElement
container.appendChild( stats.dom );
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize() {
//调整透视相机"长宽比",同时调整正交相机的"上下左右"4个面
camera.setSize( window.innerWidth, window.innerHeight );
//更新透视相机的投影矩阵
camera.updateProjectionMatrix();
//重新设置渲染场景的大小
renderer.setSize( window.innerWidth, window.innerHeight );
}
}
function animate() {
requestAnimationFrame( animate );
//这里可以在render前后使用stats.begin和stats.end,也可以在每次渲染的时候调用一次stats.update
stats.begin();
render();
stats.end();
}
function render() {
//Date.now()得到的是当前时间戳,单位毫秒
var timer = Date.now() * 0.0001;
//相机绕着场景中央,在半径200的圆周上往复运动
camera.position.x = Math.cos( timer ) * 200;
camera.position.z = Math.sin( timer ) * 200;
//调整相机视角,对着场景中央
if ( lookAtScene ) camera.lookAt( scene.position );
renderer.render( scene, camera );
}
</script>
</body>
</html>