Skip to content

Commit

Permalink
Added Shadow Slicer.
Browse files Browse the repository at this point in the history
  • Loading branch information
keijiro committed Jun 15, 2017
1 parent 09dfc65 commit 0a7f5a3
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 13 deletions.
70 changes: 58 additions & 12 deletions Assets/Prisma.unity
Original file line number Diff line number Diff line change
Expand Up @@ -2451,6 +2451,7 @@ Transform:
- {fileID: 895455914}
- {fileID: 999185933}
- {fileID: 1450734907}
- {fileID: 1107727447}
m_Father: {fileID: 0}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
Expand Down Expand Up @@ -3288,15 +3289,15 @@ Light:
m_GameObject: {fileID: 390130554}
m_Enabled: 1
serializedVersion: 8
m_Type: 1
m_Type: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 0.2
m_Range: 10
m_SpotAngle: 30
m_Intensity: 0.6
m_Range: 25
m_SpotAngle: 50
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_Resolution: 1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
Expand All @@ -3323,7 +3324,7 @@ Transform:
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 390130554}
m_LocalRotation: {x: 0.008726536, y: 0, z: 0, w: 0.9999619}
m_LocalPosition: {x: 0, y: 0, z: -10}
m_LocalPosition: {x: 0, y: 3, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 659405360}
Expand Down Expand Up @@ -3761,13 +3762,13 @@ Light:
serializedVersion: 8
m_Type: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 1.4
m_Intensity: 1.64
m_Range: 14
m_SpotAngle: 40
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_Resolution: 0
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.01
Expand Down Expand Up @@ -11415,6 +11416,51 @@ MonoBehaviour:
m_CallState: 2
m_TypeName: Klak.Wiring.NodeBase+VoidEvent, Assembly-CSharp, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!1 &1107727445
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1107727447}
- component: {fileID: 1107727446}
m_Layer: 0
m_Name: Shadow Slicer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1107727446
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1107727445}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41fef7dd5c8b7a54fa30a95193c69a80, type: 3}
m_Name:
m_EditorClassIdentifier:
_baseCamera: {fileID: 199947338}
_targetTexture: {fileID: 8400000, guid: 847b7e8511b6e454c86a6b84397f298c, type: 2}
_albedo: {r: 0.84313726, g: 0.84313726, b: 0.84313726, a: 0}
_quadMesh: {fileID: 10210, guid: 0000000000000000e000000000000000, type: 0}
_slicerShader: {fileID: 4800000, guid: db41ffe7fccd2c843b554ecae7e1f07b, type: 3}
--- !u!4 &1107727447
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1107727445}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 1.9345, z: 3.3215}
m_LocalScale: {x: 9.1, y: 3.869, z: 1}
m_Children: []
m_Father: {fileID: 310351456}
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1116142349
GameObject:
m_ObjectHideFlags: 0
Expand Down Expand Up @@ -13788,13 +13834,13 @@ Light:
serializedVersion: 8
m_Type: 0
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 1.4
m_Intensity: 1.64
m_Range: 14
m_SpotAngle: 40
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_Resolution: 0
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.01
Expand Down Expand Up @@ -14697,7 +14743,7 @@ Light:
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_Resolution: 2
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.01
Expand Down Expand Up @@ -14810,7 +14856,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!20 &1450734906
Camera:
m_ObjectHideFlags: 0
Expand Down
118 changes: 118 additions & 0 deletions Assets/Prisma/Scripts/ShadowSlicer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using UnityEngine;
using UnityEngine.Rendering;

namespace Prisma
{
//
// Shadow Slicer
//
// In the previous versions of the Pepper's ghost rig, I used a secondary
// camera to render shadows on the background wall. This is very costly
// because it needs generating whole shadow maps twice (Unity never shares
// shadow maps between cameras).
//
// This "Shadow Slicer" is designed to eliminate the cost of the secondary
// camera. It renders the shadows on the wall with reusing the shadow maps
// generated by the main camera.
//
// How it works: The shadow slicer renders the shadows by hijacking the
// forward-opaque pass of the main camera -- the other parts of this
// project only use the deferred shading pass, so we can safely mess it up!
//
// 1. (Before Forward Opaque) Make a backup of the color buffer.
// 2. (Forward Base) Clear the color buffer with a full-screen quad.
// 3. (Forward Add) Draw a full-screen quad with shadow maps.
// 4. (After Forward Opaque) Retrieve the results and restore the backup.
//
// One of the biggest disadvantages of this approach is that we can't use
// directional lights with it (in Unity 5.x, shadow maps with directional
// lights are flatten into screen-space shadow masks while rendering, so
// we can't "slice" these shadows in the later passes).
//
public class ShadowSlicer : MonoBehaviour
{
#region Exposed attributes

[SerializeField] Camera _baseCamera;
[SerializeField] RenderTexture _targetTexture;
[SerializeField, ColorUsage(false)] Color _albedo = Color.white;

#endregion

#region Built-in resources

[SerializeField, HideInInspector] Mesh _quadMesh;
[SerializeField, HideInInspector] Shader _slicerShader;

#endregion

#region Private objects

Material _slicerMaterial;
RenderTexture _backupBuffer;
CommandBuffer _backupCommand;
CommandBuffer _restoreCommand;

#endregion

#region MonoBehaviour functions

void OnEnable()
{
var width = _baseCamera.pixelWidth;
var height = _baseCamera.pixelHeight;

_backupBuffer = RenderTexture.GetTemporary(width, height, 0);

if (_backupCommand == null)
{
_backupCommand = new CommandBuffer();
_backupCommand.name = "Shadow Slicer (Backup)";
_backupCommand.Blit(BuiltinRenderTextureType.CurrentActive, _backupBuffer);
}

if (_restoreCommand == null)
{
_restoreCommand = new CommandBuffer();
_restoreCommand.name = "Shadow Slicer (Restore)";
_restoreCommand.Blit(BuiltinRenderTextureType.CurrentActive, _targetTexture);
_restoreCommand.Blit(_backupBuffer, BuiltinRenderTextureType.CameraTarget);
}

_baseCamera.AddCommandBuffer(CameraEvent.BeforeForwardOpaque, _backupCommand);
_baseCamera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, _restoreCommand);
}

void OnDisable()
{
if (_baseCamera != null)
{
_baseCamera.RemoveCommandBuffer(CameraEvent.BeforeForwardOpaque, _backupCommand);
_baseCamera.RemoveCommandBuffer(CameraEvent.AfterForwardOpaque, _restoreCommand);
}
}

void OnDestroy()
{
if (_slicerMaterial != null) Destroy(_slicerMaterial);
if (_backupBuffer != null) RenderTexture.ReleaseTemporary(_backupBuffer);
if (_backupCommand != null) _backupCommand.Dispose();
if (_restoreCommand != null) _restoreCommand.Dispose();
}

void Update()
{
if (_slicerMaterial == null)
_slicerMaterial = new Material(_slicerShader);

_slicerMaterial.SetColor("_Color", _albedo);

Graphics.DrawMesh(
_quadMesh, transform.localToWorldMatrix, _slicerMaterial,
gameObject.layer, _baseCamera
);
}

#endregion
}
}
16 changes: 16 additions & 0 deletions Assets/Prisma/Scripts/ShadowSlicer.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 83 additions & 0 deletions Assets/Prisma/Shaders/ShadowSlicer.shader
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Shadow Slicer shader: See ShadowSlicer.cs for details.

Shader "Hidden/Prisma/ShadowSlicer"
{
Properties
{
_Color("", Color) = (1, 1, 1, 1)
}
SubShader
{
ZTest always ZWrite off

// Forward base: draws black full-screen quad.
Pass
{
Tags { "LightMode" = "ForwardBase" }

CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"

float4 vert(float4 vertex : POSITION) : SV_POSITION
{
return float4(vertex.xy * float2(2, -2), 0, 1);
}

fixed4 frag() : SV_Target
{
return 0;
}

ENDCG
}

// Forward add:
// renders a slice of a shadow volume with a full-screen quad.
Pass
{
Tags { "LightMode" = "ForwardAdd" }

Blend One One

CGPROGRAM

#pragma vertex vert
#pragma fragment frag

#pragma multi_compile_fwdadd_fullshadows
#pragma skip_variants DIRECTIONAL SHADOWS_SCREEN POINT_COOKIE DIRECTIONAL_COOKIE

#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"

fixed4 _Color;

struct v2f
{
float4 vertex : SV_POSITION;
float3 worldPos : TEXCOORD0;
};

v2f vert(float4 vertex : POSITION)
{
v2f o;
o.vertex = float4(vertex.xy * float2(2, -2), 0, 1);
o.worldPos = mul(unity_ObjectToWorld, vertex).xyz;
return o;
}

half4 frag(v2f IN) : SV_Target
{
UNITY_LIGHT_ATTENUATION(atten, IN, IN.worldPos)
return half4(_Color.rgb * _LightColor0.rgb * atten, 1);
}

ENDCG
}
}
}
9 changes: 9 additions & 0 deletions Assets/Prisma/Shaders/ShadowSlicer.shader.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ProjectSettings/GraphicsSettings.asset
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ GraphicsSettings:
- {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
type: 0}
Expand Down
3 changes: 2 additions & 1 deletion ProjectSettings/ProjectSettings.asset
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,8 @@ PlayerSettings:
webGLUseEmbeddedResources: 0
webGLUseWasm: 0
webGLCompressionFormat: 1
scriptingDefineSymbols: {}
scriptingDefineSymbols:
1:
platformArchitecture: {}
scriptingBackend: {}
incrementalIl2cppBuild: {}
Expand Down

0 comments on commit 0a7f5a3

Please sign in to comment.