Postprocessing and Deferred Rendering - Stanley...

23
Postprocessing and Deferred Rendering Prof. Aaron Lanterman School of Electrical and Computer Engineering Georgia Institute of Technology

Transcript of Postprocessing and Deferred Rendering - Stanley...

Postprocessing and Deferred Rendering

Prof. Aaron Lanterman School of Electrical and Computer Engineering

Georgia Institute of Technology

2

Bloom effect - before

http://creators.xna.com/en-us/sample/bloom

3

Bloom effect - after

http://creators.xna.com/en-us/sample/bloom

Motion blur in Valve’s Portal - roll

4

http://www.valvesoftware.com/publications/2008/GDC2008_PostProcessingInTheOrangeBox.pdf

Motion blur in Valve’s Portal - falling

5

http://www.valvesoftware.com/publications/2008/GDC2008_PostProcessingInTheOrangeBox.pdf

Setup for Postprocessing struct appdata_img { ! float4 vertex : POSITION; ! half2 texcoord : TEXCOORD0; !}; !!struct v2f_img { ! float4 pos : SV_POSITION; ! half2 uv : TEXCOORD0; !}; !!v2f_img vert_img( appdata_img v ) { ! v2f_img o; ! o.pos = mul (UNITY_MATRIX_MVP, v.vertex); ! o.uv = v.texcoord; ! return o; !} !!!!!!

In UnityCG.cginc

Outline Shader (1) Shader "GPUXXOutlinerShader" { ! !Properties { ! _MainTex ("Base (RGB)", 2D) = "white" {} ! _Speed ("Speed", float) = 1 !} ! !SubShader { ! Pass { ! ZTest Always Cull Off ZWrite Off ! !CGPROGRAM !#pragma vertex vert_img!#pragma fragment frag !#include "UnityCG.cginc" !!uniform sampler2D _MainTex; !uniform float _Speed; !!!!

Outline Shader (2) float4 frag (v2f_img i) : COLOR { ! float4 original = tex2D(_MainTex, i.uv); !! // original.r *= 0.5*(sin(_Speed * _Time.w) + 1); ! // original.b *= 0.5*(cos(_Speed * _Time.w) + 1); ! // return original.brga; !! float4 original_left = ! tex2D(_MainTex, i.uv - float2(1.0 / _ScreenParams.x,0)); ! float4 original_right = ! tex2D(_MainTex, i.uv + float2(1.0 / _ScreenParams.x,0)); ! float4 original_up = ! tex2D(_MainTex, i.uv - float2(0,1.0 / _ScreenParams.y)); ! float4 original_down = ! tex2D(_MainTex, i.uv + float2(0,1.0 / _ScreenParams.y)); ! float3 horiz_diff = original_left.rgb - original_right.rgb; ! float3 vert_diff = original_up.rgb - original_down.rgb; ! float3 outline = abs(horiz_diff) + abs(vert_diff); ! return(float4(lerp(outline,original, ! 0.5*(cos(_Speed * _Time.y) + 1)),1)); !} !!

Outline Camera Script using UnityEngine; !using System.Collections; !![ExecuteInEditMode] ![AddComponentMenu("GPUXX Effects/GPUXXOutliner")] ![RequireComponent (typeof(Camera))] !!public class GPUXXOutliner : MonoBehaviour { ! private Shader postprocShader; ! private Material postprocMat; ! public float speed; !

! void Start() { ! postprocShader = Shader.Find("GPUXXOutlinerShader"); ! postprocMat = new Material(postprocShader); ! } !! void Update() { ! postprocMat.SetFloat("_Speed",speed); ! } !! void OnRenderImage (RenderTexture source, RenderTexture destination) { ! Graphics.Blit(source, destination, postprocMat); ! } !} !

DepthNormal Shader (1) Shader "GPUXXDepthNormalShader" { ! !Properties { ! _MainTex ("Base (RGB)", 2D) = "white" {} ! _Speed ("Speed", float) = 1 !} ! !SubShader { ! Pass { ! ZTest Always Cull Off ZWrite Off ! !CGPROGRAM !#pragma vertex vert_img!#pragma fragment frag !#include "UnityCG.cginc" ! !uniform sampler2D _CameraDepthNormalsTexture; !uniform sampler2D _MainTex; !uniform float _Speed; !!!

DepthNormal Shader (2) float4 frag (v2f_img i) : COLOR { ! float4 original = tex2D(_MainTex, i.uv); ! float4 enc = tex2D(_CameraDepthNormalsTexture, i.uv); !! float depth; ! float3 n, display_n; !! DecodeDepthNormal(enc, /* out */ depth, /* out */ n); !

! display_n = 0.5 * (1 + n); ! return(float4(lerp(display_n,float3(1,1,1)* depth, ! 0.5*(cos(_Speed * _Time.y) + 1)),1)); !} !!!!

DecodeDepthNormal inline void DecodeDepthNormal( float4 enc, out float depth, out float3 normal ) !{ ! depth = DecodeFloatRG (enc.zw); ! normal = DecodeViewNormalStereo (enc); !} !!inline float DecodeFloatRG( float2 enc ) !{ ! float2 kDecodeDot = float2(1.0, 1/255.0); ! return dot( enc, kDecodeDot ); !} !!inline float3 DecodeViewNormalStereo( float4 enc4 ) !{ ! float kScale = 1.7777; ! float3 nn = enc4.xyz*float3(2*kScale,2*kScale,0) + float3(-kScale,-kScale,1); ! float g = 2.0 / dot(nn.xyz,nn.xyz); ! float3 n; ! n.xy = g*nn.xy; ! n.z = g-1; ! return n; !} !!!!!!!!!

In UnityCG.cginc

DecodeDepthNormal (1) #define DECODE_EYEDEPTH(i) LinearEyeDepth(i) !!// Z buffer to linear depth !inline float LinearEyeDepth( float z ) { ! return 1.0 / (_ZBufferParams.z * z + _ZBufferParams.w); !} !!!!!!!!!!

In UnityCG.cginc

DepthNormal Camera Script public class GPUXXDepthNormalDemo : MonoBehaviour { ! private Shader postprocShader; ! private Material postprocMat; ! private Camera myCamera; ! public float speed; !

! void Start() { ! postprocShader = Shader.Find("GPUXXDepthNormalShader"); ! postprocMat = new Material(postprocShader); ! myCamera = GetComponent<Camera> (); ! myCamera.depthTextureMode = DepthTextureMode.DepthNormals; ! if (speed <= 0) speed = 1; ! } !! void Update() { ! postprocMat.SetFloat("_Speed",speed); ! } !! void OnRenderImage(RenderTexture source, RenderTexture destination) { ! Graphics.Blit(source, destination, postprocMat); ! } !} ! !

Deferred Rendering Shader (1) Shader "GPUXXHackedDRShader" { ! Properties { ! // We don't really need these to be Properties since ! // they’re set by a script ! _DiffColor ("Diff Color", Color) = (1,1,1,1) ! _SpecColor ("Spec Color", Color) = (1,1,1,1) ! _Shininess ("Shininess", Range(0.01,1)) = 0.7 !

! _CameraData ("Camera Data", Vector) = (0,0,0,0) ! _lightPosVS0 ("Light Position 0", Vector) = (0,0,0,0) ! _lightPosVS1 ("Light Position 1", Vector) = (0,0,0,0) ! _lightPosVS2 ("Light Position 2", Vector) = (0,0,0,0) ! _lightPosVS3 ("Light Position 3", Vector) = (0,0,0,0) ! _lightPosVS4 ("Light Position 4", Vector) = (0,0,0,0) ! _lightPosVS5 ("Light Position 5", Vector) = (0,0,0,0) ! } !!

Deferred Rendering Shader (2) SubShader { ! !Tags { "RenderType"="Opaque" } !LOD 300 !

!Pass { ! CGPROGRAM ! #include "UnityCG.cginc" !

! #pragma target 3.0 ! #pragma vertex vert_img! #pragma fragment frag ! ! uniform float4 _CameraData; ! ! uniform float4 _DiffColor, _SpecColor; ! uniform float _Shininess; ! ! uniform float4 _lightPosVS0, _lightPosVS1, _lightPosVS2, ! _lightPosVS3, _lightPosVS4, _lightPosVS5; ! ! uniform sampler2D _CameraDepthNormalsTexture; !!!!

Deferred Rendering Shader (3) float4 frag(v2f_img i) : COLOR { ! float3 normalVS; ! ! float4 enc = tex2D(_CameraDepthNormalsTexture, i.uv); !! float depth; ! float3 n; ! DecodeDepthNormal(enc, /* out */ depth, /* out */ normalVS); !

! normalVS.z = -normalVS.z; !

! normalVS = normalize(normalVS); !

! float zRecon = DECODE_EYEDEPTH(depth);

! float2 xy_minus1to1 = (2 * i.uv ) - 1; ! float2 xyRecon = xy_minus1to1 * zRecon * _CameraData.xy; ! float3 posVS = float3(xyRecon,zRecon); !

! // eye is at origin ! float3 eyeDir = normalize(-posVS); !!

Deferred Rendering Shader (4) // I hardcoded the light colors, which is a bad idea ! float3 lightDir = normalize(_lightPosVS0.xyz - posVS); ! float3 halfDir = normalize(lightDir + eyeDir); ! float diff = max(0,dot(normalVS, lightDir)); ! float spec = max(0,pow(dot(normalVS, halfDir),_Shininess*128.0)); ! float4 col = ! float4(0.25,0,0.25,1) * (_SpecColor * spec + _DiffColor * diff); !

! lightDir = normalize(_lightPosVS1.xyz - posVS); ! halfDir = normalize(lightDir + eyeDir); ! diff = max(0,dot(normalVS, lightDir)); ! spec = max(0,pow(dot(normalVS, halfDir),_Shininess*128.0)); ! col += float4(0.25,0,0,1) * (_SpecColor * spec + _DiffColor * diff); !! return(float4(col.rgb,1)); !} ! !

Deferred Rendering Camera Script (1) [ExecuteInEditMode] ![AddComponentMenu( !

"GPUXX Effects/GPUXXHackedDR")] ![RequireComponent (typeof(Camera))] !!public class GPUXXHackedDR : MonoBehaviour { ! public Material postMat; ! public Shader postShader; ! private Camera myCamera; !! private Vector4[] myLightPosVS; ! Vector4 cameraData; !! !!

Deferred Rendering Camera Script (2)

Start() { ! postShader = ! Shader.Find("GPUXXHackedDRShader"); ! postMat = new Material(postShader); ! myCamera = GetComponent<Camera> (); ! myCamera.depthTextureMode = ! DepthTextureMode.DepthNormals; ! myLightPosVS = new Vector4[6]; !} !! !!

Deferred Rendering Camera Script (3) void OnPreRender() { ! cameraData.y = ! Mathf.Tan(Mathf.Deg2Rad * myCamera.fieldOfView / 2); ! cameraData.x = cameraData.y * myCamera.aspect; ! cameraData.z = ! myCamera.farClipPlane - myCamera.nearClipPlane; ! cameraData.w = myCamera.nearClipPlane; ! postMat.SetVector ("_CameraData", cameraData); ! postMat.SetVector("_DiffColor",0.2f * Vector4.one); ! postMat.SetVector("_SpecColor",Vector4.one); ! postMat.SetFloat("_Shininess",0.9f); !} ! !!

Deferred Rendering Camera Script (4) void Update() { ! // an assortment of wandering lights ! // don't look for any logic here, you will find none... ! myLightPosVS[0].z = 20 * Mathf.Sin (0.5f*Time.time); ! myLightPosVS[1].y = 2 + 20 * Mathf.Cos (0.6f*Time.time + 0.5f); ! myLightPosVS[1].z = -2; ! myLightPosVS[2].x = -3 + 20 * Mathf.Sin (0.7f*Time.time); ! myLightPosVS[2].y = -2 + 20 * Mathf.Cos (0.4f*Time.time - 1f); ! myLightPosVS[2].z = -2; ! myLightPosVS[3].x = 3 + 20 * Mathf.Cos (0.9f*Time.time + 0.25f); ! myLightPosVS[3].y = -1.5f + 20 * Mathf.Sin (0.3f*Time.time); ! myLightPosVS[3].z = -2; ! myLightPosVS[4].x = -3 + 20 * Mathf.Cos (0.8f*Time.time - 0.75f); ! myLightPosVS[4].y = 4 + myLightPosVS[4].x; ! myLightPosVS[4].z = -2; ! myLightPosVS[5].x = 3 + 20 * Mathf.Sin (Time.time + 5f); ! myLightPosVS[5].y = -3 + myLightPosVS[5].x; ! myLightPosVS[5].z = -2; !} !! !!

Deferred Rendering Camera Script (5) void OnRenderImage (RenderTexture source, ! RenderTexture destination) { ! postMat.SetVector("_lightPosVS0",myLightPosVS[0]); ! postMat.SetVector("_lightPosVS1",myLightPosVS[1]); ! postMat.SetVector("_lightPosVS2",myLightPosVS[2]); ! postMat.SetVector("_lightPosVS3",myLightPosVS[3]); ! postMat.SetVector("_lightPosVS4",myLightPosVS[4]); ! postMat.SetVector("_lightPosVS5",myLightPosVS[5]); !! postMat.SetVector("_CameraData",cameraData); !! Graphics.Blit(source, destination, postMat); !} !! !!