Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
0
00:00:00,030 --> 00:00:06,000
hello and welcome to part one of a new
1
00:00:02,639 --> 00:00:09,300
series programming 3d graphics from
2
00:00:06,000 --> 00:00:11,250
scratch in this series we're going to
3
00:00:09,300 --> 00:00:12,150
start from nothing and develop quite a
4
00:00:11,250 --> 00:00:16,680
feature-rich
5
00:00:12,150 --> 00:00:19,590
software rasterizer which will allow us
6
00:00:16,680 --> 00:00:21,949
to explore 3d graphics in an interesting
7
00:00:19,590 --> 00:00:21,949
way
8
00:00:22,640 --> 00:00:27,930
the example I'm showing on the screen
9
00:00:25,019 --> 00:00:31,109
shows the one lone coda phrase rendered
10
00:00:27,930 --> 00:00:33,239
using a full 3d rastering pipeline and
11
00:00:31,109 --> 00:00:36,570
you can see it is even shaded and lit
12
00:00:33,239 --> 00:00:39,270
accordingly I've implemented a
13
00:00:36,570 --> 00:00:41,840
first-person shooter style camera and we
14
00:00:39,270 --> 00:00:44,700
can elevate the camera up and down too
15
00:00:41,840 --> 00:00:47,219
now we won't get quite that far in this
16
00:00:44,700 --> 00:00:48,989
episode this is just episode 1 we're
17
00:00:47,219 --> 00:00:51,360
really going to look at the fundamentals
18
00:00:48,989 --> 00:00:53,430
that are required as part of a 3d engine
19
00:00:51,360 --> 00:00:55,110
but that's the series progresses I'm
20
00:00:53,430 --> 00:00:57,360
going to add more and more features to
21
00:00:55,110 --> 00:01:00,000
turn this into quite a sophisticated 3d
22
00:00:57,360 --> 00:01:02,550
engine now when you hear 3d engine you
23
00:01:00,000 --> 00:01:04,920
might think of the terms OpenGL DirectX
24
00:01:02,550 --> 00:01:08,460
or Vulcan these days we won't be looking
25
00:01:04,920 --> 00:01:10,799
at those exactly instead what I'd like
26
00:01:08,460 --> 00:01:13,860
to present is the theory and the
27
00:01:10,799 --> 00:01:16,500
mathematics and the ideas that go behind
28
00:01:13,860 --> 00:01:18,659
the graphic API so that we know and love
29
00:01:16,500 --> 00:01:21,780
and what I hope to show by the end of
30
00:01:18,659 --> 00:01:23,670
the series is just how complicated it is
31
00:01:21,780 --> 00:01:25,920
to make your favorite games look very
32
00:01:23,670 --> 00:01:28,049
pretty indeed and I'll demonstrate that
33
00:01:25,920 --> 00:01:31,560
the number of calculations per triangle
34
00:01:28,049 --> 00:01:33,659
and per pixel is simply huge now there's
35
00:01:31,560 --> 00:01:36,600
one thing we can't get away from with 3d
36
00:01:33,659 --> 00:01:38,820
graphics and that is mathematics but
37
00:01:36,600 --> 00:01:40,590
don't click stop just yet I'm going to
38
00:01:38,820 --> 00:01:42,479
try and present it in a style that's
39
00:01:40,590 --> 00:01:44,909
maths friendly and the nice thing about
40
00:01:42,479 --> 00:01:48,090
3d engines is even if you don't have
41
00:01:44,909 --> 00:01:51,149
strong mathematics ability you can still
42
00:01:48,090 --> 00:01:53,040
use most of the parts of a 3d engine as
43
00:01:51,149 --> 00:01:55,259
as black boxes you don't necessarily
44
00:01:53,040 --> 00:01:57,479
need to know how they work but you need
45
00:01:55,259 --> 00:02:00,180
to know what these magical functions do
46
00:01:57,479 --> 00:02:01,890
and over time by using such functions
47
00:02:00,180 --> 00:02:04,170
you can actually develop a really
48
00:02:01,890 --> 00:02:06,869
intuitive understanding of what's going
49
00:02:04,170 --> 00:02:09,780
on behind the scenes so let's get
50
00:02:06,869 --> 00:02:11,879
started rather oddly I'm going to start
51
00:02:09,780 --> 00:02:13,890
this tutorial by saying there's no such
52
00:02:11,879 --> 00:02:16,230
thing as 3d graphics
53
00:02:13,890 --> 00:02:20,060
and that's simply because if we try to
54
00:02:16,230 --> 00:02:24,750
represent a 3d shape on a screen of
55
00:02:20,060 --> 00:02:26,970
course this screen is two-dimensional so
56
00:02:24,750 --> 00:02:28,770
even though the object looks 3d what
57
00:02:26,970 --> 00:02:32,340
we're actually trying to generate in the
58
00:02:28,770 --> 00:02:34,500
end is a sequence of 2d shapes that give
59
00:02:32,340 --> 00:02:37,200
the illusion of 3d on the screen
60
00:02:34,500 --> 00:02:40,800
so taking this cube as an example I can
61
00:02:37,200 --> 00:02:47,390
see I've got a top piece and I've got a
62
00:02:40,800 --> 00:02:49,920
side piece and I've got a front face
63
00:02:47,390 --> 00:02:54,060
should be a little squarer than that and
64
00:02:49,920 --> 00:02:57,390
so the purpose of a 3d engine is to take
65
00:02:54,060 --> 00:03:01,410
a three-dimensional geometrical data and
66
00:02:57,390 --> 00:03:05,520
convert it into these 2d shapes so we
67
00:03:01,410 --> 00:03:12,180
might define our cube as being a series
68
00:03:05,520 --> 00:03:17,670
of eight vertices which I'll mark here
69
00:03:12,180 --> 00:03:20,940
with the red dots don't forget there's
70
00:03:17,670 --> 00:03:22,980
one we can't see and from this very
71
00:03:20,940 --> 00:03:25,920
early stage even though it might seem
72
00:03:22,980 --> 00:03:32,160
strange I'm going to suggest that all of
73
00:03:25,920 --> 00:03:33,900
our dots are grouped into triangles so
74
00:03:32,160 --> 00:03:37,440
this front face here I'm marking out in
75
00:03:33,900 --> 00:03:41,880
blue consists of two triangles and the
76
00:03:37,440 --> 00:03:47,790
same applies for the top face and the
77
00:03:41,880 --> 00:03:54,209
side face and even the faces we can't
78
00:03:47,790 --> 00:03:57,600
see in the background and the reason I'm
79
00:03:54,209 --> 00:03:59,580
doing this is a triangle is a very
80
00:03:57,600 --> 00:04:02,610
simple primitive in fact it's the
81
00:03:59,580 --> 00:04:04,830
simplest 2d shape and as will become
82
00:04:02,610 --> 00:04:07,620
apparent it's convenient to group
83
00:04:04,830 --> 00:04:11,130
vertices together in some meaningful way
84
00:04:07,620 --> 00:04:14,220
and because triangles are the simplest
85
00:04:11,130 --> 00:04:16,979
2d primitive it's possible to represent
86
00:04:14,220 --> 00:04:19,910
any two-dimensional shape using nothing
87
00:04:16,979 --> 00:04:19,910
but triangles
88
00:04:29,090 --> 00:04:33,949
and finally when it comes to drawing
89
00:04:31,580 --> 00:04:35,960
triangles on a screen there are some
90
00:04:33,949 --> 00:04:38,600
very optimized algorithms to do this
91
00:04:35,960 --> 00:04:42,800
because a triangle consists of straight
92
00:04:38,600 --> 00:04:45,470
lines well not straight when Javid draws
93
00:04:42,800 --> 00:04:48,770
them and there are also some neat
94
00:04:45,470 --> 00:04:51,860
algorithms to fill in a triangle and
95
00:04:48,770 --> 00:04:54,530
shade it on the screen again using
96
00:04:51,860 --> 00:04:56,690
straight horizontal lines will look at
97
00:04:54,530 --> 00:04:59,180
rasterization in a later part of this
98
00:04:56,690 --> 00:05:02,620
series but what I'm trying to emphasize
99
00:04:59,180 --> 00:05:07,040
is that triangles are really important
100
00:05:02,620 --> 00:05:08,540
and so in this video we're going to look
101
00:05:07,040 --> 00:05:11,780
at how we can take a collection of
102
00:05:08,540 --> 00:05:14,330
vertices in three-dimensional space form
103
00:05:11,780 --> 00:05:16,940
a surface of a solid object out of
104
00:05:14,330 --> 00:05:20,510
triangles and projects these triangles
105
00:05:16,940 --> 00:05:22,370
to the screen for the user to see now
106
00:05:20,510 --> 00:05:24,139
because this is a new series and I'd
107
00:05:22,370 --> 00:05:25,760
like to show how to do this from scratch
108
00:05:24,139 --> 00:05:27,080
I'm actually going to show you how to
109
00:05:25,760 --> 00:05:30,740
create the visual studio project
110
00:05:27,080 --> 00:05:33,770
necessary to do this and in part that's
111
00:05:30,740 --> 00:05:36,289
because visual studio 2017 has changed
112
00:05:33,770 --> 00:05:37,789
the way projects are created and so I
113
00:05:36,289 --> 00:05:39,740
feel it might be useful to demonstrate
114
00:05:37,789 --> 00:05:41,690
how to set up a project to start
115
00:05:39,740 --> 00:05:45,349
something from scratch so I'm going to
116
00:05:41,690 --> 00:05:48,200
go to file new project and I want to
117
00:05:45,349 --> 00:05:49,880
choose windows console application of
118
00:05:48,200 --> 00:05:52,070
course I'm going to be doing all of this
119
00:05:49,880 --> 00:05:54,320
with the console game engine but don't
120
00:05:52,070 --> 00:05:56,300
let that put you off simply because the
121
00:05:54,320 --> 00:05:58,130
maths and the ideas don't change
122
00:05:56,300 --> 00:06:00,979
regardless of the interface that you're
123
00:05:58,130 --> 00:06:04,669
going to use select a console
124
00:06:00,979 --> 00:06:09,919
application and give it a name I'm going
125
00:06:04,669 --> 00:06:11,900
to call this one olc engine 3d now in
126
00:06:09,919 --> 00:06:12,880
previous versions of Visual Studio when
127
00:06:11,900 --> 00:06:16,010
you click OK
128
00:06:12,880 --> 00:06:18,500
it would give you some more options it
129
00:06:16,010 --> 00:06:20,240
no longer does this instead it creates a
130
00:06:18,500 --> 00:06:23,840
project for you and fills it full of
131
00:06:20,240 --> 00:06:27,560
files well the first thing I'm going to
132
00:06:23,840 --> 00:06:30,220
do is delete everything except the dot
133
00:06:27,560 --> 00:06:31,580
CPP file that it is created for me
134
00:06:30,220 --> 00:06:36,400
bye-bye
135
00:06:31,580 --> 00:06:39,169
and then going to remove this line
136
00:06:36,400 --> 00:06:41,000
standard afx that's for the precompiled
137
00:06:39,169 --> 00:06:43,040
headers I'm not interested in using
138
00:06:41,000 --> 00:06:45,230
those and even though I've removed the
139
00:06:43,040 --> 00:06:50,000
I actually need to go into properties of
140
00:06:45,230 --> 00:06:51,950
the project go to C++ expand that open
141
00:06:50,000 --> 00:06:55,100
and choose the precompiled headers
142
00:06:51,950 --> 00:07:00,860
option and tell it that no I don't want
143
00:06:55,100 --> 00:07:03,950
to use precompiled headers and click
144
00:07:00,860 --> 00:07:06,200
apply what I do want to use is the
145
00:07:03,950 --> 00:07:13,850
console game engine so I'm going to
146
00:07:06,200 --> 00:07:15,380
include it and I'm going to make sure
147
00:07:13,850 --> 00:07:17,180
that the header file that contains the
148
00:07:15,380 --> 00:07:23,570
console game engine is also in the
149
00:07:17,180 --> 00:07:25,610
project directory now we go and I'll add
150
00:07:23,570 --> 00:07:29,750
that file just because I like to see all
151
00:07:25,610 --> 00:07:32,750
the files my project is using into my
152
00:07:29,750 --> 00:07:34,100
visual studio project and of course if
153
00:07:32,750 --> 00:07:37,220
you're on a different operating system
154
00:07:34,100 --> 00:07:39,080
now you can use the OpenGL version or
155
00:07:37,220 --> 00:07:41,300
the STL version of the console game
156
00:07:39,080 --> 00:07:43,280
engine even though it says game engine
157
00:07:41,300 --> 00:07:45,470
in the title all we're really doing here
158
00:07:43,280 --> 00:07:48,140
is accepting input from the user and
159
00:07:45,470 --> 00:07:49,580
displaying things on a 2d screen the
160
00:07:48,140 --> 00:07:51,290
fact that this house game engine there
161
00:07:49,580 --> 00:07:54,260
doesn't imply we're going to be using
162
00:07:51,290 --> 00:07:55,460
any of the game engine features which is
163
00:07:54,260 --> 00:07:57,500
important because I don't want you to
164
00:07:55,460 --> 00:07:59,210
think that I'm hiding interesting
165
00:07:57,500 --> 00:08:01,160
technology and clever functions in the
166
00:07:59,210 --> 00:08:02,540
console game engine and exploiting them
167
00:08:01,160 --> 00:08:04,700
to generate 3d graphics
168
00:08:02,540 --> 00:08:06,530
I'm not regular viewers of the channel
169
00:08:04,700 --> 00:08:09,050
will know that we need to create a
170
00:08:06,530 --> 00:08:11,240
subclass of the OLC console game engine
171
00:08:09,050 --> 00:08:15,980
and so I'm going to call it olc engine
172
00:08:11,240 --> 00:08:19,940
3d which inherits from the console game
173
00:08:15,980 --> 00:08:22,570
engine let's just give it a quick
174
00:08:19,940 --> 00:08:22,570
constructor
175
00:08:25,120 --> 00:08:39,099
and there are two functions we must
176
00:08:27,490 --> 00:08:45,870
override the first is on user create and
177
00:08:39,099 --> 00:08:45,870
the second is on user update
178
00:08:58,110 --> 00:09:02,470
for now I'll make these return true and
179
00:09:00,910 --> 00:09:03,760
that tells the game engine that
180
00:09:02,470 --> 00:09:09,550
everything is fine and it should
181
00:09:03,760 --> 00:09:11,140
continue running in our in main function
182
00:09:09,550 --> 00:09:20,470
we need to create an instance of this
183
00:09:11,140 --> 00:09:22,600
class and we should try to create an
184
00:09:20,470 --> 00:09:25,330
instance of the console using it using
185
00:09:22,600 --> 00:09:27,580
the construct console function and for
186
00:09:25,330 --> 00:09:28,990
this application and indeed this series
187
00:09:27,580 --> 00:09:33,340
I'm going to use quite a high resolution
188
00:09:28,990 --> 00:09:35,200
console of 256 characters wide by 240
189
00:09:33,340 --> 00:09:38,140
characters high and each character is
190
00:09:35,200 --> 00:09:41,320
going to be 4 by 4 pixels width and
191
00:09:38,140 --> 00:09:44,080
height an oh dear quick error number 1 I
192
00:09:41,320 --> 00:09:47,400
need to publicly include the console
193
00:09:44,080 --> 00:09:50,200
game engine there we go
194
00:09:47,400 --> 00:09:55,660
so if we can successfully construct the
195
00:09:50,200 --> 00:09:58,090
console I want to start it else I would
196
00:09:55,660 --> 00:10:00,130
display some sort of error message as is
197
00:09:58,090 --> 00:10:02,170
typical in some of my videos I don't
198
00:10:00,130 --> 00:10:04,210
tend to do all of the error capture code
199
00:10:02,170 --> 00:10:08,200
that's to keep the code as clear and
200
00:10:04,210 --> 00:10:16,270
concise as possible finally I'll name
201
00:10:08,200 --> 00:10:19,090
the application 3d demo and a quick
202
00:10:16,270 --> 00:10:21,250
reminder by default now unicode will be
203
00:10:19,090 --> 00:10:23,890
enabled and this is important because I
204
00:10:21,250 --> 00:10:25,840
think it is the singular most popular
205
00:10:23,890 --> 00:10:27,790
question I've been asked since starting
206
00:10:25,840 --> 00:10:30,010
this channel how to enable the Unicode
207
00:10:27,790 --> 00:10:31,990
and thankfully Microsoft do that for me
208
00:10:30,010 --> 00:10:33,970
now well now because I want to
209
00:10:31,990 --> 00:10:37,600
demonstrate all of this from scratch I'm
210
00:10:33,970 --> 00:10:38,920
not going to be using a maths library to
211
00:10:37,600 --> 00:10:40,570
help me we're going to do absolutely
212
00:10:38,920 --> 00:10:43,840
everything so I'm going to create a
213
00:10:40,570 --> 00:10:45,400
structure called BEC 3d and this is
214
00:10:43,840 --> 00:10:49,960
going to hold three floating-point
215
00:10:45,400 --> 00:10:51,670
values X Y & Z which represent a
216
00:10:49,960 --> 00:10:53,590
coordinate in 3d space
217
00:10:51,670 --> 00:10:57,910
I'm also going to create a second
218
00:10:53,590 --> 00:11:02,190
structure called triangle which is going
219
00:10:57,910 --> 00:11:02,190
to group together three vector E DS
220
00:11:07,300 --> 00:11:12,130
as the series progresses we'll be adding
221
00:11:10,070 --> 00:11:14,270
more features to this triangle structure
222
00:11:12,130 --> 00:11:19,100
finally I'm going to create a third
223
00:11:14,270 --> 00:11:21,590
structure called mesh and a mesh is
224
00:11:19,100 --> 00:11:30,230
going to represent the object it's going
225
00:11:21,590 --> 00:11:32,210
to group together triangles and you'll
226
00:11:30,230 --> 00:11:35,390
notice a little red wiggly line has
227
00:11:32,210 --> 00:11:37,670
appeared and that's because at long last
228
00:11:35,390 --> 00:11:40,940
I finally removed the using namespace
229
00:11:37,670 --> 00:11:42,680
STD from the header file as I can here
230
00:11:40,940 --> 00:11:45,320
most of the people on discord cheering
231
00:11:42,680 --> 00:11:47,030
right now and I can't argue that it is
232
00:11:45,320 --> 00:11:49,550
good practice not to include using
233
00:11:47,030 --> 00:11:52,220
namespace in your header files but to
234
00:11:49,550 --> 00:11:56,210
keep this code clear I'm actually going
235
00:11:52,220 --> 00:11:58,610
to use it here so a quick recap we've
236
00:11:56,210 --> 00:12:01,310
got a mesh which contains a vector of
237
00:11:58,610 --> 00:12:03,050
triangles that represents an object and
238
00:12:01,310 --> 00:12:06,470
we've got a triangle which contains
239
00:12:03,050 --> 00:12:08,180
three vertices or vector 3ds these are
240
00:12:06,470 --> 00:12:10,550
the points that define the outline of
241
00:12:08,180 --> 00:12:13,040
the triangle I'm going to add now to our
242
00:12:10,550 --> 00:12:17,180
main class a mesh and I'm going to call
243
00:12:13,040 --> 00:12:19,340
it mesh cube and in on user create I'm
244
00:12:17,180 --> 00:12:21,500
going to populate that mesh with the
245
00:12:19,340 --> 00:12:28,850
vertex data to define a cube made of
246
00:12:21,500 --> 00:12:32,240
triangles and I'm going to use this with
247
00:12:28,850 --> 00:12:34,340
some nifty initializer lists I'm going
248
00:12:32,240 --> 00:12:36,830
to keep the cube simple and define it as
249
00:12:34,340 --> 00:12:39,920
a unit cube in these three dimensions so
250
00:12:36,830 --> 00:12:42,110
each side of the cube is one unit long
251
00:12:39,920 --> 00:12:46,940
and we'll assume the origin of the cube
252
00:12:42,110 --> 00:12:56,150
is at 0 0 0 x y&z therefore this point
253
00:12:46,940 --> 00:12:57,710
becomes 1 0 0 0 1 0 and 1 1 0 I've drawn
254
00:12:56,150 --> 00:13:00,290
the cube edges so we can see what's
255
00:12:57,710 --> 00:13:05,240
going on a little more clearly and this
256
00:13:00,290 --> 00:13:06,650
obviously becomes 0 1 1 in fact it's
257
00:13:05,240 --> 00:13:08,120
each one of these coordinates of the
258
00:13:06,650 --> 00:13:10,880
back is the same as the one at the front
259
00:13:08,120 --> 00:13:15,350
except the Z component is 1 so this one
260
00:13:10,880 --> 00:13:18,850
up here is 1 1 1 and this one is 1 0 1
261
00:13:15,350 --> 00:13:21,920
and the 1 hidden is 0
262
00:13:18,850 --> 00:13:26,510
zero-one and I'm going to top the
263
00:13:21,920 --> 00:13:30,140
convention that this face is South the
264
00:13:26,510 --> 00:13:33,230
face round the back is north this face
265
00:13:30,140 --> 00:13:37,430
is east and that face round the back
266
00:13:33,230 --> 00:13:40,160
there is West this one's the top and
267
00:13:37,430 --> 00:13:43,130
therefore the one underneath I'm going
268
00:13:40,160 --> 00:13:45,320
to call bottom and now I can start to
269
00:13:43,130 --> 00:13:46,850
think about my triangles but there's
270
00:13:45,320 --> 00:13:48,830
something important about the triangles
271
00:13:46,850 --> 00:13:51,050
which will come to again later on and
272
00:13:48,830 --> 00:13:53,630
that is what the order of the points
273
00:13:51,050 --> 00:13:56,960
that we define the triangle in and I
274
00:13:53,630 --> 00:14:01,430
want to always use a clockwise order so
275
00:13:56,960 --> 00:14:05,990
I'm going to take from zero zero zero up
276
00:14:01,430 --> 00:14:08,510
here all the way along and because it's
277
00:14:05,990 --> 00:14:11,960
a triangle I now need to come back down
278
00:14:08,510 --> 00:14:14,260
to the original point you'll notice I've
279
00:14:11,960 --> 00:14:16,940
gone in a clockwise direction
280
00:14:14,260 --> 00:14:23,230
and I want to do the same now for my
281
00:14:16,940 --> 00:14:27,020
second triangle up to the top back down
282
00:14:23,230 --> 00:14:30,070
and along again in a clockwise direction
283
00:14:27,020 --> 00:14:33,970
and I want to do exactly the same for
284
00:14:30,070 --> 00:14:33,970
the remaining faces
285
00:14:43,200 --> 00:14:50,070
always retaining this clockwise ordering
286
00:14:47,030 --> 00:14:52,640
using initializer lists I can define the
287
00:14:50,070 --> 00:14:56,100
vertices manually and I group them into
288
00:14:52,640 --> 00:14:58,260
South East North West and top and bottom
289
00:14:56,100 --> 00:15:00,600
but I'm also using a neat trick that
290
00:14:58,260 --> 00:15:03,360
I've got to initialize a list inside the
291
00:15:00,600 --> 00:15:05,210
other initializer list so this sub
292
00:15:03,360 --> 00:15:08,880
initializer list will initialize the
293
00:15:05,210 --> 00:15:11,220
triangle with three vectors whilst the
294
00:15:08,880 --> 00:15:13,590
outside initializer list initializes the
295
00:15:11,220 --> 00:15:16,260
standard vector I'm going to use the
296
00:15:13,590 --> 00:15:18,600
fill command in on user update to clear
297
00:15:16,260 --> 00:15:21,990
the screen from the top left to the
298
00:15:18,600 --> 00:15:23,760
bottom right and after we've cleared the
299
00:15:21,990 --> 00:15:29,370
screen we're going to need to draw our
300
00:15:23,760 --> 00:15:31,800
triangles and because our triangles are
301
00:15:29,370 --> 00:15:35,670
neatly contained inside a vector inside
302
00:15:31,800 --> 00:15:38,780
of mesh I can use an auto for loop to
303
00:15:35,670 --> 00:15:38,780
iterate through them all
304
00:15:47,100 --> 00:15:53,110
but of course it's not this simple the
305
00:15:50,530 --> 00:15:55,540
objects exist in 3d space and the screen
306
00:15:53,110 --> 00:15:57,460
is in 2d space so we need to come up
307
00:15:55,540 --> 00:15:59,560
with a way of condensing that foodie
308
00:15:57,460 --> 00:16:02,170
space to the 2d screen and this is
309
00:15:59,560 --> 00:16:05,080
called projection so how do we turn our
310
00:16:02,170 --> 00:16:07,420
3d vertices into 2d vertices for
311
00:16:05,080 --> 00:16:10,840
projection onto the screen well first of
312
00:16:07,420 --> 00:16:14,500
all let's define our screen which is
313
00:16:10,840 --> 00:16:17,050
going to be some sort of rectangle with
314
00:16:14,500 --> 00:16:19,090
a width and a height because screens
315
00:16:17,050 --> 00:16:21,330
come in all shapes and sizes it's useful
316
00:16:19,090 --> 00:16:24,730
to reduce the three-dimensional objects
317
00:16:21,330 --> 00:16:26,710
into a normalized screen space and so
318
00:16:24,730 --> 00:16:30,490
I'm going to suggest that if we
319
00:16:26,710 --> 00:16:34,240
partition the screen this way and this
320
00:16:30,490 --> 00:16:37,510
way and we label this as minus one and
321
00:16:34,240 --> 00:16:40,810
this is positive one and up here as
322
00:16:37,510 --> 00:16:43,150
minus one and this as positive one we've
323
00:16:40,810 --> 00:16:45,610
normalized the screen space obviously
324
00:16:43,150 --> 00:16:45,970
that gives us zero zero in the middle of
325
00:16:45,610 --> 00:16:47,980
the screen
326
00:16:45,970 --> 00:16:50,110
and because the width and height can be
327
00:16:47,980 --> 00:16:52,570
different we want to scale movements
328
00:16:50,110 --> 00:16:54,490
within the screen space accordingly so
329
00:16:52,570 --> 00:16:57,040
we're going to use the aspect ratio
330
00:16:54,490 --> 00:17:00,130
which I'll call a and define that as
331
00:16:57,040 --> 00:17:01,750
being the height over the width and this
332
00:17:00,130 --> 00:17:03,790
will be the first of several assumptions
333
00:17:01,750 --> 00:17:09,010
about how we're going to transform our
334
00:17:03,790 --> 00:17:11,520
3d vector X Y & Z into our screen space
335
00:17:09,010 --> 00:17:17,100
vector and I'm going to demonstrate this
336
00:17:11,520 --> 00:17:17,100
by accumulating the operations required
337
00:17:21,490 --> 00:17:25,910
normalizing the screen space has an
338
00:17:23,569 --> 00:17:29,179
additional advantage that anything above
339
00:17:25,910 --> 00:17:32,120
+1 or below minus 1 definitely won't be
340
00:17:29,179 --> 00:17:35,929
drawn to the screen so let's just draw
341
00:17:32,120 --> 00:17:38,660
in some imaginary boundaries here this
342
00:17:35,929 --> 00:17:42,080
object exists entirely within the
343
00:17:38,660 --> 00:17:44,179
visible viewing space but this object on
344
00:17:42,080 --> 00:17:47,049
the right straddles the boundary so
345
00:17:44,179 --> 00:17:50,150
we'll never see this side of the object
346
00:17:47,049 --> 00:17:52,730
however humans don't see screens in that
347
00:17:50,150 --> 00:17:56,570
manner they see instead what's called
348
00:17:52,730 --> 00:17:59,500
the field of view and we can cast array
349
00:17:56,570 --> 00:18:03,559
that way and we'll cast array that way
350
00:17:59,500 --> 00:18:06,559
so at this point it's minus 1 and plus 1
351
00:18:03,559 --> 00:18:10,840
on the screen but also out here in our
352
00:18:06,559 --> 00:18:13,070
space this is also minus 1 and plus 1
353
00:18:10,840 --> 00:18:15,200
and of course this makes a lot of sense
354
00:18:13,070 --> 00:18:17,720
because objects that are further away
355
00:18:15,200 --> 00:18:20,260
well we can see more space the further
356
00:18:17,720 --> 00:18:23,059
away it is and as we approach the screen
357
00:18:20,260 --> 00:18:25,490
we occupy more of the screen with our
358
00:18:23,059 --> 00:18:28,460
objects if the field of view is
359
00:18:25,490 --> 00:18:31,070
particularly narrow how crudely draw in
360
00:18:28,460 --> 00:18:33,530
here is a blue triangle it has the
361
00:18:31,070 --> 00:18:37,820
effect of zooming in on the object and
362
00:18:33,530 --> 00:18:40,280
if the field of view goes really wide it
363
00:18:37,820 --> 00:18:42,290
has the effect of zooming out we see
364
00:18:40,280 --> 00:18:44,450
more stuff and this means we need a
365
00:18:42,290 --> 00:18:46,429
scaling factor that relates to the field
366
00:18:44,450 --> 00:18:50,510
of view and we'll say that the field of
367
00:18:46,429 --> 00:18:52,760
view is theta well one way to think
368
00:18:50,510 --> 00:18:55,250
about a scaling factor is to draw a
369
00:18:52,760 --> 00:18:58,570
right angle triangle right down the
370
00:18:55,250 --> 00:18:58,570
middle of our field of view
371
00:19:01,760 --> 00:19:08,450
say that the right angles and as this
372
00:19:06,410 --> 00:19:11,270
angle increases so this is now theta
373
00:19:08,450 --> 00:19:14,600
divided by two our opposite side of the
374
00:19:11,270 --> 00:19:17,390
triangle increases and so it stands to
375
00:19:14,600 --> 00:19:20,060
reason that since we've got the angle of
376
00:19:17,390 --> 00:19:22,220
a triangle its opposite side and it's
377
00:19:20,060 --> 00:19:25,270
adjacent side that we might want to
378
00:19:22,220 --> 00:19:27,770
consider looking at the tangent function
379
00:19:25,270 --> 00:19:30,010
but of course it's tangent of the field
380
00:19:27,770 --> 00:19:33,080
of U divided by 2
381
00:19:30,010 --> 00:19:36,890
but there's a slight problem here if we
382
00:19:33,080 --> 00:19:40,250
take a point and we increase our field
383
00:19:36,890 --> 00:19:43,340
of view the scaling factor that we get
384
00:19:40,250 --> 00:19:47,360
as a result of this equation gets larger
385
00:19:43,340 --> 00:19:50,240
and naturally if we reduce theta the
386
00:19:47,360 --> 00:19:51,920
scaling factor gets smaller so this has
387
00:19:50,240 --> 00:19:54,050
the rather odd effect that if we
388
00:19:51,920 --> 00:19:56,540
increase the field of view we start
389
00:19:54,050 --> 00:19:59,090
displacing all of our objects outside of
390
00:19:56,540 --> 00:20:02,600
it and naturally if we decrease our
391
00:19:59,090 --> 00:20:04,730
field of view we scale them less so more
392
00:20:02,600 --> 00:20:06,560
objects can appear and this is a
393
00:20:04,730 --> 00:20:09,140
contradiction to what we've just said
394
00:20:06,560 --> 00:20:11,930
that increasing the field of view is the
395
00:20:09,140 --> 00:20:15,230
same as zooming out so what we want is
396
00:20:11,930 --> 00:20:18,470
the exact opposite of this indeed we
397
00:20:15,230 --> 00:20:20,570
want the inverse of it this gives us
398
00:20:18,470 --> 00:20:24,200
some more coefficients to add to our
399
00:20:20,570 --> 00:20:31,250
transformation where F is equal to 1
400
00:20:24,200 --> 00:20:33,710
over tan of theta over 2 since we've
401
00:20:31,250 --> 00:20:36,140
gone to the trouble of normalizing x and
402
00:20:33,710 --> 00:20:38,380
y and realistically all we're interested
403
00:20:36,140 --> 00:20:41,030
is in x and y because this is a 2d
404
00:20:38,380 --> 00:20:43,640
surface in the end we may as well also
405
00:20:41,030 --> 00:20:44,870
attempt to normalize Z and the reasons
406
00:20:43,640 --> 00:20:46,820
for this might not be immediately
407
00:20:44,870 --> 00:20:49,790
apparent but as we'll see in future
408
00:20:46,820 --> 00:20:53,390
videos knowing what Z is in the same
409
00:20:49,790 --> 00:20:55,490
space as x and y can be really useful
410
00:20:53,390 --> 00:20:57,110
for optimizing our algorithms and
411
00:20:55,490 --> 00:20:59,090
handling other interesting drawing
412
00:20:57,110 --> 00:21:01,280
routines like transparency in depth
413
00:20:59,090 --> 00:21:03,710
choosing a scaling coefficient for the z
414
00:21:01,280 --> 00:21:06,800
axis is somewhat more simpler on again a
415
00:21:03,710 --> 00:21:10,400
frustum and this is the z axis going
416
00:21:06,800 --> 00:21:12,920
forward into the distance the furthest
417
00:21:10,400 --> 00:21:15,500
distance of objects that we can see will
418
00:21:12,920 --> 00:21:19,880
be defined by this plane at the back
419
00:21:15,500 --> 00:21:21,890
which I'm going to call Zed far now you
420
00:21:19,880 --> 00:21:24,440
might assume that means where the screen
421
00:21:21,890 --> 00:21:26,210
is at the front that would be zero but
422
00:21:24,440 --> 00:21:28,970
that's not quite the case because the
423
00:21:26,210 --> 00:21:30,830
players head isn't resting against the
424
00:21:28,970 --> 00:21:32,420
screen the player would injure their
425
00:21:30,830 --> 00:21:35,330
eyes where in fact there is a small
426
00:21:32,420 --> 00:21:40,400
distance here I'm going to call that Zed
427
00:21:35,330 --> 00:21:42,590
near which is the distance represented
428
00:21:40,400 --> 00:21:45,980
from the play's head to the front of the
429
00:21:42,590 --> 00:21:49,580
screen and Zed far is from the place
430
00:21:45,980 --> 00:21:51,860
head to the furthest distance we want to
431
00:21:49,580 --> 00:21:53,630
be able to view in the in the engine if
432
00:21:51,860 --> 00:21:55,940
I put some imaginary numbers next to
433
00:21:53,630 --> 00:21:59,330
this so let's say our far plane is at 10
434
00:21:55,940 --> 00:22:02,420
and our near plane is at 1 to work out
435
00:21:59,330 --> 00:22:04,940
where the position of a point in that
436
00:22:02,420 --> 00:22:08,390
plane really is we need to first scale
437
00:22:04,940 --> 00:22:10,760
it to a normalized system so in this
438
00:22:08,390 --> 00:22:14,570
case our Zed far-
439
00:22:10,760 --> 00:22:17,060
RZ near is equal to 9 so we want to take
440
00:22:14,570 --> 00:22:20,540
our point and divide it by 9 that will
441
00:22:17,060 --> 00:22:23,030
give us a point between 0 & 1 but we've
442
00:22:20,540 --> 00:22:25,430
decided that our far plane should be 10
443
00:22:23,030 --> 00:22:28,790
so we need to scale it back up again so
444
00:22:25,430 --> 00:22:32,420
this is implying that we have for our z
445
00:22:28,790 --> 00:22:39,260
axis scale factor something that looks
446
00:22:32,420 --> 00:22:45,080
like this Zed far divided by Zed far -
447
00:22:39,260 --> 00:22:47,870
Zed near but this still leaves us with a
448
00:22:45,080 --> 00:22:50,900
bit of a discrepancy here so we'll also
449
00:22:47,870 --> 00:22:53,990
need to offset our transformed point by
450
00:22:50,900 --> 00:22:55,400
this discrepancy scaled - well
451
00:22:53,990 --> 00:22:58,520
fortunately we know where that
452
00:22:55,400 --> 00:23:01,250
discrepancy is so we can take our
453
00:22:58,520 --> 00:23:04,220
equation up here and simply multiply it
454
00:23:01,250 --> 00:23:07,220
by Z near but we're going to offset it
455
00:23:04,220 --> 00:23:13,360
from the final result so this becomes Z
456
00:23:07,220 --> 00:23:18,170
far multiplied by Z near over Zed far
457
00:23:13,360 --> 00:23:19,790
take xenia and so now if we look at our
458
00:23:18,170 --> 00:23:22,490
initial coordinates and look at the
459
00:23:19,790 --> 00:23:24,830
final transformed coordinate well it's
460
00:23:22,490 --> 00:23:26,500
starting to look a bit complicated and
461
00:23:24,830 --> 00:23:29,120
we're not even quite finished yet
462
00:23:26,500 --> 00:23:32,210
intuitively we know that when things are
463
00:23:29,120 --> 00:23:34,130
further away they appear to move less so
464
00:23:32,210 --> 00:23:37,810
this implies that a change in the
465
00:23:34,130 --> 00:23:38,960
x-coordinate is somehow related to the
466
00:23:37,810 --> 00:23:40,850
z-depth
467
00:23:38,960 --> 00:23:43,250
in this case it's inversely proportional
468
00:23:40,850 --> 00:23:44,090
as Zed gets larger ie further away from
469
00:23:43,250 --> 00:23:47,060
the screen
470
00:23:44,090 --> 00:23:53,780
it makes the changes in X smaller and
471
00:23:47,060 --> 00:23:56,450
this is analogous for Y so our final
472
00:23:53,780 --> 00:24:03,340
scaling that we need to do to our x and
473
00:23:56,450 --> 00:24:03,340
y coordinates is to divide them by Z
474
00:24:04,390 --> 00:24:11,180
let's start to simplify some of this out
475
00:24:07,960 --> 00:24:14,330
I'll take our width in a height and
476
00:24:11,180 --> 00:24:16,730
we'll call it a 4 aspect ratio we'll
477
00:24:14,330 --> 00:24:19,430
take our field of view and we'll call
478
00:24:16,730 --> 00:24:23,750
that f and let's take our said
479
00:24:19,430 --> 00:24:27,280
normalization and we'll call that Q and
480
00:24:23,750 --> 00:24:30,860
which you can see also applies here
481
00:24:27,280 --> 00:24:49,030
which means a much simpler form would be
482
00:24:30,860 --> 00:24:50,900
a F X / z f y / z and z q - said near q
483
00:24:49,030 --> 00:24:53,420
we could go and implement these
484
00:24:50,900 --> 00:24:56,660
equations directly but instead I'm going
485
00:24:53,420 --> 00:24:58,460
to represent them in matrix form as this
486
00:24:56,660 --> 00:25:00,310
allows us then to implement a function
487
00:24:58,460 --> 00:25:02,390
which can multiply a vector by a matrix
488
00:25:00,310 --> 00:25:04,820
something which we're going to use a lot
489
00:25:02,390 --> 00:25:06,890
off in 3d graphics in the Cody self
490
00:25:04,820 --> 00:25:10,580
asteroids video I already talked in
491
00:25:06,890 --> 00:25:12,920
quite some detail about how matrix
492
00:25:10,580 --> 00:25:16,520
multiplication works but just as a quick
493
00:25:12,920 --> 00:25:18,680
recap we'll take this element of the
494
00:25:16,520 --> 00:25:20,840
vector and multiply it by this element
495
00:25:18,680 --> 00:25:23,890
of the matrix and this element of the
496
00:25:20,840 --> 00:25:26,420
vector and this element of the matrix
497
00:25:23,890 --> 00:25:28,910
this element of the vector and this
498
00:25:26,420 --> 00:25:31,490
element of the matrix and we sum them up
499
00:25:28,910 --> 00:25:35,360
and that gives us a result to put into
500
00:25:31,490 --> 00:25:38,510
our new vector in this location so let's
501
00:25:35,360 --> 00:25:41,360
start with the transformed X location so
502
00:25:38,510 --> 00:25:42,930
I'm going to put the result here in the
503
00:25:41,360 --> 00:25:45,630
top corner which
504
00:25:42,930 --> 00:25:52,470
simply want AF the remaining entries are
505
00:25:45,630 --> 00:25:56,850
zero so x x AF + y x 0 + said x 0 gives
506
00:25:52,470 --> 00:25:59,370
us a F X Y is even simpler we're not too
507
00:25:56,850 --> 00:26:02,100
concerned about the X component we just
508
00:25:59,370 --> 00:26:04,290
want F and nothing else and similarly
509
00:26:02,100 --> 00:26:06,960
for the Z we don't compare about the X
510
00:26:04,290 --> 00:26:09,510
component either nor the Y but we do
511
00:26:06,960 --> 00:26:11,610
concern ourselves with Q but we've got
512
00:26:09,510 --> 00:26:12,870
some interesting addition to Zed that
513
00:26:11,610 --> 00:26:14,280
we've got to have this little offset
514
00:26:12,870 --> 00:26:15,960
that's okay
515
00:26:14,280 --> 00:26:18,110
because as we're performing the matrix
516
00:26:15,960 --> 00:26:21,180
calculation we're summing this column
517
00:26:18,110 --> 00:26:25,470
multiplied by the vector so I can simply
518
00:26:21,180 --> 00:26:32,250
include as one of the elements - Zed
519
00:26:25,470 --> 00:26:34,620
near Q but hang on we've suddenly got
520
00:26:32,250 --> 00:26:37,050
four elements in this column and we've
521
00:26:34,620 --> 00:26:39,090
only got three elements of our vector as
522
00:26:37,050 --> 00:26:43,490
an input so to make this happen
523
00:26:39,090 --> 00:26:46,590
I'm going to extend our input vector
524
00:26:43,490 --> 00:26:49,470
with a 1 this of course also means I
525
00:26:46,590 --> 00:26:51,300
have to put in additional zeros for the
526
00:26:49,470 --> 00:26:53,340
x and y elements but now I've got an
527
00:26:51,300 --> 00:26:56,970
interesting scenario of multiplying a
528
00:26:53,340 --> 00:26:59,520
four by one vector by a 3 by 4 matrix I
529
00:26:56,970 --> 00:27:01,500
have to use the final column of a four
530
00:26:59,520 --> 00:27:05,610
by four matrix to make this legitimate
531
00:27:01,500 --> 00:27:08,400
so let me just fill in Zed Q - Zed near
532
00:27:05,610 --> 00:27:10,860
Q so what do we do with this fourth
533
00:27:08,400 --> 00:27:13,560
column well you may also notice that
534
00:27:10,860 --> 00:27:15,810
we've not got to divide by Z anywhere in
535
00:27:13,560 --> 00:27:18,270
there and I can't readily do that in
536
00:27:15,810 --> 00:27:20,280
this calculation getting the divided by
537
00:27:18,270 --> 00:27:22,110
Zed is going to need to be a second
538
00:27:20,280 --> 00:27:24,570
operation in fact we're going to be
539
00:27:22,110 --> 00:27:27,690
normalizing the vector with the Z value
540
00:27:24,570 --> 00:27:32,850
so I do want to extract it and to do
541
00:27:27,690 --> 00:27:34,380
this I'm going to 0 0 1 0 so this will
542
00:27:32,850 --> 00:27:36,420
give me a fourth component of my
543
00:27:34,380 --> 00:27:39,960
transformed vector which will simply be
544
00:27:36,420 --> 00:27:41,910
Z and after I've performed the
545
00:27:39,960 --> 00:27:46,980
transformation and then going to take
546
00:27:41,910 --> 00:27:50,600
the last element of this vector and use
547
00:27:46,980 --> 00:27:50,600
it to divide the others
548
00:27:52,140 --> 00:27:56,530
giving us a coordinate in Cartesian
549
00:27:54,700 --> 00:27:58,870
space and so where we bring this
550
00:27:56,530 --> 00:28:01,630
structure all together is one this is
551
00:27:58,870 --> 00:28:04,120
called the projection matrix and yes it
552
00:28:01,630 --> 00:28:05,380
may seem like a scary bunch of maths but
553
00:28:04,120 --> 00:28:07,300
this is actually probably one of the
554
00:28:05,380 --> 00:28:09,330
more complicated transforms that we'll
555
00:28:07,300 --> 00:28:12,010
need to do as part of the 3d engine and
556
00:28:09,330 --> 00:28:13,660
as I've mentioned before you can really
557
00:28:12,010 --> 00:28:16,210
treat it like a black box this
558
00:28:13,660 --> 00:28:17,800
projection matrix will work for all 3d
559
00:28:16,210 --> 00:28:19,870
applications and it's highly
560
00:28:17,800 --> 00:28:23,170
customizable in terms of aspect ratio
561
00:28:19,870 --> 00:28:24,700
field of view and viewing distance so
562
00:28:23,170 --> 00:28:29,020
this means of course we now need a
563
00:28:24,700 --> 00:28:34,150
matrix structure I'm going to call it
564
00:28:29,020 --> 00:28:38,100
4x4 and I'm simply going to define a two
565
00:28:34,150 --> 00:28:41,380
dimensional array explicitly and
566
00:28:38,100 --> 00:28:44,020
initialize it to zero and the ordering
567
00:28:41,380 --> 00:28:45,970
of this matrix is row followed by column
568
00:28:44,020 --> 00:28:49,480
I'm going to populate the projection
569
00:28:45,970 --> 00:28:51,220
matrix once in on user create because
570
00:28:49,480 --> 00:28:52,450
the screen dimensions and field of view
571
00:28:51,220 --> 00:28:53,380
are not going to change in my
572
00:28:52,450 --> 00:28:56,170
application
573
00:28:53,380 --> 00:28:59,380
we'll have our near plane distance along
574
00:28:56,170 --> 00:29:02,370
the z axis and to set that to not point
575
00:28:59,380 --> 00:29:05,760
what we're going to need the far plane
576
00:29:02,370 --> 00:29:08,290
which I'm going to set to a thousand
577
00:29:05,760 --> 00:29:11,740
let's not forget the important field of
578
00:29:08,290 --> 00:29:16,440
view which I'm going to set to be 90
579
00:29:11,740 --> 00:29:16,440
degrees next up is the aspect ratio
580
00:29:19,020 --> 00:29:23,350
which I'm going to grab directly from
581
00:29:21,520 --> 00:29:27,000
the console so it doesn't really matter
582
00:29:23,350 --> 00:29:27,000
what size console you create
583
00:29:30,550 --> 00:29:38,520
and for convenience I'm going to do the
584
00:29:33,940 --> 00:29:38,520
tangent calculation as a one-off and
585
00:29:47,010 --> 00:29:52,660
you'll notice here I've converted it
586
00:29:49,450 --> 00:29:57,430
from degrees to radians let's create a
587
00:29:52,660 --> 00:30:00,370
projection matrix mat proj that's quite
588
00:29:57,430 --> 00:30:04,480
customary and I'm going to specify the
589
00:30:00,370 --> 00:30:07,720
elements of the matrix directly row
590
00:30:04,480 --> 00:30:10,350
column so we know that this is our W X
591
00:30:07,720 --> 00:30:15,250
value that we've just seen in the slides
592
00:30:10,350 --> 00:30:23,950
which was our aspect ratio times our
593
00:30:15,250 --> 00:30:26,370
tangent calculation our H Y value was
594
00:30:23,950 --> 00:30:29,290
just the tangent calculation directly
595
00:30:26,370 --> 00:30:32,110
and here I've just filled in the
596
00:30:29,290 --> 00:30:33,760
remaining options I've got a sneaking
597
00:30:32,110 --> 00:30:37,120
suspicion that we're going to be doing
598
00:30:33,760 --> 00:30:38,500
matrix vector multiplications a lot so
599
00:30:37,120 --> 00:30:43,750
I'm going to create a function to do it
600
00:30:38,500 --> 00:30:47,170
for me and so we're going to input one
601
00:30:43,750 --> 00:30:49,600
of our vectors and I want to get a
602
00:30:47,170 --> 00:30:53,410
different output vector because I don't
603
00:30:49,600 --> 00:30:58,060
want to upset the input data and we need
604
00:30:53,410 --> 00:31:01,210
to pass in the matrix performing the
605
00:30:58,060 --> 00:31:03,880
multiplication is simple and I'm going
606
00:31:01,210 --> 00:31:06,430
to write the x y&z components directly
607
00:31:03,880 --> 00:31:09,070
to the output vector but don't forget we
608
00:31:06,430 --> 00:31:11,440
had a mysterious fourth element which
609
00:31:09,070 --> 00:31:13,750
I'm going to call W and we have to
610
00:31:11,440 --> 00:31:16,180
include this when we're multiplying by
611
00:31:13,750 --> 00:31:18,160
four by four matrix the only thing to
612
00:31:16,180 --> 00:31:20,320
remember is that we're implying that the
613
00:31:18,160 --> 00:31:23,350
fourth element of the input vector is
614
00:31:20,320 --> 00:31:25,960
one so we can simply sum the final
615
00:31:23,350 --> 00:31:28,210
matrix element now because we've got
616
00:31:25,960 --> 00:31:30,340
four D and we need to get back to 3d
617
00:31:28,210 --> 00:31:33,730
Cartesian space we're going to divide it
618
00:31:30,340 --> 00:31:35,980
by element W but I don't want to do that
619
00:31:33,730 --> 00:31:40,630
if W is equal to zero that's going to
620
00:31:35,980 --> 00:31:43,510
cause me headaches so if W is not zero
621
00:31:40,630 --> 00:31:54,670
then I want to take the output values
622
00:31:43,510 --> 00:31:56,650
and divide them by the W now let's have
623
00:31:54,670 --> 00:31:59,530
a think about how we draw the triangles
624
00:31:56,650 --> 00:32:01,000
using our projection matrix we know that
625
00:31:59,530 --> 00:32:05,140
we're going through this Auto for loop
626
00:32:01,000 --> 00:32:06,400
picking out each triangle at the time we
627
00:32:05,140 --> 00:32:08,050
don't want to upset the original
628
00:32:06,400 --> 00:32:12,820
triangles so I'm going to create a new
629
00:32:08,050 --> 00:32:14,530
triangle called tri projected and tri
630
00:32:12,820 --> 00:32:17,650
projected is where I'm going to put the
631
00:32:14,530 --> 00:32:21,190
result of my matrix multiplication so
632
00:32:17,650 --> 00:32:24,580
I've got the input tri tri projected as
633
00:32:21,190 --> 00:32:26,280
the output and map proj as the matrix
634
00:32:24,580 --> 00:32:28,240
we're going to use in our multiplication
635
00:32:26,280 --> 00:32:30,430
however we can't use the triangle
636
00:32:28,240 --> 00:32:36,880
directly and we need to reference the
637
00:32:30,430 --> 00:32:41,710
vertex inside and I'm going to repeat
638
00:32:36,880 --> 00:32:43,900
this for the three vertices I like the
639
00:32:41,710 --> 00:32:45,940
fact that it's explicit quite a while
640
00:32:43,900 --> 00:32:48,220
ago now I added to the console game
641
00:32:45,940 --> 00:32:50,500
engine the ability to draw a triangle
642
00:32:48,220 --> 00:32:52,750
and this simply draws three lines
643
00:32:50,500 --> 00:32:55,870
between the three coordinates that are
644
00:32:52,750 --> 00:32:57,520
specified using the original draw line
645
00:32:55,870 --> 00:32:59,860
function which has been around since the
646
00:32:57,520 --> 00:33:06,070
beginning this makes drawing a triangle
647
00:32:59,860 --> 00:33:08,950
a little simpler I'm going to take the x
648
00:33:06,070 --> 00:33:10,270
coordinate and we'll do some cut and
649
00:33:08,950 --> 00:33:16,750
paste here just to speed it up a little
650
00:33:10,270 --> 00:33:19,480
bit and the y coordinate of 0.1 I'll do
651
00:33:16,750 --> 00:33:21,130
point two and point three and the final
652
00:33:19,480 --> 00:33:23,700
two arguments and how it appears on the
653
00:33:21,130 --> 00:33:25,870
screen so I want to use solid pixels and
654
00:33:23,700 --> 00:33:31,030
I'm just going to draw everything in
655
00:33:25,870 --> 00:33:32,770
white so let's take a look well I can't
656
00:33:31,030 --> 00:33:35,350
see a cube there but what I can see
657
00:33:32,770 --> 00:33:38,200
right up in the top corner is a single
658
00:33:35,350 --> 00:33:40,540
pixel and in a way this is to be
659
00:33:38,200 --> 00:33:42,580
expected because our projection matrix
660
00:33:40,540 --> 00:33:45,550
has given us results between minus one
661
00:33:42,580 --> 00:33:49,840
and plus one so now we need to scale
662
00:33:45,550 --> 00:33:52,480
that field into the viewing area of the
663
00:33:49,840 --> 00:33:54,310
console screen so the first thing I'm
664
00:33:52,480 --> 00:33:57,250
going to do is take a coordinate and
665
00:33:54,310 --> 00:34:04,150
shift it to between zero and
666
00:33:57,250 --> 00:34:05,200
- I'll do that for both x and y and I
667
00:34:04,150 --> 00:34:06,880
know this is where people will be
668
00:34:05,200 --> 00:34:08,440
screaming at me why are you not making a
669
00:34:06,880 --> 00:34:10,389
special vector class why are you not
670
00:34:08,440 --> 00:34:16,090
using operator overloading and we'll
671
00:34:10,389 --> 00:34:20,950
come to that in later videos so let's do
672
00:34:16,090 --> 00:34:23,349
that for all three points so now it's
673
00:34:20,950 --> 00:34:26,320
between 0 & 2 I want to divide it by 2
674
00:34:23,349 --> 00:34:32,800
and scale it to the appropriate size for
675
00:34:26,320 --> 00:34:38,800
that axis I'll take the X and I'm going
676
00:34:32,800 --> 00:34:43,480
to multiply it by 1/2 times the screen
677
00:34:38,800 --> 00:34:46,480
width and you'll see here I've just done
678
00:34:43,480 --> 00:34:52,060
it for the other two vertices as well so
679
00:34:46,480 --> 00:34:54,700
let's take a look well I can certainly
680
00:34:52,060 --> 00:34:56,980
see what looks to be a cube and some
681
00:34:54,700 --> 00:34:57,400
triangles but something's not quite
682
00:34:56,980 --> 00:35:00,340
right
683
00:34:57,400 --> 00:35:02,650
there's no perspective on this and I'm
684
00:35:00,340 --> 00:35:04,960
not really sure of the orientation so
685
00:35:02,650 --> 00:35:07,930
what can be going wrong here well simply
686
00:35:04,960 --> 00:35:10,119
put our cube has its origin at 0 and our
687
00:35:07,930 --> 00:35:14,320
current viewing to the world is also at
688
00:35:10,119 --> 00:35:16,510
location 0 and so this means our face
689
00:35:14,320 --> 00:35:19,720
for example could very well be inside
690
00:35:16,510 --> 00:35:22,270
the cube at this location that means
691
00:35:19,720 --> 00:35:24,280
some of the cube is behind us and we're
692
00:35:22,270 --> 00:35:27,190
still trying to draw it and this is
693
00:35:24,280 --> 00:35:28,960
undefined so it's not unsurprising that
694
00:35:27,190 --> 00:35:30,790
the result is a little bit useless at
695
00:35:28,960 --> 00:35:33,790
the moment what we need to do is
696
00:35:30,790 --> 00:35:36,700
translate our cube into the world away
697
00:35:33,790 --> 00:35:38,380
from where the camera would be so
698
00:35:36,700 --> 00:35:42,839
instead of projecting the triangle
699
00:35:38,380 --> 00:35:42,839
directly I want to translate it first
700
00:35:45,210 --> 00:35:50,740
and this is easily done for translation
701
00:35:48,040 --> 00:35:54,010
and all we want to do is offset the
702
00:35:50,740 --> 00:35:56,440
triangle in the z-axis into the screen
703
00:35:54,010 --> 00:35:58,720
so we'll add 3 to all of the Zed
704
00:35:56,440 --> 00:36:02,500
components of the triangle into our new
705
00:35:58,720 --> 00:36:04,000
triangle triangle translated so this is
706
00:36:02,500 --> 00:36:06,420
no longer the triangle we wish to
707
00:36:04,000 --> 00:36:06,420
project
708
00:36:08,099 --> 00:36:14,920
let's take a look and see if this has
709
00:36:10,420 --> 00:36:16,749
made it any clearer perfect we've
710
00:36:14,920 --> 00:36:19,690
definitely got some perspective action
711
00:36:16,749 --> 00:36:21,460
going on now but because the scene is
712
00:36:19,690 --> 00:36:23,950
static we can't really get a feel for
713
00:36:21,460 --> 00:36:26,470
what's happening in 3d so I'm not going
714
00:36:23,950 --> 00:36:28,930
to rotate the cube around its X and its
715
00:36:26,470 --> 00:36:30,999
z-axis I'm not going to do the rotations
716
00:36:28,930 --> 00:36:33,160
at the same speed because we'll become a
717
00:36:30,999 --> 00:36:35,200
victim of what's called gimbal lock
718
00:36:33,160 --> 00:36:36,880
so I'll bias the rotations per axis
719
00:36:35,200 --> 00:36:38,769
differently I'm going to add two more
720
00:36:36,880 --> 00:36:42,339
matrices that can perform the rotation
721
00:36:38,769 --> 00:36:44,259
transform around a specific axis now I'm
722
00:36:42,339 --> 00:36:45,880
pretty sure the mathematicians out there
723
00:36:44,259 --> 00:36:47,740
will start screaming while surely we can
724
00:36:45,880 --> 00:36:50,470
combine all of these matrices with
725
00:36:47,740 --> 00:36:53,200
matrix multiplications and we can but
726
00:36:50,470 --> 00:36:54,789
I'm not going to do in this video to
727
00:36:53,200 --> 00:36:56,380
give the impression that something is
728
00:36:54,789 --> 00:36:58,420
rotating I'm going to need an angle
729
00:36:56,380 --> 00:37:00,460
value that changes over time so I'm
730
00:36:58,420 --> 00:37:03,309
going to accumulate the elapsed time in
731
00:37:00,460 --> 00:37:05,950
a variable called F theta and I'm going
732
00:37:03,309 --> 00:37:08,230
to hard-code two rotation matrices one
733
00:37:05,950 --> 00:37:10,720
for the Zed axis and one for the x axis
734
00:37:08,230 --> 00:37:13,180
you can look these up on Wikipedia it's
735
00:37:10,720 --> 00:37:15,430
fairly standard and they work in quite a
736
00:37:13,180 --> 00:37:18,190
similar way as the rotation matrix that
737
00:37:15,430 --> 00:37:20,230
I derived in the asteroids video since
738
00:37:18,190 --> 00:37:22,299
we're not multiplying matrices just yet
739
00:37:20,230 --> 00:37:24,549
I'm going to need more triangle States
740
00:37:22,299 --> 00:37:27,039
for the intermediate transformations and
741
00:37:24,549 --> 00:37:29,289
I still want my translation to be the
742
00:37:27,039 --> 00:37:31,690
last thing that I do because the order
743
00:37:29,289 --> 00:37:33,880
of transformations is quite important I
744
00:37:31,690 --> 00:37:36,759
want to rotate it around the origin of
745
00:37:33,880 --> 00:37:39,339
the object which is currently 0 0 0 and
746
00:37:36,759 --> 00:37:42,009
then once it's rotated I want to
747
00:37:39,339 --> 00:37:44,920
translate the rotated object further
748
00:37:42,009 --> 00:37:46,660
into the Z plane so taking the original
749
00:37:44,920 --> 00:37:50,950
triangle the first thing I'm going to do
750
00:37:46,660 --> 00:37:53,349
is rotate it in the z axis the second
751
00:37:50,950 --> 00:37:56,349
thing I want to do is rotate it in the x
752
00:37:53,349 --> 00:37:59,349
axis I then want to update my
753
00:37:56,349 --> 00:38:02,380
translation code to use the most
754
00:37:59,349 --> 00:38:06,309
up-to-date triangle so now let's take a
755
00:38:02,380 --> 00:38:08,680
look and immediately I think that's
756
00:38:06,309 --> 00:38:11,079
perfect look at that a perfect cube
757
00:38:08,680 --> 00:38:13,690
projected evenly and nicely onto the
758
00:38:11,079 --> 00:38:17,849
screen rotating smoothly and the
759
00:38:13,690 --> 00:38:17,849
triangles and the faces are very visible
760
00:38:19,930 --> 00:38:25,160
and so that's that for part 1 of this
761
00:38:22,549 --> 00:38:27,349
series in the next part we'll be looking
762
00:38:25,160 --> 00:38:28,819
at how we can control the camera and
763
00:38:27,349 --> 00:38:32,329
we'll also be looking how we can shade
764
00:38:28,819 --> 00:38:33,799
the faces of the object as usual all the
765
00:38:32,329 --> 00:38:36,380
source code is going to be available on
766
00:38:33,799 --> 00:38:38,180
github please join the discourse server
767
00:38:36,380 --> 00:38:39,739
and come and have a discussion if you've
768
00:38:38,180 --> 00:38:41,119
enjoyed this video give me a big thumbs
769
00:38:39,739 --> 00:38:45,339
up please and have a think about
770
00:38:41,119 --> 00:38:45,339
subscribing until next time take care
58934
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.