Skip to content
This repository was archived by the owner on Nov 30, 2020. It is now read-only.

Commit 0db0e8c

Browse files
committed
Added lens distortion effect
1 parent 3df814c commit 0db0e8c

File tree

9 files changed

+164
-9
lines changed

9 files changed

+164
-9
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using UnityEngine.Rendering.PostProcessing;
2+
3+
namespace UnityEditor.Rendering.PostProcessing
4+
{
5+
[PostProcessEditor(typeof(LensDistortion))]
6+
public sealed class LensDistortionEditor : DefaultPostProcessEffectEditor
7+
{
8+
public override void OnInspectorGUI()
9+
{
10+
if (RuntimeUtilities.isVREnabled)
11+
EditorGUILayout.HelpBox("Lens Distortion is automatically disabled when VR is enabled.", MessageType.Warning);
12+
13+
base.OnInspectorGUI();
14+
}
15+
}
16+
}

PostProcessing/Editor/Effects/LensDistortionEditor.cs.meta

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System;
2+
3+
namespace UnityEngine.Rendering.PostProcessing
4+
{
5+
[Serializable]
6+
[PostProcess(typeof(LensDistortionRenderer), "Unity/Lens Distortion")]
7+
public sealed class LensDistortion : PostProcessEffectSettings
8+
{
9+
[Range(-100f, 100f), Tooltip("Total distortion amount.")]
10+
public FloatParameter intensity = new FloatParameter { value = 0f };
11+
12+
[Range(0f, 1f), DisplayName("Y Multiplier"), Tooltip("Intensity multiplier on X axis. Set it to 0 to disable distortion on this axis.")]
13+
public FloatParameter intensityX = new FloatParameter { value = 1f };
14+
15+
[Range(0f, 1f), DisplayName("X Multiplier"), Tooltip("Intensity multiplier on Y axis. Set it to 0 to disable distortion on this axis.")]
16+
public FloatParameter intensityY = new FloatParameter { value = 1f };
17+
18+
[Space]
19+
[Range(-1f, 1f), Tooltip("Distortion center point (X axis).")]
20+
public FloatParameter centerX = new FloatParameter { value = 0f };
21+
22+
[Range(-1f, 1f), Tooltip("Distortion center point (Y axis).")]
23+
public FloatParameter centerY = new FloatParameter { value = 0f };
24+
25+
[Space]
26+
[Range(0.01f, 5f), Tooltip("Global screen scaling.")]
27+
public FloatParameter scale = new FloatParameter { value = 1f };
28+
29+
public override bool IsEnabledAndSupported(PostProcessRenderContext context)
30+
{
31+
return enabled.value
32+
&& !Mathf.Approximately(intensity, 0f)
33+
&& (intensityX > 0f || intensityY > 0f)
34+
&& !RuntimeUtilities.isVREnabled;
35+
}
36+
}
37+
38+
public sealed class LensDistortionRenderer : PostProcessEffectRenderer<LensDistortion>
39+
{
40+
public override void Render(PostProcessRenderContext context)
41+
{
42+
var sheet = context.uberSheet;
43+
44+
float amount = 1.6f * Math.Max(Mathf.Abs(settings.intensity.value), 1f);
45+
float theta = Mathf.Deg2Rad * Math.Min(160f, amount);
46+
float sigma = 2f * Mathf.Tan(theta * 0.5f);
47+
var p0 = new Vector4(settings.centerX.value, settings.centerY.value, Mathf.Max(settings.intensityX.value, 1e-4f), Mathf.Max(settings.intensityY.value, 1e-4f));
48+
var p1 = new Vector4(settings.intensity.value >= 0f ? theta : 1f / theta, sigma, 1f / settings.scale.value, settings.intensity.value);
49+
50+
sheet.EnableKeyword("DISTORT");
51+
sheet.properties.SetVector(ShaderIDs.Distortion_CenterScale, p0);
52+
sheet.properties.SetVector(ShaderIDs.Distortion_Amount, p1);
53+
}
54+
}
55+
}

PostProcessing/Runtime/Effects/LensDistortion.cs.meta

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

PostProcessing/Runtime/PostProcessLayer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,7 @@ int RenderBuiltins(PostProcessRenderContext context, bool isFinalPass, int relea
839839
RenderEffect<AutoExposure>(context);
840840
uberSheet.properties.SetTexture(ShaderIDs.AutoExposureTex, context.autoExposureTexture);
841841

842+
RenderEffect<LensDistortion>(context);
842843
RenderEffect<ChromaticAberration>(context);
843844
RenderEffect<Bloom>(context);
844845
RenderEffect<Vignette>(context);

PostProcessing/Runtime/Utils/ShaderIDs.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ static class ShaderIDs
9393
internal static readonly int ChromaticAberration_Amount = Shader.PropertyToID("_ChromaticAberration_Amount");
9494
internal static readonly int ChromaticAberration_SpectralLut = Shader.PropertyToID("_ChromaticAberration_SpectralLut");
9595

96+
internal static readonly int Distortion_CenterScale = Shader.PropertyToID("_Distortion_CenterScale");
97+
internal static readonly int Distortion_Amount = Shader.PropertyToID("_Distortion_Amount");
98+
9699
internal static readonly int Lut2D = Shader.PropertyToID("_Lut2D");
97100
internal static readonly int Lut3D = Shader.PropertyToID("_Lut3D");
98101
internal static readonly int Lut3D_Params = Shader.PropertyToID("_Lut3D_Params");
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#ifndef UNITY_POSTFX_DISTORTION
2+
#define UNITY_POSTFX_DISTORTION
3+
4+
float4 _Distortion_Amount;
5+
float4 _Distortion_CenterScale;
6+
7+
float2 Distort(float2 uv)
8+
{
9+
// Note: lens distortion is automatically disabled in VR so we won't bother handling stereo uvs
10+
#if DISTORT
11+
{
12+
uv = (uv - 0.5) * _Distortion_Amount.z + 0.5;
13+
float2 ruv = _Distortion_CenterScale.zw * (uv - 0.5 - _Distortion_CenterScale.xy);
14+
float ru = length(float2(ruv));
15+
16+
UNITY_BRANCH
17+
if (_Distortion_Amount.w > 0.0)
18+
{
19+
float wu = ru * _Distortion_Amount.x;
20+
ru = tan(wu) * (1.0 / (ru * _Distortion_Amount.y));
21+
uv = uv + ruv * (ru - 1.0);
22+
}
23+
else
24+
{
25+
ru = (1.0 / ru) * _Distortion_Amount.x * atan(ru * _Distortion_Amount.y);
26+
uv = uv + ruv * (ru - 1.0);
27+
}
28+
}
29+
#endif
30+
31+
return uv;
32+
}
33+
34+
#endif // UNITY_POSTFX_DISTORTION

PostProcessing/Shaders/Builtins/Distortion.hlsl.meta

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

PostProcessing/Shaders/Builtins/Uber.shader

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Shader "Hidden/PostProcessing/Uber"
55
#pragma target 3.0
66

77
#pragma multi_compile __ UNITY_COLORSPACE_GAMMA
8+
#pragma multi_compile __ DISTORT
89
#pragma multi_compile __ CHROMATIC_ABERRATION CHROMATIC_ABERRATION_LOW
910
#pragma multi_compile __ BLOOM
1011
#pragma multi_compile __ COLOR_GRADING_LDR_2D COLOR_GRADING_HDR_2D COLOR_GRADING_HDR_3D
@@ -15,6 +16,7 @@ Shader "Hidden/PostProcessing/Uber"
1516
#include "../StdLib.hlsl"
1617
#include "../Colors.hlsl"
1718
#include "../Sampling.hlsl"
19+
#include "Distortion.hlsl"
1820
#include "Dithering.hlsl"
1921

2022
#define MAX_CHROMATIC_SAMPLES 16
@@ -71,6 +73,12 @@ Shader "Hidden/PostProcessing/Uber"
7173
half4 FragUber(VaryingsDefault i) : SV_Target
7274
{
7375
float2 uv = i.texcoord;
76+
77+
//>>> Automatically skipped by the shader optimizer when not used
78+
float2 uvDistorted = Distort(i.texcoord);
79+
float2 uvStereoDistorted = Distort(i.texcoordStereo);
80+
//<<<
81+
7482
half autoExposure = SAMPLE_TEXTURE2D(_AutoExposureTex, sampler_AutoExposureTex, uv).r;
7583
half4 color = (0.0).xxxx;
7684

@@ -90,7 +98,7 @@ Shader "Hidden/PostProcessing/Uber"
9098
for (int i = 0; i < samples; i++)
9199
{
92100
half t = (i + 0.5) / samples;
93-
half4 s = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(pos), 0);
101+
half4 s = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(pos)), 0);
94102
half4 filter = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(t, 0.0), 0).rgb, 1.0);
95103

96104
sum += s * filter;
@@ -110,17 +118,17 @@ Shader "Hidden/PostProcessing/Uber"
110118
half4 filterB = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(1.5 / 3, 0.0), 0).rgb, 1.0);
111119
half4 filterC = half4(SAMPLE_TEXTURE2D_LOD(_ChromaticAberration_SpectralLut, sampler_ChromaticAberration_SpectralLut, float2(2.5 / 3, 0.0), 0).rgb, 1.0);
112120

113-
half4 texelA = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(uv), 0);
114-
half4 texelB = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(delta + uv), 0);
115-
half4 texelC = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(delta * 2.0 + uv), 0);
121+
half4 texelA = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(uv)), 0);
122+
half4 texelB = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(delta + uv)), 0);
123+
half4 texelC = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, UnityStereoTransformScreenSpaceTex(Distort(delta * 2.0 + uv)), 0);
116124

117125
half4 sum = texelA * filterA + texelB * filterB + texelC * filterC;
118126
half4 filterSum = filterA + filterB + filterC;
119127
color = sum / filterSum;
120128
}
121129
#else
122130
{
123-
color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoordStereo);
131+
color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uvStereoDistorted);
124132
}
125133
#endif
126134

@@ -135,8 +143,13 @@ Shader "Hidden/PostProcessing/Uber"
135143

136144
#if BLOOM
137145
{
138-
half4 bloom = UpsampleTent(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), i.texcoord, _BloomTex_TexelSize.xy, _Bloom_Settings.x);
139-
half4 dirt = half4(SAMPLE_TEXTURE2D(_Bloom_DirtTex, sampler_Bloom_DirtTex, i.texcoord * _Bloom_DirtTileOffset.xy + _Bloom_DirtTileOffset.zw).rgb, 0.0);
146+
half4 bloom = UpsampleTent(TEXTURE2D_PARAM(_BloomTex, sampler_BloomTex), uvDistorted, _BloomTex_TexelSize.xy, _Bloom_Settings.x);
147+
148+
// UVs should be Distort(uv * _Bloom_DirtTileOffset.xy + _Bloom_DirtTileOffset.zw)
149+
// but considering we use a cover-style scale on the dirt texture the difference
150+
// isn't massive so we chose to save a few ALUs here instead in case lens distortion
151+
// is active
152+
half4 dirt = half4(SAMPLE_TEXTURE2D(_Bloom_DirtTex, sampler_Bloom_DirtTex, uvDistorted * _Bloom_DirtTileOffset.xy + _Bloom_DirtTileOffset.zw).rgb, 0.0);
140153

141154
// Additive bloom (artist friendly)
142155
bloom *= _Bloom_Settings.y;
@@ -151,7 +164,7 @@ Shader "Hidden/PostProcessing/Uber"
151164
UNITY_BRANCH
152165
if (_Vignette_Mode < 0.5)
153166
{
154-
half2 d = abs(uv - _Vignette_Center) * _Vignette_Settings.x;
167+
half2 d = abs(uvDistorted - _Vignette_Center) * _Vignette_Settings.x;
155168
d.x *= lerp(1.0, _ScreenParams.x / _ScreenParams.y, _Vignette_Settings.w);
156169
d = pow(saturate(d), _Vignette_Settings.z); // Roundness
157170
half vfactor = pow(saturate(1.0 - dot(d, d)), _Vignette_Settings.y);
@@ -160,7 +173,7 @@ Shader "Hidden/PostProcessing/Uber"
160173
}
161174
else
162175
{
163-
half vfactor = SAMPLE_TEXTURE2D(_Vignette_Mask, sampler_Vignette_Mask, uv).a;
176+
half vfactor = SAMPLE_TEXTURE2D(_Vignette_Mask, sampler_Vignette_Mask, uvDistorted).a;
164177

165178
#if !UNITY_COLORSPACE_GAMMA
166179
{

0 commit comments

Comments
 (0)