50
Real-time volumetric effects Andrei Tatarinov

Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

  • View
    215

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

Real-time volumetric effects

Andrei Tatarinov

Page 2: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Talk outline

Introduction

Part I – Generating fire with Perlin noise

Part II – Generate smoke using 3D fluid simulation

Part III – Rendering volumetrics

Page 3: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Why is this cool?

Volumetrics represent such common effects as fog, smoke, fire, explosions

Current approaches to rendering volumetrics in games have limitations

Video textures

Particle systems

Page 4: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

What do we have now?

Most volumetric effects are represented as sets of video textures

Everything looks cool until effect intersects an obstacle

Page 5: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Why now?

Sheer number of operations needed can only be supported by modern high end GPUs

New features in DirectX10Render to 3D texture

Integer maths

Geometry Shader

Stream Out

Page 6: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Part I - FireOutline

Perlin noise overview

Simplex noise overview

Ways to generate procedural textures

How to generate a flame using Perlin noise

Page 7: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Perlin Fire

Fire in NVIDIA’s DirectX10 SDK Sample

Page 8: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Perlin noise

Given an input point P

Find its neighboring grid points Q

For each grid point

Pick pseudo-random gradient vector G

Compute linear function G * (P - Q)

Interpolate between values in grid points

Page 9: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Random Number generation on GPU

Use a set of “power” and “modulation” operations, using some big prime number as a modulation base

Use a permutation texture

R = PermTex.Sample ( P.yw + PermTex.Sample ( P.xz ) )

Page 10: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Simplex Noise

The same as Perlin noise, but using a simplex grid instead of hypercube grid

For a space with N dimensions, simplex is the most compact shape that can be repeated to fill the entire space

Using simplex grid can significantly reduce a number of interpolations

Page 11: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Procedural Textures

Use a weighted sum of several noise frequencies to create a texture

+ + + + =

=

Page 12: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Procedural Textures

Try noise in different expressions

noise sin (x + sum 1/f( |noise| ))

sum 1/f(noise) sum 1/f( |noise| )

Page 13: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Volumetric Effects

Use noise to animate turbulent flow Flame

Clouds

Page 14: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Flame

Take a basic fire shape and revolve it around y-axis to create a fire unit

Fire shape can be customized to achieve different look and feel

Basic shape Fire unit

y

Page 15: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Flame

Perturb fire unit with 4D noise (4th component stands for time)

+ =

Fire unit Perlin noise turbulence field

Flame

Page 16: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

FlameUse a weighted sum of several noise frequencies. Change weights to achieve different look

+ + + + =

=

Page 17: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Part II - SmokeOutline

Why 3D fluid simulation is important

Overview of process

Fluid simulation basics

Dynamic arbitrary boundaries

Page 18: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Smoke

Smoke in NVIDIA’s DirectX10 SDK Sample

Page 19: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Overview

Composite on top of scene

Render

Discretize space and simulate

Decide where to place the smoke

Scene

Page 20: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Fluid Simulation

A fluid (with constant density and temperature) is described by a velocity and pressure field

Navier-Stokes equations mathematically defines the evolution of these fields over time; impose that the field conserves both mass and momentum

To use these equations we discretize the space into a grid

Define smoke density, velocity and pressure at the center of each grid cell

At each time step, we use the equations to determine the new values of the fields

Pressure DensityVelocity

Page 21: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Fluid Simulation steps

Advect Advect

AddDensity

AddVelocity Project

Density

Velocity

Iterate

Pressure

Density DensityVelocity Velocity Velocity

Pressure

Each time step

* We skip the diffusion step

Initialize

Page 22: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Advect

Velocity

Density

Time Step t

Time Step t + 1

Density

Page 23: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Fluid Simulation on the GPU

Velocity, Density, Pressure → Textures

Simulate one substep for entire grid → Render a grid sized, screen aligned, quad

Calculations for a grid cell → Pixel Shader

Output values → using Render to Texture

Page 24: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Advect on the GPU

Density Texture at timestep t

Velocity Texture at timestep t

rasterized rendered

Texture fetch Texture fetch

Render TargetDensity for timestep t+1

Quad

M

O

M

O

M

O

M

O

Pixel Shader

PS_ADVECT

calculate new

density for this grid

cell using the

density and velocity

textures from the

previous time step

Velocity in x

Vel

ocity

in y

Page 25: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Texture fetchTexture fetch

GS is used to

rasterize each

quad to proper

layer in output

Render Target

Advect on the GPU in 3D

Density Texture at timestep t

Velocity Texture at timestep t

rasterized rendered

Pixel Shader Render TargetDensity for timestep t+1

N Quads

M

O

M

OM

PS_ADVECT

calculate new

density for this grid

cell using the

density and velocity

textures from the

previous time step

N

OM

N

O

N

Page 26: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Obstacles

Smoke interacting with

obstacles and compositing with the sceneSmoke only compositing with the scene

Page 27: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Obstacles

Implicit shapes Like spheres, cylinders

Voxelize objects Static : Voxelize just once, offline

Moving:Voxelize objects per frame

Obstacle texture

Fluid cell inside obstacle

Fluid cell outside obstacle

Page 28: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Dealing with Obstacles

How should the fluid react to obstacles?The fluid should not enter obstacles cells

If the obstacles are moving they should impart the correct velocity on the fluid

How the fluid reacts to the obstacles → Boundary Conditions

Page 29: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Boundary Conditions for Density

No density should be added to or advected into the interior of obstacles

Density Obstacles

Page 30: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Boundary Conditions for Pressure

Derivative of the pressure across the boundary should be zero

(Neumann boundary conditions - specifying derivative )

cell1

u

vcell2

PressureCell1 – PressureCell2 = 0

PressureCell1 = PressureCell2

Page 31: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Boundary Conditions for Velocity

The velocity normal to the boundary of the obstacle should be equal for fluid and obstacle

(Dirichlet boundary conditions – specifying value)

u

v

Page 32: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Voxelizing an object

Obstacle texture

Obstacle Velocity texture

Page 33: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Use low res collision model for voxelization

Page 34: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Voxelizing a simple object

?

Page 35: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Voxelizing a simple object

Orthographic camera

Near plane

Far plane

Stencil Buffer

Decrement on back faces Increment on front faces

Page 36: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Voxelization

… … …

2DArray of N stencil buffers

Render model N times, each time with a different near plane

Page 37: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Part III - RenderingOutline

Ray marching

Occluding the scene

Artifacts and ways to avoid them

Page 38: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Rendering

Render front faces of box

Raycast into the3D Density texture

Composite into scene

Page 39: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Raycasting into 3D texture

What we have What we don’t have

- Ray from eye to box - Ray in texture space

Transform from world to texture space

Transform from world to texture space

Transform from world to grid space

- Ray box intersection

- Distance the eye ray traverses through the box

- Ray entry point in the texture

- Number of voxels the ray traverses = Number of samples to take

3D Density Texture

Page 40: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Raycasting: blending

FinalColor.rgba = 0 FinalColor.rgb += sampleColor.rgb * SampleColor.a *(1.0 – FinalColor.a)FinalColor.a += SampleColor.a * (1.0 – FinalColor.a)

Density Texture

= Trilinear samplefrom 3D texture

Render Fullscreen quad to frame buffer

RayDataTexture

PositionInTexture = TransformToTexSpace(RayDataTexture.rgb)

MarchingVector = TransformToTexSpace(eye - RayDataTexture.rgb)

NumberOfSamples = TransformToGridSpace(RayDataTexture.a)

Page 41: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Occluding the scene

Smoke correctly compositing with the scene

Smoke directly blended on top of the scene

Page 42: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Integrating scene depth

Page 43: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Artifacts

During the ray-marching use jittering to avoid banding

Without jittering With jittering

Page 44: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Jittered sampling

During the ray-marching use jittering to avoid banding

Page 45: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

ArtifactsIncrease sampling rate to reduce a noise caused by jittering

Increasing sampling rate leads to performance loss

Low sampling rate High sampling rate

Page 46: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Artifacts

Correctly using the depth by weighted samplingArtifacts resulting from an integral number of samples

Page 47: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Correctly integrating scene depth by weighting the last sample

FinalColor.rgb += d/sampleWidth * SampleColor.rgb * SampleColor.a * (1.0 – FinalColor.a)FinalColor.a += d/sampleWidth * SampleColor.a * (1.0 – FinalColor.a)

sampleWidth

d

Page 48: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Combining techniques

Page 49: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Conclusion

Interactive volumetric effect simulation at reasonable grid resolutions is feasible for games

We presented here a brief overview of the entire process

More informationNVIDIA DirectX10 SDK code sample

Upcoming GPU Gems3 article

Page 50: Real-time volumetric effects Andrei Tatarinov. NVIDIA Confidential Talk outline Introduction Part I – Generating fire with Perlin noise Part II – Generate

NVIDIA Confidential

Questions?