반응형

원문 링크 : https://github.com/TheMasonX/UnityPCSS
https://github.com/h33p/Unity-Graphics-Demo/tree/master?tab=readme-ov-file
https://github.com/h33p/Unity-Graphics-Demo/tree/master?tab=readme-ov-file
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; [ExecuteInEditMode] public class PCSSLight : MonoBehaviour { public int resolution = 4096; public bool customShadowResolution = false; [Space(20f)] [Range(1, 64)] public int Blocker_SampleCount = 16; [Range(1, 64)] public int PCF_SampleCount = 16; [Space(20f)] public bool RotateSamples = true; public bool UseNoiseTexture = true; public Texture2D noiseTexture; [Space(20f)] [Range(0f, 7.5f)] public float Softness = 1f; [Range(0f, 5f)] public float SoftnessFalloff = 4f; //[Range(0f, 1f)] //public float NearPlane = .1f; [Space(20f)] [Range(0f, 0.15f)] public float MaxStaticGradientBias = .05f; [Range(0f, 1f)] public float Blocker_GradientBias = 0f; [Range(0f, 1f)] public float PCF_GradientBias = 1f; /* Unity's Cascade Blending doesn't work quite right - Might be able to do something about it when I have time to research it more */ [Space(20f)] [Range(0f, 1f)] public float CascadeBlendDistance = .5f; [Space(20f)] public bool supportOrthographicProjection; [Space(20f)] public RenderTexture shadowRenderTexture; public RenderTextureFormat format = RenderTextureFormat.RFloat; public FilterMode filterMode = FilterMode.Bilinear; private LightEvent lightEvent = LightEvent.AfterShadowMap; public string shaderName = "Hidden/PCSS"; private Shader shader; private int shadowmapPropID; private CommandBuffer copyShadowBuffer; private Light _light; #region Initialization public void OnEnable () { Setup(); } public void OnDisable () { ResetShadowMode(); } [ContextMenu("Reinitialize")] public void Setup () { _light = GetComponent<Light>(); if (!_light) return; resolution = Mathf.ClosestPowerOfTwo(resolution); if (customShadowResolution) _light.shadowCustomResolution = resolution; else _light.shadowCustomResolution = 0; shader = Shader.Find(shaderName); shadowmapPropID = Shader.PropertyToID("_ShadowMap"); copyShadowBuffer = new CommandBuffer(); copyShadowBuffer.name = "PCSS Shadows"; var buffers = _light.GetCommandBuffers(lightEvent); for (int i = 0; i < buffers.Length; i++) { if(buffers[i].name == "PCSS Shadows") { _light.RemoveCommandBuffer(lightEvent, buffers[i]); } } _light.AddCommandBuffer(lightEvent, copyShadowBuffer); GraphicsSettings.SetCustomShader(BuiltinShaderType.ScreenSpaceShadows, shader); GraphicsSettings.SetShaderMode(BuiltinShaderType.ScreenSpaceShadows, BuiltinShaderMode.UseCustom); CreateShadowRenderTexture(); UpdateShaderValues(); UpdateCommandBuffer(); } public void CreateShadowRenderTexture () { shadowRenderTexture = new RenderTexture(resolution, resolution, 0, format); shadowRenderTexture.filterMode = filterMode; shadowRenderTexture.useMipMap = false; } [ContextMenu("Reset Shadows To Default")] public void ResetShadowMode () { GraphicsSettings.SetCustomShader(BuiltinShaderType.ScreenSpaceShadows, Shader.Find("Hidden/Internal-ScreenSpaceShadows")); GraphicsSettings.SetShaderMode(BuiltinShaderType.ScreenSpaceShadows, BuiltinShaderMode.Disabled); _light.shadowCustomResolution = 0; DestroyImmediate(shadowRenderTexture); GraphicsSettings.SetShaderMode(BuiltinShaderType.ScreenSpaceShadows, BuiltinShaderMode.UseBuiltin); if (!_light) return; _light.RemoveCommandBuffer(LightEvent.AfterShadowMap, copyShadowBuffer); } #endregion #region UpdateSettings public void UpdateShaderValues () { Shader.SetGlobalInt("Blocker_Samples", Blocker_SampleCount); Shader.SetGlobalInt("PCF_Samples", PCF_SampleCount); if (shadowRenderTexture) { if (shadowRenderTexture.format != format) CreateShadowRenderTexture(); else shadowRenderTexture.filterMode = filterMode; } Shader.SetGlobalFloat("Softness", Softness / 64f / Mathf.Sqrt(QualitySettings.shadowDistance)); Shader.SetGlobalFloat("SoftnessFalloff", Mathf.Exp(SoftnessFalloff)); SetFlag("USE_FALLOFF", SoftnessFalloff > Mathf.Epsilon); //Shader.SetGlobalFloat("NearPlane", NearPlane); Shader.SetGlobalFloat("RECEIVER_PLANE_MIN_FRACTIONAL_ERROR", MaxStaticGradientBias); Shader.SetGlobalFloat("Blocker_GradientBias", Blocker_GradientBias); Shader.SetGlobalFloat("PCF_GradientBias", PCF_GradientBias); SetFlag("USE_CASCADE_BLENDING", CascadeBlendDistance > 0); Shader.SetGlobalFloat("CascadeBlendDistance", CascadeBlendDistance); SetFlag("USE_STATIC_BIAS", MaxStaticGradientBias > 0); SetFlag("USE_BLOCKER_BIAS", Blocker_GradientBias > 0); SetFlag("USE_PCF_BIAS", PCF_GradientBias > 0); SetFlag("ROTATE_SAMPLES", RotateSamples); SetFlag("USE_NOISE_TEX", UseNoiseTexture); if (noiseTexture) { Shader.SetGlobalVector("NoiseCoords", new Vector4(1f / noiseTexture.width, 1f / noiseTexture.height, 0f, 0f)); Shader.SetGlobalTexture("_NoiseTexture", noiseTexture); } SetFlag("ORTHOGRAPHIC_SUPPORTED", supportOrthographicProjection); int maxSamples = Mathf.Max(Blocker_SampleCount, PCF_SampleCount); SetFlag("POISSON_32", maxSamples < 33); SetFlag("POISSON_64", maxSamples > 33); } public void UpdateCommandBuffer () { if (!_light) return; copyShadowBuffer.Clear(); copyShadowBuffer.SetShadowSamplingMode(BuiltinRenderTextureType.CurrentActive, ShadowSamplingMode.RawDepth); copyShadowBuffer.Blit(BuiltinRenderTextureType.CurrentActive, shadowRenderTexture); copyShadowBuffer.SetGlobalTexture(shadowmapPropID, shadowRenderTexture); } #endregion public void SetFlag (string shaderKeyword, bool value) { if (value) Shader.EnableKeyword(shaderKeyword); else Shader.DisableKeyword(shaderKeyword); } } |
반응형
'Technical Report > Unity' 카테고리의 다른 글
| Shader에서 Linear <-> sRGB 변환 함수 (0) | 2020.02.14 |
|---|---|
| URP Default Unlit Based to Custom Lighting (0) | 2020.01.31 |
| LWRP Basic shader code (0) | 2019.09.08 |
| Custom Material GUI (0) | 2019.08.14 |
| Unity PBR Default (0) | 2019.07.10 |