├── .gitattributes
├── 9781484263174.jpg
├── Contributing.md
├── LICENSE.txt
├── README.md
├── ch10_ex9
├── assets
│ ├── attribution.txt
│ ├── city
│ │ ├── scene.bin
│ │ ├── scene.gltf
│ │ └── textures
│ │ │ ├── World_ap.11_baseColor.jpeg
│ │ │ ├── World_ap.15_baseColor.jpeg
│ │ │ ├── World_ap.16_baseColor.jpeg
│ │ │ ├── World_ap.17_baseColor.jpeg
│ │ │ ├── World_ap.19_baseColor.jpeg
│ │ │ ├── World_ap.8_baseColor.jpeg
│ │ │ ├── World_ap.9_baseColor.jpeg
│ │ │ └── World_ap_baseColor.jpeg
│ └── dragon
│ │ ├── scene.bin
│ │ ├── scene.gltf
│ │ └── textures
│ │ ├── material_0_diffuse.png
│ │ ├── material_0_normal.png
│ │ ├── material_0_occlusion.png
│ │ └── material_0_specularGlossiness.png
└── index.html
├── ch2
└── index.html
├── ch3
├── ex2_part1
│ ├── index.html
│ └── index.js.js
├── ex2_part2
│ ├── index.html
│ └── lesson2-2.js
├── ex2_part3
│ ├── index.html
│ └── lesson2-3.js
└── webGLtemplate.js
├── ch4
├── index.html
├── lesson3-1.js
└── lesson3-2.js
├── ch5_ex4
├── index.html
├── index_ex4_final.js
├── modules
│ └── three.module.js
└── textures
│ ├── pebbies_gray.png
│ ├── pebbles.jpg
│ ├── pebbles_height.png
│ ├── pebbles_normal.png
│ └── sphere_normal.png
├── ch6_ex5
├── VRButton.js
├── index.html
├── index_xr.js
└── textures
│ ├── pebbles.png
│ ├── pebbles_normal.png
│ └── sphere_normal.png
├── ch7_ex6
├── Part1_Floating-Cube
│ ├── index.html
│ └── index.js
└── Part2_Hit-Test
│ ├── hit_test.js
│ └── index.html
├── ch8_Ex7_Parts_1_2
├── index.html
└── textures
│ ├── brick_mat.jpg
│ ├── grass-nm.jpg
│ └── grass.jpg
├── ch8_Ex7_Parts_3_4
├── index.html
└── textures
│ ├── brick_mat.jpg
│ ├── grass-nm.jpg
│ └── grass.jpg
├── ch9_ex8
├── assets
│ ├── oculus-touch-controller-left.mtl
│ ├── oculus-touch-controller-left.obj
│ ├── oculus-touch-controller-right.mtl
│ └── oculus-touch-controller-right.obj
├── index.html
└── package-lock.json
└── errata.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/9781484263174.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/9781484263174.jpg
--------------------------------------------------------------------------------
/Contributing.md:
--------------------------------------------------------------------------------
1 | # Contributing to Apress Source Code
2 |
3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers.
4 |
5 | ## How to Contribute
6 |
7 | 1. Make sure you have a GitHub account.
8 | 2. Fork the repository for the relevant book.
9 | 3. Create a new branch on which to make your change, e.g.
10 | `git checkout -b my_code_contribution`
11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted.
12 | 5. Submit a pull request.
13 |
14 | Thank you for your contribution!
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Freeware License, some rights reserved
2 |
3 | Copyright (c) 2021 Rakesh Baruah
4 |
5 | Permission is hereby granted, free of charge, to anyone obtaining a copy
6 | of this software and associated documentation files (the "Software"),
7 | to work with the Software within the limits of freeware distribution and fair use.
8 | This includes the rights to use, copy, and modify the Software for personal use.
9 | Users are also allowed and encouraged to submit corrections and modifications
10 | to the Software for the benefit of other users.
11 |
12 | It is not allowed to reuse, modify, or redistribute the Software for
13 | commercial use in any way, or for a user’s educational materials such as books
14 | or blog articles without prior permission from the copyright holder.
15 |
16 | The above copyright notice and this permission notice need to be included
17 | in all copies or substantial portions of the software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 | SOFTWARE.
26 |
27 |
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Apress Source Code
2 |
3 | This repository accompanies [*AR and VR Using the WebXR API*](https://www.apress.com/9781484263174) by Rakesh Baruah (Apress, 2021).
4 |
5 | [comment]: #cover
6 | 
7 |
8 | Download the files as a zip using the green button, or clone the repository to your machine using Git.
9 |
10 | ## Releases
11 |
12 | Release v1.0 corresponds to the code in the published book, without corrections or updates.
13 |
14 | ## Contributions
15 |
16 | See the file Contributing.md for more information on how you can contribute to this repository.
--------------------------------------------------------------------------------
/ch10_ex9/assets/attribution.txt:
--------------------------------------------------------------------------------
1 | "City" by antonmoek
2 | https://sketchfab.com/antonmoek
3 | CC BY 4.0
4 | https://creativecommons.org/licenses/by/4.0/
5 |
6 | "Dragon" by elly77ellison
7 | https://sketchfab.com/3d-models/animated-dragon-0ea921bb3d504023b891bba3fb8e6111
8 | CC BY 4.0
9 | https://creativecommons.org/licenses/by/4.0/
--------------------------------------------------------------------------------
/ch10_ex9/assets/city/scene.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/city/scene.bin
--------------------------------------------------------------------------------
/ch10_ex9/assets/city/textures/World_ap.11_baseColor.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/city/textures/World_ap.11_baseColor.jpeg
--------------------------------------------------------------------------------
/ch10_ex9/assets/city/textures/World_ap.15_baseColor.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/city/textures/World_ap.15_baseColor.jpeg
--------------------------------------------------------------------------------
/ch10_ex9/assets/city/textures/World_ap.16_baseColor.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/city/textures/World_ap.16_baseColor.jpeg
--------------------------------------------------------------------------------
/ch10_ex9/assets/city/textures/World_ap.17_baseColor.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/city/textures/World_ap.17_baseColor.jpeg
--------------------------------------------------------------------------------
/ch10_ex9/assets/city/textures/World_ap.19_baseColor.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/city/textures/World_ap.19_baseColor.jpeg
--------------------------------------------------------------------------------
/ch10_ex9/assets/city/textures/World_ap.8_baseColor.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/city/textures/World_ap.8_baseColor.jpeg
--------------------------------------------------------------------------------
/ch10_ex9/assets/city/textures/World_ap.9_baseColor.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/city/textures/World_ap.9_baseColor.jpeg
--------------------------------------------------------------------------------
/ch10_ex9/assets/city/textures/World_ap_baseColor.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/city/textures/World_ap_baseColor.jpeg
--------------------------------------------------------------------------------
/ch10_ex9/assets/dragon/scene.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/dragon/scene.bin
--------------------------------------------------------------------------------
/ch10_ex9/assets/dragon/textures/material_0_diffuse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/dragon/textures/material_0_diffuse.png
--------------------------------------------------------------------------------
/ch10_ex9/assets/dragon/textures/material_0_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/dragon/textures/material_0_normal.png
--------------------------------------------------------------------------------
/ch10_ex9/assets/dragon/textures/material_0_occlusion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/dragon/textures/material_0_occlusion.png
--------------------------------------------------------------------------------
/ch10_ex9/assets/dragon/textures/material_0_specularGlossiness.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch10_ex9/assets/dragon/textures/material_0_specularGlossiness.png
--------------------------------------------------------------------------------
/ch10_ex9/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | WebXR API: Ch.10 Ex.9
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
28 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ch2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WebGL: Canvas Context
7 |
14 |
15 |
16 |
17 |
24 |
31 |
32 |
116 |
117 |
--------------------------------------------------------------------------------
/ch3/ex2_part1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WebGL: Lesson 2 Creating 2D
7 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ch3/ex2_part1/index.js.js:
--------------------------------------------------------------------------------
1 | main();
2 |
3 | function main() {
4 | /*========== Create a WebGL Context ==========*/
5 | const canvas = document.querySelector("#c");
6 | const gl = canvas.getContext('webgl');
7 | if (!gl) {
8 | console.log('WebGL unavailable');
9 | } else {
10 | console.log('WebGL is good to go');
11 | }
12 |
13 | /*========== Define and Store the Geometry ==========*/
14 | const firstSquare = [
15 | // front face
16 | -0.3 , -0.3, -0.3,
17 | 0.3, -0.3, -0.3,
18 | 0.3, 0.3, -0.3,
19 |
20 | -0.3, -0.3, -0.3,
21 | -0.3, 0.3, -0.3,
22 | 0.3, 0.3, -0.3,
23 | ];
24 |
25 | // buffer
26 | const origBuffer = gl.createBuffer();
27 | gl.bindBuffer(gl.ARRAY_BUFFER, origBuffer);
28 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(firstSquare), gl.STATIC_DRAW);
29 |
30 | /*========== Shaders ==========*/
31 |
32 | const vsSource = `
33 | attribute vec4 aPosition;
34 |
35 | void main() {
36 | gl_Position = aPosition;
37 | }
38 | `;
39 |
40 | const fsSource = `
41 | void main() {
42 | gl_FragColor = vec4(1, 0, 0, 1);
43 | }
44 | `;
45 | //create shaders
46 | const vertexShader = gl.createShader(gl.VERTEX_SHADER);
47 | const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
48 | gl.shaderSource(vertexShader, vsSource);
49 | gl.shaderSource(fragmentShader, fsSource);
50 |
51 | // compile shaders
52 | gl.compileShader(vertexShader);
53 | gl.compileShader(fragmentShader);
54 |
55 | // create program
56 | const program = gl.createProgram();
57 | gl.attachShader(program, vertexShader);
58 | gl.attachShader(program, fragmentShader);
59 |
60 | // link program
61 | gl.linkProgram(program);
62 | gl.useProgram(program);
63 |
64 | /*========== Connect the attribute with the vertex shader ==========*/
65 | const posAttribLocation = gl.getAttribLocation(program, "aPosition");
66 | gl.vertexAttribPointer(posAttribLocation, 3, gl.FLOAT, false, 0, 0);
67 | gl.enableVertexAttribArray(posAttribLocation);
68 |
69 | /*========== Drawing ========== */
70 | gl.clearColor(1, 1, 1, 1);
71 |
72 | // gl.enable(gl.DEPTH_TEST);
73 | // gl.depthFunc(gl.LEQUAL);
74 |
75 | // gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
76 | gl.clear(gl.COLOR_BUFFER_BIT);
77 | // Draw the points on the screen
78 | const mode = gl.TRIANGLES;
79 | const first = 0;
80 | const count = 6;
81 | gl.drawArrays(mode, first, count);
82 | }
83 |
--------------------------------------------------------------------------------
/ch3/ex2_part2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WebGL: Lesson 2-2 Creating Squares
7 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ch3/ex2_part2/lesson2-2.js:
--------------------------------------------------------------------------------
1 | main();
2 |
3 | function main() {
4 | /*========== Create a WebGL Context ==========*/
5 | const canvas = document.querySelector("#c");
6 | const gl = canvas.getContext('webgl');
7 | if (!gl) {
8 | console.log('WebGL unavailable');
9 | } else {
10 | console.log('WebGL is good to go');
11 | }
12 |
13 | /*========== Define and Store the Geometry ==========*/
14 | const squares = [
15 | // front face
16 | -0.3 , -0.3, -0.3,
17 | 0.3, -0.3, -0.3,
18 | 0.3, 0.3, -0.3,
19 |
20 | -0.3, -0.3, -0.3,
21 | -0.3, 0.3, -0.3,
22 | 0.3, 0.3, -0.3,
23 |
24 | // back face
25 | -0.2, -0.2, 0.3,
26 | 0.4, -0.2, 0.3,
27 | 0.4, 0.4, 0.3,
28 |
29 | -0.2, -0.2, 0.3,
30 | -0.2, 0.4, 0.3,
31 | 0.4, 0.4, 0.3,
32 | ];
33 |
34 | // buffer
35 | const origBuffer = gl.createBuffer();
36 | gl.bindBuffer(gl.ARRAY_BUFFER, origBuffer);
37 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squares), gl.STATIC_DRAW);
38 |
39 | const squareColors = [
40 | 0.0, 0.0, 1.0, 1.0,
41 | 0.0, 0.0, 1.0, 1.0,
42 | 0.0, 0.0, 1.0, 1.0,
43 | 0.0, 0.0, 1.0, 1.0,
44 | 0.0, 0.0, 1.0, 1.0,
45 | 0.0, 0.0, 1.0, 1.0,
46 |
47 | 1.0, 0.0, 0.0, 1.0,
48 | 1.0, 0.0, 0.0, 1.0,
49 | 1.0, 0.0, 0.0, 1.0,
50 | 1.0, 0.0, 0.0, 1.0,
51 | 1.0, 0.0, 0.0, 1.0,
52 | 1.0, 0.0, 0.0, 1.0,
53 | ];
54 |
55 | const colorBuffer = gl.createBuffer();
56 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
57 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squareColors), gl.STATIC_DRAW);
58 |
59 | /*========== Shaders ==========*/
60 |
61 | const vsSource = `
62 | attribute vec4 aPosition;
63 | attribute vec4 aVertexColor;
64 |
65 | varying lowp vec4 vColor;
66 |
67 | void main() {
68 | gl_Position = aPosition;
69 | vColor = aVertexColor;
70 | }
71 | `;
72 |
73 | const fsSource = `
74 | varying lowp vec4 vColor;
75 |
76 | void main() {
77 | gl_FragColor = vColor;
78 | }
79 | `;
80 |
81 | //create shaders
82 | const vertexShader = gl.createShader(gl.VERTEX_SHADER);
83 | const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
84 | gl.shaderSource(vertexShader, vsSource);
85 | gl.shaderSource(fragmentShader, fsSource);
86 |
87 | // compile shaders
88 | gl.compileShader(vertexShader);
89 | if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
90 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vertexShader));
91 | gl.deleteShader(vertexShader);
92 | return null;
93 | }
94 | gl.compileShader(fragmentShader);
95 | if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
96 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fragmentShader));
97 | gl.deleteShader(fragmentShader);
98 | return null;
99 | }
100 |
101 | // create program
102 | const program = gl.createProgram();
103 | gl.attachShader(program, vertexShader);
104 | gl.attachShader(program, fragmentShader);
105 |
106 | // link program
107 | gl.linkProgram(program);
108 | gl.useProgram(program);
109 |
110 | /*========== Connect the attribute with the vertex shader ==========*/
111 | const posAttribLocation = gl.getAttribLocation(program, "aPosition");
112 | gl.bindBuffer(gl.ARRAY_BUFFER, origBuffer);
113 | gl.vertexAttribPointer(posAttribLocation, 3, gl.FLOAT, false, 0, 0);
114 | gl.enableVertexAttribArray(posAttribLocation);
115 |
116 | const colorAttribLocation = gl.getAttribLocation(program, "aVertexColor");
117 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
118 | gl.vertexAttribPointer(colorAttribLocation, 4, gl.FLOAT, false, 0, 0);
119 | gl.enableVertexAttribArray(colorAttribLocation);
120 |
121 | /*========== Drawing ========== */
122 | gl.clearColor(1, 1, 1, 1);
123 |
124 | gl.enable(gl.DEPTH_TEST);
125 | //gl.depthFunc(gl.LEQUAL);
126 |
127 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
128 | //gl.clear(gl.COLOR_BUFFER_BIT);
129 | // Draw the points on the screen
130 | const mode = gl.TRIANGLES;
131 | const first = 0;
132 | const count = 12;
133 | gl.drawArrays(mode, first, count);
134 | }
135 |
--------------------------------------------------------------------------------
/ch3/ex2_part3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WebGL: Lesson 2-3 Creating 3D
7 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ch3/ex2_part3/lesson2-3.js:
--------------------------------------------------------------------------------
1 | main();
2 |
3 | function main() {
4 | /*========== Create a WebGL Context ==========*/
5 | const canvas = document.querySelector("#c");
6 | const gl = canvas.getContext('webgl');
7 | if (!gl) {
8 | console.log('WebGL unavailable');
9 | } else {
10 | console.log('WebGL is good to go');
11 | }
12 |
13 | /*========== Define and Store the Geometry ==========*/
14 | const squares = [
15 | // front face
16 | -0.3 , -0.3, -0.3,
17 | 0.3, -0.3, -0.3,
18 | 0.3, 0.3, -0.3,
19 |
20 | -0.3, -0.3, -0.3,
21 | -0.3, 0.3, -0.3,
22 | 0.3, 0.3, -0.3,
23 |
24 | // back face
25 | -0.2, -0.2, 0.3,
26 | 0.4, -0.2, 0.3,
27 | 0.4, 0.4, 0.3,
28 |
29 | -0.2, -0.2, 0.3,
30 | -0.2, 0.4, 0.3,
31 | 0.4, 0.4, 0.3,
32 |
33 | // top face
34 | -0.3, 0.3, -0.3,
35 | 0.3, 0.3, -0.3,
36 | -0.2, 0.4, 0.3,
37 |
38 | 0.4, 0.4, 0.3,
39 | 0.3, 0.3, -0.3,
40 | -0.2, 0.4, 0.3,
41 | ];
42 |
43 | // buffer
44 | const origBuffer = gl.createBuffer();
45 | gl.bindBuffer(gl.ARRAY_BUFFER, origBuffer);
46 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squares), gl.STATIC_DRAW);
47 |
48 | const squareColors = [
49 | 0.0, 0.0, 1.0, 1.0,
50 | 0.0, 0.0, 1.0, 1.0,
51 | 0.0, 0.0, 1.0, 1.0,
52 | 0.0, 0.0, 1.0, 1.0,
53 | 0.0, 0.0, 1.0, 1.0,
54 | 0.0, 0.0, 1.0, 1.0,
55 | 1.0, 0.0, 0.0, 1.0,
56 | 1.0, 0.0, 0.0, 1.0,
57 | 1.0, 0.0, 0.0, 1.0,
58 | 1.0, 0.0, 0.0, 1.0,
59 | 1.0, 0.0, 0.0, 1.0,
60 | 1.0, 0.0, 0.0, 1.0,
61 | 0.0, 1.0, 0.0, 1.0,
62 | 0.0, 1.0, 0.0, 1.0,
63 | 0.0, 1.0, 0.0, 1.0,
64 | 0.0, 1.0, 0.0, 1.0,
65 | 0.0, 1.0, 0.0, 1.0,
66 | 0.0, 1.0, 0.0, 1.0,
67 | ];
68 |
69 | const colorBuffer = gl.createBuffer();
70 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
71 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squareColors), gl.STATIC_DRAW);
72 |
73 | /*========== Shaders ==========*/
74 |
75 | const vsSource = `
76 | attribute vec4 aPosition;
77 | attribute vec4 aVertexColor;
78 |
79 | varying lowp vec4 vColor;
80 |
81 | void main() {
82 | gl_Position = aPosition;
83 | vColor = aVertexColor;
84 | }
85 | `;
86 |
87 | const fsSource = `
88 | varying lowp vec4 vColor;
89 |
90 | void main() {
91 | gl_FragColor = vColor;
92 | }
93 | `;
94 |
95 | //create shaders
96 | const vertexShader = gl.createShader(gl.VERTEX_SHADER);
97 | const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
98 | gl.shaderSource(vertexShader, vsSource);
99 | gl.shaderSource(fragmentShader, fsSource);
100 |
101 | // compile shaders
102 | gl.compileShader(vertexShader);
103 | if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
104 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vertexShader));
105 | gl.deleteShader(vertexShader);
106 | return null;
107 | }
108 | gl.compileShader(fragmentShader);
109 | if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
110 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fragmentShader));
111 | gl.deleteShader(fragmentShader);
112 | return null;
113 | }
114 |
115 | // create program
116 | const program = gl.createProgram();
117 | gl.attachShader(program, vertexShader);
118 | gl.attachShader(program, fragmentShader);
119 |
120 | // link program
121 | gl.linkProgram(program);
122 | gl.useProgram(program);
123 |
124 | /*========== Connect the attribute with the vertex shader ==========*/
125 | const posAttribLocation = gl.getAttribLocation(program, "aPosition");
126 | gl.bindBuffer(gl.ARRAY_BUFFER, origBuffer);
127 | gl.vertexAttribPointer(posAttribLocation, 3, gl.FLOAT, false, 0, 0);
128 | gl.enableVertexAttribArray(posAttribLocation);
129 |
130 | const colorAttribLocation = gl.getAttribLocation(program, "aVertexColor");
131 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
132 | gl.vertexAttribPointer(colorAttribLocation, 4, gl.FLOAT, false, 0, 0);
133 | gl.enableVertexAttribArray(colorAttribLocation);
134 |
135 | /*========== Drawing ========== */
136 | gl.clearColor(1, 1, 1, 1);
137 |
138 | gl.enable(gl.DEPTH_TEST);
139 | //gl.depthFunc(gl.LEQUAL);
140 |
141 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
142 | //gl.clear(gl.COLOR_BUFFER_BIT);
143 | // Draw the points on the screen
144 | const mode = gl.TRIANGLES;
145 | const first = 0;
146 | const count = 18;
147 | gl.drawArrays(mode, first, count);
148 | }
149 |
--------------------------------------------------------------------------------
/ch3/webGLtemplate.js:
--------------------------------------------------------------------------------
1 | function main() {
2 | /*========== Create a WebGL Context ==========*/
3 |
4 |
5 | /*========== Define and Store the Geometry ==========*/
6 |
7 |
8 | /*========== Shaders ==========*/
9 |
10 |
11 | /*========== Connect the attribute with the vertex shader ===================*/
12 |
13 |
14 | /*========== Drawing ======================== */
15 |
16 |
17 |
18 | }
--------------------------------------------------------------------------------
/ch4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WebGL: Lesson 3 Rotating 3D
7 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ch4/lesson3-1.js:
--------------------------------------------------------------------------------
1 | main();
2 |
3 | function main() {
4 | /*========== Create a WebGL Context ==========*/
5 | const canvas = document.querySelector("#c");
6 | const gl = canvas.getContext('webgl');
7 | if (!gl) {
8 | console.log('WebGL unavailable');
9 | } else {
10 | console.log('WebGL is good to go');
11 | }
12 |
13 | /*========== Define and Store the Geometry ==========*/
14 | const squares = [
15 | // front face
16 | -0.3 , -0.3, -0.3,
17 | 0.3, -0.3, -0.3,
18 | 0.3, 0.3, -0.3,
19 |
20 | -0.3, -0.3, -0.3,
21 | -0.3, 0.3, -0.3,
22 | 0.3, 0.3, -0.3,
23 |
24 | // back face
25 | -0.2, -0.2, 0.3,
26 | 0.4, -0.2, 0.3,
27 | 0.4, 0.4, 0.3,
28 |
29 | -0.2, -0.2, 0.3,
30 | -0.2, 0.4, 0.3,
31 | 0.4, 0.4, 0.3,
32 |
33 | // top face
34 | -0.3, 0.3, -0.3,
35 | 0.3, 0.3, -0.3,
36 | -0.2, 0.4, 0.3,
37 |
38 | 0.4, 0.4, 0.3,
39 | 0.3, 0.3, -0.3,
40 | -0.2, 0.4, 0.3,
41 | ];
42 |
43 | // buffer
44 | const origBuffer = gl.createBuffer();
45 | gl.bindBuffer(gl.ARRAY_BUFFER, origBuffer);
46 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squares), gl.STATIC_DRAW);
47 |
48 | const squareColors = [
49 | 0.0, 0.0, 1.0, 1.0,
50 | 0.0, 0.0, 1.0, 1.0,
51 | 0.0, 0.0, 1.0, 1.0,
52 | 0.0, 0.0, 1.0, 1.0,
53 | 0.0, 0.0, 1.0, 1.0,
54 | 0.0, 0.0, 1.0, 1.0,
55 | 1.0, 0.0, 0.0, 1.0,
56 | 1.0, 0.0, 0.0, 1.0,
57 | 1.0, 0.0, 0.0, 1.0,
58 | 1.0, 0.0, 0.0, 1.0,
59 | 1.0, 0.0, 0.0, 1.0,
60 | 1.0, 0.0, 0.0, 1.0,
61 | 0.0, 1.0, 0.0, 1.0,
62 | 0.0, 1.0, 0.0, 1.0,
63 | 0.0, 1.0, 0.0, 1.0,
64 | 0.0, 1.0, 0.0, 1.0,
65 | 0.0, 1.0, 0.0, 1.0,
66 | 0.0, 1.0, 0.0, 1.0,
67 | ];
68 |
69 | const colorBuffer = gl.createBuffer();
70 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
71 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squareColors), gl.STATIC_DRAW);
72 |
73 | /*========== Shaders ==========*/
74 |
75 | const vsSource = `
76 | attribute vec4 aPosition;
77 | attribute vec4 aVertexColor;
78 |
79 | uniform mat4 uModelViewMatrix;
80 |
81 | varying lowp vec4 vColor;
82 |
83 | void main() {
84 | gl_Position = uModelViewMatrix * aPosition;
85 | vColor = aVertexColor;
86 | }
87 | `;
88 |
89 | const fsSource = `
90 | varying lowp vec4 vColor;
91 |
92 | void main() {
93 | gl_FragColor = vColor;
94 | }
95 | `;
96 |
97 | //create shaders
98 | const vertexShader = gl.createShader(gl.VERTEX_SHADER);
99 | const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
100 | gl.shaderSource(vertexShader, vsSource);
101 | gl.shaderSource(fragmentShader, fsSource);
102 |
103 | // compile shaders
104 | gl.compileShader(vertexShader);
105 | if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
106 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vertexShader));
107 | gl.deleteShader(vertexShader);
108 | return null;
109 | }
110 | gl.compileShader(fragmentShader);
111 | if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
112 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fragmentShader));
113 | gl.deleteShader(fragmentShader);
114 | return null;
115 | }
116 |
117 | // create program
118 | const program = gl.createProgram();
119 | gl.attachShader(program, vertexShader);
120 | gl.attachShader(program, fragmentShader);
121 |
122 | // link program
123 | gl.linkProgram(program);
124 | gl.useProgram(program);
125 |
126 | let cubeRotation = 0.0;
127 | let then = 0;
128 |
129 | /*========== Connect the attribute with the vertex shader ==========*/
130 | function render(now){
131 | now *= 0.001;
132 | const deltaTime = now - then;
133 | then = now;
134 |
135 | const posAttribLocation = gl.getAttribLocation(program, "aPosition");
136 | gl.bindBuffer(gl.ARRAY_BUFFER, origBuffer);
137 | gl.vertexAttribPointer(posAttribLocation, 3, gl.FLOAT, false, 0, 0);
138 | gl.enableVertexAttribArray(posAttribLocation);
139 |
140 | const colorAttribLocation = gl.getAttribLocation(program, "aVertexColor");
141 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
142 | gl.vertexAttribPointer(colorAttribLocation, 4, gl.FLOAT, false, 0, 0);
143 | gl.enableVertexAttribArray(colorAttribLocation);
144 |
145 | const modelMatrixLocation = gl.getUniformLocation(program, 'uModelViewMatrix');
146 |
147 | const modelViewMatrix = mat4.create();
148 |
149 | mat4.rotate(modelViewMatrix, // destination matrix
150 | modelViewMatrix, // matrix to rotate
151 | cubeRotation, // amount to rotate in radians
152 | [0, 0, 1]); // axis to rotate around (Z)
153 |
154 | gl.uniformMatrix4fv(modelMatrixLocation, false, modelViewMatrix);
155 |
156 | /*========== Drawing ========== */
157 | gl.clearColor(1, 1, 1, 1);
158 |
159 | gl.enable(gl.DEPTH_TEST);
160 | //gl.depthFunc(gl.LEQUAL);
161 |
162 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
163 |
164 | // Draw the points on the screen
165 | const mode = gl.TRIANGLES;
166 | const first = 0;
167 | const count = 18;
168 | gl.drawArrays(mode, first, count);
169 | cubeRotation += deltaTime;
170 | requestAnimationFrame(render);
171 | }
172 | requestAnimationFrame(render);
173 | }
174 |
--------------------------------------------------------------------------------
/ch4/lesson3-2.js:
--------------------------------------------------------------------------------
1 | main();
2 |
3 | function main() {
4 | /*========== Create a WebGL Context ==========*/
5 | const canvas = document.querySelector("#c");
6 | const gl = canvas.getContext('webgl');
7 | if (!gl) {
8 | console.log('WebGL unavailable');
9 | } else {
10 | console.log('WebGL is good to go');
11 | }
12 |
13 | /*========== Define and Store the Geometry ==========*/
14 | const squares = [
15 | // front face
16 | -0.3 , -0.3, -0.3,
17 | 0.3, -0.3, -0.3,
18 | 0.3, 0.3, -0.3,
19 |
20 | -0.3, -0.3, -0.3,
21 | -0.3, 0.3, -0.3,
22 | 0.3, 0.3, -0.3,
23 |
24 | // back face
25 | -0.2, -0.2, 0.3,
26 | 0.4, -0.2, 0.3,
27 | 0.4, 0.4, 0.3,
28 |
29 | -0.2, -0.2, 0.3,
30 | -0.2, 0.4, 0.3,
31 | 0.4, 0.4, 0.3,
32 |
33 | // top face
34 | -0.3, 0.3, -0.3,
35 | 0.3, 0.3, -0.3,
36 | -0.2, 0.4, 0.3,
37 |
38 | 0.4, 0.4, 0.3,
39 | 0.3, 0.3, -0.3,
40 | -0.2, 0.4, 0.3,
41 | ];
42 |
43 | // buffer
44 | const origBuffer = gl.createBuffer();
45 | gl.bindBuffer(gl.ARRAY_BUFFER, origBuffer);
46 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squares), gl.STATIC_DRAW);
47 |
48 | const squareColors = [
49 | 0.0, 0.0, 1.0, 1.0,
50 | 0.0, 0.0, 1.0, 1.0,
51 | 0.0, 0.0, 1.0, 1.0,
52 | 0.0, 0.0, 1.0, 1.0,
53 | 0.0, 0.0, 1.0, 1.0,
54 | 0.0, 0.0, 1.0, 1.0,
55 | 1.0, 0.0, 0.0, 1.0,
56 | 1.0, 0.0, 0.0, 1.0,
57 | 1.0, 0.0, 0.0, 1.0,
58 | 1.0, 0.0, 0.0, 1.0,
59 | 1.0, 0.0, 0.0, 1.0,
60 | 1.0, 0.0, 0.0, 1.0,
61 | 0.0, 1.0, 0.0, 1.0,
62 | 0.0, 1.0, 0.0, 1.0,
63 | 0.0, 1.0, 0.0, 1.0,
64 | 0.0, 1.0, 0.0, 1.0,
65 | 0.0, 1.0, 0.0, 1.0,
66 | 0.0, 1.0, 0.0, 1.0,
67 | ];
68 |
69 | const colorBuffer = gl.createBuffer();
70 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
71 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squareColors), gl.STATIC_DRAW);
72 |
73 | /*========== Shaders ==========*/
74 |
75 | const vsSource = `
76 | attribute vec4 aPosition;
77 | attribute vec4 aVertexColor;
78 |
79 | uniform mat4 uModelViewMatrix;
80 | uniform mat4 uProjectionMatrix;
81 |
82 | varying lowp vec4 vColor;
83 |
84 | void main() {
85 | gl_Position = uProjectionMatrix * uModelViewMatrix * aPosition;
86 | vColor = aVertexColor;
87 | }
88 | `;
89 |
90 | const fsSource = `
91 | varying lowp vec4 vColor;
92 |
93 | void main() {
94 | gl_FragColor = vColor;
95 | }
96 | `;
97 |
98 | //create shaders
99 | const vertexShader = gl.createShader(gl.VERTEX_SHADER);
100 | const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
101 | gl.shaderSource(vertexShader, vsSource);
102 | gl.shaderSource(fragmentShader, fsSource);
103 |
104 | // compile shaders
105 | gl.compileShader(vertexShader);
106 | if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
107 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(vertexShader));
108 | gl.deleteShader(vertexShader);
109 | return null;
110 | }
111 | gl.compileShader(fragmentShader);
112 | if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
113 | alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(fragmentShader));
114 | gl.deleteShader(fragmentShader);
115 | return null;
116 | }
117 |
118 | // create program
119 | const program = gl.createProgram();
120 | gl.attachShader(program, vertexShader);
121 | gl.attachShader(program, fragmentShader);
122 |
123 | // link program
124 | gl.linkProgram(program);
125 | gl.useProgram(program);
126 |
127 | let cubeRotation = 0.0;
128 | let then = 0;
129 |
130 | /*========== Connect the attribute with the vertex shader ==========*/
131 | function render(now){
132 | now *= 0.001;
133 | const deltaTime = now - then;
134 | then = now;
135 |
136 | const posAttribLocation = gl.getAttribLocation(program, "aPosition");
137 | gl.bindBuffer(gl.ARRAY_BUFFER, origBuffer);
138 | gl.vertexAttribPointer(posAttribLocation, 3, gl.FLOAT, false, 0, 0);
139 | gl.enableVertexAttribArray(posAttribLocation);
140 |
141 | const colorAttribLocation = gl.getAttribLocation(program, "aVertexColor");
142 | gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
143 | gl.vertexAttribPointer(colorAttribLocation, 4, gl.FLOAT, false, 0, 0);
144 | gl.enableVertexAttribArray(colorAttribLocation);
145 |
146 |
147 | const modelMatrixLocation = gl.getUniformLocation(program, 'uModelViewMatrix');
148 | const projMatrixLocation = gl.getUniformLocation(program, 'uProjectionMatrix');
149 |
150 | const fieldOfView = 45 * Math.PI / 180; // in radians
151 | const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
152 | const zNear = 0.1;
153 | const zFar = 100.0;
154 | const projectionMatrix = mat4.create();
155 |
156 | // note: glmatrix.js always has the first argument
157 | // as the destination to receive the result.
158 | mat4.perspective(projectionMatrix,
159 | fieldOfView,
160 | aspect,
161 | zNear,
162 | zFar);
163 |
164 | const modelViewMatrix = mat4.create();
165 |
166 | mat4.translate(modelViewMatrix, // destination matrix
167 | modelViewMatrix, // matrix to translate
168 | [-0.0, 0.0, -2.0]); // amount to translate
169 | mat4.rotate(modelViewMatrix, // destination matrix
170 | modelViewMatrix, // matrix to rotate
171 | cubeRotation, // amount to rotate in radians
172 | [0, 0, 1]); // axis to rotate around (Z)
173 | mat4.rotate(modelViewMatrix, // destination matrix
174 | modelViewMatrix, // matrix to rotate
175 | cubeRotation,// amount to rotate in radians
176 | [0, 1, 0]); // axis to rotate around (X)
177 |
178 | gl.uniformMatrix4fv(projMatrixLocation, false, projectionMatrix);
179 | gl.uniformMatrix4fv(modelMatrixLocation, false, modelViewMatrix);
180 |
181 | /*========== Drawing ========== */
182 | gl.clearColor(1, 1, 1, 1);
183 |
184 | gl.enable(gl.DEPTH_TEST);
185 | //gl.depthFunc(gl.LEQUAL);
186 |
187 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
188 |
189 | // Draw the points on the screen
190 | const mode = gl.TRIANGLES;
191 | const first = 0;
192 | const count = 18;
193 | gl.drawArrays(mode, first, count);
194 | cubeRotation += deltaTime;
195 | requestAnimationFrame(render);
196 | }
197 | requestAnimationFrame(render);
198 | }
199 |
--------------------------------------------------------------------------------
/ch5_ex4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 | WebXR Ch. 5 Ex. 4
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ch5_ex4/index_ex4_final.js:
--------------------------------------------------------------------------------
1 | import * as THREE from './modules/three.module.js';
2 |
3 | main();
4 |
5 | function main() {
6 | // create context
7 | const canvas = document.querySelector("#c");
8 | const gl = new THREE.WebGLRenderer({
9 | canvas,
10 | antialias: true
11 | });
12 |
13 | // create camera
14 | const angleOfView = 55;
15 | const aspectRatio = canvas.clientWidth / canvas.clientHeight;
16 | const nearPlane = 0.1;
17 | const farPlane = 100;
18 | const camera = new THREE.PerspectiveCamera(
19 | angleOfView,
20 | aspectRatio,
21 | nearPlane,
22 | farPlane
23 | );
24 | camera.position.set(0, 8, 30);
25 |
26 | // create the scene
27 | const scene = new THREE.Scene();
28 | scene.background = new THREE.Color(0.3, 0.5, 0.8);
29 | const fog = new THREE.Fog("grey", 1,90);
30 | scene.fog = fog;
31 |
32 | // GEOMETRY
33 | // create the cube
34 | const cubeSize = 4;
35 | const cubeGeometry = new THREE.BoxGeometry(
36 | cubeSize,
37 | cubeSize,
38 | cubeSize
39 | );
40 |
41 | // Create the Sphere
42 | const sphereRadius = 3;
43 | const sphereWidthSegments = 32;
44 | const sphereHeightSegments = 16;
45 | const sphereGeometry = new THREE.SphereGeometry(
46 | sphereRadius,
47 | sphereWidthSegments,
48 | sphereHeightSegments
49 | );
50 |
51 | // Create the upright plane
52 | const planeWidth = 256;
53 | const planeHeight = 128;
54 | const planeGeometry = new THREE.PlaneGeometry(
55 | planeWidth,
56 | planeHeight
57 | );
58 |
59 | // MATERIALS
60 | const textureLoader = new THREE.TextureLoader();
61 |
62 | const cubeMaterial = new THREE.MeshPhongMaterial({
63 | color: 'pink'
64 | });
65 |
66 | const sphereNormalMap = textureLoader.load('textures/sphere_normal.png');
67 | sphereNormalMap.wrapS = THREE.RepeatWrapping;
68 | sphereNormalMap.wrapT = THREE.RepeatWrapping;
69 | const sphereMaterial = new THREE.MeshStandardMaterial({
70 | color: 'tan',
71 | normalMap: sphereNormalMap
72 | });
73 |
74 |
75 | const planeTextureMap = textureLoader.load('textures/pebbles.jpg');
76 | planeTextureMap.wrapS = THREE.RepeatWrapping;
77 | planeTextureMap.wrapT = THREE.RepeatWrapping;
78 | planeTextureMap.repeat.set(16, 16);
79 | //planeTextureMap.magFilter = THREE.NearestFilter;
80 | planeTextureMap.minFilter = THREE.NearestFilter;
81 | planeTextureMap.anisotropy = gl.getMaxAnisotropy();
82 | const planeNorm = textureLoader.load('textures/pebbles_normal.png');
83 | planeNorm.wrapS = THREE.RepeatWrapping;
84 | planeNorm.wrapT = THREE.RepeatWrapping;
85 | planeNorm.minFilter = THREE.NearestFilter;
86 | planeNorm.repeat.set(16, 16);
87 | const planeMaterial = new THREE.MeshStandardMaterial({
88 | map: planeTextureMap,
89 | side: THREE.DoubleSide,
90 | normalMap: planeNorm
91 | });
92 |
93 | // MESHES
94 | const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
95 | cube.position.set(cubeSize + 1, cubeSize + 1, 0);
96 | scene.add(cube);
97 |
98 | const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
99 | sphere.position.set(-sphereRadius - 1, sphereRadius + 2, 0);
100 | scene.add(sphere);
101 |
102 | const plane = new THREE.Mesh(planeGeometry, planeMaterial);
103 | plane.rotation.x = Math.PI / 2;
104 | //scene.add(plane);
105 |
106 | //LIGHTS
107 | const color = 0xffffff;
108 | const intensity = .7;
109 | const light = new THREE.DirectionalLight(color, intensity);
110 | light.target = plane;
111 | light.position.set(0, 30, 30);
112 | scene.add(light);
113 | scene.add(light.target);
114 |
115 | const ambientColor = 0xffffff;
116 | const ambientIntensity = 0.2;
117 | const ambientLight = new THREE.AmbientLight(ambientColor, ambientIntensity);
118 | scene.add(ambientLight);
119 |
120 | // DRAW
121 | function draw(time){
122 | time *= 0.001;
123 |
124 | if (resizeGLToDisplaySize(gl)) {
125 | const canvas = gl.domElement;
126 | camera.aspect = canvas.clientWidth / canvas.clientHeight;
127 | camera.updateProjectionMatrix();
128 | }
129 |
130 | cube.rotation.x += 0.01;
131 | cube.rotation.y += 0.01;
132 | cube.rotation.z += 0.01;
133 |
134 | sphere.rotation.x += 0.01;
135 | sphere.rotation.y += 0.01;
136 | sphere.rotation.y += 0.01;
137 |
138 | light.position.x = 20*Math.cos(time);
139 | light.position.y = 20*Math.sin(time);
140 | gl.render(scene, camera);
141 | requestAnimationFrame(draw);
142 | }
143 |
144 | requestAnimationFrame(draw);
145 | }
146 |
147 | // UPDATE RESIZE
148 | function resizeGLToDisplaySize(gl) {
149 | const canvas = gl.domElement;
150 | const width = canvas.clientWidth;
151 | const height = canvas.clientHeight;
152 | const needResize = canvas.width != width || canvas.height != height;
153 | if (needResize) {
154 | gl.setSize(width, height, false);
155 | }
156 | return needResize;
157 | }
--------------------------------------------------------------------------------
/ch5_ex4/textures/pebbies_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch5_ex4/textures/pebbies_gray.png
--------------------------------------------------------------------------------
/ch5_ex4/textures/pebbles.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch5_ex4/textures/pebbles.jpg
--------------------------------------------------------------------------------
/ch5_ex4/textures/pebbles_height.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch5_ex4/textures/pebbles_height.png
--------------------------------------------------------------------------------
/ch5_ex4/textures/pebbles_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch5_ex4/textures/pebbles_normal.png
--------------------------------------------------------------------------------
/ch5_ex4/textures/sphere_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch5_ex4/textures/sphere_normal.png
--------------------------------------------------------------------------------
/ch6_ex5/VRButton.js:
--------------------------------------------------------------------------------
1 | var VRButton = {
2 | createButton: function(gl, options) {
3 | if (options && options.referenceSpaceType) {
4 | gl.xr.setReferenceSpaceType(options.referenceSpaceType);
5 | }
6 |
7 | function EnterVR() {
8 | // label button
9 | button.innerHTML = 'Enter XR';
10 | var currentSession = null;
11 | function onSessionStarted(session) {
12 | session.addEventListener('end', onSessionEnded);
13 |
14 | button.textContent = 'Exit XR';
15 | currentSession = session;
16 | setupWebGLLayer()
17 | .then(() => {
18 | gl.xr.setSession(currentSession);
19 | });
20 | }
21 |
22 | function onSessionEnded(/*event*/) {
23 | currentSession.removeEventListener('end', onSessionEnded);
24 | button.textContent = 'Enter XR';
25 | currentSession = null;
26 | }
27 |
28 | function setupWebGLLayer() {
29 | var glContext = gl.getContext();
30 | return glContext.makeXRCompatible().then(() => {
31 | currentSession.updateRenderState( {baseLayer: new XRWebGLLayer(currentSession, glContext) });
32 | });
33 | }
34 |
35 | button.onclick = () => {
36 | if (currentSession === null) {
37 | let sessionInit = {
38 | optionalFeatures: ["local-floor", "bounded-floor"]
39 | };
40 | navigator.xr
41 | .requestSession('immersive-vr', sessionInit)
42 | .then(onSessionStarted);
43 | }
44 | else {
45 | currentSession.end();
46 | }
47 | }
48 | }
49 |
50 | function NotFound() {
51 | console.log('immersive-vr mode not found');
52 | }
53 |
54 | if (navigator.xr) {
55 | var button = document.createElement("button");
56 | navigator.xr.isSessionSupported('immersive-vr')
57 | .then(function(supported) {
58 | if (supported) { EnterVR() }
59 | else { NotFound(); }
60 | })
61 | button.setAttribute("id", "btn");
62 | return button;
63 | } else {
64 | if (window.isSecureContext === false) {
65 | console.log('WebXR needs HTTPS');
66 | } else {
67 | console.log('WebXR not available');
68 | }
69 | return;
70 | }
71 | }
72 | }
73 |
74 | export {VRButton};
--------------------------------------------------------------------------------
/ch6_ex5/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 | WebXR Ch. 6 Ex. 5
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ch6_ex5/index_xr.js:
--------------------------------------------------------------------------------
1 | import * as THREE from '../ch5_ex4/modules/three.module.js';
2 | import {VRButton} from './VRButton.js';
3 |
4 | var gl, cube, sphere, light, camera, scene, canvas, glContext;
5 | init();
6 | animate();
7 |
8 | function init() {
9 | // create context
10 | gl = new THREE.WebGLRenderer({antialias: true});
11 | gl.setPixelRatio(window.devicePixelRatio);
12 | gl.setSize(window.innerWidth, window.innerHeight);
13 | gl.outputEncoding = THREE.sRGBEncoding;
14 | gl.xr.enabled = true;
15 | document.body.appendChild(gl.domElement);
16 | document.body.appendChild(VRButton.createButton(gl));
17 |
18 |
19 | // create camera
20 | const angleOfView = 55;
21 | const aspectRatio = window.innerWidth / window.innerHeight;
22 | const nearPlane = 0.1;
23 | const farPlane = 1000;
24 | camera = new THREE.PerspectiveCamera(
25 | angleOfView,
26 | aspectRatio,
27 | nearPlane,
28 | farPlane
29 | );
30 | camera.position.set(0, 8, 30);
31 |
32 | // create the scene
33 | scene = new THREE.Scene();
34 | scene.background = new THREE.Color(0.3, 0.5, 0.8);
35 | const fog = new THREE.Fog("grey", 1,90);
36 | scene.fog = fog;
37 |
38 | // GEOMETRY
39 | // create the cube
40 | const cubeSize = 4;
41 | const cubeGeometry = new THREE.BoxGeometry(
42 | cubeSize,
43 | cubeSize,
44 | cubeSize
45 | );
46 |
47 | // Create the Sphere
48 | const sphereRadius = 3;
49 | const sphereWidthSegments = 32;
50 | const sphereHeightSegments = 16;
51 | const sphereGeometry = new THREE.SphereGeometry(
52 | sphereRadius,
53 | sphereWidthSegments,
54 | sphereHeightSegments
55 | );
56 |
57 | // Create the upright plane
58 | const planeWidth = 256;
59 | const planeHeight = 128;
60 | const planeGeometry = new THREE.PlaneGeometry(
61 | planeWidth,
62 | planeHeight
63 | );
64 |
65 | // MATERIALS
66 | const textureLoader = new THREE.TextureLoader();
67 |
68 | const cubeMaterial = new THREE.MeshPhongMaterial({
69 | color: 'pink'
70 | });
71 |
72 | const sphereNormalMap = textureLoader.load('textures/sphere_normal.png');
73 | sphereNormalMap.wrapS = THREE.RepeatWrapping;
74 | sphereNormalMap.wrapT = THREE.RepeatWrapping;
75 | const sphereMaterial = new THREE.MeshStandardMaterial({
76 | color: 'tan',
77 | normalMap: sphereNormalMap
78 | });
79 |
80 |
81 | const planeTextureMap = textureLoader.load('textures/pebbles.png');
82 | planeTextureMap.wrapS = THREE.RepeatWrapping;
83 | planeTextureMap.wrapT = THREE.RepeatWrapping;
84 | planeTextureMap.repeat.set(16, 16);
85 | //planeTextureMap.magFilter = THREE.NearestFilter;
86 | planeTextureMap.minFilter = THREE.NearestFilter;
87 | planeTextureMap.anisotropy = gl.getMaxAnisotropy();
88 | const planeNorm = textureLoader.load('textures/pebbles_normal.png');
89 | planeNorm.wrapS = THREE.RepeatWrapping;
90 | planeNorm.wrapT = THREE.RepeatWrapping;
91 | planeNorm.minFilter = THREE.NearestFilter;
92 | planeNorm.repeat.set(16, 16);
93 | const planeMaterial = new THREE.MeshStandardMaterial({
94 | map: planeTextureMap,
95 | side: THREE.DoubleSide,
96 | normalMap: planeNorm
97 | });
98 |
99 | // MESHES
100 | cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
101 | cube.position.set(cubeSize + 1, cubeSize + 1, 0);
102 | scene.add(cube);
103 |
104 | sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
105 | sphere.position.set(-sphereRadius - 1, sphereRadius + 2, 0);
106 | scene.add(sphere);
107 |
108 | const plane = new THREE.Mesh(planeGeometry, planeMaterial);
109 | plane.rotation.x = Math.PI / 2;
110 | //scene.add(plane);
111 |
112 | //LIGHTS
113 | const color = 0xffffff;
114 | const intensity = .7;
115 | light = new THREE.DirectionalLight(color, intensity);
116 | light.target = plane;
117 | light.position.set(0, 30, 30);
118 | scene.add(light);
119 | scene.add(light.target);
120 |
121 | const ambientColor = 0xffffff;
122 | const ambientIntensity = 0.2;
123 | const ambientLight = new THREE.AmbientLight(ambientColor, ambientIntensity);
124 | scene.add(ambientLight);
125 |
126 | }
127 |
128 | function animate() {
129 | // replaces requestAnimationFrame()
130 | gl.setAnimationLoop(draw);
131 | }
132 |
133 | // Renamed from render(time)
134 | function draw(time) {
135 | time *= 0.001;
136 |
137 | if (resizeDisplay) {
138 | camera.aspect = window.innerWidth / window.innerHeight;
139 | camera.updateProjectionMatrix();
140 | }
141 |
142 | cube.rotation.x += 0.01;
143 | cube.rotation.y += 0.01;
144 | cube.rotation.z += 0.01;
145 |
146 | sphere.rotation.x += 0.01;
147 | sphere.rotation.y += 0.01;
148 | sphere.rotation.y += 0.01;
149 |
150 | light.position.x = 20*Math.cos(time);
151 | light.position.y = 20*Math.sin(time);
152 | gl.render(scene, camera);
153 | }
154 |
155 |
156 | // UPDATE RESIZE
157 | function resizeDisplay() {
158 | const canvas = gl.domElement;
159 | const width = canvas.clientWidth;
160 | const height = canvas.clientHeight;
161 | const needResize = canvas.width != width || canvas.height != height;
162 | if (needResize) {
163 | gl.setSize(width, height, false);
164 | }
165 | return needResize;
166 | }
--------------------------------------------------------------------------------
/ch6_ex5/textures/pebbles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch6_ex5/textures/pebbles.png
--------------------------------------------------------------------------------
/ch6_ex5/textures/pebbles_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch6_ex5/textures/pebbles_normal.png
--------------------------------------------------------------------------------
/ch6_ex5/textures/sphere_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch6_ex5/textures/sphere_normal.png
--------------------------------------------------------------------------------
/ch7_ex6/Part1_Floating-Cube/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WebXR API: Ch.7 Ex.6 Pt.1
7 |
8 |
9 |
10 | Immersive AR with Three.js
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ch7_ex6/Part1_Floating-Cube/index.js:
--------------------------------------------------------------------------------
1 | import * as THREE from "three/build/three.module";
2 | // global scene values
3 | var btn, gl, glCanvas, camera, scene, renderer, cube;
4 |
5 | // global xr value
6 | var xrSession = null;
7 |
8 | loadScene();
9 | init();
10 |
11 | function loadScene() {
12 | // setup WebGL
13 | glCanvas = document.createElement('canvas');
14 | gl = glCanvas.getContext('webgl', { antialias: true });
15 |
16 | // setup Three.js scene
17 | camera = new THREE.PerspectiveCamera(
18 | 70,
19 | window.innerWidth / window.innerHeight,
20 | 0.01,
21 | 1000
22 | );
23 |
24 | scene = new THREE.Scene();
25 |
26 | var light = new THREE.HemisphereLight( 0xffffff, 0xbbbbff, 1 );
27 | light.position.set( 0.5, 1, 0.25 );
28 | scene.add( light );
29 |
30 | var geometry = new THREE.BoxBufferGeometry(0.2, 0.2, 0.2);
31 | var material = new THREE.MeshPhongMaterial({color: 0x89CFF0});
32 | cube = new THREE.Mesh( geometry, material );
33 | cube.position.y = 0.2;
34 | scene.add( cube );
35 |
36 | // setup Three.js WebGL renderer
37 | renderer = new THREE.WebGLRenderer({
38 | canvas: glCanvas,
39 | context: gl
40 | });
41 | renderer.setPixelRatio( window.devicePixelRatio );
42 | renderer.setSize( window.innerWidth, window.innerHeight );
43 | renderer.xr.enabled = true;
44 | document.body.appendChild( renderer.domElement );
45 | }
46 |
47 | function init() {
48 | navigator.xr.isSessionSupported('immersive-ar')
49 | .then((supported) => {
50 | if (supported) {
51 | btn = document.createElement("button");
52 | btn.addEventListener('click', onRequestSession);
53 | btn.innerHTML = "Enter XR";
54 | var header = document.querySelector("header");
55 | header.appendChild(btn);
56 | }
57 | else {
58 | navigator.xr.isSessionSupported('inline')
59 | .then((supported) => {
60 | if (supported) {
61 | console.log('inline session supported')
62 | }
63 | else {console.log('inline not supported')};
64 | })
65 | }
66 | })
67 | .catch((reason) => {
68 | console.log('WebXR not supported: ' + reason);
69 | });
70 | }
71 |
72 | function onRequestSession() {
73 | console.log("requesting session");
74 | navigator.xr.requestSession('immersive-ar', {requiredFeatures: ['viewer', 'local']})
75 | .then(onSessionStarted)
76 | .catch((reason) => {
77 | console.log('request disabled: ' + reason);
78 | });
79 | }
80 |
81 | function onSessionStarted(session) {
82 | console.log('starting session');
83 | btn.removeEventListener('click', onRequestSession);
84 | btn.addEventListener('click', endXRSession);
85 | btn.innerHTML = "STOP AR";
86 | xrSession = session;
87 | xrSession.addEventListener("end", onSessionEnd);
88 | setupWebGLLayer()
89 | .then(()=> {
90 | renderer.xr.setReferenceSpaceType('local');
91 | renderer.xr.setSession(xrSession);
92 | animate();
93 | })
94 | }
95 |
96 | function setupWebGLLayer() {
97 | return gl.makeXRCompatible().then(() => {
98 | xrSession.updateRenderState( {baseLayer: new XRWebGLLayer(xrSession, gl) });
99 | });
100 | }
101 |
102 | function animate() {
103 | renderer.setAnimationLoop(render);
104 | }
105 |
106 | function render(time) {
107 | if (!xrSession) {
108 | renderer.clear(true, true, true);
109 | return;
110 | } else {
111 | time *= 0.001;
112 | cube.translateY(0.2 * Math.sin(time) / 100);
113 | cube.rotateY(Math.PI / 180);
114 | renderer.render(scene, camera);
115 | //renderer.render(scene, camera);
116 | }
117 | }
118 |
119 | function endXRSession() {
120 | if (xrSession) {
121 | console.log('ending session...');
122 | xrSession.end().then(onSessionEnd);
123 | }
124 | }
125 |
126 | function onSessionEnd() {
127 | xrSession = null;
128 | console.log('session ended');
129 | btn.innerHTML = "START AR";
130 | btn.removeEventListener('click', endXRSession);
131 | btn.addEventListener('click', onRequestSession);
132 | }
--------------------------------------------------------------------------------
/ch7_ex6/Part2_Hit-Test/hit_test.js:
--------------------------------------------------------------------------------
1 | import * as THREE from "three/build/three.module";
2 | // global scene values
3 | var btn, gl, glCanvas, camera, scene, renderer;
4 | var controller, reticle;
5 |
6 | // global xr value
7 | var xrSession = null;
8 | var xrViewerPose;
9 | var hitTestSource = null;
10 | var hitTestSourceRequested = false;
11 |
12 | loadScene();
13 |
14 | function loadScene() {
15 | // setup WebGL
16 | glCanvas = document.createElement('canvas');
17 | gl = glCanvas.getContext('webgl', { antialias: true });
18 |
19 | // setup Three.js scene
20 | camera = new THREE.PerspectiveCamera(
21 | 70,
22 | window.innerWidth / window.innerHeight,
23 | 0.01,
24 | 1000
25 | );
26 |
27 | scene = new THREE.Scene();
28 | // add hemisphere light
29 | var light = new THREE.HemisphereLight( 0xffffff, 0xbbbbff, 1 );
30 | light.position.set( 0.5, 1, 0.25 );
31 | scene.add( light );
32 |
33 |
34 | // setup Three.js WebGL renderer
35 | renderer = new THREE.WebGLRenderer({
36 | canvas: glCanvas,
37 | context: gl
38 | });
39 | renderer.setPixelRatio( window.devicePixelRatio );
40 | renderer.setSize( window.innerWidth, window.innerHeight );
41 | renderer.xr.enabled = true;
42 | document.body.appendChild( renderer.domElement );
43 |
44 | var geometry = new THREE.CylinderBufferGeometry(0.1, 0.1, 0.2, 32).translate(0, 0.1, 0);
45 |
46 | // controller click event listener
47 | function onSelect() {
48 | console.log("on select fired...");
49 | var material = new THREE.MeshPhongMaterial( { color: 0xffffff * Math.random() } );
50 | var mesh = new THREE.Mesh(geometry, material);
51 | mesh.applyMatrix4(reticle.matrix); // THIS IS A KEY FUNCTION
52 | mesh.scale.y = Math.random() * 2 + 1; // double value of random number then add 1 for height, why?
53 | scene.add(mesh);
54 | }
55 |
56 | // get controller WebXR Device API through Three.js
57 | controller = renderer.xr.getController(0);
58 | controller.addEventListener('select', onSelect);
59 | scene.add(controller);
60 |
61 | // reticle and reticle properties
62 | reticle = new THREE.Mesh(
63 | new THREE.RingBufferGeometry(0.15, 0.2, 32).rotateX(-Math.PI / 2),
64 | new THREE.MeshBasicMaterial({color: "#00FF00"})
65 | );
66 |
67 | reticle.matrixAutoUpdate = false;
68 | reticle.visible = false;
69 | scene.add(reticle);
70 |
71 | // begin xr query
72 | navigator.xr.isSessionSupported('immersive-ar')
73 | .then((supported) => {
74 | if (supported) {
75 | btn = document.createElement("button");
76 | btn.addEventListener('click', onRequestSession);
77 | btn.innerHTML = "Enter XR";
78 | var header = document.querySelector("header");
79 | header.appendChild(btn);
80 | }
81 | else {
82 | navigator.xr.isSessionSupported('inline')
83 | .then((supported) => {
84 | if (supported) {
85 | console.log('inline session supported')
86 | }
87 | else {console.log('inline not supported')};
88 | })
89 | }
90 | })
91 | .catch((reason) => {
92 | console.log('WebXR not supported: ' + reason);
93 | });
94 | }
95 |
96 | // request immersive-ar session with hit-test
97 | function onRequestSession() {
98 | console.log("requesting session");
99 | navigator.xr.requestSession('immersive-ar', {requiredFeatures: ['hit-test'], optionalFeatures: ['local-floor']})
100 | .then(onSessionStarted)
101 | .catch((reason) => {
102 | console.log('request disabled: ' + reason);
103 | });
104 | }
105 |
106 | function onSessionStarted(session) {
107 | console.log('starting session');
108 | btn.removeEventListener('click', onRequestSession);
109 | btn.addEventListener('click', endXRSession);
110 | btn.innerHTML = "STOP AR";
111 | xrSession = session;
112 | xrSession.addEventListener("end", endXRSession);
113 | setupWebGLLayer()
114 | .then(()=> {
115 | renderer.xr.setReferenceSpaceType('local');
116 | renderer.xr.setSession(xrSession);
117 | animate();
118 | })
119 | }
120 |
121 | function setupWebGLLayer() {
122 | return gl.makeXRCompatible().then(() => {
123 | xrSession.updateRenderState( {baseLayer: new XRWebGLLayer(xrSession, gl) });
124 | });
125 | }
126 |
127 | function animate() {
128 | renderer.setAnimationLoop(render);
129 | }
130 |
131 | function render(time, frame) {
132 | if (frame) {
133 | var referenceSpace = renderer.xr.getReferenceSpace('local');
134 | var session = frame.session;
135 | xrViewerPose = frame.getViewerPose(referenceSpace);
136 | if (hitTestSourceRequested === false) {
137 | session.requestReferenceSpace("viewer").then((referenceSpace) => {
138 | session.requestHitTestSource({space: referenceSpace})
139 | .then((source) => {
140 | hitTestSource = source;
141 | })
142 | });
143 |
144 | session.addEventListener("end", () => {
145 | hitTestSourceRequested = false;
146 | hitTestSource = null;
147 | });
148 | }
149 |
150 | if (hitTestSource) {
151 | var hitTestResults = frame.getHitTestResults(hitTestSource);
152 |
153 | if (hitTestResults.length > 0) {
154 | var hit = hitTestResults[0];
155 | reticle.visible = true;
156 | reticle.matrix.fromArray(hit.getPose(referenceSpace).transform.matrix);
157 | } else {
158 | reticle.visible = false;
159 | }
160 | }
161 | }
162 |
163 | renderer.render(scene, camera);
164 | }
165 |
166 | function endXRSession() {
167 | if (xrSession) {
168 | xrSession.end()
169 | .then(()=> {
170 | xrSession.ended = true;
171 | onSessionEnd();
172 | })
173 | .catch((reason) => {
174 | console.log('session not ended because ' + reason);
175 | onSessionEnd();
176 | })
177 | }
178 | else {onSessionEnd();}
179 | }
180 |
181 | function onSessionEnd() {
182 | xrSession = null;
183 | console.log('session ended');
184 | btn.innerHTML = "START AR";
185 | btn.removeEventListener('click', endXRSession);
186 | btn.addEventListener('click', onRequestSession);
187 | window.requestAnimationFrame(render);
188 | }
--------------------------------------------------------------------------------
/ch7_ex6/Part2_Hit-Test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WebXR API: Ch. 7 Ex. 6 Pt. 2
7 |
10 |
11 |
12 |
13 | WebXR Hit-Testing w/ Spatial Anchors
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ch8_Ex7_Parts_1_2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WebXR API / A-Frame: Ch.8 Ex.7 Pts.1 & 2
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
35 |
--------------------------------------------------------------------------------
/ch8_Ex7_Parts_1_2/textures/brick_mat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch8_Ex7_Parts_1_2/textures/brick_mat.jpg
--------------------------------------------------------------------------------
/ch8_Ex7_Parts_1_2/textures/grass-nm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch8_Ex7_Parts_1_2/textures/grass-nm.jpg
--------------------------------------------------------------------------------
/ch8_Ex7_Parts_1_2/textures/grass.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch8_Ex7_Parts_1_2/textures/grass.jpg
--------------------------------------------------------------------------------
/ch8_Ex7_Parts_3_4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WebXR API / A-Frame: Ch.8 Ex.7 Pts. 3 & 4
7 |
8 |
9 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
64 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/ch8_Ex7_Parts_3_4/textures/brick_mat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch8_Ex7_Parts_3_4/textures/brick_mat.jpg
--------------------------------------------------------------------------------
/ch8_Ex7_Parts_3_4/textures/grass-nm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch8_Ex7_Parts_3_4/textures/grass-nm.jpg
--------------------------------------------------------------------------------
/ch8_Ex7_Parts_3_4/textures/grass.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apress/ar-vr-using-webxr-api/e7b459196948a4729e8b1af48faffd3477ab7292/ch8_Ex7_Parts_3_4/textures/grass.jpg
--------------------------------------------------------------------------------
/ch9_ex8/assets/oculus-touch-controller-left.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'oculus-touch-controller-left.blend'
2 | # Material Count: 7
3 |
4 | newmtl body
5 | Ns 96.078431
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.640000 0.640000 0.640000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.000000
11 | d 1.000000
12 | illum 2
13 | map_Kd external_controller01_col.png
14 |
15 | newmtl buttonHand
16 | Ns 96.078431
17 | Ka 1.000000 1.000000 1.000000
18 | Kd 0.640000 0.640000 0.640000
19 | Ks 0.500000 0.500000 0.500000
20 | Ke 0.000000 0.000000 0.000000
21 | Ni 1.000000
22 | d 1.000000
23 | illum 2
24 | map_Kd external_controller01_col.png
25 |
26 | newmtl buttonMenu
27 | Ns 96.078431
28 | Ka 1.000000 1.000000 1.000000
29 | Kd 0.640000 0.640000 0.640000
30 | Ks 0.500000 0.500000 0.500000
31 | Ke 0.000000 0.000000 0.000000
32 | Ni 1.000000
33 | d 1.000000
34 | illum 2
35 | map_Kd external_controller01_col.png
36 |
37 | newmtl buttonTrigger
38 | Ns 96.078431
39 | Ka 1.000000 1.000000 1.000000
40 | Kd 0.640000 0.640000 0.640000
41 | Ks 0.500000 0.500000 0.500000
42 | Ke 0.000000 0.000000 0.000000
43 | Ni 1.000000
44 | d 1.000000
45 | illum 2
46 | map_Kd external_controller01_col.png
47 |
48 | newmtl buttonX
49 | Ns 96.078431
50 | Ka 1.000000 1.000000 1.000000
51 | Kd 0.640000 0.640000 0.640000
52 | Ks 0.500000 0.500000 0.500000
53 | Ke 0.000000 0.000000 0.000000
54 | Ni 1.000000
55 | d 1.000000
56 | illum 2
57 | map_Kd external_controller01_col.png
58 |
59 | newmtl buttonY
60 | Ns 96.078431
61 | Ka 1.000000 1.000000 1.000000
62 | Kd 0.640000 0.640000 0.640000
63 | Ks 0.500000 0.500000 0.500000
64 | Ke 0.000000 0.000000 0.000000
65 | Ni 1.000000
66 | d 1.000000
67 | illum 2
68 | map_Kd external_controller01_col.png
69 |
70 | newmtl stick
71 | Ns 96.078431
72 | Ka 1.000000 1.000000 1.000000
73 | Kd 0.640000 0.640000 0.640000
74 | Ks 0.500000 0.500000 0.500000
75 | Ke 0.000000 0.000000 0.000000
76 | Ni 1.000000
77 | d 1.000000
78 | illum 2
79 | map_Kd external_controller01_col.png
80 |
--------------------------------------------------------------------------------
/ch9_ex8/assets/oculus-touch-controller-right.mtl:
--------------------------------------------------------------------------------
1 | # Blender MTL File: 'oculus-touch-controller.right.blend'
2 | # Material Count: 7
3 |
4 | newmtl body
5 | Ns 96.078431
6 | Ka 1.000000 1.000000 1.000000
7 | Kd 0.640000 0.640000 0.640000
8 | Ks 0.500000 0.500000 0.500000
9 | Ke 0.000000 0.000000 0.000000
10 | Ni 1.000000
11 | d 1.000000
12 | illum 2
13 | map_Kd external_controller01_col.png
14 |
15 | newmtl buttonA
16 | Ns 96.078431
17 | Ka 1.000000 1.000000 1.000000
18 | Kd 0.640000 0.640000 0.640000
19 | Ks 0.500000 0.500000 0.500000
20 | Ke 0.000000 0.000000 0.000000
21 | Ni 1.000000
22 | d 1.000000
23 | illum 2
24 | map_Kd external_controller01_col.png
25 |
26 | newmtl buttonB
27 | Ns 96.078431
28 | Ka 1.000000 1.000000 1.000000
29 | Kd 0.640000 0.640000 0.640000
30 | Ks 0.500000 0.500000 0.500000
31 | Ke 0.000000 0.000000 0.000000
32 | Ni 1.000000
33 | d 1.000000
34 | illum 2
35 | map_Kd external_controller01_col.png
36 |
37 | newmtl buttonHand
38 | Ns 96.078431
39 | Ka 1.000000 1.000000 1.000000
40 | Kd 0.640000 0.640000 0.640000
41 | Ks 0.500000 0.500000 0.500000
42 | Ke 0.000000 0.000000 0.000000
43 | Ni 1.000000
44 | d 1.000000
45 | illum 2
46 | map_Kd external_controller01_col.png
47 |
48 |
49 | newmtl buttonHome
50 | Ns 96.078431
51 | Ka 1.000000 1.000000 1.000000
52 | Kd 0.640000 0.640000 0.640000
53 | Ks 0.500000 0.500000 0.500000
54 | Ke 0.000000 0.000000 0.000000
55 | Ni 1.000000
56 | d 1.000000
57 | illum 2
58 | map_Kd external_controller01_col.png
59 |
60 | newmtl buttonTrigger
61 | Ns 96.078431
62 | Ka 1.000000 1.000000 1.000000
63 | Kd 0.640000 0.640000 0.640000
64 | Ks 0.500000 0.500000 0.500000
65 | Ke 0.000000 0.000000 0.000000
66 | Ni 1.000000
67 | d 1.000000
68 | illum 2
69 | map_Kd external_controller01_col.png
70 |
71 | newmtl stick
72 | Ns 96.078431
73 | Ka 1.000000 1.000000 1.000000
74 | Kd 0.640000 0.640000 0.640000
75 | Ks 0.500000 0.500000 0.500000
76 | Ke 0.000000 0.000000 0.000000
77 | Ni 1.000000
78 | d 1.000000
79 | illum 2
80 | map_Kd external_controller01_col.png
81 |
--------------------------------------------------------------------------------
/ch9_ex8/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | A-Frame: Physics, Ex. 8 -- Part 1
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
26 |
27 |
29 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
39 |
42 |
43 |
44 |
47 |
48 |
49 |
50 |
52 |
53 |
54 |
58 |
59 |
60 |
61 |