Skip to content

Commit 194a362

Browse files
committed
Initial Commit
1 parent 2e77da1 commit 194a362

20 files changed

Lines changed: 1817 additions & 0 deletions

Keyhole/Keyhole.unity

Lines changed: 754 additions & 0 deletions
Large diffs are not rendered by default.

Keyhole/Keyhole.unity.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Keyhole/KeyholeOverlay.shader

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
//Some shader code is based on Dan Moran's Shader case study of Pokemon Battle Transition YouTube video
2+
//and Acerola's post processing github
3+
//The only change is the removal of the distort calculation and parameters and modifications to the gaussian blur
4+
//code to be more oriented in blurring the edges of the keyhole mask.
5+
Shader "Hidden/KeyholeOverlay"
6+
{
7+
Properties
8+
{
9+
_MainTex("Texture", 2D) = "white" {}
10+
_KeyholeTex("Keyhole Texture", 2D) = "white" {}
11+
_Color("Screen Color", Color) = (1,1,1,1)
12+
_Cutoff("Cutoff", Range(0, 1)) = 0
13+
_Fade("Fade", Range(0, 1)) = 0
14+
_Scale("Scale", Range(0,3)) = 1
15+
_BlurAmount("Blur Amount", Float) = 1.0
16+
_BlurEdgeThreshold("Blur Amount", Float) = 0.01
17+
_BlurEdgeRefine("Blur Edge Refine", Float) = 0.45
18+
}
19+
20+
SubShader
21+
{
22+
// No culling or depth
23+
Cull Off ZWrite Off ZTest Always
24+
25+
CGINCLUDE
26+
27+
#include "UnityCG.cginc"
28+
29+
//all the structs needed for the passes
30+
struct appdata
31+
{
32+
float4 vertex : POSITION;
33+
float2 uv : TEXCOORD0;
34+
};
35+
36+
struct v2f
37+
{
38+
float2 uv : TEXCOORD0;
39+
float2 uv1 : TEXCOORD1;
40+
float4 vertex : SV_POSITION;
41+
};
42+
43+
//variables relating to textures
44+
sampler2D _MainTex;
45+
float4 _MainTex_TexelSize;
46+
sampler2D _KeyholeTex;
47+
48+
//other variables
49+
float4 _Color;
50+
float _Scale;
51+
float _Fade;
52+
float _Cutoff;
53+
float _BlurAmount;
54+
float _BlurEdgeThreshold;
55+
float _BlurEdgeRefine;
56+
57+
//vert function for first pass (index 0)
58+
v2f vert(appdata v)
59+
{
60+
v2f o;
61+
o.vertex = UnityObjectToClipPos(v.vertex);
62+
63+
o.uv = v.uv;
64+
o.uv1 = v.uv;
65+
66+
#if UNITY_UV_STARTS_AT_TOP
67+
if (_MainTex_TexelSize.y < 0)
68+
o.uv1.y = 1 - o.uv1.y;
69+
#endif
70+
71+
return o;
72+
}
73+
74+
//vert function for second and third pass (index 1 & 2)
75+
v2f vp(appdata v) {
76+
v2f o;
77+
o.vertex = UnityObjectToClipPos(v.vertex);
78+
o.uv = v.uv;
79+
o.uv1 = v.uv;
80+
return o;
81+
}
82+
83+
#define PI 3.14159265358979323846f
84+
85+
// Helper function to calculate gaussian needed for the blur effect
86+
// Normally supposed to use a 3x3 matrix of pre determined weights of each pixel in a 3x3 grid
87+
// But I am using a line from Acerola's open source code from his post processing github repo to run a equation that does the
88+
// calculation itself that results a very close aproximation of the values similar to the ones in the pre determined weight matrix
89+
float gaussian(float sigma, float pos) {
90+
return (1.0f / sqrt(2.0f * PI * sigma * sigma)) * exp(-(pos * pos) / (2.0f * sigma * sigma));
91+
}
92+
93+
// Helper function to determine if we're at the edge
94+
float isEdge(float maskValue, float cutoff) {
95+
fixed edgeWidth = _BlurEdgeThreshold;
96+
fixed distFromCutoff = abs(maskValue - cutoff);
97+
return 1.0 - saturate(distFromCutoff / edgeWidth);
98+
}
99+
ENDCG
100+
101+
//keyhole hole cutout mask pass (index 0)
102+
Pass
103+
{
104+
CGPROGRAM
105+
#pragma vertex vert
106+
#pragma fragment frag
107+
108+
fixed4 frag(v2f i) : SV_Target
109+
{
110+
//Scale the uv to desired center position
111+
fixed2 uv = i.uv1;
112+
uv -= 0.5;
113+
uv /= _Scale;
114+
uv += 0.5;
115+
116+
fixed4 transit = tex2D(_KeyholeTex, uv);
117+
118+
fixed2 direction = float2(0,0);
119+
120+
//getting the screen colour with cutoff values and mask in place
121+
fixed4 col = tex2D(_MainTex, i.uv + _Cutoff * direction);
122+
123+
//overlay our results onto the screen to mask it off
124+
if (transit.b < _Cutoff){
125+
col = lerp(col, _Color, _Fade);
126+
}
127+
128+
return col;
129+
}
130+
ENDCG
131+
}
132+
133+
// Gaussian Blur First Pass (index 1)
134+
Pass {
135+
CGPROGRAM
136+
#pragma vertex vp
137+
#pragma fragment fp
138+
139+
//where all the rendering work is at
140+
fixed4 fp(v2f i) : SV_Target {
141+
//Scale the uv to desired center position
142+
fixed2 uv = i.uv1;
143+
uv -= 0.5;
144+
uv.x /= _Scale; //- 0.06f;
145+
uv.y /= _Scale; //- 0.02f;
146+
//uv /= _Scale;
147+
uv += 0.5;
148+
149+
fixed4 transit = tex2D(_KeyholeTex, uv);
150+
151+
fixed maskValue = transit.b;
152+
//get the edge factor and apply the gaussian blur on it
153+
fixed edgeFactor = isEdge(maskValue, _Cutoff);
154+
if (edgeFactor > 0.0) {
155+
fixed4 output = 0;
156+
fixed sum = 0;
157+
//gaussian blur stuff
158+
for (int x = -9; x <= 9; ++x) {
159+
fixed2 offset = float2(x, 0) * _MainTex_TexelSize.xy;
160+
fixed4 c = tex2D(_MainTex, i.uv + offset);
161+
fixed gauss = gaussian(_BlurAmount, x);
162+
163+
output += c * gauss;
164+
sum += gauss;
165+
}
166+
//normalize and overlay our results onto the screen
167+
fixed4 blurred = output / sum;
168+
return lerp(tex2D(_MainTex, i.uv), blurred, _BlurEdgeRefine);
169+
}
170+
//if its not the right place to blur, just return the original screen color
171+
return tex2D(_MainTex, i.uv);
172+
}
173+
ENDCG
174+
}
175+
176+
// Gaussian Blur Second Pass (index 2)
177+
Pass {
178+
CGPROGRAM
179+
#pragma vertex vp
180+
#pragma fragment fp
181+
182+
//where all the rendering work is at
183+
fixed4 fp(v2f i) : SV_Target {
184+
//Scale the uv to desired center position
185+
fixed2 uv = i.uv1;
186+
uv -= 0.5;
187+
uv.x /= _Scale; //- 0.06f;
188+
uv.y /= _Scale; //- 0.02f;
189+
//uv /= _Scale;
190+
uv += 0.5;
191+
192+
fixed4 transit = tex2D(_KeyholeTex, uv);
193+
194+
fixed maskValue = transit.b;
195+
//get the edge factor and apply the gaussian blur on it
196+
fixed edgeFactor = isEdge(maskValue, _Cutoff);
197+
if (edgeFactor > 0.0) {
198+
fixed4 output = 0;
199+
fixed sum = 0;
200+
//gaussian blur stuff
201+
for (int y = -9; y <= 9; ++y) {
202+
fixed2 offset = float2(0, y) * _MainTex_TexelSize.xy;
203+
fixed4 c = tex2D(_MainTex, i.uv + offset);
204+
fixed gauss = gaussian(_BlurAmount, y);
205+
206+
output += c * gauss;
207+
sum += gauss;
208+
}
209+
//normalize and overlay our results onto the screen
210+
fixed4 blurred = output / sum;
211+
return lerp(tex2D(_MainTex, i.uv), blurred, _BlurEdgeRefine);
212+
}
213+
//if its not the right place to blur, just return the original screen color
214+
return tex2D(_MainTex, i.uv);
215+
}
216+
ENDCG
217+
}
218+
}
219+
}

Keyhole/KeyholeOverlay.shader.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Keyhole/KeyholeOverlayPass.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
using UnityEngine.Rendering;
5+
using UnityEngine.Rendering.Universal;
6+
7+
//render pass code for the transition effect
8+
public class KeyholeOverlayPass : ScriptableRenderPass
9+
{
10+
static readonly string renderPassTag = "Keyhole Overlay";
11+
12+
private KeyholeOverlayVolume KeyholeOverlayVolume;
13+
//material containing the shader
14+
private Material KeyholeOverlayMaterial;
15+
16+
//initializes our variables
17+
public KeyholeOverlayPass(RenderPassEvent evt, Shader KeyholeOverlayshader)
18+
{
19+
renderPassEvent = evt;
20+
if (KeyholeOverlayshader == null)
21+
{
22+
Debug.LogError("No Shader");
23+
return;
24+
}
25+
//to make profiling easier
26+
profilingSampler = new ProfilingSampler(renderPassTag);
27+
KeyholeOverlayMaterial = CoreUtils.CreateEngineMaterial(KeyholeOverlayshader);
28+
}
29+
//where our rendering of the effect starts
30+
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
31+
{
32+
if (KeyholeOverlayMaterial == null)
33+
{
34+
Debug.LogError("No KeyholeOverlay Material");
35+
return;
36+
}
37+
//in case if the camera doesn't have the post process option enabled and if the camera is not the game's camera
38+
if (!renderingData.cameraData.postProcessEnabled || (renderingData.cameraData.cameraType != CameraType.Game))
39+
{
40+
return;
41+
}
42+
43+
VolumeStack stack = VolumeManager.instance.stack;
44+
KeyholeOverlayVolume = stack.GetComponent<KeyholeOverlayVolume>();
45+
46+
var cmd = CommandBufferPool.Get(renderPassTag);
47+
Render(cmd, ref renderingData);
48+
49+
context.ExecuteCommandBuffer(cmd);
50+
cmd.Clear();
51+
52+
CommandBufferPool.Release(cmd);
53+
}
54+
55+
//helper method to contain all of our rendering code for the Execute() method
56+
void Render(CommandBuffer cmd, ref RenderingData renderingData)
57+
{
58+
//we handle the setting the shader's material's parameters/variables in the transition volume script instead of here
59+
if (KeyholeOverlayVolume.IsActive() == false) return;
60+
KeyholeOverlayVolume.load(KeyholeOverlayMaterial, ref renderingData);
61+
62+
//for profiling
63+
using (new ProfilingScope(cmd, profilingSampler))
64+
{
65+
var src = renderingData.cameraData.renderer.cameraColorTargetHandle;
66+
67+
int width = renderingData.cameraData.cameraTargetDescriptor.width;
68+
int height = renderingData.cameraData.cameraTargetDescriptor.height;
69+
70+
var tempColorTexture = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32);
71+
var tempColorTexture2 = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32);
72+
73+
//actual rendering code
74+
cmd.Blit(src, tempColorTexture, KeyholeOverlayMaterial, 0);
75+
cmd.Blit(tempColorTexture, tempColorTexture2, KeyholeOverlayMaterial, 1);
76+
cmd.Blit(tempColorTexture2, src, KeyholeOverlayMaterial, 2);
77+
//cmd.Blit(tempColorTexture, src, KeyholeOverlayMaterial, 1);
78+
79+
RenderTexture.ReleaseTemporary(tempColorTexture);
80+
RenderTexture.ReleaseTemporary(tempColorTexture2);
81+
}
82+
}
83+
}

Keyhole/KeyholeOverlayPass.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
using UnityEngine.Rendering;
5+
using UnityEngine.Rendering.Universal;
6+
7+
public class KeyholeOverlayRenderFeature : ScriptableRendererFeature
8+
{
9+
//initialzing the render feature settings
10+
[System.Serializable]
11+
public class Settings
12+
{
13+
public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
14+
//the transition shader, will automatically be assigned
15+
public Shader shader;
16+
}
17+
public Settings settings = new Settings();
18+
19+
KeyholeOverlayPass m_KeyholeOverlayPass;
20+
21+
//When render feature object is enabled, set the shader
22+
private void OnEnable()
23+
{
24+
settings.shader = Shader.Find("Hidden/KeyholeOverlay");
25+
}
26+
//sets the hatching's render pass up
27+
public override void Create()
28+
{
29+
this.name = "KeyholeOverlay Pass";
30+
if (settings.shader == null)
31+
{
32+
Debug.LogWarning("No KeyholeOverlay Shader");
33+
return;
34+
}
35+
m_KeyholeOverlayPass = new KeyholeOverlayPass(settings.renderPassEvent, settings.shader);
36+
}
37+
38+
//call and adds the hatching render pass to the scriptable renderer's queue
39+
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
40+
{
41+
renderer.EnqueuePass(m_KeyholeOverlayPass);
42+
}
43+
}

Keyhole/KeyholeOverlayRenderFeature.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)