-
Notifications
You must be signed in to change notification settings - Fork 0
/
report.html
210 lines (189 loc) · 11.9 KB
/
report.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
<html>
<head>
<title>Voxels Project</title>
<meta name="description" content="HTML5">
<meta charset="UTF-8">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
<link rel="shortcut icon" href="favicon.png" type="image/x-icon">
<link rel="icon" href="favicon.png" type="image/x-icon">
</head>
<body>
<div class="container">
<div class="row" style="align-items: center;">
<h1 class="display-3">Voxels Project</h1>
<nav aria-label="Page navigation" style="margin-left: 20px">
<ul class="pagination" style="margin-bottom: 0">
<li class="page-item"><a class="page-link" href="../index.html">Home</a></li>
<li class="page-item"><a class="page-link" href="index.html">
Project
</a></li>
</ul>
</nav>
</div>
<h2 class="display-4">Report</h2>
<div class="row">
<div class="col-lg">
<div class="figure-container">
<div class="col-sm figure">
<img style="height: 300px;" src="images/apple.JPG"/>
</div>
<div class="col-sm figure">
<img style="height: 300px;" src="images/chicken.JPG"/>
</div>
<div class="col-sm figure">
<img style="height: 300px;" src="images/person.JPG"/>
</div>
</div>
<h3>Introduction</h3>
<div>
The aim of the project is developing an in-browser voxels editor with which the user will be able to draw 3d picture with cubes.<br/>
We tried to merge what we learnt from the course to create a more realistic 3d art figure with realistic lighting, a moving camera, and shadows.
</div>
<div class="figure-container">
<div class="col-sm figure">
<img style="height: 250px;" src="images/inspiration.JPG"/>
<div>Inspiration: <a href="https://particubes.com/">Particubes</a> (ios app)</div>
</div>
<div class="col-sm figure">
<img style="height: 250px;" src="images/inspiration2.png"/>
<div>Example of a voxel art piecen, by <a href="https://dribbble.com/shots/5486289-Voxel-Environment">Musho</a></div>
</div>
</div>
<h3>Voxel editor tutorial</h3>
<div>
The voxel editor is controlled by mouse actions on the canvas:
<ul>
<li>Left click on a cube:
<ul>
<li>When in “Drawing” mode
<ul>
<li>In "Add cube" mode: a new cube will be added</li>
<li>In "Delete cube" mode: the cube will be removed</li>
</ul>
</li>
<li>When in “Color picker” mode: the color of the cube is set as drawing color</li>
</ul>
</li>
<li>Left click and drag on canvas: the camera will rotate around the center of the scene</li>
<li>Right click and drag on canvas: the camera will truck/pedestal. It translates the camera and the point it’s looking at.</li>
<li>Mouse wheel on canvas: the camera will zoom in/out.</li>
</ul>
The color pickers control the drawing color. First choose a color in the circle, then refine it in the triangle picker.
There are some models to start with, they can be selected by clicking the buttons in the “Demos” menu.
</div>
<h3>Cube models</h3>
<div>
The starting point is drawing the first cube, which is hard coded in a center position of the scene. Every cube will be added attached to a previously created one.<br/>
We defined cube as a javascript object with the attributes: vertices (an array of vec3) and a color (vec4). All the cubes in the scene are stored in a list “allCubes”.<br/>
The cubes can be added or removed from the canvas clicking on one face of a cube.
In order to add a new cube we push the new cube object to the list, the new vertices will be calculate from the position of the cube and relative faced selected adding 1 to his coordinates.<br/>
We can only display triangles, so we need to generate the vertices of 2 triangles for each face of the cube. Then we bind the vertices to the buffer and draw the scene.<br/>
See function <code>createNewCube</code> from line 5 until 54 of <code>cubeMethods.js</code>, and <code>initCubeBuffers</code> from line 63 until 105.
</div>
<h3>Navigating the scene</h3>
<div>
For our voxel editor to be easy to use, we needed to implement an intuitive way to move the camera around in the scene. We decided to allow the user to move the camera in 3 ways:
<ul>
<li>rotate around a fixed point</li>
<li>dolly (translate the camera along the direction of view)</li>
<li>truck and pedestal (translate the camera in the plane normal to the direction of view)</li>
</ul>
The rotation and dolly are implemented as a movement in spherical coordinates (r, theta, phi). We set the “at” vector to be the center of the scene, then place the “eye” according to the rotation and dolly parameters.
To truck/pedestal the camera we translate both the “at” and “eye” vector, in directions perpendicular to the view direction. (see function <code>moveCamera</code> lines 166-191 of <code>scene.js</code>)
</div>
<h3>Color Picker</h3>
<div>
To select the color of the cube we create two shapes, a circle and a triangle. Applying the knowledge of fragment shaders, we chose values for each vertex forming the circle using the color scheme that we found <a href="https://www.w3schools.com/colors/colors_picker.asp">here</a>.<br/>
On the other hand the triangle values changes when you select a point on the circle displaying different shades of the selected color.<br/>
Two of the values of the triangle picker don’t change: black and white. The third value is the one selected on the circle and it defines which shade should be implemented, see line 101 of <code>colorPicker.js</code>.
</div>
<h3>Look up map: know on which cube the mouse is</h3>
<div>
To enable the user to interact with the scene and the cubes in it, our program needs to know at what cube and what face the mouse is pointing.
To know that, we use a method similar to what is done in <cite>Chapter 10 of WebGL Programming Guide</cite>. We encode the cube and face indices in the red and green channels of a texture,
and when we need to know what face is pointed at, we read the color values of the texture.
We use a framebuffer object to draw in a texture, instead of drawing the look up map directly on the color buffer,
so that we can store this information and draw it again only if the scene changes (a cube is added/removed, or the camera moves).
For example when the user hovers the mouse on the canvas, we can read the values in the look-up texture map without re-rendering it each time.<br/>
See function <code>getCubeFace</code>, lines 13-34 of <code>interactions.js</code>
</div>
<div>
This method will work up to 256 cubes. If we want to draw more cubes we can use the blue and alpha channels too.
</div>
<div class="figure-container">
<div class="col-sm figure">
<img style="height: 200px;" src="images/lookupmap.jpg"/>
<div>The look-up map: the red channel codes the index of the cube, the green channel codes the index of the face</div>
</div>
<div class="col-sm figure">
<img style="height: 200px;" src="images/hovermouse.JPG"/>
<div>With this method we can know where the user wants to add a cube</div>
</div>
</div>
<h3>Flat and Phong shading</h3>
<div>
<div>
First we implemented flat shading, by giving the same normal vector for all vertices of a same face.
The results looks nice in the “vortex art” style, and shadows also help add realism (see Fig.1).
</div>
<div>
Then we added Phong shading by setting different normal vectors to the vertices, and interpolating normals for each fragment in the fragment shader.<br/>
To do this, we needed a way to approximate the normal for each vertex of the model, with the goal of making the edges look more smooth.<br/>
First we approximated the normal for each vertex as the normalized vector from a fixed point (like (0, 0, 0) for example) to the vertex.
This technique is not so realistic, as the fixed point can be any random point for the model (see Fig.3). Then instead of using a random fixed point, we use the center of the model.
This adds one loop through all the cubes in the js code, as we need to compute this center (mean of centers of all the cubes) but the result is better (see Fig.4). (see lines 69-76 of <code>cubeMethods.js</code>)
<br/><br/>
We implemented Phong lighting model with customizable parameters, so that the artist can change the appearance of the cubes material.<br/>
There is a demo mode on the project web page that will set parameters to show nice highlights, and can be tested on different models. (Click “Phong Demo” button).
<br/><br/>
Note: the yellow wireframe cube represents the position of the point light.
</div>
<div class="figure-container">
<div class="col-sm figure">
<img style="height: 200px;" src="images/flatshading.JPG"/>
<div>Fig.1: Flat shading with shadows</div>
</div>
<div class="col-sm figure">
<img style="height: 200px;" src="images/flatshadingphong.JPG"/>
<div>Fig.2: Flat shading with Phong lighting model, simulating shiny surface</div>
</div>
<div class="col-sm figure">
<img style="height: 200px;" src="images/phongshadingcenter1.JPG"/>
<div>Fig.3: Phong shading with first normals model</div>
</div>
<div class="col-sm figure">
<img style="height: 200px;" src="images/phongshadingcenter2.JPG"/>
<div>Fig.4: Phong shading with second normals model</div>
</div>
</div>
As we are dealing with cubes, flat shading gives a realistic result, while phong shading gives a smoother, less blocky result and gives the illusion of curves on our cubic models.
</div>
<h3>Shadows</h3>
<div>
To have shadows on our models we needed to implement shadow mapping. We used the same method as the one described in <cite>Display Shadows</cite> section of
<cite>WebGL Programming Guide</cite>.
There were some issues when the light gets too far from the cubes, so we had to implement the more precise method described in <cite>WebGL Programming Guide</cite>,
using all R, G, B and A dimensions of the texture map to store the distance from light to object.
</div>
<h3>Conclusion</h3>
<div>
With the concepts learnt during this class, we were able to build this voxel editor with functionalities that can help artists create cool voxel models with different styles of lightings.
</div>
</div>
</div>
<div class="row" style="margin-top:20px;">
<div class="col-lg">
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<li class="page-item"><a class="page-link" href="../index.html">Home</a></li>
<li class="page-item"><a class="page-link" href="index.html">
Project
</a></li>
</ul>
</nav>
</div>
</div>
</div>
</body>
</html>