background top icon
background center wave icon
background filled rhombus icon
background two lines icon
background stroke rhombus icon

Download "The Graphics Pipeline and You | Writing Unity URP Code Shaders Tutorial [1/9] ✔️ 2021.3"

input logo icon
Video tags
|

Video tags

gamedev
game development
development
unity
unity3d
madewithunity
programming
game design
csharp
nedmakesgames
nedmakesgames dev log
indiedev
indie game
dev log
shaders
3d modeling
blender
tutorial
walkthrough
shader
universal render pipeline
urp
unitytip
unitytips
shaderlab
hlsl
beginner
starting
shader graph
hdrp
graphics
graphics programming
tech
tech art
lighting
shadows
texture
textures
interpolation
struct
swizzling
macros
material
materials
model
modeling
uvs
unreal
Subtitles
|

Subtitles

subtitles menu arrow
  • ruRussian
Download
00:00:00
hi i'm ned and i make games
00:00:02
would you like to start writing shaders
00:00:04
but don't know where to begin
00:00:06
or are you having issues with urp's
00:00:08
shader graph and would like an
00:00:09
alternative in this tutorial series i'll
00:00:11
walk you through writing a fully
00:00:13
featured general purpose shader for
00:00:14
unity's universal render pipeline
00:00:16
exclusively in code
00:00:18
this topic is pretty big so i'll break
00:00:20
it into several videos check the video
00:00:23
description for links to each tutorial
00:00:25
and a playlist too
00:00:26
we'll start with understanding the
00:00:28
structure of shaders and then move on to
00:00:30
lighting and shadows before finishing
00:00:32
with more advanced topics like
00:00:33
physically based materials and custom
00:00:35
lighting models
00:00:37
also if you prefer reading tutorials
00:00:39
i've created a written version of the
00:00:40
entire series also linked in the video
00:00:42
description before i move on i want to
00:00:45
thank all my patrons for helping make
00:00:46
this series possible and give a big
00:00:48
shout out to my next gen patron
00:00:50
cubeydoobydoo thank you all so much
00:00:53
i'd like to quickly show off a wonderful
00:00:55
game from some long time viewers kitty
00:00:57
cat squash it's an adorable casual
00:01:00
puzzle game where you match cute kitties
00:01:02
and try to beat your high scores
00:01:04
it starts simple but can quickly become
00:01:05
a brain teaser try out a bunch of
00:01:07
different game modes gravity was my
00:01:09
favorite and unlock 16 different cats i
00:01:12
love seeing juliet on my board so
00:01:14
precious kitty cat squash is available
00:01:16
on steam the google play store and the
00:01:19
amazon app store
00:01:20
go get your cute kitty fix
00:01:23
thank you inspired by madness games for
00:01:25
sponsoring this video
00:01:26
let's lay out some goals of this
00:01:28
tutorial series my aim is to teach how
00:01:30
to write shaders i will show several
00:01:33
examples writing each step by step and
00:01:35
explaining as we go
00:01:37
do not view these examples as ready for
00:01:39
production shaders but rather as a
00:01:41
blueprint that you can customize to your
00:01:43
game's needs
00:01:44
after completing this series you'll know
00:01:46
how to write your own version of urp's
00:01:48
standard lit shader
00:01:50
as well as customize it with your own
00:01:51
lighting algorithm and more you'll also
00:01:54
know several optimization techniques and
00:01:56
how to leverage unity's debugging tools
00:01:58
to diagnose and fix rendering bugs
00:02:01
the examples in this tutorial were
00:02:02
tested in unity 2020.3 and 2021.3
00:02:06
as you follow the tutorial you will come
00:02:08
across many features that are only
00:02:10
possible in 2021 however i have written
00:02:13
the shaders so that the same code runs
00:02:15
in each version
00:02:17
there's quite a lot to set up and
00:02:18
understand before anything will display
00:02:20
on screen which can make learning
00:02:22
shaders pretty difficult
00:02:24
to speed up the process i'll explain
00:02:26
information as needed and i might gloss
00:02:28
over some edge cases or technicalities
00:02:31
don't worry i'll address them if they
00:02:32
become important later on
00:02:34
to keep this series from becoming even
00:02:36
longer i will assume that you have some
00:02:38
general game development knowledge
00:02:40
you should be comfortable using unity
00:02:42
and its 3d game tools such as models
00:02:45
textures materials and mesh renderers
00:02:48
and although you need no prior
00:02:49
experience writing shaders you should
00:02:51
know how to program c-sharp experience
00:02:53
will definitely be useful with all that
00:02:56
out of the way let's get started
00:03:00
in this series we'll use unity's
00:03:01
universal render pipeline is one of
00:03:03
several rendering frameworks that unity
00:03:05
provides but i chose urp for this
00:03:08
project due to its recency and ability
00:03:10
to support a wide variety of platforms
00:03:12
all while remaining pretty lightweight
00:03:15
i would highly suggest creating a fresh
00:03:17
project for this tutorial you can either
00:03:19
select the urp project template
00:03:22
or use a blank template add urp manually
00:03:25
through the package manager and activate
00:03:27
it in graphics settings
00:03:46
either way create a new standard scene
00:03:48
to work with
00:03:51
large shaders like the one will write
00:03:53
are made of several files to help keep
00:03:55
things organized create a new folder
00:03:57
called mylit to contain them all
00:04:00
create a shader file by selecting unlit
00:04:02
shader from the create dialog and name
00:04:05
it mylit.shader
00:04:07
if you create a material you'll already
00:04:09
see your shader in the shader selection
00:04:11
menu of the material inspector
00:04:14
it will be under the unlit submenu
00:04:19
open your shader file in your code
00:04:20
editor of choice
00:04:22
if you're using visual studio sometimes
00:04:24
unity doesn't generate a visual studio
00:04:26
project correctly when there are no
00:04:27
c-sharp scripts present
00:04:30
first create an empty c-sharp script
00:04:36
so your shader will appear in the
00:04:37
solution explorer
00:04:42
regardless inside mylit.shader is a lot
00:04:45
of automatically generated code
00:04:47
delete it all for now
00:04:50
this part of a shader is written in a
00:04:52
language called shader lab and it
00:04:54
defines meta information about the
00:04:55
actual drawing code
00:04:57
the first line opens a shader block and
00:04:59
defines the shader's name in the
00:05:01
material inspector any slashes will
00:05:03
create subsections in the selection menu
00:05:06
useful for organization
00:05:08
the block is bound by curly braces
00:05:10
like classes in c sharp
00:05:13
a shader is more than just code that
00:05:14
draws a single shader is actually made
00:05:17
of many sometimes thousands of smaller
00:05:19
functions
00:05:20
unity can choose to run any of them
00:05:22
depending on the situation they're
00:05:24
organized into several subdivisions the
00:05:26
top most of which are known as
00:05:28
subshaders
00:05:30
subshaders allow you to write different
00:05:31
code for different render pipelines and
00:05:33
unity will automatically pick the
00:05:35
correct sub shader to use at any time
00:05:38
define a sub shader with a sub shader
00:05:40
block and then add a tags block to set
00:05:42
the render pipeline tags blocks hold
00:05:44
user defined metadata in a format sort
00:05:46
of like a c sharp dictionary tell unity
00:05:49
to use this sub shader when the
00:05:50
universal rendering pipeline is active
00:05:52
by setting the render pipeline tag to
00:05:54
universal pipeline
00:05:57
that's the only sub shader that we'll
00:05:58
ever need in this tutorial
00:06:00
subshaders are just the first
00:06:01
subdivision of a shader below them are
00:06:03
passes passa's purpose is a bit more
00:06:06
abstract each pass has a specific job to
00:06:09
help draw the entire scene like
00:06:11
calculating lighting casting shadows or
00:06:14
creating special data for
00:06:15
post-processing effects
00:06:17
unity expects all shaders to have
00:06:20
specific passes to enable all of urp's
00:06:22
features but for now let's only focus on
00:06:25
the most important pass the one that
00:06:27
draws a material's color
00:06:29
to signal that this pass will draw color
00:06:31
add a tags block inside the path type
00:06:34
key is light mode
00:06:36
and the value for a lit color pass is
00:06:38
universal forward
00:06:40
you can also name passes which will help
00:06:42
a lot in debugging
00:06:44
okay we're almost ready to write some
00:06:46
code erp shader code is written in a
00:06:48
language called hlsl which is similar to
00:06:51
a streamlined c plus to mark a section
00:06:54
of a shader file as containing hlsl
00:06:57
surround it with the hlsl program and
00:07:00
end hlsl code words
00:07:03
to keep things organized i like to keep
00:07:05
hlsl code in a separate file from the
00:07:07
dot shader metadata thankfully this is
00:07:09
easy to do
00:07:11
you can't create an hlsl file directly
00:07:13
in unity but you can in visual studio
00:07:17
or inside your file system
00:07:23
either way name this new file
00:07:25
myletforwardlitpass.hlsl
00:07:32
and open it in your code editor
00:07:35
i just want to mention that many code
00:07:37
editors don't work well with urp shaders
00:07:40
so while working through this tutorial
00:07:42
ignore any errors that you see in your
00:07:44
code editor and just rely on unity's
00:07:46
console
00:07:48
when writing shaders you need to have a
00:07:49
different mindset than you would when
00:07:51
working with c sharp
00:07:52
for one there's no heap meaning most
00:07:55
variables work like numeric primitives
00:07:57
or structs
00:07:58
you can't define classes or methods or
00:08:00
use inheritance structs and functions
00:08:03
are still available to help you organize
00:08:05
your code
00:08:06
if you've ever worked with data-driven
00:08:08
design you'll also feel at home writing
00:08:10
shaders
00:08:11
the focus is gathering data and then
00:08:12
transforming it from one form to another
00:08:15
in the broadest sense shaders transform
00:08:17
meshes materials and orientation data
00:08:20
into colors on the screen
00:08:22
there are two standard functions which
00:08:24
the system calls kind of like the start
00:08:26
and update functions in mono behaviors
00:08:29
these functions are called the vertex
00:08:31
and fragment functions and every pass
00:08:34
must have one of each
00:08:35
these both focus on transforming data
00:08:38
from one form to another the vertex
00:08:40
function takes mesh and world position
00:08:42
data and transforms it into positions on
00:08:45
the screen
00:08:46
the fragment function takes those
00:08:47
positions as well as material settings
00:08:50
and produces pixel colors
00:08:52
unity's rendering system employs
00:08:54
something called the graphics pipeline
00:08:56
to link together these functions and
00:08:58
handle low-level logic
00:09:00
the pipeline gathers and prepares your
00:09:01
data calls the vertex and fragment
00:09:03
functions and displays the final colors
00:09:06
on the screen it's made of several
00:09:08
stages running one after another kind of
00:09:10
like an assembly line
00:09:11
each stage has a specific job
00:09:13
transforming data for later down in the
00:09:15
assembly line
00:09:17
there are two special stages the vertex
00:09:19
and fragment stages which are
00:09:21
programmable
00:09:22
they run the vertex and fragment
00:09:24
functions that you write
00:09:25
the other stages are not programmable
00:09:28
and run the same code for all shaders
00:09:30
although you can influence them with
00:09:32
various settings
00:09:34
let's take a look at each stage starting
00:09:37
at the beginning the input assembler
00:09:39
it prepares data for the vertex stage
00:09:42
gathering data from meshes and packaging
00:09:44
it in a neat struct
00:09:45
structs in hlsl are very similar to c
00:09:48
sharp a pass by value variable
00:09:50
containing various data fields
00:09:52
this tract is customizable and you can
00:09:55
choose what data the input assembler
00:09:56
gathers by adding fields to the struct
00:09:59
but just what kind of data can the input
00:10:01
assembler access
00:10:03
the input assembler works with meshes
00:10:05
specifically mesh vertices
00:10:07
each vertex has a bunch of data assigned
00:10:09
to it such as position normal vector
00:10:12
texture uvs etc each data type is known
00:10:15
as a vertex data stream
00:10:17
to access any stream in your input
00:10:19
structure you simply need to tag it and
00:10:21
the assembler will automatically set it
00:10:23
for you
00:10:24
for example here's an input struct for
00:10:26
our forward passes vertex function
00:10:28
it defines a struct called attributes
00:10:31
which has a field called position with a
00:10:34
type called float3 float3 is the hlsl
00:10:37
term for c-sharp vector3 or a vector
00:10:40
containing three float numbers
00:10:43
we can use semantics to tag variables
00:10:45
and the input assembler will
00:10:46
automatically set them to a particular
00:10:48
data stream
00:10:50
for example the position semantic
00:10:52
corresponds to vertex position
00:10:54
keep in mind that only the semantic
00:10:56
determines what data the input assembler
00:10:58
will choose to place in variables feel
00:11:01
free to name variables however you wish
00:11:03
we'll see more semantics later on hlsl
00:11:05
uses them pretty often to help the
00:11:07
graphics pipeline along
00:11:10
with that let's move on to the vertex
00:11:12
stage as a programmable stage you get to
00:11:14
define the code that runs here defining
00:11:17
a function in hlsl is very similar to c
00:11:19
sharp with a return type void at the
00:11:22
moment
00:11:23
a function name and a list of arguments
00:11:26
an argument's type precedes the variable
00:11:29
name this function only needs a single
00:11:31
argument of attributes type
00:11:33
the vertex stage's primary objective is
00:11:36
to compute where mesh vertices appear on
00:11:37
the screen
00:11:39
however notice that the attribute struct
00:11:40
only contains a single position
00:11:43
only data for a single vertex
00:11:45
the render pipeline actually calls the
00:11:47
vertex function multiple times passing
00:11:50
it data for each vertex until all are
00:11:52
placed on the screen
00:11:53
in fact many calls will run in parallel
00:11:56
if you've ever programmed multi-threaded
00:11:58
systems you know that parallel
00:12:00
processing can introduce a lot of
00:12:02
complexity shaders bypass a lot of this
00:12:05
by forbidding storage of state
00:12:06
information
00:12:07
each vertex function call is effectively
00:12:10
isolated from all the others
00:12:12
you cannot pass the result of one vertex
00:12:14
function or any data computed inside to
00:12:16
another
00:12:18
each call can only depend on the data in
00:12:20
the input struct as well as other global
00:12:22
data but more on that later
00:12:25
in addition each vertex function call
00:12:27
only knows about data of a single vertex
00:12:30
this is mostly for efficiency the gpu
00:12:33
doesn't want to load the entire mesh at
00:12:35
once
00:12:36
we need to compute the screen position
00:12:37
for a vertex described in the attribute
00:12:39
struct when talking about positions it's
00:12:42
important to determine the coordinate
00:12:43
system that it's defined in its space
00:12:47
the position vertex data streams gives
00:12:49
values in object space
00:12:51
which is another name for the local
00:12:53
space that you're accustomed to in
00:12:54
unity's scene editor
00:12:56
if you view a mesh in a 3d modeling
00:12:58
program these positions are also
00:13:00
displayed there
00:13:04
another space you'll often use is world
00:13:06
space
00:13:08
it's a common space that all objects
00:13:10
exist in relative to one another
00:13:12
to get world space from object space
00:13:14
just apply an object's transform
00:13:16
component
00:13:17
unity provides this data to shaders as
00:13:19
we'll see soon
00:13:21
however a vertex's position on screen is
00:13:23
described using a space called clip
00:13:26
space
00:13:27
an explanation of clip space would fill
00:13:29
an entire tutorial but luckily we don't
00:13:31
have to work with it directly
00:13:33
urp provides a nice function to convert
00:13:36
an object space position to clip space
00:13:38
to access it we first need to access the
00:13:40
urp shaders library in hlsl we can
00:13:43
reference any other hlsl file with the
00:13:46
hash include directive
00:13:48
these commands tell the shader processor
00:13:50
to read the file located at a given
00:13:52
location and copy its contents into this
00:13:54
line
00:13:56
if you're curious what's inside the
00:13:57
lighting.hlsl file or any other urp
00:14:00
source file you can read them yourself
00:14:03
in your packages folder
00:14:05
included files can themselves include
00:14:07
many other files leading to a kind of
00:14:09
tree structure
00:14:11
for instance lighting hlsl will pull in
00:14:13
many helpful functions from across the
00:14:15
entire urp library
00:14:17
one such function git vertex position
00:14:20
inputs is located in the shader variable
00:14:23
functions.hlsl file
00:14:25
its source code isn't really important
00:14:27
but it returns a structure containing
00:14:29
the past object space position converted
00:14:32
into various other spaces clip space is
00:14:34
one of them just what we need
00:14:37
note that clip space is a float 4 type
00:14:40
if you tried to store it in a float 3
00:14:42
unity would give you a warning that data
00:14:44
will be truncated or lost this is a
00:14:46
common source of bugs so always heed
00:14:48
these warnings and use the correct
00:14:50
vector size
00:14:51
keeping track of which space a position
00:14:53
is in can get tricky pretty fast
00:14:56
standard erp code adds a suffix to all
00:14:58
position variables indicating the space
00:15:01
os denotes object space cs clip space
00:15:05
etc
00:15:06
we should follow this pattern as well
00:15:10
next we must fulfill the vertex stage's
00:15:12
job and output the clip space position
00:15:14
for the input vertex to do that let's
00:15:17
define another struct called
00:15:18
interpolators to serve as the vertex
00:15:20
stages return type write a float4
00:15:23
position cs field inside of it with the
00:15:26
sv underscore position semantic the
00:15:28
semantic signals that this field
00:15:30
contains clip space vertex positions
00:15:33
have the vertex function return an
00:15:35
interpolator struct declare a variable
00:15:37
of interpolator's type set the position
00:15:40
cs field and return the structure
00:15:43
with that the vertex stage is complete
00:15:46
the next stage in the rendering pipeline
00:15:47
is called the rasterizer
00:15:49
the rasterizer takes all vertex screen
00:15:51
positions and calculates which of the
00:15:53
mesh's triangles appear over which
00:15:55
pixels on the screen if a triangle is
00:15:58
entirely off screen the render is smart
00:16:00
enough to ignore it the rasterizer then
00:16:02
gathers all data for the next stage in
00:16:04
the pipeline the fragment stage
00:16:07
the fragment stage is also programmable
00:16:10
and the fragment function runs once for
00:16:12
every pixel the rasterizer determines
00:16:14
contains a triangle
00:16:15
the fragment function calculates and
00:16:17
outputs the final color each pixel
00:16:19
should display
00:16:21
but of course each call only handles one
00:16:23
pixel
00:16:25
the fragment function has a form like
00:16:27
this
00:16:28
it takes a struct as an argument which
00:16:30
contains data output from the vertex
00:16:32
function
00:16:33
naturally the type should match so both
00:16:35
should be an interpolator
00:16:37
the values inside input have been
00:16:39
modified by the rasterizer
00:16:41
for instance position cs no longer
00:16:44
contains slip space position but rather
00:16:46
this fragment's pixel position
00:16:49
you can also pass other data from the
00:16:51
vertex function into the fragment
00:16:53
function through the interpolator struct
00:16:55
a technique that we'll use later on
00:16:57
the fragment function outputs a float4
00:17:00
the color of the pixel it might be
00:17:02
strange to think about but colors are
00:17:04
just vectors they contain a red green
00:17:07
blue and alpha value each ranging from 0
00:17:09
to 1. to let the pipeline know that
00:17:11
we're returning the final pixel color
00:17:14
tag the entire fragment function with
00:17:16
the sv underscore target semantic when
00:17:19
tagging a function with a semantic the
00:17:21
compiler interprets the return value as
00:17:23
having that semantic
00:17:25
so we can finally display something on
00:17:27
screen now let's just color all pixels
00:17:29
white return a float4 with all
00:17:32
components set to 1.
00:17:34
see here that you don't need to write
00:17:35
new in hlsl when constructing vectors
00:17:39
just the type name is fine
00:17:41
the last stage in the graphics pipeline
00:17:43
is the presentation stage it takes the
00:17:46
output of the fragment function and
00:17:48
together with information from the
00:17:49
rasterizer colors all pixels accordingly
00:17:53
there's one last thing to do we need to
00:17:55
register our vertex and fragment
00:17:57
functions to a shader pass
00:17:59
return to the mylet.shader file tell the
00:18:02
compiler to read the code inside your
00:18:04
myletforwardlitpass.hlsl
00:18:06
file using a hash include command
00:18:09
next register the vertex and fragment
00:18:11
functions using a hash pragma command
00:18:14
hashpragma has a variety of uses
00:18:16
relating to shader metadata but the
00:18:19
vertex and fragment sub-commands
00:18:21
register the corresponding functions to
00:18:23
the containing pass
00:18:24
make sure that the function names match
00:18:26
those in your hlsl file
00:18:30
and we're now finally ready to view your
00:18:32
shader make sure the material has mylet
00:18:35
selected and create a sphere in your
00:18:37
scene give it your material it should
00:18:40
now appear as a flat white circle
00:18:45
if it's colored magenta or there's some
00:18:47
other issue check unity's console and
00:18:49
the shader asset to see if there are any
00:18:51
errors
00:18:56
okay so we have a flat white circle now
00:18:58
that's a good starting place let's make
00:19:00
the color adjustable from the material
00:19:03
inspector this is possible through a
00:19:05
system unity calls material properties
00:19:08
material properties are essentially hlsl
00:19:11
variables that can be set and edited
00:19:13
through the material inspector in unity
00:19:15
they are specified per material and
00:19:18
allow objects using the same shader to
00:19:20
look different
00:19:21
if you are wondering what's the
00:19:22
difference between a shader and a
00:19:24
material this is basically it a material
00:19:27
is a shader with specific property
00:19:29
settings
00:19:31
we can define properties inside the dot
00:19:33
shader file with a properties block
00:19:36
the syntax for these is inconsistent but
00:19:39
i'll explain it
00:19:41
to define a color property first decide
00:19:43
on a reference name
00:19:45
this is how you'll access a property in
00:19:47
hlsl
00:19:49
by convention property names start with
00:19:51
an underscore
00:19:52
follow that with a parentheses pair like
00:19:54
you're writing a function
00:19:56
the first argument is a string
00:19:58
this is a label how it will display in
00:20:00
the material inspector
00:20:02
the next argument is the property type
00:20:05
there are various but color defines a
00:20:08
color property
00:20:09
close the parentheses and then set a
00:20:11
default value the syntax is different
00:20:14
for each property type
00:20:15
but for colors start with an equal sign
00:20:18
and then the red green blue alpha values
00:20:21
inside of parentheses
00:20:24
as mentioned before
00:20:25
colors are just four float values each
00:20:28
corresponding to a color channel
00:20:30
red green blue and alpha
00:20:33
these combine to create any color that a
00:20:36
computer can display
00:20:38
each number ranges from zero to one
00:20:40
where white is all ones and black is all
00:20:42
zeros
00:20:43
for alpha one is opaque and zero is
00:20:46
invisible if you'd like more info on how
00:20:48
these numbers combine to create a color
00:20:51
i have a link in the video description
00:20:54
now you should be able to see your
00:20:55
property in the material inspector
00:20:58
later this shader will have many
00:21:00
properties so we should organize them
00:21:02
add a header label denoting surface
00:21:04
options to do that use this header
00:21:07
command strangely the label is not
00:21:09
enclosed in quotation marks here
00:21:12
there's one last thing that we should do
00:21:14
properties can be tagged with attributes
00:21:16
like classes in c sharp these give
00:21:18
properties special features
00:21:20
tag color tint with the main color
00:21:22
attribute
00:21:24
now it's possible to easily set this
00:21:25
property from c sharp using
00:21:27
material.color
00:21:30
the property is all set up but the value
00:21:32
is not reflected on screen
00:21:35
open myletforwardlitpass.hlsl
00:21:38
although we defined a property in
00:21:39
shaderlab we must also define it here in
00:21:42
hlsl
00:21:43
make sure the reference name matches
00:21:45
exactly
00:21:47
unity will automatically synchronize
00:21:49
this variable with the material
00:21:50
inspector
00:21:52
earlier i did say that vertex and
00:21:54
fragment functions could only access
00:21:56
data from a single vertex or fragment
00:21:58
and while this is true they can also
00:22:01
access any material properties
00:22:03
these variables are uniform meaning they
00:22:06
don't change while the pipeline is
00:22:07
running
00:22:09
unity sets them before the pipeline
00:22:10
begins and you cannot modify them from a
00:22:13
vertex or fragment function
00:22:15
with this in mind have the fragment
00:22:17
function return color tint as the final
00:22:19
color
00:22:21
return to the scene editor select your
00:22:23
material and change the color tint
00:22:25
property
00:22:26
the shader should immediately reflect
00:22:28
your choice
00:22:33
flat colors are great but it'd be really
00:22:36
cool to vary the color across the sphere
00:22:38
we can do this with textures
00:22:41
shaders love working with textures
00:22:43
they're just image files but shaders
00:22:45
think of them as 2d arrays of color data
00:22:48
when you zoom into a texture this does
00:22:50
become pretty obvious
00:22:52
to add a texture to a shader first add a
00:22:54
texture material property
00:22:57
defining a texture property is much the
00:22:59
same as a color property
00:23:01
instead of listing a typos color set it
00:23:03
to 2d
00:23:04
the syntax for default textures is kind
00:23:07
of strange following the equal sign type
00:23:10
white with quotes followed by a pair of
00:23:12
curly braces
00:23:14
if no texture is set in the material
00:23:15
inspector unity will fill this property
00:23:18
with a small white texture by default
00:23:20
you can also set the default color to
00:23:22
black gray or red
00:23:25
similarly to the main color attribute
00:23:27
there is also a main texture attribute
00:23:30
tagging this property makes it easily
00:23:31
assignable from c sharp using
00:23:33
material.main texture your property
00:23:36
should now show up in the material
00:23:37
inspector
00:23:39
notice the four numbers beside it they
00:23:41
allow you to set an offset and scale for
00:23:43
this texture which is useful for tiling
00:23:47
now let's take a look at the hlsl side
00:23:49
of things
00:23:50
defining a texture variable is a bit
00:23:52
more complicated than a color variable
00:23:55
you first must use this special syntax
00:23:57
to define a 2d texture once again the
00:24:00
name must match the property reference
00:24:02
exactly texture 2d here is not a type
00:24:06
but something called a macro
00:24:08
you can think of macros similarly to
00:24:10
functions except they run on the text
00:24:13
making up code
00:24:14
you can create macros yourself using the
00:24:16
hash define command
00:24:18
before compiling the system will search
00:24:21
for any text matching a defined macro
00:24:23
and replace the macro name with the text
00:24:26
that you specify
00:24:27
macros can also have arguments
00:24:30
the system will replace any occurrences
00:24:32
of argument names in the macro
00:24:33
definition with whatever text that you
00:24:35
pass in
00:24:36
this is a really simple overview of
00:24:38
macros but they can be pretty useful in
00:24:40
shader code hlsl doesn't have
00:24:43
inheritance or polymorphism so if you
00:24:45
want to work with any structure that has
00:24:47
a position os field but you don't
00:24:49
necessarily know the structure type a
00:24:51
macro can do the trick
00:24:53
here's an example
00:24:55
they're also great at handling platform
00:24:57
differences which is what unity has done
00:24:59
with texture2d see different graphics
00:25:01
apis like directx opengl etc use
00:25:05
different type names for textures to
00:25:07
make shader code platform independent
00:25:10
unity provides a variety of macros to
00:25:12
deal with textures
00:25:13
that's just one less thing that we have
00:25:15
to worry about
00:25:16
moving on there are a couple more
00:25:18
variables that unity automatically sets
00:25:20
when you define a texture property
00:25:22
textures have a companion structure
00:25:24
called a sampler which defines how to
00:25:26
read a texture options include the
00:25:29
sampling and clamping mode that you're
00:25:30
familiar with from the texture importer
00:25:32
point by linear etc unity stores
00:25:35
samplers in a second variable which you
00:25:37
define with the sampler macro
00:25:39
the name here is important it must
00:25:42
always have the pattern sampler followed
00:25:44
by the texture reference name
00:25:46
finally remember the tiling and offset
00:25:48
values from the material inspector
00:25:51
unity stores those inside of a float4
00:25:53
variable
00:25:54
the name must follow the pattern of the
00:25:56
texture name followed by st
00:25:59
inside the x and y components hold the x
00:26:02
and y scales while the z and w
00:26:04
components hold the x and y offsets
00:26:07
and yes the fourth component of a float4
00:26:09
vector is referred to as w in hlsl
00:26:14
now we'd like to sample the texture or
00:26:16
read color data from it
00:26:18
we should do that in the fragment stage
00:26:20
to apply texture colors to each pixel
00:26:23
use the sample texture 2d macro to get
00:26:26
the color out of a texture at a specific
00:26:28
location
00:26:29
it takes three arguments the texture the
00:26:32
sampler and the uv coordinate to sample
00:26:36
well what are uvs
00:26:38
uvs are texture coordinates assigned to
00:26:40
all vertices of a mesh
00:26:43
which define how a texture wraps around
00:26:45
a model
00:26:47
think of how cartographers try to unwrap
00:26:49
a globe to fit on a flat map they're
00:26:52
basically assigning uvs to positions on
00:26:54
the globe
00:26:55
uvs are float 2 variables where the x
00:26:58
and y coordinates define a 2d position
00:27:00
on a texture uvs are normalized or
00:27:02
independent of the texture's dimensions
00:27:05
they always range from 0 to 1 and by
00:27:07
convention 0 0 is the bottom left corner
00:27:10
of a texture
00:27:12
unfortunately we can't grab uvs out of
00:27:14
thin air in the fragment stage they're
00:27:17
another vertex data stream that the
00:27:18
input assembler needs to gather
00:27:21
add a float2 uv field to the attribute
00:27:23
structure with a text chord 0 semantic
00:27:26
text chord 0 is short for texture
00:27:29
coordinate set number 0.
00:27:31
models can have many sets of uvs or
00:27:33
texture coordinates for instance unity
00:27:35
uses tech scored 1 for light map uvs but
00:27:38
we'll get to that later
00:27:40
the attribute struct is not available in
00:27:42
the vertex stage either however we can
00:27:44
store data in the interpolator struct
00:27:46
which will eventually make its way to
00:27:48
the fragment stage
00:27:49
add another float 2 uv field there
00:27:52
have it also used the text chord 0
00:27:54
semantic
00:27:56
in the vertex function past the uv from
00:27:58
the attribute struct to the
00:27:59
interpolator's tract we can also apply
00:28:02
uv scaling and offset there which we
00:28:04
might as well
00:28:06
this way we'll only have to compute it
00:28:07
once per vertex instead of once per
00:28:09
pixel
00:28:10
it's a good idea to do as much as
00:28:11
possible in the vertex function since it
00:28:14
generally runs fewer times than the
00:28:15
fragment function
00:28:17
unity provides the transform text macro
00:28:19
to apply tiling
00:28:21
there are two interesting things about
00:28:22
it
00:28:23
first the double hash tells the
00:28:25
pre-compiler to append text to whatever
00:28:28
is passed in as the macro argument
00:28:30
when the macro runs you can see how it
00:28:32
replaces name with underscore color map
00:28:34
correctly referencing color map st
00:28:38
second the x y and zw suffixes give easy
00:28:42
access to a pair of components as a
00:28:43
float 2. this mechanism is called
00:28:45
swizzling you can ask for any
00:28:48
combination of the x y z and w
00:28:50
components in any order the compiler
00:28:53
will construct an appropriately sized
00:28:54
float vector variable for you
00:28:56
you can also use rgb and a the same way
00:29:00
which is more intuitive for colors
00:29:02
it's even possible to assign values with
00:29:04
a swizzle operator
00:29:05
anyway
00:29:06
now we have the uv data in the fragment
00:29:08
stage but let's take a moment to really
00:29:11
think about what's happening here
00:29:13
the vertex function outputs data for
00:29:15
each vertex the rasterizer takes those
00:29:17
values places the vertices on the screen
00:29:20
and figures out what pixels cover the
00:29:22
formed triangle
00:29:24
it finally generates an input structure
00:29:26
for each fragment function call but what
00:29:28
value will input uv have for each
00:29:31
fragment
00:29:32
the rasterizer will interpolate any
00:29:34
field tagged with a text chord semantic
00:29:36
using an algorithm called barycentric
00:29:38
interpolation
00:29:40
you're probably familiar with linear
00:29:42
interpolation where a value on a number
00:29:44
line is expressed as the weighted
00:29:46
average of the values at each endpoint
00:29:49
barycentric interpolation uses the same
00:29:51
idea except extends it to a triangle
00:29:54
the value at any point inside the
00:29:55
triangle is a weighted average of the
00:29:57
values at each corner
00:29:59
luckily the rasterizer handles all of
00:30:01
this for us so the algorithm is not
00:30:03
really important
00:30:06
to recap the values and interpolators
00:30:08
are a combination of values returned by
00:30:10
the vertex function
00:30:12
specifically for any fragment they are a
00:30:14
combination of values from the three
00:30:16
vertices forming the triangle that
00:30:18
covers this fragment's pixel
00:30:22
well all that for some uvs but we
00:30:25
finally have all that we need to call
00:30:27
sample texture 2d
00:30:29
it returns a float for the color of the
00:30:31
texture at the specified uv position
00:30:34
depending on the sampler sample mode
00:30:36
point by linear etc this color may be a
00:30:39
combination of adjacent pixels to help
00:30:42
smooth things out
00:30:43
regardless multiply the sample with the
00:30:45
color tint property and then return it
00:30:48
in hlsl multiplying two vectors is a
00:30:51
component-wise operation meaning the
00:30:53
x-components of each vector are
00:30:54
multiplied together then the
00:30:56
y-components etc all arithmetic
00:30:58
operators work like this
00:31:01
in the scene editor set a texture on
00:31:03
your material and marvel at what you've
00:31:05
accomplished
00:31:08
note how the texture and color tint
00:31:09
properties interact
00:31:12
also notice that if your texture has an
00:31:14
alpha component the shader doesn't
00:31:17
really handle transparency yet so the
00:31:19
sphere will always be opaque
00:31:22
we'll fix that in a future tutorial so
00:31:24
stay tuned
00:31:27
i hope that this wet your appetite for
00:31:29
shader programming because we're really
00:31:31
just getting started
00:31:33
in the next part of this tutorial series
00:31:35
we'll add simple lighting to finally
00:31:36
give objects dimensionality and then
00:31:38
we'll delve into shadows learning how to
00:31:40
add additional passes to a shader
00:31:44
you've gotten past a lot of the theory
00:31:46
and can now focus on the fun stuff
00:31:48
please stay tuned and subscribe and
00:31:50
press the bell to be notified when my
00:31:51
next tutorial video goes live
00:31:54
if you enjoyed this consider liking the
00:31:56
video as well it really helps out with
00:31:58
the youtube algorithm
00:32:00
if you have any issues or questions
00:32:02
please feel free to leave a comment or
00:32:04
contact me on any of my social media
00:32:05
accounts
00:32:07
i want to take another moment to thank
00:32:09
all of my patrons for helping make this
00:32:11
video possible and give a big shout out
00:32:13
to my next gen patron croobiedoobydoo
00:32:16
again thank you all for your support it
00:32:18
really does mean a lot and if you want
00:32:20
to download an example trader from this
00:32:22
tutorial or any of my others you can
00:32:25
join my patreon as well
00:32:27
and finally don't forget to check out
00:32:28
kitty cat squash
00:32:30
thanks again inspired by madness games
00:32:32
for sponsoring this video
00:32:35
everyone thanks so much again for
00:32:36
watching and make games
00:32:40
[Music]
00:32:53
you

Description:

Play Kitty Cat Squash ► https://store.steampowered.com/app/1814110/Kitty_Cat_Squash/ ✔️ Tutorial tested in 2020.3 and 2021.3 🚨 Edits: If you create your project from a template, ensure "Depth Priming Mode" is set to "Disabled" in your URP settings asset. To find this asset, open Project Settings, navigate to Graphics, and select the renderer asset at the top of the window. Would you like to start writing shaders but don’t know where to start? Or, have you encountered a limitation of URP’s Shader Graph you need to overcome? In this tutorial series, I’ll walk you through writing a fully featured, general purpose shader for Unity’s Universal Render Pipeline — exclusively in code. Don't know HLSL or ShaderLab? No problem. Tutorial series: 📰 Article version ►https://nedmakesgames.medium.com/writing-unity-urp-shaders-with-code-part-1-the-graphics-pipeline-and-you-798cbc941cea 🔀 Playlist ► https://www.youtube.com/playlist?list=PLAUha41PUKAYdsStTcjJbNV-GM3F2xm9s 1️⃣ The Graphics Pipeline ► You're watching it! 2️⃣ Lighting and Shadows ► https://www.youtube.com/watch?v=1bm0McKAh9E 3️⃣ Transparency ► https://www.youtube.com/watch?v=4zw6Vq5CzLY 4️⃣ PBR Materials ► https://www.youtube.com/watch?v=5GGISvt4KEA 5️⃣ Advanced Lighting ► Coming soon 6️⃣ Advanced URP Features ► Coming soon 7️⃣ Custom Lighting Models ► Coming soon 8️⃣ Vertex Animation ► Coming soon 9️⃣ Interacting with C# ► Coming soon 👑 Join my Patreon to access tutorials early, download project files, vote on future topics, and more! Thank you so much! ► https://www.patreon.com/nedmakesgames 🔗 Check out my website for a searchable list of tutorials! ► https://nedmakesgames.github.io/ 2️⃣ 2nd Channel ► https://www.youtube.com/nedmakesgames2 🔴 Twitch ► https://www.twitch.tv/nedmakesgames 🐦 Twitter ► https://twitter.com/nedmakesgames 🎮 Discord ► https://discord.com/invite/ubxSVBK 📸 Instagram ► https://www.facebook.com/unsupportedbrowser 👽 Reddit ► https://reddit.com/u/nedmakesgames 🎶 TikTok ► https://www.tiktok.com/@nedmakesgames ☕ Ko-fi ► https://ko-fi.com/nedmakesgames 📚 Reference scripts ► Flat white: https://gist.github.com/NedMakesGames/e102eaf3b0918a75d538053ab1853914 ► Flat color: https://gist.github.com/NedMakesGames/863ecfbe1c77dc9aefb4d5ebc72d19c9 ► Textures: https://gist.github.com/NedMakesGames/a10b965c8b453e07e9cedb29f155ee3b ⏲️ Timestamps: 0:00 Intro 0:53 Ad 1:26 Tutorial scope 2:58 Project set up 4:50 ShaderLab 7:02 Intro to HLSL 8:52 The Graphics Pipeline 9:34 The Input Assembler 11:09 The Vertex Stage 12:40 Spaces 15:45 The Rasterizer 16:04 The Fragment Stage 15:52 Hello World 18:54 Properties in ShaderLab 21:34 Properties in HLSL 22:31 Texture Properties 23:46 Macros 25:16 Sampling a Texture 26:35 What Are UVs 27:12 UVs in the Vertex Function 29:06 Interpolation 30:22 Hello Textures 31:26 Wrap up and credits 🎖️ Credits, references and further reading: • Unity Technologies: Shader Calibration Scene - https://assetstore.unity.com/packages/templates/tutorials/shader-calibration-scene-25422 • shedmon: Wooden Slingshot - https://sketchfab.com/3d-models/wooden-slingshot-a909ff4b85a64acebe23795967aa9fe3 • Martijn Vaes: DAE — Bilora Bella 46 Camera — Game Ready Asset - https://sketchfab.com/3d-models/dae-bilora-bella-46-camera-game-ready-asset-eeb9d9f0627f4783b5d16a8732f0d1a4 • tonyflanagan: Thailand Girl — Animated - https://sketchfab.com/3d-models/thailand-girl-animated-a41f779fe45b4a04bdbf212e49b7f6b5 • Kelvin Valerio: Brown Cat with Green Eyes - https://www.pexels.com/photo/brown-cat-with-green-eyes-617278/ • owowowsam: Mini Earth - https://www.cgtrader.com/free-3d-models/space/planet/mini-earth • Tom Patterson: Natural Earth III - http://www.shadedrelief.com/natural3/pages/textures.html • W3schools: CSS RGB Colors - https://www.w3schools.com/css/css_colors_rgb.asp Music: https://www.purple-planet.com/

Preparing download options

popular icon
Popular
hd icon
HD video
audio icon
Only sound
total icon
All
* — If the video is playing in a new tab, go to it, then right-click on the video and select "Save video as..."
** — Link intended for online playback in specialized players

Questions about downloading video

mobile menu iconHow can I download "The Graphics Pipeline and You | Writing Unity URP Code Shaders Tutorial [1/9] ✔️ 2021.3" video?mobile menu icon

  • http://unidownloader.com/ website is the best way to download a video or a separate audio track if you want to do without installing programs and extensions.

  • The UDL Helper extension is a convenient button that is seamlessly integrated into YouTube, Instagram and OK.ru sites for fast content download.

  • UDL Client program (for Windows) is the most powerful solution that supports more than 900 websites, social networks and video hosting sites, as well as any video quality that is available in the source.

  • UDL Lite is a really convenient way to access a website from your mobile device. With its help, you can easily download videos directly to your smartphone.

mobile menu iconWhich format of "The Graphics Pipeline and You | Writing Unity URP Code Shaders Tutorial [1/9] ✔️ 2021.3" video should I choose?mobile menu icon

  • The best quality formats are FullHD (1080p), 2K (1440p), 4K (2160p) and 8K (4320p). The higher the resolution of your screen, the higher the video quality should be. However, there are other factors to consider: download speed, amount of free space, and device performance during playback.

mobile menu iconWhy does my computer freeze when loading a "The Graphics Pipeline and You | Writing Unity URP Code Shaders Tutorial [1/9] ✔️ 2021.3" video?mobile menu icon

  • The browser/computer should not freeze completely! If this happens, please report it with a link to the video. Sometimes videos cannot be downloaded directly in a suitable format, so we have added the ability to convert the file to the desired format. In some cases, this process may actively use computer resources.

mobile menu iconHow can I download "The Graphics Pipeline and You | Writing Unity URP Code Shaders Tutorial [1/9] ✔️ 2021.3" video to my phone?mobile menu icon

  • You can download a video to your smartphone using the website or the PWA application UDL Lite. It is also possible to send a download link via QR code using the UDL Helper extension.

mobile menu iconHow can I download an audio track (music) to MP3 "The Graphics Pipeline and You | Writing Unity URP Code Shaders Tutorial [1/9] ✔️ 2021.3"?mobile menu icon

  • The most convenient way is to use the UDL Client program, which supports converting video to MP3 format. In some cases, MP3 can also be downloaded through the UDL Helper extension.

mobile menu iconHow can I save a frame from a video "The Graphics Pipeline and You | Writing Unity URP Code Shaders Tutorial [1/9] ✔️ 2021.3"?mobile menu icon

  • This feature is available in the UDL Helper extension. Make sure that "Show the video snapshot button" is checked in the settings. A camera icon should appear in the lower right corner of the player to the left of the "Settings" icon. When you click on it, the current frame from the video will be saved to your computer in JPEG format.

mobile menu iconWhat's the price of all this stuff?mobile menu icon

  • It costs nothing. Our services are absolutely free for all users. There are no PRO subscriptions, no restrictions on the number or maximum length of downloaded videos.