SlideShare una empresa de Scribd logo
1 de 44
GenerativeArt–MadewithUnity
Customizing a Production Pipeline
(Lightweight Render Pipeline)
Felipe Lira
Graphics Programmer
Unity Technologies
1
Note: If you are using a laptop download Unity 2018.2
and the following project: bit.ly/siggraph18
2
Workshop Pre-requisites
●If you are on a SIGGRAPH computer
○ Start Unity and open SIGGRAPH2018-WORKSHOP
project in your Desktop
●If you are on your own computer
○ Download Unity 2018.2
○ Download the following project bit.ly/siggraph18
○ Start Unity and open the project you downloaded
●Slides: bit.ly/siggraph18_slides
3
Workshop Agenda
●What is the Lightweight Render Pipeline (LWRP)
●Add LWRP to your project
●Convert a project to use LWRP
●Overview of LWRP rendering
●Customize LWRP renderer by adding custom passes
●Override LWRP renderer to implement a deferred renderer
4
What is Lightweight Render Pipeline (LWRP)
●It’s a Scriptable Render Pipeline (SRP)
○ Rendering API exposed in C#
○ Open Source: https://github.com/Unity-Technologies/ScriptableRenderPipeline
●LWRP
○ Currently 1 of 2 of our inhouse Render Pipelines we are developing
○ Designed from the ground up to perform at best on mobile hardware
○ Modern APIs in mind, as well as Legacy APIs, eg GLES 2.0
5
Why should you care about SRP and LWRP
●If you are
○ Student:
■ Learn Graphics Programming with a robust API
○ Game Developer:
■ Performance out of the box, explicit, lean and extensible
○ Researchers:
■ Implement, deploy and profile your research many platforms
6
7
Checkpoint!
●Open DemoScene
●You should see something like this
8
How to get SRP and LWRP
●In this workshop you already have it!
○ The project you are using is bundled with LWRP for simplicity
9
How to get SRP and LWRP
●You can also get it by creating a new project with LWRP
template
10
How to get SRP and LWRP
●Or by downloading from package manager UI
11
So now you have it!
● Let’s convert your project to use LWRP
12
Checkpoint!
●Created LWRP asset
○ Assets -> Create -> Rendering -> Lightweight Pipeline Asset
●Assigned LWRP to Graphics Settings
○ Edit -> Project Settings -> Graphics Settings
○ Drag and Drop LWRP asset in SRP settings
●Upgraded materials to LWRP materials
○ Edit -> Render Pipeline -> Upgrade Project Materials …
●Checked rendering settings in LWRP asset
●You should have the same image as before converting
13
Before coding let’s take a look at
core LWRP rendering
14
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
SetupPerFrameShaderConstants();
foreach (Camera camera in cameras)
{
CameraData cameraData;
InitializeCameraData(camera, out cameraData);
SetupPerCameraShaderConstants(cameraData);
CullResults.Cull(cullingParameters, context, cullResults);
List<VisibleLight> visibleLights = cullResults.visibleLights;
RenderingData renderingData;
InitializeRenderingData(cameraData, visibleLights, out renderingData);
var setup = cameraData.camera.GetComponent<IRendererSetup>();
if (setup == null)
setup = defaultRendererSetup;
setup.Setup(renderer, context, cullResults, renderingData);
renderer.Execute(context, cullResults, renderingData);
context.Submit();
}
}
15
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
SetupPerFrameShaderConstants();
foreach (Camera camera in cameras)
{
CameraData cameraData;
InitializeCameraData(camera, out cameraData);
SetupPerCameraShaderConstants(cameraData);
CullResults.Cull(cullingParameters, context, cullResults);
List<VisibleLight> visibleLights = cullResults.visibleLights;
RenderingData renderingData;
InitializeRenderingData(cameraData, visibleLights, out renderingData);
var setup = cameraData.camera.GetComponent<IRendererSetup>();
if (setup == null)
setup = defaultRendererSetup;
setup.Setup(renderer, context, cullResults, renderingData);
renderer.Execute(context, cullResults, renderingData);
context.Submit();
}
}
Called from C++ for:
● Scene
● Offscreen
● Editor
● Preview
● Reflection
16
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
SetupPerFrameShaderConstants();
foreach (Camera camera in cameras)
{
CameraData cameraData;
InitializeCameraData(camera, out cameraData);
SetupPerCameraShaderConstants(cameraData);
CullResults.Cull(cullingParameters, context, cullResults);
List<VisibleLight> visibleLights = cullResults.visibleLights;
RenderingData renderingData;
InitializeRenderingData(cameraData, visibleLights, out renderingData);
var setup = cameraData.camera.GetComponent<IRendererSetup>();
if (setup == null)
setup = defaultRendererSetup;
setup.Setup(renderer, context, cullResults, renderingData);
renderer.Execute(context, cullResults, renderingData);
context.Submit();
}
}
Shader constants setup per
access frequency
● PerFrame
● PerCamera
● PerPass
● PerObject
17
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
SetupPerFrameShaderConstants();
foreach (Camera camera in cameras)
{
CameraData cameraData;
InitializeCameraData(camera, out cameraData);
SetupPerCameraShaderConstants(cameraData);
CullResults.Cull(cullingParameters, context, cullResults);
List<VisibleLight> visibleLights = cullResults.visibleLights;
RenderingData renderingData;
InitializeRenderingData(cameraData, visibleLights, out renderingData);
var setup = cameraData.camera.GetComponent<IRendererSetup>();
if (setup == null)
setup = defaultRendererSetup;
setup.Setup(renderer, context, cullResults, renderingData);
renderer.Execute(context, cullResults, renderingData);
context.Submit();
}
}
Camera Related Rendering:
● HDR
● MSAA
● Shadows
● Render Scale
● PostProcessing
● Stereo Rendering
18
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
SetupPerFrameShaderConstants();
foreach (Camera camera in cameras)
{
CameraData cameraData;
InitializeCameraData(camera, out cameraData);
SetupPerCameraShaderConstants(cameraData);
CullResults.Cull(cullingParameters, context, cullResults);
List<VisibleLight> visibleLights = cullResults.visibleLights;
RenderingData renderingData;
InitializeRenderingData(cameraData, visibleLights, out renderingData);
var setup = cameraData.camera.GetComponent<IRendererSetup>();
if (setup == null)
setup = defaultRendererSetup;
setup.Setup(renderer, context, cullResults, renderingData);
renderer.Execute(context, cullResults, renderingData);
context.Submit();
}
}
Visible:
● Renderers
● Lights
● ...
19
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
SetupPerFrameShaderConstants();
foreach (Camera camera in cameras)
{
CameraData cameraData;
InitializeCameraData(camera, out cameraData);
SetupPerCameraShaderConstants(cameraData);
CullResults.Cull(cullingParameters, context, cullResults);
List<VisibleLight> visibleLights = cullResults.visibleLights;
RenderingData renderingData;
InitializeRenderingData(cameraData, visibleLights, out renderingData);
var setup = cameraData.camera.GetComponent<IRendererSetup>();
if (setup == null)
setup = defaultRendererSetup;
setup.Setup(renderer, context, cullResults, renderingData);
renderer.Execute(context, cullResults, renderingData);
context.Submit();
}
}
Data-drive rendering!
Rendering Data Based on:
● Cull Results
● Quality Settings
● Rendering Features
● Platform
20
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
SetupPerFrameShaderConstants();
foreach (Camera camera in cameras)
{
CameraData cameraData;
InitializeCameraData(camera, out cameraData);
SetupPerCameraShaderConstants(cameraData);
CullResults.Cull(cullingParameters, context, cullResults);
List<VisibleLight> visibleLights = cullResults.visibleLights;
RenderingData renderingData;
InitializeRenderingData(cameraData, visibleLights, out renderingData);
var setup = cameraData.camera.GetComponent<IRendererSetup>();
if (setup == null)
setup = defaultRendererSetup;
setup.Setup(renderer, context, cullResults, renderingData);
renderer.Execute(context, cullResults, renderingData);
context.Submit();
}
}
● Setup render passes
○ Allocate Resources
○ Enqueue Render Passes
○ Configure pipeline state
● Can be overridden to your
own!
21
public override void Render(ScriptableRenderContext context, Camera[] cameras)
{
SetupPerFrameShaderConstants();
foreach (Camera camera in cameras)
{
CameraData cameraData;
InitializeCameraData(camera, out cameraData);
SetupPerCameraShaderConstants(cameraData);
CullResults.Cull(cullingParameters, context, cullResults);
List<VisibleLight> visibleLights = cullResults.visibleLights;
RenderingData renderingData;
InitializeRenderingData(cameraData, visibleLights, out renderingData);
var setup = cameraData.camera.GetComponent<IRendererSetup>();
if (setup == null)
setup = defaultRendererSetup;
setup.Setup(renderer, context, cullResults, renderingData);
renderer.Execute(context, cullResults, renderingData);
context.Submit();
}
}
● Execute enqued passes
● Submit all queued rendering
22
Let’s take a look at the
DefaultRendererSetup
23
public void Setup(ScriptableRenderer renderer, … , RenderingData renderingData)
{
if (renderingData.shadowData.renderShadows)
renderer.Enqueue(m_ShadowPass);
bool requiresDepthPrepass = RequireDepthPrepass(renderingData.cameraData.requiresDepthTexture);
if (requiresDepthPrepass)
renderer.Enqueue(m_DepthPrepass);
renderer.Enqueue(m_SetupLightConstants);
renderer.Enqueue(m_RenderOpaquesForwardPass);
foreach (var pass in camera.GetComponents<IAfterOpaquePass>())
renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
if (camera.clearFlags == CameraClearFlags.Skybox)
renderer.Enqueue(m_RenderSkyboxPass);
renderer.Enqueue(m_RenderTransparentsPass);
if (renderingData.cameraData.postProcessEnabled)
renderer.Enqueue(m_PostProcessPass);
}
24
public void Setup(ScriptableRenderer renderer, … , RenderingData renderingData)
{
if (renderingData.shadowData.renderShadows)
renderer.Enqueue(m_ShadowPass);
bool requiresDepthPrepass = RequireDepthPrepass(renderingData.cameraData.requiresDepthTexture);
if (requiresDepthPrepass)
renderer.Enqueue(m_DepthPrepass);
renderer.Enqueue(m_SetupLightConstants);
renderer.Enqueue(m_RenderOpaquesForwardPass);
foreach (var pass in camera.GetComponents<IAfterOpaquePass>())
renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
if (camera.clearFlags == CameraClearFlags.Skybox)
renderer.Enqueue(m_RenderSkyboxPass);
renderer.Enqueue(m_RenderTransparentsPass);
if (renderingData.cameraData.postProcessEnabled)
renderer.Enqueue(m_PostProcessPass);
}
● Enqueue render passes
based on received data
● ScriptableRenderPass is a
building block to a render
pipeline
25
public void Setup(ScriptableRenderer renderer, … , RenderingData renderingData)
{
if (renderingData.shadowData.renderShadows)
renderer.Enqueue(m_ShadowPass);
bool requiresDepthPrepass = RequireDepthPrepass(renderingData.cameraData.requiresDepthTexture);
if (requiresDepthPrepass)
renderer.Enqueue(m_DepthPrepass);
renderer.Enqueue(m_SetupLightConstants);
renderer.Enqueue(m_RenderOpaquesForwardPass);
foreach (var pass in camera.GetComponents<IAfterOpaquePass>())
renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
if (camera.clearFlags == CameraClearFlags.Skybox)
renderer.Enqueue(m_RenderSkyboxPass);
renderer.Enqueue(m_RenderTransparentsPass);
if (renderingData.cameraData.postProcessEnabled)
renderer.Enqueue(m_PostProcessPass);
}
● Camera can contain scripts
that inject passes at specific
points in the pipeline
● IAfterOpaque is just one of
the many injecting points
26
Quick Recap
●LWRP do every frame
1.Culling
2.Setup per frame and per camera data
3.IRendererSetup enqueue multiple ScriptableRenderPass
a.A custom ScriptableRenderPass can be added at many
hook points
b.The default renderer can be even completely overridden
4.Renderer execute all enqueued passes
27
Adding a custom pass in LWRP
● Let’s switch to coding!
● We will:
○ Create a custom ScriptableRenderPass (MyNyanCatPass)
○ Inject the MyNyanCatPass after rendering opaques
(IAfterOpaque)
28
Now it’s your time to code!
● What if I get lost?
○ Call for help!
○ Use AddPassAfterOpaqueCompleted.cs in your project as
reference
29
Checkpoint
●You should have the following image
30
Customizing the render pipeline
● How about we complete override the renderer now?!
● But first let’s review how to do a mobile deferred renderer
Tiled GPU rendering review
●Splits rendering into tiles
31
Textures Framebuffer
Main Memory
Fragment Shader Tile Memory
Geometry
Data
GPU
Tiled GPU rendering review
●Splits rendering into tiles
●For each tile
○ Tile LOAD Action
32
Textures
Main Memory
Geometry
Data
GPU
Fragment Shader Tile Memory
Framebuffer
Tiled GPU rendering review
●Splits rendering into tiles
●For each tile
○ Tile LOAD Action
○ Rendering
33
Textures
Main Memory
Geometry
Data
GPU
Fragment Shader Tile Memory
Framebuffer
Tiled GPU rendering review
●Splits rendering into tiles
●For each tile
○ Tile LOAD Action
○ Rendering
○ Tile STORE Action
34
Textures
Main Memory
Geometry
Data
GPU
Fragment Shader Tile Memory
Framebuffer
Tiled GPU rendering review
●Splits rendering into tiles
●For each tile
○ Tile LOAD Action
○ Rendering
○ Tile STORE Action
35
Textures
Main Memory
Geometry
Data
GPU
Fragment Shader Tile Memory
Framebuffer
Tiled GPU rendering review
●Splits rendering into tiles
●For each tile
○ Tile LOAD Action
○ Rendering
○ Tile STORE Action
36
Textures
Main Memory
Geometry
Data
GPU
Fragment Shader Tile Memory
Framebuffer
Traditional Deferred Rendering
●GBuffer pass
○ Allocate Images
○ Setup Framebuffer (MRT)
○ Render to MRT
○ Write tiles to main memory
Textures Framebuffer
Main Memory
GPU
Fragment Shader Tile Memory
Geometry
Data
Diffuse Specular +
Rougness
Normals LightAccum
(GI + Emissive)
Depth
Traditional Deferred Rendering
●Lighting pass
○ SetFramebuffer (LightAccum)
○ Load tiles from main memory
○ Read Input Textures from main memory
○ Render to LightAccumulation
○ Write tiles to main memory
Textures Framebuffer
Main Memory
GPU
Fragment Shader Tile Memory
Geometry
Data
Diffuse Specular Normals Light
Accumulation
Depth
39
Rendering Efficiently on Mobile
●Minimize external memory read and writes
●Render Pass allows Tiled GPU interleaved rendering
○ Vulkan Multipass Mobile Deferred Done Right (Arntzen, GDC 2017)
Tile #0
Render GBuffer
Tile #0
Render Lighting
Tile #1
Render GBuffer
Tile #1
Render Lighting
Interleaved Rendering
40
Rendering Efficiently on Mobile
●RenderPass API
○ Vulkan: Transient Buffers
○ Metal: Framebuffer Fetch
○ Emulated on all other rendering backends
41
Mobile Deferred Renderer
● We will create a combined GBufferAndLighting renderpass
● For simplicity we will only support directional lights now
● It can easily be extended to support puntual lights
● Create an IRendererSetup
● Enqueue our render pass
● Add IRendererSetup to our camera
42
Now it’s your time to code!
● What if I get lost?
○ Call for help!
○ Use MyDeferredRendererCompleted.cs in your project as
reference
43
Before you leave!
1.Please rate this session in your SIGGRAPH app!
2.Save this link: bit.ly/siggraph18
3.We will have another awesome workshop on ShaderGraph!
a.Creating a Custom Production Ready Pipeline.
b.Same place, same hour!
4.We need to clear the booth for the next workshop.
5.Meet me outside for questions
44

Más contenido relacionado

La actualidad más candente

La actualidad más candente (20)

Secure container: Kata container and gVisor
Secure container: Kata container and gVisorSecure container: Kata container and gVisor
Secure container: Kata container and gVisor
 
LOD and Culling Systems That Scale - Unite LA
LOD and Culling Systems That Scale  - Unite LALOD and Culling Systems That Scale  - Unite LA
LOD and Culling Systems That Scale - Unite LA
 
Siggraph 2016 - Vulkan and nvidia : the essentials
Siggraph 2016 - Vulkan and nvidia : the essentialsSiggraph 2016 - Vulkan and nvidia : the essentials
Siggraph 2016 - Vulkan and nvidia : the essentials
 
Deep Dive into Kubernetes - Part 1
Deep Dive into Kubernetes - Part 1Deep Dive into Kubernetes - Part 1
Deep Dive into Kubernetes - Part 1
 
Hacking Exposed Live: Mobile Targeted Threats
Hacking Exposed Live: Mobile Targeted ThreatsHacking Exposed Live: Mobile Targeted Threats
Hacking Exposed Live: Mobile Targeted Threats
 
QNX Software Systems
QNX Software SystemsQNX Software Systems
QNX Software Systems
 
Remote Graphical Rendering
Remote Graphical RenderingRemote Graphical Rendering
Remote Graphical Rendering
 
Android Internals at Linaro Connect Asia 2013
Android Internals at Linaro Connect Asia 2013Android Internals at Linaro Connect Asia 2013
Android Internals at Linaro Connect Asia 2013
 
Hands on OpenCL
Hands on OpenCLHands on OpenCL
Hands on OpenCL
 
Grafana Mimir and VictoriaMetrics_ Performance Tests.pptx
Grafana Mimir and VictoriaMetrics_ Performance Tests.pptxGrafana Mimir and VictoriaMetrics_ Performance Tests.pptx
Grafana Mimir and VictoriaMetrics_ Performance Tests.pptx
 
Service-mesh options with Linkerd, Consul, Istio and AWS AppMesh
Service-mesh options with Linkerd, Consul, Istio and AWS AppMeshService-mesh options with Linkerd, Consul, Istio and AWS AppMesh
Service-mesh options with Linkerd, Consul, Istio and AWS AppMesh
 
OpenVINO introduction
OpenVINO introductionOpenVINO introduction
OpenVINO introduction
 
Explore the Latest on WSO2 Identity Server 5.11
Explore the Latest on WSO2 Identity Server 5.11Explore the Latest on WSO2 Identity Server 5.11
Explore the Latest on WSO2 Identity Server 5.11
 
Android's Multimedia Framework
Android's Multimedia FrameworkAndroid's Multimedia Framework
Android's Multimedia Framework
 
VMware Network design project example
VMware Network design project exampleVMware Network design project example
VMware Network design project example
 
Trip down the GPU lane with Machine Learning
Trip down the GPU lane with Machine LearningTrip down the GPU lane with Machine Learning
Trip down the GPU lane with Machine Learning
 
오픈소스 모니터링 알아보기(Learn about opensource monitoring)
오픈소스 모니터링 알아보기(Learn about opensource monitoring)오픈소스 모니터링 알아보기(Learn about opensource monitoring)
오픈소스 모니터링 알아보기(Learn about opensource monitoring)
 
Giới thiệu docker và ứng dụng trong ci-cd
Giới thiệu docker và ứng dụng trong ci-cdGiới thiệu docker và ứng dụng trong ci-cd
Giới thiệu docker và ứng dụng trong ci-cd
 
OpenStack Architecture
OpenStack ArchitectureOpenStack Architecture
OpenStack Architecture
 
Getting started with High-Definition Render Pipeline for games- Unite Copenha...
Getting started with High-Definition Render Pipeline for games- Unite Copenha...Getting started with High-Definition Render Pipeline for games- Unite Copenha...
Getting started with High-Definition Render Pipeline for games- Unite Copenha...
 

Similar a Customizing a production pipeline

Breizhcamp Rennes 2011
Breizhcamp Rennes 2011Breizhcamp Rennes 2011
Breizhcamp Rennes 2011
sekond0
 
RaVioli: A Parallel Vide Processing Library with Auto Resolution Adjustability
RaVioli: A Parallel Vide Processing Library with Auto Resolution AdjustabilityRaVioli: A Parallel Vide Processing Library with Auto Resolution Adjustability
RaVioli: A Parallel Vide Processing Library with Auto Resolution Adjustability
Matsuo and Tsumura lab.
 

Similar a Customizing a production pipeline (20)

Rendering Techniques for Augmented Reality and a Look Ahead at AR Foundation
Rendering Techniques for Augmented Reality and a Look Ahead at AR FoundationRendering Techniques for Augmented Reality and a Look Ahead at AR Foundation
Rendering Techniques for Augmented Reality and a Look Ahead at AR Foundation
 
How the Universal Render Pipeline unlocks games for you - Unite Copenhagen 2019
How the Universal Render Pipeline unlocks games for you - Unite Copenhagen 2019How the Universal Render Pipeline unlocks games for you - Unite Copenhagen 2019
How the Universal Render Pipeline unlocks games for you - Unite Copenhagen 2019
 
Extended and embedding: containerd update & project use cases
Extended and embedding: containerd update & project use casesExtended and embedding: containerd update & project use cases
Extended and embedding: containerd update & project use cases
 
Tools for developing Android Games
 Tools for developing Android Games Tools for developing Android Games
Tools for developing Android Games
 
3D Programming Basics: WebGL
3D Programming Basics: WebGL3D Programming Basics: WebGL
3D Programming Basics: WebGL
 
Webrender 1.0
Webrender 1.0Webrender 1.0
Webrender 1.0
 
Breizhcamp Rennes 2011
Breizhcamp Rennes 2011Breizhcamp Rennes 2011
Breizhcamp Rennes 2011
 
Immutable Deployment Hands-On Lab Interop ITX
Immutable Deployment Hands-On Lab Interop ITXImmutable Deployment Hands-On Lab Interop ITX
Immutable Deployment Hands-On Lab Interop ITX
 
Part 4 Maximizing the utilization of GPU resources on-premise and in the cloud
Part 4  Maximizing the utilization of GPU resources on-premise and in the cloudPart 4  Maximizing the utilization of GPU resources on-premise and in the cloud
Part 4 Maximizing the utilization of GPU resources on-premise and in the cloud
 
Qt Programming on TI Processors
Qt Programming on TI ProcessorsQt Programming on TI Processors
Qt Programming on TI Processors
 
State of the Art OpenGL and Qt
State of the Art OpenGL and QtState of the Art OpenGL and Qt
State of the Art OpenGL and Qt
 
426 lecture 4: AR Developer Tools
426 lecture 4: AR Developer Tools426 lecture 4: AR Developer Tools
426 lecture 4: AR Developer Tools
 
Rohit Yadav - The future of the CloudStack Virtual Router
Rohit Yadav - The future of the CloudStack Virtual RouterRohit Yadav - The future of the CloudStack Virtual Router
Rohit Yadav - The future of the CloudStack Virtual Router
 
Build your apps everywhere with Lightning Web Components Open Source, Fabien ...
Build your apps everywhere with Lightning Web Components Open Source, Fabien ...Build your apps everywhere with Lightning Web Components Open Source, Fabien ...
Build your apps everywhere with Lightning Web Components Open Source, Fabien ...
 
Copy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with QtCopy Your Favourite Nokia App with Qt
Copy Your Favourite Nokia App with Qt
 
FLAR Workflow
FLAR WorkflowFLAR Workflow
FLAR Workflow
 
RaVioli: A Parallel Vide Processing Library with Auto Resolution Adjustability
RaVioli: A Parallel Vide Processing Library with Auto Resolution AdjustabilityRaVioli: A Parallel Vide Processing Library with Auto Resolution Adjustability
RaVioli: A Parallel Vide Processing Library with Auto Resolution Adjustability
 
LAS16-201: ART JIT in Android N
LAS16-201: ART JIT in Android NLAS16-201: ART JIT in Android N
LAS16-201: ART JIT in Android N
 
How to build Kick Ass Games in the Cloud
How to build Kick Ass Games in the CloudHow to build Kick Ass Games in the Cloud
How to build Kick Ass Games in the Cloud
 
Optimizing HDRP with NVIDIA Nsight Graphics – Unite Copenhagen 2019
Optimizing HDRP with NVIDIA Nsight Graphics – Unite Copenhagen 2019Optimizing HDRP with NVIDIA Nsight Graphics – Unite Copenhagen 2019
Optimizing HDRP with NVIDIA Nsight Graphics – Unite Copenhagen 2019
 

Último

%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 

Último (20)

tonesoftg
tonesoftgtonesoftg
tonesoftg
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 

Customizing a production pipeline

  • 1. GenerativeArt–MadewithUnity Customizing a Production Pipeline (Lightweight Render Pipeline) Felipe Lira Graphics Programmer Unity Technologies 1 Note: If you are using a laptop download Unity 2018.2 and the following project: bit.ly/siggraph18
  • 2. 2 Workshop Pre-requisites ●If you are on a SIGGRAPH computer ○ Start Unity and open SIGGRAPH2018-WORKSHOP project in your Desktop ●If you are on your own computer ○ Download Unity 2018.2 ○ Download the following project bit.ly/siggraph18 ○ Start Unity and open the project you downloaded ●Slides: bit.ly/siggraph18_slides
  • 3. 3 Workshop Agenda ●What is the Lightweight Render Pipeline (LWRP) ●Add LWRP to your project ●Convert a project to use LWRP ●Overview of LWRP rendering ●Customize LWRP renderer by adding custom passes ●Override LWRP renderer to implement a deferred renderer
  • 4. 4 What is Lightweight Render Pipeline (LWRP) ●It’s a Scriptable Render Pipeline (SRP) ○ Rendering API exposed in C# ○ Open Source: https://github.com/Unity-Technologies/ScriptableRenderPipeline ●LWRP ○ Currently 1 of 2 of our inhouse Render Pipelines we are developing ○ Designed from the ground up to perform at best on mobile hardware ○ Modern APIs in mind, as well as Legacy APIs, eg GLES 2.0
  • 5. 5 Why should you care about SRP and LWRP ●If you are ○ Student: ■ Learn Graphics Programming with a robust API ○ Game Developer: ■ Performance out of the box, explicit, lean and extensible ○ Researchers: ■ Implement, deploy and profile your research many platforms
  • 6. 6
  • 8. 8 How to get SRP and LWRP ●In this workshop you already have it! ○ The project you are using is bundled with LWRP for simplicity
  • 9. 9 How to get SRP and LWRP ●You can also get it by creating a new project with LWRP template
  • 10. 10 How to get SRP and LWRP ●Or by downloading from package manager UI
  • 11. 11 So now you have it! ● Let’s convert your project to use LWRP
  • 12. 12 Checkpoint! ●Created LWRP asset ○ Assets -> Create -> Rendering -> Lightweight Pipeline Asset ●Assigned LWRP to Graphics Settings ○ Edit -> Project Settings -> Graphics Settings ○ Drag and Drop LWRP asset in SRP settings ●Upgraded materials to LWRP materials ○ Edit -> Render Pipeline -> Upgrade Project Materials … ●Checked rendering settings in LWRP asset ●You should have the same image as before converting
  • 13. 13 Before coding let’s take a look at core LWRP rendering
  • 14. 14 public override void Render(ScriptableRenderContext context, Camera[] cameras) { SetupPerFrameShaderConstants(); foreach (Camera camera in cameras) { CameraData cameraData; InitializeCameraData(camera, out cameraData); SetupPerCameraShaderConstants(cameraData); CullResults.Cull(cullingParameters, context, cullResults); List<VisibleLight> visibleLights = cullResults.visibleLights; RenderingData renderingData; InitializeRenderingData(cameraData, visibleLights, out renderingData); var setup = cameraData.camera.GetComponent<IRendererSetup>(); if (setup == null) setup = defaultRendererSetup; setup.Setup(renderer, context, cullResults, renderingData); renderer.Execute(context, cullResults, renderingData); context.Submit(); } }
  • 15. 15 public override void Render(ScriptableRenderContext context, Camera[] cameras) { SetupPerFrameShaderConstants(); foreach (Camera camera in cameras) { CameraData cameraData; InitializeCameraData(camera, out cameraData); SetupPerCameraShaderConstants(cameraData); CullResults.Cull(cullingParameters, context, cullResults); List<VisibleLight> visibleLights = cullResults.visibleLights; RenderingData renderingData; InitializeRenderingData(cameraData, visibleLights, out renderingData); var setup = cameraData.camera.GetComponent<IRendererSetup>(); if (setup == null) setup = defaultRendererSetup; setup.Setup(renderer, context, cullResults, renderingData); renderer.Execute(context, cullResults, renderingData); context.Submit(); } } Called from C++ for: ● Scene ● Offscreen ● Editor ● Preview ● Reflection
  • 16. 16 public override void Render(ScriptableRenderContext context, Camera[] cameras) { SetupPerFrameShaderConstants(); foreach (Camera camera in cameras) { CameraData cameraData; InitializeCameraData(camera, out cameraData); SetupPerCameraShaderConstants(cameraData); CullResults.Cull(cullingParameters, context, cullResults); List<VisibleLight> visibleLights = cullResults.visibleLights; RenderingData renderingData; InitializeRenderingData(cameraData, visibleLights, out renderingData); var setup = cameraData.camera.GetComponent<IRendererSetup>(); if (setup == null) setup = defaultRendererSetup; setup.Setup(renderer, context, cullResults, renderingData); renderer.Execute(context, cullResults, renderingData); context.Submit(); } } Shader constants setup per access frequency ● PerFrame ● PerCamera ● PerPass ● PerObject
  • 17. 17 public override void Render(ScriptableRenderContext context, Camera[] cameras) { SetupPerFrameShaderConstants(); foreach (Camera camera in cameras) { CameraData cameraData; InitializeCameraData(camera, out cameraData); SetupPerCameraShaderConstants(cameraData); CullResults.Cull(cullingParameters, context, cullResults); List<VisibleLight> visibleLights = cullResults.visibleLights; RenderingData renderingData; InitializeRenderingData(cameraData, visibleLights, out renderingData); var setup = cameraData.camera.GetComponent<IRendererSetup>(); if (setup == null) setup = defaultRendererSetup; setup.Setup(renderer, context, cullResults, renderingData); renderer.Execute(context, cullResults, renderingData); context.Submit(); } } Camera Related Rendering: ● HDR ● MSAA ● Shadows ● Render Scale ● PostProcessing ● Stereo Rendering
  • 18. 18 public override void Render(ScriptableRenderContext context, Camera[] cameras) { SetupPerFrameShaderConstants(); foreach (Camera camera in cameras) { CameraData cameraData; InitializeCameraData(camera, out cameraData); SetupPerCameraShaderConstants(cameraData); CullResults.Cull(cullingParameters, context, cullResults); List<VisibleLight> visibleLights = cullResults.visibleLights; RenderingData renderingData; InitializeRenderingData(cameraData, visibleLights, out renderingData); var setup = cameraData.camera.GetComponent<IRendererSetup>(); if (setup == null) setup = defaultRendererSetup; setup.Setup(renderer, context, cullResults, renderingData); renderer.Execute(context, cullResults, renderingData); context.Submit(); } } Visible: ● Renderers ● Lights ● ...
  • 19. 19 public override void Render(ScriptableRenderContext context, Camera[] cameras) { SetupPerFrameShaderConstants(); foreach (Camera camera in cameras) { CameraData cameraData; InitializeCameraData(camera, out cameraData); SetupPerCameraShaderConstants(cameraData); CullResults.Cull(cullingParameters, context, cullResults); List<VisibleLight> visibleLights = cullResults.visibleLights; RenderingData renderingData; InitializeRenderingData(cameraData, visibleLights, out renderingData); var setup = cameraData.camera.GetComponent<IRendererSetup>(); if (setup == null) setup = defaultRendererSetup; setup.Setup(renderer, context, cullResults, renderingData); renderer.Execute(context, cullResults, renderingData); context.Submit(); } } Data-drive rendering! Rendering Data Based on: ● Cull Results ● Quality Settings ● Rendering Features ● Platform
  • 20. 20 public override void Render(ScriptableRenderContext context, Camera[] cameras) { SetupPerFrameShaderConstants(); foreach (Camera camera in cameras) { CameraData cameraData; InitializeCameraData(camera, out cameraData); SetupPerCameraShaderConstants(cameraData); CullResults.Cull(cullingParameters, context, cullResults); List<VisibleLight> visibleLights = cullResults.visibleLights; RenderingData renderingData; InitializeRenderingData(cameraData, visibleLights, out renderingData); var setup = cameraData.camera.GetComponent<IRendererSetup>(); if (setup == null) setup = defaultRendererSetup; setup.Setup(renderer, context, cullResults, renderingData); renderer.Execute(context, cullResults, renderingData); context.Submit(); } } ● Setup render passes ○ Allocate Resources ○ Enqueue Render Passes ○ Configure pipeline state ● Can be overridden to your own!
  • 21. 21 public override void Render(ScriptableRenderContext context, Camera[] cameras) { SetupPerFrameShaderConstants(); foreach (Camera camera in cameras) { CameraData cameraData; InitializeCameraData(camera, out cameraData); SetupPerCameraShaderConstants(cameraData); CullResults.Cull(cullingParameters, context, cullResults); List<VisibleLight> visibleLights = cullResults.visibleLights; RenderingData renderingData; InitializeRenderingData(cameraData, visibleLights, out renderingData); var setup = cameraData.camera.GetComponent<IRendererSetup>(); if (setup == null) setup = defaultRendererSetup; setup.Setup(renderer, context, cullResults, renderingData); renderer.Execute(context, cullResults, renderingData); context.Submit(); } } ● Execute enqued passes ● Submit all queued rendering
  • 22. 22 Let’s take a look at the DefaultRendererSetup
  • 23. 23 public void Setup(ScriptableRenderer renderer, … , RenderingData renderingData) { if (renderingData.shadowData.renderShadows) renderer.Enqueue(m_ShadowPass); bool requiresDepthPrepass = RequireDepthPrepass(renderingData.cameraData.requiresDepthTexture); if (requiresDepthPrepass) renderer.Enqueue(m_DepthPrepass); renderer.Enqueue(m_SetupLightConstants); renderer.Enqueue(m_RenderOpaquesForwardPass); foreach (var pass in camera.GetComponents<IAfterOpaquePass>()) renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); if (camera.clearFlags == CameraClearFlags.Skybox) renderer.Enqueue(m_RenderSkyboxPass); renderer.Enqueue(m_RenderTransparentsPass); if (renderingData.cameraData.postProcessEnabled) renderer.Enqueue(m_PostProcessPass); }
  • 24. 24 public void Setup(ScriptableRenderer renderer, … , RenderingData renderingData) { if (renderingData.shadowData.renderShadows) renderer.Enqueue(m_ShadowPass); bool requiresDepthPrepass = RequireDepthPrepass(renderingData.cameraData.requiresDepthTexture); if (requiresDepthPrepass) renderer.Enqueue(m_DepthPrepass); renderer.Enqueue(m_SetupLightConstants); renderer.Enqueue(m_RenderOpaquesForwardPass); foreach (var pass in camera.GetComponents<IAfterOpaquePass>()) renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); if (camera.clearFlags == CameraClearFlags.Skybox) renderer.Enqueue(m_RenderSkyboxPass); renderer.Enqueue(m_RenderTransparentsPass); if (renderingData.cameraData.postProcessEnabled) renderer.Enqueue(m_PostProcessPass); } ● Enqueue render passes based on received data ● ScriptableRenderPass is a building block to a render pipeline
  • 25. 25 public void Setup(ScriptableRenderer renderer, … , RenderingData renderingData) { if (renderingData.shadowData.renderShadows) renderer.Enqueue(m_ShadowPass); bool requiresDepthPrepass = RequireDepthPrepass(renderingData.cameraData.requiresDepthTexture); if (requiresDepthPrepass) renderer.Enqueue(m_DepthPrepass); renderer.Enqueue(m_SetupLightConstants); renderer.Enqueue(m_RenderOpaquesForwardPass); foreach (var pass in camera.GetComponents<IAfterOpaquePass>()) renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle)); if (camera.clearFlags == CameraClearFlags.Skybox) renderer.Enqueue(m_RenderSkyboxPass); renderer.Enqueue(m_RenderTransparentsPass); if (renderingData.cameraData.postProcessEnabled) renderer.Enqueue(m_PostProcessPass); } ● Camera can contain scripts that inject passes at specific points in the pipeline ● IAfterOpaque is just one of the many injecting points
  • 26. 26 Quick Recap ●LWRP do every frame 1.Culling 2.Setup per frame and per camera data 3.IRendererSetup enqueue multiple ScriptableRenderPass a.A custom ScriptableRenderPass can be added at many hook points b.The default renderer can be even completely overridden 4.Renderer execute all enqueued passes
  • 27. 27 Adding a custom pass in LWRP ● Let’s switch to coding! ● We will: ○ Create a custom ScriptableRenderPass (MyNyanCatPass) ○ Inject the MyNyanCatPass after rendering opaques (IAfterOpaque)
  • 28. 28 Now it’s your time to code! ● What if I get lost? ○ Call for help! ○ Use AddPassAfterOpaqueCompleted.cs in your project as reference
  • 29. 29 Checkpoint ●You should have the following image
  • 30. 30 Customizing the render pipeline ● How about we complete override the renderer now?! ● But first let’s review how to do a mobile deferred renderer
  • 31. Tiled GPU rendering review ●Splits rendering into tiles 31 Textures Framebuffer Main Memory Fragment Shader Tile Memory Geometry Data GPU
  • 32. Tiled GPU rendering review ●Splits rendering into tiles ●For each tile ○ Tile LOAD Action 32 Textures Main Memory Geometry Data GPU Fragment Shader Tile Memory Framebuffer
  • 33. Tiled GPU rendering review ●Splits rendering into tiles ●For each tile ○ Tile LOAD Action ○ Rendering 33 Textures Main Memory Geometry Data GPU Fragment Shader Tile Memory Framebuffer
  • 34. Tiled GPU rendering review ●Splits rendering into tiles ●For each tile ○ Tile LOAD Action ○ Rendering ○ Tile STORE Action 34 Textures Main Memory Geometry Data GPU Fragment Shader Tile Memory Framebuffer
  • 35. Tiled GPU rendering review ●Splits rendering into tiles ●For each tile ○ Tile LOAD Action ○ Rendering ○ Tile STORE Action 35 Textures Main Memory Geometry Data GPU Fragment Shader Tile Memory Framebuffer
  • 36. Tiled GPU rendering review ●Splits rendering into tiles ●For each tile ○ Tile LOAD Action ○ Rendering ○ Tile STORE Action 36 Textures Main Memory Geometry Data GPU Fragment Shader Tile Memory Framebuffer
  • 37. Traditional Deferred Rendering ●GBuffer pass ○ Allocate Images ○ Setup Framebuffer (MRT) ○ Render to MRT ○ Write tiles to main memory Textures Framebuffer Main Memory GPU Fragment Shader Tile Memory Geometry Data Diffuse Specular + Rougness Normals LightAccum (GI + Emissive) Depth
  • 38. Traditional Deferred Rendering ●Lighting pass ○ SetFramebuffer (LightAccum) ○ Load tiles from main memory ○ Read Input Textures from main memory ○ Render to LightAccumulation ○ Write tiles to main memory Textures Framebuffer Main Memory GPU Fragment Shader Tile Memory Geometry Data Diffuse Specular Normals Light Accumulation Depth
  • 39. 39 Rendering Efficiently on Mobile ●Minimize external memory read and writes ●Render Pass allows Tiled GPU interleaved rendering ○ Vulkan Multipass Mobile Deferred Done Right (Arntzen, GDC 2017) Tile #0 Render GBuffer Tile #0 Render Lighting Tile #1 Render GBuffer Tile #1 Render Lighting Interleaved Rendering
  • 40. 40 Rendering Efficiently on Mobile ●RenderPass API ○ Vulkan: Transient Buffers ○ Metal: Framebuffer Fetch ○ Emulated on all other rendering backends
  • 41. 41 Mobile Deferred Renderer ● We will create a combined GBufferAndLighting renderpass ● For simplicity we will only support directional lights now ● It can easily be extended to support puntual lights ● Create an IRendererSetup ● Enqueue our render pass ● Add IRendererSetup to our camera
  • 42. 42 Now it’s your time to code! ● What if I get lost? ○ Call for help! ○ Use MyDeferredRendererCompleted.cs in your project as reference
  • 43. 43 Before you leave! 1.Please rate this session in your SIGGRAPH app! 2.Save this link: bit.ly/siggraph18 3.We will have another awesome workshop on ShaderGraph! a.Creating a Custom Production Ready Pipeline. b.Same place, same hour! 4.We need to clear the booth for the next workshop. 5.Meet me outside for questions
  • 44. 44