2026-04-16 오브젝트 그림자

This commit is contained in:
skrwns304@gmail.com
2026-04-16 04:58:10 +09:00
parent 0fe8b18872
commit 42646a636f
303 changed files with 54374 additions and 20 deletions

6
.vsconfig Normal file
View File

@@ -0,0 +1,6 @@
{
"version": "1.0",
"components": [
"Microsoft.VisualStudio.Workload.ManagedGame"
]
}

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: dd261a1eba77eca468c517f3ba3e97ef
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e1889fe709cead44891090d2a27058ac
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -21,16 +21,12 @@ Material:
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_Name: Grocery Store Racks_BaseMap m_Name: Grocery Store Racks_BaseMap
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} m_Shader: {fileID: 4800000, guid: deab2e321dbdc8a469635b200f36c496, type: 3}
m_Parent: {fileID: 0} m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0 m_ModifiedSerializedProperties: 0
m_ValidKeywords: m_ValidKeywords:
- _METALLICSPECGLOSSMAP - _METALLICSPECGLOSSMAP
m_InvalidKeywords: m_InvalidKeywords: []
- _DISABLE_SSR_TRANSPARENT
- _MASKMAP
- _METALLICGLOSSMAP
- _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 4 m_LightmapFlags: 4
m_EnableInstancingVariants: 0 m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0 m_DoubleSidedGI: 0
@@ -42,7 +38,6 @@ Material:
- TransparentDepthPostpass - TransparentDepthPostpass
- TransparentBackface - TransparentBackface
- RayTracingPrepass - RayTracingPrepass
- MOTIONVECTORS
m_LockedProperties: m_LockedProperties:
m_SavedProperties: m_SavedProperties:
serializedVersion: 3 serializedVersion: 3

View File

@@ -41,9 +41,7 @@ Material:
m_Parent: {fileID: 0} m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0 m_ModifiedSerializedProperties: 0
m_ValidKeywords: [] m_ValidKeywords: []
m_InvalidKeywords: m_InvalidKeywords: []
- _DISABLE_SSR_TRANSPARENT
- _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 4 m_LightmapFlags: 4
m_EnableInstancingVariants: 0 m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0 m_DoubleSidedGI: 0

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 502dc5fe84c33494ab0a60f2b172a97b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1315e8563efe14f819495166c8627adf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: a50c95cfd73b44394a1769a630485130
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Demo Transparent Receiver.unity
uploadId: 868458

Binary file not shown.

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 5da633c0cce214fe0a39af798dec1a2c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Demo.unity
uploadId: 868458

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fe04e7c6c17d8414f858b14aa98114bd
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4177e5add8dfba840a0a7ef242f3d85c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0fc43b0d4446343258ea2a7167aad98e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!850595691 &4890085278179872738
LightingSettings:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: DemoSettings
serializedVersion: 3
m_GIWorkflowMode: 1
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_RealtimeEnvironmentLighting: 1
m_BounceScale: 1
m_AlbedoBoost: 1
m_IndirectOutputScale: 1
m_UsingShadowmask: 0
m_BakeBackend: 0
m_LightmapMaxSize: 1024
m_BakeResolution: 40
m_Padding: 2
m_TextureCompression: 1
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAO: 0
m_MixedBakeMode: 0
m_LightmapsBakeMode: 1
m_FilterMode: 1
m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0}
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_RealtimeResolution: 2
m_ForceWhiteAlbedo: 0
m_ForceUpdates: 0
m_FinalGather: 0
m_FinalGatherRayCount: 256
m_FinalGatherFiltering: 1
m_PVRCulling: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_LightProbeSampleCountMultiplier: 4
m_PVRBounces: 2
m_PVRMinBounces: 2
m_PVREnvironmentMIS: 1
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1

View File

@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 64f0d92f8042f4e1eb4acf9092024365
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4890085278179872738
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/DemoSettings.lighting
uploadId: 868458

View File

@@ -0,0 +1,131 @@
Shader "Kronnect/UmbraScreenSpaceShadows/SimpleShader"
{
Properties
{
[MainTexture] _BaseMap ("Base Map", 2D) = "white" {}
[MainColor] _BaseColor ("Color", Color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderPipeline"="UniversalPipeline" "RenderType"="Opaque" "Queue"="Geometry" }
LOD 100
Pass
{
Name "UniversalForward"
Tags { "LightMode"="UniversalForward" }
Cull Back
ZWrite On
ZTest LEqual
Blend One Zero
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
#pragma target 2.0
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
#pragma multi_compile_fragment _ _SHADOWS_SOFT
#pragma multi_compile_fragment _ _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
float4 _BaseColor;
CBUFFER_END
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float4 shadowCoord : TEXCOORD0;
float2 uv : TEXCOORD1;
};
Varyings Vertex(Attributes input)
{
Varyings output;
VertexPositionInputs posInputs = GetVertexPositionInputs(input.positionOS.xyz);
output.positionHCS = posInputs.positionCS;
output.shadowCoord = GetShadowCoord(posInputs);
output.uv = input.uv * _BaseMap_ST.xy + _BaseMap_ST.zw;
return output;
}
half4 Fragment(Varyings input) : SV_Target
{
half shadowAtten = MainLightRealtimeShadow(input.shadowCoord);
half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
return _BaseColor * baseMap * shadowAtten;
}
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags { "LightMode"="DepthOnly" }
Cull Back
ZWrite On
ZTest LEqual
HLSLPROGRAM
#pragma vertex DepthOnlyVertex
#pragma fragment DepthOnlyFragment
#pragma target 2.0
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/DepthOnlyPass.hlsl"
ENDHLSL
}
Pass
{
Name "DepthNormals"
Tags { "LightMode"="DepthNormals" }
Cull Back
ZWrite On
HLSLPROGRAM
#pragma target 2.0
#pragma vertex DepthNormalsVertex
#pragma fragment DepthNormalsFragment
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitDepthNormalsPass.hlsl"
ENDHLSL
}
Pass
{
Name "ShadowCaster"
Tags { "LightMode"="ShadowCaster" }
Cull Back
ZWrite On
HLSLPROGRAM
#pragma vertex ShadowPassVertex
#pragma fragment ShadowPassFragment
#pragma target 2.0
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
ENDHLSL
}
}
Fallback "Hidden/Universal Render Pipeline/FallbackError"
}

View File

@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 654a3befbf7254f0084192d9acb9d73a
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/SimpleShader.shader
uploadId: 868458

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9997d11ed9828479194425d3923a2cc8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 6c1ac87607ed940e7ac3fbd7abe0db6b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/URP Settings/URP-HighFidelity-Renderer.asset
uploadId: 868458

View File

@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 4fb072dbb668147069c21f7dc52a6d36
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/URP Settings/URP-HighFidelity.asset
uploadId: 868458

View File

@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 1a990a7ceed7343abbec3af44353f819
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/UniversalRenderPipelineGlobalSettings.asset
uploadId: 868458

Binary file not shown.

View File

@@ -0,0 +1,116 @@
fileFormatVersion: 2
guid: 004577dce373a4b8b9c0f00570675e2e
ModelImporter:
serializedVersion: 22200
internalIDToNameTable: []
externalObjects: {}
materials:
materialImportMode: 0
materialName: 0
materialSearch: 1
materialLocation: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
removeConstantScaleCurves: 1
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
importAnimatedCustomProperties: 0
importConstraints: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
extraUserProperties: []
clipAnimations: []
isReadable: 1
meshes:
lODScreenPercentages: []
globalScale: 0.1
meshCompression: 0
addColliders: 0
useSRGBMaterialColor: 1
sortHierarchyByName: 1
importPhysicalCameras: 1
importVisibility: 1
importBlendShapes: 1
importCameras: 1
importLights: 1
nodeNameCollisionStrategy: 1
fileIdsGeneration: 2
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
keepQuads: 0
weldVertices: 1
bakeAxisConversion: 0
preserveHierarchy: 0
skinWeightsMode: 0
maxBonesPerVertex: 4
minBoneWeight: 0.001
optimizeBones: 1
meshOptimizationFlags: -1
indexFormat: 0
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVMarginMethod: 1
secondaryUVMinLightmapResolution: 40
secondaryUVMinObjectScale: 1
secondaryUVPackMargin: 4
useFileScale: 1
strictVertexDataChecks: 0
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0
blendShapeNormalImportMode: 1
normalSmoothingSource: 0
referencedClips: []
importAnimation: 1
humanDescription:
serializedVersion: 3
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
globalScale: 0.1
rootMotionBoneName:
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
autoGenerateAvatarMappingIfUnspecified: 1
animationType: 2
humanoidOversampling: 1
avatarSetup: 0
addHumanoidExtraRootOnlyWhenUsingAvatar: 1
importBlendShapeDeformPercent: 0
remapMaterialsIfMaterialImportModeIsNone: 0
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/Venus.fbx
uploadId: 868458

View File

@@ -0,0 +1,139 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-2054341761090198542
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Venus
m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: 2000
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossinessSource: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Shininess: 0
- _Smoothness: 0.5
- _SmoothnessSource: 0
- _SmoothnessTextureChannel: 0
- _SpecSource: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 54aca384ab99641c996e59fc0e3abd6c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/Venus.mat
uploadId: 868458

Binary file not shown.

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 9078fc8703eb440dbaeedb8051e96a6a
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/Venus.prefab
uploadId: 868458

View File

@@ -0,0 +1,139 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-5578493846381785671
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: occluderMat
m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords:
- _ENVIRONMENTREFLECTIONS_OFF
- _SPECULARHIGHLIGHTS_OFF
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: 2000
stringTagMap:
RenderType: Opaque
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 2800000, guid: 74975d324705846da90cd745e830c6e3, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 2800000, guid: dd70140ee26c54c978eca5e7315847e8, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EnvironmentReflections: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _QueueOffset: 0
- _ReceiveShadows: 1
- _Smoothness: 0
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 0
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 0
- _UVSec: 0
- _WorkflowMode: 1
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 0.9716981, g: 0.9716981, b: 0.9716981, a: 1}
- _Color: {r: 0.9716981, g: 0.9716981, b: 0.9716981, a: 1}
- _EmissionColor: {r: 0.21586053, g: 0.21586053, b: 0.21586053, a: 1}
- _SpecColor: {r: 0.2, g: 0.2, b: 0.2, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 822f1759e1ad642138396daa25d45d49
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/occluderMat.mat
uploadId: 868458

Binary file not shown.

View File

@@ -0,0 +1,134 @@
fileFormatVersion: 2
guid: c4ffcd5fed0aa4c139ff5c1edc969390
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 1
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 2
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 0
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 10
textureShape: 1
singleChannelComponent: 1
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Demo/Scene/stylizedMask.png
uploadId: 868458

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 07db272b096d6494683a775c205b870b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://kronnect.com/docs/umbra/

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 33e7bf8fb943e4f09bf35f62155e9490
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Documentation/Documentation Online.url
uploadId: 868458

View File

@@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://www.dropbox.com/scl/fo/6wh4i77k9617dqycdr5r3/AP84Vyn8qerkagGHIXgb0E0?rlkey=lvmgabqvcblo3rkl6v3t9305o&dl=0

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 01244bfa5c42b48c5b1e09d00ab5020b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Documentation/Documentation PDF.url
uploadId: 868458

View File

@@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://kronnect.com

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 28c4950a1656140338b5c2d42496d7c7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Documentation/Kronnect Assets.url
uploadId: 868458

View File

@@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://kronnect.com/docs/umbra/

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 4112410640b8942c9b62813e431f025d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Documentation/Support.url
uploadId: 868458

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1063b516634d54e4fb020287047514c3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
{
"name": "UmbraEditor",
"rootNamespace": "",
"references": [
"GUID:15fc0a57446b3144c949da3e2b9737a9"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 2b22e76c0de5e464e8e6540a80bd2b31
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Editor/UmbraEditor.asmdef
uploadId: 868458

View File

@@ -0,0 +1,317 @@
using UnityEditor;
using UnityEngine;
namespace Umbra {
[CustomEditor(typeof(UmbraProfile))]
public class UmbraProfileEditor : Editor {
SerializedProperty shadowSource;
SerializedProperty enableContactHardening, contactStrength, contactStrengthKnee, normalsSource;
SerializedProperty occludersCount, occludersSearchRadius, sampleCount, lightSize, distantSpread;
SerializedProperty blurIterations, blurType, blurSpread, blurEdgeSharpness, posterization;
SerializedProperty overlayShadows, overlayShadowsIntensity, overlayShadowsColor;
SerializedProperty preserveEdges, blurEdgeTolerance;
SerializedProperty blurDepthAttenStart, blurDepthAttenLength, blurGrazingAttenuation;
SerializedProperty blendCascades, cascade1BlendingStrength, cascade2BlendingStrength, cascade3BlendingStrength;
SerializedProperty cascade1Scale, cascade2Scale, cascade3Scale, cascade4Scale;
SerializedProperty loopStepOptimization, frameSkipOptimization, skipFrameMaxCameraDisplacement, skipFrameMaxCameraRotation, downsample, forceDepthPrepass;
SerializedProperty style, maskTexture, maskScale;
SerializedProperty contactShadows, contactShadowsInjectionPoint, contactShadowsSampleCount, contactShadowsStepping;
SerializedProperty contactShadowsThicknessNear, contactShadowsThicknessDistanceMultiplier, contactShadowsJitter, contactShadowsBias, contactShadowsBiasFar;
SerializedProperty contactShadowsIntensityMultiplier, contactShadowsDistanceFade, contactShadowsStartDistance, contactShadowsStartDistanceFade, contactShadowsNormalBias, contactShadowsVignetteSize;
SerializedProperty contactShadowsEdgeSoftness, contactShadowsSoftEdges, contactShadowsPlanarShadows;
SerializedProperty transparentReceiverPlane, receiverPlaneAltitude;
SerializedProperty earlyOutSamples;
static GUIStyle titleLabelStyle;
static Color titleColor;
Light thisLight;
private void OnEnable () {
if (target == null) return;
titleColor = EditorGUIUtility.isProSkin ? new Color(0.52f, 0.66f, 0.9f) : new Color(0.12f, 0.16f, 0.4f);
shadowSource = serializedObject.FindProperty("shadowSource");
sampleCount = serializedObject.FindProperty("sampleCount");
enableContactHardening = serializedObject.FindProperty("enableContactHardening");
contactStrength = serializedObject.FindProperty("contactStrength");
contactStrengthKnee = serializedObject.FindProperty("contactStrengthKnee");
distantSpread = serializedObject.FindProperty("distantSpread");
occludersCount = serializedObject.FindProperty("occludersCount");
occludersSearchRadius = serializedObject.FindProperty("occludersSearchRadius");
lightSize = serializedObject.FindProperty("lightSize");
blurIterations = serializedObject.FindProperty("blurIterations");
blurType = serializedObject.FindProperty("blurType");
blurSpread = serializedObject.FindProperty("blurSpread");
blurEdgeSharpness = serializedObject.FindProperty("blurEdgeSharpness");
posterization = serializedObject.FindProperty("posterization");
preserveEdges = serializedObject.FindProperty("preserveEdges");
blurEdgeTolerance = serializedObject.FindProperty("blurEdgeTolerance");
blurDepthAttenStart = serializedObject.FindProperty("blurDepthAttenStart");
blurDepthAttenLength = serializedObject.FindProperty("blurDepthAttenLength");
blurGrazingAttenuation = serializedObject.FindProperty("blurGrazingAttenuation");
overlayShadows = serializedObject.FindProperty("overlayShadows");
overlayShadowsIntensity = serializedObject.FindProperty("overlayShadowsIntensity");
overlayShadowsColor = serializedObject.FindProperty("overlayShadowsColor");
normalsSource = serializedObject.FindProperty("normalsSource");
blendCascades = serializedObject.FindProperty("blendCascades");
cascade1BlendingStrength = serializedObject.FindProperty("cascade1BlendingStrength");
cascade2BlendingStrength = serializedObject.FindProperty("cascade2BlendingStrength");
cascade3BlendingStrength = serializedObject.FindProperty("cascade3BlendingStrength");
cascade1Scale = serializedObject.FindProperty("cascade1Scale");
cascade2Scale = serializedObject.FindProperty("cascade2Scale");
cascade3Scale = serializedObject.FindProperty("cascade3Scale");
cascade4Scale = serializedObject.FindProperty("cascade4Scale");
loopStepOptimization = serializedObject.FindProperty("loopStepOptimization");
frameSkipOptimization = serializedObject.FindProperty("frameSkipOptimization");
skipFrameMaxCameraDisplacement = serializedObject.FindProperty("skipFrameMaxCameraDisplacement");
skipFrameMaxCameraRotation = serializedObject.FindProperty("skipFrameMaxCameraRotation");
downsample = serializedObject.FindProperty("downsample");
forceDepthPrepass = serializedObject.FindProperty("forceDepthPrepass");
style = serializedObject.FindProperty("style");
maskTexture = serializedObject.FindProperty("maskTexture");
maskScale = serializedObject.FindProperty("maskScale");
contactShadows = serializedObject.FindProperty("contactShadows");
contactShadowsInjectionPoint = serializedObject.FindProperty("contactShadowsInjectionPoint");
contactShadowsSampleCount = serializedObject.FindProperty("contactShadowsSampleCount");
contactShadowsStepping = serializedObject.FindProperty("contactShadowsStepping");
contactShadowsThicknessNear = serializedObject.FindProperty("contactShadowsThicknessNear");
contactShadowsThicknessDistanceMultiplier = serializedObject.FindProperty("contactShadowsThicknessDistanceMultiplier");
contactShadowsJitter = serializedObject.FindProperty("contactShadowsJitter");
contactShadowsBias = serializedObject.FindProperty("contactShadowsBias");
contactShadowsBiasFar = serializedObject.FindProperty("contactShadowsBiasFar");
contactShadowsDistanceFade = serializedObject.FindProperty("contactShadowsDistanceFade");
contactShadowsStartDistance = serializedObject.FindProperty("contactShadowsStartDistance");
contactShadowsStartDistanceFade = serializedObject.FindProperty("contactShadowsStartDistanceFade");
contactShadowsNormalBias = serializedObject.FindProperty("contactShadowsNormalBias");
contactShadowsVignetteSize = serializedObject.FindProperty("contactShadowsVignetteSize");
contactShadowsIntensityMultiplier = serializedObject.FindProperty("contactShadowsIntensityMultiplier");
contactShadowsEdgeSoftness = serializedObject.FindProperty("contactShadowsEdgeSoftness");
contactShadowsSoftEdges = serializedObject.FindProperty("contactShadowsSoftEdges");
contactShadowsPlanarShadows = serializedObject.FindProperty("contactShadowsPlanarShadows");
transparentReceiverPlane = serializedObject.FindProperty("transparentReceiverPlane");
receiverPlaneAltitude = serializedObject.FindProperty("receiverPlaneAltitude");
earlyOutSamples = serializedObject.FindProperty("earlyOutSamples");
#if UNITY_2023_1_OR_NEWER
UmbraSoftShadows umbraSoftShadows = FindAnyObjectByType<UmbraSoftShadows>(FindObjectsInactive.Include);
#else
UmbraSoftShadows umbraSoftShadows = FindObjectOfType<UmbraSoftShadows>(true);
#endif
if (umbraSoftShadows != null) {
thisLight = umbraSoftShadows.GetComponent<Light>();
}
}
public override void OnInspectorGUI () {
serializedObject.Update();
DrawSectionTitle("General Settings");
EditorGUILayout.PropertyField(shadowSource);
if (thisLight != null) {
if (shadowSource.intValue != (int)ShadowSource.OnlyContactShadows && thisLight.shadows == LightShadows.None) {
EditorGUILayout.HelpBox("Light has no shadows. Umbra Soft Shadows will not work.", MessageType.Warning);
}
else if (shadowSource.intValue == (int)ShadowSource.OnlyContactShadows && thisLight.shadows != LightShadows.None) {
EditorGUILayout.HelpBox("Disable light shadows to use just contact shadows.", MessageType.Info);
}
}
if (shadowSource.intValue == (int)ShadowSource.UmbraShadows) {
EditorGUILayout.PropertyField(sampleCount);
EditorGUILayout.PropertyField(lightSize);
EditorGUILayout.PropertyField(enableContactHardening, new GUIContent("Contact Hardening"));
if (enableContactHardening.boolValue) {
EditorGUI.indentLevel++;
#if UNITY_WEBGL
EditorGUILayout.HelpBox("Contact hardening not suppoted on WebGL.", MessageType.Warning);
GUI.enabled = false;
#endif
EditorGUILayout.PropertyField(contactStrength);
if (contactStrength.floatValue > 0) {
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(contactStrengthKnee, new GUIContent("Knee"));
EditorGUI.indentLevel--;
}
EditorGUILayout.PropertyField(distantSpread);
EditorGUILayout.PropertyField(occludersCount);
if (occludersCount.intValue > 0) {
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(occludersSearchRadius, new GUIContent("Search Radius"));
EditorGUI.indentLevel--;
}
GUI.enabled = true;
EditorGUI.indentLevel--;
}
if (UmbraSoftShadows.isDeferred) {
EditorGUILayout.PropertyField(normalsSource);
}
else {
// In forward mode, show normals source but handle GBufferNormals fallback
if (normalsSource.intValue == (int)NormalSource.GBufferNormals) {
EditorGUILayout.HelpBox("GBuffer Normals is only available in Deferred rendering. Falling back to Reconstruct From Depth.", MessageType.Info);
}
EditorGUILayout.PropertyField(normalsSource);
}
}
if (shadowSource.intValue != (int)ShadowSource.OnlyContactShadows) {
EditorGUILayout.PropertyField(contactShadows);
EditorGUI.indentLevel++;
}
else {
// In OnlyContactShadows mode, show normals source but handle GBufferNormals fallback
if (!UmbraSoftShadows.isDeferred && normalsSource.intValue == (int)NormalSource.GBufferNormals) {
EditorGUILayout.HelpBox("GBuffer Normals is only available in Deferred rendering. Falling back to Reconstruct From Depth.", MessageType.Info);
}
EditorGUILayout.PropertyField(normalsSource);
EditorGUILayout.Separator();
DrawSectionTitle("Contact Shadows Settings");
}
if (shadowSource.intValue == (int)ShadowSource.OnlyContactShadows || contactShadows.boolValue) {
EditorGUILayout.PropertyField(contactShadowsIntensityMultiplier, new GUIContent("Intensity"));
EditorGUILayout.PropertyField(contactShadowsDistanceFade, new GUIContent("Distance Fade"));
EditorGUILayout.PropertyField(contactShadowsSampleCount, new GUIContent("Sample Count"));
EditorGUILayout.PropertyField(contactShadowsStepping, new GUIContent("Stepping"));
EditorGUILayout.PropertyField(contactShadowsThicknessNear, new GUIContent("Thickness Near"));
EditorGUILayout.PropertyField(contactShadowsThicknessDistanceMultiplier, new GUIContent("Thickness Distance Multiplier"));
EditorGUILayout.PropertyField(contactShadowsPlanarShadows, new GUIContent("Planar Shadows"));
EditorGUILayout.PropertyField(contactShadowsJitter, new GUIContent("Jitter"));
EditorGUILayout.PropertyField(contactShadowsStartDistance, new GUIContent("Start Distance"));
EditorGUILayout.PropertyField(contactShadowsStartDistanceFade, new GUIContent("Start Distance Fade"));
EditorGUILayout.PropertyField(contactShadowsBias, new GUIContent("Depth Bias Near"));
EditorGUILayout.PropertyField(contactShadowsBiasFar, new GUIContent("Depth Bias Far"));
EditorGUILayout.PropertyField(contactShadowsNormalBias, new GUIContent("Normal Bias"));
EditorGUILayout.PropertyField(contactShadowsSoftEdges, new GUIContent("Soft Edges"));
if (contactShadowsSoftEdges.boolValue) {
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(contactShadowsEdgeSoftness, new GUIContent("Edge Softness"));
EditorGUI.indentLevel--;
}
EditorGUILayout.PropertyField(contactShadowsVignetteSize, new GUIContent("Vignette Size"));
if (shadowSource.intValue == (int)ShadowSource.UmbraShadows) {
EditorGUILayout.PropertyField(contactShadowsInjectionPoint, new GUIContent("Injection Point"));
if (contactShadowsInjectionPoint.intValue == (int)ContactShadowsInjectionPoint.AfterOpaque) {
EditorGUILayout.HelpBox("Computes contact shadows and blend result over the opaque texture. This option allows contact shadows over large distances (contact shadows integrated into shadow texture are limited by the shadow distance).", MessageType.Info);
}
}
else {
GUI.enabled = false;
EditorGUILayout.LabelField("Injection Point", "After Opaque");
GUI.enabled = true;
}
}
if (shadowSource.intValue != (int)ShadowSource.OnlyContactShadows) {
EditorGUI.indentLevel--;
}
if (shadowSource.intValue == (int)ShadowSource.UmbraShadows) {
DrawSectionTitle("Look");
EditorGUILayout.PropertyField(style);
switch (style.intValue) {
case (int)Style.Textured:
EditorGUILayout.PropertyField(maskTexture, new GUIContent("Mask Texture"));
EditorGUILayout.PropertyField(maskScale, new GUIContent("Scale"));
break;
case (int)Style.Default:
EditorGUILayout.PropertyField(blurIterations);
if (blurIterations.intValue > 0) {
EditorGUILayout.PropertyField(blurType);
EditorGUILayout.PropertyField(blurSpread, new GUIContent("Spread"));
EditorGUILayout.PropertyField(blurEdgeTolerance, new GUIContent("Edge Tolerance"));
EditorGUILayout.PropertyField(blurEdgeSharpness, new GUIContent("Edge Sharpness"));
EditorGUILayout.PropertyField(posterization);
if (!transparentReceiverPlane.boolValue) {
EditorGUILayout.PropertyField(blurDepthAttenStart, new GUIContent("Blur Distance Attenuation", "Distance where blur starts reducing"));
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(blurDepthAttenLength, new GUIContent("Attenuation Length", "Length of the blur attenuation"));
EditorGUI.indentLevel--;
EditorGUILayout.PropertyField(blurGrazingAttenuation, new GUIContent("Grazing Angle Attenuation"));
}
}
break;
}
EditorGUILayout.PropertyField(overlayShadows);
if (overlayShadows.boolValue) {
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(overlayShadowsIntensity, new GUIContent("Intensity"));
EditorGUILayout.PropertyField(overlayShadowsColor, new GUIContent("Color"));
EditorGUI.indentLevel--;
}
}
DrawSectionTitle("Advanced");
if (shadowSource.intValue != (int)ShadowSource.OnlyContactShadows) {
EditorGUILayout.PropertyField(downsample);
if (downsample.boolValue) {
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(preserveEdges, new GUIContent("Edge Preserve"));
EditorGUI.indentLevel--;
}
}
EditorGUILayout.PropertyField(forceDepthPrepass);
if (shadowSource.intValue != (int)ShadowSource.UnityShadows) {
EditorGUILayout.PropertyField(loopStepOptimization, new GUIContent("Loop Optimization"));
}
if (shadowSource.intValue != (int)ShadowSource.OnlyContactShadows) {
EditorGUILayout.PropertyField(frameSkipOptimization, new GUIContent("Frame Skip Optimization"));
if (frameSkipOptimization.boolValue) {
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(skipFrameMaxCameraDisplacement, new GUIContent("Max Camera Displacement"));
EditorGUILayout.PropertyField(skipFrameMaxCameraRotation, new GUIContent("Max Camera Rotation"));
EditorGUI.indentLevel--;
}
EditorGUILayout.PropertyField(earlyOutSamples);
if (shadowSource.intValue == (int)ShadowSource.UmbraShadows) {
EditorGUILayout.PropertyField(blendCascades);
if (blendCascades.boolValue) {
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(cascade1BlendingStrength, new GUIContent("Cascade 1 Blending"));
EditorGUILayout.PropertyField(cascade2BlendingStrength, new GUIContent("Cascade 2 Blending"));
EditorGUILayout.PropertyField(cascade3BlendingStrength, new GUIContent("Cascade 3 Blending"));
if (cascade1BlendingStrength.floatValue > 5f || cascade2BlendingStrength.floatValue > 5f || cascade3BlendingStrength.floatValue > 5f) {
EditorGUILayout.HelpBox("Setting a high value in blending can introduce artifacts between the cascades. Reduce this value if this happens.", MessageType.Info);
}
EditorGUI.indentLevel--;
}
EditorGUILayout.PropertyField(cascade1Scale);
EditorGUILayout.PropertyField(cascade2Scale);
EditorGUILayout.PropertyField(cascade3Scale);
EditorGUILayout.PropertyField(cascade4Scale);
}
}
EditorGUILayout.PropertyField(transparentReceiverPlane);
if (transparentReceiverPlane.boolValue) {
EditorGUI.indentLevel++;
if (contactShadows.boolValue) {
EditorGUILayout.HelpBox("Contact Shadows are not compatible with the transparent receiver plane option.", MessageType.Warning);
}
EditorGUILayout.PropertyField(receiverPlaneAltitude, new GUIContent("Altitude"));
EditorGUI.indentLevel--;
}
serializedObject.ApplyModifiedProperties();
}
void DrawSectionTitle (string s) {
if (titleLabelStyle == null) {
GUIStyle skurikenModuleTitleStyle = "ShurikenModuleTitle";
titleLabelStyle = new GUIStyle(skurikenModuleTitleStyle);
titleLabelStyle.contentOffset = new Vector2(5f, -2f);
titleLabelStyle.normal.textColor = titleColor;
titleLabelStyle.fixedHeight = 22;
titleLabelStyle.fontStyle = FontStyle.Bold;
}
EditorGUILayout.Separator();
GUILayout.Label(s, titleLabelStyle);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: f6f6dbb62acb7471d9f7543902c4799e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Editor/UmbraProfileEditor.cs
uploadId: 868458

View File

@@ -0,0 +1,152 @@
using System.IO;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace Umbra {
[CustomEditor(typeof(UmbraSoftShadows))]
public class UmbraSoftShadowsEditor : Editor {
SerializedProperty profile, debugShadows;
SerializedProperty contactShadowsSource;
SerializedProperty pointLightsTrigger;
static UmbraPreset preset = UmbraPreset.None;
static GUIStyle boxStyle;
UmbraProfile cachedProfile;
Editor cachedProfileEditor;
private void OnEnable() {
profile = serializedObject.FindProperty("profile");
debugShadows = serializedObject.FindProperty("debugShadows");
contactShadowsSource = serializedObject.FindProperty("contactShadowsSource");
pointLightsTrigger = serializedObject.FindProperty("pointLightsTrigger");
}
public override void OnInspectorGUI() {
if (boxStyle == null) {
boxStyle = new GUIStyle(GUI.skin.box);
boxStyle.padding = new RectOffset(15, 10, 5, 5);
}
UniversalRenderPipelineAsset pipe = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
if (pipe == null) {
EditorGUILayout.HelpBox("Universal Rendering Pipeline asset is not set in 'Project Settings / Graphics' !", MessageType.Error);
EditorGUILayout.Separator();
} else if (!UmbraSoftShadows.installed) {
EditorGUILayout.HelpBox("Umbra Render Feature must be added to the rendering pipeline renderer.", MessageType.Error);
if (GUILayout.Button("Go to Universal Rendering Pipeline Asset")) {
Selection.activeObject = pipe;
}
EditorGUILayout.Separator();
}
serializedObject.Update();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(profile);
if (profile.objectReferenceValue != null) {
if (GUILayout.Button("Save To Asset", GUILayout.Width(120))) {
ExportProfile();
}
} else {
if (GUILayout.Button("Create Profile", GUILayout.Width(120))) {
CreateProfile();
}
}
EditorGUILayout.EndHorizontal();
if (profile.objectReferenceValue == null) return;
EditorGUILayout.BeginHorizontal();
preset = (UmbraPreset)EditorGUILayout.EnumPopup(new GUIContent("Sample Preset"), preset);
if (GUILayout.Button("Apply", GUILayout.Width(60))) {
UmbraSoftShadows settings = (UmbraSoftShadows)target;
settings.profile.ApplyPreset(preset);
EditorUtility.SetDirty(target);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.PropertyField(debugShadows);
EditorGUILayout.PropertyField(contactShadowsSource);
if (contactShadowsSource.enumValueIndex == (int)ContactShadowsSource.PointLights) {
EditorGUILayout.PropertyField(pointLightsTrigger);
if (UmbraPointLightContactShadows.umbraPointLights.Count == 0) {
EditorGUILayout.HelpBox("No suitable point lights found. Add a UmbraPointLightContactShadows component to a point light to enable contact shadows on the light.", MessageType.Info);
}
}
if (profile.objectReferenceValue != null) {
if (cachedProfile != profile.objectReferenceValue) {
cachedProfile = null;
}
if (cachedProfile == null) {
cachedProfile = (UmbraProfile)profile.objectReferenceValue;
cachedProfileEditor = CreateEditor(profile.objectReferenceValue);
}
// Drawing the profile editor
EditorGUILayout.BeginVertical(boxStyle);
cachedProfileEditor.OnInspectorGUI();
EditorGUILayout.EndVertical();
}
serializedObject.ApplyModifiedProperties();
}
void CreateProfile() {
var fp = CreateInstance<UmbraProfile>();
fp.name = "New Umbra Profile";
string path = "Assets";
foreach (Object obj in Selection.GetFiltered(typeof(Object), SelectionMode.Assets)) {
path = AssetDatabase.GetAssetPath(obj);
if (File.Exists(path)) {
path = Path.GetDirectoryName(path);
}
break;
}
string fullPath = path + "/" + fp.name + ".asset";
fullPath = AssetDatabase.GenerateUniqueAssetPath(fullPath);
AssetDatabase.CreateAsset(fp, fullPath);
AssetDatabase.SaveAssets();
profile.objectReferenceValue = fp;
EditorGUIUtility.PingObject(fp);
}
void ExportProfile() {
var fp = (UmbraProfile)profile.objectReferenceValue;
var newProfile = Instantiate(fp);
string path = AssetDatabase.GetAssetPath(fp);
string fullPath = path;
if (string.IsNullOrEmpty(path)) {
path = "Assets";
foreach (Object obj in Selection.GetFiltered(typeof(Object), SelectionMode.Assets)) {
path = AssetDatabase.GetAssetPath(obj);
if (File.Exists(path)) {
path = Path.GetDirectoryName(path);
}
break;
}
fullPath = path + "/" + fp.name + ".asset";
}
fullPath = AssetDatabase.GenerateUniqueAssetPath(fullPath);
AssetDatabase.CreateAsset(newProfile, fullPath);
AssetDatabase.SaveAssets();
profile.objectReferenceValue = newProfile;
EditorGUIUtility.PingObject(fp);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 25ee00eb7253b430a895a39dc1115063
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Editor/UmbraSoftShadowsEditor.cs
uploadId: 868458

View File

@@ -0,0 +1,119 @@
**************************************
* UMBRA SOFT SHADOWS *
* by Kronnect *
* README FILE *
**************************************
Quick help: how to use this asset?
----------------------------------
1. Add "Umbra Render Feature" to the URP Renderer.
2. Add "Umbra Soft Shadows" to the directional light in the scene and customize the settings.
Help & Support Forum
--------------------
Check the Documentation folder for detailed instructions:
Have any question or issue?
* Support-Web: https://kronnect.com/docs/umbra/
* Support-Discord: https://discord.gg/EH2GMaM
* Email: contact@kronnect.com
* Twitter: @Kronnect
If you like Umbra Soft Shadows, please rate it on the Asset Store. It encourages us to keep improving it! Thanks!
Future updates
--------------
All our assets follow an incremental development process by which a few beta releases are published on our support forum (kronnect.com).
We encourage you to signup and engage our forum. The forum is the primary support and feature discussions medium.
Of course, all updates of Umbra will be eventually available on the Asset Store.
More Cool Assets!
-----------------
Check out our other assets here:
https://assetstore.unity.com/publishers/15018
Version history
---------------
Version 10.1
- [Fix] Fixed ImportTexture compatibility with Unity 6 Render Graph
Version 10.0
- Added support for Unity 6.4
Version 7.1
- Added "Force Depth Prepass" option in Advanced Section. Useful to support forward-only materials in deferred rendering path.
- [Fix] Fixes for Unity 6.3
Version 7.0.1
- [Fix] Fixed compatibility with forward opaques in deferred rendering path (also must choose Normals Source = Reconstruct From Depth)
Version 7.0
- Contact shadows: added support for point lights
- More options for constat shadows: depth bias far, edge softness, planar shadows
Version 6.1
- Added early out samples option
- Added option to render only contact shadows
- Added bias option to contact shadows
Version 6.0
- Added "Overlay Shadows" option which allows additional customization options
Version 5.0.1
- Render Graph optimizations
Version 5.0
- Added transparent soft shadows receiver plane support
Versio 4.2.3
- [Fix] Fixes an issue with URP Render Graph in deferred rendering path in Unity 6
Version 4.2.2.1
- [Fix] Fixed missing shadows on surfaces parallel to camera
Version 4.2.2
- Added support for orthographic camera
Version 4.2.1
- [Fix] Fixed contact shadows shader warning message
Version 4.2
- Improved support for multiple directional lights (note: in URP only the brightest directional light can cast shadows)
- [Fix] Fixes an issue with terrain normals
Version 4.1
- Improved contact shadows quality by adding "Vignette Size" and "Normal Bias" options
Version 4.0
- Added Contact Shadows feature
Version 3.0
- Added Render Graph support
- Added Unity native shadows support
- Cascade blending now supports up to 4 cascades
Version 2.0
- Added new options for stylized looks
- Added posterization option to default style with blur
- New optimization options
Version 1.1.2
- [Fix] Fixed shadow intensity issue with blur option
Version 1.1.1
- WebGL/mobile optimizations and fixes
Version 1.1 (May/2024)
- First release

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: d14c1841eb9a24564b69a6d06e4f1e30
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/README.txt
uploadId: 868458

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 931679de89fcd4b7dab7dc5ee27940fc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3cd48523710754e7fb63556087fafce7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7997da25fef5647d2a56b20fa2942ae9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cd9666e1302f84659a44ae61cdc184c7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,124 @@
#pragma once
TEXTURE2D_X(_MainTex);
float4 _MainTex_ST;
float4 _MainTex_TexelSize;
float4 _ShadowData;
#define SHADOW_SAMPLES _ShadowData.x
#define POSTERIZATION _ShadowData.y
#define DEPTH_REJECTION _ShadowData.z
#define SHADOW_MAX_BLUR_DEPTH _ShadowData.w
float4 _ShadowData2;
#define CONTACT_STRENGTH _ShadowData2.x
#define MAX_SHADOW_SPREAD _ShadowData2.y
#define SHADOW_MAX_DEPTH _ShadowData2.z
#define LIGHT_SIZE _ShadowData2.w
float4 _ShadowData3;
#define BLUR_DEPTH_ATTEN_START _ShadowData3.x
#define BLUR_DEPTH_ATTEN_LENGTH _ShadowData3.y
#define BLUR_GRAZING_ATTEN_STRENGTH _ShadowData3.z
#define BLUR_EDGE_SHARPNESS _ShadowData3.w
float _BlurSpread;
#define BLUR_SPREAD _BlurSpread
float4 _ShadowData4;
#define OCCLUDERS_COUNT _ShadowData4.x
#define OCCLUDERS_SEARCH_RADIUS _ShadowData4.y
#define CONTACT_STRENGTH_KNEE _ShadowData4.z
#define MASK_SCALE _ShadowData4.w
float _BlurScale;
float4 _BlendCascadeData;
#define BLEND_CASCADE_DATA _BlendCascadeData
float2 _SourceSize;
float _ReceiverPlaneAltitude;
int _EarlyOutSamples;
#define dot2(x) dot(x,x)
struct AttributesSimple {
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct VaryingsSimple {
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsSimple VertSimple(AttributesSimple v) {
VaryingsSimple o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.positionCS = v.positionOS;
o.positionCS.y *= _ProjectionParams.x;
o.uv = v.uv;
return o;
}
float GetLinearDepth(float2 uv) {
float rawDepth = SampleSceneDepth(uv);
float depthPersp = Linear01Depth(rawDepth, _ZBufferParams);
float depthOrtho = rawDepth;
#if UNITY_REVERSED_Z
depthOrtho = 1.0 - depthOrtho;
#endif
float depth = lerp(depthPersp, depthOrtho, unity_OrthoParams.w);
return depth;
}
float3 GetWorldPosition(float2 uv, float rawDepth) {
#if UNITY_REVERSED_Z
float depth = rawDepth;
#else
float depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, rawDepth);
#endif
float3 worldPos = ComputeWorldSpacePosition(uv, depth, UNITY_MATRIX_I_VP);
return worldPos;
}
float3 GetNormalFromWPOS(float3 wpos) {
float3 dx = ddx(wpos);
float3 dy = ddy(wpos);
float3 cr = cross(dy, dx);
float len = length(cr);
if (len == 0) {
return -UNITY_MATRIX_IT_MV[2].xyz;
}
return cr / len;
}
float3 GetNormalFromUV(float2 uv, float depth) {
float3 wpos = GetWorldPosition(uv, depth);
return GetNormalFromWPOS(wpos);
}
half InvLerp(half b, half t) {
half oneMinusT = 1 - t;
return oneMinusT + b * t;
}
bool IsSkyBox(float rawDepth) {
#if UNITY_REVERSED_Z
return rawDepth <= 0;
#else
return rawDepth >= 1;
#endif
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: b4011d16d47104fac8fb0ab72211d911
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Resources/Umbra/Shaders/Common.hlsl
uploadId: 868458

View File

@@ -0,0 +1,221 @@
int _ContactShadowsSampleCount;
#define SAMPLE_COUNT _ContactShadowsSampleCount
float4 _ContactShadowsData1;
#define STEPPING _ContactShadowsData1.x
#define INTENSITY_MULTIPLIER _ContactShadowsData1.y
#define JITTER _ContactShadowsData1.z
#define DISTANCE_FADE _ContactShadowsData1.w
float4 _ContactShadowsData2;
#define CONTACT_SHADOWS_MIN_DISTANCE _ContactShadowsData2.x
#define CONTACT_SHADOWS_MIN_DISTANCE_FADE _ContactShadowsData2.y
#define CONTACT_SHADOWS_MAX_DISTANCE _ContactShadowsData2.z
#define CONTACT_SHADOWS_NORMAL_BIAS _ContactShadowsData2.w
float4 _ContactShadowsData3;
#define THICKNESS_NEAR _ContactShadowsData3.x
#define THICKNESS_DEPTH_MULTIPLIER _ContactShadowsData3.y
#define VIGNETTE_SIZE _ContactShadowsData3.z
#define BIAS _ContactShadowsData3.w
float4 _ContactShadowsData4;
#define BIAS_FAR _ContactShadowsData4.x
#define EDGE_SOFTNESS _ContactShadowsData4.y
#define SHADOWS_3D _ContactShadowsData4.z
float4 _PointLightPosition;
#if _LOOP_STEP_X3
#define LOOP_STEP 3
#elif _LOOP_STEP_X2
#define LOOP_STEP 2
#else
#define LOOP_STEP 1
#endif
#define SHADER_API_WEBGL ((SHADER_API_GLES || SHADER_API_GLES3) && SHADER_API_DESKTOP)
#if SHADER_API_MOBILE || SHADER_API_WEBGL
#define LOOP(index, count) UNITY_UNROLL for(int index=0;index<64;index+=LOOP_STEP) if (index < count) {
#else
#define LOOP(index, count) for(int index=0;index<count;index+=LOOP_STEP) {
#endif
#define END_LOOP }
inline float GetLinearDepth01(float2 uv) {
float rawDepth = SAMPLE_TEXTURE2D_X_LOD(_CameraDepthTexture, sampler_PointClamp, uv, 0).r;
float depthPersp = Linear01Depth(rawDepth, _ZBufferParams);
float depthOrtho = rawDepth;
#if UNITY_REVERSED_Z
depthOrtho = 1.0 - depthOrtho;
#endif
float depth01 = lerp(depthPersp, depthOrtho, unity_OrthoParams.w);
return depth01;
}
inline float3 GetSSCoords(float3 wpos) {
float4 pos = TransformWorldToHClip(wpos);
pos.xyz /= pos.w;
pos.y *= _ProjectionParams.x;
float3 coords = pos.xyz;
coords.xy = coords.xy * 0.5 + 0.5;
float depthPersp = Linear01Depth(coords.z, _ZBufferParams);
float depthOrtho = coords.z;
#if UNITY_REVERSED_Z
depthOrtho = 1.0 - depthOrtho;
#endif
coords.z = lerp(depthPersp, depthOrtho, unity_OrthoParams.w);
return coords;
}
half4 FragContactShadows(Varyings input) : SV_Target {
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord.xy;
float rawDepth = SampleSceneDepth(uv);
#if !_RECEIVER_PLANE
if (IsSkyBox(rawDepth)) return half4(0, 0, 0, 0);
#endif
float depthPersp = Linear01Depth(rawDepth, _ZBufferParams);
float depthOrtho = rawDepth;
#if UNITY_REVERSED_Z
depthOrtho = 1.0 - depthOrtho;
#endif
float depth01 = lerp(depthPersp, depthOrtho, unity_OrthoParams.w);
#if defined(CONTACT_SHADOWS_AFTER_OPAQUE)
if (depth01 >= CONTACT_SHADOWS_MAX_DISTANCE || depth01 < CONTACT_SHADOWS_MIN_DISTANCE)
return half4(0, 0, 0, 0);
#else
if (depth01 >= SHADOW_MAX_DEPTH || depth01 < CONTACT_SHADOWS_MIN_DISTANCE)
return half4(1, 0, 0, 1);
#endif
float3 wpos0 = GetWorldPosition(uv, rawDepth);
#if _NORMALS_TEXTURE
float3 norm = SampleSceneNormals(uv);
#else
float3 norm = GetNormalFromWPOS(wpos0);
#endif
wpos0 += norm * CONTACT_SHADOWS_NORMAL_BIAS;
#if _RECEIVER_PLANE
if (wpos0.y < _ReceiverPlaneAltitude) {
float3 cameraToWpos = wpos0 - _WorldSpaceCameraPos;
float t = (_ReceiverPlaneAltitude - _WorldSpaceCameraPos.y) / cameraToWpos.y;
wpos0 = _WorldSpaceCameraPos + t * cameraToWpos;
#if _NORMALS_TEXTURE
norm = float3(0, 1, 0);
#endif
}
#endif
float3 lightDirection;
#if _USE_POINT_LIGHT
_PointLightPosition.y = lerp(wpos0.y - 0.05f, _PointLightPosition.y, SHADOWS_3D);
lightDirection = normalize(_PointLightPosition.xyz - wpos0);
#else
lightDirection = _MainLightPosition.xyz;
#endif
float3 step = lightDirection * STEPPING;
half randomVal = InterleavedGradientNoise(uv * _SourceSize.xy, 0);
wpos0 += step * (randomVal * JITTER);
float bias = depth01 * lerp(BIAS, BIAS_FAR, depth01);
float thickness = THICKNESS_NEAR + depth01 * THICKNESS_DEPTH_MULTIPLIER;
float maxDist = STEPPING * SAMPLE_COUNT;
half shadow = 1.0;
half dist = 0;
#if _SOFT_EDGES
// Complex loop with edge softness
float softestShadow = 1.0;
LOOP(k, SAMPLE_COUNT)
float3 wpos = wpos0 + step * k;
float3 coords = GetSSCoords(wpos);
if (any(floor(coords.xy)!=0)) break;
float depth = GetLinearDepth01(coords.xy);
float depthDiff = coords.z - depth;
if (depthDiff > bias && depthDiff < thickness) {
// Soft edge calculation based on how close we are to the bias threshold
float edgeFade = saturate((depthDiff - bias) / (thickness * EDGE_SOFTNESS));
dist = STEPPING * k;
float distanceFade = lerp(0, DISTANCE_FADE, (float)k / SAMPLE_COUNT);
// Additional softening based on distance
float distanceSoftness = saturate(dist / (STEPPING * SAMPLE_COUNT * 0.5));
distanceFade = lerp(distanceFade, 1.0, distanceSoftness * 0.3);
float currentShadow = lerp(1.0, distanceFade, edgeFade);
softestShadow = min(softestShadow, currentShadow);
// Continue sampling for softer edges
if (edgeFade > 0.98 && k > SAMPLE_COUNT * 0.5) break;
}
END_LOOP
shadow = softestShadow;
#else
// Simple loop that exits immediately on hit
LOOP(k, SAMPLE_COUNT)
float3 wpos = wpos0 + step * k;
float3 coords = GetSSCoords(wpos);
if (any(floor(coords.xy)!=0)) break;
float depth = GetLinearDepth01(coords.xy);
float depthDiff = coords.z - depth;
if (depthDiff > bias && depthDiff < thickness) {
dist = STEPPING * k;
shadow = lerp(0, DISTANCE_FADE, (float)k / SAMPLE_COUNT);
break;
}
END_LOOP
#endif
shadow = saturate( shadow + 1.0 - saturate((depth01 - CONTACT_SHADOWS_MIN_DISTANCE) / CONTACT_SHADOWS_MIN_DISTANCE_FADE) );
// apply shadow intensity
half4 shadowParams = GetMainLightShadowParams();
if (all(shadowParams.xy == 0)) shadowParams.x = 1; // if shadows are disabled, shadowParams is not set
half shadowIntensity = shadowParams.x * INTENSITY_MULTIPLIER;
if (VIGNETTE_SIZE > 0) {
float2 screenCoord = uv * _SourceSize;
float2 distanceToEdges = min(screenCoord, _SourceSize - screenCoord);
float edgeDistance = min(distanceToEdges.x, distanceToEdges.y);
half vignette = edgeDistance / (VIGNETTE_SIZE * min(_SourceSize.x, _SourceSize.y));
vignette = saturate(vignette);
shadow = lerp(1, shadow, vignette);
}
shadow = InvLerp(shadow, shadowIntensity);
#if defined(CONTACT_SHADOWS_AFTER_OPAQUE)
return half4(0, 0, 0, 1.0 - shadow);
#else
return half4(shadow, dist, 0, 0);
#endif
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 8c459ab4b3eba4c6f910b2049df58ddf
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Resources/Umbra/Shaders/ContactShadows.hlsl
uploadId: 868458

View File

@@ -0,0 +1,287 @@
TEXTURE2D_X_FLOAT(_DownsampledDepth);
float4 _DownsampledDepth_TexelSize;
half4 _OverlayShadowColor;
struct VaryingsCross {
float4 positionCS : SV_POSITION;
float2 uv: TEXCOORD0;
float2 dir : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
VaryingsCross VertBlur(AttributesSimple v) {
VaryingsCross o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.positionCS = v.positionOS;
o.positionCS.y *= _ProjectionParams.x;
o.uv = v.uv;
#if defined(BLUR_VERT)
o.dir = float2(0, _MainTex_TexelSize.y * _BlurScale);
#else
o.dir = float2(_MainTex_TexelSize.x * _BlurScale, 0);
#endif
return o;
}
#if _BLUR_HQ
static const float weights[] = { 0.14446445, 0.13543542, 0.11153505, 0.08055309, 0.05087564, 0.02798160, 0.01332457, 0.00545096 };
#define SAMPLE_COUNT 7
#else
static const float weights[] = { 0.2270270270, 0.3162162162, 0.0702702703 };
#define SAMPLE_COUNT 2
#endif
half2 BlurShadowGaussian(VaryingsCross i, float depth) {
float2 uv = UnityStereoTransformScreenSpaceTex(i.uv);
half2 shadow = SAMPLE_TEXTURE2D_X_LOD(_MainTex, sampler_LinearClamp, uv, 0).xy;
if (depth > SHADOW_MAX_BLUR_DEPTH) return shadow;
float referenceDepth = 10.0 / _ProjectionParams.z;
float spread = BLUR_SPREAD * clamp(referenceDepth / depth, 1.0, 10.0);
#if _CONTACT_HARDENING
spread *= lerp(1, shadow.y, CONTACT_STRENGTH);
#endif
spread = clamp(spread, 0.5, 10);
half2 shadowBlur = 0;
half sum = 0.0000001;
UNITY_UNROLL
for (int index = -SAMPLE_COUNT; index <= SAMPLE_COUNT; index++) {
float2 uv = i.uv + i.dir * (index * spread);
float2 shadowN = SAMPLE_TEXTURE2D_X_LOD(_MainTex, sampler_LinearClamp, UnityStereoTransformScreenSpaceTex(uv), 0).xy;
float depthN = GetLinearDepth(uv);
float depthDiff = abs(depthN - depth);
float r2 = depthDiff * DEPTH_REJECTION;
float g = exp(-r2 * r2);
float w = g * weights[abs(index)];
shadowBlur += w * shadowN;
sum += w;
}
shadowBlur /= sum;
return shadowBlur;
}
half2 BlurShadowBox(VaryingsSimple i, float depth) {
float2 uv = UnityStereoTransformScreenSpaceTex(i.uv);
half2 shadow = SAMPLE_TEXTURE2D_X_LOD(_MainTex, sampler_LinearClamp, uv, 0).xy;
if (depth > SHADOW_MAX_BLUR_DEPTH) return shadow;
float referenceDepth = 10.0 / _ProjectionParams.z;
float spread = BLUR_SPREAD * clamp(referenceDepth / depth, 1.0, 10.0);
#if _CONTACT_HARDENING
spread *= lerp(1, shadow.y, CONTACT_STRENGTH);
#endif
spread = clamp(spread, 1, 10);
half2 shadowBlur = 0;
half sum = 0.0000001;
float2 blurSize = _MainTex_TexelSize.xy * spread;
UNITY_UNROLL
for(int y=-1;y<=1;y++) {
UNITY_UNROLL
for (int x = -1; x <= 1; x++) {
float2 uv = i.uv + float2(x,y) * blurSize;
float2 shadowN = SAMPLE_TEXTURE2D_X_LOD(_MainTex, sampler_LinearClamp, UnityStereoTransformScreenSpaceTex(uv), 0).xy;
float depthN = GetLinearDepth(uv);
float depthDiff = abs(depthN - depth);
float r2 = depthDiff * DEPTH_REJECTION;
float g = exp(-r2 * r2);
float w = g;
shadowBlur += w * shadowN;
sum += w;
}
}
shadowBlur /= sum;
return shadowBlur;
}
half4 FragBlurGaussian (VaryingsCross i): SV_Target {
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float depth = GetLinearDepth(i.uv);
if (depth >= SHADOW_MAX_DEPTH) return 1;
half2 shadow = BlurShadowGaussian(i, depth);
return half4(shadow, 0, 0);
}
half4 FragBlurBox (VaryingsSimple i): SV_Target {
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float depth = GetLinearDepth(i.uv);
if (depth >= SHADOW_MAX_DEPTH) return 1;
half2 shadow = BlurShadowBox(i, depth);
return half4(shadow, 0, 0);
}
half4 FragCompose (VaryingsSimple i): SV_Target {
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float rawDepth = SampleSceneDepth(i.uv);
float depthPersp = Linear01Depth(rawDepth, _ZBufferParams);
float depthOrtho = rawDepth;
#if UNITY_REVERSED_Z
depthOrtho = 1.0 - depthOrtho;
#endif
float depth = lerp(depthPersp, depthOrtho, unity_OrthoParams.w);
if (depth >= SHADOW_MAX_DEPTH) return 1;
float2 uv = UnityStereoTransformScreenSpaceTex(i.uv);
#if _PRESERVE_EDGES
const float threshold = 0.00005;
const float t = 0.5;
float2 uv00 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, -t));
float2 uv10 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, -t));
float2 uv01 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, t));
float2 uv11 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, t));
float4 depths;
depths.x = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_PointClamp, uv00).r;
depths.y = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_PointClamp, uv10).r;
depths.z = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_PointClamp, uv01).r;
depths.w = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_PointClamp, uv11).r;
float4 diffs = abs(depth.xxxx - depths);
float2 minUV = UnityStereoTransformScreenSpaceTex(uv);
if (any(diffs > threshold)) {
// Check 10 vs 00
float minDiff = lerp(diffs.x, diffs.y, diffs.y < diffs.x);
minUV = lerp(uv00, uv10, diffs.y < diffs.x);
// Check against 01
minUV = lerp(minUV, uv01, diffs.z < minDiff);
minDiff = lerp(minDiff, diffs.z, diffs.z < minDiff);
// Check against 11
minUV = lerp(minUV, uv11, diffs.w < minDiff);
}
half2 shadow = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, minUV).xy;
#else
half2 shadow = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv).xy;
#endif
// improve shadow edge
#if _CONTACT_HARDENING
half penumbra = lerp(1.0 - BLUR_EDGE_SHARPNESS, 1.0, shadow.y);
#else
half penumbra = 1.0 - BLUR_EDGE_SHARPNESS;
#endif
half u0 = 0.5 - penumbra * 0.5;
half u1 = 0.5 + penumbra * 0.5;
// lerp between fine and smooth edge based on distance to occluder
half edged = smoothstep(u0, u1, shadow.x);
shadow.x = lerp(shadow.x, edged, BLUR_EDGE_SHARPNESS);
shadow = round(shadow * POSTERIZATION) / POSTERIZATION;
half blendingFactor = 1.0;
#if defined(COMPOSE_WITH_BLENDING)
// reduce blur with distance
blendingFactor -= saturate((depth - BLUR_DEPTH_ATTEN_START) / BLUR_DEPTH_ATTEN_LENGTH);
// under skewed view, reduce blur
if (BLUR_GRAZING_ATTEN_STRENGTH > 0) {
float3 wpos = GetWorldPosition(uv, rawDepth);
float3 viewDir = normalize(wpos - GetCameraPositionWS());
#if _NORMALS_TEXTURE
float3 norm = SampleSceneNormals(uv);
#else
float3 norm = GetNormalFromWPOS(wpos);
#endif
blendingFactor *= lerp(1, abs(dot(norm, viewDir)), BLUR_GRAZING_ATTEN_STRENGTH);
}
#endif
return half4(shadow.x, 0, 0, blendingFactor);
}
float4 FragDownsampleDepth (VaryingsSimple i): SV_Target {
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float depth = GetLinearDepth(i.uv);
if (depth >= SHADOW_MAX_DEPTH) return 1;
return depth;
}
half4 FragComposeUnity (VaryingsSimple i): SV_Target {
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
float rawDepth = SampleSceneDepth(i.uv);
#if !_RECEIVER_PLANE
if (IsSkyBox(rawDepth)) return 1;
#endif
float2 uv = UnityStereoTransformScreenSpaceTex(i.uv);
#if _PRESERVE_EDGES
float depth = Linear01Depth(rawDepth, _ZBufferParams);
const float threshold = 0.00005;
const float t = 0.5;
float2 uv00 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, -t));
float2 uv10 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, -t));
float2 uv01 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, t));
float2 uv11 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, t));
float4 depths;
depths.x = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_PointClamp, uv00).r;
depths.y = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_PointClamp, uv10).r;
depths.z = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_PointClamp, uv01).r;
depths.w = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_PointClamp, uv11).r;
float4 diffs = abs(depth.xxxx - depths);
float2 minUV = UnityStereoTransformScreenSpaceTex(uv);
if (any(diffs > threshold)) {
// Check 10 vs 00
float minDiff = lerp(diffs.x, diffs.y, diffs.y < diffs.x);
minUV = lerp(uv00, uv10, diffs.y < diffs.x);
// Check against 01
minUV = lerp(minUV, uv01, diffs.z < minDiff);
minDiff = lerp(minDiff, diffs.z, diffs.z < minDiff);
// Check against 11
minUV = lerp(minUV, uv11, diffs.w < minDiff);
}
half shadow = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, minUV).x;
#else
half shadow = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv).x;
#endif
return half4(shadow, 0, 0, 0);
}
half4 FragDebugShadows(Varyings input) : SV_Target {
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord.xy);
half shadow = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv).x;
return shadow.xxxx;
}
half4 FragOverlayShadows(Varyings input) : SV_Target {
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord.xy);
half shadow = SAMPLE_TEXTURE2D_X(_ScreenSpaceShadowmapTexture, sampler_LinearClamp, uv).x;
return half4(1, 1, 1, 1 - shadow) * _OverlayShadowColor;
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: e319766b9a5a64e008d361eaac8a7079
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Resources/Umbra/Shaders/ShadowBlur.hlsl
uploadId: 868458

View File

@@ -0,0 +1,341 @@
TEXTURE2D(_NoiseTex);
float4 _NoiseTex_TexelSize;
float4 _UmbraCascadeRects[4];
float _UmbraCascadeScales[4];
static const float2 randomOffsets[64] = {
float2(0.000000, 0.000000),
float2(-0.737277, 0.675590),
float2(0.123257, -1.408832),
float2(1.054406, 1.374128),
float2(-1.969616, -0.347296),
float2(1.885881, -1.201438),
float2(-0.633975, 2.366025),
float2(-1.221672, -2.346810),
float2(2.657852, 0.967379),
float2(-2.771639, 1.148050),
float2(1.336436, -2.865997),
float2(0.997328, 3.163121),
float2(-3.000000, -1.732051),
float2(3.520085, -0.780384),
float2(-2.146127, 3.064986),
float2(-0.505526, -3.839849),
float2(3.064178, 2.571150),
float2(-4.119181, 0.179847),
float2(3.000000, -3.000000),
float2(-0.190133, 4.354750),
float2(-2.874634, -3.425855),
float2(4.543371, 0.598146),
float2(-3.842164, 2.690312),
float2(1.038008, -4.682151),
float2(2.449490, 4.242641),
float2(-4.768585, -1.503529),
float2(4.621281, -2.154939),
float2(-1.988481, 4.800619),
float2(-1.809800, -4.972386),
float2(4.776700, 2.486592),
float2(-5.290594, 1.417610),
float2(2.991558, -4.695805),
float2(0.982302, 5.570914),
float2(-4.557468, -3.497068),
float2(5.808763, -0.508201),
float2(-3.996846, 4.361792),
float2(-0.000000, -6.000000),
float2(4.109455, 4.484683),
float2(-6.140957, -0.537264),
float2(4.954490, -3.801714),
float2(-1.098248, 6.228471),
float2(-3.440396, -5.400340),
float2(6.259915, 1.677339),
float2(-5.816519, 3.027888),
float2(2.268705, -6.233216),
float2(2.567119, 6.197572),
float2(-6.146878, -2.866337),
float2(6.538354, -2.061535),
float2(-3.464102, 6.000000),
float2(-1.515077, -6.834072),
float2(5.792280, 4.055798),
float2(-7.080333, 0.932143),
float2(4.635207, -5.524025),
float2(0.317554, 7.273181),
float2(-5.196152, -5.196152),
float2(7.409140, 0.323490),
float2(-5.732552, 4.810182),
float2(0.985451, -7.485245),
float2(4.368228, 6.238476),
float2(-7.499072, -1.662504),
float2(6.708204, -3.872983),
float2(-2.348587, 7.448768),
float2(-3.327700, -7.136275),
float2(7.333066, 3.037456)
};
#if _LOOP_STEP_X3
#define LOOP_STEP 3
#elif _LOOP_STEP_X2
#define LOOP_STEP 2
#else
#define LOOP_STEP 1
#endif
#define SHADER_API_WEBGL ((SHADER_API_GLES || SHADER_API_GLES3) && SHADER_API_DESKTOP)
#if SHADER_API_MOBILE || SHADER_API_WEBGL
#define LOOP(index, count) UNITY_UNROLL for(int index=0;index<64;index+=LOOP_STEP) if (index < count) {
#else
#define LOOP(index, count) for(int index=0;index<count;index+=LOOP_STEP) {
#endif
#define END_LOOP }
half ComputeCascadeIndexWithBlending(float3 positionWS, out half blendFactor) {
float3 fromCenter0 = positionWS - _CascadeShadowSplitSpheres0.xyz;
float3 fromCenter1 = positionWS - _CascadeShadowSplitSpheres1.xyz;
float3 fromCenter2 = positionWS - _CascadeShadowSplitSpheres2.xyz;
float3 fromCenter3 = positionWS - _CascadeShadowSplitSpheres3.xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
// Determine the closest cascade
half4 weights = half4(distances2 < _CascadeShadowSplitSphereRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
half cascadeIndex = 4 - dot(weights, half4(4, 3, 2, 1));
// Compute blend factor between cascades
half4 distancesToBorders = abs(distances2 - _CascadeShadowSplitSphereRadii);
half4 blendFactors = 1.0 - saturate(distancesToBorders / BLEND_CASCADE_DATA);
blendFactors *= blendFactors;
blendFactors *= 0.5;
if (blendFactors.x > blendFactors.y) {
blendFactor = blendFactors.x;
return saturate(1 - cascadeIndex);
}
if (blendFactors.y > blendFactors.z) {
blendFactor = blendFactors.y;
return clamp(3 - cascadeIndex, 1, 2);
}
blendFactor = blendFactors.z;
return clamp(5 - cascadeIndex, 2, 3);
}
float4 CustomTransformWorldToShadowCoord(float3 positionWS, out half cascadeIndex, out half blendFactor)
{
#ifdef _MAIN_LIGHT_SHADOWS_CASCADE
cascadeIndex = ComputeCascadeIndexWithBlending(positionWS, blendFactor);
#else
cascadeIndex = 0;
blendFactor = 0;
#endif
float4 shadowCoord = mul(_MainLightWorldToShadow[cascadeIndex], float4(positionWS, 1.0));
return float4(shadowCoord.xyz, 0);
}
float4 CustomTransformWorldToShadowCoord(float3 positionWS, out half cascadeIndex)
{
#ifdef _MAIN_LIGHT_SHADOWS_CASCADE
cascadeIndex = ComputeCascadeIndex(positionWS);
#else
cascadeIndex = 0;
#endif
float4 shadowCoord = mul(_MainLightWorldToShadow[cascadeIndex], float4(positionWS, 1.0));
return float4(shadowCoord.xyz, 0);
}
inline float3 InterpolateShadowmapCoord(float3 coords, float3 dx, float3 dy, float2 offset) {
return coords + dx * offset.x + dy * offset.y;
}
#if _MASK_TEXTURE
TEXTURE2D(_MaskTex);
half ComputeMaskWorldSpace(float3 wpos, float3 normalWS) {
float3 maskUV = wpos * MASK_SCALE;
half n1 = SAMPLE_TEXTURE2D(_MaskTex, sampler_LinearRepeat, maskUV.zy).r;
half n2 = SAMPLE_TEXTURE2D(_MaskTex, sampler_LinearRepeat, maskUV.xz).r;
half n3 = SAMPLE_TEXTURE2D(_MaskTex, sampler_LinearRepeat, maskUV.xy).r;
float3 triW = abs(normalWS);
float3 weights = triW / (triW.x + triW.y + triW.z);
half mask = dot(half3(n1, n2, n3), weights);
return mask;
}
#endif
half4 FragCast(Varyings input) : SV_Target {
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
float2 uv = input.texcoord.xy;
float rawDepth = SampleSceneDepth(uv);
#if !_RECEIVER_PLANE
if (IsSkyBox(rawDepth)) return half4(1, 0, 0, 0);
#endif
half cascadeIndex;
// normal provided by normals texture
#if _NORMALS_TEXTURE
float3 norm = SampleSceneNormals(uv);
#endif
float3 wpos = GetWorldPosition(uv, rawDepth);
#if _RECEIVER_PLANE
if (wpos.y < _ReceiverPlaneAltitude) {
float3 cameraToWpos = wpos - _WorldSpaceCameraPos;
float t = (_ReceiverPlaneAltitude - _WorldSpaceCameraPos.y) / cameraToWpos.y;
wpos = _WorldSpaceCameraPos + t * cameraToWpos;
#if _NORMALS_TEXTURE
norm = float3(0, 1, 0);
#endif
}
#endif
// compute normal at world position
#if !_NORMALS_TEXTURE
float3 norm = GetNormalFromWPOS(wpos);
#endif
// get cascade and shadowmap coordinate
#if defined(_BLEND_CASCADE)
half blendFactor;
float4 coords = CustomTransformWorldToShadowCoord(wpos, cascadeIndex, blendFactor);
if (blendFactor <= 0 || blendFactor >= 0.5) discard;
#else
float4 coords = CustomTransformWorldToShadowCoord(wpos, cascadeIndex);
#endif
if (BEYOND_SHADOW_FAR(coords)) return half4(1, 0, 0, 0);
// prepare noise
float2 pos = uv * _SourceSize;
float2 noise = normalize(SAMPLE_TEXTURE2D_LOD(_NoiseTex, sampler_PointRepeat, pos * _NoiseTex_TexelSize.xy, 0).xy - 0.5);
// pick tangent & binormal that are orthogonal to light direction
float3 v = _MainLightPosition.xyz;
v.y = abs(norm.y) < 0.9;
v = normalize(v);
float3 tangent = normalize(cross(norm, v));
float3 binormal = cross(norm, tangent);
// compute shadowmap axis coordinates for later interpolation
float3 cr0 = mul(_MainLightWorldToShadow[cascadeIndex], float4(wpos + tangent, 1.0)).xyz;
float3 cr1 = mul(_MainLightWorldToShadow[cascadeIndex], float4(wpos + binormal, 1.0)).xyz;
float3 dx = cr0 - coords.xyz;
float3 dy = cr1 - coords.xyz;
// clamp to cascade boundary
#if _MAIN_LIGHT_SHADOWS_CASCADE
float4 cascadeRect = _UmbraCascadeRects[cascadeIndex];
#endif
#if _CONTACT_HARDENING
// contact hardening
float depthAvg = 0;
float occluders = 0;
float3 dxSearch = dx * OCCLUDERS_SEARCH_RADIUS;
float3 dySearch = dy * OCCLUDERS_SEARCH_RADIUS;
#if SHADER_API_MOBILE
//UNITY_UNROLLX(32)
#endif
LOOP(i, OCCLUDERS_COUNT)
float2 offset = reflect(randomOffsets[i], noise);
float3 cr2 = InterpolateShadowmapCoord(coords.xyz, dxSearch, dySearch, offset);
#if _MAIN_LIGHT_SHADOWS_CASCADE
cr2.xy = clamp(cr2.xy, cascadeRect.xy, cascadeRect.zw);
#endif
float d = SAMPLE_TEXTURE2D_LOD(_MainLightShadowmapTexture, sampler_LinearClamp, cr2.xy, 0).x;
if (d > cr2.z) {
depthAvg += d;
occluders++;
}
END_LOOP
if (occluders < 1) return half4(1, 0, 0, 0);
depthAvg = depthAvg / occluders + 0.00001;
float distAvg = depthAvg - coords.z;
#if _MAIN_LIGHT_SHADOWS_CASCADE
distAvg *= _UmbraCascadeScales[cascadeIndex];
#endif
float smoothness = distAvg / depthAvg;
float distanceFactor = lerp(CONTACT_STRENGTH, MAX_SHADOW_SPREAD, saturate(distAvg / CONTACT_STRENGTH_KNEE) * smoothness) * LIGHT_SIZE;
#else
float distanceFactor = LIGHT_SIZE;
#endif
// compute shadow term
dx *= distanceFactor;
dy *= distanceFactor;
half shadow = 0;
half samples = 0;
#if SHADER_API_MOBILE
//SHADOW_SAMPLES = min(SHADOW_SAMPLES, 32);
//UNITY_UNROLLX(32)
#endif
LOOP(j, SHADOW_SAMPLES)
float2 offset = reflect(randomOffsets[j], noise);
float3 cr2 = InterpolateShadowmapCoord(coords.xyz, dx, dy, offset);
#if _MAIN_LIGHT_SHADOWS_CASCADE
cr2.xy = clamp(cr2.xy, cascadeRect.xy, cascadeRect.zw);
#endif
shadow += SAMPLE_TEXTURE2D_SHADOW(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture, cr2);
samples++;
if (samples > _EarlyOutSamples && (shadow <= 0 || shadow >= samples)) break;
END_LOOP
shadow /= samples;
#if _MASK_TEXTURE
half mask = ComputeMaskWorldSpace(wpos, norm);
shadow = saturate(shadow + mask);
#endif
// apply shadow intensity
half4 shadowParams = GetMainLightShadowParams();
half shadowIntensity = shadowParams.x;
shadow = InvLerp(shadow, shadowIntensity);
// output with alpha if cascade blending is used
#if defined(_BLEND_CASCADE)
return half4(shadow, distanceFactor, 0, blendFactor);
#else
return half4(shadow, distanceFactor, 0, 1);
#endif
}
half4 FragUnityShadows(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#if UNITY_REVERSED_Z
float deviceDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_PointClamp, input.texcoord.xy).r;
#else
float deviceDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_PointClamp, input.texcoord.xy).r;
deviceDepth = deviceDepth * 2.0 - 1.0;
#endif
//Fetch shadow coordinates for cascade.
float3 wpos = ComputeWorldSpacePosition(input.texcoord.xy, deviceDepth, unity_MatrixInvVP);
float4 coords = TransformWorldToShadowCoord(wpos);
// Screenspace shadowmap is only used for directional lights which use orthogonal projection.
half realtimeShadow = MainLightRealtimeShadow(coords);
return realtimeShadow;
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: ec87f1a05845843d3bb05b576314b62a
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Resources/Umbra/Shaders/ShadowCast.hlsl
uploadId: 868458

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6c3132133fcd34506aa421c69014901d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
#ifndef UMBRA_SHADOW_FUNCTIONS_INCLUDED
#define UMBRA_SHADOW_FUNCTIONS_INCLUDED
#ifdef SHADERGRAPH_PREVIEW
void GetMainShadow_float(float3 worldPos, out half shadowAtten){
shadowAtten = 1;
}
#else
void GetMainShadow_float(float3 worldPos, out half shadowAtten){
float4 shadowCoord = ComputeScreenPos(TransformWorldToHClip(worldPos));
shadowAtten = SampleScreenSpaceShadowmap(shadowCoord);
}
#endif
#endif // UMBRA_SHADOW_FUNCTIONS_INCLUDED

View File

@@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 97b280ff217a64e4fbf524cc3adf374a
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Resources/Umbra/Shaders/Transparent
Receiver/ShadowFunctions.hlsl
uploadId: 868458

View File

@@ -0,0 +1,804 @@
{
"m_SGVersion": 3,
"m_Type": "UnityEditor.ShaderGraph.GraphData",
"m_ObjectId": "313d9d1fe28a4561bfcd174269782ca6",
"m_Properties": [
{
"m_Id": "5f2fa682a67d4b9bb3ce0c032b99524c"
}
],
"m_Keywords": [],
"m_Dropdowns": [],
"m_CategoryData": [
{
"m_Id": "fbc63f3198b944c0ae62acc54dfb7583"
}
],
"m_Nodes": [
{
"m_Id": "9a45fa2786da4e9a8880b2416e884c1f"
},
{
"m_Id": "792ce8177b4b40f2b49db74b402ef06f"
},
{
"m_Id": "745ea9abdb724f25952d4740bf30c020"
},
{
"m_Id": "533b2f26ee9a43fdaa385258dc054356"
},
{
"m_Id": "15e6e2478d6b4b82aff4190884ad03de"
},
{
"m_Id": "0d8b270b1d8f40d8ac19121eb472db47"
},
{
"m_Id": "0e1e3ddeb5424df7a0afa5fe3064b5fb"
},
{
"m_Id": "046e55d7fa1f4aca841e660634642385"
},
{
"m_Id": "dc71a03354764aa4b2793dcec9e02920"
}
],
"m_GroupDatas": [],
"m_StickyNoteDatas": [],
"m_Edges": [
{
"m_OutputSlot": {
"m_Node": {
"m_Id": "046e55d7fa1f4aca841e660634642385"
},
"m_SlotId": 0
},
"m_InputSlot": {
"m_Node": {
"m_Id": "533b2f26ee9a43fdaa385258dc054356"
},
"m_SlotId": 0
}
},
{
"m_OutputSlot": {
"m_Node": {
"m_Id": "0d8b270b1d8f40d8ac19121eb472db47"
},
"m_SlotId": 0
},
"m_InputSlot": {
"m_Node": {
"m_Id": "15e6e2478d6b4b82aff4190884ad03de"
},
"m_SlotId": 0
}
},
{
"m_OutputSlot": {
"m_Node": {
"m_Id": "15e6e2478d6b4b82aff4190884ad03de"
},
"m_SlotId": 1
},
"m_InputSlot": {
"m_Node": {
"m_Id": "dc71a03354764aa4b2793dcec9e02920"
},
"m_SlotId": 0
}
},
{
"m_OutputSlot": {
"m_Node": {
"m_Id": "dc71a03354764aa4b2793dcec9e02920"
},
"m_SlotId": 1
},
"m_InputSlot": {
"m_Node": {
"m_Id": "0e1e3ddeb5424df7a0afa5fe3064b5fb"
},
"m_SlotId": 0
}
}
],
"m_VertexContext": {
"m_Position": {
"x": 165.0,
"y": 184.0
},
"m_Blocks": [
{
"m_Id": "9a45fa2786da4e9a8880b2416e884c1f"
},
{
"m_Id": "792ce8177b4b40f2b49db74b402ef06f"
},
{
"m_Id": "745ea9abdb724f25952d4740bf30c020"
}
]
},
"m_FragmentContext": {
"m_Position": {
"x": 165.0,
"y": 401.0
},
"m_Blocks": [
{
"m_Id": "533b2f26ee9a43fdaa385258dc054356"
},
{
"m_Id": "0e1e3ddeb5424df7a0afa5fe3064b5fb"
}
]
},
"m_PreviewData": {
"serializedMesh": {
"m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}",
"m_Guid": ""
},
"preventRotation": false
},
"m_Path": "Shader Graphs",
"m_GraphPrecision": 1,
"m_PreviewMode": 2,
"m_OutputNode": {
"m_Id": ""
},
"m_SubDatas": [],
"m_ActiveTargets": [
{
"m_Id": "e36cc0dd20a44f22923e392b9bfccc84"
}
]
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.PropertyNode",
"m_ObjectId": "046e55d7fa1f4aca841e660634642385",
"m_Group": {
"m_Id": ""
},
"m_Name": "Property",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": -239.0000457763672,
"y": 183.99993896484376,
"width": 147.0,
"height": 34.00004577636719
}
},
"m_Slots": [
{
"m_Id": "7459cf9619dd4269918e7e62a14828e4"
}
],
"synonyms": [],
"m_Precision": 0,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 0,
"m_CustomColors": {
"m_SerializableColors": []
},
"m_Property": {
"m_Id": "5f2fa682a67d4b9bb3ce0c032b99524c"
}
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot",
"m_ObjectId": "073a43107aba4af6b619005c8ec766ea",
"m_Id": 0,
"m_DisplayName": "Alpha",
"m_SlotType": 0,
"m_Hidden": false,
"m_ShaderOutputName": "Alpha",
"m_StageCapability": 2,
"m_Value": 1.0,
"m_DefaultValue": 1.0,
"m_Labels": []
}
{
"m_SGVersion": 1,
"m_Type": "UnityEditor.ShaderGraph.PositionNode",
"m_ObjectId": "0d8b270b1d8f40d8ac19121eb472db47",
"m_Group": {
"m_Id": ""
},
"m_Name": "Position",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": -1064.0,
"y": 257.9999694824219,
"width": 208.0,
"height": 314.4999694824219
}
},
"m_Slots": [
{
"m_Id": "fe302a6ca1e9493d92edbeb37dd9d398"
}
],
"synonyms": [
"location"
],
"m_Precision": 1,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 2,
"m_CustomColors": {
"m_SerializableColors": []
},
"m_Space": 2,
"m_PositionSource": 0
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.BlockNode",
"m_ObjectId": "0e1e3ddeb5424df7a0afa5fe3064b5fb",
"m_Group": {
"m_Id": ""
},
"m_Name": "SurfaceDescription.Alpha",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": 0.0,
"y": 0.0,
"width": 0.0,
"height": 0.0
}
},
"m_Slots": [
{
"m_Id": "073a43107aba4af6b619005c8ec766ea"
}
],
"synonyms": [],
"m_Precision": 0,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 0,
"m_CustomColors": {
"m_SerializableColors": []
},
"m_SerializedDescriptor": "SurfaceDescription.Alpha"
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot",
"m_ObjectId": "13ee747054f84538ba3da482273283c7",
"m_Id": 0,
"m_DisplayName": "Base Color",
"m_SlotType": 0,
"m_Hidden": false,
"m_ShaderOutputName": "BaseColor",
"m_StageCapability": 2,
"m_Value": {
"x": 0.5,
"y": 0.5,
"z": 0.5
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_Labels": [],
"m_ColorMode": 0,
"m_DefaultColor": {
"r": 0.5,
"g": 0.5,
"b": 0.5,
"a": 1.0
}
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot",
"m_ObjectId": "14b5565b46d3477daee496d9ab92b620",
"m_Id": 1,
"m_DisplayName": "attenuation",
"m_SlotType": 1,
"m_Hidden": false,
"m_ShaderOutputName": "attenuation",
"m_StageCapability": 3,
"m_Value": 0.0,
"m_DefaultValue": 0.0,
"m_Labels": []
}
{
"m_SGVersion": 1,
"m_Type": "UnityEditor.ShaderGraph.CustomFunctionNode",
"m_ObjectId": "15e6e2478d6b4b82aff4190884ad03de",
"m_Group": {
"m_Id": ""
},
"m_Name": "GetMainShadow (Custom Function)",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": -802.5,
"y": 262.0000305175781,
"width": 262.5,
"height": 277.9999694824219
}
},
"m_Slots": [
{
"m_Id": "a8408df2e5c84a1380869614a19939c2"
},
{
"m_Id": "14b5565b46d3477daee496d9ab92b620"
}
],
"synonyms": [
"code",
"HLSL"
],
"m_Precision": 1,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 0,
"m_CustomColors": {
"m_SerializableColors": []
},
"m_SourceType": 0,
"m_FunctionName": "GetMainShadow",
"m_FunctionSource": "97b280ff217a64e4fbf524cc3adf374a",
"m_FunctionBody": "Enter function body here..."
}
{
"m_SGVersion": 2,
"m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalUnlitSubTarget",
"m_ObjectId": "16533883a7c0489eaecf612ab54498ff"
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot",
"m_ObjectId": "26741a9638224fc6bcd1bfa42507da22",
"m_Id": 0,
"m_DisplayName": "In",
"m_SlotType": 0,
"m_Hidden": false,
"m_ShaderOutputName": "In",
"m_StageCapability": 3,
"m_Value": {
"x": 1.0,
"y": 1.0,
"z": 1.0,
"w": 1.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.BlockNode",
"m_ObjectId": "533b2f26ee9a43fdaa385258dc054356",
"m_Group": {
"m_Id": ""
},
"m_Name": "SurfaceDescription.BaseColor",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": 0.0,
"y": 0.0,
"width": 0.0,
"height": 0.0
}
},
"m_Slots": [
{
"m_Id": "13ee747054f84538ba3da482273283c7"
}
],
"synonyms": [],
"m_Precision": 0,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 0,
"m_CustomColors": {
"m_SerializableColors": []
},
"m_SerializedDescriptor": "SurfaceDescription.BaseColor"
}
{
"m_SGVersion": 3,
"m_Type": "UnityEditor.ShaderGraph.Internal.ColorShaderProperty",
"m_ObjectId": "5f2fa682a67d4b9bb3ce0c032b99524c",
"m_Guid": {
"m_GuidSerialized": "e3787be8-4877-4493-8455-7d929ee3a994"
},
"m_Name": "ShadowColor",
"m_DefaultRefNameVersion": 1,
"m_RefNameGeneratedByDisplayName": "ShadowColor",
"m_DefaultReferenceName": "_ShadowColor",
"m_OverrideReferenceName": "",
"m_GeneratePropertyBlock": true,
"m_UseCustomSlotLabel": false,
"m_CustomSlotLabel": "",
"m_DismissedVersion": 0,
"m_Precision": 0,
"overrideHLSLDeclaration": false,
"hlslDeclarationOverride": 0,
"m_Hidden": false,
"m_Value": {
"r": 0.0,
"g": 0.0,
"b": 0.0,
"a": 0.0
},
"isMainColor": false,
"m_ColorMode": 0
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot",
"m_ObjectId": "7459cf9619dd4269918e7e62a14828e4",
"m_Id": 0,
"m_DisplayName": "ShadowColor",
"m_SlotType": 1,
"m_Hidden": false,
"m_ShaderOutputName": "Out",
"m_StageCapability": 3,
"m_Value": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
},
"m_Labels": []
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.BlockNode",
"m_ObjectId": "745ea9abdb724f25952d4740bf30c020",
"m_Group": {
"m_Id": ""
},
"m_Name": "VertexDescription.Tangent",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": 0.0,
"y": 0.0,
"width": 0.0,
"height": 0.0
}
},
"m_Slots": [
{
"m_Id": "8be0770c35914fe2951ec373bae178ed"
}
],
"synonyms": [],
"m_Precision": 0,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 0,
"m_CustomColors": {
"m_SerializableColors": []
},
"m_SerializedDescriptor": "VertexDescription.Tangent"
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.BlockNode",
"m_ObjectId": "792ce8177b4b40f2b49db74b402ef06f",
"m_Group": {
"m_Id": ""
},
"m_Name": "VertexDescription.Normal",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": 0.0,
"y": 0.0,
"width": 0.0,
"height": 0.0
}
},
"m_Slots": [
{
"m_Id": "c900a2e48237468ba5e76c3677280076"
}
],
"synonyms": [],
"m_Precision": 0,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 0,
"m_CustomColors": {
"m_SerializableColors": []
},
"m_SerializedDescriptor": "VertexDescription.Normal"
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot",
"m_ObjectId": "8be0770c35914fe2951ec373bae178ed",
"m_Id": 0,
"m_DisplayName": "Tangent",
"m_SlotType": 0,
"m_Hidden": false,
"m_ShaderOutputName": "Tangent",
"m_StageCapability": 1,
"m_Value": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_Labels": [],
"m_Space": 0
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.BlockNode",
"m_ObjectId": "9a45fa2786da4e9a8880b2416e884c1f",
"m_Group": {
"m_Id": ""
},
"m_Name": "VertexDescription.Position",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": 0.0,
"y": 0.0,
"width": 0.0,
"height": 0.0
}
},
"m_Slots": [
{
"m_Id": "df25a6de5fd648879475811c09b1810a"
}
],
"synonyms": [],
"m_Precision": 0,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 0,
"m_CustomColors": {
"m_SerializableColors": []
},
"m_SerializedDescriptor": "VertexDescription.Position"
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot",
"m_ObjectId": "a8408df2e5c84a1380869614a19939c2",
"m_Id": 0,
"m_DisplayName": "worldPos",
"m_SlotType": 0,
"m_Hidden": false,
"m_ShaderOutputName": "worldPos",
"m_StageCapability": 3,
"m_Value": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_Labels": []
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot",
"m_ObjectId": "c900a2e48237468ba5e76c3677280076",
"m_Id": 0,
"m_DisplayName": "Normal",
"m_SlotType": 0,
"m_Hidden": false,
"m_ShaderOutputName": "Normal",
"m_StageCapability": 1,
"m_Value": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_Labels": [],
"m_Space": 0
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot",
"m_ObjectId": "d364eb86aab34fd08179bcb500ede32c",
"m_Id": 1,
"m_DisplayName": "Out",
"m_SlotType": 1,
"m_Hidden": false,
"m_ShaderOutputName": "Out",
"m_StageCapability": 3,
"m_Value": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 0.0
}
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.OneMinusNode",
"m_ObjectId": "dc71a03354764aa4b2793dcec9e02920",
"m_Group": {
"m_Id": ""
},
"m_Name": "One Minus",
"m_DrawState": {
"m_Expanded": true,
"m_Position": {
"serializedVersion": "2",
"x": -487.0000305175781,
"y": 262.0000305175781,
"width": 208.0,
"height": 277.9999694824219
}
},
"m_Slots": [
{
"m_Id": "26741a9638224fc6bcd1bfa42507da22"
},
{
"m_Id": "d364eb86aab34fd08179bcb500ede32c"
}
],
"synonyms": [
"complement",
"invert",
"opposite"
],
"m_Precision": 0,
"m_PreviewExpanded": true,
"m_DismissedVersion": 0,
"m_PreviewMode": 0,
"m_CustomColors": {
"m_SerializableColors": []
}
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot",
"m_ObjectId": "df25a6de5fd648879475811c09b1810a",
"m_Id": 0,
"m_DisplayName": "Position",
"m_SlotType": 0,
"m_Hidden": false,
"m_ShaderOutputName": "Position",
"m_StageCapability": 1,
"m_Value": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_Labels": [],
"m_Space": 0
}
{
"m_SGVersion": 1,
"m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalTarget",
"m_ObjectId": "e36cc0dd20a44f22923e392b9bfccc84",
"m_Datas": [],
"m_ActiveSubTarget": {
"m_Id": "16533883a7c0489eaecf612ab54498ff"
},
"m_AllowMaterialOverride": false,
"m_SurfaceType": 1,
"m_ZTestMode": 4,
"m_ZWriteControl": 0,
"m_AlphaMode": 0,
"m_RenderFace": 0,
"m_AlphaClip": false,
"m_CastShadows": false,
"m_ReceiveShadows": false,
"m_SupportsLODCrossFade": false,
"m_CustomEditorGUI": "",
"m_SupportVFX": false
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.CategoryData",
"m_ObjectId": "fbc63f3198b944c0ae62acc54dfb7583",
"m_Name": "",
"m_ChildObjectList": [
{
"m_Id": "5f2fa682a67d4b9bb3ce0c032b99524c"
}
]
}
{
"m_SGVersion": 0,
"m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot",
"m_ObjectId": "fe302a6ca1e9493d92edbeb37dd9d398",
"m_Id": 0,
"m_DisplayName": "Out",
"m_SlotType": 1,
"m_Hidden": false,
"m_ShaderOutputName": "Out",
"m_StageCapability": 3,
"m_Value": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_DefaultValue": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"m_Labels": []
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 2653b59b7388e4f53806f4ab964d71c8
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Resources/Umbra/Shaders/Transparent
Receiver/ShadowReceiverTransparent.shadergraph
uploadId: 868458

View File

@@ -0,0 +1,136 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Transparent Floor
m_Shader: {fileID: -6465566751694194690, guid: 2653b59b7388e4f53806f4ab964d71c8, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_InvalidKeywords: []
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: 3000
stringTagMap: {}
disabledShaderPasses:
- MOTIONVECTORS
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_Lightmaps:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_LightmapsInd:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- unity_ShadowMasks:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Ints: []
m_Floats:
- _AlphaClip: 0
- _AlphaToMask: 0
- _Blend: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _Cull: 2
- _Cutoff: 0.5
- _DetailAlbedoMapScale: 1
- _DetailNormalMapScale: 1
- _DstBlend: 10
- _DstBlendAlpha: 10
- _EnvironmentReflections: 1
- _GlossMapScale: 0
- _Glossiness: 0
- _GlossyReflections: 0
- _Metallic: 0
- _OcclusionStrength: 1
- _Parallax: 0.005
- _QueueControl: 0
- _QueueOffset: 0
- _ReceiveShadows: 0
- _Smoothness: 0.5
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 1
- _WorkflowMode: 1
- _ZWrite: 0
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _ShadowColor: {r: 0.028301895, g: 0.028301895, b: 0.028301895, a: 1}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
m_BuildTextureStacks: []
m_AllowLocking: 1
--- !u!114 &4464394433452166678
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 10

View File

@@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: a2dfb70d5172b43e29db28656b0948e5
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Resources/Umbra/Shaders/Transparent
Receiver/Transparent Floor.mat
uploadId: 868458

View File

@@ -0,0 +1,219 @@
Shader "Hidden/Kronnect/UmbraScreenSpaceShadows"
{
Properties {
// _MainTex ("Main Tex", 2D) = "white" {}
// _Color ("Color", Color) = (1, 1, 1, 1)
[NoScaleoffset] _NoiseTex("Noise Tex", 2D) = "white" {}
_ContactShadowsBlend ("Contact Shadows Blend", Int) = 10 // OneMinusSrcAlpha
}
SubShader
{
Tags{ "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True"}
ZTest Always ZWrite Off Cull Off
HLSLINCLUDE
#pragma target 3.0
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl"
#include "Common.hlsl"
ENDHLSL
Pass
{
Name "Umbra Shadows"
HLSLPROGRAM
#pragma multi_compile _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma multi_compile_local_fragment _ _NORMALS_TEXTURE
#pragma multi_compile_local_fragment _ _CONTACT_HARDENING
#pragma multi_compile_local_fragment _ _LOOP_STEP_X2 _LOOP_STEP_X3
#pragma multi_compile_local_fragment _ _MASK_TEXTURE
#pragma multi_compile_local_fragment _ _RECEIVER_PLANE
#pragma vertex Vert
#pragma fragment FragCast
#include "ShadowCast.hlsl"
ENDHLSL
}
Pass
{
Name "Blur Horiz"
HLSLPROGRAM
#pragma multi_compile_local_fragment _ _BLUR_HQ
#pragma multi_compile_local_fragment _ _CONTACT_HARDENING
#pragma vertex VertBlur
#pragma fragment FragBlurGaussian
#include "ShadowBlur.hlsl"
ENDHLSL
}
Pass
{
Name "Blur Vert"
HLSLPROGRAM
#pragma multi_compile_local_fragment _ _BLUR_HQ
#pragma multi_compile_local_fragment _ _CONTACT_HARDENING
#pragma vertex VertBlur
#pragma fragment FragBlurGaussian
#define BLUR_VERT
#include "ShadowBlur.hlsl"
ENDHLSL
}
Pass
{
Name "Box Blur"
HLSLPROGRAM
#pragma multi_compile_local_fragment _ _CONTACT_HARDENING
#pragma vertex VertSimple
#pragma fragment FragBlurBox
#define BOX_BLUR
#include "ShadowBlur.hlsl"
ENDHLSL
}
Pass
{
Name "Compose with Blending"
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma multi_compile_local_fragment _ _PRESERVE_EDGES
#pragma multi_compile_local_fragment _ _NORMALS_TEXTURE
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma vertex VertSimple
#pragma fragment FragCompose
#define COMPOSE_WITH_BLENDING
#include "ShadowBlur.hlsl"
ENDHLSL
}
Pass
{
Name "Downsample Depth"
HLSLPROGRAM
#pragma vertex VertSimple
#pragma fragment FragDownsampleDepth
#include "ShadowBlur.hlsl"
ENDHLSL
}
Pass
{
Name "Umbra Cascade Blending"
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma multi_compile _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
#pragma multi_compile_local_fragment _ _NORMALS_TEXTURE
#pragma multi_compile_local_fragment _ _CONTACT_HARDENING
#pragma multi_compile_local_fragment _ _LOOP_STEP_X2 _LOOP_STEP_X3
#pragma multi_compile_local_fragment _ _MASK_TEXTURE
#define _BLEND_CASCADE
#pragma vertex Vert
#pragma fragment FragCast
#include "ShadowCast.hlsl"
ENDHLSL
}
Pass
{
Name "ScreenSpaceShadows"
HLSLPROGRAM
#pragma multi_compile _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH
#pragma vertex Vert
#pragma fragment FragUnityShadows
#include "ShadowCast.hlsl"
ENDHLSL
}
Pass
{
Name "Compose Unity Shadows"
HLSLPROGRAM
#pragma multi_compile_local_fragment _ _PRESERVE_EDGES
#pragma vertex VertSimple
#pragma fragment FragComposeUnity
#include "ShadowBlur.hlsl"
ENDHLSL
}
Pass
{
Name "Contact Shadows"
Blend One One
BlendOp Min
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment FragContactShadows
#pragma multi_compile_local_fragment _ _LOOP_STEP_X2 _LOOP_STEP_X3
#pragma multi_compile_local_fragment _ _NORMALS_TEXTURE
#pragma multi_compile_local_fragment _ _RECEIVER_PLANE
#pragma multi_compile_local_fragment _ _USE_POINT_LIGHT
#pragma multi_compile_local_fragment _ _SOFT_EDGES
#include "ContactShadows.hlsl"
ENDHLSL
}
Pass
{
Name "Compose"
HLSLPROGRAM
#pragma multi_compile_local_fragment _ _PRESERVE_EDGES
#pragma vertex VertSimple
#pragma fragment FragCompose
#include "ShadowBlur.hlsl"
ENDHLSL
}
Pass
{
Name "Debug Shadows"
HLSLPROGRAM
#pragma multi_compile_local_fragment _ _PRESERVE_EDGES
#pragma vertex Vert
#pragma fragment FragDebugShadows
#include "ShadowBlur.hlsl"
ENDHLSL
}
Pass
{
Name "Contact Shadows After Opaque"
Blend SrcAlpha [_ContactShadowsBlend]
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment FragContactShadows
#pragma multi_compile_local_fragment _ _LOOP_STEP_X2 _LOOP_STEP_X3
#pragma multi_compile_local_fragment _ _NORMALS_TEXTURE
#pragma multi_compile_local_fragment _ _RECEIVER_PLANE
#pragma multi_compile_local_fragment _ _USE_POINT_LIGHT
#pragma multi_compile_local_fragment _ _SOFT_EDGES
#define CONTACT_SHADOWS_AFTER_OPAQUE
#include "ContactShadows.hlsl"
ENDHLSL
}
Pass
{
Name "Overlay Shadows"
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment FragOverlayShadows
#include "ShadowBlur.hlsl"
ENDHLSL
}
}
}

View File

@@ -0,0 +1,17 @@
fileFormatVersion: 2
guid: d461f5567983941438cff09455e8b8f4
ShaderImporter:
externalObjects: {}
defaultTextures:
- _BlueNoise: {fileID: 2800000, guid: e48811f1a66574b199fbc047d7139f79, type: 3}
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Resources/Umbra/Shaders/UmbraScreenSpaceShadows.shader
uploadId: 868458

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2b377dac2021c4e30923e01c90299f79
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,147 @@
fileFormatVersion: 2
guid: 32293bd0d9827458cb949a5cc32b3027
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 0
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 0
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 1
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 1
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Server
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Resources/Umbra/Textures/NoiseTex.png
uploadId: 868458

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 728e006b190ca466b95d89b38279a52f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,75 @@
using System.Collections.Generic;
using UnityEngine;
namespace Umbra {
[RequireComponent(typeof(Light))]
[ExecuteAlways]
[HelpURL("https://kronnect.com/docs/umbra/")]
public class UmbraPointLightContactShadows : MonoBehaviour {
public BoxCollider boxCollider;
public float fadeDistance = 1f;
public static readonly Dictionary<Light, UmbraPointLightContactShadows> umbraPointLights = new Dictionary<Light, UmbraPointLightContactShadows>();
Light attachedLight;
void OValidate () {
fadeDistance = Mathf.Max(fadeDistance, 0f);
}
private void OnEnable() {
attachedLight = GetComponent<Light>();
if (attachedLight == null) {
Debug.LogError("UmbraPointLightContactShadows requires a Light component on the same GameObject.");
return;
}
if (attachedLight.type != LightType.Point) {
Debug.LogWarning("UmbraPointLightContactShadows is designed for Point lights but found " + attachedLight.type + " light.");
return;
}
// Initialize or get the BoxCollider
boxCollider = GetComponent<BoxCollider>();
if (boxCollider == null) {
boxCollider = gameObject.AddComponent<BoxCollider>();
boxCollider.isTrigger = true;
boxCollider.size = Vector3.one * 20f;
}
umbraPointLights[attachedLight] = this;
}
private void OnDisable() {
if (attachedLight != null) {
umbraPointLights.Remove(attachedLight);
}
}
/// <summary>
/// Check if a world position is inside this point light's volume
/// </summary>
/// <param name="worldPosition">World space position to check</param>
/// <returns>True if the position is inside the volume</returns>
public float ComputeVolumeFade(Vector3 worldPosition) {
if (boxCollider == null) return 0;
Bounds bounds = boxCollider.bounds;
Vector3 diff = bounds.center - worldPosition;
diff.x = diff.x < 0 ? -diff.x : diff.x;
diff.y = diff.y < 0 ? -diff.y : diff.y;
diff.z = diff.z < 0 ? -diff.z : diff.z;
Vector3 gap = diff - bounds.extents;
float maxDiff = gap.x > gap.y ? gap.x : gap.y;
maxDiff = maxDiff > gap.z ? maxDiff : gap.z;
return 1f - Mathf.Clamp01(maxDiff / (fadeDistance + 0.0001f));
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Scripts/UmbraPointLightContactShadows.cs
uploadId: 868458

View File

@@ -0,0 +1,351 @@
using UnityEngine;
namespace Umbra {
public enum ShadowSource {
UnityShadows,
UmbraShadows,
OnlyContactShadows
}
public enum ContactShadowsInjectionPoint {
ShadowTexture,
AfterOpaque
}
public enum UmbraPreset {
[InspectorName("")]
None = 0,
Hard = 10,
Soft = 20,
Smooth = 30,
ExtraSmooth = 40,
Blurred = 50,
Fast = 60
}
public enum BlurType {
[InspectorName("Gaussian (15 taps, 2 passes)")]
Gaussian15 = 10,
[InspectorName("Gaussian (5 taps, 2 passes)")]
Gaussian5 = 20,
[InspectorName("Box Blur (9 taps, 1 pass)")]
Box = 30
}
public enum NormalSource {
ReconstructFromDepth,
NormalsPass,
[InspectorName("GBuffer Normals")]
GBufferNormals
}
public enum LoopStep {
Default,
x2,
x3
}
public enum Style {
Default,
Textured
}
[CreateAssetMenu(fileName = "UmbraProfile", menuName = "Umbra Profile", order = 251)]
[HelpURL("https://kronnect.com/docs/umbra/")]
public class UmbraProfile : ScriptableObject {
[Tooltip("Which shadow generation system should be used")]
public ShadowSource shadowSource = ShadowSource.UmbraShadows;
[Tooltip("Translates to the number of shadow map samples used to resolve shadows")]
[Range(1, 64)]
public int sampleCount = 16;
[Tooltip("Number of samples to early out if shadow is already fully resolved")]
[Range(1, 64)]
public int earlyOutSamples = 32;
[Tooltip("Size of the directional light which influences the penumbra size")]
[Range(0f, 32)]
public float lightSize = 6;
[Tooltip("Makes shadows sharper nearer to the occluder")]
public bool enableContactHardening = true;
[Tooltip("Makes shadows sharper and stronger near the occluder")]
[Range(0, 1)]
public float contactStrength = 0.5f;
[Tooltip("Usual value is 5. Modify to alter the shadow edge appearance.")]
public float contactStrengthKnee = 0.0001f;
[Tooltip("Makes shadows smoother when far from occluder")]
[Range(1, 16)]
public float distantSpread = 1f;
[Tooltip("Number of shadow map samples to find occluders which improve the penumbra radius calculation")]
[Range(1, 64)]
public int occludersCount = 8;
[Tooltip("Multiplier to the occluder search radius in texture space. A higher value creates more diffused penumbra.")]
public float occludersSearchRadius = 8f;
[Tooltip("Number of blur passes. Each blur pass increases shadow softness but reduces performance.")]
[Range(0, 3)]
public int blurIterations;
[Tooltip("Specifies the blur method. Gaussian blur uses two passes per iteration and produces smoother results.")]
public BlurType blurType = BlurType.Gaussian15;
[Tooltip("Blur kerner radius multiplier. Improves softness but can introduce artifacts")]
[Range(0.5f, 5)]
public float blurSpread = 1f;
[Tooltip("Increases the contrast on the shadow border to create sharper shadows when blur is used")]
[Range(0, 1)]
public float blurEdgeSharpness;
[Tooltip("Strength of the edge weight when blurring")]
public float blurEdgeTolerance = 5f;
[Tooltip("Reduces blur on distance from camera")]
public float blurDepthAttenStart = 50;
[Tooltip("Blur reduction intensity")]
public float blurDepthAttenLength = 50;
[Tooltip("Blur reduction when viewing shadow from a grazing angle")]
[Range(0, 1)]
public float blurGrazingAttenuation;
public bool blendCascades;
[Range(1, 10)]
public int posterization = 1;
public float cascade1BlendingStrength = 0.1f;
public float cascade2BlendingStrength = 0.1f;
public float cascade3BlendingStrength = 0.1f;
[Tooltip("Manual adjustment of shadow smoothness multiplier for this cascade")]
public float cascade1Scale = 1f;
[Tooltip("Manual adjustment of shadow smoothness multiplier for this cascade")]
public float cascade2Scale = 1f;
[Tooltip("Manual adjustment of shadow smoothness multiplier for this cascade")]
public float cascade3Scale = 1f;
[Tooltip("Manual adjustment of shadow smoothness multiplier for this cascade")]
public float cascade4Scale = 1f;
[Tooltip("Method used to obtain surface normals. Reconstruct from depth is fastest, normals pass is more accurate, and GBuffer normals (deferred only) uses existing GBuffer data.")]
public NormalSource normalsSource = NormalSource.ReconstructFromDepth;
/// <summary>
/// Gets the effective normals source, falling back to ReconstructFromDepth when GBufferNormals is selected but not in deferred mode
/// </summary>
public NormalSource effectiveNormalsSource =>
normalsSource == NormalSource.GBufferNormals && !UmbraSoftShadows.isDeferred
? NormalSource.ReconstructFromDepth
: normalsSource;
[Tooltip("Reduces the number of samples while keeping the shadow size")]
public LoopStep loopStepOptimization = LoopStep.Default;
[Tooltip("Resolves shadowmap every two frames, reusing the result from previous frame")]
public bool frameSkipOptimization;
[Tooltip("Distance threshold - if camera has moved this distance from previous frame, ignore cached shadowmap")]
public float skipFrameMaxCameraDisplacement = 0.1f;
[Tooltip("Rotation threshold - if camera has rotated this angle from previous frame, ignore cached shadowmap")]
public float skipFrameMaxCameraRotation = 5f;
[Tooltip("Resolves screen space shadows in a reduced buffer of half of screen size")]
public bool downsample;
[Tooltip("Forces a depth prepass so depth and normals are available even for forward-only materials (useful in Deferred when using forward only materials).")]
public bool forceDepthPrepass;
[Tooltip("Prevents shadow blurring on geometry edges")]
public bool preserveEdges = true;
[Tooltip("Stylized look for shadows")]
public Style style = Style.Default;
[Tooltip("Optional mask texture to create stylized shadows")]
public Texture2D maskTexture;
public float maskScale = 1f;
public bool contactShadows;
[Range(0, 1)]
public float contactShadowsIntensityMultiplier = 0.85f;
public ContactShadowsInjectionPoint contactShadowsInjectionPoint = ContactShadowsInjectionPoint.ShadowTexture;
public ContactShadowsInjectionPoint actualContactShadowsInjectionPoint => shadowSource == ShadowSource.OnlyContactShadows || contactShadowsInjectionPoint == ContactShadowsInjectionPoint.AfterOpaque ? ContactShadowsInjectionPoint.AfterOpaque : contactShadowsInjectionPoint;
[Range(1, 64)]
public int contactShadowsSampleCount = 16;
public float contactShadowsStepping = 0.01f;
public float contactShadowsThicknessNear = 0.5f;
public float contactShadowsThicknessDistanceMultiplier;
public float contactShadowsJitter = 0.3f;
[Range(0, 1)]
[Tooltip("Attenuates shadow intensity with distance to occluder")]
public float contactShadowsDistanceFade = 0.75f;
public float contactShadowsStartDistance;
public float contactShadowsStartDistanceFade = 0.01f;
[Tooltip("Adds an offset to the pixel position to avoid self-occlusion")]
[Range(0.0001f, 0.25f)]
public float contactShadowsNormalBias = 0.1f;
[Tooltip("Attenuates contact shadows on the edges of screen")]
[Range(0, 0.5f)]
public float contactShadowsVignetteSize = 0.15f;
[Tooltip("Adds an offset to the pixel position to avoid self-occlusion")]
[Range(0f, 1f)]
public float contactShadowsBias = 0.001f;
[Tooltip("Bias applied at far distances. Use only if self-shadowing occurs on certain surfaces.")]
[Range(0, 1)]
public float contactShadowsBiasFar = 0.4f;
[Tooltip("Softens the edges of contact shadows. Higher values create softer edges.")]
[Range(0.01f, 0.5f)]
public float contactShadowsEdgeSoftness = 0.1f;
[Tooltip("Enables soft edges for contact shadows. When disabled, shadows have hard edges for better performance.")]
public bool contactShadowsSoftEdges;
[Tooltip("Makes contact shadows planar by ignoring the Y component of the light direction. Useful for ground shadows.")]
public bool contactShadowsPlanarShadows;
[Tooltip("Adds an extra pass after opaque with custom colored shadows")]
public bool overlayShadows;
public float overlayShadowsIntensity = 0.5f;
[ColorUsage(showAlpha: false, hdr: false)]
public Color overlayShadowsColor = Color.black;
[Tooltip("Enables a receiver plane to cast shadows from transparent objects. Check demo scene Transparent Receiver for an example.")]
public bool transparentReceiverPlane;
public float receiverPlaneAltitude;
void OnValidate() {
blurDepthAttenLength = Mathf.Max(0.001f, blurDepthAttenLength);
blurEdgeTolerance = Mathf.Max(0, blurEdgeTolerance);
blurDepthAttenStart = Mathf.Max(0, blurDepthAttenStart);
blurDepthAttenLength = Mathf.Max(0, blurDepthAttenLength);
blurGrazingAttenuation = Mathf.Max(0, blurGrazingAttenuation);
occludersSearchRadius = Mathf.Max(0.01f, occludersSearchRadius);
contactStrengthKnee = Mathf.Max(0.0001f, contactStrengthKnee);
cascade1BlendingStrength = Mathf.Max(0.01f, cascade1BlendingStrength);
cascade2BlendingStrength = Mathf.Max(0.01f, cascade2BlendingStrength);
cascade3BlendingStrength = Mathf.Max(0.01f, cascade3BlendingStrength);
cascade1Scale = Mathf.Max(0, cascade1Scale);
cascade2Scale = Mathf.Max(0, cascade2Scale);
cascade3Scale = Mathf.Max(0, cascade3Scale);
cascade4Scale = Mathf.Max(0, cascade4Scale);
maskScale = Mathf.Max(maskScale, 0);
skipFrameMaxCameraRotation = Mathf.Max(skipFrameMaxCameraRotation, 0);
skipFrameMaxCameraDisplacement = Mathf.Max(skipFrameMaxCameraDisplacement, 0);
contactShadowsStepping = Mathf.Max(0.0001f, contactShadowsStepping);
contactShadowsThicknessNear = Mathf.Max(0.0f, contactShadowsThicknessNear);
contactShadowsThicknessDistanceMultiplier = Mathf.Max(0.0f, contactShadowsThicknessDistanceMultiplier);
contactShadowsJitter = Mathf.Max(0f, contactShadowsJitter);
contactShadowsStartDistance = Mathf.Max(0, contactShadowsStartDistance);
contactShadowsStartDistanceFade = Mathf.Max(0.00001f, contactShadowsStartDistanceFade);
overlayShadowsIntensity = Mathf.Max(0, overlayShadowsIntensity);
}
public void ApplyPreset(UmbraPreset preset) {
shadowSource = ShadowSource.UmbraShadows;
switch (preset) {
case UmbraPreset.Fast:
sampleCount = 12;
lightSize = 12;
occludersCount = 6;
occludersSearchRadius = 5f;
enableContactHardening = true;
contactStrength = 0.5f;
contactStrengthKnee = 0.0001f;
blurIterations = 0;
distantSpread = 1f;
break;
case UmbraPreset.Hard:
sampleCount = 1;
lightSize = 0.5f;
enableContactHardening = false;
blurIterations = 1;
blurType = BlurType.Box;
blurSpread = 1f;
blurEdgeTolerance = 5f;
blurEdgeSharpness = 1f;
blurDepthAttenStart = 75;
blurDepthAttenLength = 50;
blurGrazingAttenuation = 0;
break;
case UmbraPreset.Soft:
sampleCount = 16;
lightSize = 8;
enableContactHardening = true;
occludersCount = 8;
occludersSearchRadius = 8f;
contactStrength = 0.5f;
contactStrengthKnee = 0.0001f;
distantSpread = 1f;
blurIterations = 0;
break;
case UmbraPreset.Smooth:
sampleCount = 16;
lightSize = 13;
enableContactHardening = true;
occludersCount = 9;
occludersSearchRadius = 8f;
contactStrength = 0.5f;
contactStrengthKnee = 0.0001f;
distantSpread = 1.2f;
blurIterations = 0;
break;
case UmbraPreset.ExtraSmooth:
sampleCount = 20;
lightSize = 16;
enableContactHardening = true;
occludersCount = 16;
occludersSearchRadius = 10;
contactStrength = 0.8f;
contactStrengthKnee = 0.0001f;
distantSpread = 1.4f;
blurIterations = 0;
break;
case UmbraPreset.Blurred:
sampleCount = 32;
lightSize = 16;
enableContactHardening = true;
occludersCount = 24;
occludersSearchRadius = 16;
contactStrength = 0.4f;
contactStrengthKnee = 0.0001f;
blurIterations = 0;
distantSpread = 2f;
break;
}
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 6751c6668ce8047e5bcc50f8586c1fe7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Scripts/UmbraProfile.cs
uploadId: 868458

View File

@@ -0,0 +1,484 @@
#if UNITY_2023_3_OR_NEWER
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule;
using System.Collections.Generic;
namespace Umbra {
internal partial class UmbraRenderFeature : ScreenSpaceShadows {
private partial class UmbraScreenSpaceShadowsPass : ScriptableRenderPass {
class PassData {
public UmbraScreenSpaceShadowsPass pass;
public UniversalShadowData shadowData;
public UniversalLightData lightData;
public UniversalCameraData cameraData;
public UniversalRenderingData renderingData;
public TextureHandle rtCameraDepthTexture;
public TextureHandle rtCameraNormalsTexture;
}
public override void RecordRenderGraph (RenderGraph renderGraph, ContextContainer frameData) {
if (mat == null) {
Debug.LogError("Umbra material not initialized");
return;
}
using (var builder = renderGraph.AddUnsafePass<PassData>("Umbra Soft Shadows", out var passData, m_ProfilingSampler)) {
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
desc = cameraData.cameraTargetDescriptor;
desc.depthBufferBits = 0;
desc.msaaSamples = 1;
desc.graphicsFormat = screenShadowTextureFormat;
UmbraProfile profile = settings.profile;
if (profile.downsample && !profile.preserveEdges) {
desc.width /= 2;
desc.height /= 2;
}
Camera cam = cameraData.camera;
#if UNITY_EDITOR
if (profile.frameSkipOptimization && Application.isPlaying) {
#else
if (profile.frameSkipOptimization) {
#endif
newShadowmap = !shadowTextures.TryGetValue(cam, out m_RenderTarget);
}
if (RenderingUtils.ReAllocateHandleIfNeeded(ref m_RenderTarget, desc, FilterMode.Point, TextureWrapMode.Clamp, name: "_ScreenSpaceShadowmapTexture")) {
newShadowmap = true;
}
if (newShadowmap) {
shadowTextures[cam] = m_RenderTarget;
}
builder.AllowGlobalStateModification(true);
#if UNITY_6000_0_OR_NEWER
TextureHandle shadowmap = renderGraph.ImportTexture(m_RenderTarget, new RenderTargetInfo {
width = desc.width,
height = desc.height,
volumeDepth = 1,
msaaSamples = 1,
format = desc.graphicsFormat
});
#else
TextureHandle shadowmap = renderGraph.ImportTexture(m_RenderTarget);
#endif
builder.UseTexture(shadowmap, AccessFlags.ReadWrite);
if (UmbraSoftShadows.isDeferred && resourceData.gBuffer[2].IsValid()) {
passData.rtCameraNormalsTexture = resourceData.gBuffer[2];
builder.UseTexture(passData.rtCameraNormalsTexture, AccessFlags.Read);
}
passData.rtCameraDepthTexture = resourceData.cameraDepthTexture;
builder.UseTexture(resourceData.cameraDepthTexture, AccessFlags.Read);
if ((input & ScriptableRenderPassInput.Normal) != 0) {
builder.UseTexture(resourceData.cameraNormalsTexture, AccessFlags.Read);
}
passData.pass = this;
passData.cameraData = cameraData;
passData.lightData = frameData.Get<UniversalLightData>();
passData.shadowData = frameData.Get<UniversalShadowData>();
passData.renderingData = frameData.Get<UniversalRenderingData>();
builder.SetRenderFunc(static (PassData data, UnsafeGraphContext rgContext) => {
if (data.rtCameraDepthTexture.IsValid()) {
mat.SetTexture(ShaderParams.CameraDepthTexture, data.rtCameraDepthTexture);
}
if (data.rtCameraNormalsTexture.IsValid()) {
mat.SetTexture(ShaderParams.CameraNormalsTexture, data.rtCameraNormalsTexture);
}
CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd);
cmd.SetGlobalTexture(m_RenderTarget.name, m_RenderTarget.nameID);
ExecutePass(cmd, data);
});
}
}
static void ExecutePass (CommandBuffer cmd, PassData passData) {
UmbraProfile profile = settings.profile;
int frameCount = Time.frameCount;
#if UNITY_EDITOR
bool useFrame = !Application.isPlaying || !profile.frameSkipOptimization || newShadowmap || !usesCachedShadowmap;
#else
bool useFrame = !profile.frameSkipOptimization || newShadowmap || !usesCachedShadowmap;
#endif
if (useFrame) {
cachedShadowmapTimestap = frameCount;
newShadowmap = false;
RTHandle shadowsHandle;
if (profile.downsample && profile.preserveEdges) {
desc.width /= 2;
desc.height /= 2;
#if UNITY_6000_0_OR_NEWER
RenderingUtils.ReAllocateHandleIfNeeded(ref m_DownscaledRenderTarget, desc, FilterMode.Point, TextureWrapMode.Clamp);
#else
RenderingUtils.ReAllocateIfNeeded(ref m_DownscaledRenderTarget, desc, FilterMode.Point, TextureWrapMode.Clamp);
#endif
shadowsHandle = m_DownscaledRenderTarget;
}
else {
shadowsHandle = m_RenderTarget;
}
float farClipPlane = passData.cameraData.camera.farClipPlane;
int cascadeCount = passData.shadowData.mainLightShadowCascadesCount;
UniversalRenderPipelineAsset urpAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
float shadowMaxDistance = urpAsset.shadowDistance;
Pass castShadowsPass;
if (profile.shadowSource == ShadowSource.UnityShadows) {
castShadowsPass = Pass.UnityShadows;
}
else {
castShadowsPass = Pass.UmbraCastShadows;
if (profile.transparentReceiverPlane) {
mat.EnableKeyword(ShaderParams.SKW_RECEIVER_PLANE);
cmd.SetGlobalFloat(ShaderParams.ReceiverPlaneAltitude, profile.receiverPlaneAltitude);
}
else {
mat.DisableKeyword(ShaderParams.SKW_RECEIVER_PLANE);
}
cmd.SetGlobalVector(ShaderParams.ShadowData, new Vector4(profile.sampleCount, 1024 / Mathf.Pow(2, profile.posterization), profile.blurEdgeTolerance * 1000f, (profile.blurDepthAttenStart + profile.blurDepthAttenLength) / farClipPlane));
float shadowMaxDepth = profile.transparentReceiverPlane ? 2 : shadowMaxDistance / farClipPlane;
cmd.SetGlobalVector(ShaderParams.ShadowData2, new Vector4(1f - profile.contactStrength, profile.distantSpread, shadowMaxDepth, profile.lightSize * 0.02f));
cmd.SetGlobalVector(ShaderParams.ShadowData3, new Vector4(profile.blurDepthAttenStart / farClipPlane, profile.blurDepthAttenLength / farClipPlane, profile.blurGrazingAttenuation, profile.blurEdgeSharpness));
cmd.SetGlobalVector(ShaderParams.ShadowData4, new Vector4(profile.occludersCount, profile.occludersSearchRadius * 0.02f, profile.contactStrength > 0 ? profile.contactStrengthKnee * 0.1f : 0.00001f, profile.maskScale));
cmd.SetGlobalVector(ShaderParams.SourceSize, new Vector4(desc.width, desc.height, 0, 0));
cmd.SetGlobalInt(ShaderParams.EarlyOutSamples, profile.earlyOutSamples);
if (cascadeCount > 1) {
VisibleLight shadowLight = passData.lightData.visibleLights[shadowLightIndex];
float shadowNearPlane = shadowLight.light.shadowNearPlane;
for (int k = 0; k < cascadeCount; k++) {
passData.renderingData.cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
k, cascadeCount, passData.shadowData.mainLightShadowCascadesSplit, urpAsset.mainLightShadowmapResolution, shadowNearPlane, out _, out Matrix4x4 proj,
out _);
Matrix4x4 invProj = proj.inverse;
autoCascadeScales[k] = Mathf.Abs(invProj.MultiplyPoint(ShaderParams.Vector3Back).z - invProj.MultiplyPoint(ShaderParams.Vector3Forward).z) / 100f;
}
Vector4[] cascadeRectsTemp = cascadeRectsWithPadding[cascadeCount - 1];
float texel = 1f / urpAsset.mainLightShadowmapResolution;
float padding = texel;
for (int c = 0; c < 4; c++) {
Vector4 defaultRect = cascadeRects[cascadeCount - 1][c];
Vector4 rect = cascadeRectsTemp[c];
rect.x = defaultRect.x + padding;
rect.y = defaultRect.y + padding;
rect.z = defaultRect.z - padding;
rect.w = defaultRect.w - padding;
cascadeRectsTemp[c] = rect;
}
cmd.SetGlobalVectorArray(ShaderParams.UmbraCascadeRects, cascadeRectsTemp);
cascadeScales[0] = profile.cascade1Scale * autoCascadeScales[0];
cascadeScales[1] = profile.cascade2Scale * autoCascadeScales[1];
cascadeScales[2] = profile.cascade3Scale * autoCascadeScales[2];
cascadeScales[3] = profile.cascade4Scale * autoCascadeScales[3];
cmd.SetGlobalFloatArray(ShaderParams.UmbraCascadeScales, cascadeScales);
}
if ((UmbraSoftShadows.isDeferred && profile.normalsSource == NormalSource.GBufferNormals) || profile.effectiveNormalsSource == NormalSource.NormalsPass || profile.downsample) {
mat.EnableKeyword(ShaderParams.SKW_NORMALS_TEXTURE);
}
else {
mat.DisableKeyword(ShaderParams.SKW_NORMALS_TEXTURE);
}
#if !UNITY_WEBGL
if (profile.enableContactHardening) {
mat.EnableKeyword(ShaderParams.SKW_CONTACT_HARDENING);
}
else
#endif
{
mat.DisableKeyword(ShaderParams.SKW_CONTACT_HARDENING);
}
mat.DisableKeyword(ShaderParams.SKW_LOOP_STEP_X3);
mat.DisableKeyword(ShaderParams.SKW_LOOP_STEP_X2);
if (profile.loopStepOptimization == LoopStep.x3) {
mat.EnableKeyword(ShaderParams.SKW_LOOP_STEP_X3);
}
else if (profile.loopStepOptimization == LoopStep.x2) {
mat.EnableKeyword(ShaderParams.SKW_LOOP_STEP_X2);
}
if (profile.style == Style.Textured && profile.maskTexture != null) {
mat.EnableKeyword(ShaderParams.SKW_MASK_TEXTURE);
mat.SetTexture(ShaderParams.MaskTexture, profile.maskTexture);
}
else {
mat.DisableKeyword(ShaderParams.SKW_MASK_TEXTURE);
}
}
// Resolve screen space shadows
Blitter.BlitCameraTexture(cmd, m_RenderTarget, shadowsHandle, mat, (int)castShadowsPass);
// Blend cascades 0 & 1
if (profile.shadowSource == ShadowSource.UmbraShadows) {
if (profile.blendCascades && cascadeCount > 1) {
cmd.SetGlobalVector(ShaderParams.BlendCascadeData, new Vector4(profile.cascade1BlendingStrength * 100f, profile.cascade2BlendingStrength * 100f, profile.cascade3BlendingStrength * 100f, 1f));
Blitter.BlitCameraTexture(cmd, shadowsHandle, shadowsHandle, mat, (int)Pass.CascadeBlending);
}
}
// Add contact shadows
if (profile.contactShadows && SetupContactShadowsMaterial(passData.cameraData.camera, profile, mat)) {
if (!settings.debugShadows && profile.actualContactShadowsInjectionPoint == ContactShadowsInjectionPoint.ShadowTexture) {
Blitter.BlitCameraTexture(cmd, shadowsHandle, shadowsHandle, mat, (int)Pass.ContactShadows);
}
}
// Downscale depth for upscaler
if (profile.downsample && profile.preserveEdges) {
RenderTextureDescriptor downscampledDepthDesc = desc;
downscampledDepthDesc.colorFormat = RenderTextureFormat.RFloat;
cmd.GetTemporaryRT(ShaderParams.DownsampledDepth, downscampledDepthDesc);
FullScreenBlit(cmd, ShaderParams.DownsampledDepth, mat, (int)Pass.DownsampledDepth);
mat.EnableKeyword(ShaderParams.SKW_PRESERVE_EDGES);
}
else {
mat.DisableKeyword(ShaderParams.SKW_PRESERVE_EDGES);
}
if (profile.shadowSource == ShadowSource.UnityShadows) {
if (profile.downsample && profile.preserveEdges) {
// upscale
FullScreenBlit(cmd, m_DownscaledRenderTarget, m_RenderTarget, mat, (int)Pass.ComposeUnity);
}
}
else {
if (profile.style == Style.Default && profile.blurIterations > 0) {
cmd.SetGlobalFloat(ShaderParams.BlurSpread, profile.blurSpread);
// perform blur
cmd.GetTemporaryRT(ShaderParams.BlurTemp, desc);
cmd.GetTemporaryRT(ShaderParams.BlurTemp2, desc);
cmd.SetGlobalFloat(ShaderParams.BlurScale, 1f);
RenderTargetIdentifier shadowsRT = shadowsHandle;
RenderTargetIdentifier blurredRT = ShaderParams.BlurTemp2;
if (profile.blurType == BlurType.Box) {
for (int k = 0; k < profile.blurIterations; k++) {
blurredRT = (k % 2) == 0 ? ShaderParams.BlurTemp2 : ShaderParams.BlurTemp;
FullScreenBlit(cmd, shadowsRT, blurredRT, mat, (int)Pass.BoxBlur);
shadowsRT = blurredRT;
cmd.SetGlobalFloat(ShaderParams.BlurScale, k + 1f);
}
}
else {
if (profile.blurType == BlurType.Gaussian15) {
mat.EnableKeyword(ShaderParams.SKW_BLUR_HQ);
}
else {
mat.DisableKeyword(ShaderParams.SKW_BLUR_HQ);
}
FullScreenBlit(cmd, shadowsRT, ShaderParams.BlurTemp, mat, (int)Pass.BlurHoriz);
cmd.SetGlobalFloat(ShaderParams.BlurScale, 1f);
for (int k = 0; k < profile.blurIterations - 1; k++) {
FullScreenBlit(cmd, ShaderParams.BlurTemp, ShaderParams.BlurTemp2, mat, (int)Pass.BlurVert);
cmd.SetGlobalFloat(ShaderParams.BlurScale, k + 2f);
FullScreenBlit(cmd, ShaderParams.BlurTemp2, ShaderParams.BlurTemp, mat, (int)Pass.BlurHoriz);
}
FullScreenBlit(cmd, ShaderParams.BlurTemp, ShaderParams.BlurTemp2, mat, (int)Pass.BlurVert);
}
// blit blurred shadows
FullScreenBlit(cmd, blurredRT, m_RenderTarget, mat, (int)Pass.ComposeWithBlending);
}
else if (profile.downsample && profile.preserveEdges) {
// upscale
FullScreenBlit(cmd, m_DownscaledRenderTarget, m_RenderTarget, mat, (int)Pass.Compose);
}
}
}
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, false);
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, false);
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowScreen, true);
}
}
private partial class UmbraScreenSpaceShadowsPostPass : ScriptableRenderPass {
internal class PassData {
internal UniversalShadowData shadowData;
}
private static void ExecutePass (RasterCommandBuffer cmd, UniversalShadowData shadowData) {
int cascadesCount = shadowData.mainLightShadowCascadesCount;
bool mainLightShadows = shadowData.supportsMainLightShadows;
bool receiveShadowsNoCascade = mainLightShadows && cascadesCount == 1;
bool receiveShadowsCascades = mainLightShadows && cascadesCount > 1;
// Before transparent object pass, force to disable screen space shadow of main light
cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadowScreen, false);
// then enable main light shadows with or without cascades
cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadows, receiveShadowsNoCascade);
cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadowCascades, receiveShadowsCascades);
}
public override void RecordRenderGraph (RenderGraph renderGraph, ContextContainer frameData) {
using (var builder = renderGraph.AddRasterRenderPass<PassData>("Umbra Screen Space Shadow Post Pass", out var passData, m_ProfilingSampler)) {
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
TextureHandle color = resourceData.activeColorTexture;
builder.SetRenderAttachment(color, 0, AccessFlags.Write);
passData.shadowData = frameData.Get<UniversalShadowData>();
builder.AllowGlobalStateModification(true);
builder.SetRenderFunc(static (PassData data, RasterGraphContext rgContext) => {
ExecutePass(rgContext.cmd, data.shadowData);
});
}
}
}
private partial class UmbraDebugPass : ScriptableRenderPass {
internal class PassData {
internal Camera cam;
}
private static void ExecutePass (RasterCommandBuffer cmd, Camera cam) {
Material mat = UmbraScreenSpaceShadowsPass.mat;
if (mat == null) return;
RTHandle shadows = null;
Dictionary<Camera, RTHandle> shadowTextures = shadowPass.shadowTextures;
if (shadowTextures != null) {
shadows = shadowTextures[cam];
}
if (shadows == null) return;
using (new ProfilingScope(cmd, m_ProfilingSampler)) {
Blitter.BlitTexture(cmd, shadows, new Vector4(1, 1, 0, 0), mat, (int)Pass.DebugShadows);
if (settings.debugShadows && settings.profile != null && settings.profile.contactShadows) {
Blitter.BlitTexture(cmd, shadows, new Vector4(1, 1, 0, 0), mat, (int)Pass.ContactShadowsAfterOpaque);
}
}
}
public override void RecordRenderGraph (RenderGraph renderGraph, ContextContainer frameData) {
using (var builder = renderGraph.AddRasterRenderPass<PassData>("Umbra Debug Pass", out var passData, m_ProfilingSampler)) {
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
TextureHandle color = resourceData.activeColorTexture;
builder.SetRenderAttachment(color, 0, AccessFlags.Write);
passData.cam = frameData.Get<UniversalCameraData>().camera;
builder.SetRenderFunc((PassData data, RasterGraphContext rgContext) => {
ExecutePass(rgContext.cmd, data.cam);
});
}
}
}
private partial class UmbraContactShadowsAfterOpaquePass : ScriptableRenderPass {
internal class PassData {
internal TextureHandle colorTexture;
internal TextureHandle depthTexture;
}
private static void ExecutePass (RasterCommandBuffer cmd, RTHandle source, RTHandle depth) {
Material mat = UmbraScreenSpaceShadowsPass.mat;
if (mat == null) return;
using (new ProfilingScope(cmd, m_ProfilingSampler)) {
mat.SetTexture(ShaderParams.CameraDepthTexture, depth);
UmbraProfile profile = settings.profile;
if (profile.transparentReceiverPlane) {
cmd.SetGlobalFloat(ShaderParams.ReceiverPlaneAltitude, profile.receiverPlaneAltitude);
}
cmd.SetGlobalVector(ShaderParams.SourceSize, new Vector4(source.rt.width, source.rt.height, 0, 0));
Blitter.BlitTexture(cmd, source, new Vector4(1, 1, 0, 0), mat, (int)Pass.ContactShadowsAfterOpaque);
}
}
public override void RecordRenderGraph (RenderGraph renderGraph, ContextContainer frameData) {
using (var builder = renderGraph.AddRasterRenderPass<PassData>("Umbra Contact Shadows After Opaque Pass", out var passData, m_ProfilingSampler)) {
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
TextureHandle color = resourceData.activeColorTexture;
if (UmbraSoftShadows.isDeferred && resourceData.gBuffer[4].IsValid()) {
passData.depthTexture = resourceData.gBuffer[4];
builder.UseTexture(passData.depthTexture, AccessFlags.Read);
}
else {
passData.depthTexture = resourceData.cameraDepthTexture;
builder.UseTexture(resourceData.cameraDepthTexture, AccessFlags.Read);
}
builder.AllowGlobalStateModification(true);
builder.SetRenderAttachment(color, 0, AccessFlags.Write);
passData.colorTexture = color;
builder.SetRenderFunc((PassData data, RasterGraphContext rgContext) => {
ExecutePass(rgContext.cmd, data.colorTexture, data.depthTexture);
});
}
}
}
private partial class UmbraOverlayShadows : ScriptableRenderPass {
internal class PassData {
internal TextureHandle colorTexture;
}
private static void ExecutePass (RasterCommandBuffer cmd, RTHandle source) {
Material mat = UmbraScreenSpaceShadowsPass.mat;
if (mat == null) return;
using (new ProfilingScope(cmd, m_ProfilingSampler)) {
Color shadowColor = settings.profile.overlayShadowsColor;
shadowColor.a = settings.profile.overlayShadowsIntensity;
mat.SetColor(ShaderParams.OverlayShadowColor, shadowColor);
Blitter.BlitTexture(cmd, source, new Vector4(1, 1, 0, 0), mat, (int)Pass.OverlayShadows);
}
}
public override void RecordRenderGraph (RenderGraph renderGraph, ContextContainer frameData) {
using (var builder = renderGraph.AddRasterRenderPass<PassData>("Umbra Overlay Shadows", out var passData, m_ProfilingSampler)) {
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
TextureHandle color = resourceData.activeColorTexture;
builder.SetRenderAttachment(color, 0, AccessFlags.Write);
passData.colorTexture = color;
builder.SetRenderFunc((PassData data, RasterGraphContext rgContext) => {
ExecutePass(rgContext.cmd, data.colorTexture);
});
}
}
}
}
}
#endif

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: cb0594141e67f4a1aadba1722240bb79
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Scripts/UmbraRenderFeature.RG.cs
uploadId: 868458

View File

@@ -0,0 +1,915 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Umbra {
[DisallowMultipleRendererFeature("Umbra Render Feature")]
[Tooltip("Umbra Render Feature")]
internal partial class UmbraRenderFeature : ScreenSpaceShadows {
#if UNITY_EDITOR
[UnityEditor.ShaderKeywordFilter.SelectIf(true, keywordNames: ShaderKeywordStrings.MainLightShadowScreen)]
private const bool k_RequiresScreenSpaceShadowsKeyword = true;
#endif
static class ShaderParams {
readonly public static int MainTex = Shader.PropertyToID("_MainTex");
readonly public static int ShadowData = Shader.PropertyToID("_ShadowData");
readonly public static int ShadowData2 = Shader.PropertyToID("_ShadowData2");
readonly public static int ShadowData3 = Shader.PropertyToID("_ShadowData3");
readonly public static int ShadowData4 = Shader.PropertyToID("_ShadowData4");
readonly public static int BlurTemp = Shader.PropertyToID("_BlurTemp");
readonly public static int BlurTemp2 = Shader.PropertyToID("_BlurTemp2");
readonly public static int BlurScale = Shader.PropertyToID("_BlurScale");
readonly public static int BlurSpread = Shader.PropertyToID("_BlurSpread");
readonly public static int UmbraCascadeRects = Shader.PropertyToID("_UmbraCascadeRects");
readonly public static int UmbraCascadeScales = Shader.PropertyToID("_UmbraCascadeScales");
readonly public static int DownsampledDepth = Shader.PropertyToID("_DownsampledDepth");
readonly public static int NoiseTex = Shader.PropertyToID("_NoiseTex");
readonly public static int SourceSize = Shader.PropertyToID("_SourceSize");
readonly public static int BlendCascadeData = Shader.PropertyToID("_BlendCascadeData");
readonly public static int MaskTexture = Shader.PropertyToID("_MaskTex");
readonly public static int CameraDepthTexture = Shader.PropertyToID("_CameraDepthTexture");
readonly public static int CameraNormalsTexture = Shader.PropertyToID("_CameraNormalsTexture");
readonly public static int ContactShadowsSampleCount = Shader.PropertyToID("_ContactShadowsSampleCount");
readonly public static int ContactShadowsData1 = Shader.PropertyToID("_ContactShadowsData1");
readonly public static int ContactShadowsData2 = Shader.PropertyToID("_ContactShadowsData2");
readonly public static int ContactShadowsData3 = Shader.PropertyToID("_ContactShadowsData3");
readonly public static int ContactShadowsData4 = Shader.PropertyToID("_ContactShadowsData4");
readonly public static int ContactShadowsBlendMode = Shader.PropertyToID("_ContactShadowsBlend");
readonly public static int ReceiverPlaneAltitude = Shader.PropertyToID("_ReceiverPlaneAltitude");
readonly public static int OverlayShadowColor = Shader.PropertyToID("_OverlayShadowColor");
readonly public static int EarlyOutSamples = Shader.PropertyToID("_EarlyOutSamples");
readonly public static int PointLightPosition = Shader.PropertyToID("_PointLightPosition");
public static Vector3 Vector3Back = Vector3.back;
public static Vector3 Vector3Forward = Vector3.forward;
public const string SKW_LOOP_STEP_X3 = "_LOOP_STEP_X3";
public const string SKW_LOOP_STEP_X2 = "_LOOP_STEP_X2";
public const string SKW_PRESERVE_EDGES = "_PRESERVE_EDGES";
public const string SKW_BLUR_HQ = "_BLUR_HQ";
public const string SKW_NORMALS_TEXTURE = "_NORMALS_TEXTURE";
public const string SKW_CONTACT_HARDENING = "_CONTACT_HARDENING";
public const string SKW_MASK_TEXTURE = "_MASK_TEXTURE";
public const string SKW_RECEIVER_PLANE = "_RECEIVER_PLANE";
public const string SKW_USE_POINT_LIGHT = "_USE_POINT_LIGHT";
public const string SKW_CONTACT_SHADOWS_SOFT_EDGES = "_SOFT_EDGES";
}
enum Pass {
UmbraCastShadows,
BlurHoriz,
BlurVert,
BoxBlur,
ComposeWithBlending,
DownsampledDepth,
CascadeBlending,
UnityShadows,
ComposeUnity,
ContactShadows,
Compose,
DebugShadows,
ContactShadowsAfterOpaque,
OverlayShadows
}
struct CameraLocation {
public Vector3 position;
public Vector3 forward;
}
const string k_ShaderName = "Hidden/Kronnect/UmbraScreenSpaceShadows";
[Tooltip("Specify which cameras can render Umbra Soft Shadows")]
public LayerMask camerasLayerMask = -1;
public static UmbraSoftShadows settings;
public static int shadowLightIndex;
static int cachedShadowmapTimestap;
static bool usesCachedShadowmap;
readonly Dictionary<Camera, CameraLocation> cameraPrevLocation = new Dictionary<Camera, CameraLocation>();
static readonly Dictionary<Light, UmbraSoftShadows> umbraSettings = new Dictionary<Light, UmbraSoftShadows>();
Material mat;
UmbraScreenSpaceShadowsPass m_SSShadowsPass;
UmbraScreenSpaceShadowsPostPass m_SSShadowsPostPass;
UmbraDebugPass m_SSSShadowsDebugPass;
UmbraContactShadowsAfterOpaquePass m_ContactShadowsAfterOpaquePass;
UmbraOverlayShadows m_OverlayShadowsPass;
public static void RegisterUmbraLight (UmbraSoftShadows settings) {
Light light = settings.GetComponent<Light>();
if (light != null) {
if (light.type == LightType.Directional) {
umbraSettings[light] = settings;
}
else {
Debug.LogError("Umbra Soft Shadows only work on directiona light.");
}
}
}
public static void UnregisterUmbraLight (UmbraSoftShadows settings) {
Light light = settings.GetComponent<Light>();
if (light != null && umbraSettings.ContainsKey(light)) {
umbraSettings.Remove(light);
}
}
public override void Create () {
if (m_SSShadowsPass == null) {
m_SSShadowsPass = new UmbraScreenSpaceShadowsPass();
}
if (m_SSShadowsPostPass == null) {
m_SSShadowsPostPass = new UmbraScreenSpaceShadowsPostPass();
}
if (m_ContactShadowsAfterOpaquePass == null) {
m_ContactShadowsAfterOpaquePass = new UmbraContactShadowsAfterOpaquePass();
}
if (m_SSSShadowsDebugPass == null) {
m_SSSShadowsDebugPass = new UmbraDebugPass();
}
if (m_OverlayShadowsPass == null) {
m_OverlayShadowsPass = new UmbraOverlayShadows();
}
cachedShadowmapTimestap = -100;
LoadMaterial();
m_SSShadowsPass.renderPassEvent = RenderPassEvent.AfterRenderingGbuffer;
m_SSShadowsPostPass.renderPassEvent = RenderPassEvent.BeforeRenderingTransparents;
m_OverlayShadowsPass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques + 1;
m_ContactShadowsAfterOpaquePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques + 1;
m_SSSShadowsDebugPass.renderPassEvent = RenderPassEvent.AfterRenderingTransparents;
}
void OnDisable () {
UmbraSoftShadows.installed = false;
}
protected override void Dispose (bool disposing) {
m_SSShadowsPass?.Dispose();
m_SSShadowsPass = null;
CoreUtils.Destroy(mat);
}
static bool SetupContactShadowsMaterial (Camera cam, UmbraProfile profile, Material mat) {
float intensityMultiplier = profile.contactShadowsIntensityMultiplier;
// Check if we should use point lights for contact shadows
mat.DisableKeyword(ShaderParams.SKW_USE_POINT_LIGHT);
if (settings.contactShadowsSource == ContactShadowsSource.PointLights) {
if (settings.pointLightsTrigger == null && Camera.main != null) {
settings.pointLightsTrigger = Camera.main.transform;
}
float fade = 0;
if (settings.pointLightsTrigger != null) {
Vector3 triggerPosition = settings.pointLightsTrigger.position;
// Find the point light that contains the trigger position
foreach (var kvp in UmbraPointLightContactShadows.umbraPointLights) {
UmbraPointLightContactShadows pointLightComponent = kvp.Value;
if (pointLightComponent == null) continue;
fade = pointLightComponent.ComputeVolumeFade(triggerPosition);
if (fade > 0) {
// Set point light data for the shader
Vector3 pointLightPosition = pointLightComponent.transform.position;
mat.SetVector(ShaderParams.PointLightPosition, new Vector4(pointLightPosition.x, pointLightPosition.y, pointLightPosition.z, 1.0f));
mat.EnableKeyword(ShaderParams.SKW_USE_POINT_LIGHT);
break; // Use the first point light found
}
}
}
if (fade <= 0) return false;
intensityMultiplier *= fade;
}
float farClipPlane = cam.farClipPlane;
UniversalRenderPipelineAsset urpAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
float shadowMaxDistance = urpAsset.shadowDistance;
mat.SetInt(ShaderParams.ContactShadowsSampleCount, profile.contactShadowsSampleCount);
float contactShadowsMaxDistance;
if (settings.profile.shadowSource == ShadowSource.UnityShadows || settings.profile.actualContactShadowsInjectionPoint == ContactShadowsInjectionPoint.AfterOpaque) {
contactShadowsMaxDistance = 1;
}
else {
contactShadowsMaxDistance = shadowMaxDistance / farClipPlane;
}
mat.SetVector(ShaderParams.ContactShadowsData1, new Vector4(profile.contactShadowsStepping, intensityMultiplier, profile.contactShadowsJitter, profile.contactShadowsDistanceFade));
mat.SetVector(ShaderParams.ContactShadowsData2, new Vector4(profile.contactShadowsStartDistance / farClipPlane, profile.contactShadowsStartDistanceFade / farClipPlane, contactShadowsMaxDistance, profile.contactShadowsNormalBias));
mat.SetVector(ShaderParams.ContactShadowsData3, new Vector4(profile.contactShadowsThicknessNear / farClipPlane, profile.contactShadowsThicknessDistanceMultiplier * 0.1f, profile.contactShadowsVignetteSize, profile.contactShadowsBias));
mat.SetVector(ShaderParams.ContactShadowsData4, new Vector4(profile.contactShadowsBiasFar + 0.0025f, profile.contactShadowsEdgeSoftness, profile.contactShadowsPlanarShadows ? 0f : 1f, 0));
mat.SetInt(ShaderParams.ContactShadowsBlendMode, settings.debugShadows ? (int)BlendMode.SrcAlpha : (int)BlendMode.OneMinusSrcAlpha);
// Enable/disable soft edges keyword
if (profile.contactShadowsSoftEdges) {
mat.EnableKeyword(ShaderParams.SKW_CONTACT_SHADOWS_SOFT_EDGES);
}
else {
mat.DisableKeyword(ShaderParams.SKW_CONTACT_SHADOWS_SOFT_EDGES);
}
return true;
}
static void SetupContactShadowsAfterOpaqueOnlyMaterial (UmbraProfile profile, Material mat) {
if ((UmbraSoftShadows.isDeferred && profile.normalsSource == NormalSource.GBufferNormals) || profile.effectiveNormalsSource == NormalSource.NormalsPass) {
mat.EnableKeyword(ShaderParams.SKW_NORMALS_TEXTURE);
}
else {
mat.DisableKeyword(ShaderParams.SKW_NORMALS_TEXTURE);
}
mat.DisableKeyword(ShaderParams.SKW_LOOP_STEP_X3);
mat.DisableKeyword(ShaderParams.SKW_LOOP_STEP_X2);
if (profile.loopStepOptimization == LoopStep.x3) {
mat.EnableKeyword(ShaderParams.SKW_LOOP_STEP_X3);
}
else if (profile.loopStepOptimization == LoopStep.x2) {
mat.EnableKeyword(ShaderParams.SKW_LOOP_STEP_X2);
}
if (profile.transparentReceiverPlane) {
mat.EnableKeyword(ShaderParams.SKW_RECEIVER_PLANE);
}
else {
mat.DisableKeyword(ShaderParams.SKW_RECEIVER_PLANE);
}
}
static bool IsOffscreenDepthTexture (ref CameraData cameraData) => cameraData.targetTexture != null && cameraData.targetTexture.format == RenderTextureFormat.Depth;
public override void AddRenderPasses (ScriptableRenderer renderer, ref RenderingData renderingData) {
UmbraSoftShadows.installed = true;
if (IsOffscreenDepthTexture(ref renderingData.cameraData))
return;
if (!LoadMaterial()) {
Debug.LogError("Umbra: can't load material");
return;
}
// Fetch settings from current main directional light
Light light = null;
shadowLightIndex = renderingData.lightData.mainLightIndex;
if (shadowLightIndex < 0) {
// fallback to static instance search in case that "Only Contact Shadows" option is used
if (UmbraSoftShadows.instance != null) {
light = UmbraSoftShadows.instance.GetComponent<Light>();
}
}
else {
light = renderingData.lightData.visibleLights[shadowLightIndex].light;
}
if (light == null) return;
if (!umbraSettings.TryGetValue(light, out settings)) return;
if (settings == null) return;
Camera cam = renderingData.cameraData.camera;
usesCachedShadowmap = cachedShadowmapTimestap == Time.frameCount - 1 && settings != null && settings.profile != null && settings.profile.frameSkipOptimization && Application.isPlaying;
if (usesCachedShadowmap) {
// test camera rotation/movement
Transform t = cam.transform;
Vector3 pos = t.position;
Vector3 fwd = t.forward;
bool camMoved = true;
if (cameraPrevLocation.TryGetValue(cam, out CameraLocation prevLocation)) {
float dx = pos.x - prevLocation.position.x;
float dy = pos.y - prevLocation.position.y;
float dz = pos.z - prevLocation.position.z;
if (dx < 0) dx = -dx;
if (dy < 0) dy = -dy;
if (dz < 0) dz = -dz;
float thresholdPosition = settings.profile.skipFrameMaxCameraDisplacement;
if (dx <= thresholdPosition && dy <= thresholdPosition && dz <= thresholdPosition) {
if (Vector3.Angle(prevLocation.forward, fwd) <= settings.profile.skipFrameMaxCameraRotation) {
camMoved = false;
}
}
}
if (camMoved) {
prevLocation.position = pos;
prevLocation.forward = fwd;
cameraPrevLocation[cam] = prevLocation;
usesCachedShadowmap = false;
}
}
UmbraSoftShadows.isDeferred = renderer is UniversalRenderer && ((UniversalRenderer)renderer).renderingModeRequested == RenderingMode.Deferred;
bool shouldEnqueue = ((camerasLayerMask & (1 << cam.gameObject.layer)) != 0) && m_SSShadowsPass.Setup(mat);
if (shouldEnqueue) {
bool allowMainLightShadows = renderingData.shadowData.supportsMainLightShadows && renderingData.lightData.mainLightIndex != -1 && renderingData.lightData.visibleLights[renderingData.lightData.mainLightIndex].light.shadowStrength > 0;
bool allowScreenSpaceShadows = allowMainLightShadows && (settings.profile == null || settings.profile.shadowSource != ShadowSource.OnlyContactShadows);
if (allowScreenSpaceShadows) {
m_SSShadowsPass.renderPassEvent = UmbraSoftShadows.isDeferred
? RenderPassEvent.AfterRenderingGbuffer
: RenderPassEvent.AfterRenderingPrePasses + 1; // We add 1 to ensure this happens after depth priming depth copy pass that might be scheduled
renderer.EnqueuePass(m_SSShadowsPass);
renderer.EnqueuePass(m_SSShadowsPostPass);
}
if (settings.profile != null) {
if (!settings.debugShadows && allowScreenSpaceShadows && settings.profile.overlayShadows && settings.profile.overlayShadowsIntensity > 0) {
renderer.EnqueuePass(m_OverlayShadowsPass);
}
if (settings.profile.contactShadows || settings.profile.shadowSource == ShadowSource.OnlyContactShadows) {
if (SetupContactShadowsMaterial(cam, settings.profile, mat)) {
if (settings.profile.shadowSource != ShadowSource.UmbraShadows || settings.profile.actualContactShadowsInjectionPoint == ContactShadowsInjectionPoint.AfterOpaque) {
SetupContactShadowsAfterOpaqueOnlyMaterial(settings.profile, mat);
m_ContactShadowsAfterOpaquePass.Setup();
renderer.EnqueuePass(m_ContactShadowsAfterOpaquePass);
}
}
}
}
if (allowScreenSpaceShadows && settings.debugShadows) {
m_SSSShadowsDebugPass.Setup(m_SSShadowsPass);
renderer.EnqueuePass(m_SSSShadowsDebugPass);
}
}
}
private bool LoadMaterial () {
if (mat != null) {
return true;
}
Shader shader = Shader.Find(k_ShaderName);
if (shader == null) {
return false;
}
mat = CoreUtils.CreateEngineMaterial(shader);
Texture2D noiseTex = Resources.Load<Texture2D>("Umbra/Textures/NoiseTex");
mat.SetTexture(ShaderParams.NoiseTex, noiseTex);
return mat != null;
}
private partial class UmbraScreenSpaceShadowsPass : ScriptableRenderPass {
static string m_ProfilerTag = "UmbraSoftShadows";
static ProfilingSampler m_ProfilingSampler = new ProfilingSampler(m_ProfilerTag);
public static Material mat;
static RTHandle m_RenderTarget, m_DownscaledRenderTarget;
static readonly Vector4[][] cascadeRects = {
new Vector4[] { new Vector4(0, 0, 1, 1), new Vector4(0, 0, 1, 1), new Vector4(0, 0, 1, 1), new Vector4(0, 0, 1, 1) },
new Vector4[] { new Vector4(0, 0, 0.5f, 1f), new Vector4(0.5f, 0, 1, 1f), new Vector4(0, 0, 1, 1), new Vector4(0, 0, 1, 1) },
new Vector4[] { new Vector4(0, 0, 0.5f, 0.5f), new Vector4(0.5f, 0, 1, 0.5f), new Vector4(0, 0.5f, 0.5f, 1), new Vector4(0.5f, 0.5f, 1, 1) },
new Vector4[] { new Vector4(0, 0, 0.5f, 0.5f), new Vector4(0.5f, 0, 1, 0.5f), new Vector4(0, 0.5f, 0.5f, 1), new Vector4(0.5f, 0.5f, 1, 1) }
};
static readonly Vector4[][] cascadeRectsWithPadding = {
new Vector4[] { new Vector4(0, 0, 1, 1), new Vector4(0, 0, 1, 1), new Vector4(0, 0, 1, 1), new Vector4(0, 0, 1, 1) },
new Vector4[] { new Vector4(0, 0, 0.5f, 1f), new Vector4(0.5f, 0, 1, 1f), new Vector4(0, 0, 1, 1), new Vector4(0, 0, 1, 1) },
new Vector4[] { new Vector4(0, 0, 0.5f, 0.5f), new Vector4(0.5f, 0, 1, 0.5f), new Vector4(0, 0.5f, 0.5f, 1), new Vector4(0.5f, 0.5f, 1, 1) },
new Vector4[] { new Vector4(0, 0, 0.5f, 0.5f), new Vector4(0.5f, 0, 1, 0.5f), new Vector4(0, 0.5f, 0.5f, 1), new Vector4(0.5f, 0.5f, 1, 1) }
};
static readonly float[] cascadeScales = { 1, 1, 1, 1 };
static RenderTextureDescriptor desc;
GraphicsFormat screenShadowTextureFormat;
public readonly Dictionary<Camera, RTHandle> shadowTextures = new Dictionary<Camera, RTHandle>();
static bool newShadowmap = true;
static readonly float[] autoCascadeScales = new float[4];
public void Dispose () {
foreach (var rt in shadowTextures.Values) {
rt?.Release();
}
shadowTextures.Clear();
m_RenderTarget?.Release();
m_DownscaledRenderTarget?.Release();
}
internal bool Setup (Material material) {
if (settings == null || !settings.enabled || settings.profile == null) return false;
mat = material;
UmbraProfile profile = settings.profile;
GraphicsFormat desiredFormat = profile.shadowSource == ShadowSource.UmbraShadows && profile.blurIterations > 0 && profile.enableContactHardening ? GraphicsFormat.R8G8_UNorm : GraphicsFormat.R8_UNorm;
#if UNITY_2023_1_OR_NEWER
screenShadowTextureFormat = SystemInfo.IsFormatSupported(desiredFormat, GraphicsFormatUsage.Linear | GraphicsFormatUsage.Render)
#else
screenShadowTextureFormat = RenderingUtils.SupportsGraphicsFormat(desiredFormat, FormatUsage.Linear | FormatUsage.Render)
#endif
? desiredFormat
: GraphicsFormat.B8G8R8A8_UNorm;
if (usesCachedShadowmap) {
ConfigureInput(ScriptableRenderPassInput.None);
}
else {
if (profile.shadowSource == ShadowSource.UmbraShadows && (profile.effectiveNormalsSource == NormalSource.NormalsPass || profile.downsample || profile.forceDepthPrepass)) {
ConfigureInput(ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal);
}
else {
ConfigureInput(ScriptableRenderPassInput.Depth);
}
}
return mat != null;
}
#if !UNITY_6000_3_OR_NEWER
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData renderingData) {
desc = renderingData.cameraData.cameraTargetDescriptor;
desc.depthBufferBits = 0;
desc.msaaSamples = 1;
desc.graphicsFormat = screenShadowTextureFormat;
if (settings == null || settings.profile == null) return;
UmbraProfile profile = settings.profile;
if (profile.downsample && !profile.preserveEdges) {
desc.width /= 2;
desc.height /= 2;
}
Camera cam = renderingData.cameraData.camera;
#if UNITY_EDITOR
if (profile.frameSkipOptimization && Application.isPlaying) {
#else
if (profile.frameSkipOptimization) {
#endif
newShadowmap = !shadowTextures.TryGetValue(cam, out m_RenderTarget);
}
#if UNITY_6000_0_OR_NEWER
if (RenderingUtils.ReAllocateHandleIfNeeded(ref m_RenderTarget, desc, FilterMode.Point, TextureWrapMode.Clamp, name: "_ScreenSpaceShadowmapTexture")) {
#else
if (RenderingUtils.ReAllocateIfNeeded(ref m_RenderTarget, desc, FilterMode.Point, TextureWrapMode.Clamp, name: "_ScreenSpaceShadowmapTexture")) {
#endif
newShadowmap = true;
}
if (newShadowmap) {
shadowTextures[cam] = m_RenderTarget;
}
cmd.SetGlobalTexture(m_RenderTarget.name, m_RenderTarget.nameID);
ConfigureTarget(m_RenderTarget);
ConfigureClear(ClearFlag.None, Color.white);
}
#endif
#if !UNITY_6000_3_OR_NEWER
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) {
if (mat == null) {
Debug.LogError("Umbra material not initialized");
return;
}
UmbraProfile profile = settings.profile;
var cmd = renderingData.commandBuffer;
using (new ProfilingScope(cmd, m_ProfilingSampler)) {
int frameCount = Time.frameCount;
#if UNITY_EDITOR
bool useFrame = !Application.isPlaying || !profile.frameSkipOptimization || newShadowmap || !usesCachedShadowmap;
#else
bool useFrame = !profile.frameSkipOptimization || newShadowmap || !usesCachedShadowmap;
#endif
if (useFrame) {
cachedShadowmapTimestap = frameCount;
newShadowmap = false;
RTHandle shadowsHandle;
if (profile.downsample && profile.preserveEdges) {
desc.width /= 2;
desc.height /= 2;
#if UNITY_6000_0_OR_NEWER
RenderingUtils.ReAllocateHandleIfNeeded(ref m_DownscaledRenderTarget, desc, FilterMode.Point, TextureWrapMode.Clamp);
#else
RenderingUtils.ReAllocateIfNeeded(ref m_DownscaledRenderTarget, desc, FilterMode.Point, TextureWrapMode.Clamp);
#endif
shadowsHandle = m_DownscaledRenderTarget;
}
else {
shadowsHandle = m_RenderTarget;
}
int cascadeCount = renderingData.shadowData.mainLightShadowCascadesCount;
float farClipPlane = renderingData.cameraData.camera.farClipPlane;
UniversalRenderPipelineAsset urpAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
float shadowMaxDistance = urpAsset.shadowDistance;
Pass castShadowsPass;
if (profile.shadowSource == ShadowSource.UnityShadows) {
castShadowsPass = Pass.UnityShadows;
}
else {
castShadowsPass = Pass.UmbraCastShadows;
if (profile.transparentReceiverPlane) {
mat.EnableKeyword(ShaderParams.SKW_RECEIVER_PLANE);
cmd.SetGlobalFloat(ShaderParams.ReceiverPlaneAltitude, profile.receiverPlaneAltitude);
cmd.SetGlobalVector(ShaderParams.ShadowData3, new Vector4(10f, 0.001f, 0, profile.blurEdgeSharpness));
}
else {
mat.DisableKeyword(ShaderParams.SKW_RECEIVER_PLANE);
cmd.SetGlobalVector(ShaderParams.ShadowData3, new Vector4(profile.blurDepthAttenStart / farClipPlane, profile.blurDepthAttenLength / farClipPlane, profile.blurGrazingAttenuation, profile.blurEdgeSharpness));
}
cmd.SetGlobalVector(ShaderParams.ShadowData, new Vector4(profile.sampleCount, 1024 / Mathf.Pow(2, profile.posterization), profile.blurEdgeTolerance * 1000f, (profile.blurDepthAttenStart + profile.blurDepthAttenLength) / farClipPlane));
float shadowMaxDepth = profile.transparentReceiverPlane ? 2 : shadowMaxDistance / farClipPlane;
cmd.SetGlobalVector(ShaderParams.ShadowData2, new Vector4(1f - profile.contactStrength, profile.distantSpread, shadowMaxDepth, profile.lightSize * 0.02f));
cmd.SetGlobalVector(ShaderParams.ShadowData4, new Vector4(profile.occludersCount, profile.occludersSearchRadius * 0.02f, profile.contactStrength > 0 ? profile.contactStrengthKnee * 0.1f : 0.00001f, profile.maskScale));
cmd.SetGlobalVector(ShaderParams.SourceSize, new Vector4(desc.width, desc.height, 0, 0));
cmd.SetGlobalInt(ShaderParams.EarlyOutSamples, profile.earlyOutSamples);
if (cascadeCount > 1) {
VisibleLight shadowLight = renderingData.lightData.visibleLights[shadowLightIndex];
float shadowNearPlane = shadowLight.light.shadowNearPlane;
for (int k = 0; k < cascadeCount; k++) {
renderingData.cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex,
k, cascadeCount, renderingData.shadowData.mainLightShadowCascadesSplit, urpAsset.mainLightShadowmapResolution, shadowNearPlane, out _, out Matrix4x4 proj,
out _);
Matrix4x4 invProj = proj.inverse;
autoCascadeScales[k] = Mathf.Abs(invProj.MultiplyPoint(ShaderParams.Vector3Back).z - invProj.MultiplyPoint(ShaderParams.Vector3Forward).z) / 100f;
}
Vector4[] cascadeRectsTemp = cascadeRectsWithPadding[cascadeCount - 1];
float texel = 1f / urpAsset.mainLightShadowmapResolution;
float padding = texel;
for (int c = 0; c < 4; c++) {
Vector4 defaultRect = cascadeRects[cascadeCount - 1][c];
Vector4 rect = cascadeRectsTemp[c];
rect.x = defaultRect.x + padding;
rect.y = defaultRect.y + padding;
rect.z = defaultRect.z - padding;
rect.w = defaultRect.w - padding;
cascadeRectsTemp[c] = rect;
}
cmd.SetGlobalVectorArray(ShaderParams.UmbraCascadeRects, cascadeRectsTemp);
cascadeScales[0] = profile.cascade1Scale * autoCascadeScales[0];
cascadeScales[1] = profile.cascade2Scale * autoCascadeScales[1];
cascadeScales[2] = profile.cascade3Scale * autoCascadeScales[2];
cascadeScales[3] = profile.cascade4Scale * autoCascadeScales[3];
cmd.SetGlobalFloatArray(ShaderParams.UmbraCascadeScales, cascadeScales);
}
if ((UmbraSoftShadows.isDeferred && profile.normalsSource == NormalSource.GBufferNormals) || profile.effectiveNormalsSource == NormalSource.NormalsPass || profile.downsample) {
mat.EnableKeyword(ShaderParams.SKW_NORMALS_TEXTURE);
}
else {
mat.DisableKeyword(ShaderParams.SKW_NORMALS_TEXTURE);
}
#if !UNITY_WEBGL
if (profile.enableContactHardening) {
mat.EnableKeyword(ShaderParams.SKW_CONTACT_HARDENING);
}
else
#endif
{
mat.DisableKeyword(ShaderParams.SKW_CONTACT_HARDENING);
}
mat.DisableKeyword(ShaderParams.SKW_LOOP_STEP_X3);
mat.DisableKeyword(ShaderParams.SKW_LOOP_STEP_X2);
if (profile.loopStepOptimization == LoopStep.x3) {
mat.EnableKeyword(ShaderParams.SKW_LOOP_STEP_X3);
}
else if (profile.loopStepOptimization == LoopStep.x2) {
mat.EnableKeyword(ShaderParams.SKW_LOOP_STEP_X2);
}
if (profile.style == Style.Textured && profile.maskTexture != null) {
mat.EnableKeyword(ShaderParams.SKW_MASK_TEXTURE);
mat.SetTexture(ShaderParams.MaskTexture, profile.maskTexture);
}
else {
mat.DisableKeyword(ShaderParams.SKW_MASK_TEXTURE);
}
}
// Resolve screen space shadows
Blitter.BlitCameraTexture(cmd, m_RenderTarget, shadowsHandle, mat, (int)castShadowsPass);
// Blend cascades 0 & 1
if (profile.shadowSource == ShadowSource.UmbraShadows) {
if (profile.blendCascades && cascadeCount > 1) {
cmd.SetGlobalVector(ShaderParams.BlendCascadeData, new Vector4(profile.cascade1BlendingStrength * 100f, profile.cascade2BlendingStrength * 100f, profile.cascade3BlendingStrength * 100f, 1f));
Blitter.BlitCameraTexture(cmd, shadowsHandle, shadowsHandle, mat, (int)Pass.CascadeBlending);
}
}
// Add contact shadows
if (profile.contactShadows) {
if (!settings.debugShadows && profile.actualContactShadowsInjectionPoint == ContactShadowsInjectionPoint.ShadowTexture) {
Blitter.BlitCameraTexture(cmd, shadowsHandle, shadowsHandle, mat, (int)Pass.ContactShadows);
}
}
// Downscale depth for upscaler
if (profile.downsample && profile.preserveEdges) {
RenderTextureDescriptor downscampledDepthDesc = desc;
downscampledDepthDesc.colorFormat = RenderTextureFormat.RFloat;
cmd.GetTemporaryRT(ShaderParams.DownsampledDepth, downscampledDepthDesc);
FullScreenBlit(cmd, ShaderParams.DownsampledDepth, mat, (int)Pass.DownsampledDepth);
mat.EnableKeyword(ShaderParams.SKW_PRESERVE_EDGES);
}
else {
mat.DisableKeyword(ShaderParams.SKW_PRESERVE_EDGES);
}
if (profile.shadowSource == ShadowSource.UnityShadows) {
if (profile.downsample && profile.preserveEdges) {
// upscale
FullScreenBlit(cmd, m_DownscaledRenderTarget, m_RenderTarget, mat, (int)Pass.ComposeUnity);
}
}
else {
if (profile.style == Style.Default && profile.blurIterations > 0) {
cmd.SetGlobalFloat(ShaderParams.BlurSpread, profile.blurSpread);
// perform blur
cmd.GetTemporaryRT(ShaderParams.BlurTemp, desc);
cmd.GetTemporaryRT(ShaderParams.BlurTemp2, desc);
cmd.SetGlobalFloat(ShaderParams.BlurScale, 1f);
RenderTargetIdentifier shadowsRT = shadowsHandle;
RenderTargetIdentifier blurredRT = ShaderParams.BlurTemp2;
if (profile.blurType == BlurType.Box) {
for (int k = 0; k < profile.blurIterations; k++) {
blurredRT = (k % 2) == 0 ? ShaderParams.BlurTemp2 : ShaderParams.BlurTemp;
FullScreenBlit(cmd, shadowsRT, blurredRT, mat, (int)Pass.BoxBlur);
shadowsRT = blurredRT;
cmd.SetGlobalFloat(ShaderParams.BlurScale, k + 1f);
}
}
else {
if (profile.blurType == BlurType.Gaussian15) {
mat.EnableKeyword(ShaderParams.SKW_BLUR_HQ);
}
else {
mat.DisableKeyword(ShaderParams.SKW_BLUR_HQ);
}
FullScreenBlit(cmd, shadowsRT, ShaderParams.BlurTemp, mat, (int)Pass.BlurHoriz);
cmd.SetGlobalFloat(ShaderParams.BlurScale, 1f);
for (int k = 0; k < profile.blurIterations - 1; k++) {
FullScreenBlit(cmd, ShaderParams.BlurTemp, ShaderParams.BlurTemp2, mat, (int)Pass.BlurVert);
cmd.SetGlobalFloat(ShaderParams.BlurScale, k + 2f);
FullScreenBlit(cmd, ShaderParams.BlurTemp2, ShaderParams.BlurTemp, mat, (int)Pass.BlurHoriz);
}
FullScreenBlit(cmd, ShaderParams.BlurTemp, ShaderParams.BlurTemp2, mat, (int)Pass.BlurVert);
}
// blit blurred shadows
FullScreenBlit(cmd, blurredRT, m_RenderTarget, mat, (int)Pass.ComposeWithBlending);
}
else if (profile.downsample && profile.preserveEdges) {
// upscale
FullScreenBlit(cmd, m_DownscaledRenderTarget, m_RenderTarget, mat, (int)Pass.Compose);
}
}
}
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, false);
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, false);
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowScreen, true);
}
}
#endif
static Mesh _fullScreenMesh;
static Mesh fullscreenMesh {
get {
if (_fullScreenMesh != null) {
return _fullScreenMesh;
}
float num = 1f;
float num2 = 0f;
Mesh val = new Mesh();
_fullScreenMesh = val;
_fullScreenMesh.SetVertices(new List<Vector3> {
new Vector3 (-1f, -1f, 0f),
new Vector3 (-1f, 1f, 0f),
new Vector3 (1f, -1f, 0f),
new Vector3 (1f, 1f, 0f)
});
_fullScreenMesh.SetUVs(0, new List<Vector2> {
new Vector2 (0f, num2),
new Vector2 (0f, num),
new Vector2 (1f, num2),
new Vector2 (1f, num)
});
_fullScreenMesh.SetIndices(new int[6] { 0, 1, 2, 2, 1, 3 }, (MeshTopology)0, 0, false);
_fullScreenMesh.UploadMeshData(true);
return _fullScreenMesh;
}
}
static void FullScreenBlit (CommandBuffer cmd, RenderTargetIdentifier destination, Material material, int passIndex) {
destination = new RenderTargetIdentifier(destination, 0, CubemapFace.Unknown, -1);
cmd.SetRenderTarget(destination);
cmd.DrawMesh(fullscreenMesh, Matrix4x4.identity, material, 0, passIndex);
}
static void FullScreenBlit (CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, int passIndex) {
destination = new RenderTargetIdentifier(destination, 0, CubemapFace.Unknown, -1);
cmd.SetRenderTarget(destination);
cmd.SetGlobalTexture(ShaderParams.MainTex, source);
cmd.DrawMesh(fullscreenMesh, Matrix4x4.identity, material, 0, passIndex);
}
}
private partial class UmbraScreenSpaceShadowsPostPass : ScriptableRenderPass {
// Profiling tag
private static string m_ProfilerTag = "Umbra Screen Space Shadows Post Pass";
private static ProfilingSampler m_ProfilingSampler = new ProfilingSampler(m_ProfilerTag);
private static readonly RTHandle k_CurrentActive = RTHandles.Alloc(BuiltinRenderTextureType.CurrentActive);
#if !UNITY_6000_3_OR_NEWER
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void Configure (CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) {
ConfigureTarget(k_CurrentActive);
}
#endif
#if !UNITY_6000_3_OR_NEWER
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) {
var cmd = renderingData.commandBuffer;
using (new ProfilingScope(cmd, m_ProfilingSampler)) {
ShadowData shadowData = renderingData.shadowData;
int cascadesCount = shadowData.mainLightShadowCascadesCount;
bool mainLightShadows = renderingData.shadowData.supportsMainLightShadows;
bool receiveShadowsNoCascade = mainLightShadows && cascadesCount == 1;
bool receiveShadowsCascades = mainLightShadows && cascadesCount > 1;
// Before transparent object pass, force to disable screen space shadow of main light
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowScreen, false);
// then enable main light shadows with or without cascades
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, receiveShadowsNoCascade);
CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadowCascades, receiveShadowsCascades);
}
}
#endif
}
private partial class UmbraDebugPass : ScriptableRenderPass {
// Profiling tag
private static string m_ProfilerTag = "Umbra Debug Pass";
private static ProfilingSampler m_ProfilingSampler = new ProfilingSampler(m_ProfilerTag);
RTHandle source;
static UmbraScreenSpaceShadowsPass shadowPass;
public void Setup (UmbraScreenSpaceShadowsPass shadowPass) {
UmbraDebugPass.shadowPass = shadowPass;
if (settings.debugShadows) {
ConfigureInput(ScriptableRenderPassInput.Depth);
}
}
#if !UNITY_6000_3_OR_NEWER
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData renderingData) {
source = renderingData.cameraData.renderer.cameraColorTargetHandle;
}
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) {
Material mat = UmbraScreenSpaceShadowsPass.mat;
if (mat == null) return;
RTHandle shadows = null;
Camera cam = renderingData.cameraData.camera;
Dictionary<Camera, RTHandle> shadowTextures = shadowPass.shadowTextures;
if (shadowTextures != null) {
shadows = shadowTextures[cam];
}
if (shadows == null) return;
var cmd = renderingData.commandBuffer;
using (new ProfilingScope(cmd, m_ProfilingSampler)) {
Blitter.BlitCameraTexture(cmd, shadows, source, mat, (int)Pass.DebugShadows);
if (settings.debugShadows && settings.profile != null && settings.profile.contactShadows) {
Blitter.BlitCameraTexture(cmd, source, source, mat, (int)Pass.ContactShadowsAfterOpaque);
}
}
}
#endif
}
private partial class UmbraContactShadowsAfterOpaquePass : ScriptableRenderPass {
// Profiling tag
private static string m_ProfilerTag = "Umbra Contact Shadows After Opaque Pass";
private static ProfilingSampler m_ProfilingSampler = new ProfilingSampler(m_ProfilerTag);
RTHandle source;
public void Setup () {
ConfigureInput(ScriptableRenderPassInput.Depth);
}
#if !UNITY_6000_3_OR_NEWER
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData renderingData) {
source = renderingData.cameraData.renderer.cameraColorTargetHandle;
ConfigureTarget(source);
}
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) {
Material mat = UmbraScreenSpaceShadowsPass.mat;
if (mat == null || source.rt == null) return;
var cmd = renderingData.commandBuffer;
using (new ProfilingScope(cmd, m_ProfilingSampler)) {
UmbraProfile profile = settings.profile;
if (profile.transparentReceiverPlane) {
cmd.SetGlobalFloat(ShaderParams.ReceiverPlaneAltitude, profile.receiverPlaneAltitude);
}
cmd.SetGlobalVector(ShaderParams.SourceSize, new Vector4(source.rt.width, source.rt.height, 0, 0));
Blitter.BlitCameraTexture(cmd, source, source, mat, (int)Pass.ContactShadowsAfterOpaque);
}
}
#endif
}
private partial class UmbraOverlayShadows : ScriptableRenderPass {
// Profiling tag
private static string m_ProfilerTag = "Umbra Overlay Shadows";
private static ProfilingSampler m_ProfilingSampler = new ProfilingSampler(m_ProfilerTag);
RTHandle source;
#if !UNITY_6000_3_OR_NEWER
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void OnCameraSetup (CommandBuffer cmd, ref RenderingData renderingData) {
source = renderingData.cameraData.renderer.cameraColorTargetHandle;
ConfigureTarget(source);
}
#if UNITY_2023_3_OR_NEWER
[Obsolete]
#endif
public override void Execute (ScriptableRenderContext context, ref RenderingData renderingData) {
Material mat = UmbraScreenSpaceShadowsPass.mat;
if (mat == null || source == null) return;
var cmd = renderingData.commandBuffer;
using (new ProfilingScope(cmd, m_ProfilingSampler)) {
Color shadowColor = settings.profile.overlayShadowsColor;
shadowColor.a = settings.profile.overlayShadowsIntensity;
mat.SetColor(ShaderParams.OverlayShadowColor, shadowColor);
Blitter.BlitCameraTexture(cmd, source, source, mat, (int)Pass.OverlayShadows);
}
}
#endif
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 163d34cee9b7a428d9899ab92abd7e0d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Scripts/UmbraRenderFeature.cs
uploadId: 868458

View File

@@ -0,0 +1,61 @@
using UnityEngine;
namespace Umbra {
public enum ContactShadowsSource {
DirectionalLight,
PointLights
}
[ExecuteAlways]
[HelpURL("https://kronnect.com/docs/umbra/")]
public class UmbraSoftShadows : MonoBehaviour {
[Tooltip("Currently used umbra profile with settings")]
public UmbraProfile profile;
[Tooltip("Source of contact shadows")]
public ContactShadowsSource contactShadowsSource = ContactShadowsSource.DirectionalLight;
[Tooltip("Object whose position is used to determine if it's inside point light volumes")]
public Transform pointLightsTrigger;
public bool debugShadows;
public static bool installed;
public static bool isDeferred;
public static UmbraSoftShadows instance;
private void OnEnable () {
CheckProfile();
instance = this;
}
private void OnDisable () {
UmbraRenderFeature.UnregisterUmbraLight(this);
instance = null;
}
void OnValidate () {
CheckProfile();
}
private void Reset () {
CheckProfile();
}
void CheckProfile () {
if (profile == null) {
profile = ScriptableObject.CreateInstance<UmbraProfile>();
profile.name = "New Umbra Profile";
#if UNITY_EDITOR
UnityEditor.EditorUtility.SetDirty(this);
#endif
}
UmbraRenderFeature.RegisterUmbraLight(this);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 7e828e348ac39438eb8ae845fe499ae5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/Scripts/UmbraSoftShadows.cs
uploadId: 868458

View File

@@ -0,0 +1,3 @@
{
"reference": "GUID:15fc0a57446b3144c949da3e2b9737a9"
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 7aeef6f5814744ae3a7b75542a11ec53
AssemblyDefinitionReferenceImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 282485
packageName: Umbra Soft Shadows - Better Directional & Contact Shadows for URP
packageVersion: 10.0.1
assetPath: Assets/UmbraSoftShadows/Runtime/UmbraAsmRef.asmref
uploadId: 868458

View File

@@ -11,5 +11,5 @@ MonoBehaviour:
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d7e9a0ba2b7f40ebbb3dad8385aa807b, type: 3} m_Script: {fileID: 11500000, guid: d7e9a0ba2b7f40ebbb3dad8385aa807b, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier: Unity.XR.AndroidOpenXR.Editor::UnityEditor.XR.OpenXR.Features.Android.AndroidXRSettingsInitializer
isInitialized: 0 isInitialized: 0

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aa41aa4504bb16e4c9983c6d1d784beb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More