top of page
Shader Optimization
These are some techniques I learned from classes at Gnomon taught by Anton Napierala, Ben Cloward's Shading series, book The Unity Shaders Bible by Fabrizio Espindola.
The principles of shader optimization
Move math to a cheaper stage
Move to Vertex Shader
Move to the CPU
Reduce Math Calculations
Simplify equations
Don't calculate redundantly
Don't over normalize
Pixel Clip
Optimizing Texture Sampling
Sample fewer texture
Make textures smaller
Compress textures
Reduce texture filtering
These are the 3 categories of shader optimization. Let's first get into the first one, move math to a cheaper stage. We need to understand the basics of the graphics pipeline to know which part of the computer you need to move the operation to in order for it to be cheaper.
Graphics Pipeline - Transforming 3D data to our 2D monitor screen
CPU
3D software
Send vertex data to GPU
GPU
Vertex Processor
Cheap
Convert the vertices to screen projection space
Primitive Assembly
connect vertices into triangles
Rasterizer
converts triangles into pixels
Pixel Processor
Expensive
Calculate colors of pixels
Optimize by pushing some operations that are in the Pixel Shader to the Vertex Shader
Output image
Unreal - How to know which operation is in the vertex or pixel shader?

Find ways to lower the Pixel Shader's instructions count will make the shader chaper*
*This is a preliminary measurment of cost, to find the most accurate performance measure, you must package the build and test it in a performance software like PIX*

If doing things like UV scrolling, moving vertices, using VertexInterpolator node will push the operation from Pixel to Vertex shader so we don't have to move every pixel
Knowing the cost of each node in the shader graph and chose to use cheaper ones if possible
Use Saturate instead of Clamp when clamping between 0-1
Use Add / Mulitply instead of Divide / Subtract / Power

Use Swizzle instead of CustomRotator to rotate texture 90 degrees

Use custom node setup instead of BlendAngleCorrectedNormals to blend normal maps

Using shaders to optimize rendering
> Computing reflections and refraction in the shader
It can be cheaper to map our environment reflection texture onto our object manually rather than having to calculate the light reflections in-engine.
LatLong Projections
Projecting HDRI map into our object to resemble its reflection.

Cube Map
Projecting our game environment into a map to be used for reflection


To make a cube map, render 6 images of our environment using 90 FOV camera and square aspect ratio, then compose them into one map using photoshop.
The basic LatLong projection setup. The LogLatToUV node could be replaced with :


Use reflection vector as UV of our cube map
Manually transforming U and V of the refelction vector is cheaper

Projection result

Projection result
> Using cube map for room interior mapping
This method is used to fake 3 dimentional depth. It is common to use it to map room interior to be seen only from the outside without having to model the room.

source : 80lvl article about Spiderman game

source : Polycount
source : 80lvl article about Spiderman game


Optimizing Texture Sampling
This method is all about reducing the size of our texture before being sampled into our shader.
Factors that control texture size
- Resoloution
- Number of channels
- Compression type

credit : Ben Cloward
We can conclude that :
- Dropping texture resolution 1 step will reduce the size 4 times
- Using 4k texture is very expensive
- Uncompressed textures need to be low resolution
- Using an alpha channel doubles the cost

Make sure to turn off Alpha if unused.
Use DXT1 compression for roughness, AO, Specular
Remove unnessecery channels
Terrain/foliage : Normal map Z direction could be opted out and computed manually, pack other masks in that channel, compression type will make normal lose a bit of quality but won't suffer quality loss since terrain will mostly be covered by other assests.

Channel packing
You should always pack the roughness texture into the Alpha channel of base color to avoid loading another entire texture.
Pack black and white mask textures into R / G / B channels of one single texture.
Texture array

Denim
Felt
Leather
Combine multiple normal maps into one texture array that only has to be loaded once.
Good for character clothing with a lot of materials.

bottom of page