-
Notifications
You must be signed in to change notification settings - Fork 2
/
exemple_7.html
378 lines (319 loc) · 13.9 KB
/
exemple_7.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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
<!--
Source: Johannes-Raida tutorial
http://www.johannes-raida.de/tutorials.htm
http://www.johannes-raida.de/tutorials/three.js/tutorial07/tutorial07webgl.htm
note: Texture loading not works when file opened locally file://
should be opened using http://
If you have python
using the terminal go to the folder of the sample
run
python -m SimpleHTTPServer
and then open
http://localhost:8000/foo.html
-->
<!doctype html>
<html>
<head>
<!-- fem servir la llibreria three.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r72/three.js"></script>
<style type="text/css">
body {
/* Set the background color of the HTML page to black */
background-color: #000000;
/* Hide oversized content. This prevents the scroll bars. */
overflow: hidden;
/* Define the font and the color for the usage, which is an ordinary HTML overlay. */
font-family: Monospace;
color: white;
}
</style>
<script src="js/three.js"></script>
<script src="js/Detector.js"></script>
<script src="js/Projector.js"></script>
<script src="js/CanvasRenderer.js"></script>
</head>
<body>
<!-- Create a DIV element, which will be shown over the WebGL canvas. The last line
("Renderer: ") will be completed either by "WebGL Renderer" or by "Canvas Renderer". -->
<div id="overlaytext" style="position: absolute; top: 10px; left: 10px">
'F': Loop through the three texture filters (only for WebGL renderer)<br/>
'L': Toggle light (only for WebGL renderer)<br/>
'B': Toggle blending<br/>
Cursor left / right: Control y rotation speed<br/>
Cursor up / down: Control x rotation speed<br/>
Page up / down: Move along z axis<br/>
Renderer:
</div>
<!-- This is the DIV element which will contain the WebGL canvas. To be identifiable lateron,
the id 'WebGLCanvas' is applied to it. -->
<div id="WebGLCanvas">
<script>
// Global scene object
var scene;
// Global camera object
var camera;
// x and y rotation
var xRotation = 0.0;
var yRotation = 0.0;
// Rotation speed around x and y axis
var xSpeed = 0.0;
var ySpeed = 0.0;
// Translation along the z axis
var zTranslation = 0.0;
// The x and y speed is controlled by the cursor keys.
// The translation on the z axis by 'Page up / down'.
// 'glassTexture' is the texture object. We set it global, to modify it's attributes
// lateron.
// 'textureFilter' will have three states (0, 1 or 2), controlling the current texture
// filtering (nearest, linear or mipmapped).
// The next two objects hold two different kinds of light: Ambient and directional light.
// 'enableLights' is the flag, which is switched by the key 'f'.
// Texture and flag for current texture filter
var glassTexture;
var textureFilter = 0;
// Flag for toggling light
var lightIsOn = true;
// Flag for toggling blending
var blendingIsOn = true;
// Global mesh object of the cube
var boxMesh;
// Initialize the scene
initializeScene();
// Animate the scene
animateScene();
/**
* Initialze the scene.
*/
function initializeScene(){
// Check whether the browser supports WebGL. If so, instantiate the hardware accelerated
// WebGL renderer. For antialiasing, we have to enable it. The canvas renderer uses
// antialiasing by default.
// The approach of multiplse renderers is quite nice, because your scene can also be
// viewed in browsers, which don't support WebGL. The limitations of the canvas renderer
// in contrast to the WebGL renderer will be explained in the tutorials, when there is a
// difference.
webGLAvailable = false;
if(Detector.webgl){
renderer = new THREE.WebGLRenderer({antialias:true});
webGLAvailable = true;
document.getElementById("overlaytext").innerHTML += "WebGL Renderer";
// If its not supported, instantiate the canvas renderer to support all non WebGL
// browsers
} else {
renderer = new THREE.CanvasRenderer();
document.getElementById("overlaytext").innerHTML += "Canvas Renderer";
}
// Set the background color of the renderer to black, with full opacity
renderer.setClearColor(0x000000, 1);
// Get the size of the inner window (content area)
// Reduce the canvas size a little bit to prevent scrolling the whole window
// content in Firefox while rotating the cube with the keys.
canvasWidth = window.innerWidth - 10;
canvasHeight = window.innerHeight - 20;
// Set the renderers size to the content areas size
renderer.setSize(canvasWidth, canvasHeight);
// Get the DIV element from the HTML document by its ID and append the renderers DOM
// object to it
document.getElementById("WebGLCanvas").appendChild(renderer.domElement);
// Create the scene, in which all objects are stored (e. g. camera, lights,
// geometries, ...)
scene = new THREE.Scene();
// Now that we have a scene, we want to look into it. Therefore we need a camera.
// Three.js offers three camera types:
// - PerspectiveCamera (perspective projection)
// - OrthographicCamera (parallel projection)
// - CombinedCamera (allows to switch between perspective / parallel projection
// during runtime)
// In this example we create a perspective camera. Parameters for the perspective
// camera are ...
// ... field of view (FOV),
// ... aspect ratio (usually set to the quotient of canvas width to canvas height)
// ... near and
// ... far.
// Near and far define the cliping planes of the view frustum. Three.js provides an
// example (http://mrdoob.github.com/three.js/examples/
// -> canvas_camera_orthographic2.html), which allows to play around with these
// parameters.
// The camera is moved 10 units towards the z axis to allow looking to the center of
// the scene.
// After definition, the camera has to be added to the scene.
camera = new THREE.PerspectiveCamera(45, canvasWidth / canvasHeight, 1, 100);
camera.position.set(0, 0, 6);
camera.lookAt(scene.position);
scene.add(camera);
// Create the cube
var boxGeometry = new THREE.BoxGeometry(2.0, 2.0, 2.0);
// When the CanvasRenderer is used, you will see, that the texture has some distortions.
// To get rid of this, you only have to increase the number of cube segments. The
// WebGLRenderer doesn't needs this workaround.
//var boxGeometry = new THREE.BoxGeometry(2.0, 2.0, 2.0, 4, 4, 4);
// Load an image as texture
glassTexture = new THREE.ImageUtils.loadTexture("images/Glass.jpg");
// Create a material, which contains the texture
// Unfortunately, the CanvasRenderer doesn't support MeshLambertMaterial in combination
// with Textures. Otherwise, the MeshBasicMaterial doesn't support lighting. As
// compromise, the CanvasRenderer will show the texture without lighting via
// MeshBasicMaterial.
var boxMaterial = new THREE.MeshLambertMaterial({
map:glassTexture,
depthWrite: false,
transparent: true,
opacity: 0.5,
side:THREE.DoubleSide,
combine: THREE.MixOperation
});
if(!webGLAvailable){
boxMaterial = new THREE.MeshBasicMaterial({
map:glassTexture,
transparent: true,
opacity: 0.5,
side:THREE.DoubleSide
});
}
// Create a mesh and insert the geometry and the material. Translate the
// whole mesh by 'zTranslation' units on the z axis. Finally add the mesh
// to the scene.
boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);
boxMesh.position.set(0.0, 0.0, zTranslation);
scene.add(boxMesh);
// Ambient light has no direction, it illuminates every object with the same
// intensity. If only ambient light is used, no shading effects will occur.
var ambientLight = new THREE.AmbientLight(0x101010, 1.0);
scene.add(ambientLight);
// Directional light has a source and shines in all directions, like the sun.
// This behaviour creates shading effects.
var directionalLight = new THREE.DirectionalLight(0xffffff, 1.0);
directionalLight.position.set(camera.position.x, camera.position.y, camera.position.z);
scene.add(directionalLight);
// Add a listener for 'keydown' events. By this listener, all key events will be
// passed to the function 'onDocumentKeyDown'. There's another event type 'keypress'.
// It will report only the visible characters like 'a', but not the function keys
// like 'cursor up'.
document.addEventListener("keydown", onDocumentKeyDown, false);
}
/**
* This function is called, when a key is oushed down.
*/
function onDocumentKeyDown(event){
// Get the key code of the pressed key
var keyCode = event.which;
// 'F' - Toggle through the texture filters
if(keyCode == 70){
// The CanvasRenderer doesn't support texture filters.
switch(textureFilter){
case 0:
glassTexture.minFilter = THREE.NearestFilter;
glassTexture.magFilter = THREE.NearestFilter;
textureFilter = 1;
break;
case 1:
glassTexture.minFilter = THREE.LinearFilter;
glassTexture.magFilter = THREE.LinearFilter;
textureFilter = 2;
break;
case 2:
glassTexture.minFilter = THREE.LinearFilter;
glassTexture.magFilter = THREE.LinearMipMapNearestFilter;
textureFilter = 0;
break;
};
glassTexture.needsUpdate = true;
// 'L' - Toggle light
} else if(keyCode == 76){
// If we would just remove the lights from the scene, or set the lights to
// invisible, we would get a black cube due to the MeshLambertMaterial (it needs
// light). So we just switch the material to toggle the light
if(lightIsOn){
boxMesh.material = new THREE.MeshBasicMaterial({map:glassTexture});
boxMesh.material.side = THREE.DoubleSide;
if(blendingIsOn){
boxMesh.material.depthWrite = false;
boxMesh.material.transparent = true;
boxMesh.material.opacity = 0.5;
boxMesh.material.combine = THREE.MixOperation;
} else {
boxMesh.material.depthWrite = true;
boxMesh.material.opacity = 1.0;
boxMesh.material.combine = THREE.MultiplyOperation;
}
lightIsOn = false;
} else {
boxMesh.material = new THREE.MeshLambertMaterial({map:glassTexture});
if(!webGLAvailable){
boxMesh.material = new THREE.MeshBasicMaterial({map:glassTexture});
}
boxMesh.material.side = THREE.DoubleSide;
if(blendingIsOn){
boxMesh.material.depthWrite = false;
boxMesh.material.transparent = true;
boxMesh.material.opacity = 0.5;
boxMesh.material.combine = THREE.MixOperation;
} else {
boxMesh.material.depthWrite = true;
boxMesh.material.opacity = 1.0;
boxMesh.material.combine = THREE.MultiplyOperation;
}
lightIsOn = true;
}
boxMesh.material.needsUpdate = true;
// 'B' - Toggle blending
} else if(keyCode == 66){
if(blendingIsOn){
boxMesh.material.depthWrite = true;
boxMesh.material.opacity = 1.0;
boxMesh.material.combine = THREE.MultiplyOperation;
blendingIsOn = false;
} else {
boxMesh.material.depthWrite = false;
boxMesh.material.transparent = true;
boxMesh.material.opacity = 0.5;
boxMesh.material.combine = THREE.MixOperation;
blendingIsOn = true;
}
boxMesh.material.needsUpdate = true;
// Cursor up
} else if(keyCode == 38){
xSpeed -= 0.01;
// Cursor down
} else if(keyCode == 40){
xSpeed += 0.01;
// Cursor left
} else if(keyCode == 37){
ySpeed -= 0.01;
// Cursor right
} else if(keyCode == 39){
ySpeed += 0.01;
// Page up
} else if(keyCode == 33){
zTranslation -= 0.2;
// Page down
} else if(keyCode == 34){
zTranslation += 0.2;
}
}
/**
* Animate the scene and call rendering.
*/
function animateScene(){
// Update and set the rotation around x and y axis
xRotation += xSpeed;
yRotation += ySpeed;
boxMesh.rotation.set(xRotation, yRotation, 0.0);
// Apply the the translation along the z axis
boxMesh.position.z = zTranslation;
// Define the function, which is called by the browser supported timer loop. If the
// browser tab is not visible, the animation is paused. So 'animateScene()' is called
// in a browser controlled loop.
requestAnimationFrame(animateScene);
// Map the 3D scene down to the 2D screen (render the frame)
renderScene();
}
/**
* Render the scene. Map the 3D world to the 2D screen.
*/
function renderScene(){
renderer.render(scene, camera);
}
</script>
</body>
</html>