-
Notifications
You must be signed in to change notification settings - Fork 12
/
canvas_performance.html
197 lines (177 loc) · 8.61 KB
/
canvas_performance.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
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - performance</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;
}
</style>
</head>
<body>
<script src="../build/three.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>
<script>
var container, stats;
var camera, scene, renderer;
var light;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
scene = new THREE.Scene();
/*
透视相机
PerspectiveCamera(fov, aspect, near, far)
fov(视场):从相机位置能够看到的部分场景。推荐默认值45
aspect(长宽比):渲染结果输出区域的横向长度和纵向长度的比值。推荐默认值window.innerWidth/window.innerHeight
near(近面):定义从距离相机多近的地方开始渲染场景。推荐默认值0.1
far(远面):定义相机可以从它所处的位置看多远。默认值1000
*/
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
//定义相机的位置,有如下两种方式。如果不设置的话,相机位置为默认的Vector3{x:0,y:0,z:0}
camera.position.set( 0, 1000, 1000 );
//camera.position.x = 0;
//camera.position.y = 1000;
//camera.position.z = 1000;
camera.lookAt( scene.position );
// Grid,绘制网格
var size = 500, step = 100;
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.5 } );
/*
THREE.Line使用WebGL中的gl.LINE_STRIP(一系列的连续直线,即折线)渲染
THREE.LineSegments使用WebGL中的gl.LINES(每一对顶点被解释为一条直线,即线段)渲染
*/
var line = new THREE.LineSegments( geometry, material );
scene.add( line );
/*
Sphere,球体
function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {……}
radius: 半径
widthSegments: 水平方向上的分段数,段数越多,球体表面越光滑,默认是8。最小是3
heightSegments: 垂直方向上的分段数,段数越多,球体表面越光滑,默认是6,最小是2
phiStart: 从X轴的什么地方开始绘制(X轴负方向为起始点,逆时针方向为正,即符合右手螺旋定则)
phiLength: 绘制的弧度
thetaStart: 从Y轴的什么地方开始绘制(Y轴正方向为起始点,逆时针方向为正,即符合右手螺旋定则)
thetaLength: 绘制的弧度
*/
geometry = new THREE.SphereGeometry( 100, 26, 18 );
/*
MeshLambertMaterial,这种材质会考虑光照的影响,可以用来创建颜色暗淡的、不光亮的物体
color: 即diffuse,漫射颜色,默认为0xffffff,白色
ambient: 环境色,默认为0xffffff, 白色, 乘以环境光得到对象的颜色
emissive: 自发光(荧光)颜色,默认为0x000000,黑色,实体颜色,不受其他灯光的影响.
overdraw: 过渡描绘。如果用THREE.CanvasRenderer对象,有缝隙时需设置该值。例如当前如果使用0.5以下的值,三角形的分界线就很明显。但是使用WebGLRenderer则不会有分割线
morphTargets: 表示是否启用变形
*/
material = new THREE.MeshLambertMaterial( { color: 0xffffff, overdraw: 0.5 } );
for ( var i = 0; i < 20; i ++ ) {
var sphere = new THREE.Mesh( geometry, material );
sphere.position.x = ( i % 5 ) * 200 - 400;
sphere.position.z = Math.floor( i / 5 ) * 200 - 400;
scene.add( sphere );
}
// Lights
/*
环境光,提供的是在不同位置和方向上强度都相同的光源,它的颜色会添加到整个场景和所有对象的当前颜色上,相当于光照模型中各物体之间的反射光,因此通常用来表现光强中非常弱的那部分光
AmbientLight( color, intensity)
color 光源的颜色
intensity 光照强度,默认为1
*/
var ambientLight = new THREE.AmbientLight( Math.random() * 0x202020 );
scene.add( ambientLight );
//color.getStyle()
console.log("ambientLight", ambientLight.color.getStyle(), ambientLight.color.getHexString());
/*
平行光,也称作无限光,平行光光源就如同太阳,若在场景中添加了一个平行光,它可以影响场景中的所有物体,而无论平行光光源设置在任何位置
DirectionalLight( color, intensity)
color 光源的颜色
intensity 光照强度,默认为1
*/
var directionalLight = new THREE.DirectionalLight( Math.random() * 0xffffff );
//directionLight(平行光)的position实际上存储的是它的方向,而非位置
directionalLight.position.set( 0, 1, 0 );
scene.add( directionalLight );
console.log("directionalLight", directionalLight.color.getStyle(), directionalLight.color.getHexString());
/*
点光源,空间中的一点,朝所有方向发射光线
PointLight(color, intensity, distance, decay)
color 光源的颜色
intensity 光照强度,默认为1
distance 光照射的距离
decay 衰减系数
*/
light = new THREE.PointLight( 0xff0000, 1, 500 );
scene.add( light );
renderer = new THREE.CanvasRenderer();
renderer.setClearColor( 0xf0f0f0 );
//devicePixelRatio是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例,与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() {
//重新设置相机的宽高比。如果宽高比不对,那么正方形可能就不是正方形了
camera.aspect = window.innerWidth / window.innerHeight;
//更新透视相机的投影矩阵
camera.updateProjectionMatrix();
//重新设置渲染场景的大小
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
//这里可以在render前后使用stats.begin和stats.end,也可以在每次渲染的时候调用一次stats.update
stats.update();
}
function render() {
//Date.now()得到的是当前时间戳,单位毫秒
var timer = Date.now() * 0.001;
//点光源绕着Y轴旋转
light.position.x = Math.cos( timer ) * 1000;
light.position.y = 500;
light.position.z = Math.sin( timer ) * 1000;
renderer.render( scene, camera );
}
</script>
</body>
</html>