├── .gitignore ├── Assets ├── Addons.meta ├── Addons │ ├── Dither Functions.cginc │ └── Dither Functions.cginc.meta ├── Materials.meta ├── Materials │ ├── ReceiveShadowMat.mat │ ├── ReceiveShadowMat.mat.meta │ ├── TransReceiveShadowMat.mat │ └── TransReceiveShadowMat.mat.meta ├── Scenes.meta ├── Scenes │ ├── scene.unity │ └── scene.unity.meta ├── Scripts.meta ├── Scripts │ ├── CustomShadows.cs │ └── CustomShadows.cs.meta ├── Shaders.meta └── Shaders │ ├── DepthShader.shader │ ├── DepthShader.shader.meta │ ├── LitShader.shader │ ├── LitShader.shader.meta │ ├── compute.meta │ └── compute │ ├── blur-compute.compute │ └── blur-compute.compute.meta ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityAdsSettings.asset └── UnityConnectSettings.asset └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | # Visual Studio 2015 cache directory 9 | /.vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | 26 | # Unity3D generated meta files 27 | *.pidb.meta 28 | 29 | # Unity3D Generated File On Crash Reports 30 | sysinfo.txt 31 | 32 | # Builds 33 | *.apk 34 | *.unitypackage 35 | -------------------------------------------------------------------------------- /Assets/Addons.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1657f39f98b71f042b51ad83468e47a9 3 | folderAsset: yes 4 | timeCreated: 1508213162 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Addons/Dither Functions.cginc: -------------------------------------------------------------------------------- 1 | // Returns > 0 if not clipped, < 0 if clipped based 2 | // on the dither 3 | // For use with the "clip" function 4 | float isDithered(float2 pos, float alpha) { 5 | // Define a dither threshold matrix which can 6 | // be used to define how a 4x4 set of pixels 7 | // will be dithered 8 | float4x4 DITHER_THRESHOLDS = 9 | { 10 | 1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0, 11 | 13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0, 12 | 4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0, 13 | 16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0 14 | }; 15 | 16 | return alpha - DITHER_THRESHOLDS[pos.x % 4][pos.y % 4]; 17 | } 18 | 19 | // Returns whether the pixel should be discarded based 20 | // on the dither texture 21 | float isDithered(float2 pos, float alpha, sampler2D tex, float scale) { 22 | pos.x -= _ScreenParams.x / 2; 23 | pos.y -= _ScreenParams.y / 2; 24 | pos.x /= scale; 25 | pos.y /= scale; 26 | 27 | return alpha - tex2D(tex, pos.xy).r; 28 | } 29 | 30 | // Helpers that call the above functions and clip if necessary 31 | void ditherClip(float2 pos, float alpha) { 32 | clip(isDithered(pos, alpha)); 33 | } 34 | 35 | void ditherClip(float2 pos, float alpha, sampler2D tex, float scale) { 36 | clip(isDithered(pos, alpha, tex, scale)); 37 | } -------------------------------------------------------------------------------- /Assets/Addons/Dither Functions.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb65016cfe72c584899dcf72d06ae87a 3 | timeCreated: 1508213200 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0f95528e15567bc488f41ee639cc0c7c 3 | folderAsset: yes 4 | timeCreated: 1472605517 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Materials/ReceiveShadowMat.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/Assets/Materials/ReceiveShadowMat.mat -------------------------------------------------------------------------------- /Assets/Materials/ReceiveShadowMat.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3331a09088e01ce41a5a67bffec2d9e7 3 | timeCreated: 1457680726 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/TransReceiveShadowMat.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/Assets/Materials/TransReceiveShadowMat.mat -------------------------------------------------------------------------------- /Assets/Materials/TransReceiveShadowMat.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 806597ff05a57d94db78abdd75561da7 3 | timeCreated: 1457680726 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 00ae5e24aea94414aa9269d314be8f31 3 | folderAsset: yes 4 | timeCreated: 1472600815 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Scenes/scene.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/Assets/Scenes/scene.unity -------------------------------------------------------------------------------- /Assets/Scenes/scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f8bfb3c8b07519841b9915bd594687d0 3 | timeCreated: 1472602502 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4de31ed03b6c114cbc198de90ebbfc0 3 | folderAsset: yes 4 | timeCreated: 1455166483 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Scripts/CustomShadows.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | 4 | [ExecuteInEditMode] 5 | public class CustomShadows : MonoBehaviour { 6 | 7 | public enum Shadows 8 | { 9 | NONE, 10 | HARD, 11 | VARIANCE 12 | } 13 | 14 | [Header("Initialization")] 15 | [SerializeField] 16 | Shader _depthShader; 17 | 18 | [SerializeField] 19 | int _resolution = 1024; 20 | 21 | [SerializeField] 22 | ComputeShader _blur; 23 | 24 | [Header("Shadow Settings")] 25 | [Range(0, 100)] 26 | public int blurIterations = 1; 27 | 28 | [Range(0, 1)] 29 | public float maxShadowIntensity = 1; 30 | public bool drawTransparent = true; 31 | 32 | [Range(0, 1)] 33 | public float varianceShadowExpansion = 0.3f; 34 | public Shadows _shadowType = Shadows.HARD; 35 | public FilterMode _filterMode = FilterMode.Bilinear; 36 | 37 | // Render Targets 38 | Camera _shadowCam; 39 | RenderTexture _backTarget; 40 | RenderTexture _target; 41 | 42 | #region LifeCycle 43 | void Update () 44 | { 45 | _depthShader = _depthShader ? _depthShader : Shader.Find("Hidden/CustomShadows/Depth"); 46 | SetUpShadowCam(); 47 | UpdateRenderTexture(); 48 | UpdateShadowCameraPos(); 49 | 50 | _shadowCam.targetTexture = _target; 51 | _shadowCam.RenderWithShader(_depthShader, ""); 52 | 53 | if (_shadowType == Shadows.VARIANCE) 54 | { 55 | for (int i = 0; i < blurIterations; i++) 56 | { 57 | _blur.SetTexture(0, "Read", _target); 58 | _blur.SetTexture(0, "Result", _backTarget); 59 | _blur.Dispatch(0, _target.width / 8, _target.height / 8, 1); 60 | 61 | Swap(ref _backTarget, ref _target); 62 | } 63 | } 64 | 65 | UpdateShaderValues(); 66 | } 67 | 68 | // Disable the shadows 69 | void OnDisable() 70 | { 71 | if (_shadowCam) 72 | { 73 | DestroyImmediate(_shadowCam.gameObject); 74 | _shadowCam = null; 75 | } 76 | 77 | if (_target) 78 | { 79 | DestroyImmediate(_target); 80 | _target = null; 81 | } 82 | 83 | if (_backTarget) 84 | { 85 | DestroyImmediate(_backTarget); 86 | _backTarget = null; 87 | } 88 | 89 | ForAllKeywords(s => Shader.DisableKeyword(ToKeyword(s))); 90 | } 91 | 92 | private void OnDestroy() 93 | { 94 | OnDisable(); 95 | } 96 | #endregion 97 | 98 | #region Update Functions 99 | void SetUpShadowCam() 100 | { 101 | if (_shadowCam) return; 102 | 103 | // Create the shadow rendering camera 104 | GameObject go = new GameObject("shadow cam"); 105 | //go.hideFlags = HideFlags.HideAndDontSave; 106 | go.hideFlags = HideFlags.DontSave; 107 | 108 | _shadowCam = go.AddComponent(); 109 | _shadowCam.orthographic = true; 110 | _shadowCam.nearClipPlane = 0; 111 | _shadowCam.enabled = false; 112 | _shadowCam.backgroundColor = new Color(0, 0, 0, 0); 113 | _shadowCam.clearFlags = CameraClearFlags.SolidColor; 114 | } 115 | 116 | void UpdateShaderValues() 117 | { 118 | ForAllKeywords(s => Shader.DisableKeyword(ToKeyword(s))); 119 | Shader.EnableKeyword(ToKeyword(_shadowType)); 120 | 121 | // Set the qualities of the textures 122 | Shader.SetGlobalTexture("_ShadowTex", _target); 123 | Shader.SetGlobalMatrix("_LightMatrix", _shadowCam.transform.worldToLocalMatrix); 124 | Shader.SetGlobalFloat("_MaxShadowIntensity", maxShadowIntensity); 125 | Shader.SetGlobalFloat("_VarianceShadowExpansion", varianceShadowExpansion); 126 | 127 | if(drawTransparent) Shader.EnableKeyword("DRAW_TRANSPARENT_SHADOWS"); 128 | else Shader.DisableKeyword("DRAW_TRANSPARENT_SHADOWS"); 129 | 130 | // TODO: Generate a matrix that transforms between 0-1 instead 131 | // of doing the extra math on the GPU 132 | Vector4 size = Vector4.zero; 133 | size.y = _shadowCam.orthographicSize * 2; 134 | size.x = _shadowCam.aspect * size.y; 135 | size.z = _shadowCam.farClipPlane; 136 | size.w = 1.0f / _resolution; 137 | Shader.SetGlobalVector("_ShadowTexScale", size); 138 | } 139 | 140 | // Refresh the render target if the scale has changed 141 | void UpdateRenderTexture() 142 | { 143 | if (_target != null && (_target.width != _resolution || _target.filterMode!= _filterMode)) 144 | { 145 | DestroyImmediate(_target); 146 | _target = null; 147 | } 148 | 149 | if (_target == null) 150 | { 151 | _target = CreateTarget(); 152 | _backTarget = CreateTarget(); 153 | } 154 | } 155 | 156 | // Update the camera view to encompass the geometry it will draw 157 | void UpdateShadowCameraPos() 158 | { 159 | // Update the position 160 | Camera cam = _shadowCam; 161 | Light l = FindObjectOfType(); 162 | cam.transform.position = l.transform.position; 163 | cam.transform.rotation = l.transform.rotation; 164 | cam.transform.LookAt(cam.transform.position + cam.transform.forward, cam.transform.up); 165 | 166 | Vector3 center, extents; 167 | List renderers = new List(); 168 | renderers.AddRange(FindObjectsOfType()); 169 | 170 | GetRenderersExtents(renderers, cam.transform, out center, out extents); 171 | 172 | center.z -= extents.z / 2; 173 | cam.transform.position = cam.transform.TransformPoint(center); 174 | cam.nearClipPlane = 0; 175 | cam.farClipPlane = extents.z; 176 | 177 | cam.aspect = extents.x / extents.y; 178 | cam.orthographicSize = extents.y / 2; 179 | } 180 | #endregion 181 | 182 | #region Utilities 183 | // Creates a rendertarget 184 | RenderTexture CreateTarget() 185 | { 186 | RenderTexture tg = new RenderTexture(_resolution, _resolution, 24, RenderTextureFormat.RGFloat); 187 | tg.filterMode = _filterMode; 188 | tg.wrapMode = TextureWrapMode.Clamp; 189 | tg.enableRandomWrite = true; 190 | tg.Create(); 191 | 192 | return tg; 193 | } 194 | 195 | void ForAllKeywords(System.Action func) 196 | { 197 | func(Shadows.HARD); 198 | func(Shadows.VARIANCE); 199 | } 200 | 201 | string ToKeyword(Shadows en) 202 | { 203 | if (en == Shadows.HARD) return "HARD_SHADOWS"; 204 | if (en == Shadows.VARIANCE) return "VARIANCE_SHADOWS"; 205 | return ""; 206 | } 207 | 208 | // Returns the bounds extents in the provided frame 209 | void GetRenderersExtents(List renderers, Transform frame, out Vector3 center, out Vector3 extents) 210 | { 211 | Vector3[] arr = new Vector3[8]; 212 | 213 | Vector3 min = Vector3.one * Mathf.Infinity; 214 | Vector3 max = Vector3.one * Mathf.NegativeInfinity; 215 | foreach (var r in renderers) 216 | { 217 | GetBoundsPoints(r.bounds, arr, frame.worldToLocalMatrix); 218 | 219 | foreach(var p in arr) 220 | { 221 | for(int i = 0; i < 3; i ++) 222 | { 223 | min[i] = Mathf.Min(p[i], min[i]); 224 | max[i] = Mathf.Max(p[i], max[i]); 225 | } 226 | } 227 | } 228 | 229 | extents = max - min; 230 | center = (max + min) / 2; 231 | } 232 | 233 | // Returns the 8 points for the given bounds multiplied by 234 | // the given matrix 235 | void GetBoundsPoints(Bounds b, Vector3[] points, Matrix4x4? mat = null) 236 | { 237 | Matrix4x4 trans = mat ?? Matrix4x4.identity; 238 | 239 | int count = 0; 240 | for (int x = -1; x <= 1; x += 2) 241 | for (int y = -1; y <= 1; y += 2) 242 | for (int z = -1; z <= 1; z += 2) 243 | { 244 | Vector3 v = b.extents; 245 | v.x *= x; 246 | v.y *= y; 247 | v.z *= z; 248 | v += b.center; 249 | v = trans.MultiplyPoint(v); 250 | 251 | points[count++] = v; 252 | } 253 | } 254 | 255 | // Swap Elements A and B 256 | void Swap(ref T a, ref T b) 257 | { 258 | T temp = a; 259 | a = b; 260 | b = temp; 261 | } 262 | #endregion 263 | } 264 | -------------------------------------------------------------------------------- /Assets/Scripts/CustomShadows.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c67473dc06bd38a4cb59d6e55f91adf2 3 | timeCreated: 1453346996 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7af35c98c9539ee409477d3e9ced0c1a 3 | folderAsset: yes 4 | timeCreated: 1452997336 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/DepthShader.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/CustomShadows/Depth" { 2 | Properties 3 | { 4 | _Color("Main Color", Color) = (1,1,1,1) 5 | _MainTex("Texture", 2D) = "white" {} 6 | } 7 | 8 | SubShader { 9 | Tags { "RenderType"="Opaque" } 10 | 11 | Pass 12 | { 13 | CGPROGRAM 14 | #include "UnityCG.cginc" 15 | #include "../Addons/Dither Functions.cginc" 16 | #pragma vertex vert 17 | #pragma fragment frag 18 | #pragma multi_compile _ DRAW_TRANSPARENT_SHADOWS 19 | 20 | sampler2D _MainTex; 21 | float4 _Color; 22 | 23 | struct appdata 24 | { 25 | float4 vertex : POSITION; 26 | float2 uv : TEXCOORD0; 27 | }; 28 | 29 | struct v2f 30 | { 31 | float4 vertex : SV_POSITION; 32 | float2 uv : TEXCOORD0; 33 | }; 34 | 35 | v2f vert(appdata v) 36 | { 37 | v2f o; 38 | o.vertex = UnityObjectToClipPos(v.vertex); 39 | o.uv = v.uv; 40 | return o; 41 | } 42 | 43 | fixed4 frag(v2f i) : SV_Target 44 | { 45 | float4 col = _Color; 46 | #if defined(DRAW_TRANSPARENT_SHADOWS) 47 | ditherClip(i.vertex, col.a); 48 | #else 49 | if (col.a < 0.5) discard; 50 | #endif 51 | 52 | // TODO: Understand why depth is reversed 53 | float depth = 1 - i.vertex.z; 54 | return float4(depth, pow(depth, 2), 0, 0); 55 | } 56 | ENDCG 57 | } 58 | } 59 | 60 | Fallback "VertexLit" 61 | } -------------------------------------------------------------------------------- /Assets/Shaders/DepthShader.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f94df5574a36a6149b9835728f4ecb5d 3 | timeCreated: 1453343991 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/LitShader.shader: -------------------------------------------------------------------------------- 1 | Shader "CustomShadows/Shadowed" { 2 | Properties 3 | { 4 | _Color ("Main Color", Color) = (1,1,1,1) 5 | _ZWrite ("ZWrite", Float) = 1 6 | 7 | } 8 | SubShader { 9 | Tags { "RenderType" = "Opaque" } 10 | 11 | Pass { 12 | Lighting On 13 | Blend SrcAlpha OneMinusSrcAlpha 14 | ZWrite[_ZWrite] 15 | 16 | CGPROGRAM 17 | #include "UnityCG.cginc" 18 | #pragma vertex vert 19 | #pragma fragment frag 20 | #pragma multi_compile _ HARD_SHADOWS VARIANCE_SHADOWS MOMENT_SHADOWS 21 | 22 | float4 _Color; 23 | 24 | // Shadow Map info 25 | sampler2D _ShadowTex; 26 | float4x4 _LightMatrix; 27 | float4 _ShadowTexScale; 28 | 29 | // Shadow Variables 30 | float _MaxShadowIntensity; 31 | int _DrawTransparentGeometry; 32 | float _VarianceShadowExpansion; 33 | 34 | float3 CTIllum(float4 wVertex, float3 normal) 35 | { 36 | // Reference 37 | // http://ruh.li/GraphicsCookTorrance.html 38 | 39 | float fresnel_val = 0.2; 40 | float roughness_val = .06; 41 | float k = 0.01; 42 | 43 | wVertex = mul(unity_WorldToObject, wVertex); 44 | float3 viewpos = -mul(UNITY_MATRIX_MV, wVertex).xyz; 45 | 46 | float3 col = float3(0, 0, 0); 47 | for (int i = 0; i < 2; i++) 48 | { 49 | // View vector, light direction, and Normal in model-view space 50 | float3 toLight = unity_LightPosition[i].xyz; 51 | float3 L = normalize(toLight); 52 | float3 V = normalize(viewpos);//float3(0, 0, 1); 53 | float3 N = mul(UNITY_MATRIX_MV, float4(normal,0)); 54 | N = normalize(N); 55 | 56 | // Half vector from view to light vector 57 | float3 H = normalize(V + L); 58 | 59 | // Dot products 60 | float NdotL = max(dot(N, L), 0); 61 | float NdotV = max(dot(N, V), 0); 62 | float NdotH = max(dot(N, H), 1.0e-7); 63 | float VdotH = max(dot(V, H), 0); 64 | 65 | // model the geometric attenuation of the surface 66 | float geo_numerator = 2 * NdotH; 67 | float geo_b = (geo_numerator * NdotV) / VdotH; 68 | float geo_c = (geo_numerator * NdotL) / VdotH; 69 | float geometric = 2 * NdotH / VdotH; 70 | geometric = min(1, max(0,min(geo_b, geo_c))); 71 | 72 | // calculate the roughness of the model 73 | float r2 = roughness_val * roughness_val; 74 | float NdotH2 = NdotH * NdotH; 75 | float NdotH2_r = 1 / (NdotH2 * r2); 76 | float roughness_exp = (NdotH2 - 1) * NdotH2_r; 77 | float roughness = exp(roughness_exp) * NdotH2_r / (4 * NdotH2); 78 | 79 | // Calculate the fresnel value 80 | float fresnel = pow(1.0 - VdotH, 5.0); 81 | fresnel *= 1 - fresnel_val; 82 | fresnel += fresnel_val; 83 | 84 | // Calculate the final specular value 85 | float s = (1-k)*(fresnel * geometric * roughness) / (NdotV * NdotL * 3.14 + 1.0e-7) + k; 86 | float3 spec = float3(1,1,1)*s; 87 | 88 | // apply to the model 89 | float lengthSq = dot(toLight, toLight); 90 | float atten = 1.0 / (1.0 + lengthSq * unity_LightAtten[i].z); 91 | col += NdotL * (unity_LightColor[i].xyz * spec + unity_LightColor[i].xyz *_Color) * atten; 92 | } 93 | return col; 94 | } 95 | 96 | // Code from 97 | // https://www.gdcvault.com/play/1023808/Rendering-Antialiased-Shadows-with-Moment 98 | float ComputeMSMShadowIntensity(float4 b, float FragmentDepth) { 99 | float L32D22 = mad(-b[0], b[1], b[2]); 100 | float D22 = mad(-b[0], b[0], b[1]); 101 | float SquaredDepthVariance = mad(-b[1], b[1], b[3]); 102 | float D33D22 = dot(float2(SquaredDepthVariance, -L32D22), 103 | float2(D22, L32D22)); 104 | float InvD22 = 1.0f / D22; 105 | float L32 = L32D22*InvD22; 106 | float3 z; 107 | z[0] = FragmentDepth; 108 | float3 c = float3(1.0f, z[0], z[0] * z[0]); 109 | c[1] -= b.x; 110 | c[2] -= b.y + L32*c[1]; 111 | c[1] *= InvD22; 112 | c[2] *= D22 / D33D22; 113 | c[1] -= L32*c[2]; 114 | c[0] -= dot(c.yz, b.xy); 115 | float InvC2 = 1.0f / c[2]; 116 | float p = c[1] * InvC2; 117 | float q = c[0] * InvC2; 118 | float r = sqrt((p*p*0.25f) - q); 119 | z[1] = -p*0.5f - r; 120 | z[2] = -p*0.5f + r; 121 | float4 Switch = 122 | (z[2] Read; 6 | RWTexture2D Result; 7 | 8 | [numthreads(8,8,1)] 9 | void Blur (uint3 id : SV_DispatchThreadID) 10 | { 11 | float4 col = float4(0,0,0,0); 12 | for(int x = -1 ; x <= 1; x ++) 13 | for( int y = -1 ; y <= 1 ; y ++) 14 | { 15 | uint2 index = id.xy; 16 | index.x += x; 17 | index.y += y; 18 | 19 | col += Read[index.xy]/9; 20 | } 21 | 22 | col.a = 1; 23 | Result[id.xy] = col; 24 | } 25 | -------------------------------------------------------------------------------- /Assets/Shaders/compute/blur-compute.compute.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b7bca1f2a14d73145ac985db88be341a 3 | timeCreated: 1454298772 4 | licenseType: Free 5 | ComputeShaderImporter: 6 | currentBuildTarget: 5 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2017.1.1f1 2 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityAdsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/UnityAdsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gkjohnson/unity-custom-shadow-experiments/30947d05326289fc91ac6e22557db2e42de35068/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # unity-custom-shadow-experiments 2 | A few custom shadow implementation experiments within Unity and repo for experimenting with shadowing techniques. 3 | 4 | ## Shadow Types 5 | ### Hard 6 | Basic binary hard shadow implementation. 7 | 8 | #### TODO 9 | - [ ] Provide sample count option for PCF 10 | - [ ] Provide option for using a a ShadowMap type for smoother sampling 11 | 12 | ### Variance 13 | Implements variance shadow mapping from [this paper](http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/VarianceShadowMapping/Doc/VarianceShadowMapping.pdf). 14 | --------------------------------------------------------------------------------