>>Amanda: Hey, all. I hope
you've had a fantastic week. With its second installment
in the series, The Coalition made
Gears 5 their own, with refined graphics,
new open-world sections, revamped AI, and more. In our lengthy interview,
the Vancouver, Canada, based studio shares how they
delivered best-in-class effects and achieved some of the highest-fidelity
character models seen in game, all while achieving 4K
60 fps on the Xbox One X. In addition to the interview,
we have included their Visual Technology
of Gears 5 presentation
from Unreal Dev Days. Recently, Microsoft held its
biggest Inside Xbox event yet, and many
Unreal Engine-powered games were featured center stage
at the annual show. There were newly announced games
from Microsoft Studios, Obsidian Entertainment,
and Rare, along with release-date reveals
for highly anticipated titles that include Ninja Theory's
Bleeding Edge and Mojang's
Minecraft Dungeons. To celebrate, we have compiled
a list of fantastic titles that took center stage coupled
with their official trailers and descriptions.
See them all! Unreal Engine 4.24 Preview 3
is now available. Download it today
to get the latest fixes and try out new features, including Landscape tools,
hair and fur features, updated Material Layers,
and many more. Visit the 4.24 Preview
forum thread for a full list of updates, and share your feedback on this
and subsequent releases. Remember that preview builds
are not production ready, so I encourage you to make
a copy of your project for testing. Now over to our
community rock stars who are jumping
in AnswerHub and problem solving with
other developers. Thanks to Everynon, LordStuff,
DDemon, BlueMind Studio, ClockworkOcean, Tuerer,
ThompsonN13, Koraemon, SubDevs,
and Cassio Pantoja. Thank you, all,
so very much. And on over
to our community spotlights, jump into the ultimate
toy sandbox and build the train set
of your dreams with Tracks: The Family Friendly Open
World Train Set Game! Create colorful railway systems,
decorate beautiful towns, transport communicating
passengers, and even ride your own train
in first-person. Check out the game on Steam. Fight for the high ground
in Gun & Buckler, a multiplayer action game
where you, a frog, either fight for rewards
or cooperate to escape the clutches
of the frog-fighting industry. The game features laser guns
and reflective laser shields. Follow their progress on
Hamar Game Collective's website. With aesthetics inspired
by older generations of comics and flash games, Starglades
is a 2.5D platformer that you can demo now. Download their game
from our forums and give Zenrok Studios
your feedback. Thanks for tuning in
for this week's news and community spotlight. >>Victor: Hey,
everyone, and welcome to the Unreal Engine livestream. I'm your host,
Victor Brodin, and with me today I've
a whole slew of smart people that are going to talk about
some very interesting topics. First off, our Principal
Mathematician, David Hill. Welcome to the stream. >>David: Thank you. >>Victor: We also have a Senior
VFX Artist, Bill Kladis, on the stream and our Technical Art Director
for VFX, Wyeth Johnson. >>Wyeth: Hello. >>Victor: Thanks, you all,
for taking the time, coming here to share
your knowledge on a topic that, to some,
can be a little bit foreign and perhaps intimidating.
How did this come to be? >>Bill: I think I would start
by saying David and I -- So I did a GDC
talk about 2 or 3 years ago, and it was aimed at FX artists, actually a very similar
premise of, hey, let's try to be
a little better at math and not be so afraid of it, and realized how we can build
our own tools to be a little smarter
and do, you know -- It was how to solve
really large-scale problems, and I don't even know
how you and I got introduced, but I asked a simple, like -- It was something about vector
squared or something like that and how to notate it
or something, and David, instead of
just sending me a message and just going on his way,
he actually came to my desk with this huge thing of notes
and was like, "So this is this,"
and he is explaining. I was just like,
"Wow, what a" -- "What a generous person,"
you know, to be able to do that. So immediately, you know
I used him as a resource to be able to just improve
my presentation in a few other areas, and afterwards,
you and I were thinking. I was like, "You know,
this is the kind of stuff that's gold for artists
internally, externally. This is something
that we should teach." And then I think
you should take it from here because you were the one
that put us together, and we all kind of went
to have lunch one day. >>Bill: Yeah. I think Wyeth
was talking similar things, so I wanted to get us
all together to talk about these concepts
and see where everybody was, what kind of information
we could deliver that would be really useful. I guess that was
a little while ago, so we got a chance -- >>Bill: Yeah.
That was last year. >>David: -- internally
within Epic. We have given a few courses
to the different artists where we showed them
some of the same Material we'll show today, although this is a slightly
different version of it, and the idea was just
to help level up people. As our tools are getting
more sophisticated, they're getting
more mathematical, and it just helps to know
some of that language so that you can express yourself
as fully as possible with them. >>Wyeth: Yeah, and I think it's
important to express that this isn't a math class. It's an intuition class,
is the way I think about it which is I don't think anybody has to come away
from this conversation with any concrete piece
of knowledge about any of the topics. To me it's more of,
"Oh, I heard that term once," and then you start to,
"Oh, they talked a little bit about a Dot Product,"
and then you start to -- We'll show some visuals,
and maybe you will start to equate some of these terms
with a visual thing, and then the little synapses
will start to fuse, and really it's
just about intuition. And over my career
it has been lots of tiny little a-ha moments,
rather than a, "I'm going to think
about math for 2 weeks and then get smarter." That is now how
this stuff works. It's always like, "Oh, I've
a little problem to solve, so I'm going to find a piece
of intuition that I don't have, and maybe somebody like David
will help us get over the hump, or we'll go deconstruct
one of the content examples, or we'll go look
at the Math Hall," which is this amazing resource
we have. Then you start to just nudge
your knowledge and intuition forward
a little bit, and then maybe when you're thinking
about a different problem, you will have that little spark,
"A-ha! I know how I could
maybe take that idea of comparing two vectors, and I could apply it
to Characters." You know what I mean? So I think intuition generator
is a better way to think of this than like a math seminar,
if that makes sense. >>Victor: Yeah. I think
that sums it up pretty well. >>Wyeth: Yeah. >>Victor: I think whenever you
are ready, we'll get started. >>Bill: Okay.
>>David: Yeah. Should we pop up this stuff,
Wyeth, you have right now,
just this -- >>Wyeth: Yeah. So basically
we just wanted to start with something moving and some context for the first
part of the conversation, and this is
a little simple scene. The point of none
of any of these examples isn't visual fidelity. It's more of just
expressing a subject. The problem that we were kind of
solving here is, "How do you make
something bounce?" And we're not going to go into
all the different pieces of what it takes
to do a collision system. That would be outside the scope
of this conversation, but just thinking about,
"What does it mean for something to bounce off something else
or collide with something?" There are a bunch of topics
that kind of fall out of that that are really fundamental,
rudimentary math topics that might guide people
to some intuition. The first and most obvious one are these arrows here
in the scene, and these are vectors
which are basically directions, and fundamentally, in order to make something
bounce off something else, you compare these directions
to each other, and when certain criteria
is met, maybe you flip a piece of them
or you do a little work to invert the direction
you were traveling, and so this scene basically
shows some balls flying around. This is their velocity,
and their velocity is a vector, and David is going to
talk about vectors if you need
some intuition about that, and then the scene is full. I've just scattered
a little sparse version of them, but the scene,
every little thing that could possibly
be collided with has these vectors
that are facing off of them which we refer to
as the surface normals. And so we're comparing the
velocity vector of these balls to the surface
normal vectors of this world, and when we do that comparison through some actually
shockingly simple math, you come out the other end
with a ball that bounces. And so this is kind of where we
wanted to start the conversation because it expresses
a bunch of interesting things, and then this also will tie,
as we go forward, will tie into actually a whole
bunch of the other things we might talk about later, like distance fields
and gradients, and there is a lot of stuff
buried in this little scene, so we figured this would be a good way
to start the conversation. >>Victor: Nice.
>>Wyeth: You going to grab that? >>David: Oh, sure. Alright.
How do I flip over to the -- >>Wyeth: Just go lower left
to the edge. >>David: Alright.
Great, so I've got probably the most thrilling form
of media presentation, some slides,
but the idea is I just want to highlight
some mathematical concepts. For some of you,
they may be things you know, so it's refreshing
your memory a little bit. For others,
it may be some new stuff, and then for you
it's more of an introduction, so it's not too deep, but we're going to talk
about vectors for a little bit. You saw the vectors that Wyeth
was just showing on those balls. So what is a vector? Well, the best way to think
about a vector is we generally draw it
as a little arrow, but what it really means is it's a direction
and a magnitude. Now, it doesn't have an origin
associated with it in the sense that, "This vector
lives at this place. This vector lives
at another place." That is an additional assignment
we can make if we feel like it, but vectors themselves, these four little green arrows
on the screen, these are all equivalent.
They all have the same length, and they're all pointing
in the same direction, even though I've drawn them
in different places. So if we want to compare vectors
because their location in space is really kind of arbitrary,
actually what we do is, is we'll take two vectors,
like this ball and this little boy
who is running. So the ball has an orange arrow. The little boy has a red one,
and we put them tail to tail, and then we can compare
the angle between them. The simplest way to compare them is something called
a Dot Product, and I'll talk about that
in just a minute. I want to talk a little bit more
just about other things we can do with vectors first. So this is more of
the refresher standpoint of how to picture
a vector addition. So there are different things
we do with vectors. We could add them.
We subtract them. We can transform them, but let's just talk about
adding them for a minute because that's sort of
the basic mechanic. So here I want to add vector
a and vector b. Well, the way I would like you
to picture adding them is you move the tail of one them
to the head of the other, so I'm going to move the tail
to the head of a, and now I'll draw a new vector that goes from their common
vertex out to this new tail, and that's going to be
the vector a plus b. Now, if I've a vector written
out in mathematical form, it's three
different components. It could be x component,
y component, z component if it's in space,
or it could be colors, but if I'm going to add them,
what I just did graphically is identical to just
adding them component-wise. So adding them algebraically
is very easy, but it's nice to have the
geometric concept in your mind attaching one vector
to the other sort of head to tail like that. Now, subtraction is just about
the same as addition. We can have a geometric
form of it. There are two different ways
you can view subtraction. The first is I'm going to draw
an arrow from the one I'm subtracting to the one
who is doing the subtraction. So in this case,
it's a minus b. I'll draw an arrow
from b to a, and I'll relocate him
to the origin this way, and that's the direction
for the guy who is the difference
between a and b. But as you know with
just regular mathematics, one minus three is the the same
thing as one plus minus three, so I could do something similar.
I could say, "I'll just add -b to a, and that should be
the same thing as a minus b, and I can use my addition trick
of go from head to tail where -b is the original vector b but flipped going
the other direction." And the way we subtract them
algebraically, super simple. It's just like the way
we add them. We just do it component-wise, but it has this nice sort of
geometric representation. So I know Wyeth is going to show a little bit more
with reflection vectors here. >>Wyeth: If we're
working in 3D, we're going to use
a Dot Product to give us a comparison
between vectors, and David will get
into the Dot Products, but as a more simple
kind of visual exercise thinking about this problem, why don't we just constrain it
to two dimensions? And if we do that, some things
kind of simplify a little bit, and then we can start to gain
a little bit better intuition. Let me turn this down. There we go.
So what's happening here? I've got my ball incoming,
and this is the velocity vector. What I did is kind
of normalize it just so that it makes it easier
to compare them to this normal. Normally this would be
kind of the length of how fast it's moving
would be associated with this, but for now,
just for ease of comparison, I've just simplified
the problem and said, "This is the direction that the ball
is coming into the surface," and then we have
this surface normal. So this is the direction that's
sticking out of this surface. And so the goal is,
well, this is going to come in. It's basically going to mirror
around this little center point, and I'm going to bounce off
the other direction. So in two dimensions,
what do we do? What kind of work are we doing
here to figure out what this is? So kind of behind
the scenes here, I've hidden a little bit
of a visualization of kind of how you could start to think
about these vectors, and this is really simple stuff, but actually
this little concept here can start to unlock
some important things when you're thinking
about vectors because just as David showed
a minute ago, these are components, right? In 3D you have,
"I'm pointing a little bit in x and a little bit in y
and a little bit in z, and that combination gives me
a direction in that space." So keep that in your mind
when you think of vectors, is it's not just this kind of
monolithic idea of, "That way." Instead, you should always
be thinking of vectors as, "Well, I'm
a little bit over here, a little bit over here
and a little bit up," and take those
three things combined to get me to a direction. So what does that look
like in 2D? Well, it looks like:
Here is how much downward I'm facing
of this incoming vector. And again, vectors
don't have a position, so I'm able to transpose this over here
to think about the problem, and this vector is the
equivalent to this one, okay? So let's think about
this direction here. This is how much of the z
direction that this arrow is in. Alright? And this is how much of the x
direction that this arrow is in, and the combination of these two
guys makes my overall direction. In two dimensions,
this problem is really easy because I can say,
"Well, I've a surface normal that's facing
the other direction. How much of that normal
is facing towards or away from how much my vector
is facing towards or away?" And so this is how much
of my incoming vector is on x, and this is how much
of my comparison is on x. Turns out they're equal which
makes the problem really easy. I just flip this guy.
So now I've said, "I have just exactly
the same amount of me in z, but now I have the negative
amount of me in x." Alright? So I've done a little
mental gymnastics to compare to what I was coming from,
and then I've said, "Well, I see how much of me
is facing in the appropriate direction
to kind of bounce off of." This is a very simple version
of this problem, but I think it starts to unlock
some stuff for people to think about vectors as components,
and that's an important way to start thinking
about this concept. And then this is just a
visualization of that in action with varying random directions. And really all I'm doing
is I'm saying, "Well, I'm comparing myself
to this normal once I reach this plane," and actually
the Dot Product is cool because it would actually
tell me when I reached this plane, and then some other
interesting things that fall out of that,
that David will talk about, and we'll talk
about more later, but when that criteria is met, we just say,
"Well, however much of my vector was going along this axis,
flip it, and here I go." And the same is true if this
little arrow was down here. That would now be on world z,
and I would do the exact, same thing
where I come off this guy. How much of me is in world z?
Let me flip that much. And so hopefully
that starts to give you a little bit of an intuition
for thinking about vectors as these components
of a larger space and not just one idea
of an arrow pointing somewhere. >>David: Yeah, it's cool.
I like that. >>Victor: That's a good
visualization. >>David: Alright. How do I get back to the --
There we go. Great. Alright. So I'll talk
a little bit more about this. So that example was really cool. One of the things that made that
example really straightforward was the fact that the wall
and the ground were aligned either with the x-y plane or they were either horizontal
or vertical. And there it was easy to say, "How much of my vector
is going straight at this wall?" That is the part that's headed
in the x direction, and I want to flip that speed so it's headed
away from the wall at exactly the same speed
that it was going towards it, but maintaining
the up-or-down speed that it had
that was parallel to the wall. So then there's the question, "What happens if my wall
is not aligned horizontally or vertically where
the components of the vectors naturally
are in terms of x, y, and z, but I want to flip a component
that's perpendicular to a wall that's at a funny angle?
What does that mean?" So this is just meant
to generalize what Wyeth was showing,
and it's using a Dot Product, and the idea
is we're going to show you how to reflect around
an arbitrary wall. So I'm going to start off by saying I have something
that's a normalized vector. I've got a unit vector. It's
a unit normal from the wall, and I'll have some velocity. In this case, the unit normal
and the velocity is my vector v, but let's look at
the little triangle that will be on the left-hand
side of your screen. That Dot Product
is something that's great. If I take the Dot Product
of a vector with some arbitrary direction, so you tell me
that you're little n, that's just a direction.
It's got unit length. Then the length of that triangle
down below is v dot n. So that's what I want you
to understand for right now
about the Dot Product, is that if I give you
a direction in terms of a unit vector, I can ask the question
for the other vector, "How much of this other vector
points in that direction?" And it will give me
a number back, and that number will be related to how much of my original
vector points that way. So that's useful.
I've got my original vector. What I really want to do is I want
to flip a component of it. So the first thing
I want to know is how much of my vector
is headed towards this wall, for instance,
that's defined by this normal? So if we look over
on the little triangle I've drawn over
on the right-hand side, I've taken
my original normal vector from my little red vector n,
and now I've scaled him by the amount
that v points in that direction. So now it makes the entire base
of this triangle, so I've scaled up
my initial normal vector so he is now as long
as the side of that triangle. Now we can do something cool. We can say,
"What happens to my vector v if I subtract that new vector?" Well, now I'll get a vector
that just points straight up. What I've done is I've taken
away the component of the vector that was pointing
in the normal direction, and I can go even further. I can say, "What happens
if I want to reflect?" I can take that vector away
one more time, and now it's going to be
pointing in the other direction. It's kind of like
if you have five and you want minus five, you could either just put
a minus sign in front of it, or you could subtract
10 from that, and then you would end up
with minus five. So I've taken
my original vector, and I want to flip
a component of it, so I'm going
to find that component, and I'm going to
subtract it twice, and that flips that component so it will point
in the other direction. So this is one of the really
powerful things with the Dot Product. Now, there are lots of other
things we can do with it, but I think this is
probably enough for right now. I encourage you to learn
a lot about it. It ends up being a bread
and butter of all sorts of tricks
in computer graphics. >>Wyeth: Yeah. It's one of
the three big things. If you were going to pick three,
okay, this is one of the real
meat-and-potatoes ideas here. >>David: Yeah. You'll get a lot
of mileage out of Dot Products. >>Bill: Yeah, that's true.
>>Wyeth: Yes. >>David: So this is meant
to be a teaser, so when you see this,
you'll say later, "Oh, yeah, Dot Products are pretty cool.
They did this thing." Turns out we do
almost everything with them. >>Wyeth: Yeah.
>>David: Bill is going to show you a little bit more
with reflection vectors and having fun with them. >>Bill: Yeah, so let me load
up my example here. So in case any of you watching are getting
a little overwhelmed, I think just
a very quick breakdown: A Dot Product is just comparing
two vectors, how similar they're
and if those vectors, the length,
is just the value of one. It's just 1, .5, 0, right?
You can think of it like that, and it goes from one
to negative one, so the basic concept is we're
just comparing those angles. And to talk about
reflection vectors, just like what Wyeth
talked about and David talked about in their slides,
just think about, "You're throwing
a tennis ball on the ground. Which way is the tennis ball going to bounce right after
it contacts the surface?" So an example
I wanted to put together is something with mirrors. I think this is a really
cool example visually, and it just also reinforced
the idea of reflection vectors. >>Wyeth: And this is great
because it's, unlike my contrived example where everything is beautifully
axis-aligned, this is reliant
on the Dot Product giving you the arbitrary walls
facing arbitrary directions, and this is doing exactly
the same as the simple example, but now it's the general case.
The proof is in the pudding here that this works, basically,
is this example. >>Bill: Yeah, and what's
actually really important, too, and I want to stress this, and we stressed this when we did
our talks internally here, is you don't have to do
all this math shorthand. Alright? We have functions
everywhere, in Blueprints, in the Material Editor
and [inaudible] like that. As long as you understand
what it does and what data to put into it,
it's useful, right? Let the computer
do the work for you. So I've got
a little transmitter that's transmitting a laser. It's really tricky to click on.
So what it's doing is it's tracing from its origin
against the vector, and we'll actually talk
about transforms here shortly because it's related
to this example, but we're just going to
keep it simple to say that it's just shooting a laser
on a vector forward, so 2,000 units
or 1,000 units on x, and once we collide,
we get a hit result. So we can see
that we're scaling the laser, but I only want to be
able to isolate it to different surfaces. So on the Blueprint,
I made sure to check and say, "If I hit a mirror, now I can
turn on the other mirror's laser and then calculate
the reflection vector." So as I turn it here, you can see that
it's spawning a new one, and then it will just keep
going to infinity up until it traces to itself which I just had to tell it
to stop because it was causing problems.
But you can see. This is a reflection vector
in a real-world example being shown in the Editor, and this is all done
on the CPU in the Blueprint, not just on a Take function,
right? And there is -- >>David: It's super fun.
>>Bill: Yeah. We could go into the meat
and potatoes of it later, but all we're really doing is:
We trace. We get that hit result which is
going to give us things like, "Where did that trace end
in world space? What was the surface normal
of the hit result?" So then I could start
doing things like here was my directional vector that
I was going along with my laser, and this was the surface
normal vector that I hit and then returned
the reflection vector, and then I can transform
that to spawn a new one. So that's really it,
just kind of fun to watch. We'll go ahead
and release this. >>Wyeth: Yeah,
it's a fun example. >>Bill: We'll release this
to the public, too, so you guys can play around
and learn with this if you would like at home,
so that's it from me. >>Victor: That's awesome.
So no infinity lasers? >>Bill: Alright. I did this pretty quick,
so I saw the problem happen. I was like, "I could make this
go to infinity, but I'm just going to tell it
to stop if it reflects back to itself
to make this a little easier." >>David: Alright. I was going to talk very briefly
about transforms because they're something
that come up quite often, and in this case, I have a little cartoon
there on the left-hand side. I've got some initial vector, a, and I've a Matrix, capital M,
and that's my transform. I'm going to talk
a little bit about what it means to transform it, and usually when we do
transform, we can transform vectors
in lots of ways. Sometimes we stretch them out.
Sometimes we scale them. We can scale and stretch
and rotate them, but the thing
we do most often is, we'll just transform them
from one coordinate system to another coordinate system.
Usually these coordinate systems are orthogonal
coordinate systems like X and Y
at right angles to each other, and that's sort of our bread
and butter, is, I'll have a vector that's expressed
in terms of one local basis, one little X, Y, and Z,
and I'll want to talk about that in terms of another
local basis that I need to translate
from one to another. So when I have a vector,
as Wyeth mentioned earlier, I really have -- In this case,
it's two components. It's a little 2D vector. How far do I go on X?
How far do I go on Y? And I'm now drawing these funny
little green lines here. Now, my new basis,
my other coordinate system, I'm going to just pretend is a rotated version
of the first one. So the new X axis
is down a few degrees, and the new Y axis is rotated
over a few degrees as well, and when I'm
transforming a vector, all I'm really asking
to do is to -- In this case,
I want to just re-express it, my original vector, in terms
of this new coordinate system. So that means it will be,
"How much in the new X axis do I go, and how much in the new Y axis
do I go?" So here, originally, it was a little bit of Y
and a lot of X, and now it's
a little more balanced. With my new coordinate system, if I wanted
to talk about this vector a, I'll say that it's one unit
of X and one unit of Y, and let me copy it over
to this other side of the page. So it looks like that,
and I'll go ahead and rotate this back
so the coordinate system is aligned
horizontally and vertically. So in this other space,
in this new system, my new coordinate system
on the right-hand side, my vector looks like it
is rotated. It's not pointing mostly
in the X axis like it was with the other one. So that's also really secretly
how we do things like rotations, is, we'll just say,
"Oh, let's look at this in the terms of this
rotated coordinate system, and it will make my vector
look like it's turned", but a lot of what we do is,
we'll just have a matrix that will encapsulate all this
information of how to go from one set of axes
to another set of axes. "How can I express this vector
in the language of my local space
versus world space or camera space
or something like that?" Under the hood, secretly,
a lot of the things, the mechanics of that matrix
operating on a vector, are related to Dot Product sill, again,
another plug for going back and learning Dot Product
at some point. >>Wyeth: Yeah, it's really
the same idea under the hood. How much of me
is pointing in any -- >>David: In this direction,
a different -- >>Wyeth: -- different direction
in one system, and how much of me is pointing
in a different system, and Dot Products tell you that. >>David: That's right,
so under the hood, that ended up
being intimately related, but now we've got -- I apologize.
We are leaving the cool slides to just show examples
for a little while. >>Bill: So, and correct me
if I'm wrong, David, just so I make sure
I remember this right, just to demystify
the Dot Product, it is literally
just multiplying components and anything in them, right? >>David: It is, yep.
>>Bill: So if you're at home, and you're like, "Dot Product
sounds really advanced," it's like everything -- All of these advanced topics
just break down into addition and subtraction
and multiplication. It's always a small thing. >>David: Multiply first component
times the first component plus the second component
times the second component, third component times
the third component. Just add them together, so it's super simple
to actually calculate. So that's the great part. >>Bill: So in this quick
example, I thought it was going
to be good to show just a quick visualization
to be able to get a grasp about the difference between
world space and local space, and we can think in the world,
I think even if I just hit G, right, we can see the world grid
that the Editor puts for us. Right, this is world space
or world-aligned coordinates, right,
so everything has a position, an X and Y and Z in the world.
So if we move things around, we can get those
different components, but to help visualize this,
I put a Material on here that's world-aligned to give you a sense
of what world space means, right, so even though
the cube is moving, the Material stays fixed
regardless of position, rotation, or scale, and to help solidify
that even more, I think a good example is, if you duplicate the object,
right, you can see that the grids completely
overlap each other perfectly because this Material is mapped
to world space or world unit, so basically, it takes
this pixel that it's rendering, and it says,
"Okay, what is your world position
on X, Y, and Z?" and go ahead
and map it to these. When we think about things
in local space, it's kind of more what we would
expect with geometry in here where as the object rotates, it's actually transforming that
world position into local space. So that's basically like
my space versus your space, is the way you can kind of think
of world space and local space. The other quick visualizer here
that I put in here is the little X, Y, Z widgets. So you can see
on the world-space examples, even though I'm rotating it, this little Z always
stays up, right? This little Y points down
to a positive Y and positive X for the red one.
But in local space, right, this is also rotating
with the object. So we could show
the Material later on, but there is just very,
very simple transform nodes that just do all this
for you, right? You could do the math yourself
if you want, or, like I said before,
there is a lot of things that the computer
can do for you, so -- >>Wyeth: I wanted to add
one more piece of intuition to this good visualization, too.
If we had a details panel open, and you clicked one
of these cubes, if you thought about this cube
in world space, its position in that details
panel is the position, the vector from the world zero. Unreal has this concept
of this world origin, this center point to the world, and any position,
world-space position, that your little Static Mesh
cube is, is just a vector. It's a line
from that zero center to you, and so when you're typing
in a transform of, "What is my location
of my Static Mesh in Unreal?" you're actually drawing
this arrow in X, Y, and Z. You are drawing this vector
to this thing. When you start to think about
the same object in local space, the center of that object
is your zero. And everything that
is happening from it and transformed to it is happening in relation
to this object, and so it's like you have
a little mini Unreal world moving along for the ride
with this local-space object. And so I think that's
a useful piece of intuition when you start thinking about transforming things
into different spaces, is remembering that there's
just a magical secret vector drawing from the center
of the Unreal world to any of your objects
in world space, and in local space,
that origin sits at the center of the thing
you're dealing with, and that's a good
intuition thing to generate. >>Victor: Yeah. I could
definitely see a showcase example for that where you could
just hide and show all the arrows
going to all your components. >>Bill: That's going to
get messy really fast. >>Victor: Probably. >>Wyeth: I can't wait.
And now I have -- I just have
a little Niagara example to elucidate this
a little bit further. So I like this visualization
because it starts to just create a little bit of intuition. Basically, what I have here is,
I have my Actor. This is my Actor position, and this Actor has spawned
a particle in world space. So this Niagara system said,
"I'm making a particle. I'm putting it in the world." I put a little printout up here
of the world-space position of this particle, okay, so if I were to find
the origin of the world, I'm 220 units
above the origin in Z. I'm 125 units away
from the origin in X and so on. Now the question becomes, "What do these numbers look like
if I transform this world-space ball's position
into my local-space position?" So now I'm saying, "Instead
of being relative to the world, which is just a big vector
to the world origin, now I'm going to take
this same position, but I'm going to draw
that same vector to me," because I'm the center now.
I'm the nucleus. This is my world,
and so I can visualize that. Let me turn this one off,
turn this one on. So now you see
these numbers have changed, and as I move this -- Well, let me flip back
for a second. When I'm in world space,
no matter what I do with this parent emitter,
these numbers are stable. I'm always locked here.
This is my position. When I switch over
to local space, now you see how I'm relative
to this world center. Imagine this Unreal world
moving with me, and now it starts
to get interesting because you can start
to visualize. I'm just 12 units ahead
of it on X, and as I nudge past it, oh, now
it's actually behind me on X. See my local X axis, okay? So as I move this around
in local space, this guy is very, very relative
to me now, and it gets even
more interesting when you start
to rotate this guy. So I can say, "Watch the blue number here. Watch it change
as I rotate this guy toward it". You can see that
the amount of Z distance is increasing as I rotate, and if I get nice
and close here, I'm not any on Z there. It turns out if I go into 3D,
I'm a little bit offset on Y, so that's why
that number is still big. But if I went right
to the center of this guy, it's zero, zero, zero. So now you're starting
to get intuition for what being in local space
means, which is really powerful. This is a big thing to know. One question people
might have though, is, "Why would I do this?" And the thing to know
about transforms is that transformation
is a language translator. Okay? It basically lets two
things speak the same language, and so if I had some ball flying
around in the world space, but I want my hand, the palm
of my hand to repel that ball, I need to find a way to compare
the direction that my hand is facing to this ball
in a way that's really simple for both of those guys
to understand. I just want to move it in Z. I just want to deal
with one little piece of it. I don't want to do all these
Dot Products and comparisons. So you transform it
into the space in my hand, and now moving away or towards that becomes this
incredibly simple thing. Just add a little Z, right? And so without this little
translator in the middle telling them to speak
the same language, these problems are complicated
and hard, and there is lots of weird math
in between, and if you tell them
to speak the same language, they can talk to each other
really simply. So that's why we do this,
right, and so you literally are going
to see this everywhere, so this is one of these
incredibly fundamental concepts. >>Bill: Yeah.
I'm going to second that. To what Wyeth is saying, it's super powerful, and going back to
the reflection-vector example, that's exactly how we take
a number of saying, "Hey, just trace forward
X amount of units" right, but traces expect
world positions. Where do I start my trace
in the world space, and where do I end my trace
in the world space? So it's just
the intermediate step of, "I'm at this position,
and I'm rotated this way, and what is that local forward
X on 2,000 units?" So that's a perfect use case just from this example
set that we're showing. >>Victor: And there are a couple of functions
in the Blueprint API that allows you
to just flip them, as well. >>Wyeth: Yep, you go back
in the other direction. Oh, I would go one way
to get into this space. I would go the opposite way
to come out, and those are all the Blueprint
Editor, Niagara, the Material Editor,
all have those nodes sitting there in the cradle
waiting to be used. >>Bill: It's a little different.
Materials have a pull-down where you select which space you
want to transform from and to, and Blueprints, there is inverse
transform and transforms. One is for one.
It flipped for the other. And I think the other thing, just to solidify the concept
for viewers at home, is that we mainly deal
with either transforming vectors or transforming positions,
right? Those are the two main things. >>Wyeth: That's a point of a ton
of confusion for people. So it probably is worth
spending a minute on it, but there is --
I don't know. Do you want to kind of approach
it from philosophical side? >>David: Well, yeah, I guess
one of the things I can say is that the way we generally do
our transformations, when we're doing it
with positions, we'll make our transforms
a little bit bigger so they can translate things. So it will do a translation
and then a rotation and a scale or something like that,
and with vectors themselves, because they don't
really have an origin, we don't need
this translational aspect to it. It's simply, "Take this direction and rotate
it to that direction," or, "Take this direction
and scale part of it before you rotate it,"
things like that. So when we do our transform, the underlying mathematics
in things like the Engine are built to be
a little bit more general, so they can do all the rotations
and stuff and translations, and we'll have to tell
the Engine often, "Translate this like
a position," meaning, "I want you to do
the translation as well as the regular rotations
and stuff," or tell it,
"No, this is just a vector, so you don't have to do
an additional translation step." And if I take two points
in space, the difference between them
is a vector. If it take one point
and the origin, the difference
between those is a vector, but a point by itself,
if I just want to transform it with the standard computer
graphics transform, it will -- That computer graphics
transform will also have a translation built into it,
so it's a funny way that we differentiate
between those things, but it's something to be aware
of that people will make
this distinction between, "Am I transforming
a point or a vector?" And what they're really
talking about is, "Do I want to also translate it
somehow or not?" >>Wyeth: Yeah, and usually, the
mental model you have to have when you're thinking
about this is, "Do I've a point in space
that I care about when I'm doing
these comparisons?" because oftentimes, you're
just using this as a tool to be able to compare
two things in a simpler way that's a common way
to think about why you would use
these techniques, and really, the root of it is,
"Can I compare the two of them irrespective of where they live
in the 3D world?" And if you can, you can just
transform the vectors and talk to each other, and if it really,
really matters, my position in 3D space and then my relative position
in 3D space and which direction
I'm facing, you would transform
the full position, and then you would deal with where it's kind of
in that stack. That is kind of
a simplification, but I think that might
guide people toward a little piece
of the intuition for, when they come at the problem,
it's like, "Do I just have a direction
to it that I care about, or do I have a direction and exactly where I am
in the world that I care about?" So that might get the juices
flowing anyways without being too
far down the road. >>Bill: Sometimes I only care
about position data. >>Wyeth: That's true.
>>Bill: It just depends, so I think just laying
the foundation of that, that's an issue
that you have to be able to -- I can't even say the word. >>Wyeth: Compartmentalize,
maybe. >>Bill: Thank you,
tongue-twisted. You got to -- You've got to be able to isolate those concepts. >>Victor: We had a question
that's relevant. Can you get the local-space
reference frame for other Actors without calculating
the difference manually? >>Bill: Repeat that question
one more time. So if you want to get
the local space compared from one to the other,
is that the difference, maybe? >>Victor: So to get the
local space reference frame for other Actors, so I believe what
they're asking is, is there a function in any of the libraries
that allows you to get the local-space reference frame
for another Actor rather than the Actor,
I guess, you're in? >>Wyeth: Yes, we have
Blueprint functions for that. So oftentimes,
what you're doing is -- The real question
you're asking is, "How do I express me
in another guy's space?" And oftentimes, if you're trying
to find commonality there, you would actually ask that.
In Blueprint, you would say, "What is your transform?"
basically. And then you could say
something like, "Give me the inverse of that,"
which kind of gets me from how you got to
where you're back out, if that makes some sense.
We just have Blueprint functions that would ask for the local
transform of an object in any of those
coordinate spaces. We have Blueprint functions
with that stuff, basically. >>David: So often, people will
do things where one object
will have its transform that takes it from a local space
to the world space, so in terms
of my local coordinates, I'll put those as input
and then give me world coordinates as output,
and if two objects have that, then you can actually
concatenate them. Say, "One, I'll
take its information, and I'll turn it
into world information, and then I'll use the inverse
transform for the other guy to go from world
to his local space." So usually, you will take
one person's transform that goes local to world
and then multiply it by somebody else's that goes
from world to his local, and then you have
a new transform that will go from one local space
to another local space. So that's one of the really
cool things about transforms we didn't really get into, is that you could often
multiply them together and make a transform
that goes from where you want to another place. So instead of going
from my local to world and then from world
to your local, you can go directly from
my local to your local space by multiplying
these two transforms together. So that's something
that's pretty fun. >>Victor: I think it's just
the breadth of possibilities of what you can do here
might be a reason why there isn't
a specific function just for
"do this for my Actors," right? >>Bill: Yeah,
and for what it's worth, if it's something
that's common enough, it probably already exists. I would be happy to,
after we're done, we can search around
in Blueprints, too. I know there are
distance functions. You plug two Actors in, and I think that only just
gives you the length, but there might be another one
that is very specific without having to do
an inverse transform and be an Actor location,
but we can help either way. I'm also realizing I didn't show the in-game
example of transforms. Do you mind if I --
>>Wyeth: Oh, yeah. >>Bill: -- hop into Fortnite
really quick? >>Wyeth: Get in there.
>>Bill: This will be very quick. >>Wyeth: It looks cool,
so, yeah, do it. >>Bill: Oh, we got
to move this over here. So this is a real-world example
that I created for Creative Mode inside of Fortnite where we have these little what
are called color-changing cubes, so as you're racing down
the street, you and your team run over these little slabs
of concrete over here, and it changes
to your team color. So we can visualize it here, and you could see wherever
I jump onto the cube itself, it's actually starting its
transition origin at that point. So this is another example
of transforms. There are actually two levels
of transforms going on here, and one thing we did not talk
about is UV space, right? We talked about world
coordinates in local space, but each object actually has a two-dimensional
coordinate system called UV, which is how we map
our Textures, right? So in this case, no matter which
way the object is oriented, wherever I jump and hit it, you can see it
is actually being translated and transformed properly
into UV space, and we just play
a little Material animation. So just wanted to show that
and another real-world example of that in action. >>Wyeth: I love how that looks,
super cool. >>Victor: Yeah. >>Bill: Want to try it, man? >>Wyeth: Yeah, sure. Okay, onward and upward
to the roller coaster. So this is kind of
a topic change, although none of this
is really a topic change because all these things
are kind of the same problems, in the sense that vectors
and comparing them and asking questions about them
is the root of pretty much everything we
are talking about today, or at least trying to figure out
what the vector is that I care about, I guess.
This example I chose because it starts to get
into a couple of topics which normally we wouldn't cover on a lighthearted introduction to simple game development
math concepts, but I think it's actually
perfect for exactly that reason because it will maybe
demystify some stuff, but we're actually going to
get into some calculus, and don't worry. This stuff
is actually deceptively simple. But let's start with the goal.
So what is the goal? So what we have here
is a Niagara emitter which is placing particles
on a spline. The spline, nobody really cares,
but it's a Bezier spline. The only reason I say that's
because at the end of the day, this is a mathematically
generated shape. So I have control points like,
"Where do I start? Which direction
do I take off in," which we would call our tangent.
Which is like, "Oh, I start at this position.
I zoom off in this direction," and then I have an end point,
and then I have another tangent, which is, "Which way
am I coming in?" right? And with those four pieces
of information, the math, it turns out,
is actually shockingly simple. You just interpolate all of those four things
along the little value, and when you do that, instead of
being four lines between them, you get this lovely,
swoopy little curve. It's a satisfying shape, right? There are some questions
to answer about this curve though and some interesting
qualities to it. It's a three-dimensional shape,
but it's dimensionless. It isn't a three-dimensional
thing like a tube, so you have to ask
this question of, "Is there a coordinate system
that has an X, Y, and Z locally along this shape because I want to do something
cool like take these Meshes and actually cause them
to swoop along it," and you can see how
they kind of rotate and twist and torque along that shape. We would basically call this
kind of the local coordinates to each point of this spline.
"How do we find that?" is the question that we would
like to answer, basically. Turns out, the idea behind it
is kind of straightforward, but it takes a little bit
of calculus. >>David: Alright.
>>Wyeth: Pass it on. >>David: Yeah, so we talked
about vectors. Now we're going to talk
a little bit about slope. So what I like about that
last image Wyeth showed is that instead of having just
two different coordinate systems like a world coordinate system and a single local coordinate
system like a camera system with camera forward
and up and left or whatever, you could, at each little point
along that curve, have your own little
coordinate system if you like. And we're going to work
towards that, but first, let's just talk
about something even simpler. We are going to talk about
slope, rate of change, things like that. Here is a really
simple function. It's not a big complicated curve in three-dimensional space. It's just a little curve
in 2D here. Could be a height field, just a slice
of the height field. Could be pretty much
anything you want. So my green line
is some function of X, and I'm going to ask
the question of, "At this particular point,
this value of X, that's my parameter
drawing my line. What is the slope of this
low green line, my function?" And the intuition
that I want you to have is that
if I get really close to a line, as long as it doesn't have
a jump in it or something funky, as long as it's a nice, smooth line you drew,
if I get close enough, it's going to look like
a straight line. And with straight lines,
if I asked you, "What is the slope
of a straight line?" well, you know how to do that. That is just the rise
over the run, and wherever you calculate this
on a straight line, you will get the same slope. So if we take that back
to our little curve, I'll say, "I'm just going to pretend
your curve is a straight line." I'm going to sample it
at two different points, and you see I compute the rise, how much my function has gone up
between those two points, and the run, how far apart
those two points were on NX. So I'm going to calculate it
at X and X plus a little delta X. Now, delta X will be my run,
how far over I've gone, and the difference
in the function will be my rise. So that's my good approximation
for the slope because I just said
I'm calling it a straight line, and as you make the distance
between these two sample points X and X plus DX,
makes those closer together if you make
that DX smaller and smaller. Well, then you're zooming
in more and more on the curve, and the curve is getting to look
a lot more like a straight line, so it will get more
and more accurate. And if that line
was not height, let's just say it was the distance
of a ball from a wall. I'm throwing a ball away
from me or something like that. Instead of slope,
I could say that this is speed. It's how far did it travel,
distance, divided by time, the time that it traveled.
So the speed and slope in this case
are really just the same thing. I'm evaluating that function
a little bit later. I'm evaluating it now
and dividing by how long it took.
So that's rate of change. Now, what we're
really doing is, we're just talking about
something called derivative, which is calculus. This is what they call
the derivative operator, and "operator" just means
it's going to take a function, and it's going to give you back
another function, and we're taking in function F, and it's going to tell you
the slope of F. It uses these two Ds. One is the change
or the difference in F, and the other is the difference
in the input that I put in. So it's just what we were
talking about before. It's just computing that slope,
and it's, in analytic case, it's when the little run gets very, very, very small,
as small as you can make it. Now, often,
you will just have functions. You won't have a nice
smooth function. I won't tell you the function
is X-cubed or something. You will just have data points. And there,
you won't have the option to make that little run smaller. You can just sample your two
different points in space and compute
a derivative that way. But let's take this idea
a little further. So here is a curve in space. This is meant to be a curve
in three-dimensional space, and I'm going to pretend
that it's really a path and a little particle,
my little smiley face there. Pretty cool, huh?
He travels along this curve. >>Bill: Told you,
the Bob Ross of math. >>David: So he starts there,
and at a later time, he has moved up the curve
to this location, so there is a little time
difference there. His position now instead
of just being a single value, it's three values. It's an X value, a Y value,
and a Z value. So I can subtract the two, and I can make a little vector
that goes between them, and that vector just points
from one smiley face to the other one,
and I could say, "Well, if I divide it
by the time it took it to get from one point
to the other, that's how fast
that little guy was traveling." And it's approximating the
actual derivative at that point. But what is cool about it's,
if this approximation, that little delta T,
the distance that he traveled is very small,
then the vector I get is going to be
a perfect tangent to the curve. You can see when they're
pretty far apart, it's not such a good
approximation to the tangent, but as they get closer
and closer together, it's going to become
the tangent to the curve. >>Wyeth: And the tangent being
kind of the forward direction along the curve,
just to clarify. >>David: That's right, yes.
Yeah, thank you. So what we really want
to get is, I would like to get
a little local basis, and I want to get a forward
direction that he is traveling, and I want to get two directions that are
at right angles to that. That would give me a teeny
little local coordinate system. So this is starting to feel
a little bit like physics. So I said that the velocity was
the rate of change and position. It was my little delta
into position. So now let's take
our little guy again. He is traveling with
some velocity in that direction. It's going to take him up
to the curve, and then a little later, he is going to have
a different velocity. He is turned.
He slowed down at the same time. And I can compare
these two different velocities. I can say,
"Here was his initial velocity. It's pretty big, and it's pointing mostly
to the right on the screen" and then later,
it's pointing much more up, and it's not nearly as big, so there is a difference
in those velocities. That is just how
the velocity has changed, and from even driving a car, that's acceleration,
how I change my velocity, so that's all
we have done right here. So the acceleration
is really the rate of change of our velocity, and it's going to be
a little vector, and that little vector
is going to point. Some will point back against
the original velocity if you're slowing it down. Some will point in the direction
of the velocity if you're accelerating
and speeding it up, but part of that velocity vector is going to have to point
in the direction that's perpendicular
to this direction we're already going
because I'm turning, so some of it's going to point
in a direction. Part of my velocity vector is going to point
in the turning direction, and you can use the Dot Product
to actually pull that piece out. You can say,
"Here is my acceleration vector. Give me the part that isn't in
the direction of my velocity." I won't go
into the details there, but this is an opportunity
for you to say, "I wonder how I can use
the Dot Product to actually do that,"
and that would give me a second vector
that's orthogonal. It's at a right angle
to the first vector. And then if you want
another vector at a right angle to those two, we haven't really
talked about it, but there is a cool trick.
It's called a Cross Product, and it takes two vectors,
and it gives you one that points out the plane
that those two made, so you could do that
to get a third direction. >>Wyeth: That hand thing you did
is what all of us do every time you think about a Cross Product. Just burn that into your mind
because you're like, "Oh, yeah. It just does that.
You get another one." >>Bill: Are you counting still? >>Wyeth: No,
I'm doing Cross Product. >>David: Everybody will point out
their thumb, their forefinger, and then their middle finger, and then it ends up being
a little local x, y, and z coordinate system, and they will call
the thumb as maybe x. The index finger is y, and then z
is their middle finger. [LAUGHTER] But Bill was going to show
some examples of derivatives. So derivatives were what
we were just talking about where I just take the difference
in things and divide by -- >>Victor: Before we pass off, we have a small
microphone problem, so we're just going to take
a couple minutes to fix that. We'll all be right back. >>David: Okay. >>Victor: Yeah. Alright.
I think we're back. We fixed the problem.
We can now all hear David -- >>David: Okay. Good. >>Victor: -- as well as possible.
Alright. Over to Bill. >>Bill: So to re-emphasize
what David just said, again bringing it down
to its simplest element and idea is that we're really
just calculating differences, and Wyeth's example and David's slide of calculating
along a spine and establishing a tangent
and so forth are perfectly good use cases,
and we do this very frequently, but I wanted to show an example
that's of the same concept with but
with a different nature, and that's with image
techniques or using imagine data to be able
to calculate differences. So again, I'm using
the examples from Creative Mode. This is all free to play, so creative mode is Fortnite's
little side-shot mode where you can actually
kind of be a game developer, and we have all these
different devices and props, and you can make your own games,
and in the menu, we have got things
that are called Camera Filters. If you're familiar
with Post Process Materials, that's actually what we're
using inside the Editor, and it's probably worth
actually explaining really quickly what
a Post Process Material is. You can imagine
the game is rendering -- The Engine is rending an image
that goes to the user. We actually give them
an extra step to be able to say, "Let us make adjustments
to those images," so it's like taking
an image in Photoshop, and you can blast colors. You can clamp ranges,
whatever you want to do, right? That is basically what
a Post Process Material is. So I had the idea -- I'm a huge fan
of '80s synthwave and stuff like that, the new retro wave of music
that's come out, and I was like,
"We should make a retro filter." So we actually call it Retro,
and it's super obnoxious, hopefully in
the best possible way, but it outlines the character. We can see the wire frame on all
of the geometry in the world, right,
and we have to start thinking of how to approach
this problem technically, right, because you can see the faces
on the geometry are actually faceted now, so it's actually ignoring
any kind of normal information that's on the geometry.
So how do we do this? Oh, blasting away here.
There we go. How do we do this with a game
that's got tens of thousands of Static Meshes
and Skeletal Meshes and stuff? We can't go back
and change those, so a lot of all this done actually with calculus
and with derivatives. So one thing
I thought would be good is actually to show
something like this in Photoshop of just the basics of how we're
establishing this kind of data. It's probably worth actually showing
inside the Editor really quick. If you load the Editor,
you can go over here to where it says
the lighting model or View Mode. You can go
to Buffer Visualizations, and if you do overview,
it's just a very quick overview of the major ones
that are commonly used, so you can think of the Editor
or the Engine is actually rendering multiple passes of all these
different things, and it's kind of compositing
all that data. That is a gross
oversimplifications, but it's putting
all that data together to render the final image,
so you can see actually one that's really important up here
on the top right is World Normal,
so going to back to vectors, this is which way our geometry
at a certain point is facing. >>Wyeth: That is
what I would bounce of off if I were a flying ball. >>Bill: Exactly, yeah.
It's the same data, right? And then there is this one right
down here in the bottom-left. I'm going to just
make it bigger really quick. Is it Scene Depth? There we go. Ignore the stepping out
to infinity, but as you can see, what it's doing here is we're writing
a piece of data per pixel that actually just
tells us distance, right, and we're kind of dividing because you can think of
in the Engine, a value of one is pure white, so if this wasn't divided
or scaled, this would just be like
looking into the sun. It would just be
super bloom city. So we're just taking that data. Just think of dividing
by 1,000 or 2,000, so as things get closer, they actually get
closer to black. The farther away they get, they
actually turn to white, right? So it's just
a distance measurement. So going back to Photoshop
to put this as an example that we can kind of break down
piece by piece, I've taken here -- we use the high-res
screenshot tool that's built into the Editor, and it can actually
write HDR formats. That means it's floating-point,
just like our Engine works, and this is a depth example. This is some props
that we have in Creative Mode, and let's take this depth.
I'm going to duplicate it, and Photoshop has
some basic math operations, and I want to
subtract them, right? So what happens here is,
it's gone completely black because it's evaluating every
pixel and saying 0.38 - 0.38. When you subtract from itself,
it's always going to be zero, but what happens if I slide? Oh, it didn't work.
Hold on one second. Did it work? It might be this. Oh, I'm not on
the right layer, I think. Let us try this one more time. >>Wyeth: Yeah, it keeps
selecting the levels of layer. >>Bill: Alright.
Photoshop isn't cooperating. Sorry. Give me one second. There we go. So what I did here is,
I took this duplicate layer, and I slid it over
exactly 1 pixel, right, and we're actually calculating
a slope to positive x, if you will, and it's returning
that difference value, and that difference, even though
there is negative values here, which Photoshop doesn't
really deal with very well, that difference though
is actually appearing as a grayscale value, so it's actually
just edge detection. I was even watching a video
about how they do license-plate identification
for tolls and stuff like that. To read your license plate,
they do Sobel edge stuff like this,
so this is commonly used. So if we just do this
a couple more times, and I've got it
already done for us, some maybe we go one
to the right, one to the left,
one up and one down, we can see we actually get
a pretty good approximation of where our difference
is in our edges. And again, this isn't
a really good example because of Photoshop not working
well with floating-point values. It's not really like the Editor
or something like Substance, but just doing some quick level
adjustments and so forth, we can actually start
to filter out the noise and get the data that we want,
so how is this data used? So in the Material, we say, "I really want the small,
fine edges." I can bring this back up. I really want
the small differences, and that's what is going
to be our wire frame that's showing up
on the Meshes itself. And I would use that value because it goes from zero
to whatever, and I can clamp it so it's
just in zero to one space, and then we use that
with a lerp. A lerp basically says,
you take an A, and then a B, and then just switch between A
and B based on the zero to one, and then we can isolate
other areas like this wire frame back here and just make that
a different color, right? So even though there is
a lot going on visually, it's just a bunch
of small steps like that of just taking
those differences, remapping them
to different ranges, clamping them, scaling them,
dividing them. One trick I can give
that I used a lot with this is inverse lerping,
which is really useful, so instead
of going from zero to one, you actually give it A and B,
which might be 300 to 1,000, and it remaps 300 to 1,000
to zero-to-one space, so it's really good
for computer-graphic stuff, so that's it for my example. >>David: Alright, cool.
I love the way that looks. >>Wyeth: I don't recall
if we get back to my other spline,
we had a plan. But I could go back
and show the torus, too, if we feel like it. >>David: Oh, yeah.
You want to show it now? >>Wyeth: Yeah,
just because in the context of the rise-over-run conversation, I think this image starts
to make a little more sense. If we're thinking
about your diagram there, and I'm taking
a little step forward, and I'm getting this difference
between the two of them. The direction in between them is that tangent
you're talking about. And then I'm taking a step
from here to here, and this point
and this simple point have a difference
in their direction, and so the tips of these
are subtly different. Well, that's this guy. And then as this guy
curves around, this part of the coordinate
system curves around. There is a subtle difference
in how these guys are facing. Turns out, that's this guy. So you can see how I'm
basically getting a whole bunch of interesting vectors
and coordinate information out of what really amounts
in small changes in a little one-dimension
function, which is, I'm advancing forward
on this little curve in time, so it's kind of a cool trick,
basically, and you're just subtracting
things from each other for the most part. It's really not as crazy
as it sounds, I guess. I also have just another example
of another analytical shape just like the spine
that we saw earlier, and this is basically
working the same way, except now it's
a three-dimensional shape, and if I fly inside, at every
one of these little positions, you can image these as little
vertices of my torus here. You have got these little subtle
changes in difference as the torus starts
to bend around, and each one of these changes
in difference is going to result
in these arrows pointing slightly away
from each other as it advances and marches around the shape, and as you do and you calculate
your little difference between them,
the coordinate system, which is the orientation
of my little local point on this torus, it just kind of falls
out the other end. The math just kind of gracefully
tells you, "Hey, you have this neat function
that makes a torus. Oh, and you just happen to have
all this other information." Mostly, I just think
this is neat. There is a bunch of cool things
when it comes to kind of particle effects
that come out of this too because you imagine that I'm
creating this kind of torus, and what it really is
is this blob of vectors. It's a blob of directions,
so if I wanted to, I could say, "Hey, I'm going to pretend
I'm at this point on the torus, but I'm just a point in space.
I'm a particle. Start flying in the direction
of this red arrow," and then as I start
to fly around, I can keep asking
where I am along the torus, and so I get this vortex
swirling of particles, and that's kind of coming
for free just out of the idea that I made the torus
in the first place, which I think is
just kind of a remarkable thing. It's this happy accident
almost, and it's a result
of these functions being able to be evaluated
in the way that they are, so it's just a bunch
of cool stuff that falls together basically. >>Victor: Did you use the basis
of a Mesh to create the locations
for particles? >>Wyeth: No,
so this is what we call our Torus Location Module
in Niagara. Each of these is a particle. Each of these little gnomons
that you see here is a particle, and we would call it
an analytical function. This is just a piece of math
that says what a torus is. >>Victor: Alright. >>Wyeth: And so you can either
put the particles on the surface of it, or you can put them distributed
throughout the center with whatever density you want, so that's one of the
built-in modules that we had to write
for Niagara artists who wanted to make things
swirl around or to spawn them in a doughnut
or whatever you want to do. The world is your oyster. >>Victor: Yeah. >>Wyeth: But this is
one of the built-in behaviors, and it is math
making a torus, basically. >>Victor: Awesome. >>Wyeth: And that's
the beauty of it is, since math made the torus,
math gives us all these other things
on the torus kind of for free, so that's why it works,
basically. >>Victor: That's great. >>David: Alright. Okay. So I was going to talk
a little bit more about slopes, so what Bill showed you
a little while ago was the thing with the images
where he slid it off by a pixel in one direction or a pixel
in the other direction, so this image is really
a function of two variables: a function of x and y or u
and v or something like that. And the question is, "Alright.
I know how to compute the slope of a function
of one variable at my curve, and I knew how
to compute its slope. What does it mean
if I've two variables?" Well, it's just
what Bill showed you. I can compute the slope
in one variable, in x, and I can compute the slope
in the other variable, in y. I've got two pictures. One is a nice little
height field, and on the height field,
I've colored it so that all the heights that are at the same elevation
share the same band, the little color
that goes around, so contour, but then the other height field,
I've drawn a cross on it and a little x
and y-coordinate system, and I'm just saying, "I could ask right at the center
of that coordinate system what the slope
is if you only travel in x, and what is the slope
if I only travel in y?" And that's like what Bill was doing when he
was offsetting his pixels, and what you're doing
at this case is actually called
a partial derivative. It's just like doing
a regular derivative, but we give it
a different notation. A regular derivative function,
just one variable, gets this hard d, and if I'm doing
a partial derivative, it means I'm going to look,
in this case, to my left and right in x, and I'm only evaluating it
in that sense. I'm freezing y, and I'm going to
look to the left and right in x, but that's all really
a partial derivative means. It means I'm differentiating.
I'm taking a derivative. I'm looking at the slope if I only travel
in one direction of many possible directions
I can go. And Wyeth was going to show us
something cool before we -- >>Wyeth: Before we move on.
>>David: Before me move on. Before I show you
something cool. >>Wyeth: So I made a little
thing to help you think about why what David just said
was relevant basically, and the thing that he will get
to in more detail is this idea that you have got
this direction, this slope, this height field,
which is a scaler. It's a single value. It's just a number,
but buried in that number, if you look at it
the right way, are directions. There is a vector buried
in this number, and if you're working
in a 3D coordinate space, those vectors are 3D,
three-dimensional things that are encoded in this little
one-dimensional idea, and that's pretty cool,
and a whole bunch of the stuff that we do in kind of modern
computer graphics falls out of this. One of the ones
that you're going to hear a lot is this term signed distance field
or distance field. They have become ubiquitous
in computer graphics because they're awesome.
They are cheap to evaluate, and they can combine together
in interesting, easy ways, and there is just
a million reasons why distance fields are awesome, but what they are is if you
have a point in space -- So let's say I've got
my little Albert Einstein here. I've got a point on Albert. A distance field
would basically just say, from any other point
out here in the world or even inside
of Albert's brain -- That would be an
interesting place to live -- It's going to say,
"How far away am I?" And that's a distance field. How far away
from this point am I? And it's just a single number
that encodes. "I'm 33 units away, sir,"
and you're like, "Great. Thanks.
Good information." If you're a signed
distance field -- You guys might hear that term --
All that means is, is that if I go inside,
that number is negative. That is the only thing
that it means, so if somebody says,
"Oh, I'm working with SDFs," that sounds like a fancy thing.
It's a signed distance field, which is a single number
that can be negative, okay? I made a little point cloud to visualize
the inside of Albert's head, and basically,
you can see on the surface, that distance field
would be zero, okay? So wherever
this kind of function we would evaluate to say, like the distance function,
how far away am I? Wherever that is zero,
that's the surface. So everywhere on Albert,
the function is zero, and then as I get further away
out or in, that number starts to increase
by the distance, so it's this really,
really simple idea. What is cool about it, though,
is what David will show you why this works and how this
works, but what is cool about that is this little guy
encodes direction in it kind of magically via this
little partial differential -- >>David: Derivatives.
>>Wyeth: -- derivatives. Thank you. You take these
little derivatives, and it encodes these directions,
so I visualize them. I basically put particles
at zero, which means I put
all those particles right at the zero point
on Albert where the function evaluates
at zero, and I've then pulled out
of that little field, what we call the gradient, and that's basically
a direction. I flipped it so that you can kind of
visualize it a little better, but basically
what this would be is, if I'm at a point
on the surface, if I move away from it,
that little field would say, "How far away am I, and which direction would
I've to go to get back to it, the closest point to me on it?"
basically, and so if I went in, those arrows would kind of point
inward toward Albert's head, and as I fly out here, those are
pointing the other direction, so there is like lovely
kind of blob of gradients, these directions, that are
encoded in this distance field, and then I'll just give you
a little preview of the kind of fun things
we can do with this knowledge. All of this here falls out
of comparing vectors just like we have been doing
this whole time, got some Dot Products
and some other things going on, and then there is
one little extra thing, which is the magic of pulling this gradient
out of this distance field, which David will talk about,
and we also happen to get some of this motion
with Cross Product, as well, which remember
your little hand thing. We basically need
to get ourselves a vector which is pointing away
from that surface, and so some Dot Products,
a Cross Product, and this distance field
create these orbs which roll around
poor Albert's head, and this is all done with
the built-in nodes in Niagara, so it's
kind of a fun visualization. >>David: I'm glad they were
little orbs instead of ants. That would be too creepy. >>Wyeth: We tried something
like that. It was really creepy. So leave it for another day. >>Bill: Go back to your slides?
>>David: Yeah. Alright. That was Wyeth's cool example, so I'm going to talk
about gradient, which is a generalization
of slope, and why it's important
and why it's really useful, but the first thing
I'm going to say is, it's just
a generalization of slope. We have already
got some notation. It's our derivative notation,
a d, f, dx, and this is gradient. The notation for gradient
is this funny, upside-down triangle.
It's called nabla, but everybody
just calls it grad. Nabla is pretty fun.
I was really curious. Where does that name come from? And one of
the earlier practitioners of differential calculus decided
that it looked like a harp, so nabla is some
Hellenistic Greek. It means harp. But for us,
it means gradient, and it's
an upside-down triangle. And it generalizes
the idea of slope, and what do I mean by
generalizes the idea of slope? It works on functions
that are more than one variable, so multiple variables, and will give us someone idea
of a slope for it. Well, here is a height field, and again,
I've drawn these bands. All those bands are at the
elevation in my height field, but if I give you
a height field, you could try to
figure out which way -- I tell you're at a certain
location on this mountain. You could figure out
which way is downhill, even though the height filed is just a scaler function
of x and y. You could use that
to figure out which way do I've to go to go downhill
or to go most uphill? So what the gradient does is, it tells you in the x
and y space which way you have to go to go
in the most uphill direction, and if you know
that at a local -- If you zoom in close enough
to a height field like this, the surface instead
looking curved, just like with our curve. If I got close enough, it looked
like a little straight line. Well, if you really zoomed
in a lot on this surface, it would start to look like
little flat patches of ground, and each little flat patch
of ground would have a single direction
that was most uphill. They are not horizontally flat. They are just like
shingles on a roof. So I want you to think
about height fields. If I get really close, they kind of look
like roof shingles, and you could tell me which way
this little roof shingle is pointing to go straight up, and then you could also say
on this little flat area, if I go diagonally,
what slope would I experience? So the gradient,
it turns out it's a vector. We write them as vectors,
and the way we compute them is, we take the derivative,
if it's a 2D function, in the x direction
and the y direction, and that makes
a little arrow for us. I'll show you in a second
what that looks like. It points in the most direction
you have to go to really go uphill,
and if you have a gradient, and you take that product
with itself and the square root, you will end up
with the length of it, but that would actually tell you
what the slope is if I traveled in that most uphill direction.
But here is something. Well, I wouldn't say
the other image was supercool, but this one might be
a little less so. But on the left-hand side,
there is my little mountain. Again, I've colored it so you can see the different
levels of elevation, and then down on the ground,
projected down beneath it, those are the curves
in the x-y space, but if I stay on those curves,
I don't go up or downhill. And then I've copied
that little x-y space over into this other image
on the right, and if you just take any point
in x-y, it will have a corresponding c,
a corresponding height, but if you compute the gradient
of any of those points, it will be
pointing perpendicular to the lines
of constant elevation. So if I just compute
these two partial derivatives, I'll take f and I'll sample
it moving left and right in x, and I'll take f and I'll sample it moving up
and down in y, and I'll get a little vector, and that little vector is going
to point in the direction that I would travel
to really go uphill. >>Wyeth: And imagine
Einstein's head is in the middle of that swirl. >>David: And you could
also use it the other way. You could say, "That is
the most uphill direction, so I'm going to go
exactly the other direction if I want to go down." So here is another example.
This is 3D. So instead of Einstein,
this is just some green guy, and what I've drawn
next to him is, I've drawn these different
sheets wrapping around him. Each of these sheets, if you're
on one of those sheets and you stay on those sheets, you're at always the same
distance from this head, so anywhere
on one of those sheets, you could say,
"If I stay on the sheet, I'm not going
to get any closer, and I'm not going to get any
further from the head." The point that I'm closest
to changes. I could be on the sheet
near his nose, and that's the tip of his nose
I'm closest too. I can move around to his ear, but I'm always the same
distance from the skin, the closest distance,
so each of those surface, they call them an isocontour,
isosurface. Iso just means same. Here it's the same distance.
So that's my function. I'm going to say my function
is the distance from his head, the shortest distance,
and I can compute its gradient. Just like Wyeth showed
you before, it corresponds to a bunch
of little arrows, and these little arrows
are pointing in the direction that's the most
uphill direction. And by uphill, I mean increases the distance
the most the quickest. So if I take one
of those little arrows, and I'm on the outer sheet,
and I go in that direction, then my distance from my head
will increase the fastest. Or I could say I'm going to go in
exactly the opposite direction, and that will tell me
what direction do I have to go to get straight
to this guy's skin as fast as possible.
And with a distance field, it's really cool
because I know two things. I've computed this gradient,
these little arrows, and I also already know
how far I'm. So if I on the third sheet
out, I know I'm -- Maybe the sheets
are each a centimeter. I'm 3 centimeters,
and I also know the direction I've to travel
to get to the skin, so I can take
my current position. I can take the opposite
of the gradient. It will point at the skin and move in that direction
3 centimeters, and I should be right
on the skin again. >>Wyeth: And that's exactly
in my examples swirling around on Einstein, the first thing I do
is spawn a particle anywhere, and then I just ask for the
gradient and how far away I am, and it just snaps
perfectly right to his face because we have those
two pieces of information, so that's the very first thing
that I do whenever I create a particle
in that sim. >>Bill: Can you honestly call
that transferring it to the distance field space,
then? Is that term ever used? >>David: People will call it, something like this
where you snap to the face, the closest-point transform. >>Bill: Okay.
>>David: I have a point in space, and I'm going to transform it
to the closest point on whatever this object is. But that's really
the sort of stuff I think we wanted to cover
for the most part today. First we talked a little bit
about vectors, and we talked about
functions and slope, and then we brought it back to how these slopes
can become vectors again, and they can be,
at every step along the way, very important tricks
for us to play with them. >>Victor: They did ask
if you could define derivative. >>David: Define the derivative?
Sure. Let me see. If I go back in the slide
a little bit, I think -- >>Victor: We had it there
at some point. >>David: Yeah. Here is the slide,
so if I have a function f, its derivative is really
its slope at a certain point, so you tell me a point,
and I will compute its slope, and I'll locally approximate
my function by a little straight line,
like we did a little earlier. I'll show you
the earlier slide, kind of like this,
a little straight line. I'll evaluate it further
and closer and divide by the distance in between.
It was this rise over run. In this case,
distance over time, and that's my definition
of a derivative. It's going to be something that
takes a function and a position and will give you back
another value, and the value
is just the local slope, and in a more
mathematical definition, it's the limit as the run part
gets smaller and smaller, so like two little sample points
get closer and closer together. But that's just all
the derivative is in this case. It's just a local slope
of the function. >>Wyeth: And
intuition-wise, almost every time we talk about this, we have the little spline, or we have this distance field
that's living in a 3D coordinate system,
and you want to figure out which direction
is encoded magically in there. Almost every time
we deal with this, and it's exactly true of Bill's
screen space example as well, we're just moving forward
a little bit, moving backward a little bit. Get the difference
between those two things, and this stuff
kind of falls out of it, and when you want your
three-dimensional vector to fall out of this single
scaler field, this single value, you're basically doing
that little comparison in all three
of those directions, and you're getting
how much of me is pointing
in each one of those, and together, those three pieces
of information will make a 3D vector,
or in the case of 2D, I go a little bit right
and left, a little bit up and down, and then a 2D vector
falls out of that, so I think it's useful
to have this visualization of seeing it on the graph and understanding
the kind of mathematical piece and seeing the symbols,
the mathematical symbols, getting comfortable with what is
that little grab triangle, and what is this D,
partial derivative thing. It's nice. Even if you don't remember,
I think it's fine. You just start to build them
into your intuition, but oftentimes, the equally
important thing to remember is that often we're
just talking about moving around
a little bit in a bunch, in however many directions
our coordinate system is and asking for those
little differences between them, and that's --
Really, that's the trick, I guess,
would be the way to say it. It's so simple
when you put it that way, which is why I think
this stuff is kind of neat. It demystifies it.
It did for me anyway. It seemed impossible to me. We are going to calculate
partial derivatives of some calculus
something or other, and it's like,
"What" and then, "No, no, no. I'm just going to subtract
a couple things," and you're like, "Oh, oh,
and that gets me a direction." "Yeah." It's kind of neat.
I just think that's cool. >>David: Yeah. I guess another
way to think about is, it's how much does
my function change if I change
the input a teeny bit, so if I'm at this point and I change
my input just a little bit, how much does
my function change, and I'm going to turn that
into a fraction, how much my function
changed divided by how much my input changed, so my function doesn't change
at all, I get zero out. If it changes a lot, I'll
probably get a big number out. >>Victor: Alright. We have had
a few questions come in. Some of them a little bit
more general, but I think it definitely
applies to the topic. I think I've seen quaternions mentioned
about five times in -- >>Wyeth: Hoo, boy. >>Victor: -- five times in chat,
so one of the questions was, "Do we need to
understand quaternions when we're using Unreal Engine? >>Wyeth: Alright. I got this.
The answer is pretty much no. I use them every day
because we use them as the bones of our Mesh orientation,
and rotation work in Niagara, so when you have a Mesh particle and it spins around some world
or local coordinate system or in its own Mesh particle
space, we use coordinates -- quaternions to represent
that rotation. Will you ever really
understand mathematically what is going on
with quaternions? Probably not. Most humans won't,
and I think that's fine. There is a piece of it if you
wanted to go and start reading. If you just talk about -- maybe watch a Khan Academy video
on complex numbers. That is the first step toward
understanding quaternions, but that's not
even important right now. Don't even worry about that. Here is what a quaternion
is to demystify it a little bit. It's a direction,
and you spin around it, so I've got an orange. I stick a pencil through
the orange, and I twist it. That is a quaternion in its most
fundamental sense, right, and please clarify if you -- >>David: No, that's perfect. >>Wyeth: -- think there is more
I should say, but to me, that's
the most foundational way that you could understand
a quaternion is stick a pencil
through an orange and spin it, and the quaternion encodes which direction the pencil
is going in world space or whatever
and how much spin happened, and there is a bunch
of really weird stuff buried in quaternions, and why they work
is magical and cool, but you don't have to know
any of that stuff. You just have to know
what it's that it's encoding. I will say though that it's
almost impossible for a human to type in a quaternion
to make a rotation. There is way too much
going on under the hood of deconstructed trig functions
and half angles, and there is a bunch
of strange things happening, so a human would not ever be
expected to type in a quaternion
to rotate something. Instead, we would use
a different paradigm like just yaw, pitch,
and roll or whatever, which is exactly
what Unreal does. It abstracts all of that,
but the FTransform in Unreal, the thing that holds rotations, translations,
scales has a quaternion in it, but we don't expose
those to people because they're not
human-parse-able, really. They are if you truly
understand them, but I defy you
to really just sit there and write the quaternion
for some arbitrary rotation. It just doesn't really happen. >>Victor: And you can --
>>Wyeth: But if you could take that intuition away,
I think it would be successful. >>Victor: And you can see
how crazy they can get by just rotating
an objective inside Editor, and you can look at the values and see how they're flipping
between negative 90 or 90, and just I was trying to grasp
that at some point, and just saying, "Why is it doing this"
and it's like, "Oh, because there is a lot more
crazy stuff going on." >>Wyeth: There's interesting things
under the hood happening there, so unless you're really
going to go deep tech art, like writing complex
particle behaviors or something like that, you don't really
have to understand them. Just know that it's
a rotation around an axis. >>David: Yeah. Well, I guess the only thing
I would add, you have different ways
you can represent rotation. Some people do a matrix.
Some people use a quaternion, and quaternions are much better
just for rotations because if you want to blend it
between two of them, that works really well, so if you find yourself
in that position where you want to blend
between different rotations, then a quaternion framework
is a good one to use because they're
always rotations, but if you have
a matrix framework and you want to blend
between rotations, you get stuff that's not
rotations in between them. It's not always good,
so that's it. That would be
the only advance thing I would want to add in there, is that if you start to blend it
between different rotations, it's a good framework to use. >>Wyeth: I guess that's
a really good point. A, they're less information,
so a matrix has a lot of data in it
that comes along for the ride. A quaternion
is a lot more lightweight. It's just four
little float values to encode a bunch
of important information, and like David said too, they really gracefully blend
with each other. You just multiply them together, and they just do
what they're supposed to do. >>Victor: Would an example of
that be the combine-rotators function that exist. >>Wyeth: Yep. I mean, under the
hood, if it's an FTransform
in Unreal, which is our big bucket
container object, which actually is
this interesting beast in and of itself,
but it has a quaternion in it, and that would be
the kind of stuff where under the hood
it would evaluate quaternions and multiply them together
and then spit out the new one. >>Victor: Yeah, because the only
thing you need to think about is the order that you add them, and then it sort does
what you want it to, and you don't really have
to think about it that hard, just sort of get back
to how you use it inside there. >>Wyeth: I think they're fascinating,
but I have a hard time explaining them to anyone else in a complexity
that exceeds what I just did. >>Victor: Next time, we'll --
>>Wyeth: So basically, you know -- >>Victor: We'll have a pencil
and an orange next time. Yeah. >>Wyeth: I'm happy to visualize
the analogy in a screenshot form, but yeah. >>Victor: Let's see here. Can you recommend any good books
or courses on linear algebra? I need to understand
the Dot Product better. Thanks. >>David: Oh. I really love that,
on YouTube, was it 3Brown? >>Wyeth: 3Blue1Brown. >>David: Yeah. That is a great
channel on YouTube. It's the 3Blue1Brown channel, and they have got a nice bit
on Dot Products and a bit on matrix
multiplications, vectors in general,
just beautiful visualizations, so that's something
I would start with. >>Wyeth: Even a soothing voice,
just has it all. >>David: Yeah. >>Bill: Did we include the slide?
>>David: No, we did not. >>Bill: That is maybe something
we can follow up with. We had a slide
from the math for artists class that we did internally that had
that probably five or six other
recommended readings that you could go after. >>Wyeth: Put them on the forum.
>>Victor: Yeah. Perhaps we could
add them to the slide deck and then share that? >>David: Yeah. We could definitely
do something like that. Yeah. We'll add some good
references, starting points. >>Victor: Awesome. Yeah. >>Wyeth: But just for
mathematical learning in general,
3Blue1Brown is awesome. Khan Academy is awesome,
and BetterExplained is awesome. All three of those in very,
very different formats and reasonings are successful. >>Victor: And it can be good
to have several references to find the one
that works for you, right? Even though you have studied
once and maybe did not get it, try to find a different resource
to learn from. >>Wyeth: Some of them are better
for one thing than others. Like the 3Blue1Brown Dot Product
stuff is super awesome, but on BetterExplained, their simple-English
explanation of trig was the greatest trig thing
I've ever read. It was so digestable in a way
that almost none of them are, so it's like
each of these resources has their great points.
You know what I mean? >>Victor: Awesome.
Can you guys talk a little bit about mouse vector. Is there any easy way
to understand it? >>Wyeth: It may be that they are talking
about screen coordinates. >>Victor: I think so. >>Wyeth: Is that kind of of
the reference point? >>Victor: I think so, yeah. >>Wyeth: Yeah, so we do a lot of
work where we would transform
something so that wherever you're
in the world is just relative to where you are compared
to the view into the world, and there is two ways
to think about that. There is the view transform, which gets you
into this kind of -- Imagine the screen is UVs, so it would be like from corner
to corner, zero to one, and that's
this kind of view space, and then if you ever hear
somebody refer to something called clip space, it takes that and just shifts it
so the zero point is in the middle of the screen,
and that's important for a bunch of interesting
rendering reasons. That is how we do
our perfective transform, but also that's kind of cool
to work in that space because now all of
your positions are relative to that center point,
and you can do -- So like right now
we're dabbling in some lens-flare stuff
just for fun experimenting, and we can do all that work
kind of in clip space because you have this relative
to the center that you can move things around,
so that's one -- Those are both transforms that we have across Blueprints
and Materials and so on. You can transform from,
let's say, world to view, and then you will get that -- "What am I relative to the box
I'm looking through," or you could transform
to clip space, and then you're like, "What am I relative
to the center of my screen," and those are very,
very useful transformations where you could do comparisons
to your mouse cursor because your mouse cursor
naturally is in that relative zero-to-one space already, and so you could just take
a world-space position, transform it into
that view space to say like, "I'm at point one,
and my mouse is at point nine," and now I can do
all sorts of friendly -- Again, it's
that language translator. Now that you're both
speaking the same language, you can complete each other
and, "How far away am I?" and "What is my angle from you?" All those things kind of fall
out of answering that question as long as they
are speaking the same language. >>David: I don't know if there
is one for mouse position in Material Editor,
but you can feed it in from a Blueprint
or something as a parameter. But a lot of things
in Materials, like let's say we map things to
a screen position on the world, but then you want
to add its position, and this effectively just
a transform, right, so you -- maybe a line. I do this a lot,
holographic scan lines, and it's a line to the screen,
but as the objective moves, the scan lines move with it,
so it's kind of tracked. There is a lot of visual use
cases for something like that. >>Victor: Are you using numerical
maths in Unreal Engine, for example algorithms. >>David: I could tell you, we -- I'm not sure exactly what he is
referring to by numerical maths, but we do have a math library
and several parts of math libraries throughout
the Engine on the C++ side that we use to do
a whole host of things, so we have implemented inside
of the Unreal Engine, like Wyeth was talking
about FTransforms. We have quaternions. We have representations
for vectors, where you can take Dot Products
between them, get Cross Products, and more sophisticated
for very specialized purposes, different sorts of transforms, a little bit of matrix
multiplication in there, so we're using
numerical methods a lot, and we have different
parts of math library scattered about the Engine
to help us with these different tools
or these different -- trying to meet these
different applications. Some of it is more on simulation
for moving particles around, where you have the velocity
of the particle, and you need to updated
its location and have it test
the world around it and do that again and again,
so the physics engines use a lot of numerical methods
for their simulations, so we're using numerics lots
and lots of places, rendering, physics, geometry,
all sorts of things. >>Victor: Cool. I would say that answers
the question pretty well. So we talked a little bit
about vectors. There was also a couple
questions around distance fields and a little bit more practical,
how you use, so I'm going to give us
a couple of the questions, and then we can talk
a little bit about it. Where does one use distance
fields in Unreal Engine. Is that a data type you import? Is is accessible in Materials,
Niagara, et cetera? And then are there
any Distance Field examples in the Content Examples
or elsewhere? >>Wyeth: I believe there are
examples. I'm pretty sure we have -- If I'm not mistaken,
there is a Cascade Collision with Distance Field example,
although I would have to look. At the very least, that's
one of the default options in the existing tools
in Cascade, or now Niagara,
the new particle sim, can collide with
the world distance fields, but more broadly to answer
that question, if you go into
your project settings and enable Mesh
Distance Fields, now it will go through
and as a preprocess step, it will calculate
based on some metric of how much memory
you want to spend and how high resolution
you want them to be, it will calculate those distance
fields for those Meshes, and all of your Static Meshes will have this precalculation
step done unless the box isn't checked, but if you place
a Static Mesh in the world, this calculation will happen. It will build
these distance fields around each of
your atomic objects, right, and then for performance, what happens is if you want
to sample them, it would be a little bit
tough to say, "Hey, I'm going to look around
for the nearest object to me and only sample
its distance field." It's just a hard problem
when it is so atomic and you don't have
this broader kind of container of what we would call
a global distance field, which is just the sum
of all these distance fields that are on individual assets
in the scene, so what we do is every frame we basically take
the sum of all those, and we pack them into
a lower-resolution kind of grid that's aligned to your view, and we're just rebuilding
that every frame, and we have functions
in Niagara. We have functions
in Material Editor, functions all over the tool to say what is my distance
from the nearest thing to me, and we can get
that answer back by looking up into
that big global distance field, and so in the Editor,
there is a visualize mode. You can just go show
distance fields, and it will bring up this hazy,
ethereal view of the level, which is basically
a visualization of how far is any given point in the world
from the nearest thing to it, and we query that.
In Niagara, we query that distance field
for particle collisions, and the particle
is just going like, "Hey, query the field.
Query the field." Every frame,
it's asking how far -- "Am I really close
to something?" and then it starts to care
when it gets really close, and when it's close enough,
it will say, "Okay, I'm close enough to care. What is the gradient
of the surface that I'm colliding with?" and so that would be basically
just be I would take whatever that gradient that would have
got me there and flip. Now that's my little normal,
and I do exactly what we showed at the very first example
where I go, "Oh, I know what that --
I know I'm past the surface because it's
a signed distance field." I don't know
if you guys remember that, but if I'm going to go through,
that would mean that that value that I'm sampling
would be become negative, and so on that frame
that I would have gone in there, I say, "Oh, oh, boy.
I would have gone in. That's not good," so I stop, figure out how far
I would have had to travel because I have that gradient.
I have the distance. I have all that encoded
information right there in the distance field.
I move right to the surface, and then I take the remainder
of how far I would have gone, and I just flip it back
using this reflection technique that we have already shown, so that's kind of
a built-in Unreal-ism, and there are a lot of things. In the Material Editor too,
you can do that per pixel. You can ask, "How far am I
from the distance field?" and there is a bunch
of cool visualizations people have done of blobs
that start to deform as they get close to the surface
because that blob is saying, "Oh, I'm a vertex.
I'm getting really close now. Oh, I'm getting too close.
I don't want to go in. I want to push away,"
and then the end result of that is the thing goes blorp
and squishes into a pancake instead of penetrating
the surface, and that kind of comes for free
by asking the distance field how far am I from it
and its gradient, so, yeah. That is a built-in Unreal-ism. >>Victor: For those
specific things, I generally try to think of it as a wrapping paper
that's over everything -- >>Wyeth: Sure. >>Victor: --at least when you think
about it in terms of collision. >>Wyeth: Right. Yeah. >>Bill: And that's useful
for fog too. If you do volumetric fog stuff, sampling distance field data
is super nice. You can say as it approaches
closer to surfaces, much like we would expect fog
to collect on the floor or something like that, you can access all that data
in the Material Editor, so there is a lot of powerful
usages for that. >>Victor: So it's a little
different from the depth fade then? >>Bill: Yeah.
It's a similar concept. Depth fade is, with translucent
Materials, it's saying, "Get behind me
what the distance is," and you can do things like
just get the difference, and then you can do Dot Products to try to calculate angles
and stuff like that. Distance fields
have way more data. I don't think -- We don't support distance field
on translucent stuff, right? Is that not a thing? It's got to be
an opaque geometry. >>Wyeth: No. You can query it.
>>Bill: You can? Okay, well, today
I learned then, so it's even more powerful
than I thought, but same concept, way more
powerful though and robust. And I thought -- You can correct me if I'm wrong,
but with collision, with distance field collision, I thought it could do it
off-camera too. Scene-depth collision is -- >>Wyeth: That is the beauty, that's the great beauty
of the distance field. The only limiter of the
distance field is resolution, so we encode these
as Textures basically. They are like little
volumetric Textures, 3D Textures that surround
all our objects, and they make a coarse
approximation of the distance to that surface.
If we spent a ton of memory, we would have a really
perfect thing where the -- what David was referring
to as the isosurface, which is that zero point, would be really well
conformed to me, but as it stands,
if I were a statue, it would probably just say,
"I'm hand-shaped," and I would bounce
of the hand-shaped blob because that's as much
resolution as we're going to dedicate to the problem
to make it performant and run on modern consoles
and all that kind of thing, so that's the downside
of distance fields is they're inherently
an approximation unless you have a really,
really high-resolution one. The upside is is that
it's three-dimensional, so with scene-depth
buffer collision, if I can see it,
I can collide with it, but if I had a particle
flying toward me, and I wanted it to bounce off
the back of something, I can't -- As the camera,
I can't see that, so I just go right through. You just lose particles
to scene-depth collision, and we actually have all these
checks in there to be like, "Oh, I lost you.
We should probably kill you." We just kind of manage
that for you and try to make it not terrible. With the
distance field collision, you have this full, beautiful,
3D representation of the scene, and so the balls,
in my first example, would do exactly the same thing if they were colliding
as a distance field. They would have that no matter
which part of the scene they were bouncing off
or colliding against. They would have something
to talk to to ask the question, "How far away am I,
and what is this little normal?" They would be able to ask that
from any direction, so they're awesome. >>Victor: Is that why distance
field shadows also are drawn even when they're not
in the frustum? >>Wyeth: Exactly the same.
>>Victor: Okay, yeah. These are good topics. I'm enjoying this,
good questions too. A couple more have come in. We have a little bit
of time left. I'm feeling there has been
quite a lot of information, so let's take the full time and just go through
the questions as well. A few tidbits: I think both chats were individually calling you
the Bob Ross of math, and they were all really happy,
and they would like to see more episodes
of this Math for Artists thing. >>Wyeth: Awesome.
It was really fun. >>Victor: Yeah, and it's
extremely useful, right, especially getting it
in the context of a tool that you might be working with, and so we can relate a little
bit more to the real world of how you're working
with the math. Why do you have transform,
rotators, color, et cetera as different classes
while it's just vectors. Yeah. That was pretty
much the question. >>Wyeth: I can answer that
in the context of, for instance, Niagara. We do that because we can
guide you to behavior, so a quaternion
is a vector-four. It's the same thing. It's just
four pieces of information that if they're encoded
in the right way result in a rotation around an axis. That's cool. You can just say
that's a vector-four, four floats,
four pieces of information. We type it so that if I pull off
of a quaternion in that Editor, I get a bunch of
context-sensitive, useful things that are relevant
to my interests when working with quaternions, and if I had a module
which took -- It expected quaternions,
if I'm encoding a quaternion from some other means,
like I have a module which generated one
that I know is good. It's normalized,
and it's rotating. If there is another behavior
further down my stack of behaviors
that expects a quaternion, I don't want the user to just
plug some arbitrary four-vector in because you're going to get
an undesirable result, so almost all the times
that we classify these things even though they really
are all just vectors, we do that to guide the user
to healthy, predictable behavior and not for any other purpose. >>David: That there could be
potential, I'm sure, memory-saving concerns
too about different data types and how much of that data
we want to store. Precision matters, but I think
the intuition of the person who was asking that question
is totally right. We are just establishing
numbers, right? Why can't RGBA drive
RPY rotations, things like that, and we can. A lot of times,
we break information out and get
the individual components and do different things
with that, so one other tail bit
of that too is context. Going with what Wyeth said is that you open
put the Blueprint Editor and a vec-four versus
a linear color is very convenient for me
as an artist. A linear color,
if you double-click, actually brings up
the color pick, and I don't want
to type in RGBA. Sometimes I do, but sometimes you want
to be able to just use your eye and start adjusting value,
hue-saturation value and stuff, so some of that's just
convenience too from the tool, from the Editor. >>Victor: And it helps you
to understand the concept of data types
if you didn't know when you started working
with Blueprint, for example. >>Bill: Oh, yeah, that's critical.
>>Victor: Yeah. Yeah, it is,
and so it's a lot of help, and especially just trying
to plug things in. "Oh, it's blue, and that
is orange. Alright. Okay." >>Bill: And that's the thing
about Blueprints. It does a lot of
the casting stuff for you. If you were doing this in C++, you would have to break
the stuff with a lot of extra steps.
You can break apart -- I think this is a little secret
that most people don't know. You can right-click
on most variables or outputs or inputs in Blueprints and actually say
split components, I think it's called
or break components. I can't remember, and it actually
just shows RGBA right there. >>Victor: I think it's split struct
is actually what it's called. >>Bill: It's a similar idea.
A struct will break apart all the individual
components of the structure, but this is like I have an X,
Y, Z, like a vector, and you right-click and say
split or show components, whatever it's called,
might as well just show it. It will actually turn
from yellow, which is the color coordination
in Blueprints for a vector-three, and it will actually show
three greens, so the individual scalar
components, so -- >>Victor: Instead of using the
break, adding another number. >>Bill: Exactly, yeah, yeah.
>>Victor: Yeah. >>Bill: So it's useful,
super useful. I use it all the time. >>Victor: We got
time for a few more. They were wondering
if you might know if there was
a distance field example in the particle examples
project. >>Wyeth: I thought there was
a Cascade one, but it's been a very,
very long time since I looked, so we probably
should not that as gospel. I do know that we have not yet
written one for Niagara, but that is on our list. The next time we address
the Niagara sample content, we want to have -- elucidate more of the options
of individual modules, and instead of just talking
about the key concepts behind how Niagara works, we wanted to be
a little bit clearer on how some of
the core behaviors work, like how the modules work, so as we go
and make example content, we'll make sure
that that's on there. >>Victor: Awesome.
>>Wyeth: Yep. But I will also say,
if you're in Niagara and you put in a collision module
in 4.23 or the 4.24 preview, one of the dropdowns,
if you are a GPU sim, one of the dropdowns
is distance field, and then it just samples
the distance field. It does what it says on the tin,
and so you can -- With a couple of clicks,
you could try it out basically. >>Victor: Alright. They were
asking about fun examples for all the things
we talked about. Don't really have time
to go through that, but maybe next time
there can be -- >>Wyeth: More fun?
>>Bill: I was going to say. What was wrong
with our examples? [LAUGHTER] >>Victor: I think they
were relating -- >>Wyeth: See that was the
problem. >>Bill: We do have stuff
from the math class. We could pull that up
if you guys want if you feel it's worth it. >>Wyeth: I mean, I think the
reality is we're just going to do more of these at some point. There is a million topics.
We could sit here and just talking about vectors
for 4 hours, and useful stuff would just
fall out of that the whole time. >>Victor: That would be great.
That would be great. Let's do that.
I'll grab a few more. How to smooth SDFs,
signed distance fields. It currently like voxelized grid, kind of blobs in space
in Unreal Engine. >>Wyeth: The Texture filtering
does its best to interpolate between the positions that
are encoded in that big Texture, but there is only
so much you can do. You have to increase resolution
to get more data. At some point,
you're sampling a Texture that we rebuild or a buffer,
I guess. I don't know
if we actually encode it or not into a 3D Texture,
a volume Texture. Ask Daniel. At some point,
you're having this data, which we're interpolating
between center point of these cells
that we're saving off, and that's going to be lossy
and linear in a way that if you had this beautiful mathematical
function would not be, but there are project settings
to increase the resolution. This grid, this froxel they call it grid
is a pyramid in front of you, which we rebuild every frame and we make the global
distance field out of. You can increase
the resolution of that because the individual Meshes
are pretty high resolution, much higher than
the global distance field that we rebuild every frame, so there is more data
sitting there, and so you could, if you had
the performance to do so, you could spend more of that by
changing some CVars or some INIs or whatever the project
setting is, and so you could spend
more of your budget on a high-resolution version
of the global distance field. >>Victor: So it's always
a balance between what the scene looks like
and what you're trying to do. >>Bill: I was going to say I'm
ignorant on a lot of this stuff, but this is the same problem
with fluid Sims, right, because you're just obviously
solving individual voxels, and then they do
a bunch of math to make something
really nice-looking. I'm sure there is a way.
I'm sure it's not cheap and not very friendly
to do this every frame and get 30
or 60 frames per second. >>Wyeth: So there is one interesting
quality of a distance field. If you just think
about a distance field as a distance from a surface, the farther away
you are from the thing that is the isosurface,
that zero boundary, the more a distance field
resembles a sphere or a disk. It rounds itself off by
the nature of the sampling of it the further away you go
from that surface, and so sometimes people
will use the trick of they will sample
from further away than they want and then kind of subtract
to get themselves back to where they wanted to sample, and they can sample a rounded
version of the distance field that they want to ask for. And that's a common trick
and technique, and so if you had
a distance field of a square and you march out a little bit, that square looks more
like a rounded box, and then you subtract
how far out you went, and now you have made yourself
a rounded box for free because you have sampled
a box distance field at a point where it looked
a little bit more like a circle, and so that's a trick
that we use too to round off and contour spiky
distance fields. You could actually just ask
for the position a little further out
and then fudge it. >>Bill: It's almost like
a detail scaler or something. >>Wyeth: It is. >>Bill: Less details.
>>Wyeth: It is. >>Bill: That's interesting.
I like that. >>Victor: I sometimes mix up
Cross Product and Dot Product. I know one is functionally
a normal and the other represents an angle,
and they're asking for a trick or mnemonic to remember
which is which, and the community responded
with something that I thought was pretty cool
that we have not mentioned yet. We already showed
the Cross Product. I don't think it was in camera
last time we did it. >>Wyeth: We are all doing
the same thing. >>Victor: Finger guns. >>David: Throw down.
>>Victor: The community response was think of a dot
as a small symbol. The Dot Product
gives you only one number, so it's small in size. Think of a cross
as a larger symbol. The Cross Product
gives you a new vector, so it's larger in size. >>Wyeth: I could see that being
a useful mnemonic, for sure. >>Bill: I think that the number
one thing to recognize and remember is that the dot gives you
a single value from two vectors, and then the cross
gives you a new vector, right, which is actually -- My hands don't make sense
when I'm doing that, but it just gives you
a single floating value versus a cross
gives you the X, Y, and Z. That is the most
important thing. And what you can do with it,
there is tons. We can probably do
a whole class on that too. >>Wyeth: We should. I think
that's a whole other area, which you could mine
for a very, very long time, and when we talk about trig
at some point, I hope we do, when we start talking about
sines and cosines and stuff, all that stuff
is all interrelated, and it all falls
out of the same place, so that will be a fun one. >>Victor: Alright.
This has definitely gone on. We are almost up
to the 2-hour mark already. >>David: Oh, my goodness.
>>Bill: Three fifty-six. >>Victor: And so any future
questions, we'll have to leave
for the next stream, I guess. Thank you all so much
for coming on, preparing all this
amazing content for us. >>Wyeth: It's our pleasure.
>>Victor: Yeah. >>David: Super fun. >>Victor: I really like the
interaction between the deck and then some content and seeing
what it looks like in reality. That definitely helps
sort of digest the math itself. >>David: Sure.
>>Victor: And so did chat think. They were very happy about it, so we would all love
to have you back. That would be awesome. Next week,
we will not have a stream. We are all out for Thanksgiving
here in the office, the American holiday
that we'll be celebrating, but the week after that, we will
be talking about 4.24 features, and Ryan Brooks will actually show off some of
our new Landscape Tools that we have
in 4.24. Yeah. Supercool. >>Wyeth: They look awesome,
so enjoy that one. >>Victor: Yeah. No, it's great. I did see his talk
from Unreal Dev Days, and that's actually available
online now. If you can't wait,
you can go ahead and -- >>Wyeth: Spoiler alert.
>>Victor: Yeah, spoiler alert. Yeah.
He did show it off, but we'll do it here
on the stream as well. Nick Penwarden will be here as well to talk about
sort of general 4.24 features. But until then, if you're interested
in our Meetups that happen around the world, go ahead and go to
unrealengine.com/user-groups. If you don't find any Meetups
near you, you can go ahead and reach out to us
in case you're wondering, "Has there been one here before? Was there an organizer that's
no longer hosting any meetups?" And if you're interested
in what that might mean, and you think there is
a community around you that would like this to happen, go ahead and reach out to us
at community@unrealengine.com. As always, make sure
you visit our forums, the unofficial Discord,
Unreal Slackers. I know Wyeth is on there.
I've seen your -- >>Wyeth: I dance that dance
from time to time. >>Victor: Yeah, a little bit. It's a good community.
If you have a quick question, and you want some people
to just talk about the subject, they are almost up to 29,000
members now, I think -- >>Wyeth: That is awesome.
I did not know that. >>Victor: -- which is amazing, and
it is all run by the community. We hang out there to answer
some questions and whatnot. But Nick Pfisterer
is a great guy, is making sure
all that's working. There is a Facebook group,
and then Reddit as well is very active
if you're looking for resources and want to get in contact more
with the community around Unreal Engine. We are getting low
on countdown videos. I would love to see another one
being submitted to us. If you're unfamiliar
with what they're, it's the first little 5 minutes
of the stream where we count down
before we go live. It is 30 minutes of development
in the Editor. Speed that up to 5 minutes and then send that
with your logo separately to us, and we'll composite them
together to add the countdown. It would be awesome to see them, so I'm going to keep mentioning
that until I see more. If you stream on Twitch, make sure you use the Unreal
Engine category like we do and make sure you follow us on
all our social media accounts: Twitter, Facebook.
We have a LinkedIn one that's a little bit more
tailored towards AIE Enterprise. That is where we pretty
much deliver all of our news that come out
from what happens here at Epic regarding Unreal Engine. And so until next time
that we have all of you on, thank you very much for coming, and to all of you,
we'll see you in 2 weeks. Have a good week
and a good Thanksgiving. Bye-bye.