diff --git a/Assets/External/Horizon Based Ambient Occlusion.meta b/Assets/External/Horizon Based Ambient Occlusion.meta new file mode 100644 index 00000000..05aebdf3 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1e2cc9e9ad4f108458033887c97bb038 +folderAsset: yes +timeCreated: 1487248984 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo.meta new file mode 100644 index 00000000..06cd026a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 264dde3b9012fa346b510f9f1d502066 +folderAsset: yes +timeCreated: 1455959812 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Demo.unity b/Assets/External/Horizon Based Ambient Occlusion/Demo/Demo.unity new file mode 100644 index 00000000..eee65a10 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Demo.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f09dd2ea1b69a276900edce00e84911c38163c9aaa74cef10f92f03bedea92f +size 61758 diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Demo.unity.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Demo.unity.meta new file mode 100644 index 00000000..feb01d31 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Demo.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 241634a1ead4cbf4aa1750dbe7debbab +timeCreated: 1453576474 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/DemoSettings.lighting b/Assets/External/Horizon Based Ambient Occlusion/Demo/DemoSettings.lighting new file mode 100644 index 00000000..cddf7dad --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/DemoSettings.lighting @@ -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: 8 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_RealtimeEnvironmentLighting: 1 + m_BounceScale: 1 + m_AlbedoBoost: 1 + m_IndirectOutputScale: 1 + m_UsingShadowmask: 0 + m_BakeBackend: 1 + m_LightmapMaxSize: 1024 + m_LightmapSizeFixed: 0 + m_UseMipmapLimits: 1 + m_BakeResolution: 40 + m_Padding: 2 + m_LightmapCompression: 3 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 0 + m_CompAOExponentDirect: 0 + m_ExtractAO: 0 + m_MixedBakeMode: 1 + m_LightmapsBakeMode: 1 + m_FilterMode: 1 + m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0} + m_ExportTrainingData: 0 + m_EnableWorkerProcessBaking: 1 + m_TrainingDataDestination: TrainingData + m_RealtimeResolution: 2 + m_ForceWhiteAlbedo: 0 + m_ForceUpdates: 0 + m_PVRCulling: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVREnvironmentSampleCount: 512 + m_PVREnvironmentReferencePointCount: 2048 + m_LightProbeSampleCountMultiplier: 4 + m_PVRBounces: 2 + m_PVRMinBounces: 2 + m_PVREnvironmentImportanceSampling: 0 + m_PVRFilteringMode: 0 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + 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 + m_RespectSceneVisibilityWhenBakingGI: 0 diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/DemoSettings.lighting.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/DemoSettings.lighting.meta new file mode 100644 index 00000000..5fd7c38a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/DemoSettings.lighting.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 137fb38e8593ded4ea9a4d6c5e4dc19a +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 4890085278179872738 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Models.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models.meta new file mode 100644 index 00000000..bd1a108f --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 28143174a74ad204d9199cb14598af2f +folderAsset: yes +timeCreated: 1455959813 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Dragons Candle.fbx b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Dragons Candle.fbx new file mode 100644 index 00000000..0f8558ef --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Dragons Candle.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc0752cd7b3de320ae9c9f5f5340378c290660b7bb725865ae8d824d8d106eee +size 5704768 diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Dragons Candle.fbx.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Dragons Candle.fbx.meta new file mode 100644 index 00000000..e443a4cd --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Dragons Candle.fbx.meta @@ -0,0 +1,76 @@ +fileFormatVersion: 2 +guid: c8916d4ec4caf80458ef5a2a1d354228 +timeCreated: 1454157498 +licenseType: Store +ModelImporter: + serializedVersion: 19 + fileIDToRecycleName: + 100000: //RootNode + 400000: //RootNode + 2300000: //RootNode + 3300000: //RootNode + 4300000: Mesh + materials: + importMaterials: 1 + materialName: 0 + materialSearch: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleRotations: 1 + optimizeGameObjects: 0 + motionNodeName: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + animationCompression: 1 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1000 + meshCompression: 0 + addColliders: 0 + importBlendShapes: 1 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + optimizeMeshForGPU: 1 + keepQuads: 0 + weldVertices: 1 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVPackMargin: 4 + useFileScale: 1 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + importAnimation: 1 + copyAvatar: 0 + humanDescription: + human: [] + skeleton: [] + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + rootMotionBoneName: + hasTranslationDoF: 0 + lastHumanDescriptionAvatarSource: {instanceID: 0} + animationType: 0 + humanoidOversampling: 1 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Materials.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Materials.meta new file mode 100644 index 00000000..ef77836e --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Materials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 29ca2b7c485291d4b92e1a7e3c2ec3a7 +folderAsset: yes +timeCreated: 1455959813 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Materials/Dragons.mat b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Materials/Dragons.mat new file mode 100644 index 00000000..8a643f87 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Materials/Dragons.mat @@ -0,0 +1,91 @@ +%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: Dragons + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _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: 2800000, guid: ca39994063dd9c94894e7e05a63ed4af, type: 3} + 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} + m_Ints: [] + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _EmissionScaleUI: 0 + - _GlossMapScale: 1 + - _Glossiness: 0 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 0} + - _EmissionColorUI: {r: 1, g: 1, b: 1, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Materials/Dragons.mat.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Materials/Dragons.mat.meta new file mode 100644 index 00000000..76a19b69 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Materials/Dragons.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 86e1545bedbf12044bc434adf047297c +timeCreated: 1454157498 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Textures.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Textures.meta new file mode 100644 index 00000000..68d6039a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Textures.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d8a5653e008d6c545b047c7dd9b89368 +folderAsset: yes +timeCreated: 1455959813 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Textures/Dragons.png b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Textures/Dragons.png new file mode 100644 index 00000000..729ad417 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Textures/Dragons.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bb5d543d86a2b2df7c43ce820fa5e1528da74587df6b5bb8fa4efcc0dac8ef1 +size 5811266 diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Textures/Dragons.png.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Textures/Dragons.png.meta new file mode 100644 index 00000000..c5c8f498 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Models/Textures/Dragons.png.meta @@ -0,0 +1,57 @@ +fileFormatVersion: 2 +guid: ca39994063dd9c94894e7e05a63ed4af +timeCreated: 1454158430 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + linearTexture: 0 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 7 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: -1 + mipBias: -1 + wrapMode: -1 + nPOTScale: 1 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + allowsAlphaSplitting: 0 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 0 + textureType: -1 + buildTargetSettings: [] + spriteSheet: + sprites: [] + outline: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime.meta new file mode 100644 index 00000000..e79b530a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 25eb19968142c7c40ae4ac3180eb03ab +folderAsset: yes +timeCreated: 1455959813 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAO.Demo.Runtime.asmdef b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAO.Demo.Runtime.asmdef new file mode 100644 index 00000000..e9094657 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAO.Demo.Runtime.asmdef @@ -0,0 +1,16 @@ +{ + "name": "HBAO.Demo.Runtime", + "rootNamespace": "", + "references": [ + "GUID:b83dc51897666cb44bdfbf9671f74e85" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAO.Demo.Runtime.asmdef.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAO.Demo.Runtime.asmdef.meta new file mode 100644 index 00000000..acd4b42a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAO.Demo.Runtime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d7729a5237c96f948aaf7de13ad4cffb +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAOControl.cs b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAOControl.cs new file mode 100644 index 00000000..a40c13df --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAOControl.cs @@ -0,0 +1,29 @@ +using UnityEngine; + +namespace HorizonBasedAmbientOcclusion +{ + public class HBAOControl : MonoBehaviour + { + public HBAO hbao; + public UnityEngine.UI.Slider aoRadiusSlider; + + public void Start() + { + hbao.SetDebugMode(HBAO.DebugMode.Disabled); + hbao.SetAoRadius(aoRadiusSlider.value); + } + + public void ToggleShowAO() + { + if (hbao.generalSettings.debugMode != HBAO.DebugMode.Disabled) + hbao.SetDebugMode(HBAO.DebugMode.Disabled); + else + hbao.SetDebugMode(HBAO.DebugMode.AOOnly); + } + + public void UpdateAoRadius() + { + hbao.SetAoRadius(aoRadiusSlider.value); + } + } +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAOControl.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAOControl.cs.meta new file mode 100644 index 00000000..1896ad0d --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/HBAOControl.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: b8c0ece2d92e8be4f8a5909e6896f948 +timeCreated: 1453634854 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/RotateObject.cs b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/RotateObject.cs new file mode 100644 index 00000000..e05d53e9 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/RotateObject.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace HorizonBasedAmbientOcclusion +{ + public class RotateObject : MonoBehaviour + { + // Use this for initialization + void Start() + { + + } + + // Update is called once per frame + void Update() + { + transform.Rotate(Vector3.up * Time.deltaTime * 15.0f, Space.World); + } + } +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/RotateObject.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/RotateObject.cs.meta new file mode 100644 index 00000000..09485494 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Demo/Runtime/RotateObject.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f1b93e48d84b64e4cac4a08f2da9f69f +timeCreated: 1453573806 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Documentation.meta b/Assets/External/Horizon Based Ambient Occlusion/Documentation.meta new file mode 100644 index 00000000..9361df75 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Documentation.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 9869ea90af1da7949848b63dddb25d26 +folderAsset: yes +timeCreated: 1467127598 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Documentation/User Guide.pdf b/Assets/External/Horizon Based Ambient Occlusion/Documentation/User Guide.pdf new file mode 100644 index 00000000..0caac436 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Documentation/User Guide.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b77c14f6e6961102776f2a9d6d58049c318c649ebe8cdac4ac9b28feb15583f6 +size 931890 diff --git a/Assets/External/Horizon Based Ambient Occlusion/Documentation/User Guide.pdf.meta b/Assets/External/Horizon Based Ambient Occlusion/Documentation/User Guide.pdf.meta new file mode 100644 index 00000000..ff062116 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Documentation/User Guide.pdf.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 061da04314aaba248977f5671e799370 +timeCreated: 1467127598 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor.meta b/Assets/External/Horizon Based Ambient Occlusion/Editor.meta new file mode 100644 index 00000000..0c00a205 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 478a5a24ad1152f43ad164da3759717b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAO.Editor.asmdef b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAO.Editor.asmdef new file mode 100644 index 00000000..06bfd64c --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAO.Editor.asmdef @@ -0,0 +1,24 @@ +{ + "name": "HBAO.Editor", + "rootNamespace": "", + "references": [ + "GUID:b83dc51897666cb44bdfbf9671f74e85" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "Unity", + "expression": "2020.3.13", + "define": "UNITY_2020_3_13_OR_NEWER" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAO.Editor.asmdef.meta b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAO.Editor.asmdef.meta new file mode 100644 index 00000000..78ca452a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAO.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: bbd7cb83004dde543aac62cbce764d58 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOEditor.cs b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOEditor.cs new file mode 100644 index 00000000..26d0cc1e --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOEditor.cs @@ -0,0 +1,282 @@ +using UnityEngine; +using UnityEditor; +using UnityEditor.Rendering; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace HorizonBasedAmbientOcclusion +{ + [CustomEditor(typeof(HBAO))] + public class HBAOEditor : Editor + { + private HBAO m_HBAO; + private Texture2D m_HBAOTex; + private GUIStyle m_SettingsGroupStyle; + private GUIStyle m_TitleLabelStyle; + private int m_SelectedPreset; + // settings group + private Dictionary> m_GroupFields; + private readonly Dictionary m_Presets = new Dictionary() + { + { 0, HBAO.Preset.Normal }, + { 1, HBAO.Preset.FastPerformance }, + { 2, HBAO.Preset.FastestPerformance }, + { 3, HBAO.Preset.Custom }, + { 4, HBAO.Preset.HighQuality }, + { 5, HBAO.Preset.HighestQuality } + }; + + + void OnEnable() + { + m_HBAO = (HBAO)target; + m_HBAOTex = Resources.Load("hbao"); + + m_GroupFields = new Dictionary>(); + + var settingsGroups = typeof(HBAO).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .Where(x => x.GetCustomAttributes(typeof(HBAO.SettingsGroup), false).Any()); + foreach (var group in settingsGroups) + { + foreach (var setting in group.FieldType.GetFields(BindingFlags.Instance | BindingFlags.Public)) + { + if (!m_GroupFields.ContainsKey(group)) + m_GroupFields[group] = new List(); + + var property = serializedObject.FindProperty(group.Name + "." + setting.Name); + if (property != null) + m_GroupFields[group].Add(property); + } + } + + m_SelectedPreset = m_Presets.Values.ToList().IndexOf(m_HBAO.GetCurrentPreset()); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + SetStyles(); + + EditorGUILayout.BeginVertical(); + { + // header + GUILayout.Space(10.0f); + GUILayout.Label(m_HBAOTex, m_TitleLabelStyle, GUILayout.ExpandWidth(true)); + + //if (m_HBAO.GetComponents()[0] != m_HBAO) + //{ + //GUILayout.Space(6.0f); + //EditorGUILayout.HelpBox("This Post FX should be one of the first in your effect stack", MessageType.Info); + //} + + Event e = Event.current; + + // settings groups + foreach (var group in m_GroupFields) + { + var groupProperty = serializedObject.FindProperty(group.Key.Name); + if (groupProperty == null) + continue; + + GUILayout.Space(6.0f); + Rect rect = GUILayoutUtility.GetRect(16f, 22f, m_SettingsGroupStyle); + GUI.Box(rect, ObjectNames.NicifyVariableName(groupProperty.displayName), m_SettingsGroupStyle); + if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) + { + groupProperty.isExpanded = !groupProperty.isExpanded; + e.Use(); + } + + if (!groupProperty.isExpanded) + continue; + + // presets is a special case + if (group.Key.FieldType == typeof(HBAO.Presets)) + { + GUILayout.Space(6.0f); + m_SelectedPreset = GUILayout.SelectionGrid(m_SelectedPreset, m_Presets.Values.Select(x => ObjectNames.NicifyVariableName(x.ToString())).ToArray(), 3); + GUILayout.Space(6.0f); + if (GUILayout.Button("Apply Preset")) + { + Undo.RecordObject(target, "Apply Preset"); + m_HBAO.ApplyPreset(m_Presets[m_SelectedPreset]); + EditorUtility.SetDirty(target); + if (!EditorApplication.isPlaying) + { + UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene()); + } + } + } + + foreach (var field in group.Value) + { + // hide real presets + if (group.Key.FieldType == typeof(HBAO.Presets)) + continue; + + // hide resolution when deinterleaved HBAO is on + if (group.Key.FieldType == typeof(HBAO.GeneralSettings) && field.name == "resolution") + { + if (m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled) + { + continue; + } + } + // hide noise type when deinterleaved HBAO is on + else if (group.Key.FieldType == typeof(HBAO.GeneralSettings) && field.name == "noiseType") + { + if (m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled) + { + continue; + } + } + // hide useMultiBounce setting in BeforeReflections integration stage + else if (group.Key.FieldType == typeof(HBAO.AOSettings) && field.name == "useMultiBounce") + { + if (m_HBAO.GetPipelineStage() == HBAO.PipelineStage.BeforeReflections) + { + continue; + } + } + // hide multiBounceInfluence setting when not used + else if (group.Key.FieldType == typeof(HBAO.AOSettings) && field.name == "multiBounceInfluence") + { + if (m_HBAO.GetPipelineStage() == HBAO.PipelineStage.BeforeReflections || !m_HBAO.UseMultiBounce()) + { + continue; + } + } + // warn about distance falloff greater than max distance + else if (group.Key.FieldType == typeof(HBAO.AOSettings) && field.name == "perPixelNormals") + { + if (m_HBAO.GetAoDistanceFalloff() > m_HBAO.GetAoMaxDistance()) + { + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("Distance Falloff shoudn't be greater than Max Distance.", MessageType.Warning); + } + } + // warn about motion vectors not supported + else if (group.Key.FieldType == typeof(HBAO.TemporalFilterSettings) && field.name == "enabled") + { + // For platforms not supporting motion vectors texture + // https://docs.unity3d.com/ScriptReference/DepthTextureMode.MotionVectors.html + if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGHalf)) + { + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("Motion vectors not supported on this platform...", MessageType.Warning); + + if (m_HBAO.IsTemporalFilterEnabled()) + m_HBAO.EnableTemporalFilter(false); + } + else + { + if (IsVrRunning()) + { + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("Not supported yet in VR...", MessageType.Warning); + + if (m_HBAO.IsTemporalFilterEnabled()) + m_HBAO.EnableTemporalFilter(false); + } + } + } + // warn about color bleeding not supported in VR + MSAA prior to 2020.3.13 + else if (group.Key.FieldType == typeof(HBAO.ColorBleedingSettings) && field.name == "enabled") + { +#if !UNITY_2020_3_13_OR_NEWER + if (m_HBAO.IsColorBleedingEnabled() && IsVrRunning()) + { + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("Unity 2020.3.13+ required when using VR + MSAA and color bleeding.", MessageType.Warning); + } +#endif + } + // hide albedoMultiplier when not in deferred + else if (group.Key.FieldType == typeof(HBAO.ColorBleedingSettings) && field.name == "albedoMultiplier") + { + if (m_HBAO.GetPipelineStage() == HBAO.PipelineStage.BeforeImageEffectsOpaque) + continue; + } + + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(12.0f); + EditorGUILayout.PropertyField(field); + EditorGUILayout.EndHorizontal(); + } + } + } + EditorGUILayout.EndVertical(); + + serializedObject.ApplyModifiedProperties(); + } + + private void SetStyles() + { + // set banner label style + m_TitleLabelStyle = new GUIStyle(GUI.skin.label); + m_TitleLabelStyle.alignment = TextAnchor.MiddleCenter; + m_TitleLabelStyle.contentOffset = new Vector2(0f, 0f); + + // get shuriken module title style + GUIStyle skurikenModuleTitleStyle = "ShurikenModuleTitle"; + + // clone it as to not interfere with the original, and adjust it + m_SettingsGroupStyle = new GUIStyle(skurikenModuleTitleStyle); + m_SettingsGroupStyle.font = (new GUIStyle("Label")).font; + m_SettingsGroupStyle.fontStyle = FontStyle.Bold; + m_SettingsGroupStyle.border = new RectOffset(15, 7, 4, 4); + m_SettingsGroupStyle.fixedHeight = 22; + m_SettingsGroupStyle.contentOffset = new Vector2(10f, -2f); + } + + List displays = new List(); + + private bool IsVrRunning() + { + bool vrIsRunning = false; + displays.Clear(); + SubsystemManager.GetSubsystems(displays); + foreach (var displaySubsystem in displays) + { + if (displaySubsystem.running) + { + vrIsRunning = true; + break; + } + } + + return vrIsRunning; + } + + [CustomPropertyDrawer(typeof(HBAO.MinMaxSliderAttribute))] + public class MinMaxSliderDrawer : PropertyDrawer + { + + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + + if (property.propertyType == SerializedPropertyType.Vector2) + { + Vector2 range = property.vector2Value; + float min = range.x; + float max = range.y; + var attr = attribute as HBAO.MinMaxSliderAttribute; + EditorGUI.BeginChangeCheck(); + EditorGUI.MinMaxSlider(position, label, ref min, ref max, attr.min, attr.max); + if (EditorGUI.EndChangeCheck()) + { + range.x = min; + range.y = max; + property.vector2Value = range; + } + } + else + { + EditorGUI.LabelField(position, label, "Use only with Vector2"); + } + } + } + } +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOEditor.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOEditor.cs.meta new file mode 100644 index 00000000..6ea3f96a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOEditor.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: c11bfebf2cb67334d8e543d164ef0cb0 +timeCreated: 1478884394 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOGaiaExtension.cs b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOGaiaExtension.cs new file mode 100644 index 00000000..eb5f48c5 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOGaiaExtension.cs @@ -0,0 +1,140 @@ +#if GAIA_PRESENT && UNITY_EDITOR + +using HorizonBasedAmbientOcclusion; +using UnityEditor; +using UnityEngine; + +namespace Gaia.GX.MichaelJimenez +{ + public class HBAOGaiaExtension : MonoBehaviour + { +#region Generic informational methods + + /// + /// Returns the publisher name if provided. + /// This will override the publisher name in the namespace ie Gaia.GX.PublisherName + /// + /// Publisher name + public static string GetPublisherName() + { + return "Michael Jimenez"; + } + + /// + /// Returns the package name if provided + /// This will override the package name in the class name ie public class PackageName. + /// + /// Package name + public static string GetPackageName() + { + return "Horizon Based Ambient Occlusion"; + } + +#endregion + +#region Methods exposed by Gaia as buttons must be prefixed with GX_ + + public static void GX_About() + { + EditorUtility.DisplayDialog("About Horizon Based Ambient Occlusion ", "HBAO is a post processing image effect to use in order to add realism to your scenes. It helps accentuating small surface details and reproduce light attenuation due to occlusion.\n\nNote: This Post FX should be the first in your effect stack.", "OK"); + } + + public static void GX_Presets_FastestPerformance() + { + HBAO hbao = StackPostFXOnTop(); + if (hbao != null) + { + hbao.ApplyPreset(HBAO.Preset.FastestPerformance); + MarkDirty(hbao); + } + } + + public static void GX_Presets_FastPerformance() + { + HBAO hbao = StackPostFXOnTop(); + if (hbao != null) + { + hbao.ApplyPreset(HBAO.Preset.FastPerformance); + MarkDirty(hbao); + } + } + + public static void GX_Presets_Normal() + { + HBAO hbao = StackPostFXOnTop(); + if (hbao != null) + { + hbao.ApplyPreset(HBAO.Preset.Normal); + MarkDirty(hbao); + } + } + + public static void GX_Presets_HighQuality() + { + HBAO hbao = StackPostFXOnTop(); + if (hbao != null) + { + hbao.ApplyPreset(HBAO.Preset.HighQuality); + MarkDirty(hbao); + } + } + + + public static void GX_Presets_HighestQuality() + { + HBAO hbao = StackPostFXOnTop(); + if (hbao != null) + { + hbao.ApplyPreset(HBAO.Preset.HighestQuality); + MarkDirty(hbao); + } + } + +#endregion + +#region Helper methods + + private static HBAO StackPostFXOnTop() + { + Camera camera = Camera.main; + if (camera == null) + { + camera = FindObjectOfType(); + } + if (camera == null) + { + EditorUtility.DisplayDialog("OOPS!", "Could not find camera to add camera effects to. Please add a camera to your scene.", "OK"); + return null; + } + + // add HBAO to camera + HBAO hbao = camera.GetComponent(); + if (hbao != null) + { + DestroyImmediate(hbao); + } + hbao = camera.gameObject.AddComponent(); + + // stack it on top + while (camera.GetComponents()[0] != hbao) + { + UnityEditorInternal.ComponentUtility.MoveComponentUp(hbao); + } + + return hbao; + } + + private static void MarkDirty(HBAO hbao) + { + EditorUtility.SetDirty(hbao); + if (!EditorApplication.isPlaying) + { + UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene()); + } + } + +#endregion + } +} + +#endif diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOGaiaExtension.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOGaiaExtension.cs.meta new file mode 100644 index 00000000..af960a45 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/HBAOGaiaExtension.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 50df544c23aafa84584188552d7a8cd5 +timeCreated: 1462456119 +licenseType: Store +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources.meta b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources.meta new file mode 100644 index 00000000..bf1922e1 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fff65aff3cee6c44183cf61a6df77cac +folderAsset: yes +timeCreated: 1463304680 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/hbao.png b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/hbao.png new file mode 100644 index 00000000..ddcd86d0 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/hbao.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c61855b2735564a800e507312fac5d6e1b9c2e1c6ee93c9012293480eda821e +size 8563 diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/hbao.png.meta b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/hbao.png.meta new file mode 100644 index 00000000..4fbf7997 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/hbao.png.meta @@ -0,0 +1,55 @@ +fileFormatVersion: 2 +guid: 363f071b5e3670a43ba62ba5322fc4d6 +timeCreated: 1463304735 +licenseType: Store +TextureImporter: + fileIDToRecycleName: {} + serializedVersion: 2 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + linearTexture: 1 + correctGamma: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: .25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 0 + cubemapConvolution: 0 + cubemapConvolutionSteps: 8 + cubemapConvolutionExponent: 1.5 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + filterMode: -1 + aniso: 1 + mipBias: -1 + wrapMode: 1 + nPOTScale: 0 + lightmap: 0 + rGBM: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: .5, y: .5} + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spritePixelsToUnits: 100 + alphaIsTransparency: 1 + textureType: 2 + buildTargetSettings: [] + spriteSheet: + sprites: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/icon.png b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/icon.png new file mode 100644 index 00000000..241fb24b --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71bd1cd6e06c9c0aa61f1d68bd93d154318e7b0d8c532af7cdfbac445d44e4b9 +size 8823 diff --git a/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/icon.png.meta b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/icon.png.meta new file mode 100644 index 00000000..d5255918 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Editor/Resources/icon.png.meta @@ -0,0 +1,101 @@ +fileFormatVersion: 2 +guid: 6daa87e2aaa1bb04d930ca4b4bc926a7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: -1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: -1 + wrapV: -1 + wrapW: -1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + 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: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - serializedVersion: 2 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: ea6ccb6043e0b05449baf0ac8d87f817 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Readme.txt b/Assets/External/Horizon Based Ambient Occlusion/Readme.txt new file mode 100644 index 00000000..78ed2d9d --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Readme.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79201b99293f680b90f3f9c23fdc6542e0a83a865532c7b3a2f17d1b3c605c44 +size 9837 diff --git a/Assets/External/Horizon Based Ambient Occlusion/Readme.txt.meta b/Assets/External/Horizon Based Ambient Occlusion/Readme.txt.meta new file mode 100644 index 00000000..f0990452 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Readme.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5ea4d0d9dc9d11941b341f03453fd6d3 +timeCreated: 1453642158 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Runtime.meta b/Assets/External/Horizon Based Ambient Occlusion/Runtime.meta new file mode 100644 index 00000000..9cbfbd7d --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Runtime.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6b4762034a7dbee44a7dfa37d2418bf2 +folderAsset: yes +timeCreated: 1455959812 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.Runtime.asmdef b/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.Runtime.asmdef new file mode 100644 index 00000000..05539cc9 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.Runtime.asmdef @@ -0,0 +1,20 @@ +{ + "name": "HBAO.Runtime", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.modules.vr", + "expression": "1.0.0", + "define": "ENABLE_VR_MODULE" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.Runtime.asmdef.meta b/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.Runtime.asmdef.meta new file mode 100644 index 00000000..35f2493c --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.Runtime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b83dc51897666cb44bdfbf9671f74e85 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.cs b/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.cs new file mode 100644 index 00000000..a0296d4e --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.cs @@ -0,0 +1,1823 @@ +using UnityEngine; +using UnityEngine.Rendering; +#if ENABLE_VR_MODULE && ENABLE_VR +using XRSettings = UnityEngine.XR.XRSettings; +#endif +#if UNITY_EDITOR +using UnityEditor; +#endif +using System; +using System.Collections.Generic; + +namespace HorizonBasedAmbientOcclusion +{ + [ExecuteInEditMode, ImageEffectAllowedInSceneView, AddComponentMenu("Image Effects/HBAO")] + [RequireComponent(typeof(Camera))] + public class HBAO : MonoBehaviour + { + public enum Preset + { + FastestPerformance, + FastPerformance, + Normal, + HighQuality, + HighestQuality, + Custom + } + + public enum PipelineStage + { + BeforeImageEffectsOpaque, + AfterLighting, + BeforeReflections + } + + public enum Quality + { + Lowest, + Low, + Medium, + High, + Highest + } + + public enum Resolution + { + Full, + Half + } + + public enum NoiseType + { + Dither, + InterleavedGradientNoise, + SpatialDistribution + } + + public enum Deinterleaving + { + Disabled, + x4 + } + + public enum DebugMode + { + Disabled, + AOOnly, + ColorBleedingOnly, + SplitWithoutAOAndWithAO, + SplitWithAOAndAOOnly, + SplitWithoutAOAndAOOnly, + ViewNormals + } + + public enum BlurType + { + None, + Narrow, + Medium, + Wide, + ExtraWide + } + + public enum PerPixelNormals + { + GBuffer, + Camera, + Reconstruct + } + + public enum VarianceClipping + { + Disabled, + _4Tap, + _8Tap + } + + public Shader hbaoShader; + + [Serializable] + public struct Presets + { + public Preset preset; + + [SerializeField] + public static Presets defaults + { + get + { + return new Presets + { + preset = Preset.Normal + }; + } + } + } + + [Serializable] + public struct GeneralSettings + { + [Tooltip("The stage the AO is injected into the rendering pipeline.")] + [Space(6)] + public PipelineStage pipelineStage; + + [Tooltip("The quality of the AO.")] + [Space(10)] + public Quality quality; + + [Tooltip("The deinterleaving factor.")] + public Deinterleaving deinterleaving; + + [Tooltip("The resolution at which the AO is calculated.")] + public Resolution resolution; + + [Tooltip("The type of noise to use.")] + [Space(10)] + public NoiseType noiseType; + + [Tooltip("The debug mode actually displayed on screen.")] + [Space(10)] + public DebugMode debugMode; + + [SerializeField] + public static GeneralSettings defaults + { + get + { + return new GeneralSettings + { + pipelineStage = PipelineStage.BeforeImageEffectsOpaque, + quality = Quality.Medium, + deinterleaving = Deinterleaving.Disabled, + resolution = Resolution.Full, + noiseType = NoiseType.Dither, + debugMode = DebugMode.Disabled + }; + } + } + } + + [Serializable] + public struct AOSettings + { + [Tooltip("AO radius: this is the distance outside which occluders are ignored.")] + [Space(6), Range(0.25f, 5f)] + public float radius; + + [Tooltip("Maximum radius in pixels: this prevents the radius to grow too much with close-up " + + "object and impact on performances.")] + [Range(16, 256)] + public float maxRadiusPixels; + + [Tooltip("For low-tessellated geometry, occlusion variations tend to appear at creases and " + + "ridges, which betray the underlying tessellation. To remove these artifacts, we use " + + "an angle bias parameter which restricts the hemisphere.")] + [Range(0, 0.5f)] + public float bias; + + [Tooltip("This value allows to scale up the ambient occlusion values.")] + [Range(0, 4)] + public float intensity; + + [Tooltip("Enable/disable MultiBounce approximation.")] + public bool useMultiBounce; + + [Tooltip("MultiBounce approximation influence.")] + [Range(0, 1)] + public float multiBounceInfluence; + + [Tooltip("The amount of AO offscreen samples are contributing.")] + [Range(0, 1)] + public float offscreenSamplesContribution; + + [Tooltip("The max distance to display AO.")] + [Space(10)] + public float maxDistance; + + [Tooltip("The distance before max distance at which AO start to decrease.")] + public float distanceFalloff; + + [Tooltip("The type of per pixel normals to use.")] + [Space(10)] + public PerPixelNormals perPixelNormals; + + [Tooltip("This setting allow you to set the base color if the AO, the alpha channel value is unused.")] + [Space(10)] + public Color baseColor; + + [SerializeField] + public static AOSettings defaults + { + get + { + return new AOSettings + { + radius = 0.8f, + maxRadiusPixels = 128f, + bias = 0.05f, + intensity = 1f, + useMultiBounce = false, + multiBounceInfluence = 1f, + offscreenSamplesContribution = 0f, + maxDistance = 150f, + distanceFalloff = 50f, + perPixelNormals = PerPixelNormals.GBuffer, + baseColor = Color.black + }; + } + } + } + + [Serializable] + public struct TemporalFilterSettings + { + [Space(6)] + public bool enabled; + + [Tooltip("The type of variance clipping to use.")] + public VarianceClipping varianceClipping; + + [SerializeField] + public static TemporalFilterSettings defaults + { + get + { + return new TemporalFilterSettings + { + enabled = false, + varianceClipping = VarianceClipping._4Tap + }; + } + } + } + + [Serializable] + public struct BlurSettings + { + [Tooltip("The type of blur to use.")] + [Space(6)] + public BlurType type; + + [Tooltip("This parameter controls the depth-dependent weight of the bilateral filter, to " + + "avoid bleeding across edges. A zero sharpness is a pure Gaussian blur. Increasing " + + "the blur sharpness removes bleeding by using lower weights for samples with large " + + "depth delta from the current pixel.")] + [Space(10), Range(0, 16)] + public float sharpness; + + [SerializeField] + public static BlurSettings defaults + { + get + { + return new BlurSettings + { + type = BlurType.Medium, + sharpness = 8f + }; + } + } + } + + [Serializable] + public struct ColorBleedingSettings + { + [Space(6)] + public bool enabled; + + [Tooltip("This value allows to control the saturation of the color bleeding.")] + [Space(10), Range(0, 4)] + public float saturation; + + [Tooltip("This value allows to scale the contribution of the color bleeding samples.")] + [Range(0, 32)] + public float albedoMultiplier; + + [Tooltip("Use masking on emissive pixels")] + [Range(0, 1)] + public float brightnessMask; + + [Tooltip("Brightness level where masking starts/ends")] + [MinMaxSlider(0, 2)] + public Vector2 brightnessMaskRange; + + [SerializeField] + public static ColorBleedingSettings defaults + { + get + { + return new ColorBleedingSettings + { + enabled = false, + saturation = 1f, + albedoMultiplier = 4f, + brightnessMask = 1f, + brightnessMaskRange = new Vector2(0.0f, 0.5f) + }; + } + } + } + + [AttributeUsage(AttributeTargets.Field)] + public class SettingsGroup : Attribute { } + + [SerializeField, SettingsGroup] + private Presets m_Presets = Presets.defaults; + public Presets presets + { + get { return m_Presets; } + set { m_Presets = value; } + } + + [SerializeField, SettingsGroup] + private GeneralSettings m_GeneralSettings = GeneralSettings.defaults; + public GeneralSettings generalSettings + { + get { return m_GeneralSettings; } + set { m_GeneralSettings = value; } + } + + [SerializeField, SettingsGroup] + private AOSettings m_AOSettings = AOSettings.defaults; + public AOSettings aoSettings + { + get { return m_AOSettings; } + set { m_AOSettings = value; } + } + + [SerializeField, SettingsGroup] + private TemporalFilterSettings m_TemporalFilterSettings = TemporalFilterSettings.defaults; + public TemporalFilterSettings temporalFilterSettings + { + get { return m_TemporalFilterSettings; } + set { m_TemporalFilterSettings = value; } + } + + [SerializeField, SettingsGroup] + private BlurSettings m_BlurSettings = BlurSettings.defaults; + public BlurSettings blurSettings + { + get { return m_BlurSettings; } + set { m_BlurSettings = value; } + } + + [SerializeField, SettingsGroup] + private ColorBleedingSettings m_ColorBleedingSettings = ColorBleedingSettings.defaults; + public ColorBleedingSettings colorBleedingSettings + { + get { return m_ColorBleedingSettings; } + set { m_ColorBleedingSettings = value; } + } + + public class MinMaxSliderAttribute : PropertyAttribute + { + public readonly float max; + public readonly float min; + + public MinMaxSliderAttribute(float min, float max) + { + this.min = min; + this.max = max; + } + } + + public Preset GetCurrentPreset() + { + return m_Presets.preset; + } + + public void ApplyPreset(Preset preset) + { + if (preset == Preset.Custom) + { + m_Presets.preset = preset; + return; + } + + var debugMode = generalSettings.debugMode; + + m_GeneralSettings = GeneralSettings.defaults; + m_AOSettings = AOSettings.defaults; + m_ColorBleedingSettings = ColorBleedingSettings.defaults; + m_BlurSettings = BlurSettings.defaults; + + SetDebugMode(debugMode); + + switch (preset) + { + case Preset.FastestPerformance: + SetQuality(Quality.Lowest); + SetAoRadius(0.5f); + SetAoMaxRadiusPixels(64.0f); + SetBlurType(BlurType.ExtraWide); + break; + case Preset.FastPerformance: + SetQuality(Quality.Low); + SetAoRadius(0.5f); + SetAoMaxRadiusPixels(64.0f); + SetBlurType(BlurType.Wide); + break; + case Preset.HighQuality: + SetQuality(Quality.High); + SetAoRadius(1.0f); + break; + case Preset.HighestQuality: + SetQuality(Quality.Highest); + SetAoRadius(1.2f); + SetAoMaxRadiusPixels(256.0f); + SetBlurType(BlurType.Narrow); + break; + case Preset.Normal: + default: + break; + } + + m_Presets.preset = preset; + } + + public PipelineStage GetPipelineStage() + { + return m_GeneralSettings.pipelineStage; + } + + public void SetPipelineStage(PipelineStage pipelineStage) + { + m_GeneralSettings.pipelineStage = pipelineStage; + } + + public Quality GetQuality() + { + return m_GeneralSettings.quality; + } + + public void SetQuality(Quality quality) + { + m_GeneralSettings.quality = quality; + } + + public Deinterleaving GetDeinterleaving() + { + return m_GeneralSettings.deinterleaving; + } + + public void SetDeinterleaving(Deinterleaving deinterleaving) + { + m_GeneralSettings.deinterleaving = deinterleaving; + } + + public Resolution GetResolution() + { + return m_GeneralSettings.resolution; + } + + public void SetResolution(Resolution resolution) + { + m_GeneralSettings.resolution = resolution; + } + + public NoiseType GetNoiseType() + { + return m_GeneralSettings.noiseType; + } + + public void SetNoiseType(NoiseType noiseType) + { + m_GeneralSettings.noiseType = noiseType; + } + + public DebugMode GetDebugMode() + { + return m_GeneralSettings.debugMode; + } + + public void SetDebugMode(DebugMode debugMode) + { + m_GeneralSettings.debugMode = debugMode; + } + + public float GetAoRadius() + { + return m_AOSettings.radius; + } + + public void SetAoRadius(float radius) + { + m_AOSettings.radius = Mathf.Clamp(radius, 0.25f, 5); + } + + public float GetAoMaxRadiusPixels() + { + return m_AOSettings.maxRadiusPixels; + } + + public void SetAoMaxRadiusPixels(float maxRadiusPixels) + { + m_AOSettings.maxRadiusPixels = Mathf.Clamp(maxRadiusPixels, 16, 256); + } + + public float GetAoBias() + { + return m_AOSettings.bias; + } + + public void SetAoBias(float bias) + { + m_AOSettings.bias = Mathf.Clamp(bias, 0, 0.5f); + } + + public float GetAoOffscreenSamplesContribution() + { + return m_AOSettings.offscreenSamplesContribution; + } + + public void SetAoOffscreenSamplesContribution(float contribution) + { + m_AOSettings.offscreenSamplesContribution = Mathf.Clamp01(contribution); + } + + public float GetAoMaxDistance() + { + return m_AOSettings.maxDistance; + } + + public void SetAoMaxDistance(float maxDistance) + { + m_AOSettings.maxDistance = maxDistance; + } + + public float GetAoDistanceFalloff() + { + return m_AOSettings.distanceFalloff; + } + + public void SetAoDistanceFalloff(float distanceFalloff) + { + m_AOSettings.distanceFalloff = distanceFalloff; + } + + public PerPixelNormals GetAoPerPixelNormals() + { + return m_AOSettings.perPixelNormals; + } + + public void SetAoPerPixelNormals(PerPixelNormals perPixelNormals) + { + m_AOSettings.perPixelNormals = perPixelNormals; + } + + public Color GetAoColor() + { + return m_AOSettings.baseColor; + } + + public void SetAoColor(Color color) + { + m_AOSettings.baseColor = color; + } + + public float GetAoIntensity() + { + return m_AOSettings.intensity; + } + + public void SetAoIntensity(float intensity) + { + m_AOSettings.intensity = Mathf.Clamp(intensity, 0, 4); + } + + public bool UseMultiBounce() + { + return m_AOSettings.useMultiBounce; + } + + public void EnableMultiBounce(bool enabled = true) + { + m_AOSettings.useMultiBounce = enabled; + } + + public float GetAoMultiBounceInfluence() + { + return m_AOSettings.multiBounceInfluence; + } + + public void SetAoMultiBounceInfluence(float multiBounceInfluence) + { + m_AOSettings.multiBounceInfluence = Mathf.Clamp01(multiBounceInfluence); + } + + public bool IsTemporalFilterEnabled() + { + return m_TemporalFilterSettings.enabled; + } + + public void EnableTemporalFilter(bool enabled = true) + { + m_TemporalFilterSettings.enabled = enabled; + } + + public VarianceClipping GetTemporalFilterVarianceClipping() + { + return m_TemporalFilterSettings.varianceClipping; + } + + public void SetTemporalFilterVarianceClipping(VarianceClipping varianceClipping) + { + m_TemporalFilterSettings.varianceClipping = varianceClipping; + } + + public BlurType GetBlurType() + { + return m_BlurSettings.type; + } + + public void SetBlurType(BlurType blurType) + { + m_BlurSettings.type = blurType; + } + + public float GetBlurSharpness() + { + return m_BlurSettings.sharpness; + } + + public void SetBlurSharpness(float sharpness) + { + m_BlurSettings.sharpness = Mathf.Clamp(sharpness, 0, 16); + } + + public bool IsColorBleedingEnabled() + { + return m_ColorBleedingSettings.enabled; + } + + public void EnableColorBleeding(bool enabled = true) + { + m_ColorBleedingSettings.enabled = enabled; + } + + public float GetColorBleedingSaturation() + { + return m_ColorBleedingSettings.saturation; + } + + public void SetColorBleedingSaturation(float saturation) + { + m_ColorBleedingSettings.saturation = Mathf.Clamp(saturation, 0, 4); + } + + public float GetColorBleedingAlbedoMultiplier() + { + return m_ColorBleedingSettings.albedoMultiplier; + } + + public void SetColorBleedingAlbedoMultiplier(float albedoMultiplier) + { + m_ColorBleedingSettings.albedoMultiplier = Mathf.Clamp(albedoMultiplier, 0, 32); + } + + public float GetColorBleedingBrightnessMask() + { + return m_ColorBleedingSettings.brightnessMask; + } + + public void SetColorBleedingBrightnessMask(float brightnessMask) + { + m_ColorBleedingSettings.brightnessMask = Mathf.Clamp01(brightnessMask); + } + + public Vector2 GetColorBleedingBrightnessMaskRange() + { + return m_ColorBleedingSettings.brightnessMaskRange; + } + + public void SetColorBleedingBrightnessMaskRange(Vector2 brightnessMaskRange) + { + brightnessMaskRange.x = Mathf.Clamp(brightnessMaskRange.x, 0, 2); + brightnessMaskRange.y = Mathf.Clamp(brightnessMaskRange.y, 0, 2); + brightnessMaskRange.x = Mathf.Min(brightnessMaskRange.x, brightnessMaskRange.y); + m_ColorBleedingSettings.brightnessMaskRange = brightnessMaskRange; + } + + private static class Pass + { + public const int AO = 0; + public const int AO_Deinterleaved = 1; + + public const int Deinterleave_Depth = 2; + public const int Deinterleave_Normals = 3; + public const int Atlas_AO_Deinterleaved = 4; + public const int Reinterleave_AO = 5; + + public const int Blur = 6; + + public const int Temporal_Filter = 7; + + public const int Copy = 8; + + public const int Composite = 9; + public const int Composite_AfterLighting = 10; + public const int Composite_BeforeReflections = 11; + public const int Composite_BlendAO = 12; + public const int Composite_BlendCB = 13; + + public const int Debug_ViewNormals = 14; + } + + private static class ShaderProperties + { + public static int mainTex; + public static int hbaoTex; + public static int tempTex; + public static int tempTex2; + public static int noiseTex; + public static int depthTex; + public static int normalsTex; + public static int[] depthSliceTex; + public static int[] normalsSliceTex; + public static int[] aoSliceTex; + public static int[] deinterleaveOffset; + public static int atlasOffset; + public static int jitter; + public static int uvTransform; + public static int inputTexelSize; + public static int aoTexelSize; + public static int deinterleavedAOTexelSize; + public static int reinterleavedAOTexelSize; + public static int uvToView; + //public static int worldToCameraMatrix; + public static int targetScale; + public static int radius; + public static int maxRadiusPixels; + public static int negInvRadius2; + public static int angleBias; + public static int aoMultiplier; + public static int intensity; + public static int multiBounceInfluence; + public static int offscreenSamplesContrib; + public static int maxDistance; + public static int distanceFalloff; + public static int baseColor; + public static int colorBleedSaturation; + public static int albedoMultiplier; + public static int colorBleedBrightnessMask; + public static int colorBleedBrightnessMaskRange; + public static int blurDeltaUV; + public static int blurSharpness; + public static int temporalParams; + + static ShaderProperties() + { + mainTex = Shader.PropertyToID("_MainTex"); + hbaoTex = Shader.PropertyToID("_HBAOTex"); + tempTex = Shader.PropertyToID("_TempTex"); + tempTex2 = Shader.PropertyToID("_TempTex2"); + noiseTex = Shader.PropertyToID("_NoiseTex"); + depthTex = Shader.PropertyToID("_DepthTex"); + normalsTex = Shader.PropertyToID("_NormalsTex"); + depthSliceTex = new int[4 * 4]; + normalsSliceTex = new int[4 * 4]; + aoSliceTex = new int[4 * 4]; + for (int i = 0; i < 4 * 4; i++) + { + depthSliceTex[i] = Shader.PropertyToID("_DepthSliceTex" + i); + normalsSliceTex[i] = Shader.PropertyToID("_NormalsSliceTex" + i); + aoSliceTex[i] = Shader.PropertyToID("_AOSliceTex" + i); + } + deinterleaveOffset = new int[] { + Shader.PropertyToID("_Deinterleave_Offset00"), + Shader.PropertyToID("_Deinterleave_Offset10"), + Shader.PropertyToID("_Deinterleave_Offset01"), + Shader.PropertyToID("_Deinterleave_Offset11") + }; + atlasOffset = Shader.PropertyToID("_AtlasOffset"); + jitter = Shader.PropertyToID("_Jitter"); + uvTransform = Shader.PropertyToID("_UVTransform"); + inputTexelSize = Shader.PropertyToID("_Input_TexelSize"); + aoTexelSize = Shader.PropertyToID("_AO_TexelSize"); + deinterleavedAOTexelSize = Shader.PropertyToID("_DeinterleavedAO_TexelSize"); + reinterleavedAOTexelSize = Shader.PropertyToID("_ReinterleavedAO_TexelSize"); + uvToView = Shader.PropertyToID("_UVToView"); + //worldToCameraMatrix = Shader.PropertyToID("_WorldToCameraMatrix"); + targetScale = Shader.PropertyToID("_TargetScale"); + radius = Shader.PropertyToID("_Radius"); + maxRadiusPixels = Shader.PropertyToID("_MaxRadiusPixels"); + negInvRadius2 = Shader.PropertyToID("_NegInvRadius2"); + angleBias = Shader.PropertyToID("_AngleBias"); + aoMultiplier = Shader.PropertyToID("_AOmultiplier"); + intensity = Shader.PropertyToID("_Intensity"); + multiBounceInfluence = Shader.PropertyToID("_MultiBounceInfluence"); + offscreenSamplesContrib = Shader.PropertyToID("_OffscreenSamplesContrib"); + maxDistance = Shader.PropertyToID("_MaxDistance"); + distanceFalloff = Shader.PropertyToID("_DistanceFalloff"); + baseColor = Shader.PropertyToID("_BaseColor"); + colorBleedSaturation = Shader.PropertyToID("_ColorBleedSaturation"); + albedoMultiplier = Shader.PropertyToID("_AlbedoMultiplier"); + colorBleedBrightnessMask = Shader.PropertyToID("_ColorBleedBrightnessMask"); + colorBleedBrightnessMaskRange = Shader.PropertyToID("_ColorBleedBrightnessMaskRange"); + blurDeltaUV = Shader.PropertyToID("_BlurDeltaUV"); + blurSharpness = Shader.PropertyToID("_BlurSharpness"); + temporalParams = Shader.PropertyToID("_TemporalParams"); + } + + public static string GetOrthographicOrDeferredKeyword(bool orthographic, GeneralSettings settings) + { + // need to check that integrationStage is not BeforeImageEffectOpaque as Gbuffer0 is not available in this case + return orthographic ? "ORTHOGRAPHIC_PROJECTION" : settings.pipelineStage != PipelineStage.BeforeImageEffectsOpaque ? "DEFERRED_SHADING" : "__"; + } + + public static string GetQualityKeyword(GeneralSettings settings) + { + switch (settings.quality) + { + case Quality.Lowest: + return "QUALITY_LOWEST"; + case Quality.Low: + return "QUALITY_LOW"; + case Quality.Medium: + return "QUALITY_MEDIUM"; + case Quality.High: + return "QUALITY_HIGH"; + case Quality.Highest: + return "QUALITY_HIGHEST"; + default: + return "QUALITY_MEDIUM"; + } + } + + public static string GetNoiseKeyword(GeneralSettings settings) + { + switch (settings.noiseType) + { + case NoiseType.InterleavedGradientNoise: + return "INTERLEAVED_GRADIENT_NOISE"; + case NoiseType.Dither: + case NoiseType.SpatialDistribution: + default: + return "__"; + } + } + + public static string GetDeinterleavingKeyword(GeneralSettings settings) + { + switch (settings.deinterleaving) + { + case Deinterleaving.x4: + return "DEINTERLEAVED"; + case Deinterleaving.Disabled: + default: + return "__"; + } + } + + public static string GetDebugKeyword(GeneralSettings settings) + { + switch (settings.debugMode) + { + case DebugMode.AOOnly: + return "DEBUG_AO"; + case DebugMode.ColorBleedingOnly: + return "DEBUG_COLORBLEEDING"; + case DebugMode.SplitWithoutAOAndWithAO: + return "DEBUG_NOAO_AO"; + case DebugMode.SplitWithAOAndAOOnly: + return "DEBUG_AO_AOONLY"; + case DebugMode.SplitWithoutAOAndAOOnly: + return "DEBUG_NOAO_AOONLY"; + case DebugMode.Disabled: + default: + return "__"; + } + } + + public static string GetMultibounceKeyword(AOSettings settings) + { + return settings.useMultiBounce ? "MULTIBOUNCE" : "__"; + } + + public static string GetOffscreenSamplesContributionKeyword(AOSettings settings) + { + return settings.offscreenSamplesContribution > 0 ? "OFFSCREEN_SAMPLES_CONTRIBUTION" : "__"; + } + + public static string GetPerPixelNormalsKeyword(AOSettings settings) + { + switch (settings.perPixelNormals) + { + case PerPixelNormals.Camera: + return "NORMALS_CAMERA"; + case PerPixelNormals.Reconstruct: + return "NORMALS_RECONSTRUCT"; + case PerPixelNormals.GBuffer: + default: + return "__"; + } + } + + public static string GetBlurRadiusKeyword(BlurSettings settings) + { + switch (settings.type) + { + case BlurType.Narrow: + return "BLUR_RADIUS_2"; + case BlurType.Medium: + return "BLUR_RADIUS_3"; + case BlurType.Wide: + return "BLUR_RADIUS_4"; + case BlurType.ExtraWide: + return "BLUR_RADIUS_5"; + case BlurType.None: + default: + return "BLUR_RADIUS_3"; + } + } + + public static string GetVarianceClippingKeyword(TemporalFilterSettings settings) + { + switch (settings.varianceClipping) + { + case VarianceClipping._4Tap: + return "VARIANCE_CLIPPING_4TAP"; + case VarianceClipping._8Tap: + return "VARIANCE_CLIPPING_8TAP"; + case VarianceClipping.Disabled: + default: + return "__"; + } + } + + public static string GetColorBleedingKeyword(ColorBleedingSettings settings) + { + return settings.enabled ? "COLOR_BLEEDING" : "__"; + } + + public static string GetLightingLogEncodedKeyword(bool hdr) + { + return hdr ? "__" : "LIGHTING_LOG_ENCODED"; + } + } + + public enum StereoRenderingMode + { + MultiPass, + SinglePassInstanced + }; + + private static class MersenneTwister + { + // Mersenne-Twister random numbers in [0,1). + public static float[] Numbers = new float[] { + //0.463937f,0.340042f,0.223035f,0.468465f,0.322224f,0.979269f,0.031798f,0.973392f,0.778313f,0.456168f,0.258593f,0.330083f,0.387332f,0.380117f,0.179842f,0.910755f, + //0.511623f,0.092933f,0.180794f,0.620153f,0.101348f,0.556342f,0.642479f,0.442008f,0.215115f,0.475218f,0.157357f,0.568868f,0.501241f,0.629229f,0.699218f,0.707733f + 0.556725f,0.005520f,0.708315f,0.583199f,0.236644f,0.992380f,0.981091f,0.119804f,0.510866f,0.560499f,0.961497f,0.557862f,0.539955f,0.332871f,0.417807f,0.920779f, + 0.730747f,0.076690f,0.008562f,0.660104f,0.428921f,0.511342f,0.587871f,0.906406f,0.437980f,0.620309f,0.062196f,0.119485f,0.235646f,0.795892f,0.044437f,0.617311f + }; + } + + private static readonly Vector2[] s_jitter = new Vector2[4 * 4]; + private static readonly float[] s_temporalRotations = { 60.0f, 300.0f, 180.0f, 240.0f, 120.0f, 0.0f }; + private static readonly float[] s_temporalOffsets = { 0.0f, 0.5f, 0.25f, 0.75f }; + + private Material material { get; set; } + private Camera hbaoCamera { get; set; } + private CommandBuffer cmdBuffer { get; set; } + private int width { get; set; } + private int height { get; set; } + private bool stereoActive { get; set; } + private int xrActiveEye { get; set; } + private StereoRenderingMode stereoRenderingMode { get; set; } + private int screenWidth { get; set; } + private int screenHeight { get; set; } + private int aoWidth { get; set; } + private int aoHeight { get; set; } + private int reinterleavedAoWidth { get; set; } + private int reinterleavedAoHeight { get; set; } + private int deinterleavedAoWidth { get; set; } + private int deinterleavedAoHeight { get; set; } + private int frameCount { get; set; } + private bool motionVectorsSupported { get; set; } + private RenderTexture aoHistoryBuffer { get; set; } + private RenderTexture colorBleedingHistoryBuffer { get; set; } + private Texture2D noiseTex { get; set; } + + private Mesh fullscreenTriangle + { + get + { + if (m_FullscreenTriangle != null) + return m_FullscreenTriangle; + + m_FullscreenTriangle = new Mesh { name = "Fullscreen Triangle" }; + + // Because we have to support older platforms (GLES2/3, DX9 etc) we can't do all of + // this directly in the vertex shader using vertex ids :( + m_FullscreenTriangle.SetVertices(new List + { + new Vector3(-1f, -1f, 0f), + new Vector3(-1f, 3f, 0f), + new Vector3( 3f, -1f, 0f) + }); + m_FullscreenTriangle.SetIndices(new[] { 0, 1, 2 }, MeshTopology.Triangles, 0, false); + m_FullscreenTriangle.UploadMeshData(false); + + return m_FullscreenTriangle; + } + } + + private CameraEvent cameraEvent + { + get + { + // Forces BeforeImageEffectsOpaque as soon as normal display mode isn't used, + // the component still display its integration stage but we force it here to ensure + // all debug modes display correctly. + if (generalSettings.debugMode != DebugMode.Disabled) + return CameraEvent.BeforeImageEffectsOpaque; + + switch (generalSettings.pipelineStage) + { + case PipelineStage.BeforeReflections: + return CameraEvent.BeforeReflections; + case PipelineStage.AfterLighting: + return CameraEvent.AfterLighting; + case PipelineStage.BeforeImageEffectsOpaque: + default: + return CameraEvent.BeforeImageEffectsOpaque; + } + } + } + + private bool isCommandBufferDirty + { + get + { + if (m_IsCommandBufferDirty || m_PreviousPipelineStage != generalSettings.pipelineStage || m_PreviousResolution != generalSettings.resolution || + m_PreviousDebugMode != generalSettings.debugMode || m_PreviousAllowHDR != hbaoCamera.allowHDR || m_PreviousWidth != width || m_PreviousHeight != height || + m_PreviousDeinterleaving != generalSettings.deinterleaving || m_PreviousBlurAmount != blurSettings.type || m_PreviousUseMultibounce != aoSettings.useMultiBounce || + m_PreviousColorBleedingEnabled != colorBleedingSettings.enabled || m_PreviousTemporalFilterEnabled != temporalFilterSettings.enabled || + m_PreviousRenderingPath != hbaoCamera.actualRenderingPath) + { + m_PreviousPipelineStage = generalSettings.pipelineStage; + m_PreviousResolution = generalSettings.resolution; + m_PreviousDebugMode = generalSettings.debugMode; + m_PreviousAllowHDR = hbaoCamera.allowHDR; + m_PreviousWidth = width; + m_PreviousHeight = height; + m_PreviousDeinterleaving = generalSettings.deinterleaving; + m_PreviousBlurAmount = blurSettings.type; + m_PreviousUseMultibounce = aoSettings.useMultiBounce; + m_PreviousColorBleedingEnabled = colorBleedingSettings.enabled; + m_PreviousTemporalFilterEnabled = temporalFilterSettings.enabled; + m_PreviousRenderingPath = hbaoCamera.actualRenderingPath; + + return true; + } + + return false; + } + set + { + m_IsCommandBufferDirty = value; + } + } + + private bool isHistoryBufferDirty + { + get + { + if (aoHistoryBuffer == null || (colorBleedingSettings.enabled && colorBleedingHistoryBuffer == null) || + m_PreviousTemporalFilterEnabled != temporalFilterSettings.enabled || + m_PreviousResolution != generalSettings.resolution || + m_PreviousColorBleedingEnabled != colorBleedingSettings.enabled || + m_PrevStereoRenderingMode != stereoRenderingMode) + { + m_PreviousTemporalFilterEnabled = temporalFilterSettings.enabled; + m_PreviousResolution = generalSettings.resolution; + m_PreviousColorBleedingEnabled = colorBleedingSettings.enabled; + m_PrevStereoRenderingMode = stereoRenderingMode; + + return true; + } + + return false; + } + } + + private static RenderTextureFormat defaultHDRRenderTextureFormat + { + get + { +#if UNITY_ANDROID || UNITY_IPHONE || UNITY_TVOS || UNITY_SWITCH || UNITY_EDITOR + RenderTextureFormat format = RenderTextureFormat.RGB111110Float; +#if UNITY_EDITOR + var target = EditorUserBuildSettings.activeBuildTarget; + if (target != BuildTarget.Android && target != BuildTarget.iOS && target != BuildTarget.tvOS && target != BuildTarget.Switch) + return RenderTextureFormat.DefaultHDR; +#endif // UNITY_EDITOR + if (SystemInfo.SupportsRenderTextureFormat(format)) + return format; +#endif // UNITY_ANDROID || UNITY_IPHONE || UNITY_TVOS || UNITY_SWITCH || UNITY_EDITOR + return RenderTextureFormat.DefaultHDR; + } + } + + private RenderTextureFormat sourceFormat { get { return hbaoCamera.allowHDR ? defaultHDRRenderTextureFormat : RenderTextureFormat.Default; } } + //private static RenderTextureFormat colorFormat { get { return SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB64) ? RenderTextureFormat.ARGB64 : RenderTextureFormat.ARGB32; } } + private static RenderTextureFormat colorFormat { get { return SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default; } } + private static RenderTextureFormat depthFormat { get { return SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RFloat) ? RenderTextureFormat.RFloat : RenderTextureFormat.RHalf; } } + private static RenderTextureFormat normalsFormat { get { return SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB2101010) ? RenderTextureFormat.ARGB2101010 : RenderTextureFormat.Default; } } + private static bool isLinearColorSpace { get { return QualitySettings.activeColorSpace == ColorSpace.Linear; } } + private bool renderingInSceneView { get { return hbaoCamera.cameraType == CameraType.SceneView; } } + + private RenderTextureDescriptor m_sourceDescriptor; + private string[] m_ShaderKeywords; + private Vector4[] m_UVToViewPerEye = new Vector4[2]; + private float[] m_RadiusPerEye = new float[2]; + private bool m_IsCommandBufferDirty; + private Mesh m_FullscreenTriangle; + private PipelineStage? m_PreviousPipelineStage; + private Resolution? m_PreviousResolution; + private Deinterleaving? m_PreviousDeinterleaving; + private DebugMode? m_PreviousDebugMode; + private NoiseType? m_PreviousNoiseType; + private BlurType? m_PreviousBlurAmount; + private int m_PreviousWidth; + private int m_PreviousHeight; + private bool m_PreviousAllowHDR; + private bool m_PreviousUseMultibounce; + private bool m_PreviousColorBleedingEnabled; + private bool m_PreviousTemporalFilterEnabled; + private RenderingPath m_PreviousRenderingPath; + private StereoRenderingMode m_PrevStereoRenderingMode; + + + void OnEnable() + { + if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.Depth)) + { + Debug.LogWarning("HBAO shader is not supported on this platform."); + this.enabled = false; + return; + } + + if (hbaoShader == null) hbaoShader = Shader.Find("Hidden/HBAO"); + if (hbaoShader == null) + { + Debug.LogError("HBAO shader was not found..."); + return; + } + + if (!hbaoShader.isSupported) + { + Debug.LogWarning("HBAO shader is not supported on this platform."); + this.enabled = false; + return; + } + + Initialize(); + } + + void OnDisable() + { + ClearCommandBuffer(cmdBuffer); + + ReleaseHistoryBuffers(); + + if (material != null) + DestroyImmediate(material); + if (noiseTex != null) + DestroyImmediate(noiseTex); + if (fullscreenTriangle != null) + DestroyImmediate(fullscreenTriangle); + } + + void OnPreRender() + { + if (hbaoShader == null || hbaoCamera == null) return; + + FetchRenderParameters(); + CheckParameters(); + UpdateMaterialProperties(); + UpdateShaderKeywords(); + + if (isCommandBufferDirty) + { + ClearCommandBuffer(cmdBuffer); + BuildCommandBuffer(cmdBuffer, cameraEvent); + hbaoCamera.AddCommandBuffer(cameraEvent, cmdBuffer); + isCommandBufferDirty = false; + } + } + + void OnPostRender() + { + frameCount++; + } + + void OnValidate() + { + if (hbaoShader == null || hbaoCamera == null) return; + + CheckParameters(); + } + + private void Initialize() + { + m_sourceDescriptor = new RenderTextureDescriptor(0, 0); + + hbaoCamera = GetComponent(); + hbaoCamera.forceIntoRenderTexture = true; + + material = new Material(hbaoShader); + material.hideFlags = HideFlags.HideAndDontSave; + + // For platforms not supporting motion vectors texture + // https://docs.unity3d.com/ScriptReference/DepthTextureMode.MotionVectors.html + motionVectorsSupported = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGHalf); + + cmdBuffer = new CommandBuffer { name = "HBAO" }; + isCommandBufferDirty = true; + } + + private void FetchRenderParameters() + { +#if !UNITY_SWITCH && ENABLE_VR_MODULE && ENABLE_VR + if (hbaoCamera.stereoEnabled) + { + var xrDesc = XRSettings.eyeTextureDesc; + stereoRenderingMode = StereoRenderingMode.MultiPass; + +#if UNITY_STANDALONE || UNITY_EDITOR || UNITY_PS4 || UNITY_PS5 || UNITY_ANDROID + if (xrDesc.dimension == TextureDimension.Tex2DArray) + stereoRenderingMode = StereoRenderingMode.SinglePassInstanced; +#endif + + width = xrDesc.width; + height = xrDesc.height; + m_sourceDescriptor = xrDesc; + xrActiveEye = (int)hbaoCamera.stereoActiveEye; + screenWidth = XRSettings.eyeTextureWidth; + screenHeight = XRSettings.eyeTextureHeight; + stereoActive = true; + } + else +#endif + { + width = hbaoCamera.pixelWidth; + height = hbaoCamera.pixelHeight; + m_sourceDescriptor.width = width; + m_sourceDescriptor.height = height; + xrActiveEye = 0; + screenWidth = width; + screenHeight = height; + stereoActive = false; + } + + var downsamplingFactor = generalSettings.resolution == Resolution.Full ? 1 : generalSettings.deinterleaving == Deinterleaving.Disabled ? 2 : 1; + if (downsamplingFactor > 1) + { + aoWidth = (width + width % 2) / downsamplingFactor; + aoHeight = (height + height % 2) / downsamplingFactor; + } + else + { + aoWidth = width; + aoHeight = height; + } + + reinterleavedAoWidth = width + (width % 4 == 0 ? 0 : 4 - (width % 4)); + reinterleavedAoHeight = height + (height % 4 == 0 ? 0 : 4 - (height % 4)); + deinterleavedAoWidth = reinterleavedAoWidth / 4; + deinterleavedAoHeight = reinterleavedAoHeight / 4; + } + + private void AllocateHistoryBuffers() + { + ReleaseHistoryBuffers(); + + aoHistoryBuffer = GetScreenSpaceRT(widthOverride: aoWidth, heightOverride: aoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear); + if (colorBleedingSettings.enabled) + colorBleedingHistoryBuffer = GetScreenSpaceRT(widthOverride: aoWidth, heightOverride: aoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear); + + // Clear history buffers to default + var lastActive = RenderTexture.active; + RenderTexture.active = aoHistoryBuffer; + GL.Clear(false, true, Color.white); + if (colorBleedingSettings.enabled) + { + RenderTexture.active = colorBleedingHistoryBuffer; + GL.Clear(false, true, new Color(0, 0, 0, 1)); + } + RenderTexture.active = lastActive; + + frameCount = 0; + } + + private void ReleaseHistoryBuffers() + { + if (aoHistoryBuffer != null) + aoHistoryBuffer.Release(); + + if (colorBleedingHistoryBuffer != null) + colorBleedingHistoryBuffer.Release(); + } + + private void ClearCommandBuffer(CommandBuffer cmd) + { + if (cmd != null) + { + if (hbaoCamera != null) + { + hbaoCamera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, cmd); + hbaoCamera.RemoveCommandBuffer(CameraEvent.AfterLighting, cmd); + hbaoCamera.RemoveCommandBuffer(CameraEvent.BeforeReflections, cmd); + } + cmd.Clear(); + } + } + + private void BuildCommandBuffer(CommandBuffer cmd, CameraEvent cameraEvent) + { + // AO + if (generalSettings.deinterleaving == Deinterleaving.Disabled) + { + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.hbaoTex, widthOverride: aoWidth, heightOverride: aoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear); + AO(cmd); + } + else + { + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.hbaoTex, widthOverride: reinterleavedAoWidth, heightOverride: reinterleavedAoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear); + DeinterleavedAO(cmd); + } + + // Blur + Blur(cmd); + + // Temporal Filter + TemporalFilter(cmd); + + // Composite + Composite(cmd, cameraEvent); + + ReleaseTemporaryRT(cmd, ShaderProperties.hbaoTex); + + //Debug.Log("CommandBuffer has been rebuilt"); + } + + private void AO(CommandBuffer cmd) + { + BlitFullscreenTriangleWithClear(cmd, BuiltinRenderTextureType.CameraTarget, ShaderProperties.hbaoTex, material, new Color(0, 0, 0, 1), Pass.AO); + } + + private void DeinterleavedAO(CommandBuffer cmd) + { + // Deinterleave depth & normals (4x4) + for (int i = 0; i < 4; i++) + { + var rtsDepth = new RenderTargetIdentifier[] { + ShaderProperties.depthSliceTex[(i << 2) + 0], + ShaderProperties.depthSliceTex[(i << 2) + 1], + ShaderProperties.depthSliceTex[(i << 2) + 2], + ShaderProperties.depthSliceTex[(i << 2) + 3] + }; + var rtsNormals = new RenderTargetIdentifier[] { + ShaderProperties.normalsSliceTex[(i << 2) + 0], + ShaderProperties.normalsSliceTex[(i << 2) + 1], + ShaderProperties.normalsSliceTex[(i << 2) + 2], + ShaderProperties.normalsSliceTex[(i << 2) + 3] + }; + + int offsetX = (i & 1) << 1; int offsetY = (i >> 1) << 1; + cmd.SetGlobalVector(ShaderProperties.deinterleaveOffset[0], new Vector2(offsetX + 0, offsetY + 0)); + cmd.SetGlobalVector(ShaderProperties.deinterleaveOffset[1], new Vector2(offsetX + 1, offsetY + 0)); + cmd.SetGlobalVector(ShaderProperties.deinterleaveOffset[2], new Vector2(offsetX + 0, offsetY + 1)); + cmd.SetGlobalVector(ShaderProperties.deinterleaveOffset[3], new Vector2(offsetX + 1, offsetY + 1)); + for (int j = 0; j < 4; j++) + { + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.depthSliceTex[j + 4 * i], widthOverride: deinterleavedAoWidth, heightOverride: deinterleavedAoHeight, colorFormat: depthFormat, readWrite: RenderTextureReadWrite.Linear, filter: FilterMode.Point); + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.normalsSliceTex[j + 4 * i], widthOverride: deinterleavedAoWidth, heightOverride: deinterleavedAoHeight, colorFormat: normalsFormat, readWrite: RenderTextureReadWrite.Linear, filter: FilterMode.Point); + } + BlitFullscreenTriangle(cmd, BuiltinRenderTextureType.CameraTarget, rtsDepth, material, Pass.Deinterleave_Depth); // outputs 4 render textures + BlitFullscreenTriangle(cmd, BuiltinRenderTextureType.CameraTarget, rtsNormals, material, Pass.Deinterleave_Normals); // outputs 4 render textures + } + + // AO on each layer + for (int i = 0; i < 4 * 4; i++) + { + cmd.SetGlobalTexture(ShaderProperties.depthTex, ShaderProperties.depthSliceTex[i]); + cmd.SetGlobalTexture(ShaderProperties.normalsTex, ShaderProperties.normalsSliceTex[i]); + cmd.SetGlobalVector(ShaderProperties.jitter, s_jitter[i]); + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.aoSliceTex[i], widthOverride: deinterleavedAoWidth, heightOverride: deinterleavedAoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear, filter: FilterMode.Point); + BlitFullscreenTriangleWithClear(cmd, BuiltinRenderTextureType.CameraTarget, ShaderProperties.aoSliceTex[i], material, new Color(0, 0, 0, 1), Pass.AO_Deinterleaved); // ao + ReleaseTemporaryRT(cmd, ShaderProperties.depthSliceTex[i]); + ReleaseTemporaryRT(cmd, ShaderProperties.normalsSliceTex[i]); + } + + // Atlas Deinterleaved AO, 4x4 + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex, widthOverride: reinterleavedAoWidth, heightOverride: reinterleavedAoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear); + for (int i = 0; i < 4 * 4; i++) + { + cmd.SetGlobalVector(ShaderProperties.atlasOffset, new Vector2(((i & 1) + (((i & 7) >> 2) << 1)) * deinterleavedAoWidth, (((i & 3) >> 1) + ((i >> 3) << 1)) * deinterleavedAoHeight)); + BlitFullscreenTriangle(cmd, ShaderProperties.aoSliceTex[i], ShaderProperties.tempTex, material, Pass.Atlas_AO_Deinterleaved); // atlassing + ReleaseTemporaryRT(cmd, ShaderProperties.aoSliceTex[i]); + } + + // Reinterleave AO + ApplyFlip(cmd); + BlitFullscreenTriangle(cmd, ShaderProperties.tempTex, ShaderProperties.hbaoTex, material, Pass.Reinterleave_AO); // reinterleave + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex); + } + + private void Blur(CommandBuffer cmd) + { + if (blurSettings.type != BlurType.None) + { + float width = aoWidth; + float height = aoHeight; + if (hbaoCamera.allowDynamicResolution) + { + width *= ScalableBufferManager.widthScaleFactor; + height *= ScalableBufferManager.heightScaleFactor; + } + + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex, widthOverride: aoWidth, heightOverride: aoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear); + cmd.SetGlobalVector(ShaderProperties.blurDeltaUV, new Vector2(1f / width, 0)); + BlitFullscreenTriangle(cmd, ShaderProperties.hbaoTex, ShaderProperties.tempTex, material, Pass.Blur); // blur X + cmd.SetGlobalVector(ShaderProperties.blurDeltaUV, new Vector2(0, 1f / height)); + BlitFullscreenTriangle(cmd, ShaderProperties.tempTex, ShaderProperties.hbaoTex, material, Pass.Blur); // blur Y + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex); + } + } + + private void TemporalFilter(CommandBuffer cmd) + { + if (isHistoryBufferDirty && temporalFilterSettings.enabled) + AllocateHistoryBuffers(); + + if (temporalFilterSettings.enabled && !renderingInSceneView) + { + if (colorBleedingSettings.enabled) + { + // For Color Bleeding we have 2 history buffers to fill so there are 2 render targets. + // AO is still contained in Color Bleeding history buffer (alpha channel) so that we + // can use it as a render texture for the composite pass. + var rts = new RenderTargetIdentifier[] { + aoHistoryBuffer, + colorBleedingHistoryBuffer + }; + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex, widthOverride: aoWidth, heightOverride: aoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear); + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex2, widthOverride: aoWidth, heightOverride: aoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear); + BlitFullscreenTriangle(cmd, aoHistoryBuffer, ShaderProperties.tempTex2, material, Pass.Copy); + BlitFullscreenTriangle(cmd, colorBleedingHistoryBuffer, ShaderProperties.tempTex, material, Pass.Copy); + BlitFullscreenTriangle(cmd, ShaderProperties.tempTex2, rts, material, Pass.Temporal_Filter); + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex); + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex2); + cmd.SetGlobalTexture(ShaderProperties.hbaoTex, colorBleedingHistoryBuffer); + } + else + { + // AO history buffer contains ao in aplha channel so we can just use history as + // a render texture for the composite pass. + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex, widthOverride: aoWidth, heightOverride: aoHeight, colorFormat: colorFormat, readWrite: RenderTextureReadWrite.Linear); + BlitFullscreenTriangle(cmd, aoHistoryBuffer, ShaderProperties.tempTex, material, Pass.Copy); + BlitFullscreenTriangle(cmd, ShaderProperties.tempTex, aoHistoryBuffer, material, Pass.Temporal_Filter); + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex); + cmd.SetGlobalTexture(ShaderProperties.hbaoTex, aoHistoryBuffer); + } + } + } + + private void Composite(CommandBuffer cmd, CameraEvent cameraEvent) + { + if (generalSettings.debugMode == DebugMode.Disabled) + { + if (cameraEvent == CameraEvent.BeforeReflections) + CompositeBeforeReflections(cmd); + else if (cameraEvent == CameraEvent.AfterLighting) + CompositeAfterLighting(cmd); + else // if (BeforeImageEffectsOpaque) + CompositeBeforeImageEffectsOpaque(cmd); + } + else // debug mode + CompositeDebug(cmd, generalSettings.debugMode == DebugMode.ViewNormals ? Pass.Debug_ViewNormals : Pass.Composite); + } + + // Cases of BeforeReflections & AfterLighting + // If using HDR there’s no separate rendertarget being created for Emission+lighting buffer (RT3); + // instead the rendertarget that the Camera renders into (that is, the one that is passed to the image effects) is used as RT3. + // If non-HDR GBuffer3 texture is available. HDR uses ARGBHalf, non-HDR uses ARGB2101010 + // Emission + lighting buffer(RT3) is logarithmically encoded to provide greater dynamic range than is usually possible with + // an ARGB32 texture, when the Camera is not using HDR. + // https://docs.unity3d.com/Manual/RenderTech-DeferredShading.html + + private void CompositeBeforeReflections(CommandBuffer cmd) + { + var hdr = hbaoCamera.allowHDR; + var rts = new RenderTargetIdentifier[] { + BuiltinRenderTextureType.GBuffer0, // Albedo, Occ + hdr ? BuiltinRenderTextureType.CameraTarget : BuiltinRenderTextureType.GBuffer3 // Ambient + }; + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex, colorFormat: RenderTextureFormat.ARGB32); + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex2, colorFormat: hdr ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB2101010); + BlitFullscreenTriangle(cmd, rts[0], ShaderProperties.tempTex, material, Pass.Copy); + BlitFullscreenTriangle(cmd, rts[1], ShaderProperties.tempTex2, material, Pass.Copy); + BlitFullscreenTriangle(cmd, ShaderProperties.tempTex2, rts, material, Pass.Composite_BeforeReflections); + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex); + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex2); + } + + private void CompositeAfterLighting(CommandBuffer cmd) + { + var hdr = hbaoCamera.allowHDR; + var rt3 = hdr ? BuiltinRenderTextureType.CameraTarget : BuiltinRenderTextureType.GBuffer3; + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex, colorFormat: hdr ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB2101010); + BlitFullscreenTriangle(cmd, rt3, ShaderProperties.tempTex, material, Pass.Copy); + BlitFullscreenTriangle(cmd, ShaderProperties.tempTex, rt3, material, Pass.Composite_AfterLighting); + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex); + } + + private void CompositeBeforeImageEffectsOpaque(CommandBuffer cmd) + { + if (aoSettings.useMultiBounce) + { + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex, colorFormat: sourceFormat); + if (stereoActive && hbaoCamera.actualRenderingPath != RenderingPath.DeferredShading) + cmd.Blit(BuiltinRenderTextureType.CameraTarget, ShaderProperties.tempTex); + else + BlitFullscreenTriangle(cmd, BuiltinRenderTextureType.CameraTarget, ShaderProperties.tempTex, material, Pass.Copy); + } + + ApplyFlip(cmd, SystemInfo.graphicsUVStartsAtTop); + BlitFullscreenTriangle(cmd, aoSettings.useMultiBounce ? (RenderTargetIdentifier)ShaderProperties.tempTex : BuiltinRenderTextureType.None, BuiltinRenderTextureType.CameraTarget, material, Pass.Composite_BlendAO); + if (colorBleedingSettings.enabled) + BlitFullscreenTriangle(cmd, BuiltinRenderTextureType.None, BuiltinRenderTextureType.CameraTarget, material, Pass.Composite_BlendCB); + + if (aoSettings.useMultiBounce) + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex); + } + + private void CompositeDebug(CommandBuffer cmd, int finalPassId = Pass.Composite) + { + GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex, colorFormat: sourceFormat); + if (stereoActive && hbaoCamera.actualRenderingPath != RenderingPath.DeferredShading) + cmd.Blit(BuiltinRenderTextureType.CameraTarget, ShaderProperties.tempTex); + else + BlitFullscreenTriangle(cmd, BuiltinRenderTextureType.CameraTarget, ShaderProperties.tempTex, material, Pass.Copy); + ApplyFlip(cmd, SystemInfo.graphicsUVStartsAtTop); + BlitFullscreenTriangle(cmd, ShaderProperties.tempTex, BuiltinRenderTextureType.CameraTarget, material, finalPassId); + ReleaseTemporaryRT(cmd, ShaderProperties.tempTex); + } + + private void UpdateMaterialProperties() + { + int eyeCount = stereoActive && stereoRenderingMode == StereoRenderingMode.SinglePassInstanced && !renderingInSceneView ? 2 : 1; + for (int viewIndex = 0; viewIndex < eyeCount; viewIndex++) + { + var projMatrix = viewIndex == 0 ? hbaoCamera.projectionMatrix : hbaoCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); + float invTanHalfFOVxAR = projMatrix.m00; // m00 => 1.0f / (tanHalfFOV * aspectRatio) + float invTanHalfFOV = projMatrix.m11; // m11 => 1.0f / tanHalfFOV + m_UVToViewPerEye[viewIndex == 0 ? xrActiveEye : viewIndex] = new Vector4(2.0f / invTanHalfFOVxAR, -2.0f / invTanHalfFOV, -1.0f / invTanHalfFOVxAR, 1.0f / invTanHalfFOV); + m_RadiusPerEye[viewIndex == 0 ? xrActiveEye : viewIndex] = aoSettings.radius * 0.5f * (screenHeight / (generalSettings.deinterleaving == Deinterleaving.x4 ? 4 : 1) / (2.0f / invTanHalfFOV)); + } + + //float tanHalfFovY = Mathf.Tan(0.5f * hbaoCamera.fieldOfView * Mathf.Deg2Rad); + //float invFocalLenX = 1.0f / (1.0f / tanHalfFovY * (screenHeight / (float)screenWidth)); + //float invFocalLenY = 1.0f / (1.0f / tanHalfFovY); + float maxRadInPixels = Mathf.Max(16, aoSettings.maxRadiusPixels * Mathf.Sqrt((screenWidth * screenHeight) / (1080.0f * 1920.0f))); + maxRadInPixels /= (generalSettings.deinterleaving == Deinterleaving.x4 ? 4 : 1); + + var targetScale = generalSettings.deinterleaving == Deinterleaving.x4 ? + new Vector4(reinterleavedAoWidth / (float)width, reinterleavedAoHeight / (float)height, 1.0f / (reinterleavedAoWidth / (float)width), 1.0f / (reinterleavedAoHeight / (float)height)) : + generalSettings.resolution == Resolution.Half /*&& aoSettings.perPixelNormals == PerPixelNormals.Reconstruct*/ ? + new Vector4((width + 0.5f) / width, (height + 0.5f) / height, 1f, 1f) : + Vector4.one; + + material.SetTexture(ShaderProperties.noiseTex, noiseTex); + material.SetVector(ShaderProperties.inputTexelSize, new Vector4(1f / width, 1f / height, width, height)); + if (hbaoCamera.allowDynamicResolution) + material.SetVector(ShaderProperties.aoTexelSize, new Vector4(1f / (aoWidth * ScalableBufferManager.widthScaleFactor), 1f / (aoHeight * ScalableBufferManager.heightScaleFactor), aoWidth * ScalableBufferManager.widthScaleFactor, aoHeight * ScalableBufferManager.heightScaleFactor)); + else + material.SetVector(ShaderProperties.aoTexelSize, new Vector4(1f / aoWidth, 1f / aoHeight, aoWidth, aoHeight)); + material.SetVector(ShaderProperties.deinterleavedAOTexelSize, new Vector4(1.0f / deinterleavedAoWidth, 1.0f / deinterleavedAoHeight, deinterleavedAoWidth, deinterleavedAoHeight)); + material.SetVector(ShaderProperties.reinterleavedAOTexelSize, new Vector4(1f / reinterleavedAoWidth, 1f / reinterleavedAoHeight, reinterleavedAoWidth, reinterleavedAoHeight)); + material.SetVector(ShaderProperties.targetScale, targetScale); + //material.SetVector(ShaderProperties.uvToView, new Vector4(2.0f * invFocalLenX, -2.0f * invFocalLenY, -1.0f * invFocalLenX, 1.0f * invFocalLenY)); + material.SetVectorArray(ShaderProperties.uvToView, m_UVToViewPerEye); + //material.SetMatrix(ShaderProperties.worldToCameraMatrix, hbaoCamera.worldToCameraMatrix); + //material.SetFloat(ShaderProperties.radius, aoSettings.radius * 0.5f * ((screenHeight / (generalSettings.deinterleaving == Deinterleaving.x4 ? 4 : 1)) / (tanHalfFovY * 2.0f))); + //material.SetFloat(ShaderProperties.radius, aoSettings.radius * 0.5f * ((screenHeight / (generalSettings.deinterleaving == Deinterleaving.x4 ? 4 : 1)) / (invFocalLenY * 2.0f))); + material.SetFloatArray(ShaderProperties.radius, m_RadiusPerEye); + material.SetFloat(ShaderProperties.maxRadiusPixels, maxRadInPixels); + material.SetFloat(ShaderProperties.negInvRadius2, -1.0f / (aoSettings.radius * aoSettings.radius)); + material.SetFloat(ShaderProperties.angleBias, aoSettings.bias); + material.SetFloat(ShaderProperties.aoMultiplier, 2.0f * (1.0f / (1.0f - aoSettings.bias))); + material.SetFloat(ShaderProperties.intensity, isLinearColorSpace ? aoSettings.intensity : aoSettings.intensity * 0.454545454545455f); + material.SetColor(ShaderProperties.baseColor, aoSettings.baseColor); + material.SetFloat(ShaderProperties.multiBounceInfluence, aoSettings.multiBounceInfluence); + material.SetFloat(ShaderProperties.offscreenSamplesContrib, aoSettings.offscreenSamplesContribution); + material.SetFloat(ShaderProperties.maxDistance, aoSettings.maxDistance); + material.SetFloat(ShaderProperties.distanceFalloff, aoSettings.distanceFalloff); + material.SetFloat(ShaderProperties.blurSharpness, blurSettings.sharpness); + material.SetFloat(ShaderProperties.colorBleedSaturation, colorBleedingSettings.saturation); + material.SetFloat(ShaderProperties.albedoMultiplier, colorBleedingSettings.albedoMultiplier); + material.SetFloat(ShaderProperties.colorBleedBrightnessMask, colorBleedingSettings.brightnessMask); + material.SetVector(ShaderProperties.colorBleedBrightnessMaskRange, AdjustBrightnessMaskToGammaSpace(new Vector2(Mathf.Pow(colorBleedingSettings.brightnessMaskRange.x, 3), Mathf.Pow(colorBleedingSettings.brightnessMaskRange.y, 3)))); + material.SetVector(ShaderProperties.temporalParams, temporalFilterSettings.enabled && !renderingInSceneView ? new Vector2(s_temporalRotations[frameCount % 6] / 360.0f, s_temporalOffsets[frameCount % 4]) : Vector2.zero); + } + + private void UpdateShaderKeywords() + { + if (m_ShaderKeywords == null || m_ShaderKeywords.Length != 12) m_ShaderKeywords = new string[12]; + + m_ShaderKeywords[0] = ShaderProperties.GetOrthographicOrDeferredKeyword(hbaoCamera.orthographic, generalSettings); + m_ShaderKeywords[1] = ShaderProperties.GetQualityKeyword(generalSettings); + m_ShaderKeywords[2] = ShaderProperties.GetNoiseKeyword(generalSettings); + m_ShaderKeywords[3] = ShaderProperties.GetDeinterleavingKeyword(generalSettings); + m_ShaderKeywords[4] = ShaderProperties.GetDebugKeyword(generalSettings); + m_ShaderKeywords[5] = ShaderProperties.GetMultibounceKeyword(aoSettings); + m_ShaderKeywords[6] = ShaderProperties.GetOffscreenSamplesContributionKeyword(aoSettings); + m_ShaderKeywords[7] = ShaderProperties.GetPerPixelNormalsKeyword(aoSettings); + m_ShaderKeywords[8] = ShaderProperties.GetBlurRadiusKeyword(blurSettings); + m_ShaderKeywords[9] = ShaderProperties.GetVarianceClippingKeyword(temporalFilterSettings); + m_ShaderKeywords[10] = ShaderProperties.GetColorBleedingKeyword(colorBleedingSettings); + m_ShaderKeywords[11] = ShaderProperties.GetLightingLogEncodedKeyword(hbaoCamera.allowHDR); + + material.shaderKeywords = m_ShaderKeywords; + } + + private void CheckParameters() + { + // Camera textures + hbaoCamera.depthTextureMode |= DepthTextureMode.Depth; + if (aoSettings.perPixelNormals == PerPixelNormals.Camera) + hbaoCamera.depthTextureMode |= DepthTextureMode.DepthNormals; + if (temporalFilterSettings.enabled) + hbaoCamera.depthTextureMode |= DepthTextureMode.MotionVectors; + + // Settings to force + if (hbaoCamera.actualRenderingPath != RenderingPath.DeferredShading && aoSettings.perPixelNormals == PerPixelNormals.GBuffer) + SetAoPerPixelNormals(PerPixelNormals.Camera); + + if (generalSettings.deinterleaving != Deinterleaving.Disabled && SystemInfo.supportedRenderTargetCount < 4) + SetDeinterleaving(Deinterleaving.Disabled); + + if (generalSettings.pipelineStage != PipelineStage.BeforeImageEffectsOpaque && hbaoCamera.actualRenderingPath != RenderingPath.DeferredShading) + SetPipelineStage(PipelineStage.BeforeImageEffectsOpaque); + + if (generalSettings.pipelineStage != PipelineStage.BeforeImageEffectsOpaque && aoSettings.perPixelNormals == PerPixelNormals.Camera) + SetAoPerPixelNormals(PerPixelNormals.GBuffer); + + if (stereoActive && hbaoCamera.actualRenderingPath != RenderingPath.DeferredShading && aoSettings.perPixelNormals != PerPixelNormals.Reconstruct) + SetAoPerPixelNormals(PerPixelNormals.Reconstruct); + + if (temporalFilterSettings.enabled && !motionVectorsSupported) + EnableTemporalFilter(false); + + if (colorBleedingSettings.enabled && temporalFilterSettings.enabled && SystemInfo.supportedRenderTargetCount < 2) + EnableTemporalFilter(false); + + // Noise texture + if (noiseTex == null || m_PreviousNoiseType != generalSettings.noiseType) + { + if (noiseTex != null) DestroyImmediate(noiseTex); + + CreateNoiseTexture(); + + m_PreviousNoiseType = generalSettings.noiseType; + } + } + + private RenderTextureDescriptor GetDefaultDescriptor(int depthBufferBits = 0, RenderTextureFormat colorFormat = RenderTextureFormat.Default, RenderTextureReadWrite readWrite = RenderTextureReadWrite.Default) + { + var modifiedDesc = new RenderTextureDescriptor(m_sourceDescriptor.width, m_sourceDescriptor.height, + m_sourceDescriptor.colorFormat, depthBufferBits); + modifiedDesc.dimension = m_sourceDescriptor.dimension; + modifiedDesc.volumeDepth = m_sourceDescriptor.volumeDepth; + modifiedDesc.vrUsage = m_sourceDescriptor.vrUsage; + modifiedDesc.msaaSamples = m_sourceDescriptor.msaaSamples; + modifiedDesc.memoryless = m_sourceDescriptor.memoryless; + + modifiedDesc.useMipMap = m_sourceDescriptor.useMipMap; + modifiedDesc.autoGenerateMips = m_sourceDescriptor.autoGenerateMips; + modifiedDesc.enableRandomWrite = m_sourceDescriptor.enableRandomWrite; + modifiedDesc.shadowSamplingMode = m_sourceDescriptor.shadowSamplingMode; + + if (hbaoCamera.allowDynamicResolution) + modifiedDesc.useDynamicScale = true; + + if (colorFormat != RenderTextureFormat.Default) + modifiedDesc.colorFormat = colorFormat; + + if (readWrite == RenderTextureReadWrite.sRGB) + modifiedDesc.sRGB = true; + else if (readWrite == RenderTextureReadWrite.Linear) + modifiedDesc.sRGB = false; + else if (readWrite == RenderTextureReadWrite.Default) + modifiedDesc.sRGB = isLinearColorSpace; + + return modifiedDesc; + } + + private RenderTexture GetScreenSpaceRT(int depthBufferBits = 0, RenderTextureFormat colorFormat = RenderTextureFormat.Default, RenderTextureReadWrite readWrite = RenderTextureReadWrite.Default, + FilterMode filter = FilterMode.Bilinear, int widthOverride = 0, int heightOverride = 0) + { + var desc = GetDefaultDescriptor(depthBufferBits, colorFormat, readWrite); + if (widthOverride > 0) + desc.width = widthOverride; + if (heightOverride > 0) + desc.height = heightOverride; + + var rt = new RenderTexture(desc); + rt.filterMode = filter; + return rt; + } + + private void GetScreenSpaceTemporaryRT(CommandBuffer cmd, int nameID, + int depthBufferBits = 0, RenderTextureFormat colorFormat = RenderTextureFormat.Default, RenderTextureReadWrite readWrite = RenderTextureReadWrite.Default, + FilterMode filter = FilterMode.Bilinear, int widthOverride = 0, int heightOverride = 0) + { + var desc = GetDefaultDescriptor(depthBufferBits, colorFormat, readWrite); + if (widthOverride > 0) + desc.width = widthOverride; + if (heightOverride > 0) + desc.height = heightOverride; + + cmd.GetTemporaryRT(nameID, desc, filter); + } + + private void ReleaseTemporaryRT(CommandBuffer cmd, int nameID) + { + cmd.ReleaseTemporaryRT(nameID); + } + + private void BlitFullscreenTriangle(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, int pass = 0) + { + cmd.SetGlobalTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destination, 0, CubemapFace.Unknown, -1); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, pass); + } + + private void BlitFullscreenTriangle(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier[] destinations, Material material, int pass = 0) + { + cmd.SetGlobalTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destinations, destinations[0], 0, CubemapFace.Unknown, -1); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, pass); + } + + private void BlitFullscreenTriangleWithClear(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, Color clearColor, int pass = 0) + { + cmd.SetGlobalTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destination, 0, CubemapFace.Unknown, -1); + cmd.ClearRenderTarget(false, true, clearColor); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, pass); + } + + private static void ApplyFlip(CommandBuffer cmd, bool flip = true) + { + if (flip) + cmd.SetGlobalVector(ShaderProperties.uvTransform, new Vector4(1f, -1f, 0f, 1f)); + else + cmd.SetGlobalVector(ShaderProperties.uvTransform, new Vector4(1f, 1f, 0f, 0f)); + } + + private static Vector2 AdjustBrightnessMaskToGammaSpace(Vector2 v) + { + return isLinearColorSpace ? v : ToGammaSpace(v); + } + + private static float ToGammaSpace(float v) + { + return Mathf.Pow(v, 0.454545454545455f); + } + + private static Vector2 ToGammaSpace(Vector2 v) + { + return new Vector2(ToGammaSpace(v.x), ToGammaSpace(v.y)); + } + + private void CreateNoiseTexture() + { + noiseTex = new Texture2D(4, 4, SystemInfo.SupportsTextureFormat(TextureFormat.RGHalf) ? TextureFormat.RGHalf : TextureFormat.RGB24, false, true); + noiseTex.filterMode = FilterMode.Point; + noiseTex.wrapMode = TextureWrapMode.Repeat; + int z = 0; + for (int x = 0; x < 4; ++x) + { + for (int y = 0; y < 4; ++y) + { + float r1 = generalSettings.noiseType != NoiseType.Dither ? 0.25f * (0.0625f * ((x + y & 3) << 2) + (x & 3)) : MersenneTwister.Numbers[z++]; + float r2 = generalSettings.noiseType != NoiseType.Dither ? 0.25f * ((y - x) & 3) : MersenneTwister.Numbers[z++]; + Color color = new Color(r1, r2, 0); + noiseTex.SetPixel(x, y, color); + } + } + noiseTex.Apply(); + + for (int i = 0, j = 0; i < s_jitter.Length; ++i) + { + float r1 = MersenneTwister.Numbers[j++]; + float r2 = MersenneTwister.Numbers[j++]; + s_jitter[i] = new Vector2(r1, r2); + } + } + } +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.cs.meta new file mode 100644 index 00000000..06c586eb --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Runtime/HBAO.cs.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: e1580e32f765c994b86a57bb3c49fe75 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: + - noiseTex: {instanceID: 0} + - quadMesh: {instanceID: 0} + - hbaoShader: {fileID: 4800000, guid: 7b834eafaedd0d842bb05a969d9d14bd, type: 3} + executionOrder: 0 + icon: {fileID: 2800000, guid: 6daa87e2aaa1bb04d930ca4b4bc926a7, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP.meta new file mode 100644 index 00000000..4d695dcf --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: b9eaca9eab5e52347a811cead6015f6f +folderAsset: yes +timeCreated: 1582907081 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/HDRP.unitypackage b/Assets/External/Horizon Based Ambient Occlusion/SRP/HDRP.unitypackage new file mode 100644 index 00000000..9ffeef86 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/HDRP.unitypackage @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cfee6bc4ad67919a701f9390705f239179f734c98ef8a6dffa4de8b9cf7d56d2 +size 87385 diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/HDRP.unitypackage.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/HDRP.unitypackage.meta new file mode 100644 index 00000000..c072ca3a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/HDRP.unitypackage.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ec64a5c46b7b32c4c8d953edfaea62b1 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/Readme.txt b/Assets/External/Horizon Based Ambient Occlusion/SRP/Readme.txt new file mode 100644 index 00000000..899a6bea --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/Readme.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b6d2f9314838a2176ff1fa524bd7337a81246e624f4075466a8d52822a2d471 +size 444 diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/Readme.txt.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/Readme.txt.meta new file mode 100644 index 00000000..b12818a3 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/Readme.txt.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 15a5b7bce341d6a4189869b3d1c95ca1 +timeCreated: 1582907133 +licenseType: Store +TextScriptImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP.meta new file mode 100644 index 00000000..6f6ed417 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4c2f710d028e8644b9e7012d3657c785 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP.unitypackage b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP.unitypackage new file mode 100644 index 00000000..129745c4 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP.unitypackage @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc573cc6c7c1add1274a844d0a99f17c78c4376392c18d7b1fdff99a5d57285e +size 93280 diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP.unitypackage.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP.unitypackage.meta new file mode 100644 index 00000000..8611e5e2 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP.unitypackage.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f322ee7f8809e914b9ff960b53a2d90f +timeCreated: 1582908230 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo.meta new file mode 100644 index 00000000..35e82c6a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 77627965239b49c4db3d57d344cb7b8f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Demo.unity b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Demo.unity new file mode 100644 index 00000000..47a3f3dd --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Demo.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:248402325ecf6bdfbfb816b410e0c18b5995f80d1b9e0690f777a468431886cf +size 62217 diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Demo.unity.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Demo.unity.meta new file mode 100644 index 00000000..14d60937 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Demo.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7fd201e2f8d95b9428ab5708b9577531 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Materials.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Materials.meta new file mode 100644 index 00000000..d98f4a69 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d0bb23ae9cc0ea44a4501419c2f20fa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Materials/Dragons.mat b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Materials/Dragons.mat new file mode 100644 index 00000000..2c5db591 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Materials/Dragons.mat @@ -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: Dragons + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, 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: 2800000, guid: ca39994063dd9c94894e7e05a63ed4af, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 2800000, guid: bfacece48cb4c964eb84698e1d9cf1f5, type: 3} + 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: 2800000, guid: ca39994063dd9c94894e7e05a63ed4af, type: 3} + 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: + - _AddPrecomputedVelocity: 0 + - _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 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 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 +--- !u!114 &3150744375204830071 +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: 9 diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Materials/Dragons.mat.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Materials/Dragons.mat.meta new file mode 100644 index 00000000..7f002df5 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Materials/Dragons.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a66ae531fc9a3474caa5ddc1f82de0cd +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Post Process Volume Profile.asset b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Post Process Volume Profile.asset new file mode 100644 index 00000000..1f32ecd9 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Post Process Volume Profile.asset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31e767a1487e34b59e52f6d72dc1521b2b5b05ed21c77e66cb08d1248c6d2842 +size 5022 diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Post Process Volume Profile.asset.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Post Process Volume Profile.asset.meta new file mode 100644 index 00000000..4c51ddc2 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Post Process Volume Profile.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f1c9c1b41992f574b96467b208087240 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Prefabs.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Prefabs.meta new file mode 100644 index 00000000..5e60da98 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Prefabs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bcc72c6af57f7c143aa431b0886b0937 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Prefabs/Dragons Candle.prefab b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Prefabs/Dragons Candle.prefab new file mode 100644 index 00000000..1f44849a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Prefabs/Dragons Candle.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a4109c689a304239721dd02c9f55fd2399cbb785c14bf2835daf1d854e1f524 +size 2720 diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Prefabs/Dragons Candle.prefab.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Prefabs/Dragons Candle.prefab.meta new file mode 100644 index 00000000..65282e40 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Prefabs/Dragons Candle.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4fa342793b1493444a4aa2562a2d6aa4 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime.meta new file mode 100644 index 00000000..914c0699 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9953f3228182b364e8eb030d0c44cd09 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAO.Demo.Universal.Runtime.asmdef b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAO.Demo.Universal.Runtime.asmdef new file mode 100644 index 00000000..5245d65a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAO.Demo.Universal.Runtime.asmdef @@ -0,0 +1,17 @@ +{ + "name": "HBAO.Demo.Universal.Runtime", + "rootNamespace": "", + "references": [ + "GUID:09d385cb911270749b709e1bb48e9ea1", + "GUID:df380645f10b7bc4b97d4f5eb6303d95" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAO.Demo.Universal.Runtime.asmdef.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAO.Demo.Universal.Runtime.asmdef.meta new file mode 100644 index 00000000..f8365442 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAO.Demo.Universal.Runtime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 611af4d5a827be644a4876b4cb89fb6b +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAOControl.cs b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAOControl.cs new file mode 100644 index 00000000..49fb9a1d --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAOControl.cs @@ -0,0 +1,61 @@ +using UnityEngine; +using UnityEngine.Rendering; + +namespace HorizonBasedAmbientOcclusion.Universal +{ + public class HBAOControl : MonoBehaviour + { + public VolumeProfile postProcessProfile; + public UnityEngine.UI.Slider aoRadiusSlider; + + private bool m_HbaoDisplayed = true; + + public void Start() + { + HBAO hbao; + postProcessProfile.TryGet(out hbao); + + if (hbao != null) + { + hbao.EnableHBAO(true); + hbao.SetDebugMode(HBAO.DebugMode.Disabled); + hbao.SetAoRadius(aoRadiusSlider.value); + } + } + + public void ToggleHBAO() + { + HBAO hbao; + postProcessProfile.TryGet(out hbao); + + if (hbao != null) + { + m_HbaoDisplayed = !m_HbaoDisplayed; + hbao.EnableHBAO(m_HbaoDisplayed); + } + } + + public void ToggleShowAO() + { + HBAO hbao; + postProcessProfile.TryGet(out hbao); + + if (hbao != null) + { + if (hbao.GetDebugMode() != HBAO.DebugMode.Disabled) + hbao.SetDebugMode(HBAO.DebugMode.Disabled); + else + hbao.SetDebugMode(HBAO.DebugMode.AOOnly); + } + } + + public void UpdateAoRadius() + { + HBAO hbao; + postProcessProfile.TryGet(out hbao); + + if (hbao != null) + hbao.SetAoRadius(aoRadiusSlider.value); + } + } +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAOControl.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAOControl.cs.meta new file mode 100644 index 00000000..cfa7f32f --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/HBAOControl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 29ecb91848e7b0e4396f2e31373e63e8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/RotateObject.cs b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/RotateObject.cs new file mode 100644 index 00000000..1f95f66c --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/RotateObject.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace HorizonBasedAmbientOcclusion.Universal +{ + public class RotateObject : MonoBehaviour + { + // Use this for initialization + void Start() + { + + } + + // Update is called once per frame + void Update() + { + transform.Rotate(Vector3.up * Time.deltaTime * 15.0f, Space.World); + } + } +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/RotateObject.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/RotateObject.cs.meta new file mode 100644 index 00000000..002c89a0 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Demo/Runtime/RotateObject.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 661c50f52ae812e42a32e8ed7dfa84c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor.meta new file mode 100644 index 00000000..ccf8aaf4 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a82bfeb39ff8ba5459ceb4eb8d655938 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAO.Universal.Editor.asmdef b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAO.Universal.Editor.asmdef new file mode 100644 index 00000000..b34bf56c --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAO.Universal.Editor.asmdef @@ -0,0 +1,20 @@ +{ + "name": "HBAO.Universal.Editor", + "rootNamespace": "", + "references": [ + "GUID:09d385cb911270749b709e1bb48e9ea1", + "GUID:df380645f10b7bc4b97d4f5eb6303d95", + "GUID:3eae0364be2026648bf74846acb8a731" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAO.Universal.Editor.asmdef.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAO.Universal.Editor.asmdef.meta new file mode 100644 index 00000000..a0d56946 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAO.Universal.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f352a4e1c986a0b4e8661cfff9c14881 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAOEditor.cs b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAOEditor.cs new file mode 100644 index 00000000..523cdb1d --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAOEditor.cs @@ -0,0 +1,340 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEditor.Rendering; +using UnityEngine; +using UnityEngine.Rendering; + +namespace HorizonBasedAmbientOcclusion.Universal +{ +#if UNITY_2022_2_OR_NEWER + [CustomEditor(typeof(HBAO))] +#else + [VolumeComponentEditor(typeof(HBAO))] +#endif + public class HBAOEditor : VolumeComponentEditor + { + private HBAO m_HBAO; + private Texture2D m_HBAOTex; + private GUIStyle m_SettingsGroupStyle; + private GUIStyle m_TitleLabelStyle; + private int m_SelectedPreset; + private PropertyFetcher m_PropertyFetcher; + + // settings group + private Dictionary> m_GroupFields; + private readonly Dictionary m_Presets = new Dictionary() + { + { 0, HBAO.Preset.Normal }, + { 1, HBAO.Preset.FastPerformance }, + { 2, HBAO.Preset.FastestPerformance }, + { 3, HBAO.Preset.Custom }, + { 4, HBAO.Preset.HighQuality }, + { 5, HBAO.Preset.HighestQuality } + }; + +#if UNITY_2021_2_OR_NEWER + public override bool hasAdditionalProperties => false; +#else + public override bool hasAdvancedMode => false; +#endif + + public override void OnEnable() + { + base.OnEnable(); + + m_HBAO = (HBAO)target; + m_HBAOTex = Resources.Load("hbao_urp"); + + //var o = new PropertyFetcher(serializedObject); + m_PropertyFetcher = new PropertyFetcher(serializedObject); + m_GroupFields = new Dictionary>(); + + var settings = m_HBAO.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .Where(t => t.FieldType.IsSubclassOf(typeof(VolumeParameter))) + .Where(t => (t.IsPublic && t.GetCustomAttributes(typeof(NonSerializedAttribute), false).Length == 0) || + (t.GetCustomAttributes(typeof(SerializeField), false).Length > 0)) + .Where(t => t.GetCustomAttributes(typeof(HideInInspector), false).Length == 0) + .Where(t => t.GetCustomAttributes(typeof(HBAO.SettingsGroup), false).Any()); + foreach (var setting in settings) + { + //Debug.Log("setting name: " + setting.Name); + + foreach (var attr in setting.GetCustomAttributes(typeof(HBAO.SettingsGroup)) as IEnumerable) + { + if (!m_GroupFields.ContainsKey(attr)) + m_GroupFields[attr] = new List(); + + m_GroupFields[attr].Add(setting); + } + } + + m_SelectedPreset = m_Presets.Values.ToList().IndexOf(m_HBAO.GetCurrentPreset()); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + + SetStyles(); + + EditorGUILayout.BeginVertical(); + { + // header + GUILayout.Space(10.0f); + GUILayout.Label(m_HBAOTex, m_TitleLabelStyle, GUILayout.ExpandWidth(true)); + + //if (m_HBAO.GetComponents()[0] != m_HBAO) + //{ + //GUILayout.Space(6.0f); + //EditorGUILayout.HelpBox("This Post FX should be one of the first in your effect stack", MessageType.Info); + //} + + Event e = Event.current; + + // settings groups + foreach (var group in m_GroupFields) + { + GUILayout.Space(6.0f); + Rect rect = GUILayoutUtility.GetRect(16f, 22f, m_SettingsGroupStyle); + GUI.Box(rect, ObjectNames.NicifyVariableName(group.Key.GetType().Name), m_SettingsGroupStyle); + if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) + { + group.Key.isExpanded = !group.Key.isExpanded; + e.Use(); + } + + if (!group.Key.isExpanded) + continue; + + // presets is a special case + if (group.Key.GetType() == typeof(HBAO.Presets)) + { + GUILayout.Space(6.0f); + m_SelectedPreset = GUILayout.SelectionGrid(m_SelectedPreset, m_Presets.Values.Select(x => ObjectNames.NicifyVariableName(x.ToString())).ToArray(), 3); + GUILayout.Space(6.0f); + if (GUILayout.Button("Apply Preset")) + { + Undo.RecordObject(target, "Apply Preset"); + m_HBAO.ApplyPreset(m_Presets[m_SelectedPreset]); + EditorUtility.SetDirty(target); + /*if (!EditorApplication.isPlaying) + { + UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEngine.SceneManagement.SceneManager.GetActiveScene()); + }*/ + } + + continue; + } + + foreach (var field in group.Value) + { + // warn about URP10+ required when mode is LitAO + if (group.Key.GetType() == typeof(HBAO.GeneralSettings) && field.Name == "renderingPath") + { +#if UNITY_2021_2_OR_NEWER + if (m_HBAO.mode.overrideState && m_HBAO.mode.value != HBAO.Mode.LitAO) + { + continue; // hides rendering path settings when not LitAO + } +#else + continue; // hides rendering path before URP12 +#endif + } + + // hide resolution when deinterleaved HBAO is on + if (group.Key.GetType() == typeof(HBAO.GeneralSettings) && field.Name == "resolution") + { + if (m_HBAO.deinterleaving.overrideState && m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled) + { + continue; + } + } + // hide noise type when deinterleaved HBAO is on + else if (group.Key.GetType() == typeof(HBAO.GeneralSettings) && field.Name == "noiseType") + { + if (m_HBAO.deinterleaving.overrideState && m_HBAO.GetDeinterleaving() != HBAO.Deinterleaving.Disabled) + { + continue; + } + } + // warn about HBAO being disabled by default + else if (group.Key.GetType() == typeof(HBAO.AOSettings) && field.Name == "radius") + { + if (m_HBAO.intensity.overrideState == false) + { + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("The effect is disabled by default, you need to override intensity value in order to enable HBAO.", MessageType.Warning); + } + } + // hide useMultiBounce setting when mode is LitAO + else if (group.Key.GetType() == typeof(HBAO.AOSettings) && field.Name == "useMultiBounce") + { + if (m_HBAO.mode.overrideState && m_HBAO.mode.value == HBAO.Mode.LitAO) + { + continue; + } + } + // hide multiBounceInfluence setting when not used or when mode is LitAO + else if (group.Key.GetType() == typeof(HBAO.AOSettings) && field.Name == "multiBounceInfluence") + { + if (!m_HBAO.useMultiBounce.overrideState || !m_HBAO.UseMultiBounce() || + (m_HBAO.mode.overrideState && m_HBAO.mode.value == HBAO.Mode.LitAO)) + { + continue; + } + } + // hide directLightingStrength setting when mode is normal + else if (group.Key.GetType() == typeof(HBAO.AOSettings) && field.Name == "directLightingStrength") + { + if (!m_HBAO.mode.overrideState || m_HBAO.mode.value == HBAO.Mode.Normal) + { + continue; + } + } + // warn about distance falloff greater than max distance + else if (group.Key.GetType() == typeof(HBAO.AOSettings) && field.Name == "perPixelNormals") + { + if ((m_HBAO.distanceFalloff.overrideState || m_HBAO.maxDistance.overrideState) && m_HBAO.GetAoDistanceFalloff() > m_HBAO.GetAoMaxDistance()) + { + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("Distance Falloff shoudn't be greater than Max Distance.", MessageType.Warning); + } + } + // warn about motion vectors not supported + else if (group.Key.GetType() == typeof(HBAO.TemporalFilterSettings) && field.Name == "temporalFilterEnabled") + { + // For platforms not supporting motion vectors texture + // https://docs.unity3d.com/ScriptReference/DepthTextureMode.MotionVectors.html + if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGHalf)) + { + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("Motion vectors not supported on this platform...", MessageType.Warning); + + if (m_HBAO.IsTemporalFilterEnabled()) + m_HBAO.EnableTemporalFilter(false); + } + else + { +#if !UNITY_2021_2_OR_NEWER + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("Requires proper motion vectors support available in 2021.2+", MessageType.Warning); + + if (m_HBAO.IsTemporalFilterEnabled()) + m_HBAO.EnableTemporalFilter(false); +#else + if (IsVrRunning()) + { + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("Not supported yet in VR...", MessageType.Warning); + + if (m_HBAO.IsTemporalFilterEnabled()) + m_HBAO.EnableTemporalFilter(false); + } +#endif + } + } + // warn about color bleeding not supported when doing LitAO + else if (group.Key.GetType() == typeof(HBAO.ColorBleedingSettings) && field.Name == "colorBleedingEnabled") + { + if (m_HBAO.mode.overrideState && m_HBAO.mode.value == HBAO.Mode.LitAO) + { + GUILayout.Space(6.0f); + EditorGUILayout.HelpBox("Color bleeding can't be used in LitAO mode as AO is being injected into the lighting.", MessageType.Warning); + + if (m_HBAO.IsColorBleedingEnabled()) + m_HBAO.EnableColorBleeding(false); + } + } + + var parameter = Unpack(m_PropertyFetcher.Find(field.Name)); + var displayName = parameter.displayName; + var hasDisplayName = field.GetCustomAttributes(typeof(HBAO.ParameterDisplayName)).Any(); + if (hasDisplayName) + { + var displayNameAttribute = field.GetCustomAttributes(typeof(HBAO.ParameterDisplayName)).First() as HBAO.ParameterDisplayName; + displayName = displayNameAttribute.name; + } + + PropertyField(parameter, new GUIContent(displayName)); + } + + GUILayout.Space(6.0f); + } + } + EditorGUILayout.EndVertical(); + + serializedObject.ApplyModifiedProperties(); + } + + private void SetStyles() + { + // set banner label style + m_TitleLabelStyle = new GUIStyle(GUI.skin.label); + m_TitleLabelStyle.alignment = TextAnchor.MiddleCenter; + m_TitleLabelStyle.contentOffset = new Vector2(0f, 0f); + + // get shuriken module title style + GUIStyle skurikenModuleTitleStyle = "ShurikenModuleTitle"; + + // clone it as to not interfere with the original, and adjust it + m_SettingsGroupStyle = new GUIStyle(skurikenModuleTitleStyle); + m_SettingsGroupStyle.font = (new GUIStyle("Label")).font; + m_SettingsGroupStyle.fontStyle = FontStyle.Bold; + m_SettingsGroupStyle.border = new RectOffset(15, 7, 4, 4); + m_SettingsGroupStyle.fixedHeight = 22; + m_SettingsGroupStyle.contentOffset = new Vector2(10f, -2f); + } + + List displays = new List(); + + private bool IsVrRunning() + { + bool vrIsRunning = false; + displays.Clear(); + SubsystemManager.GetSubsystems(displays); + foreach (var displaySubsystem in displays) + { + if (displaySubsystem.running) + { + vrIsRunning = true; + break; + } + } + + return vrIsRunning; + } + + [VolumeParameterDrawer(typeof(HBAO.MinMaxFloatParameter))] + public class MaxFloatParameterDrawer : VolumeParameterDrawer + { + public override bool OnGUI(SerializedDataParameter parameter, GUIContent title) + { + if (parameter.value.propertyType == SerializedPropertyType.Vector2) + { + var o = parameter.GetObjectRef(); + var range = o.value; + float x = range.x; + float y = range.y; + + EditorGUI.BeginChangeCheck(); + EditorGUILayout.MinMaxSlider(title, ref x, ref y, o.min, o.max); + if (EditorGUI.EndChangeCheck()) + { + range.x = x; + range.y = y; + o.SetValue(new HBAO.MinMaxFloatParameter(range, o.min, o.max)); + } + return true; + } + else + { + EditorGUILayout.LabelField(title, "Use only with Vector2"); + return false; + } + } + } + } +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAOEditor.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAOEditor.cs.meta new file mode 100644 index 00000000..f11400ee --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/HBAOEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e055f53efc7d248489d6579ce7685547 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/Resources.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/Resources.meta new file mode 100644 index 00000000..02949c25 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 2ad43aa805fd6dd44a59e307ed9aa4bc +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/Resources/hbao_urp.png b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/Resources/hbao_urp.png new file mode 100644 index 00000000..b939917c --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/Resources/hbao_urp.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d959bb0d5fdf2696a8841515e51a9d68214601cd40f70407bfe69c92667ab7dc +size 8881 diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/Resources/hbao_urp.png.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/Resources/hbao_urp.png.meta new file mode 100644 index 00000000..d1eb3e9c --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Editor/Resources/hbao_urp.png.meta @@ -0,0 +1,115 @@ +fileFormatVersion: 2 +guid: ef156e8079ba9474aa9c13a37223ef49 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + 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 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: 1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: -1 + nPOTScale: 0 + 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: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 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 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: WebGL + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime.meta new file mode 100644 index 00000000..9686f3fd --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1f906a4e3c3820d4a9e15a21943c91ed +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.Universal.Runtime.asmdef b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.Universal.Runtime.asmdef new file mode 100644 index 00000000..cf34d9f6 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.Universal.Runtime.asmdef @@ -0,0 +1,23 @@ +{ + "name": "HBAO.Universal.Runtime", + "rootNamespace": "", + "references": [ + "GUID:df380645f10b7bc4b97d4f5eb6303d95", + "GUID:15fc0a57446b3144c949da3e2b9737a9" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.modules.vr", + "expression": "1.0.0", + "define": "ENABLE_VR_MODULE" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.Universal.Runtime.asmdef.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.Universal.Runtime.asmdef.meta new file mode 100644 index 00000000..9df0d616 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.Universal.Runtime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 09d385cb911270749b709e1bb48e9ea1 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.cs b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.cs new file mode 100644 index 00000000..f892fae2 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.cs @@ -0,0 +1,627 @@ +using System; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +namespace HorizonBasedAmbientOcclusion.Universal +{ + [ExecuteInEditMode, VolumeComponentMenu("Lighting/HBAO")] + public class HBAO : VolumeComponent, IPostProcessComponent + { + public enum Preset + { + FastestPerformance, + FastPerformance, + Normal, + HighQuality, + HighestQuality, + Custom + } + + public enum Mode + { + Normal, + LitAO + } + + public enum RenderingPath + { + Forward, + Deferred + } + + public enum Quality + { + Lowest, + Low, + Medium, + High, + Highest + } + + public enum Resolution + { + Full, + Half + } + + public enum NoiseType + { + Dither, + InterleavedGradientNoise, + SpatialDistribution + } + + public enum Deinterleaving + { + Disabled, + x4 + } + + public enum DebugMode + { + Disabled, + AOOnly, + ColorBleedingOnly, + SplitWithoutAOAndWithAO, + SplitWithAOAndAOOnly, + SplitWithoutAOAndAOOnly, + ViewNormals + } + + public enum BlurType + { + None, + Narrow, + Medium, + Wide, + ExtraWide + } + + public enum PerPixelNormals + { + Reconstruct2Samples, + Reconstruct4Samples, + Camera + } + + public enum VarianceClipping + { + Disabled, + _4Tap, + _8Tap + } + + [Serializable] + public sealed class PresetParameter : VolumeParameter + { + public PresetParameter(Preset value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class ModeParameter : VolumeParameter + { + public ModeParameter(Mode value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class RenderingPathParameter : VolumeParameter + { + public RenderingPathParameter(RenderingPath value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class QualityParameter : VolumeParameter + { + public QualityParameter(Quality value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class DeinterleavingParameter : VolumeParameter + { + public DeinterleavingParameter(Deinterleaving value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class ResolutionParameter : VolumeParameter + { + public ResolutionParameter(Resolution value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class NoiseTypeParameter : VolumeParameter + { + public NoiseTypeParameter(NoiseType value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class DebugModeParameter : VolumeParameter + { + public DebugModeParameter(DebugMode value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class PerPixelNormalsParameter : VolumeParameter + { + public PerPixelNormalsParameter(PerPixelNormals value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class VarianceClippingParameter : VolumeParameter + { + public VarianceClippingParameter(VarianceClipping value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class BlurTypeParameter : VolumeParameter + { + public BlurTypeParameter(BlurType value, bool overrideState = false) + : base(value, overrideState) { } + } + + [Serializable] + public sealed class MinMaxFloatParameter : VolumeParameter + { + public float min; + public float max; + + public MinMaxFloatParameter(Vector2 value, float min, float max, bool overrideState = false) + : base(value, overrideState) + { + this.min = min; + this.max = max; + } + } + + [AttributeUsage(AttributeTargets.Field)] + public class SettingsGroup : Attribute + { + public bool isExpanded = true; + } + + [AttributeUsage(AttributeTargets.Field)] + public class ParameterDisplayName : Attribute + { + public string name; + + public ParameterDisplayName(string name) + { + this.name = name; + } + } + + public class Presets : SettingsGroup { } + public class GeneralSettings : SettingsGroup { } + public class AOSettings : SettingsGroup { } + public class TemporalFilterSettings : SettingsGroup { } + public class BlurSettings : SettingsGroup { } + public class ColorBleedingSettings : SettingsGroup { } + + [Presets] + public PresetParameter preset = new PresetParameter(Preset.Normal); + + [Tooltip("The mode of the AO.")] + [GeneralSettings, Space(6)] + public ModeParameter mode = new ModeParameter(Mode.LitAO); + [Tooltip("The rendering path used for AO. Temporary settings as for now rendering path is internal to renderer settings.")] + [GeneralSettings, Space(6)] + public RenderingPathParameter renderingPath = new RenderingPathParameter(RenderingPath.Forward); + [Tooltip("The quality of the AO.")] + [GeneralSettings, Space(6)] + public QualityParameter quality = new QualityParameter(Quality.Medium); + [Tooltip("The deinterleaving factor.")] + [GeneralSettings] + public DeinterleavingParameter deinterleaving = new DeinterleavingParameter(Deinterleaving.Disabled); + [Tooltip("The resolution at which the AO is calculated.")] + [GeneralSettings] + public ResolutionParameter resolution = new ResolutionParameter(Resolution.Full); + [Tooltip("The type of noise to use.")] + [GeneralSettings, Space(10)] + public NoiseTypeParameter noiseType = new NoiseTypeParameter(NoiseType.Dither); + [Tooltip("The debug mode actually displayed on screen.")] + [GeneralSettings, Space(10)] + public DebugModeParameter debugMode = new DebugModeParameter(DebugMode.Disabled); + + [Tooltip("AO radius: this is the distance outside which occluders are ignored.")] + [AOSettings, Space(6)] + public ClampedFloatParameter radius = new ClampedFloatParameter(0.8f, 0.25f, 5f); + [Tooltip("Maximum radius in pixels: this prevents the radius to grow too much with close-up " + + "object and impact on performances.")] + [AOSettings] + public ClampedFloatParameter maxRadiusPixels = new ClampedFloatParameter(128f, 16f, 256f); + [Tooltip("For low-tessellated geometry, occlusion variations tend to appear at creases and " + + "ridges, which betray the underlying tessellation. To remove these artifacts, we use " + + "an angle bias parameter which restricts the hemisphere.")] + [AOSettings] + public ClampedFloatParameter bias = new ClampedFloatParameter(0.05f, 0f, 0.5f); + [Tooltip("This value allows to scale up the ambient occlusion values.")] + [AOSettings] + public ClampedFloatParameter intensity = new ClampedFloatParameter(0f, 0, 4f); + [Tooltip("Enable/disable MultiBounce approximation.")] + [AOSettings] + public BoolParameter useMultiBounce = new BoolParameter(false); + [Tooltip("MultiBounce approximation influence.")] + [AOSettings] + public ClampedFloatParameter multiBounceInfluence = new ClampedFloatParameter(1f, 0f, 1f); + [Tooltip("How much AO affect direct lighting.")] + [AOSettings] + public ClampedFloatParameter directLightingStrength = new ClampedFloatParameter(0.25f, 0, 1f); + [Tooltip("The amount of AO offscreen samples are contributing.")] + [AOSettings] + public ClampedFloatParameter offscreenSamplesContribution = new ClampedFloatParameter(0f, 0f, 1f); + [Tooltip("The max distance to display AO.")] + [AOSettings, Space(10)] + public FloatParameter maxDistance = new FloatParameter(150f); + [Tooltip("The distance before max distance at which AO start to decrease.")] + [AOSettings] + public FloatParameter distanceFalloff = new FloatParameter(50f); + [Tooltip("The type of per pixel normals to use.")] + [AOSettings, Space(10)] + public PerPixelNormalsParameter perPixelNormals = new PerPixelNormalsParameter(PerPixelNormals.Camera); + [Tooltip("This setting allow you to set the base color if the AO, the alpha channel value is unused.")] + [AOSettings, Space(10)] + public ColorParameter baseColor = new ColorParameter(Color.black); + + [TemporalFilterSettings, ParameterDisplayName("Enabled"), Space(6)] + public BoolParameter temporalFilterEnabled = new BoolParameter(false); + [Tooltip("The type of variance clipping to use.")] + [TemporalFilterSettings] + public VarianceClippingParameter varianceClipping = new VarianceClippingParameter(VarianceClipping._4Tap); + + [Tooltip("The type of blur to use.")] + [BlurSettings, ParameterDisplayName("Type"), Space(6)] + public BlurTypeParameter blurType = new BlurTypeParameter(BlurType.Medium); + + [Tooltip("This parameter controls the depth-dependent weight of the bilateral filter, to " + + "avoid bleeding across edges. A zero sharpness is a pure Gaussian blur. Increasing " + + "the blur sharpness removes bleeding by using lower weights for samples with large " + + "depth delta from the current pixel.")] + [BlurSettings, Space(10)] + public ClampedFloatParameter sharpness = new ClampedFloatParameter(8f, 0f, 16f); + + [ColorBleedingSettings, ParameterDisplayName("Enabled"), Space(6)] + public BoolParameter colorBleedingEnabled = new BoolParameter(false); + [Tooltip("This value allows to control the saturation of the color bleeding.")] + [ColorBleedingSettings, Space(10)] + public ClampedFloatParameter saturation = new ClampedFloatParameter(1f, 0f, 4f); + [Tooltip("Use masking on emissive pixels")] + [ColorBleedingSettings] + public ClampedFloatParameter brightnessMask = new ClampedFloatParameter(1f, 0f, 1f); + [Tooltip("Brightness level where masking starts/ends")] + [ColorBleedingSettings] + public MinMaxFloatParameter brightnessMaskRange = new MinMaxFloatParameter(new Vector2(0f, 0.5f), 0f, 2f); + + public void EnableHBAO(bool enable) + { + intensity.overrideState = enable; + } + + public Preset GetCurrentPreset() + { + return preset.value; + } + + public void ApplyPreset(Preset preset) + { + if (preset == Preset.Custom) + { + this.preset.Override(preset); + return; + } + + var actualDebugMode = debugMode.value; + var actualDebugModeOverride = debugMode.overrideState; + SetAllOverridesTo(false); + debugMode.overrideState = actualDebugModeOverride; + debugMode.value = actualDebugMode; + + switch (preset) + { + case Preset.FastestPerformance: + SetQuality(Quality.Lowest); + SetAoRadius(0.5f); + SetAoMaxRadiusPixels(64.0f); + SetBlurType(BlurType.ExtraWide); + break; + case Preset.FastPerformance: + SetQuality(Quality.Low); + SetAoRadius(0.5f); + SetAoMaxRadiusPixels(64.0f); + SetBlurType(BlurType.Wide); + break; + case Preset.HighQuality: + SetQuality(Quality.High); + SetAoRadius(1.0f); + break; + case Preset.HighestQuality: + SetQuality(Quality.Highest); + SetAoRadius(1.2f); + SetAoMaxRadiusPixels(256.0f); + SetBlurType(BlurType.Narrow); + break; + case Preset.Normal: + default: + break; + } + + this.preset.Override(preset); + } + + public Mode GetMode() + { + return mode.value; + } + + public void SetMode(Mode mode) + { + this.mode.Override(mode); + } + + public RenderingPath GetRenderingPath() + { + return renderingPath.value; + } + + public void SetRenderingPath(RenderingPath renderingPath) + { + this.renderingPath.Override(renderingPath); + } + + public Quality GetQuality() + { + return quality.value; + } + + public void SetQuality(Quality quality) + { + this.quality.Override(quality); + } + + public Deinterleaving GetDeinterleaving() + { + return deinterleaving.value; + } + + public void SetDeinterleaving(Deinterleaving deinterleaving) + { + this.deinterleaving.Override(deinterleaving); + } + + public Resolution GetResolution() + { + return resolution.value; + } + + public void SetResolution(Resolution resolution) + { + this.resolution.Override(resolution); + } + + public NoiseType GetNoiseType() + { + return noiseType.value; + } + + public void SetNoiseType(NoiseType noiseType) + { + this.noiseType.Override(noiseType); + } + + public DebugMode GetDebugMode() + { + return debugMode.value; + } + + public void SetDebugMode(DebugMode debugMode) + { + this.debugMode.Override(debugMode); + } + + public float GetAoRadius() + { + return radius.value; + } + + public void SetAoRadius(float radius) + { + this.radius.Override(Mathf.Clamp(radius, this.radius.min, this.radius.max)); + } + + public float GetAoMaxRadiusPixels() + { + return maxRadiusPixels.value; + } + + public void SetAoMaxRadiusPixels(float maxRadiusPixels) + { + this.maxRadiusPixels.Override(Mathf.Clamp(maxRadiusPixels, this.maxRadiusPixels.min, this.maxRadiusPixels.max)); + } + + public float GetAoBias() + { + return bias.value; + } + + public void SetAoBias(float bias) + { + this.bias.Override(Mathf.Clamp(bias, this.bias.min, this.bias.max)); + } + + public float GetAoOffscreenSamplesContribution() + { + return offscreenSamplesContribution.value; + } + + public void SetAoOffscreenSamplesContribution(float offscreenSamplesContribution) + { + this.offscreenSamplesContribution.Override(Mathf.Clamp(offscreenSamplesContribution, this.offscreenSamplesContribution.min, this.offscreenSamplesContribution.max)); + } + + public float GetAoMaxDistance() + { + return maxDistance.value; + } + + public void SetAoMaxDistance(float maxDistance) + { + this.maxDistance.Override(maxDistance); + } + + public float GetAoDistanceFalloff() + { + return distanceFalloff.value; + } + + public void SetAoDistanceFalloff(float distanceFalloff) + { + this.distanceFalloff.Override(distanceFalloff); + } + + public PerPixelNormals GetAoPerPixelNormals() + { + return perPixelNormals.value; + } + + public void SetAoPerPixelNormals(PerPixelNormals perPixelNormals) + { + this.perPixelNormals.Override(perPixelNormals); + } + + public Color GetAoColor() + { + return baseColor.value; + } + + public void SetAoColor(Color baseColor) + { + this.baseColor.Override(baseColor); + } + + public float GetAoIntensity() + { + return intensity.value; + } + + public void SetAoIntensity(float intensity) + { + this.intensity.Override(Mathf.Clamp(intensity, this.intensity.min, this.intensity.max)); + } + + public bool UseMultiBounce() + { + return useMultiBounce.value; + } + + public void EnableMultiBounce(bool enabled = true) + { + useMultiBounce.Override(enabled); + } + + public float GetAoMultiBounceInfluence() + { + return multiBounceInfluence.value; + } + + public void SetAoMultiBounceInfluence(float multiBounceInfluence) + { + this.multiBounceInfluence.Override(Mathf.Clamp(multiBounceInfluence, this.multiBounceInfluence.min, this.multiBounceInfluence.max)); + } + + public bool IsTemporalFilterEnabled() + { + return temporalFilterEnabled.value; + } + + public void EnableTemporalFilter(bool enabled = true) + { + temporalFilterEnabled.Override(enabled); + } + + public VarianceClipping GetTemporalFilterVarianceClipping() + { + return varianceClipping.value; + } + + public void SetTemporalFilterVarianceClipping(VarianceClipping varianceClipping) + { + this.varianceClipping.Override(varianceClipping); + } + + public BlurType GetBlurType() + { + return blurType.value; + } + + public void SetBlurType(BlurType blurType) + { + this.blurType.Override(blurType); + } + + public float GetBlurSharpness() + { + return sharpness.value; + } + + public void SetBlurSharpness(float sharpness) + { + this.sharpness.Override(Mathf.Clamp(sharpness, this.sharpness.min, this.sharpness.max)); + } + + public bool IsColorBleedingEnabled() + { + return colorBleedingEnabled.value; + } + + public void EnableColorBleeding(bool enabled = true) + { + colorBleedingEnabled.Override(enabled); + } + + public float GetColorBleedingSaturation() + { + return saturation.value; + } + + public void SetColorBleedingSaturation(float saturation) + { + this.saturation.Override(Mathf.Clamp(saturation, this.saturation.min, this.saturation.max)); + } + + public float GetColorBleedingBrightnessMask() + { + return brightnessMask.value; + } + + public void SetColorBleedingBrightnessMask(float brightnessMask) + { + this.brightnessMask.Override(Mathf.Clamp(brightnessMask, this.brightnessMask.min, this.brightnessMask.max)); + } + + public Vector2 GetColorBleedingBrightnessMaskRange() + { + return brightnessMaskRange.value; + } + + public void SetColorBleedingBrightnessMaskRange(Vector2 brightnessMaskRange) + { + brightnessMaskRange.x = Mathf.Clamp(brightnessMaskRange.x, this.brightnessMaskRange.min, this.brightnessMaskRange.max); + brightnessMaskRange.y = Mathf.Clamp(brightnessMaskRange.y, this.brightnessMaskRange.min, this.brightnessMaskRange.max); + brightnessMaskRange.x = Mathf.Min(brightnessMaskRange.x, brightnessMaskRange.y); + this.brightnessMaskRange.Override(brightnessMaskRange); + } + + public bool IsActive() => intensity.overrideState && intensity.value > 0; + + public bool IsTileCompatible() => true; + } +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.cs.meta new file mode 100644 index 00000000..b6cea389 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 90fbf49926625114084d7e0c0cffe8d1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAORendererFeature.cs b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAORendererFeature.cs new file mode 100644 index 00000000..0bd93124 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAORendererFeature.cs @@ -0,0 +1,1564 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +#if UNITY_2023_3_OR_NEWER +using UnityEngine.Rendering.RenderGraphModule; +#endif +using UnityEngine.Rendering.Universal; +#if ENABLE_VR_MODULE && ENABLE_VR +using XRSettings = UnityEngine.XR.XRSettings; +#endif + +namespace HorizonBasedAmbientOcclusion.Universal +{ + public class HBAORendererFeature : ScriptableRendererFeature + { + private class HBAORenderPass : ScriptableRenderPass + { + public HBAO hbao; + +#if UNITY_2023_3_OR_NEWER + // Holds the data needed for the render pass. + private class PassData + { + public Material Material { get; set; } + public RenderTextureDescriptor TargetDescriptor { get; set; } + public RenderTextureDescriptor AOTextureDescriptor { get; set; } + public TextureHandle CameraDepthTexture { get; set; } + public TextureHandle SourceTexture { get; set; } + public TextureHandle AOTexture { get; set; } + public TextureHandle TempTexture { get; set; } + public TextureHandle DestinationTexture { get; set; } + public CameraHistoryBuffers HistoryBuffers { get; set; } + public RenderTargetIdentifier[] TemporalFilterRenderTargets { get; set; } + public Mesh FullscreenTriangle { get; set; } + public MaterialPropertyBlock MaterialProperties { get; set; } + public bool UseLitAO { get; set; } + public bool UseColorBleeding { get; set; } + public bool UseBlur { get; set; } + public bool UseTemporalFilter { get; set; } + public float DirectLightingStrength { get; set; } + public bool ShowDebug { get; set; } + public bool ShowViewNormals { get; set; } + public bool RenderingInSceneView { get; set; } + } +#endif + + private static class Pass + { + public const int AO = 0; + public const int AO_Deinterleaved = 1; + + public const int Deinterleave_Depth = 2; + public const int Deinterleave_Normals = 3; + public const int Atlas_AO_Deinterleaved = 4; + public const int Reinterleave_AO = 5; + + public const int Blur = 6; + + public const int Temporal_Filter = 7; + + public const int Copy = 8; + + public const int Composite = 9; + + public const int Debug_ViewNormals = 10; + } + + private static class ShaderProperties + { + public static int mainTex; + public static int inputTex; + public static int hbaoTex; + public static int tempTex; + public static int tempTex2; + public static int noiseTex; + public static int depthTex; + public static int normalsTex; + public static int ssaoTex; + public static int[] depthSliceTex; + public static int[] normalsSliceTex; + public static int[] aoSliceTex; + public static int[] deinterleaveOffset; + public static int atlasOffset; + public static int jitter; + public static int uvTransform; + public static int inputTexelSize; + public static int aoTexelSize; + public static int deinterleavedAOTexelSize; + public static int reinterleavedAOTexelSize; + public static int uvToView; + //public static int worldToCameraMatrix; + public static int targetScale; + public static int radius; + public static int maxRadiusPixels; + public static int negInvRadius2; + public static int angleBias; + public static int aoMultiplier; + public static int intensity; + public static int multiBounceInfluence; + public static int offscreenSamplesContrib; + public static int maxDistance; + public static int distanceFalloff; + public static int baseColor; + public static int colorBleedSaturation; + public static int albedoMultiplier; + public static int colorBleedBrightnessMask; + public static int colorBleedBrightnessMaskRange; + public static int blurDeltaUV; + public static int blurSharpness; + public static int temporalParams; + public static int historyBufferRTHandleScale; + public static int cameraDepthTexture; + public static int screenSpaceOcclusionTexture; + public static int screenSpaceOcclusionParam; +#if UNITY_2023_3_OR_NEWER + public static GlobalKeyword screenSpaceOcclusionKeyword; +#endif + + static ShaderProperties() + { + mainTex = Shader.PropertyToID("_MainTex"); + inputTex = Shader.PropertyToID("_InputTex"); + hbaoTex = Shader.PropertyToID("_HBAOTex"); + tempTex = Shader.PropertyToID("_TempTex"); + tempTex2 = Shader.PropertyToID("_TempTex2"); + noiseTex = Shader.PropertyToID("_NoiseTex"); + depthTex = Shader.PropertyToID("_DepthTex"); + normalsTex = Shader.PropertyToID("_NormalsTex"); + ssaoTex = Shader.PropertyToID("_SSAOTex"); + depthSliceTex = new int[4 * 4]; + normalsSliceTex = new int[4 * 4]; + aoSliceTex = new int[4 * 4]; + for (int i = 0; i < 4 * 4; i++) + { + depthSliceTex[i] = Shader.PropertyToID("_DepthSliceTex" + i); + normalsSliceTex[i] = Shader.PropertyToID("_NormalsSliceTex" + i); + aoSliceTex[i] = Shader.PropertyToID("_AOSliceTex" + i); + } + deinterleaveOffset = new int[] { + Shader.PropertyToID("_Deinterleave_Offset00"), + Shader.PropertyToID("_Deinterleave_Offset10"), + Shader.PropertyToID("_Deinterleave_Offset01"), + Shader.PropertyToID("_Deinterleave_Offset11") + }; + atlasOffset = Shader.PropertyToID("_AtlasOffset"); + jitter = Shader.PropertyToID("_Jitter"); + uvTransform = Shader.PropertyToID("_UVTransform"); + inputTexelSize = Shader.PropertyToID("_Input_TexelSize"); + aoTexelSize = Shader.PropertyToID("_AO_TexelSize"); + deinterleavedAOTexelSize = Shader.PropertyToID("_DeinterleavedAO_TexelSize"); + reinterleavedAOTexelSize = Shader.PropertyToID("_ReinterleavedAO_TexelSize"); + uvToView = Shader.PropertyToID("_UVToView"); + //worldToCameraMatrix = Shader.PropertyToID("_WorldToCameraMatrix"); + targetScale = Shader.PropertyToID("_TargetScale"); + radius = Shader.PropertyToID("_Radius"); + maxRadiusPixels = Shader.PropertyToID("_MaxRadiusPixels"); + negInvRadius2 = Shader.PropertyToID("_NegInvRadius2"); + angleBias = Shader.PropertyToID("_AngleBias"); + aoMultiplier = Shader.PropertyToID("_AOmultiplier"); + intensity = Shader.PropertyToID("_Intensity"); + multiBounceInfluence = Shader.PropertyToID("_MultiBounceInfluence"); + offscreenSamplesContrib = Shader.PropertyToID("_OffscreenSamplesContrib"); + maxDistance = Shader.PropertyToID("_MaxDistance"); + distanceFalloff = Shader.PropertyToID("_DistanceFalloff"); + baseColor = Shader.PropertyToID("_BaseColor"); + colorBleedSaturation = Shader.PropertyToID("_ColorBleedSaturation"); + albedoMultiplier = Shader.PropertyToID("_AlbedoMultiplier"); + colorBleedBrightnessMask = Shader.PropertyToID("_ColorBleedBrightnessMask"); + colorBleedBrightnessMaskRange = Shader.PropertyToID("_ColorBleedBrightnessMaskRange"); + blurDeltaUV = Shader.PropertyToID("_BlurDeltaUV"); + blurSharpness = Shader.PropertyToID("_BlurSharpness"); + temporalParams = Shader.PropertyToID("_TemporalParams"); + historyBufferRTHandleScale = Shader.PropertyToID("_HistoryBuffer_RTHandleScale"); + cameraDepthTexture = Shader.PropertyToID("_CameraDepthTexture"); + screenSpaceOcclusionTexture = Shader.PropertyToID("_ScreenSpaceOcclusionTexture"); + screenSpaceOcclusionParam = Shader.PropertyToID("_AmbientOcclusionParam"); +#if UNITY_2023_3_OR_NEWER + screenSpaceOcclusionKeyword = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceOcclusion); +#endif + } + + public static string GetOrthographicProjectionKeyword(bool orthographic) + { + return orthographic ? "ORTHOGRAPHIC_PROJECTION" : "__"; + } + + public static string GetQualityKeyword(HBAO.Quality quality) + { + switch (quality) + { + case HBAO.Quality.Lowest: + return "QUALITY_LOWEST"; + case HBAO.Quality.Low: + return "QUALITY_LOW"; + case HBAO.Quality.Medium: + return "QUALITY_MEDIUM"; + case HBAO.Quality.High: + return "QUALITY_HIGH"; + case HBAO.Quality.Highest: + return "QUALITY_HIGHEST"; + default: + return "QUALITY_MEDIUM"; + } + } + + public static string GetNoiseKeyword(HBAO.NoiseType noiseType) + { + switch (noiseType) + { + case HBAO.NoiseType.InterleavedGradientNoise: + return "INTERLEAVED_GRADIENT_NOISE"; + case HBAO.NoiseType.Dither: + case HBAO.NoiseType.SpatialDistribution: + default: + return "__"; + } + } + + public static string GetDeinterleavingKeyword(HBAO.Deinterleaving deinterleaving) + { + switch (deinterleaving) + { + case HBAO.Deinterleaving.x4: + return "DEINTERLEAVED"; + case HBAO.Deinterleaving.Disabled: + default: + return "__"; + } + } + + public static string GetDebugKeyword(HBAO.DebugMode debugMode) + { + switch (debugMode) + { + case HBAO.DebugMode.AOOnly: + return "DEBUG_AO"; + case HBAO.DebugMode.ColorBleedingOnly: + return "DEBUG_COLORBLEEDING"; + case HBAO.DebugMode.SplitWithoutAOAndWithAO: + return "DEBUG_NOAO_AO"; + case HBAO.DebugMode.SplitWithAOAndAOOnly: + return "DEBUG_AO_AOONLY"; + case HBAO.DebugMode.SplitWithoutAOAndAOOnly: + return "DEBUG_NOAO_AOONLY"; + case HBAO.DebugMode.Disabled: + default: + return "__"; + } + } + + public static string GetMultibounceKeyword(bool useMultiBounce, bool litAoModeEnabled) + { + return useMultiBounce && !litAoModeEnabled ? "MULTIBOUNCE" : "__"; + } + + public static string GetOffscreenSamplesContributionKeyword(float offscreenSamplesContribution) + { + return offscreenSamplesContribution > 0 ? "OFFSCREEN_SAMPLES_CONTRIBUTION" : "__"; + } + + public static string GetPerPixelNormalsKeyword(HBAO.PerPixelNormals perPixelNormals) + { + switch (perPixelNormals) + { + case HBAO.PerPixelNormals.Reconstruct4Samples: + return "NORMALS_RECONSTRUCT4"; + case HBAO.PerPixelNormals.Reconstruct2Samples: + return "NORMALS_RECONSTRUCT2"; + case HBAO.PerPixelNormals.Camera: + default: + return "__"; + } + } + + public static string GetBlurRadiusKeyword(HBAO.BlurType blurType) + { + switch (blurType) + { + case HBAO.BlurType.Narrow: + return "BLUR_RADIUS_2"; + case HBAO.BlurType.Medium: + return "BLUR_RADIUS_3"; + case HBAO.BlurType.Wide: + return "BLUR_RADIUS_4"; + case HBAO.BlurType.ExtraWide: + return "BLUR_RADIUS_5"; + case HBAO.BlurType.None: + default: + return "BLUR_RADIUS_3"; + } + } + + public static string GetVarianceClippingKeyword(HBAO.VarianceClipping varianceClipping) + { + switch (varianceClipping) + { + case HBAO.VarianceClipping._4Tap: + return "VARIANCE_CLIPPING_4TAP"; + case HBAO.VarianceClipping._8Tap: + return "VARIANCE_CLIPPING_8TAP"; + case HBAO.VarianceClipping.Disabled: + default: + return "__"; + } + } + + public static string GetColorBleedingKeyword(bool colorBleedingEnabled, bool litAoModeEnabled) + { + return colorBleedingEnabled && !litAoModeEnabled ? "COLOR_BLEEDING" : "__"; + } + + public static string GetModeKeyword(HBAO.Mode mode) + { + return mode == HBAO.Mode.LitAO ? "LIT_AO" : "__"; + } + } + + private static class MersenneTwister + { + // Mersenne-Twister random numbers in [0,1). + public static float[] Numbers = new float[] { + //0.463937f,0.340042f,0.223035f,0.468465f,0.322224f,0.979269f,0.031798f,0.973392f,0.778313f,0.456168f,0.258593f,0.330083f,0.387332f,0.380117f,0.179842f,0.910755f, + //0.511623f,0.092933f,0.180794f,0.620153f,0.101348f,0.556342f,0.642479f,0.442008f,0.215115f,0.475218f,0.157357f,0.568868f,0.501241f,0.629229f,0.699218f,0.707733f + 0.556725f,0.005520f,0.708315f,0.583199f,0.236644f,0.992380f,0.981091f,0.119804f,0.510866f,0.560499f,0.961497f,0.557862f,0.539955f,0.332871f,0.417807f,0.920779f, + 0.730747f,0.076690f,0.008562f,0.660104f,0.428921f,0.511342f,0.587871f,0.906406f,0.437980f,0.620309f,0.062196f,0.119485f,0.235646f,0.795892f,0.044437f,0.617311f + }; + } + + private class CameraHistoryBuffers + { + public Camera camera { get; set; } + public BufferedRTHandleSystem historyRTSystem { get; set; } + public int frameCount { get; set; } + public int lastRenderedFrame { get; set; } + } + + private enum HistoryBufferType + { + AmbientOcclusion, + ColorBleeding + } + + private static readonly Vector2[] s_jitter = new Vector2[4 * 4]; + private static readonly float[] s_temporalRotations = { 60.0f, 300.0f, 180.0f, 240.0f, 120.0f, 0.0f }; + private static readonly float[] s_temporalOffsets = { 0.0f, 0.5f, 0.25f, 0.75f }; + + private Material material { get; set; } + private RenderTargetIdentifier source { get; set; } + private CameraData cameraData { get; set; } + private RenderTextureDescriptor sourceDesc { get; set; } + private RenderTextureDescriptor aoDesc { get; set; } + private RenderTextureDescriptor deinterleavedDepthDesc { get; set; } + private RenderTextureDescriptor deinterleavedNormalsDesc { get; set; } + private RenderTextureDescriptor deinterleavedAoDesc { get; set; } + private RenderTextureDescriptor reinterleavedAoDesc { get; set; } + private RenderTextureDescriptor ssaoDesc { get; set; } + private RenderTextureFormat colorFormat { get; set; } + private RenderTextureFormat ssaoFormat { get; set; } + private GraphicsFormat graphicsColorFormat { get; set; } + private GraphicsFormat graphicsDepthFormat { get; set; } + private GraphicsFormat graphicsNormalsFormat { get; set; } + private RenderTextureFormat depthFormat { get; set; } + private RenderTextureFormat normalsFormat { get; set; } + private bool motionVectorsSupported { get; set; } + private Texture2D noiseTex { get; set; } + private static bool isLinearColorSpace { get { return QualitySettings.activeColorSpace == ColorSpace.Linear; } } + private bool renderingInSceneView { get { return cameraData.camera.cameraType == CameraType.SceneView; } } + + private Mesh fullscreenTriangle + { + get + { + if (m_FullscreenTriangle != null) + return m_FullscreenTriangle; + + m_FullscreenTriangle = new Mesh { name = "Fullscreen Triangle" }; + + // Because we have to support older platforms (GLES2/3, DX9 etc) we can't do all of + // this directly in the vertex shader using vertex ids :( + m_FullscreenTriangle.SetVertices(new List + { + new Vector3(-1f, -1f, 0f), + new Vector3(-1f, 3f, 0f), + new Vector3( 3f, -1f, 0f) + }); + m_FullscreenTriangle.SetIndices(new[] { 0, 1, 2 }, MeshTopology.Triangles, 0, false); + m_FullscreenTriangle.UploadMeshData(false); + + return m_FullscreenTriangle; + } + } + + private MaterialPropertyBlock materialPropertyBlock + { + get + { + if (m_MaterialPropertyBlock != null) + return m_MaterialPropertyBlock; + + m_MaterialPropertyBlock = new MaterialPropertyBlock(); + + return m_MaterialPropertyBlock; + } + } + + private Mesh m_FullscreenTriangle; + private MaterialPropertyBlock m_MaterialPropertyBlock; + private HBAO.Resolution? m_PreviousResolution; + private HBAO.NoiseType? m_PreviousNoiseType; + private bool m_PreviousColorBleedingEnabled; +#if ENABLE_VR_MODULE && ENABLE_VR + private XRSettings.StereoRenderingMode m_PrevStereoRenderingMode; +#endif + private string[] m_ShaderKeywords; + private RenderTargetIdentifier[] m_RtsDepth = new RenderTargetIdentifier[4]; + private RenderTargetIdentifier[] m_RtsNormals = new RenderTargetIdentifier[4]; + private RenderTargetIdentifier[] m_RtsTemporalFilter = new RenderTargetIdentifier[2]; + private List m_CameraHistoryBuffers = new List(); + private Vector4[] m_UVToViewPerEye = new Vector4[2]; + private float[] m_RadiusPerEye = new float[2]; + private ProfilingSampler m_ProfilingSampler = new ProfilingSampler("HBAO"); + + + public void FillSupportedRenderTextureFormats() + { + colorFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default; + ssaoFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.R8) ? RenderTextureFormat.R8 : RenderTextureFormat.ARGB32; + graphicsColorFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf) ? GraphicsFormat.R16G16B16A16_SFloat : GraphicsFormat.R8G8B8A8_SRGB; + graphicsDepthFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RFloat) ? GraphicsFormat.R32_SFloat : GraphicsFormat.R16_SFloat; + graphicsNormalsFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB2101010) ? GraphicsFormat.A2R10G10B10_UNormPack32 : GraphicsFormat.R8G8B8A8_SRGB; + depthFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RFloat) ? RenderTextureFormat.RFloat : RenderTextureFormat.RHalf; + normalsFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB2101010) ? RenderTextureFormat.ARGB2101010 : RenderTextureFormat.Default; + motionVectorsSupported = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGHalf); + } + + public void Setup(Shader shader, ScriptableRenderer renderer, RenderingData renderingData) + { + if (material == null) material = CoreUtils.CreateEngineMaterial(shader); + + //--- + FetchVolumeComponent(); + + var passInput = ScriptableRenderPassInput.Depth; + if (hbao.perPixelNormals.value == HBAO.PerPixelNormals.Camera) + passInput |= ScriptableRenderPassInput.Normal; +#if UNITY_2021_2_OR_NEWER + if (hbao.temporalFilterEnabled.value) + passInput |= ScriptableRenderPassInput.Motion; +#endif + ConfigureInput(passInput); + +#if UNITY_2021_2_OR_NEWER +#if !UNITY_2023_3_OR_NEWER + ConfigureColorStoreAction(RenderBufferStoreAction.DontCare); +#endif + + // Configures where the render pass should be injected. + // Rendering after PrePasses is usually correct except when depth priming is in play: + // then we rely on a depth resolve taking place after the PrePasses in order to have it ready for SSAO. + // Hence we set the event to RenderPassEvent.AfterRenderingPrePasses + 1 at the earliest. + renderPassEvent = hbao.debugMode.value == HBAO.DebugMode.Disabled ? + hbao.mode.value == HBAO.Mode.LitAO ? + hbao.renderingPath.value == HBAO.RenderingPath.Deferred ? RenderPassEvent.AfterRenderingGbuffer : RenderPassEvent.AfterRenderingPrePasses + 1 : + RenderPassEvent.BeforeRenderingTransparents : RenderPassEvent.AfterRenderingTransparents; +#else + // Configures where the render pass should be injected. + // Rendering after PrePasses is usually correct except when depth priming is in play: + // then we rely on a depth resolve taking place after the PrePasses in order to have it ready for SSAO. + // Hence we set the event to RenderPassEvent.AfterRenderingPrePasses + 1 at the earliest. + renderPassEvent = hbao.debugMode.value == HBAO.DebugMode.Disabled ? + hbao.mode.value == HBAO.Mode.LitAO ? RenderPassEvent.AfterRenderingPrePasses + 1 : RenderPassEvent.BeforeRenderingTransparents : + RenderPassEvent.AfterRenderingTransparents; +#endif + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) + { + //source = new RenderTargetIdentifier("_CameraColorTexture"); +#if UNITY_2022_1_OR_NEWER + source = renderingData.cameraData.renderer.cameraColorTargetHandle; +#else + source = renderingData.cameraData.renderer.cameraColorTarget; +#endif + cameraData = renderingData.cameraData; + + /* + FetchVolumeComponent(); + + var passInput = ScriptableRenderPassInput.Depth; + if (hbao.perPixelNormals.value == HBAO.PerPixelNormals.Camera) + passInput |= ScriptableRenderPassInput.Normal; +#if UNITY_2021_2_OR_NEWER + if (hbao.temporalFilterEnabled.value) + passInput |= ScriptableRenderPassInput.Motion; +#endif + ConfigureInput(passInput); + +#if UNITY_2021_2_OR_NEWER + ConfigureColorStoreAction(RenderBufferStoreAction.DontCare); + + // Configures where the render pass should be injected. + // Rendering after PrePasses is usually correct except when depth priming is in play: + // then we rely on a depth resolve taking place after the PrePasses in order to have it ready for SSAO. + // Hence we set the event to RenderPassEvent.AfterRenderingPrePasses + 1 at the earliest. + renderPassEvent = hbao.debugMode.value == HBAO.DebugMode.Disabled ? + hbao.mode.value == HBAO.Mode.LitAO ? + hbao.renderingPath.value == HBAO.RenderingPath.Deferred ? RenderPassEvent.AfterRenderingGbuffer : RenderPassEvent.AfterRenderingPrePasses + 1 : + RenderPassEvent.BeforeRenderingTransparents : RenderPassEvent.AfterRenderingTransparents; +#else + // Configures where the render pass should be injected. + // Rendering after PrePasses is usually correct except when depth priming is in play: + // then we rely on a depth resolve taking place after the PrePasses in order to have it ready for SSAO. + // Hence we set the event to RenderPassEvent.AfterRenderingPrePasses + 1 at the earliest. + renderPassEvent = hbao.debugMode.value == HBAO.DebugMode.Disabled ? + hbao.mode.value == HBAO.Mode.LitAO ? RenderPassEvent.AfterRenderingPrePasses + 1 : RenderPassEvent.BeforeRenderingTransparents : + RenderPassEvent.AfterRenderingTransparents; +#endif + */ + } + + // This method is called before executing the render pass. + // It can be used to configure render targets and their clear state. Also to create temporary render target textures. + // When empty this render pass will render to the active camera render target. + // You should never call CommandBuffer.SetRenderTarget. Instead call ConfigureTarget and ConfigureClear. + // The render pipeline will ensure target setup and clearing happens in an performance manner. +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) + { + if (material == null) return; + + FetchVolumeComponent(); + + if (!hbao.IsActive()) return; + + FetchRenderParameters(cameraTextureDescriptor); + CheckParameters(); + UpdateMaterialProperties(); + UpdateShaderKeywords(); + } + + // Here you can implement the rendering logic. + // Use ScriptableRenderContext to issue drawing commands or execute command buffers + // https://docs.unity3d.com/ScriptReference/Rendering.ScriptableRenderContext.html + // You don't have to call ScriptableRenderContext.submit, the render pipeline will call it at specific points in the pipeline. +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + if (material == null) + { + Debug.LogError("HBAO material has not been correctly initialized..."); + return; + } + + if (!hbao.IsActive()) return; + +#if UNITY_2021_2_OR_NEWER + var historyBuffers = GetCurrentCameraHistoryBuffers(); + historyBuffers?.historyRTSystem.SwapAndSetReferenceSize(aoDesc.width, aoDesc.height); +#else + var historyBuffers = null as CameraHistoryBuffers; +#endif + + var cmd = CommandBufferPool.Get("HBAO"); + + if (hbao.mode.value == HBAO.Mode.LitAO) + { + CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.ScreenSpaceOcclusion, true); + + cmd.GetTemporaryRT(ShaderProperties.ssaoTex, aoDesc, FilterMode.Bilinear); + } + else + { + cmd.GetTemporaryRT(ShaderProperties.inputTex, sourceDesc, FilterMode.Point); + + // Source copy + CopySource(cmd); + } + + // AO + cmd.SetGlobalVector(ShaderProperties.temporalParams, historyBuffers != null ? new Vector2(s_temporalRotations[historyBuffers.frameCount % 6] / 360.0f, s_temporalOffsets[historyBuffers.frameCount % 4]) : Vector2.zero); + if (hbao.deinterleaving.value == HBAO.Deinterleaving.Disabled) + { + cmd.GetTemporaryRT(ShaderProperties.hbaoTex, aoDesc, FilterMode.Bilinear); + AO(cmd); + } + else + { + cmd.GetTemporaryRT(ShaderProperties.hbaoTex, reinterleavedAoDesc, FilterMode.Bilinear); + DeinterleavedAO(cmd); + } + + // Blur + Blur(cmd); + + // Temporal Filter + TemporalFilter(cmd, historyBuffers); + + // Composite + Composite(cmd); + + cmd.ReleaseTemporaryRT(ShaderProperties.hbaoTex); + if (hbao.mode.value != HBAO.Mode.LitAO) cmd.ReleaseTemporaryRT(ShaderProperties.inputTex); + + context.ExecuteCommandBuffer(cmd); + + CommandBufferPool.Release(cmd); + } + +#if UNITY_2023_3_OR_NEWER + // The RecordRenderGraph function will define the Setup and Rendering functions for our render pass. + // In the Setup we will configure resources such as which textures it reads from and what render textures + // it writes to. The Rendering delegate will contain the rendering code that will execute in the render + // graph execution step. + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + if (material == null || !hbao.IsActive()) return; + + + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + + + FetchRenderParameters(universalCameraData.cameraTargetDescriptor); + CheckParameters(); + UpdateMaterialPropertiesRG(universalCameraData); + UpdateShaderKeywordsRG(universalCameraData); + + + var historyBuffers = GetCurrentCameraHistoryBuffersRG(universalCameraData); + historyBuffers?.historyRTSystem.SwapAndSetReferenceSize(aoDesc.width, aoDesc.height); + + + using (var builder = renderGraph.AddUnsafePass("HBAO Pass", out var passData, m_ProfilingSampler)) + { + // Shader keyword changes are considered as global state modifications + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(false); + + TextureHandle cameraDepthTexture = hbao.renderingPath.value == HBAO.RenderingPath.Deferred ? resourceData.activeDepthTexture : resourceData.cameraDepthTexture; + TextureHandle cameraNormalsTexture = resourceData.cameraNormalsTexture; + TextureHandle motionVectorsTexture = resourceData.motionVectorColor; + + // source texture is the active color buffer + TextureHandle sourceTexture = resourceData.activeColorTexture; + + // descriptor that match the size and format of the pipeline color buffer. + RenderTextureDescriptor targetDesc = universalCameraData.cameraTargetDescriptor; + targetDesc.depthBufferBits = 0; // we don't need the depth buffer + targetDesc.msaaSamples = 1; + + bool passUsesCameraNormals = hbao.perPixelNormals.value == HBAO.PerPixelNormals.Camera; + bool passUsesMotionVectors = hbao.temporalFilterEnabled.value; + bool passUsesLitAO = hbao.mode.value == HBAO.Mode.LitAO; + bool passUsesBlur = hbao.blurType.value != HBAO.BlurType.None; + bool passUsesTemporalFilter = hbao.temporalFilterEnabled.value; + bool passUsesColorBleeding = hbao.colorBleedingEnabled.value; + bool passShowDebug = hbao.debugMode.value != HBAO.DebugMode.Disabled; + + // fill up the passData with the data needed by the pass + passData.Material = material; + passData.TargetDescriptor = targetDesc; + passData.AOTextureDescriptor = aoDesc; + passData.CameraDepthTexture = cameraDepthTexture; + passData.SourceTexture = sourceTexture; + passData.AOTexture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, aoDesc, "_HBAO_AOTexture0", false, FilterMode.Bilinear); + passData.TempTexture = passUsesBlur ? UniversalRenderer.CreateRenderGraphTexture(renderGraph, aoDesc, "_HBAO_AOTexture1", false, FilterMode.Bilinear) : TextureHandle.nullHandle; + passData.DestinationTexture = passUsesLitAO && !passShowDebug ? + UniversalRenderer.CreateRenderGraphTexture(renderGraph, ssaoDesc, "_ScreenSpaceOcclusionTexture", false, FilterMode.Bilinear) : + UniversalRenderer.CreateRenderGraphTexture(renderGraph, targetDesc, "_ScreenSpaceOcclusionTexture", false, FilterMode.Bilinear); + passData.HistoryBuffers = historyBuffers; + passData.TemporalFilterRenderTargets = m_RtsTemporalFilter; + passData.FullscreenTriangle = fullscreenTriangle; + passData.MaterialProperties = materialPropertyBlock; + passData.UseLitAO = passUsesLitAO; + passData.UseColorBleeding = passUsesColorBleeding; + passData.UseBlur = passUsesBlur; + passData.UseTemporalFilter = passUsesTemporalFilter; + passData.DirectLightingStrength = hbao.directLightingStrength.value; + passData.ShowDebug = passShowDebug; + passData.ShowViewNormals = hbao.debugMode.value == HBAO.DebugMode.ViewNormals; + passData.RenderingInSceneView = universalCameraData.camera.cameraType == CameraType.SceneView; + + // declare the textures used in this pass + builder.UseTexture(cameraDepthTexture, AccessFlags.Read); + if (passUsesCameraNormals) + builder.UseTexture(cameraNormalsTexture, AccessFlags.Read); + if (passUsesMotionVectors) + builder.UseTexture(motionVectorsTexture, AccessFlags.Read); + builder.UseTexture(passData.SourceTexture, passUsesLitAO && !passShowDebug ? AccessFlags.Read : AccessFlags.ReadWrite); + builder.UseTexture(passData.AOTexture, AccessFlags.ReadWrite); + if (passData.TempTexture.IsValid()) + builder.UseTexture(passData.TempTexture, AccessFlags.ReadWrite); + builder.UseTexture(passData.DestinationTexture, passUsesLitAO && !passShowDebug ? AccessFlags.Write : AccessFlags.ReadWrite); + + // for litAO make SSAO texture global after this pass + if (passUsesLitAO && !passShowDebug) + { + //resourceData.ssaoTexture = passData.DestinationTexture; + builder.SetGlobalTextureAfterPass(passData.DestinationTexture, ShaderProperties.screenSpaceOcclusionTexture); + } + + builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); + } + } + + // ExecutePass is the render function for each of the blit render graph recordings. This is good + // practice to avoid using variables outside of the lambda it is called from. + // It is static to avoid using member variables which could cause unintended behaviour. + private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); + //var mpb = rgContext.renderGraphPool.GetTempMaterialPropertyBlock(); // allocate GC, replaced by custom solution below + var mpb = data.MaterialProperties; + + mpb.SetTexture(ShaderProperties.cameraDepthTexture, data.CameraDepthTexture); // is it really required? + + if (!data.UseLitAO || data.ShowDebug) + BlitFullscreenTriangle(cmd, data.SourceTexture, data.DestinationTexture, data.Material, data.FullscreenTriangle, Pass.Copy, mpb); + + // AO + mpb.SetVector(ShaderProperties.temporalParams, data.HistoryBuffers != null ? new Vector2(s_temporalRotations[data.HistoryBuffers.frameCount % 6] / 360.0f, s_temporalOffsets[data.HistoryBuffers.frameCount % 4]) : Vector2.zero); + BlitFullscreenTriangleWithClear(cmd, data.SourceTexture, data.AOTexture, data.Material, new Color(0, 0, 0, 1), data.FullscreenTriangle, Pass.AO, mpb); + + // blur + if (data.UseBlur) + { + float width = data.AOTextureDescriptor.width; + float height = data.AOTextureDescriptor.height; + if (data.TargetDescriptor.useDynamicScale) + { + width *= ScalableBufferManager.widthScaleFactor; + height *= ScalableBufferManager.heightScaleFactor; + } + + mpb.SetVector(ShaderProperties.blurDeltaUV, new Vector2(1f / width, 0)); + BlitFullscreenTriangle(cmd, data.AOTexture, data.TempTexture, data.Material, data.FullscreenTriangle, Pass.Blur, mpb); + + mpb.SetVector(ShaderProperties.blurDeltaUV, new Vector2(0, 1f / height)); + BlitFullscreenTriangle(cmd, data.TempTexture, data.AOTexture, data.Material, data.FullscreenTriangle, Pass.Blur, mpb); + } + + mpb.SetTexture(ShaderProperties.hbaoTex, data.AOTexture); + + // temporal filter + if (data.UseTemporalFilter && !data.RenderingInSceneView && data.HistoryBuffers != null) + { + mpb.SetVector(ShaderProperties.historyBufferRTHandleScale, data.HistoryBuffers.historyRTSystem.rtHandleProperties.rtHandleScale); + + if (data.HistoryBuffers.frameCount == 0) + { + // buffers were just allocated this frame, clear them (previous frame RT) + RenderTargetIdentifier aoRenderTargetIdentifier = new RenderTargetIdentifier(data.HistoryBuffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 1), 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices); + cmd.SetRenderTarget(aoRenderTargetIdentifier, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); + cmd.ClearRenderTarget(false, true, Color.white); + if (data.UseColorBleeding) + { + RenderTargetIdentifier cbRenderTargetIdentifier = new RenderTargetIdentifier(data.HistoryBuffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.ColorBleeding, 1), 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices); + cmd.SetRenderTarget(cbRenderTargetIdentifier, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); + cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 1)); + } + } + + var viewportRect = new Rect(Vector2.zero, data.HistoryBuffers.historyRTSystem.rtHandleProperties.currentViewportSize); + + if (data.UseColorBleeding) + { + // For Color Bleeding we have 2 history buffers to fill so there are 2 render targets. + // AO is still contained in Color Bleeding history buffer (alpha channel) so that we + // can use it as a render texture for the composite pass. + var currentFrameAORT = data.HistoryBuffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 0); + var currentFrameCBRT = data.HistoryBuffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.ColorBleeding, 0); + var previousFrameAORT = data.HistoryBuffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 1); + var previousFrameCBRT = data.HistoryBuffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.ColorBleeding, 1); + data.TemporalFilterRenderTargets[0] = currentFrameAORT; + data.TemporalFilterRenderTargets[1] = currentFrameCBRT; + //cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity); + mpb.SetTexture(ShaderProperties.tempTex, previousFrameCBRT); + BlitFullscreenTriangle(cmd, previousFrameAORT, data.TemporalFilterRenderTargets, viewportRect, data.Material, data.FullscreenTriangle, Pass.Temporal_Filter, mpb); + //cmd.SetViewProjectionMatrices(cameraData.camera.worldToCameraMatrix, cameraData.camera.projectionMatrix); + + mpb.SetTexture(ShaderProperties.hbaoTex, currentFrameCBRT); + } + else + { + // AO history buffer contains ao in aplha channel so we can just use history as + // a render texture for the composite pass. + var currentFrameRT = data.HistoryBuffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 0); + var previousFrameRT = data.HistoryBuffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 1); + BlitFullscreenTriangle(cmd, previousFrameRT, currentFrameRT, viewportRect, data.Material, data.FullscreenTriangle, Pass.Temporal_Filter, mpb); + + mpb.SetTexture(ShaderProperties.hbaoTex, currentFrameRT); + } + + // increment buffers frameCount for next frame, track last buffer use + data.HistoryBuffers.frameCount++; + data.HistoryBuffers.lastRenderedFrame = Time.frameCount; + } + else + mpb.SetVector(ShaderProperties.historyBufferRTHandleScale, Vector4.one); + + // composite + if (data.UseLitAO && !data.ShowDebug) + { + BlitFullscreenTriangle(cmd, data.SourceTexture, data.DestinationTexture, data.Material, data.FullscreenTriangle, Pass.Composite, mpb); + + // set global ambient occlusion keyword and param so that it is used by lit shaders + cmd.SetKeyword(ShaderProperties.screenSpaceOcclusionKeyword, true); + cmd.SetGlobalVector(ShaderProperties.screenSpaceOcclusionParam, new Vector4(1f, 0f, 0f, data.DirectLightingStrength)); + } + else + BlitFullscreenTriangle(cmd, data.DestinationTexture, data.SourceTexture, data.Material, data.FullscreenTriangle, data.ShowViewNormals ? Pass.Debug_ViewNormals : Pass.Composite, mpb); + } +#endif + + /// Cleanup any allocated resources that were created during the execution of this render pass. + public override void FrameCleanup(CommandBuffer cmd) + { + if (hbao.mode.value == HBAO.Mode.LitAO) + { + cmd.ReleaseTemporaryRT(ShaderProperties.ssaoTex); // TODO: should not be called with RenderGraph rendering + +#if UNITY_2023_3_OR_NEWER + cmd.SetKeyword(ShaderProperties.screenSpaceOcclusionKeyword, false); +#else + CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.ScreenSpaceOcclusion, false); +#endif + } + + // we release any camera history buffers that has not rendered for more than 1 frames + for (var i = m_CameraHistoryBuffers.Count - 1; i >= 0; i--) + { + var buffers = m_CameraHistoryBuffers[i]; + if (Time.frameCount - buffers.lastRenderedFrame > 1) + { + ReleaseCameraHistoryBuffers(ref buffers); + } + } + } + + public void Cleanup() + { + for (var i = m_CameraHistoryBuffers.Count - 1; i >= 0; i--) + { + var buffers = m_CameraHistoryBuffers[i]; + ReleaseCameraHistoryBuffers(ref buffers); + } + + CoreUtils.Destroy(material); + CoreUtils.Destroy(noiseTex); + } + + private void FetchVolumeComponent() + { + if (hbao == null) + hbao = VolumeManager.instance.stack.GetComponent(); + } + + private void FetchRenderParameters(RenderTextureDescriptor cameraTextureDesc) + { + cameraTextureDesc.msaaSamples = 1; + cameraTextureDesc.depthBufferBits = 0; + sourceDesc = cameraTextureDesc; + + var width = cameraTextureDesc.width; + var height = cameraTextureDesc.height; + var downsamplingFactor = hbao.resolution.value == HBAO.Resolution.Full ? 1 : hbao.deinterleaving.value == HBAO.Deinterleaving.Disabled ? 2 : 1; + if (downsamplingFactor > 1) + { + width = (width + width % 2) / downsamplingFactor; + height = (height + height % 2) / downsamplingFactor; + } + + aoDesc = GetStereoCompatibleDescriptor(width, height, format: colorFormat, readWrite: RenderTextureReadWrite.Linear); + ssaoDesc = GetStereoCompatibleDescriptor(width, height, format: ssaoFormat, readWrite: RenderTextureReadWrite.Linear); + + if (hbao.deinterleaving.value != HBAO.Deinterleaving.Disabled) + { + var reinterleavedWidth = cameraTextureDesc.width + (cameraTextureDesc.width % 4 == 0 ? 0 : 4 - (cameraTextureDesc.width % 4)); + var reinterleavedHeight = cameraTextureDesc.height + (cameraTextureDesc.height % 4 == 0 ? 0 : 4 - (cameraTextureDesc.height % 4)); + var deinterleavedWidth = reinterleavedWidth / 4; + var deinterleavedHeight = reinterleavedHeight / 4; + + deinterleavedDepthDesc = GetStereoCompatibleDescriptor(deinterleavedWidth, deinterleavedHeight, format: depthFormat, readWrite: RenderTextureReadWrite.Linear); + deinterleavedNormalsDesc = GetStereoCompatibleDescriptor(deinterleavedWidth, deinterleavedHeight, format: normalsFormat, readWrite: RenderTextureReadWrite.Linear); + deinterleavedAoDesc = GetStereoCompatibleDescriptor(deinterleavedWidth, deinterleavedHeight, format: colorFormat, readWrite: RenderTextureReadWrite.Linear); + reinterleavedAoDesc = GetStereoCompatibleDescriptor(reinterleavedWidth, reinterleavedHeight, format: colorFormat, readWrite: RenderTextureReadWrite.Linear); + } + } + + private RTHandle HistoryBufferAllocator(RTHandleSystem rtHandleSystem, int frameIndex) + { + var texDimension = TextureDimension.Tex2D; + var sliceCount = 1; +#if ENABLE_VR_MODULE && ENABLE_VR + if (XRSettings.enabled && XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassInstanced) + { + texDimension = TextureDimension.Tex2DArray; + sliceCount = 2; + } +#endif + return rtHandleSystem.Alloc(Vector2.one, colorFormat: graphicsColorFormat, useDynamicScale: true, name: "HBAO_HistoryBuffer_" + frameIndex, dimension: texDimension, slices: sliceCount); + //return rtHandleSystem.Alloc(scaleFactor: Vector2.one, slices: TextureXR.slices, colorFormat: graphicsColorFormat, dimension: TextureXR.dimension, useDynamicScale: true, name: "HBAO_HistoryBuffer_" + frameIndex); + } + + private void AllocCameraHistoryBuffers(ref CameraHistoryBuffers buffers) + { + buffers = new CameraHistoryBuffers(); + buffers.camera = cameraData.camera; + buffers.frameCount = 0; + buffers.historyRTSystem = new BufferedRTHandleSystem(); // https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@12.0/manual/rthandle-system-using.html + buffers.historyRTSystem.AllocBuffer((int)HistoryBufferType.AmbientOcclusion, HistoryBufferAllocator, 2); + if (hbao.colorBleedingEnabled.value) + buffers.historyRTSystem.AllocBuffer((int)HistoryBufferType.ColorBleeding, HistoryBufferAllocator, 2); + + m_CameraHistoryBuffers.Add(buffers); + } + +#if UNITY_2023_3_OR_NEWER + private void AllocCameraHistoryBuffersRG(UniversalCameraData cameraData, ref CameraHistoryBuffers buffers) + { + buffers = new CameraHistoryBuffers(); + buffers.camera = cameraData.camera; + buffers.frameCount = 0; + buffers.historyRTSystem = new BufferedRTHandleSystem(); // https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@12.0/manual/rthandle-system-using.html + buffers.historyRTSystem.AllocBuffer((int)HistoryBufferType.AmbientOcclusion, HistoryBufferAllocator, 2); + if (hbao.colorBleedingEnabled.value) + buffers.historyRTSystem.AllocBuffer((int)HistoryBufferType.ColorBleeding, HistoryBufferAllocator, 2); + + m_CameraHistoryBuffers.Add(buffers); + } +#endif + + private void ReleaseCameraHistoryBuffers(ref CameraHistoryBuffers buffers) + { + buffers.historyRTSystem.ReleaseAll(); + buffers.historyRTSystem.Dispose(); + + m_CameraHistoryBuffers.Remove(buffers); + + buffers = null; + } + + private CameraHistoryBuffers GetCurrentCameraHistoryBuffers() + { + CameraHistoryBuffers buffers = null; + if (hbao.temporalFilterEnabled.value && !renderingInSceneView) + { + for (var i = 0; i < m_CameraHistoryBuffers.Count; i++) + { + if (m_CameraHistoryBuffers[i].camera == cameraData.camera) + { + buffers = m_CameraHistoryBuffers[i]; + break; + } + } + + if ((m_PreviousColorBleedingEnabled != hbao.colorBleedingEnabled.value || +#if ENABLE_VR_MODULE && ENABLE_VR + m_PrevStereoRenderingMode != XRSettings.stereoRenderingMode || +#endif + m_PreviousResolution != hbao.resolution.value) + && buffers != null) + { + ReleaseCameraHistoryBuffers(ref buffers); + m_PreviousColorBleedingEnabled = hbao.colorBleedingEnabled.value; + m_PreviousResolution = hbao.resolution.value; +#if ENABLE_VR_MODULE && ENABLE_VR + m_PrevStereoRenderingMode = XRSettings.stereoRenderingMode; +#endif + } + + if (buffers == null) + AllocCameraHistoryBuffers(ref buffers); + } + + return buffers; + } + +#if UNITY_2023_3_OR_NEWER + private CameraHistoryBuffers GetCurrentCameraHistoryBuffersRG(UniversalCameraData cameraData) + { + CameraHistoryBuffers buffers = null; + if (hbao.temporalFilterEnabled.value && !(cameraData.cameraType == CameraType.SceneView)) + { + for (var i = 0; i < m_CameraHistoryBuffers.Count; i++) + { + if (m_CameraHistoryBuffers[i].camera == cameraData.camera) + { + buffers = m_CameraHistoryBuffers[i]; + break; + } + } + + if ((m_PreviousColorBleedingEnabled != hbao.colorBleedingEnabled.value || +#if ENABLE_VR_MODULE && ENABLE_VR + m_PrevStereoRenderingMode != XRSettings.stereoRenderingMode || +#endif + m_PreviousResolution != hbao.resolution.value) + && buffers != null) + { + ReleaseCameraHistoryBuffers(ref buffers); + m_PreviousColorBleedingEnabled = hbao.colorBleedingEnabled.value; + m_PreviousResolution = hbao.resolution.value; +#if ENABLE_VR_MODULE && ENABLE_VR + m_PrevStereoRenderingMode = XRSettings.stereoRenderingMode; +#endif + } + + if (buffers == null) + AllocCameraHistoryBuffersRG(cameraData, ref buffers); + } + + return buffers; + } +#endif + + private void CopySource(CommandBuffer cmd) + { + BlitFullscreenTriangle(cmd, source, ShaderProperties.inputTex, material, fullscreenTriangle, Pass.Copy); + } + + private void AO(CommandBuffer cmd) + { + BlitFullscreenTriangleWithClear(cmd, hbao.mode.value == HBAO.Mode.LitAO ? source : ShaderProperties.inputTex, ShaderProperties.hbaoTex, material, new Color(0, 0, 0, 1), fullscreenTriangle, Pass.AO); + } + + private void DeinterleavedAO(CommandBuffer cmd) + { + // Deinterleave depth & normals (4x4) + //cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity); + for (int i = 0; i < 4; i++) + { + m_RtsDepth[0] = ShaderProperties.depthSliceTex[(i << 2) + 0]; + m_RtsDepth[1] = ShaderProperties.depthSliceTex[(i << 2) + 1]; + m_RtsDepth[2] = ShaderProperties.depthSliceTex[(i << 2) + 2]; + m_RtsDepth[3] = ShaderProperties.depthSliceTex[(i << 2) + 3]; + m_RtsNormals[0] = ShaderProperties.normalsSliceTex[(i << 2) + 0]; + m_RtsNormals[1] = ShaderProperties.normalsSliceTex[(i << 2) + 1]; + m_RtsNormals[2] = ShaderProperties.normalsSliceTex[(i << 2) + 2]; + m_RtsNormals[3] = ShaderProperties.normalsSliceTex[(i << 2) + 3]; + + int offsetX = (i & 1) << 1; int offsetY = (i >> 1) << 1; + cmd.SetGlobalVector(ShaderProperties.deinterleaveOffset[0], new Vector2(offsetX + 0, offsetY + 0)); + cmd.SetGlobalVector(ShaderProperties.deinterleaveOffset[1], new Vector2(offsetX + 1, offsetY + 0)); + cmd.SetGlobalVector(ShaderProperties.deinterleaveOffset[2], new Vector2(offsetX + 0, offsetY + 1)); + cmd.SetGlobalVector(ShaderProperties.deinterleaveOffset[3], new Vector2(offsetX + 1, offsetY + 1)); + for (int j = 0; j < 4; j++) + { + cmd.GetTemporaryRT(ShaderProperties.depthSliceTex[j + 4 * i], deinterleavedDepthDesc, FilterMode.Point); + cmd.GetTemporaryRT(ShaderProperties.normalsSliceTex[j + 4 * i], deinterleavedNormalsDesc, FilterMode.Point); + } + BlitFullscreenTriangle(cmd, BuiltinRenderTextureType.CameraTarget, m_RtsDepth, material, fullscreenTriangle, Pass.Deinterleave_Depth); // outputs 4 render textures + BlitFullscreenTriangle(cmd, BuiltinRenderTextureType.CameraTarget, m_RtsNormals, material, fullscreenTriangle, Pass.Deinterleave_Normals); // outputs 4 render textures + } + //cmd.SetViewProjectionMatrices(cameraData.camera.worldToCameraMatrix, cameraData.camera.projectionMatrix); + + // AO on each layer + for (int i = 0; i < 4 * 4; i++) + { + cmd.SetGlobalTexture(ShaderProperties.depthTex, ShaderProperties.depthSliceTex[i]); + cmd.SetGlobalTexture(ShaderProperties.normalsTex, ShaderProperties.normalsSliceTex[i]); + cmd.SetGlobalVector(ShaderProperties.jitter, s_jitter[i]); + cmd.GetTemporaryRT(ShaderProperties.aoSliceTex[i], deinterleavedAoDesc, FilterMode.Point); + BlitFullscreenTriangleWithClear(cmd, hbao.mode.value == HBAO.Mode.LitAO ? source : ShaderProperties.inputTex, ShaderProperties.aoSliceTex[i], material, new Color(0, 0, 0, 1), fullscreenTriangle, Pass.AO_Deinterleaved); // ao + cmd.ReleaseTemporaryRT(ShaderProperties.depthSliceTex[i]); + cmd.ReleaseTemporaryRT(ShaderProperties.normalsSliceTex[i]); + } + + // Atlas Deinterleaved AO, 4x4 + cmd.GetTemporaryRT(ShaderProperties.tempTex, reinterleavedAoDesc, FilterMode.Point); + for (int i = 0; i < 4 * 4; i++) + { + cmd.SetGlobalVector(ShaderProperties.atlasOffset, new Vector2(((i & 1) + (((i & 7) >> 2) << 1)) * deinterleavedAoDesc.width, (((i & 3) >> 1) + ((i >> 3) << 1)) * deinterleavedAoDesc.height)); + BlitFullscreenTriangle(cmd, ShaderProperties.aoSliceTex[i], ShaderProperties.tempTex, material, fullscreenTriangle, Pass.Atlas_AO_Deinterleaved); // atlassing + cmd.ReleaseTemporaryRT(ShaderProperties.aoSliceTex[i]); + } + + // Reinterleave AO + BlitFullscreenTriangle(cmd, ShaderProperties.tempTex, ShaderProperties.hbaoTex, material, fullscreenTriangle, Pass.Reinterleave_AO); // reinterleave + cmd.ReleaseTemporaryRT(ShaderProperties.tempTex); + } + + private void Blur(CommandBuffer cmd) + { + if (hbao.blurType.value != HBAO.BlurType.None) + { + float width = aoDesc.width; + float height = aoDesc.height; + if (sourceDesc.useDynamicScale) + { + width *= ScalableBufferManager.widthScaleFactor; + height *= ScalableBufferManager.heightScaleFactor; + } + + cmd.GetTemporaryRT(ShaderProperties.tempTex, aoDesc, FilterMode.Bilinear); + cmd.SetGlobalVector(ShaderProperties.blurDeltaUV, new Vector2(1f / width, 0)); + BlitFullscreenTriangle(cmd, ShaderProperties.hbaoTex, ShaderProperties.tempTex, material, fullscreenTriangle, Pass.Blur); + cmd.SetGlobalVector(ShaderProperties.blurDeltaUV, new Vector2(0, 1f / height)); + BlitFullscreenTriangle(cmd, ShaderProperties.tempTex, ShaderProperties.hbaoTex, material, fullscreenTriangle, Pass.Blur); + cmd.ReleaseTemporaryRT(ShaderProperties.tempTex); + } + } + + private void TemporalFilter(CommandBuffer cmd, CameraHistoryBuffers buffers) + { + if (hbao.temporalFilterEnabled.value && !renderingInSceneView && buffers != null) + { + cmd.SetGlobalVector(ShaderProperties.historyBufferRTHandleScale, buffers.historyRTSystem.rtHandleProperties.rtHandleScale); + + if (buffers.frameCount == 0) + { + // buffers were just allocated this frame, clear them (previous frame RT) + cmd.SetRenderTarget(buffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 1), 0, CubemapFace.Unknown, -1); + cmd.ClearRenderTarget(false, true, Color.white); + if (hbao.colorBleedingEnabled.value) + { + cmd.SetRenderTarget(buffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.ColorBleeding, 1), 0, CubemapFace.Unknown, -1); + cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 1)); + } + } + + var viewportRect = new Rect(Vector2.zero, buffers.historyRTSystem.rtHandleProperties.currentViewportSize); + + if (hbao.colorBleedingEnabled.value) + { + // For Color Bleeding we have 2 history buffers to fill so there are 2 render targets. + // AO is still contained in Color Bleeding history buffer (alpha channel) so that we + // can use it as a render texture for the composite pass. + var currentFrameAORT = buffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 0); + var currentFrameCBRT = buffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.ColorBleeding, 0); + var previousFrameAORT = buffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 1); + var previousFrameCBRT = buffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.ColorBleeding, 1); + var rts = new RenderTargetIdentifier[] { + currentFrameAORT, + currentFrameCBRT + }; + //cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity); + cmd.SetGlobalTexture(ShaderProperties.tempTex, previousFrameCBRT); + BlitFullscreenTriangle(cmd, previousFrameAORT, rts, viewportRect, material, fullscreenTriangle, Pass.Temporal_Filter); + //cmd.SetViewProjectionMatrices(cameraData.camera.worldToCameraMatrix, cameraData.camera.projectionMatrix); + cmd.SetGlobalTexture(ShaderProperties.hbaoTex, currentFrameCBRT); + } + else + { + // AO history buffer contains ao in aplha channel so we can just use history as + // a render texture for the composite pass. + var currentFrameRT = buffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 0); + var previousFrameRT = buffers.historyRTSystem.GetFrameRT((int)HistoryBufferType.AmbientOcclusion, 1); + BlitFullscreenTriangle(cmd, previousFrameRT, currentFrameRT, viewportRect, material, fullscreenTriangle, Pass.Temporal_Filter); + cmd.SetGlobalTexture(ShaderProperties.hbaoTex, currentFrameRT); + } + + // increment buffers frameCount for next frame, track last buffer use + buffers.frameCount++; + buffers.lastRenderedFrame = Time.frameCount; + } + else + cmd.SetGlobalVector(ShaderProperties.historyBufferRTHandleScale, Vector4.one); + } + + private void Composite(CommandBuffer cmd) + { + BlitFullscreenTriangle(cmd, + hbao.mode.value == HBAO.Mode.LitAO ? source : ShaderProperties.inputTex, + hbao.mode.value == HBAO.Mode.LitAO && hbao.debugMode.value == HBAO.DebugMode.Disabled ? ShaderProperties.ssaoTex : source, + material, fullscreenTriangle, + hbao.debugMode.value == HBAO.DebugMode.ViewNormals ? Pass.Debug_ViewNormals : Pass.Composite + ); + + if (hbao.mode.value == HBAO.Mode.LitAO) + { + cmd.SetGlobalTexture("_ScreenSpaceOcclusionTexture", ShaderProperties.ssaoTex); + cmd.SetGlobalVector("_AmbientOcclusionParam", new Vector4(1f, 0f, 0f, hbao.directLightingStrength.value)); + } + } + + private void UpdateMaterialProperties() + { + var sourceWidth = cameraData.cameraTargetDescriptor.width; + var sourceHeight = cameraData.cameraTargetDescriptor.height; + +#if ENABLE_VR_MODULE && ENABLE_VR + int eyeCount = XRSettings.enabled && XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassInstanced && !renderingInSceneView ? 2 : 1; +#else + int eyeCount = 1; +#endif + for (int viewIndex = 0; viewIndex < eyeCount; viewIndex++) + { + var projMatrix = cameraData.GetProjectionMatrix(viewIndex); + float invTanHalfFOVxAR = projMatrix.m00; // m00 => 1.0f / (tanHalfFOV * aspectRatio) + float invTanHalfFOV = projMatrix.m11; // m11 => 1.0f / tanHalfFOV + m_UVToViewPerEye[viewIndex] = new Vector4(2.0f / invTanHalfFOVxAR, -2.0f / invTanHalfFOV, -1.0f / invTanHalfFOVxAR, 1.0f / invTanHalfFOV); + m_RadiusPerEye[viewIndex] = hbao.radius.value * 0.5f * (sourceHeight / (hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? 4 : 1) / (2.0f / invTanHalfFOV)); + } + + //float tanHalfFovY = Mathf.Tan(0.5f * cameraData.camera.fieldOfView * Mathf.Deg2Rad); + //float invFocalLenX = 1.0f / (1.0f / tanHalfFovY * (sourceHeight / (float)sourceWidth)); + //float invFocalLenY = 1.0f / (1.0f / tanHalfFovY); + float maxRadInPixels = Mathf.Max(16, hbao.maxRadiusPixels.value * Mathf.Sqrt(sourceWidth * sourceHeight / (1080.0f * 1920.0f))); + maxRadInPixels /= hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? 4 : 1; + + var targetScale = hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? + new Vector4(reinterleavedAoDesc.width / (float)sourceWidth, reinterleavedAoDesc.height / (float)sourceHeight, 1.0f / (reinterleavedAoDesc.width / (float)sourceWidth), 1.0f / (reinterleavedAoDesc.height / (float)sourceHeight)) : + hbao.resolution.value == HBAO.Resolution.Half /*&& (settings.perPixelNormals.value == HBAO.PerPixelNormals.Reconstruct2Samples || settings.perPixelNormals.value == HBAO.PerPixelNormals.Reconstruct4Samples)*/ ? + new Vector4((sourceWidth + 0.5f) / sourceWidth, (sourceHeight + 0.5f) / sourceHeight, 1f, 1f) : + Vector4.one; + + material.SetTexture(ShaderProperties.noiseTex, noiseTex); + material.SetVector(ShaderProperties.inputTexelSize, new Vector4(1f / sourceWidth, 1f / sourceHeight, sourceWidth, sourceHeight)); + if (sourceDesc.useDynamicScale) + material.SetVector(ShaderProperties.aoTexelSize, new Vector4(1f / (aoDesc.width * ScalableBufferManager.widthScaleFactor), 1f / (aoDesc.height * ScalableBufferManager.heightScaleFactor), aoDesc.width * ScalableBufferManager.widthScaleFactor, aoDesc.height * ScalableBufferManager.heightScaleFactor)); + else + material.SetVector(ShaderProperties.aoTexelSize, new Vector4(1f / aoDesc.width, 1f / aoDesc.height, aoDesc.width, aoDesc.height)); + material.SetVector(ShaderProperties.deinterleavedAOTexelSize, new Vector4(1.0f / deinterleavedAoDesc.width, 1.0f / deinterleavedAoDesc.height, deinterleavedAoDesc.width, deinterleavedAoDesc.height)); + material.SetVector(ShaderProperties.reinterleavedAOTexelSize, new Vector4(1f / reinterleavedAoDesc.width, 1f / reinterleavedAoDesc.height, reinterleavedAoDesc.width, reinterleavedAoDesc.height)); + material.SetVector(ShaderProperties.targetScale, targetScale); + //material.SetVector(ShaderProperties.uvToView, new Vector4(2.0f * invFocalLenX, -2.0f * invFocalLenY, -1.0f * invFocalLenX, 1.0f * invFocalLenY)); + material.SetVectorArray(ShaderProperties.uvToView, m_UVToViewPerEye); + //material.SetMatrix(ShaderProperties.worldToCameraMatrix, cameraData.camera.worldToCameraMatrix); + //material.SetFloat(ShaderProperties.radius, hbao.radius.value * 0.5f * ((sourceHeight / (hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? 4 : 1)) / (tanHalfFovY * 2.0f))); + //material.SetFloat(ShaderProperties.radius, hbao.radius.value * 0.5f * ((sourceHeight / (hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? 4 : 1)) / (invFocalLenY * 2.0f))); + material.SetFloatArray(ShaderProperties.radius, m_RadiusPerEye); + material.SetFloat(ShaderProperties.maxRadiusPixels, maxRadInPixels); + material.SetFloat(ShaderProperties.negInvRadius2, -1.0f / (hbao.radius.value * hbao.radius.value)); + material.SetFloat(ShaderProperties.angleBias, hbao.bias.value); + material.SetFloat(ShaderProperties.aoMultiplier, 2.0f * (1.0f / (1.0f - hbao.bias.value))); + material.SetFloat(ShaderProperties.intensity, isLinearColorSpace ? hbao.intensity.value : hbao.intensity.value * 0.454545454545455f); + material.SetFloat(ShaderProperties.multiBounceInfluence, hbao.multiBounceInfluence.value); + material.SetFloat(ShaderProperties.offscreenSamplesContrib, hbao.offscreenSamplesContribution.value); + material.SetFloat(ShaderProperties.maxDistance, hbao.maxDistance.value); + material.SetFloat(ShaderProperties.distanceFalloff, hbao.distanceFalloff.value); + material.SetColor(ShaderProperties.baseColor, hbao.baseColor.value); + material.SetFloat(ShaderProperties.blurSharpness, hbao.sharpness.value); + material.SetFloat(ShaderProperties.colorBleedSaturation, hbao.saturation.value); + material.SetFloat(ShaderProperties.colorBleedBrightnessMask, hbao.brightnessMask.value); + material.SetVector(ShaderProperties.colorBleedBrightnessMaskRange, AdjustBrightnessMaskToGammaSpace(new Vector2(Mathf.Pow(hbao.brightnessMaskRange.value.x, 3), Mathf.Pow(hbao.brightnessMaskRange.value.y, 3)))); + } + +#if UNITY_2023_3_OR_NEWER + private void UpdateMaterialPropertiesRG(UniversalCameraData cameraData) + { + var sourceWidth = cameraData.cameraTargetDescriptor.width; + var sourceHeight = cameraData.cameraTargetDescriptor.height; + +#if ENABLE_VR_MODULE && ENABLE_VR + int eyeCount = XRSettings.enabled && XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassInstanced && !(cameraData.cameraType == CameraType.SceneView) ? 2 : 1; +#else + int eyeCount = 1; +#endif + for (int viewIndex = 0; viewIndex < eyeCount; viewIndex++) + { + var projMatrix = cameraData.GetProjectionMatrix(viewIndex); + float invTanHalfFOVxAR = projMatrix.m00; // m00 => 1.0f / (tanHalfFOV * aspectRatio) + float invTanHalfFOV = projMatrix.m11; // m11 => 1.0f / tanHalfFOV + m_UVToViewPerEye[viewIndex] = new Vector4(2.0f / invTanHalfFOVxAR, -2.0f / invTanHalfFOV, -1.0f / invTanHalfFOVxAR, 1.0f / invTanHalfFOV); + m_RadiusPerEye[viewIndex] = hbao.radius.value * 0.5f * (sourceHeight / (hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? 4 : 1) / (2.0f / invTanHalfFOV)); + } + + //float tanHalfFovY = Mathf.Tan(0.5f * cameraData.camera.fieldOfView * Mathf.Deg2Rad); + //float invFocalLenX = 1.0f / (1.0f / tanHalfFovY * (sourceHeight / (float)sourceWidth)); + //float invFocalLenY = 1.0f / (1.0f / tanHalfFovY); + float maxRadInPixels = Mathf.Max(16, hbao.maxRadiusPixels.value * Mathf.Sqrt(sourceWidth * sourceHeight / (1080.0f * 1920.0f))); + maxRadInPixels /= hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? 4 : 1; + + var targetScale = hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? + new Vector4(reinterleavedAoDesc.width / (float)sourceWidth, reinterleavedAoDesc.height / (float)sourceHeight, 1.0f / (reinterleavedAoDesc.width / (float)sourceWidth), 1.0f / (reinterleavedAoDesc.height / (float)sourceHeight)) : + hbao.resolution.value == HBAO.Resolution.Half /*&& (settings.perPixelNormals.value == HBAO.PerPixelNormals.Reconstruct2Samples || settings.perPixelNormals.value == HBAO.PerPixelNormals.Reconstruct4Samples)*/ ? + new Vector4((sourceWidth + 0.5f) / sourceWidth, (sourceHeight + 0.5f) / sourceHeight, 1f, 1f) : + Vector4.one; + + material.SetTexture(ShaderProperties.noiseTex, noiseTex); + material.SetVector(ShaderProperties.inputTexelSize, new Vector4(1f / sourceWidth, 1f / sourceHeight, sourceWidth, sourceHeight)); + if (sourceDesc.useDynamicScale) + material.SetVector(ShaderProperties.aoTexelSize, new Vector4(1f / (aoDesc.width * ScalableBufferManager.widthScaleFactor), 1f / (aoDesc.height * ScalableBufferManager.heightScaleFactor), aoDesc.width * ScalableBufferManager.widthScaleFactor, aoDesc.height * ScalableBufferManager.heightScaleFactor)); + else + material.SetVector(ShaderProperties.aoTexelSize, new Vector4(1f / aoDesc.width, 1f / aoDesc.height, aoDesc.width, aoDesc.height)); + material.SetVector(ShaderProperties.deinterleavedAOTexelSize, new Vector4(1.0f / deinterleavedAoDesc.width, 1.0f / deinterleavedAoDesc.height, deinterleavedAoDesc.width, deinterleavedAoDesc.height)); + material.SetVector(ShaderProperties.reinterleavedAOTexelSize, new Vector4(1f / reinterleavedAoDesc.width, 1f / reinterleavedAoDesc.height, reinterleavedAoDesc.width, reinterleavedAoDesc.height)); + material.SetVector(ShaderProperties.targetScale, targetScale); + //material.SetVector(ShaderProperties.uvToView, new Vector4(2.0f * invFocalLenX, -2.0f * invFocalLenY, -1.0f * invFocalLenX, 1.0f * invFocalLenY)); + material.SetVectorArray(ShaderProperties.uvToView, m_UVToViewPerEye); + //material.SetMatrix(ShaderProperties.worldToCameraMatrix, cameraData.camera.worldToCameraMatrix); + //material.SetFloat(ShaderProperties.radius, hbao.radius.value * 0.5f * ((sourceHeight / (hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? 4 : 1)) / (tanHalfFovY * 2.0f))); + //material.SetFloat(ShaderProperties.radius, hbao.radius.value * 0.5f * ((sourceHeight / (hbao.deinterleaving.value == HBAO.Deinterleaving.x4 ? 4 : 1)) / (invFocalLenY * 2.0f))); + material.SetFloatArray(ShaderProperties.radius, m_RadiusPerEye); + material.SetFloat(ShaderProperties.maxRadiusPixels, maxRadInPixels); + material.SetFloat(ShaderProperties.negInvRadius2, -1.0f / (hbao.radius.value * hbao.radius.value)); + material.SetFloat(ShaderProperties.angleBias, hbao.bias.value); + material.SetFloat(ShaderProperties.aoMultiplier, 2.0f * (1.0f / (1.0f - hbao.bias.value))); + material.SetFloat(ShaderProperties.intensity, isLinearColorSpace ? hbao.intensity.value : hbao.intensity.value * 0.454545454545455f); + material.SetFloat(ShaderProperties.multiBounceInfluence, hbao.multiBounceInfluence.value); + material.SetFloat(ShaderProperties.offscreenSamplesContrib, hbao.offscreenSamplesContribution.value); + material.SetFloat(ShaderProperties.maxDistance, hbao.maxDistance.value); + material.SetFloat(ShaderProperties.distanceFalloff, hbao.distanceFalloff.value); + material.SetColor(ShaderProperties.baseColor, hbao.baseColor.value); + material.SetFloat(ShaderProperties.blurSharpness, hbao.sharpness.value); + material.SetFloat(ShaderProperties.colorBleedSaturation, hbao.saturation.value); + material.SetFloat(ShaderProperties.colorBleedBrightnessMask, hbao.brightnessMask.value); + material.SetVector(ShaderProperties.colorBleedBrightnessMaskRange, AdjustBrightnessMaskToGammaSpace(new Vector2(Mathf.Pow(hbao.brightnessMaskRange.value.x, 3), Mathf.Pow(hbao.brightnessMaskRange.value.y, 3)))); + } +#endif + + private void UpdateShaderKeywords() + { + if (m_ShaderKeywords == null || m_ShaderKeywords.Length != 12) m_ShaderKeywords = new string[12]; + + m_ShaderKeywords[0] = ShaderProperties.GetOrthographicProjectionKeyword(cameraData.camera.orthographic); + m_ShaderKeywords[1] = ShaderProperties.GetQualityKeyword(hbao.quality.value); + m_ShaderKeywords[2] = ShaderProperties.GetNoiseKeyword(hbao.noiseType.value); + m_ShaderKeywords[3] = ShaderProperties.GetDeinterleavingKeyword(hbao.deinterleaving.value); + m_ShaderKeywords[4] = ShaderProperties.GetDebugKeyword(hbao.debugMode.value); + m_ShaderKeywords[5] = ShaderProperties.GetMultibounceKeyword(hbao.useMultiBounce.value, hbao.mode.value == HBAO.Mode.LitAO); + m_ShaderKeywords[6] = ShaderProperties.GetOffscreenSamplesContributionKeyword(hbao.offscreenSamplesContribution.value); + m_ShaderKeywords[7] = ShaderProperties.GetPerPixelNormalsKeyword(hbao.perPixelNormals.value); + m_ShaderKeywords[8] = ShaderProperties.GetBlurRadiusKeyword(hbao.blurType.value); + m_ShaderKeywords[9] = ShaderProperties.GetVarianceClippingKeyword(hbao.varianceClipping.value); + m_ShaderKeywords[10] = ShaderProperties.GetColorBleedingKeyword(hbao.colorBleedingEnabled.value, hbao.mode.value == HBAO.Mode.LitAO); + m_ShaderKeywords[11] = ShaderProperties.GetModeKeyword(hbao.mode.value); + + material.shaderKeywords = m_ShaderKeywords; + } + +#if UNITY_2023_3_OR_NEWER + private void UpdateShaderKeywordsRG(UniversalCameraData cameraData) + { + if (m_ShaderKeywords == null || m_ShaderKeywords.Length != 12) m_ShaderKeywords = new string[12]; + + m_ShaderKeywords[0] = ShaderProperties.GetOrthographicProjectionKeyword(cameraData.camera.orthographic); + m_ShaderKeywords[1] = ShaderProperties.GetQualityKeyword(hbao.quality.value); + m_ShaderKeywords[2] = ShaderProperties.GetNoiseKeyword(hbao.noiseType.value); + m_ShaderKeywords[3] = ShaderProperties.GetDeinterleavingKeyword(hbao.deinterleaving.value); + m_ShaderKeywords[4] = ShaderProperties.GetDebugKeyword(hbao.debugMode.value); + m_ShaderKeywords[5] = ShaderProperties.GetMultibounceKeyword(hbao.useMultiBounce.value, hbao.mode.value == HBAO.Mode.LitAO); + m_ShaderKeywords[6] = ShaderProperties.GetOffscreenSamplesContributionKeyword(hbao.offscreenSamplesContribution.value); + m_ShaderKeywords[7] = ShaderProperties.GetPerPixelNormalsKeyword(hbao.perPixelNormals.value); + m_ShaderKeywords[8] = ShaderProperties.GetBlurRadiusKeyword(hbao.blurType.value); + m_ShaderKeywords[9] = ShaderProperties.GetVarianceClippingKeyword(hbao.varianceClipping.value); + m_ShaderKeywords[10] = ShaderProperties.GetColorBleedingKeyword(hbao.colorBleedingEnabled.value, hbao.mode.value == HBAO.Mode.LitAO); + m_ShaderKeywords[11] = ShaderProperties.GetModeKeyword(hbao.mode.value); + + material.shaderKeywords = m_ShaderKeywords; + } +#endif + + private void CheckParameters() + { + if (hbao.deinterleaving.value != HBAO.Deinterleaving.Disabled && SystemInfo.supportedRenderTargetCount < 4) + hbao.SetDeinterleaving(HBAO.Deinterleaving.Disabled); + + if (hbao.temporalFilterEnabled.value && !motionVectorsSupported) + hbao.EnableTemporalFilter(false); + + if (hbao.colorBleedingEnabled.value && hbao.temporalFilterEnabled.value && SystemInfo.supportedRenderTargetCount < 2) + hbao.EnableTemporalFilter(false); + + if (hbao.colorBleedingEnabled.value && hbao.mode.value == HBAO.Mode.LitAO) + hbao.EnableColorBleeding(false); + + // Noise texture + if (noiseTex == null || m_PreviousNoiseType != hbao.noiseType.value) + { + CoreUtils.Destroy(noiseTex); + + CreateNoiseTexture(); + + m_PreviousNoiseType = hbao.noiseType.value; + } + } + + private RenderTextureDescriptor GetStereoCompatibleDescriptor(int width, int height, RenderTextureFormat format = RenderTextureFormat.Default, int depthBufferBits = 0, RenderTextureReadWrite readWrite = RenderTextureReadWrite.Default) + { + // Inherit the VR setup from the camera descriptor + var desc = sourceDesc; + desc.depthBufferBits = depthBufferBits; + desc.msaaSamples = 1; + desc.width = width; + desc.height = height; + desc.colorFormat = format; + + if (readWrite == RenderTextureReadWrite.sRGB) + desc.sRGB = true; + else if (readWrite == RenderTextureReadWrite.Linear) + desc.sRGB = false; + else if (readWrite == RenderTextureReadWrite.Default) + desc.sRGB = isLinearColorSpace; + + return desc; + } + + private static void BlitFullscreenTriangle(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, Mesh fullscreenTriangle, int passIndex = 0) + { + cmd.SetGlobalTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destination, 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex); + } + + private static void BlitFullscreenTriangle(CommandBuffer cmd, RenderTexture source, RenderTargetIdentifier destination, Material material, Mesh fullscreenTriangle, int passIndex, MaterialPropertyBlock properties) + { + properties.SetTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(new RenderTargetIdentifier(destination, 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices), RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex, properties); + } + + private static void BlitFullscreenTriangle(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Rect viewportRect, Material material, Mesh fullscreenTriangle, int passIndex = 0) + { + cmd.SetGlobalTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destination, 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices); + cmd.SetViewport(viewportRect); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex); + } + + private static void BlitFullscreenTriangle(CommandBuffer cmd, RenderTexture source, RenderTargetIdentifier destination, Rect viewportRect, Material material, Mesh fullscreenTriangle, int passIndex, MaterialPropertyBlock properties) + { + properties.SetTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(new RenderTargetIdentifier(destination, 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices), RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); + cmd.SetViewport(viewportRect); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex, properties); + } + + private static void BlitFullscreenTriangle(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier[] destinations, Material material, Mesh fullscreenTriangle, int passIndex = 0) + { + cmd.SetGlobalTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destinations, destinations[0], 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex); + } + + private static void BlitFullscreenTriangle(CommandBuffer cmd, RenderTexture source, RenderTargetIdentifier[] destinations, Material material, Mesh fullscreenTriangle, int passIndex, MaterialPropertyBlock properties) + { + properties.SetTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destinations, destinations[0], 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex, properties); + } + + private static void BlitFullscreenTriangle(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier[] destinations, Rect viewportRect, Material material, Mesh fullscreenTriangle, int passIndex = 0) + { + cmd.SetGlobalTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destinations, destinations[0], 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices); + cmd.SetViewport(viewportRect); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex); + } + + private static void BlitFullscreenTriangle(CommandBuffer cmd, RenderTexture source, RenderTargetIdentifier[] destinations, Rect viewportRect, Material material, Mesh fullscreenTriangle, int passIndex, MaterialPropertyBlock properties) + { + properties.SetTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destinations, destinations[0], 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices); + cmd.SetViewport(viewportRect); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex, properties); + } + + private static void BlitFullscreenTriangleWithClear(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, Color clearColor, Mesh fullscreenTriangle, int passIndex = 0) + { + cmd.SetGlobalTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(destination, 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices); + cmd.ClearRenderTarget(false, true, clearColor); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex); + } + + private static void BlitFullscreenTriangleWithClear(CommandBuffer cmd, RenderTexture source, RenderTargetIdentifier destination, Material material, Color clearColor, Mesh fullscreenTriangle, int passIndex, MaterialPropertyBlock properties) + { + properties.SetTexture(ShaderProperties.mainTex, source); + cmd.SetRenderTarget(new RenderTargetIdentifier(destination, 0, CubemapFace.Unknown, RenderTargetIdentifier.AllDepthSlices), RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); + cmd.ClearRenderTarget(false, true, clearColor); + cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, passIndex, properties); + } + + private Vector2 AdjustBrightnessMaskToGammaSpace(Vector2 v) + { + return isLinearColorSpace ? v : ToGammaSpace(v); + } + + private float ToGammaSpace(float v) + { + return Mathf.Pow(v, 0.454545454545455f); + } + + private Vector2 ToGammaSpace(Vector2 v) + { + return new Vector2(ToGammaSpace(v.x), ToGammaSpace(v.y)); + } + + private void CreateNoiseTexture() + { + noiseTex = new Texture2D(4, 4, SystemInfo.SupportsTextureFormat(TextureFormat.RGHalf) ? TextureFormat.RGHalf : TextureFormat.RGB24, false, true); + noiseTex.filterMode = FilterMode.Point; + noiseTex.wrapMode = TextureWrapMode.Repeat; + int z = 0; + for (int x = 0; x < 4; ++x) + { + for (int y = 0; y < 4; ++y) + { + float r1 = hbao.noiseType.value != HBAO.NoiseType.Dither ? 0.25f * (0.0625f * ((x + y & 3) << 2) + (x & 3)) : MersenneTwister.Numbers[z++]; + float r2 = hbao.noiseType.value != HBAO.NoiseType.Dither ? 0.25f * ((y - x) & 3) : MersenneTwister.Numbers[z++]; + Color color = new Color(r1, r2, 0); + noiseTex.SetPixel(x, y, color); + } + } + noiseTex.Apply(); + + for (int i = 0, j = 0; i < s_jitter.Length; ++i) + { + float r1 = MersenneTwister.Numbers[j++]; + float r2 = MersenneTwister.Numbers[j++]; + s_jitter[i] = new Vector2(r1, r2); + } + } + } + + [SerializeField, HideInInspector] + private Shader shader; + private HBAORenderPass m_HBAORenderPass; + + void OnDisable() + { + m_HBAORenderPass?.Cleanup(); + } + + public override void Create() + { + if (!isActive) + { + m_HBAORenderPass?.Cleanup(); + m_HBAORenderPass = null; + return; + } + + name = "HBAO"; + + m_HBAORenderPass = new HBAORenderPass(); + m_HBAORenderPass.FillSupportedRenderTextureFormats(); + } + + protected override void Dispose(bool disposing) + { + m_HBAORenderPass?.Cleanup(); + m_HBAORenderPass = null; + } + + // Here you can inject one or multiple render passes in the renderer. + // This method is called when setting up the renderer once per-camera. + public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) + { + shader = Shader.Find("Hidden/Universal Render Pipeline/HBAO"); + if (shader == null) + { + Debug.LogWarning("HBAO shader was not found. Please ensure it compiles correctly"); + return; + } + + if (renderingData.cameraData.postProcessEnabled) + { + m_HBAORenderPass.Setup(shader, renderer, renderingData); + renderer.EnqueuePass(m_HBAORenderPass); + } + } + } +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAORendererFeature.cs.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAORendererFeature.cs.meta new file mode 100644 index 00000000..2c84c51a --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Runtime/HBAORendererFeature.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: f7c2c2c3c19808149a4d3454e1019255 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: + - settings: {fileID: 11400000, guid: 68dde9df85a05a54fbc92e3b6f3a8c42, type: 2} + - hbaoShader: {fileID: 4800000, guid: bf610497676b34e4dbe0f14fe3fe311c, type: 3} + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders.meta new file mode 100644 index 00000000..a2dea7d0 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 39ee3648c2c58684590305025db692f6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO.shader b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO.shader new file mode 100644 index 00000000..236e4ace --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO.shader @@ -0,0 +1,384 @@ +Shader "Hidden/Universal Render Pipeline/HBAO" +{ + Properties + { + _MainTex("", any) = "" {} + _HBAOTex("", any) = "" {} + _TempTex("", any) = "" {} + _NoiseTex("", 2D) = "" {} + _DepthTex("", any) = "" {} + _NormalsTex("", any) = "" {} + } + + HLSLINCLUDE + + #pragma target 3.0 + #pragma prefer_hlslcc gles + #pragma exclude_renderers d3d11_9x + #pragma editor_sync_compilation + //#pragma enable_d3d11_debug_symbols + + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #if UNITY_VERSION >= 202330 + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/GlobalSamplers.hlsl" + #endif + + TEXTURE2D_X(_MainTex); + TEXTURE2D_X(_HBAOTex); + TEXTURE2D_X(_TempTex); + TEXTURE2D_X(_DepthTex); + TEXTURE2D_X(_NormalsTex); + //TEXTURE2D_X(_CameraNormalsTexture); + TEXTURE2D_X(_MotionVectorTexture); + TEXTURE2D(_NoiseTex); + #if !(UNITY_VERSION >= 202330) + SAMPLER(sampler_LinearClamp); + SAMPLER(sampler_PointRepeat); + SAMPLER(sampler_PointClamp); + #endif + + float4 _HistoryBuffer_RTHandleScale; + + CBUFFER_START(FrequentlyUpdatedUniforms) + float4 _Input_TexelSize; + float4 _AO_TexelSize; + float4 _DeinterleavedAO_TexelSize; + float4 _ReinterleavedAO_TexelSize; + float4 _TargetScale; + float4 _UVToView[2]; + //float4x4 _WorldToCameraMatrix; + float _Radius[2]; + float _MaxRadiusPixels; + float _NegInvRadius2; + float _AngleBias; + float _AOmultiplier; + float _Intensity; + half4 _BaseColor; + float _MultiBounceInfluence; + float _OffscreenSamplesContrib; + float _MaxDistance; + float _DistanceFalloff; + float _BlurSharpness; + float _ColorBleedSaturation; + float _ColorBleedBrightnessMask; + float2 _ColorBleedBrightnessMaskRange; + float2 _TemporalParams; + CBUFFER_END + + CBUFFER_START(PerPassUpdatedUniforms) + float2 _BlurDeltaUV; + CBUFFER_END + + CBUFFER_START(PerPassUpdatedDeinterleavingUniforms) + float2 _Deinterleave_Offset00; + float2 _Deinterleave_Offset10; + float2 _Deinterleave_Offset01; + float2 _Deinterleave_Offset11; + float2 _AtlasOffset; + float2 _Jitter; + CBUFFER_END + + struct Attributes + { + float4 positionOS : POSITION; + + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 positionCS : SV_POSITION; + float2 uv : TEXCOORD0; + + UNITY_VERTEX_OUTPUT_STEREO + }; + + float2 TransformTriangleVertexToUV(float2 vertex) + { + float2 uv = (vertex + 1.0) * 0.5; + return uv; + } + + Varyings Vert(Attributes input) + { + Varyings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + //output.positionCS = TransformObjectToHClip(input.positionOS.xyz); + // Note: The pass is setup with a mesh already in CS + // Therefore, we can just output vertex position + output.positionCS = float4(input.positionOS.xy, 0.0, 1.0); + output.uv = TransformTriangleVertexToUV(input.positionOS.xy); + #if UNITY_UV_STARTS_AT_TOP + output.uv = output.uv * float2(1.0, -1.0) + float2(0.0, 1.0); + #endif + return output; + } + + Varyings Vert_Atlas(Attributes input) + { + Varyings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + //float3 pos = input.positionOS.xyz; + //pos.xy = pos.xy * (_DeinterleavedAO_TexelSize.zw / _ReinterleavedAO_TexelSize.zw) + _AtlasOffset * _ReinterleavedAO_TexelSize.xy; + //output.positionCS = TransformObjectToHClip(pos); + output.positionCS = float4((input.positionOS.xy + float2(-3.0, 1.0)) * (_DeinterleavedAO_TexelSize.zw / _ReinterleavedAO_TexelSize.zw) + 2.0 * _AtlasOffset * _ReinterleavedAO_TexelSize.xy, 0.0, 1.0); + output.uv = TransformTriangleVertexToUV(input.positionOS.xy); + + // flip triangle upside down + output.positionCS.y = 1 - output.positionCS.y; + return output; + } + + ENDHLSL + + SubShader + { + Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" } + LOD 100 + ZWrite Off ZTest Always Blend Off Cull Off + + Pass // 0 + { + Name "HBAO - AO" + + HLSLPROGRAM + #pragma multi_compile_local_fragment __ ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ OFFSCREEN_SAMPLES_CONTRIBUTION + #pragma multi_compile_local_fragment __ NORMALS_RECONSTRUCT2 NORMALS_RECONSTRUCT4 + #pragma multi_compile_local_fragment __ INTERLEAVED_GRADIENT_NOISE + #pragma multi_compile_local_fragment QUALITY_LOWEST QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_HIGHEST + #pragma multi_compile_fragment __ _GBUFFER_NORMALS_OCT // support octahedron endoded normals + + #if QUALITY_LOWEST + #define DIRECTIONS 3 + #define STEPS 2 + #elif QUALITY_LOW + #define DIRECTIONS 4 + #define STEPS 3 + #elif QUALITY_MEDIUM + #define DIRECTIONS 6 + #define STEPS 4 + #elif QUALITY_HIGH + #define DIRECTIONS 8 + #define STEPS 4 + #elif QUALITY_HIGHEST + #define DIRECTIONS 8 + #define STEPS 6 + #else + #define DIRECTIONS 1 + #define STEPS 1 + #endif + + #pragma vertex Vert + #pragma fragment AO_Frag + + #include "HBAO_AO.hlsl" + ENDHLSL + } + + Pass // 1 + { + Name "HBAO - AO Deinterleaved" + + HLSLPROGRAM + #pragma multi_compile_local_fragment __ ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ OFFSCREEN_SAMPLES_CONTRIBUTION + #pragma multi_compile_local_fragment QUALITY_LOWEST QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_HIGHEST + + #if QUALITY_LOWEST + #define DIRECTIONS 3 + #define STEPS 2 + #elif QUALITY_LOW + #define DIRECTIONS 4 + #define STEPS 3 + #elif QUALITY_MEDIUM + #define DIRECTIONS 6 + #define STEPS 4 + #elif QUALITY_HIGH + #define DIRECTIONS 8 + #define STEPS 4 + #elif QUALITY_HIGHEST + #define DIRECTIONS 8 + #define STEPS 6 + #else + #define DIRECTIONS 1 + #define STEPS 1 + #endif + + #define DEINTERLEAVED + + #pragma vertex Vert + #pragma fragment AO_Frag + + #include "HBAO_AO.hlsl" + ENDHLSL + } + + // 2 + Pass { + Name "HBAO - Deinterleave Depth" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment DeinterleaveDepth_Frag + + #include "HBAO_Deinterleaving.hlsl" + ENDHLSL + } + + // 3 + Pass { + Name "HBAO - Deinterleave Normals" + + HLSLPROGRAM + #pragma multi_compile_local_fragment __ ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ NORMALS_RECONSTRUCT2 NORMALS_RECONSTRUCT4 + #pragma multi_compile_fragment __ _GBUFFER_NORMALS_OCT // support octahedron endoded normals + + #pragma vertex Vert + #pragma fragment DeinterleaveNormals_Frag + + #include "HBAO_Deinterleaving.hlsl" + ENDHLSL + } + + // 4 + Pass { + Name "HBAO - Atlas Deinterleaved AO" + + HLSLPROGRAM + #pragma vertex Vert_Atlas + #pragma fragment Frag + + half4 Frag(Varyings input) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = UnityStereoTransformScreenSpaceTex(input.uv); + return SAMPLE_TEXTURE2D_X(_MainTex, sampler_PointClamp, uv); + } + ENDHLSL + } + + // 5 + Pass { + Name "HBAO - Reinterleave AO" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment ReinterleaveAO_Frag + + #include "HBAO_Deinterleaving.hlsl" + ENDHLSL + } + + Pass // 6 + { + Name "HBAO - Blur" + + HLSLPROGRAM + #pragma multi_compile_local_fragment __ ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment BLUR_RADIUS_2 BLUR_RADIUS_3 BLUR_RADIUS_4 BLUR_RADIUS_5 + + #if BLUR_RADIUS_2 + #define KERNEL_RADIUS 2 + #elif BLUR_RADIUS_3 + #define KERNEL_RADIUS 3 + #elif BLUR_RADIUS_4 + #define KERNEL_RADIUS 4 + #elif BLUR_RADIUS_5 + #define KERNEL_RADIUS 5 + #else + #define KERNEL_RADIUS 0 + #endif + + #pragma vertex Vert + #pragma fragment Blur_Frag + + #include "HBAO_Blur.hlsl" + ENDHLSL + } + + Pass // 7 + { + Name "HBAO - Temporal Filter" + + HLSLPROGRAM + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ VARIANCE_CLIPPING_4TAP VARIANCE_CLIPPING_8TAP + + #pragma vertex Vert + #pragma fragment TemporalFilter_Frag + + #include "HBAO_TemporalFilter.hlsl" + ENDHLSL + } + + Pass // 8 + { + Name "HBAO - Copy" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment Frag + + half4 Frag(Varyings input) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = UnityStereoTransformScreenSpaceTex(input.uv); + return SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv); + } + ENDHLSL + } + + Pass // 9 + { + Name "HBAO - Composite" + + ColorMask RGB + + HLSLPROGRAM + #pragma multi_compile_local_fragment __ LIT_AO + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ MULTIBOUNCE + #pragma multi_compile_local_fragment __ DEBUG_AO DEBUG_COLORBLEEDING DEBUG_NOAO_AO DEBUG_AO_AOONLY DEBUG_NOAO_AOONLY + + #pragma vertex Vert + #pragma fragment Composite_Frag + + #include "HBAO_Composite.hlsl" + ENDHLSL + } + + Pass // 10 + { + Name "HBAO - Debug ViewNormals" + + ColorMask RGB + + HLSLPROGRAM + #pragma multi_compile_local_fragment __ ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ NORMALS_RECONSTRUCT2 NORMALS_RECONSTRUCT4 + #pragma multi_compile_fragment __ _GBUFFER_NORMALS_OCT // support octahedron endoded normals + + #pragma vertex Vert + #pragma fragment AO_Frag + + #define DIRECTIONS 1 + #define STEPS 1 + #define DEBUG_VIEWNORMALS + + #include "HBAO_AO.hlsl" + ENDHLSL + } + } + + Fallback Off +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO.shader.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO.shader.meta new file mode 100644 index 00000000..c979c4a0 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bf610497676b34e4dbe0f14fe3fe311c +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_AO.hlsl b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_AO.hlsl new file mode 100644 index 00000000..0845ef34 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_AO.hlsl @@ -0,0 +1,205 @@ +//---------------------------------------------------------------------------------- +// +// Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//---------------------------------------------------------------------------------- + +#ifndef HBAO_AO_INCLUDED +#define HBAO_AO_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Macros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "HBAO_Common.hlsl" + +inline float3 FetchLayerViewPos(float2 uv) { + uv = clamp(uv, 0, 1 - _Input_TexelSize.xy * 0.5); // uv guard + float depth = LinearizeDepth(SAMPLE_TEXTURE2D_X(_DepthTex, sampler_PointClamp, uv).r); +#if ORTHOGRAPHIC_PROJECTION + return float3((uv * _UVToView[unity_StereoEyeIndex].xy + _UVToView[unity_StereoEyeIndex].zw), depth); +#else + return float3((uv * _UVToView[unity_StereoEyeIndex].xy + _UVToView[unity_StereoEyeIndex].zw) * depth, depth); +#endif +} + +inline float Falloff(float distanceSquare) { + // 1 scalar mad instruction + return distanceSquare * _NegInvRadius2 + 1.0; +} + +inline float ComputeAO(float3 P, float3 N, float3 S) { + float3 V = S - P; + float VdotV = dot(V, V); + float NdotV = dot(N, V) * rsqrt(VdotV); + + // Use saturate(x) instead of max(x,0.f) because that is faster on Kepler + return saturate(NdotV - _AngleBias) * saturate(Falloff(VdotV)); +} + +inline float2 RotateDirections(float2 dir, float2 rot) { + return float2(dir.x * rot.x - dir.y * rot.y, + dir.x * rot.y + dir.y * rot.x); +} + +inline float InterleavedGradientNoise(float2 screenPos) { + // http://www.iryoku.com/downloads/Next-Generation-Post-Processing-in-Call-of-Duty-Advanced-Warfare-v18.pptx (slide 123) + float3 magic = float3(0.06711056, 0.00583715, 52.9829189); + return frac(magic.z * frac(dot(screenPos, magic.xy))); +} + +inline float2 FetchNoise(float2 screenPos) { + #if INTERLEAVED_GRADIENT_NOISE + // Use Jorge Jimenez's IGN noise and GTAO spatial offsets distribution + // https://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf (slide 93) + return float2(InterleavedGradientNoise(screenPos), SAMPLE_TEXTURE2D(_NoiseTex, sampler_PointRepeat, screenPos / 4.0).g); + #else + // (cos(alpha), sin(alpha), jitter) + return SAMPLE_TEXTURE2D(_NoiseTex, sampler_PointRepeat, screenPos / 4.0).rg; + #endif +} + +float4 AO_Frag(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = UnityStereoTransformScreenSpaceTex(input.uv); + //uint2 positionSS = input.uv * _ScreenSize.xy; + + #ifdef DEINTERLEAVED + float3 P = FetchLayerViewPos(uv); + #else + float3 P = FetchViewPos(uv); + #endif + + #ifndef DEBUG_VIEWNORMALS + clip(_MaxDistance - P.z); + #endif + + #if ORTHOGRAPHIC_PROJECTION + float stepSize = min(_Radius[unity_StereoEyeIndex], _MaxRadiusPixels) / (STEPS + 1.0); + #else + float stepSize = min((_Radius[unity_StereoEyeIndex] / P.z), _MaxRadiusPixels) / (STEPS + 1.0); + #endif + + #ifdef DEINTERLEAVED + float3 N = SAMPLE_TEXTURE2D_X(_NormalsTex, sampler_PointClamp, uv).rgb * 2.0 - 1.0; + float2 rand = _Jitter; // angle, jitter + #else + float3 N = FetchViewNormals(uv, _AO_TexelSize.xy, P); + //float2 rand = FetchNoise(positionSS); + //float2 rand = FetchNoise(input.positionCS.xy); + float2 rand = FetchNoise(uv * _AO_TexelSize.zw); + #endif + + const float alpha = 2.0 * PI / DIRECTIONS; + float ao = 0; + + #if COLOR_BLEEDING + static float2 cbUVs[DIRECTIONS * STEPS]; + static float cbContribs[DIRECTIONS * STEPS]; + #endif + + UNITY_UNROLL + for (int d = 0; d < DIRECTIONS; ++d) { + float angle = alpha * (float(d) + rand.x + _TemporalParams.x); + + // Compute normalized 2D direction + float cosA, sinA; + sincos(angle, sinA, cosA); + float2 direction = float2(cosA, sinA); + + // Jitter starting sample within the first step + float rayPixels = (frac(rand.y + _TemporalParams.y) * stepSize + 1.0); + + UNITY_UNROLL + for (int s = 0; s < STEPS; ++s) { + + #ifdef DEINTERLEAVED + float2 snappedUV = round(rayPixels * direction) * _DeinterleavedAO_TexelSize.xy + uv; + float3 S = FetchLayerViewPos(snappedUV); + #else + float2 snappedUV = round(rayPixels * direction) * _Input_TexelSize.xy + uv; + float3 S = FetchViewPos(snappedUV); + #endif + + rayPixels += stepSize; + + float contrib = ComputeAO(P, N, S); + #if OFFSCREEN_SAMPLES_CONTRIBUTION + float2 offscreenAmount = _OffscreenSamplesContrib * (snappedUV - saturate(snappedUV) != 0 ? 1 : 0); + contrib = max(contrib, offscreenAmount.x); + contrib = max(contrib, offscreenAmount.y); + #endif + ao += contrib; + + #if COLOR_BLEEDING + int sampleIdx = d * s; + cbUVs[sampleIdx] = snappedUV; + cbContribs[sampleIdx] = contrib; + #endif + } + } + + #ifdef DEBUG_VIEWNORMALS + return float4(N * 0.5 + 0.5, 1); + #else + + #if COLOR_BLEEDING + half3 col = half3(0, 0, 0); + UNITY_UNROLL + for (int s = 0; s < DIRECTIONS * STEPS; s += 2) { + half3 emission = SAMPLE_TEXTURE2D_X_LOD(_MainTex, sampler_LinearClamp, cbUVs[s], 0).rgb; + half average = (emission.x + emission.y + emission.z) / 3; + half scaledAverage = saturate((average - _ColorBleedBrightnessMaskRange.x) / (_ColorBleedBrightnessMaskRange.y - _ColorBleedBrightnessMaskRange.x + 1e-6)); + half maskMultiplier = 1 - (scaledAverage * _ColorBleedBrightnessMask); + col += emission * cbContribs[s] * maskMultiplier; + } + float4 aoOutput = float4(col, ao); + #else + float aoOutput = ao; + #endif + + // apply bias multiplier + aoOutput *= (_AOmultiplier / (STEPS * DIRECTIONS)); + + float fallOffStart = _MaxDistance - _DistanceFalloff; + float distFactor = saturate((P.z - fallOffStart) / (_MaxDistance - fallOffStart)); + + #if COLOR_BLEEDING + //aoOutput.rgb = saturate(1 - lerp(dot(aoOutput.rgb, 0.333).xxx, aoOutput.rgb, _ColorBleedSaturation)); + aoOutput.rgb = saturate(lerp(dot(aoOutput.rgb, 0.333).xxx, aoOutput.rgb, _ColorBleedSaturation)); + aoOutput = lerp(saturate(float4(aoOutput.rgb, 1 - aoOutput.a)), float4(0, 0, 0, 1), distFactor); + return aoOutput; + #else + aoOutput = lerp(saturate(1 - aoOutput), 1, distFactor); + return float4(EncodeFloatRG(saturate(P.z * (1.0 / _ProjectionParams.z))), 1.0, aoOutput); + #endif + + #endif // DEBUG_VIEWNORMALS +} + +#endif // HBAO_AO_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_AO.hlsl.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_AO.hlsl.meta new file mode 100644 index 00000000..2c68d739 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_AO.hlsl.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1361d098ef86d6c41a6a6c41e84c33a4 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Blur.hlsl b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Blur.hlsl new file mode 100644 index 00000000..9a6f1662 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Blur.hlsl @@ -0,0 +1,143 @@ +//---------------------------------------------------------------------------------- +// +// Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//---------------------------------------------------------------------------------- + +#ifndef HBAO_BLUR_INCLUDED +#define HBAO_BLUR_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "HBAO_Common.hlsl" + +#if COLOR_BLEEDING + +inline void FetchAoAndDepth(float2 uv, inout half4 ao, inout float depth) { + ao = SAMPLE_TEXTURE2D_X_LOD(_MainTex, sampler_PointClamp, uv, 0); + depth = LinearizeDepth(FetchRawDepth(uv)); +} + +inline float CrossBilateralWeight(float r, float d, float d0) { + const float BlurSigma = (float)KERNEL_RADIUS * 0.5; + const float BlurFalloff = 1.0 / (2.0*BlurSigma*BlurSigma); + + float dz = (d0 - d) * _BlurSharpness; + return exp2(-r*r*BlurFalloff - dz*dz); +} + +inline void ProcessSample(float4 ao, float z, float r, float d0, inout half4 totalAO, inout float totalW) { + float w = CrossBilateralWeight(r, d0, z); + totalW += w; + totalAO += w * ao; +} + +inline void ProcessRadius(float2 uv0, float2 deltaUV, float d0, inout half4 totalAO, inout float totalW) { + half4 ao; + float z; + float2 uv; + UNITY_UNROLL + for (int r = 1; r <= KERNEL_RADIUS; r++) { + uv = uv0 + r * deltaUV; + FetchAoAndDepth(uv, ao, z); + ProcessSample(ao, z, r, d0, totalAO, totalW); + } +} + +inline half4 ComputeBlur(float2 uv0, float2 deltaUV) { + half4 totalAO; + float depth; + FetchAoAndDepth(uv0, totalAO, depth); + float totalW = 1.0; + + ProcessRadius(uv0, -deltaUV, depth, totalAO, totalW); + ProcessRadius(uv0, deltaUV, depth, totalAO, totalW); + + totalAO /= totalW; + return totalAO; +} + +#else + +inline void FetchAoAndDepth(float2 uv, inout half ao, inout float2 depth) { + float3 aod = SAMPLE_TEXTURE2D_X_LOD(_MainTex, sampler_PointClamp, uv, 0).rga; + ao = aod.z; + depth = aod.xy; +} + +inline float CrossBilateralWeight(float r, float d, float d0) { + const float BlurSigma = (float)KERNEL_RADIUS * 0.5; + const float BlurFalloff = 1.0 / (2.0*BlurSigma*BlurSigma); + + float dz = (d0 - d) * _ProjectionParams.z * _BlurSharpness; + return exp2(-r*r*BlurFalloff - dz*dz); +} + +inline void ProcessSample(float2 aoz, float r, float d0, inout half totalAO, inout float totalW) { + float w = CrossBilateralWeight(r, d0, aoz.y); + totalW += w; + totalAO += w * aoz.x; +} + +inline void ProcessRadius(float2 uv0, float2 deltaUV, float d0, inout half totalAO, inout float totalW) { + half ao; + float z; + float2 d, uv; + UNITY_UNROLL + for (int r = 1; r <= KERNEL_RADIUS; r++) { + uv = uv0 + r * deltaUV; + FetchAoAndDepth(uv, ao, d); + z = DecodeFloatRG(d); + ProcessSample(float2(ao, z), r, d0, totalAO, totalW); + } +} + +inline float4 ComputeBlur(float2 uv0, float2 deltaUV) { + half totalAO; + float2 depth; + FetchAoAndDepth(uv0, totalAO, depth); + float d0 = DecodeFloatRG(depth); + float totalW = 1.0; + + ProcessRadius(uv0, -deltaUV, d0, totalAO, totalW); + ProcessRadius(uv0, deltaUV, d0, totalAO, totalW); + + totalAO /= totalW; + return float4(depth, 1.0, totalAO); +} +#endif // COLOR_BLEEDING + +float4 Blur_Frag(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = UnityStereoTransformScreenSpaceTex(input.uv); + + return ComputeBlur(uv, _BlurDeltaUV); +} + +#endif // HBAO_BLUR_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Blur.hlsl.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Blur.hlsl.meta new file mode 100644 index 00000000..8795429b --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Blur.hlsl.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 88f16f7670609254aa357e3d46e3dffe +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Common.hlsl b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Common.hlsl new file mode 100644 index 00000000..25601e41 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Common.hlsl @@ -0,0 +1,93 @@ +#ifndef HBAO_COMMON_INCLUDED +#define HBAO_COMMON_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" +#if VERSION_GREATER_EQUAL(10, 0) +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl" +#endif + +inline float FetchRawDepth(float2 uv) { + return SampleSceneDepth(uv * _TargetScale.xy); +} + +inline float LinearizeDepth(float depth) { + // References: https://docs.unity3d.com/Manual/SL-PlatformDifferences.html +#if ORTHOGRAPHIC_PROJECTION +#if UNITY_REVERSED_Z + depth = 1 - depth; +#endif // UNITY_REVERSED_Z + float linearDepth = _ProjectionParams.y + depth * (_ProjectionParams.z - _ProjectionParams.y); // near + depth * (far - near) +#else + float linearDepth = LinearEyeDepth(depth, _ZBufferParams); +#endif // ORTHOGRAPHIC_PROJECTION + return linearDepth; +} + +inline float3 FetchViewPos(float2 uv) { + uv = clamp(uv, 0, 1 - _Input_TexelSize.xy * 0.5); // uv guard + float depth = LinearizeDepth(FetchRawDepth(uv)); +#if ORTHOGRAPHIC_PROJECTION + return float3((uv * _UVToView[unity_StereoEyeIndex].xy + _UVToView[unity_StereoEyeIndex].zw), depth); +#else + return float3((uv * _UVToView[unity_StereoEyeIndex].xy + _UVToView[unity_StereoEyeIndex].zw) * depth, depth); +#endif +} + +inline float3 MinDiff(float3 P, float3 Pr, float3 Pl) { + float3 V1 = Pr - P; + float3 V2 = P - Pl; + return (dot(V1, V1) < dot(V2, V2)) ? V1 : V2; +} + +inline float3 FetchViewNormals(float2 uv, float2 delta, float3 P) { +#if NORMALS_RECONSTRUCT4 + float3 Pr, Pl, Pt, Pb; + Pr = FetchViewPos(uv + float2(delta.x, 0)); + Pl = FetchViewPos(uv + float2(-delta.x, 0)); + Pt = FetchViewPos(uv + float2(0, delta.y)); + Pb = FetchViewPos(uv + float2(0, -delta.y)); + float3 N = normalize(cross(MinDiff(P, Pr, Pl), MinDiff(P, Pt, Pb))); +#elif NORMALS_RECONSTRUCT2 + float3 Pr, Pt; + Pr = FetchViewPos(uv + float2(delta.x, 0)); + Pt = FetchViewPos(uv + float2(0, delta.y)); + float3 N = normalize(cross(Pt - P, P - Pr)); +#else +#if VERSION_GREATER_EQUAL(10, 0) + float3 N = SampleSceneNormals(uv * _TargetScale.xy); +#if VERSION_GREATER_EQUAL(12, 0) + N = normalize(TransformWorldToViewDir(N)); // normals are worldspace, convert to viewspace + N = float3(N.x, -N.yz); +#else + N = float3(N.x, -N.y, N.z); +#endif +#else + float3 N = float3(0, 0, 0); +#endif +#endif + return N; +} + +inline float3 FetchViewNormals(float2 uv, float2 delta) { + + float3 P = FetchViewPos(uv); + return FetchViewNormals(uv, delta, P); +} + +// https://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ + +inline float2 EncodeFloatRG(float v) { + float2 enc = float2(1.0, 255.0) * v; + enc = frac(enc); + enc.x -= enc.y * (1.0 / 255.0); + return enc; +} + +inline float DecodeFloatRG(float2 rg) { + return dot(rg, float2(1.0, 1 / 255.0)); +} + +#endif // HBAO_COMMON_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Common.hlsl.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Common.hlsl.meta new file mode 100644 index 00000000..0b08b8be --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Common.hlsl.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c9db0967d4ddb8d4da2fc53a15906f15 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Composite.hlsl b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Composite.hlsl new file mode 100644 index 00000000..57887610 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Composite.hlsl @@ -0,0 +1,79 @@ +#ifndef HBAO_COMPOSITE_INCLUDED +#define HBAO_COMPOSITE_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "HBAO_Common.hlsl" + +inline half4 FetchOcclusion(float2 uv) { + uv *= _HistoryBuffer_RTHandleScale.xy; + return SAMPLE_TEXTURE2D_X(_HBAOTex, sampler_LinearClamp, uv * _TargetScale.zw); +} + +inline half4 FetchSceneColor(float2 uv) { + //return LOAD_TEXTURE2D_X(_MainTex, positionSS); // load not supported on GLES2 + return SAMPLE_TEXTURE2D_X(_MainTex, sampler_PointClamp, uv); +} + +inline half3 MultiBounceAO(float visibility, half3 albedo) { + half3 a = 2.0404 * albedo - 0.3324; + half3 b = -4.7951 * albedo + 0.6417; + half3 c = 2.7552 * albedo + 0.6903; + + float x = visibility; + return max(x, ((x * a + b) * x + c) * x); +} + +float4 Composite_Frag(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + //uint2 positionSS = input.uv * _ScreenSize.xy; + float2 uv = UnityStereoTransformScreenSpaceTex(input.uv); + + half4 ao = FetchOcclusion(uv); + + ao.a = saturate(pow(abs(ao.a), _Intensity)); + + #if LIT_AO + half3 aoColor = ao.aaa; + half4 col = ao.aaaa; + #else + half3 aoColor = lerp(_BaseColor.rgb, half3(1.0, 1.0, 1.0), ao.a); + half4 col = FetchSceneColor(uv); + + #if MULTIBOUNCE + aoColor = lerp(aoColor, MultiBounceAO(ao.a, lerp(col.rgb, _BaseColor.rgb, _BaseColor.rgb)), _MultiBounceInfluence); + #endif + + col.rgb *= aoColor; + + #if COLOR_BLEEDING + //col.rgb += 1 - ao.rgb; + col.rgb += ao.rgb; + #endif + #endif // LIT_AO + + #if DEBUG_AO + col.rgb = aoColor; + #elif DEBUG_COLORBLEEDING && COLOR_BLEEDING + //col.rgb = 1 - ao.rgb; + col.rgb = ao.rgb; + #elif DEBUG_NOAO_AO || DEBUG_AO_AOONLY || DEBUG_NOAO_AOONLY + if (uv.x <= 0.4985) { + #if DEBUG_NOAO_AO || DEBUG_NOAO_AOONLY + col = FetchSceneColor(uv); + #endif // DEBUG_NOAO_AO || DEBUG_NOAO_AOONLY + return col; + } + if (uv.x > 0.4985 && uv.x < 0.5015) { + return half4(0, 0, 0, 1); + } + #if DEBUG_AO_AOONLY || DEBUG_NOAO_AOONLY + col.rgb = aoColor; + #endif // DEBUG_AO_AOONLY) || DEBUG_NOAO_AOONLY + #endif // DEBUG_AO + return col; +} + +#endif // HBAO_COMPOSITE_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Composite.hlsl.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Composite.hlsl.meta new file mode 100644 index 00000000..216ef631 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Composite.hlsl.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5724686e7ad5fff4cb8cc1ad5529cd06 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Deinterleaving.hlsl b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Deinterleaving.hlsl new file mode 100644 index 00000000..4fa06fd5 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Deinterleaving.hlsl @@ -0,0 +1,70 @@ +#ifndef HBAO_DEINTERLEAVING_INCLUDED +#define HBAO_DEINTERLEAVING_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "HBAO_Common.hlsl" + +struct DeinterleavedOutput { + float4 Z00 : SV_Target0; + float4 Z10 : SV_Target1; + float4 Z01 : SV_Target2; + float4 Z11 : SV_Target3; +}; + +DeinterleavedOutput DeinterleaveDepth_Frag(Varyings input) +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + DeinterleavedOutput o; + + float2 uv = UnityStereoTransformScreenSpaceTex(input.uv); + + float2 pos = floor(uv * _DeinterleavedAO_TexelSize.zw) * 4.0; + float2 uv00 = (pos + _Deinterleave_Offset00 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv10 = (pos + _Deinterleave_Offset10 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv01 = (pos + _Deinterleave_Offset01 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv11 = (pos + _Deinterleave_Offset11 + 0.5) * _ReinterleavedAO_TexelSize.xy; + + o.Z00 = FetchRawDepth(uv00).rrrr; + o.Z10 = FetchRawDepth(uv10).rrrr; + o.Z01 = FetchRawDepth(uv01).rrrr; + o.Z11 = FetchRawDepth(uv11).rrrr; + return o; +} + +DeinterleavedOutput DeinterleaveNormals_Frag(Varyings input) +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + DeinterleavedOutput o; + + float2 uv = UnityStereoTransformScreenSpaceTex(input.uv); + + float2 pos = floor(uv * _DeinterleavedAO_TexelSize.zw) * 4.0; + float2 uv00 = (pos + _Deinterleave_Offset00 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv10 = (pos + _Deinterleave_Offset10 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv01 = (pos + _Deinterleave_Offset01 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv11 = (pos + _Deinterleave_Offset11 + 0.5) * _ReinterleavedAO_TexelSize.xy; + + o.Z00 = float4(FetchViewNormals(uv00, _ReinterleavedAO_TexelSize.xy) * 0.5 + 0.5, 0); + o.Z10 = float4(FetchViewNormals(uv10, _ReinterleavedAO_TexelSize.xy) * 0.5 + 0.5, 0); + o.Z01 = float4(FetchViewNormals(uv01, _ReinterleavedAO_TexelSize.xy) * 0.5 + 0.5, 0); + o.Z11 = float4(FetchViewNormals(uv11, _ReinterleavedAO_TexelSize.xy) * 0.5 + 0.5, 0); + + return o; +} + +half4 ReinterleaveAO_Frag(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = UnityStereoTransformScreenSpaceTex(input.uv); + + float2 offset = fmod(floor(uv * _ReinterleavedAO_TexelSize.zw), 4.0); + uv = (floor(uv * _DeinterleavedAO_TexelSize.zw) + (offset * _DeinterleavedAO_TexelSize.zw) + 0.5) * _ReinterleavedAO_TexelSize.xy; + + return SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv); +} + +#endif // HBAO_DEINTERLEAVING_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Deinterleaving.hlsl.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Deinterleaving.hlsl.meta new file mode 100644 index 00000000..b13bd5bf --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_Deinterleaving.hlsl.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 713016b17f006794a883de31a276c28e +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_TemporalFilter.hlsl b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_TemporalFilter.hlsl new file mode 100644 index 00000000..76e26287 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_TemporalFilter.hlsl @@ -0,0 +1,175 @@ +#ifndef HBAO_TEMPORALFILTER_INCLUDED +#define HBAO_TEMPORALFILTER_INCLUDED + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "HBAO_Common.hlsl" + +struct HistoryOutput { + float4 aoHistory : SV_Target0; + #if COLOR_BLEEDING + half4 colorBleedingHistory : SV_Target1; + #endif +}; + +#if COLOR_BLEEDING +#define CTYPE half4 +#else +#define CTYPE half +#endif + +inline void FetchAoAndDepth(float2 uv, inout CTYPE ao, inout float2 depth) { + #if COLOR_BLEEDING + ao = SAMPLE_TEXTURE2D_X(_HBAOTex, sampler_PointClamp, uv); + depth = EncodeFloatRG(saturate(LinearizeDepth(FetchRawDepth(uv)) * (1.0 / _ProjectionParams.z))); + #else + float3 aod = SAMPLE_TEXTURE2D_X(_HBAOTex, sampler_PointClamp, uv).rga; + ao = aod.z; + depth = aod.xy; + #endif +} + +inline float2 FetchMotionVectors(float2 uv) { + return SAMPLE_TEXTURE2D_X(_MotionVectorTexture, sampler_PointClamp, uv * _TargetScale.xy).rg; +} + +inline float4 FetchAoHistory(float2 uv) { + return SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv * _HistoryBuffer_RTHandleScale.zw); +} + +inline half4 FetchColorBleedingHistory(float2 uv) { + return SAMPLE_TEXTURE2D_X(_TempTex, sampler_LinearClamp, uv * _HistoryBuffer_RTHandleScale.zw); +} + +inline CTYPE FetchNeighbor(float2 uv, float2 offset) { + #if COLOR_BLEEDING + return SAMPLE_TEXTURE2D_X(_HBAOTex, sampler_PointClamp, uv + _AO_TexelSize.xy * offset); + #else + return SAMPLE_TEXTURE2D_X(_HBAOTex, sampler_PointClamp, uv + _AO_TexelSize.xy * offset).a; + #endif +} + +inline half DisocclusionTest(float2 uvm1, float2 depth, float2 depthm1) { + + // disocclusion test + // https://developer.nvidia.com/sites/default/files/akamai/gamedev/files/gdc12/GDC12_Bavoil_Stable_SSAO_In_BF3_With_STF.pdf (Page 19) + float z = DecodeFloatRG(depth); + float zm1 = DecodeFloatRG(depthm1); + // for fetching zi-1, use clamp-to-border to discard out-of-frame data, with borderZ = 0.f + // https://developer.nvidia.com/sites/default/files/akamai/gamedev/files/gdc12/GDC12_Bavoil_Stable_SSAO_In_BF3_With_STF.pdf (Page 39) + // if (uvm1.x < 0 || uvm1.y < 0 || uvm1.x > 1 || uvm1.y > 1) zm1 = 0; + // if (uvm1.x < 0 || uvm1.y < 0 || uvm1.x > 1 || uvm1.y > 1) => dot(step(half4(uvm1, 1, 1), half4(0, 0, uvm1)), 1) is 1 if out-of-frame, so + zm1 *= 1.0 - dot(step(float4(uvm1, 1, 1), float4(0, 0, uvm1)), 1); + // relaxed disocclusion test: abs(1.0 - (z / zm1)) > 0.1 => 10% + // float disocclusion = max(sign(abs(1.0 - (z / zm1)) - 0.1), 0.0); + float disocclusion = abs(1.0 - (z / zm1)) > 0.1; + + return disocclusion; +} + +inline CTYPE VarianceClipping(float2 uv, CTYPE ao, CTYPE aom1, float velocityWeight) { + + // neighborhood clamping + // http://twvideo01.ubm-us.net/o1/vault/gdc2016/Presentations/Pedersen_LasseJonFuglsang_TemporalReprojectionAntiAliasing.pdf // (pages 26-28) + // superseded by variance clipping + // http://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf (page 23-29) + #if VARIANCE_CLIPPING_4TAP + CTYPE cT = FetchNeighbor(uv, float2(0, 1)); + CTYPE cR = FetchNeighbor(uv, float2(1, 0)); + CTYPE cB = FetchNeighbor(uv, float2(0, -1)); + CTYPE cL = FetchNeighbor(uv, float2(-1, 0)); + // compute 1st and 2nd color moments + CTYPE m1 = ao + cT + cR + cB + cL; + CTYPE m2 = ao * ao + cT * cT + cR * cR + cB * cB + cL * cL; + // aabb from mean u and variance sigma2 + CTYPE mu = m1 / 5.0; + CTYPE sigma = sqrt(m2 / 5.0 - mu * mu); + + #elif VARIANCE_CLIPPING_8TAP + CTYPE cTL = FetchNeighbor(uv, float2(-1, 1)); + CTYPE cT = FetchNeighbor(uv, float2(0, 1)); + CTYPE cTR = FetchNeighbor(uv, float2(1, 1)); + CTYPE cR = FetchNeighbor(uv, float2(1, 0)); + CTYPE cBR = FetchNeighbor(uv, float2(1, -1)); + CTYPE cB = FetchNeighbor(uv, float2(0, -1)); + CTYPE cBL = FetchNeighbor(uv, float2(-1, -1)); + CTYPE cL = FetchNeighbor(uv, float2(-1, 0)); + // compute 1st and 2nd color moments + CTYPE m1 = ao + cTL + cT + cTR + cR + cBR + cB + cBL + cL; + CTYPE m2 = ao * ao + cTL * cTL + cT * cT + cTR * cTR + cR * cR + cBR * cBR + cB * cB + cBL * cBL + cL * cL; + // aabb from mean u and variance sigma2 + CTYPE mu = m1 / 9.0; + CTYPE sigma = sqrt(m2 / 9.0 - mu * mu); + #endif + + #if VARIANCE_CLIPPING_4TAP || VARIANCE_CLIPPING_8TAP + float gamma = lerp(75.0, 0.75, velocityWeight); // scale down sigma for reduced ghosting + CTYPE cmin = mu - gamma * sigma; + CTYPE cmax = mu + gamma * sigma; + + // clipping + return clamp(aom1, cmin, cmax); + #else + return aom1; + #endif +} + +HistoryOutput TemporalFilter_Frag(Varyings input) +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = UnityStereoTransformScreenSpaceTex(input.uv); + + // fetch current frame data + CTYPE ao; float2 depth; + FetchAoAndDepth(uv, ao, depth); + + // fetch motion vectors, calculate previous frame uv + float2 mv = FetchMotionVectors(uv); + float2 uvm1 = uv - mv.xy; + float mvl = length(mv); + + // fetch history + float4 aoHistory = FetchAoHistory(uvm1); + #if COLOR_BLEEDING + half4 colorBleedingHistory = FetchColorBleedingHistory(uvm1); + CTYPE aom1 = colorBleedingHistory; + #else + CTYPE aom1 = aoHistory.w; + #endif + float2 depthm1 = aoHistory.xy; + float mvlm1 = aoHistory.z; + + // velocity weight + float velocityWeight = saturate(abs(mvl - mvlm1) * 300.0); + + // do disocclusion test + half disocclusion = DisocclusionTest(uvm1, depth, depthm1); + + // apply velocity weight and disocclusion + #if COLOR_BLEEDING + aom1.a = aom1.a + saturate(dot(float2(velocityWeight, disocclusion), 1.0)) * (ao.a - aom1.a); + #else + aom1 = aom1 + saturate(dot(float2(velocityWeight, disocclusion), 1.0)) * (ao - aom1); + #endif + + // do variance clipping + aom1 = VarianceClipping(uv, ao, aom1, velocityWeight); + + // exponential accumulation buffer + // http://www.klayge.org/material/4_11/Filmic%20SMAA%20v7.pdf (page 54) + // http://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf (page 13) + ao = aom1 + 0.1 * (ao - aom1); + + HistoryOutput o; + #if COLOR_BLEEDING + o.aoHistory = float4(depth, mvl, ao.a); + o.colorBleedingHistory = ao; + #else + o.aoHistory = float4(depth, mvl, ao); + #endif + + return o; +} + +#endif // HBAO_TEMPORALFILTER_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_TemporalFilter.hlsl.meta b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_TemporalFilter.hlsl.meta new file mode 100644 index 00000000..79f7a18d --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/SRP/URP/Shaders/HBAO_TemporalFilter.hlsl.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bbf71e1c97b8d654da3f7646050e713e +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders.meta b/Assets/External/Horizon Based Ambient Occlusion/Shaders.meta new file mode 100644 index 00000000..29d3173e --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a4a5705f6447808468fca071356bd185 +folderAsset: yes +timeCreated: 1455959813 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO.shader b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO.shader new file mode 100644 index 00000000..bdb0e826 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO.shader @@ -0,0 +1,464 @@ +Shader "Hidden/HBAO" +{ + Properties { + _MainTex ("", any) = "" {} + _HBAOTex ("", any) = "" {} + _TempTex("", any) = "" {} + _NoiseTex("", 2D) = "" {} + _DepthTex("", any) = "" {} + _NormalsTex("", any) = "" {} + } + + CGINCLUDE + + #pragma target 3.0 + #pragma editor_sync_compilation + + #include "UnityCG.cginc" + + UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex); + UNITY_DECLARE_SCREENSPACE_TEXTURE(_HBAOTex); + UNITY_DECLARE_SCREENSPACE_TEXTURE(_TempTex); + UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture); + UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraGBufferTexture0); // diffuse color (RGB), occlusion (A) + UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraGBufferTexture2); // normal (rgb), --unused-- (a) + UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraMotionVectorsTexture); + UNITY_DECLARE_SCREENSPACE_TEXTURE(_NormalsTex); + UNITY_DECLARE_TEX2D(_NoiseTex); + + UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture); + UNITY_DECLARE_DEPTH_TEXTURE(_DepthTex); + + CBUFFER_START(FrequentlyUpdatedUniforms) + float4 _Input_TexelSize; + float4 _AO_TexelSize; + float4 _DeinterleavedAO_TexelSize; + float4 _ReinterleavedAO_TexelSize; + float4 _TargetScale; + float4 _UVToView[2]; + //float4x4 _WorldToCameraMatrix; + float _Radius[2]; + float _MaxRadiusPixels; + float _NegInvRadius2; + float _AngleBias; + float _AOmultiplier; + float _Intensity; + half4 _BaseColor; + float _MultiBounceInfluence; + float _OffscreenSamplesContrib; + float _MaxDistance; + float _DistanceFalloff; + float _BlurSharpness; + float _ColorBleedSaturation; + float _AlbedoMultiplier; + float _ColorBleedBrightnessMask; + float2 _ColorBleedBrightnessMaskRange; + float2 _TemporalParams; + CBUFFER_END + + CBUFFER_START(PerPassUpdatedUniforms) + float4 _UVTransform; + float2 _BlurDeltaUV; + CBUFFER_END + + CBUFFER_START(PerPassUpdatedDeinterleavingUniforms) + float2 _Deinterleave_Offset00; + float2 _Deinterleave_Offset10; + float2 _Deinterleave_Offset01; + float2 _Deinterleave_Offset11; + float2 _AtlasOffset; + float2 _Jitter; + CBUFFER_END + + struct Attributes + { + float3 vertex : POSITION; + + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 vertex : SV_POSITION; + float2 uv : TEXCOORD0; + //float2 uvStereo : TEXCOORD1; + //#if STEREO_INSTANCING_ENABLED + //uint stereoTargetEyeIndex : SV_RenderTargetArrayIndex; + //#endif + + UNITY_VERTEX_OUTPUT_STEREO + }; + + float2 TransformTriangleVertexToUV(float2 vertex) + { + float2 uv = (vertex + 1.0) * 0.5; + return uv; + } + + Varyings Vert_Default(Attributes input) + { + Varyings o; + + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_OUTPUT(Varyings, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.vertex = float4(input.vertex.xy, 0.0, 1.0); + o.uv = TransformTriangleVertexToUV(input.vertex.xy); + + #if UNITY_UV_STARTS_AT_TOP + o.uv = o.uv * float2(1.0, -1.0) + float2(0.0, 1.0); + #endif + + //o.uvStereo = TransformStereoScreenSpaceTex(o.uv, 1.0); + o.uv = TransformStereoScreenSpaceTex(o.uv, 1.0); + + return o; + } + + Varyings Vert_Atlas(Attributes input) + { + Varyings o; + + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_OUTPUT(Varyings, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.vertex = float4((input.vertex.xy + float2(-3.0, 1.0)) * (_DeinterleavedAO_TexelSize.zw / _ReinterleavedAO_TexelSize.zw) + 2.0 * _AtlasOffset * _ReinterleavedAO_TexelSize.xy, 0.0, 1.0); + o.uv = TransformTriangleVertexToUV(input.vertex.xy); + + // flip triangle upside down + o.vertex.y = 1 - o.vertex.y; + + //o.uvStereo = TransformStereoScreenSpaceTex(o.uv, 1.0); + o.uv = TransformStereoScreenSpaceTex(o.uv, 1.0); + + return o; + } + + Varyings Vert_UVTransform(Attributes input) + { + Varyings o; + + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_OUTPUT(Varyings, o); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); + + o.vertex = float4(input.vertex.xy, 0.0, 1.0); + o.uv = TransformTriangleVertexToUV(input.vertex.xy) * _UVTransform.xy + _UVTransform.zw; + + //o.uvStereo = TransformStereoScreenSpaceTex(o.uv, 1.0); + o.uv = TransformStereoScreenSpaceTex(o.uv, 1.0); + + //#if STEREO_INSTANCING_ENABLED + //o.stereoTargetEyeIndex = (uint)_DepthSlice; + //#endif + + return o; + } + + ENDCG + + SubShader { + LOD 100 + ZTest Always Cull Off ZWrite Off + + // 0 + Pass { + Name "HBAO - AO" + + CGPROGRAM + #pragma multi_compile_local_fragment __ DEFERRED_SHADING ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ OFFSCREEN_SAMPLES_CONTRIBUTION + #pragma multi_compile_local_fragment __ NORMALS_CAMERA NORMALS_RECONSTRUCT + #pragma multi_compile_local_fragment __ INTERLEAVED_GRADIENT_NOISE + #pragma multi_compile_local_fragment QUALITY_LOWEST QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_HIGHEST + + #if QUALITY_LOWEST + #define DIRECTIONS 3 + #define STEPS 2 + #elif QUALITY_LOW + #define DIRECTIONS 4 + #define STEPS 3 + #elif QUALITY_MEDIUM + #define DIRECTIONS 6 + #define STEPS 4 + #elif QUALITY_HIGH + #define DIRECTIONS 8 + #define STEPS 4 + #elif QUALITY_HIGHEST + #define DIRECTIONS 8 + #define STEPS 6 + #else + #define DIRECTIONS 1 + #define STEPS 1 + #endif + + #pragma vertex Vert_Default + #pragma fragment AO_Frag + + #include "HBAO_AO.cginc" + ENDCG + } + + // 1 + Pass { + Name "HBAO - AO Deinterleaved" + + CGPROGRAM + #pragma multi_compile_local_fragment __ DEFERRED_SHADING ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ OFFSCREEN_SAMPLES_CONTRIBUTION + #pragma multi_compile_local_fragment QUALITY_LOWEST QUALITY_LOW QUALITY_MEDIUM QUALITY_HIGH QUALITY_HIGHEST + + #if QUALITY_LOWEST + #define DIRECTIONS 3 + #define STEPS 2 + #elif QUALITY_LOW + #define DIRECTIONS 4 + #define STEPS 3 + #elif QUALITY_MEDIUM + #define DIRECTIONS 6 + #define STEPS 4 + #elif QUALITY_HIGH + #define DIRECTIONS 8 + #define STEPS 4 + #elif QUALITY_HIGHEST + #define DIRECTIONS 8 + #define STEPS 6 + #else + #define DIRECTIONS 1 + #define STEPS 1 + #endif + + #define DEINTERLEAVED + + #pragma vertex Vert_Default + #pragma fragment AO_Frag + + #include "HBAO_AO.cginc" + ENDCG + } + + // 2 + Pass { + Name "HBAO - Deinterleave Depth" + + CGPROGRAM + #pragma vertex Vert_Default + #pragma fragment DeinterleaveDepth_Frag + + #include "HBAO_Deinterleaving.cginc" + ENDCG + } + + // 3 + Pass { + Name "HBAO - Deinterleave Normals" + + CGPROGRAM + #pragma multi_compile_local_fragment __ ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ NORMALS_CAMERA NORMALS_RECONSTRUCT + + #pragma vertex Vert_Default + #pragma fragment DeinterleaveNormals_Frag + + #include "HBAO_Deinterleaving.cginc" + ENDCG + } + + // 4 + Pass { + Name "HBAO - Atlas Deinterleaved AO" + + CGPROGRAM + #pragma vertex Vert_Atlas + #pragma fragment Frag + + half4 Frag(Varyings input) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, input.uv); + } + ENDCG + } + + // 5 + Pass { + Name "HBAO - Reinterleave AO" + + CGPROGRAM + #pragma vertex Vert_UVTransform + #pragma fragment ReinterleaveAO_Frag + + #include "HBAO_Deinterleaving.cginc" + ENDCG + } + + // 6 + Pass { + Name "HBAO - Blur" + + CGPROGRAM + #pragma multi_compile_local_fragment __ ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment BLUR_RADIUS_2 BLUR_RADIUS_3 BLUR_RADIUS_4 BLUR_RADIUS_5 + + #if BLUR_RADIUS_2 + #define KERNEL_RADIUS 2 + #elif BLUR_RADIUS_3 + #define KERNEL_RADIUS 3 + #elif BLUR_RADIUS_4 + #define KERNEL_RADIUS 4 + #elif BLUR_RADIUS_5 + #define KERNEL_RADIUS 5 + #else + #define KERNEL_RADIUS 0 + #endif + + #pragma vertex Vert_Default + #pragma fragment Blur_Frag + + #include "HBAO_Blur.cginc" + ENDCG + } + + // 7 + Pass { + Name "HBAO - Temporal Filter" + + CGPROGRAM + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ VARIANCE_CLIPPING_4TAP VARIANCE_CLIPPING_8TAP + + #pragma vertex Vert_Default + #pragma fragment TemporalFilter_Frag + + #include "HBAO_TemporalFilter.cginc" + ENDCG + } + + // 8 + Pass { + Name "HBAO - Copy" + + CGPROGRAM + #pragma vertex Vert_Default + #pragma fragment Frag + + half4 Frag(Varyings input) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, input.uv); + } + ENDCG + } + + // 9 + Pass { + Name "HBAO - Composite" + + ColorMask RGB + + CGPROGRAM + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ MULTIBOUNCE + #pragma multi_compile_local_fragment __ DEBUG_AO DEBUG_COLORBLEEDING DEBUG_NOAO_AO DEBUG_AO_AOONLY DEBUG_NOAO_AOONLY + + #pragma vertex Vert_UVTransform + #pragma fragment Composite_Frag + + #include "HBAO_Composite.cginc" + ENDCG + } + + // 10 + Pass { + Name "HBAO - Composite AfterLighting" + + CGPROGRAM + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ MULTIBOUNCE + #pragma multi_compile_local_fragment __ LIGHTING_LOG_ENCODED + + #pragma vertex Vert_Default + #pragma fragment Composite_Frag + + #include "HBAO_Composite.cginc" + ENDCG + } + + // 11 + Pass { + Name "HBAO - Composite BeforeReflections" + + CGPROGRAM + #pragma multi_compile_local_fragment __ COLOR_BLEEDING + #pragma multi_compile_local_fragment __ LIGHTING_LOG_ENCODED + + #pragma vertex Vert_Default + #pragma fragment Composite_Lit_Frag + + #include "HBAO_Composite.cginc" + ENDCG + } + + // 12 + Pass { + Name "HBAO - Composite BlendAO" + + ColorMask RGB + Blend Zero SrcColor + + CGPROGRAM + #pragma multi_compile_local_fragment __ MULTIBOUNCE + + #pragma vertex Vert_UVTransform + #pragma fragment Composite_Frag_BlendAO + + #include "HBAO_Composite.cginc" + ENDCG + } + + // 13 + Pass { + Name "HBAO - Composite BlendCB" + + ColorMask RGB + Blend One One + + CGPROGRAM + + #pragma vertex Vert_UVTransform + #pragma fragment Composite_Frag_BlendCB + + #include "HBAO_Composite.cginc" + ENDCG + } + + // 14 + Pass { + Name "HBAO - Debug ViewNormals" + + ColorMask RGB + + CGPROGRAM + #pragma multi_compile_local_fragment __ ORTHOGRAPHIC_PROJECTION + #pragma multi_compile_local_fragment __ NORMALS_CAMERA NORMALS_RECONSTRUCT + + #pragma vertex Vert_UVTransform + #pragma fragment AO_Frag + + #define DIRECTIONS 1 + #define STEPS 1 + #define DEBUG_VIEWNORMALS + #include "HBAO_AO.cginc" + ENDCG + } + } + + FallBack off +} diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO.shader.meta b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO.shader.meta new file mode 100644 index 00000000..c6811917 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7b834eafaedd0d842bb05a969d9d14bd +timeCreated: 1453645791 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_AO.cginc b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_AO.cginc new file mode 100644 index 00000000..f617349b --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_AO.cginc @@ -0,0 +1,204 @@ +//---------------------------------------------------------------------------------- +// +// Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//---------------------------------------------------------------------------------- + +#ifndef HBAO_AO_INCLUDED +#define HBAO_AO_INCLUDED + +#include "UnityCG.cginc" +#include "HBAO_Common.cginc" + +inline float3 FetchLayerViewPos(float2 uv) { + uv = clamp(uv, 0, 1 - _Input_TexelSize.xy * 0.5); // uv guard + float depth = LinearizeDepth(SAMPLE_DEPTH_TEXTURE(_DepthTex, uv)); + #if ORTHOGRAPHIC_PROJECTION + return float3((uv * _UVToView[unity_StereoEyeIndex].xy + _UVToView[unity_StereoEyeIndex].zw), depth); + #else + return float3((uv * _UVToView[unity_StereoEyeIndex].xy + _UVToView[unity_StereoEyeIndex].zw) * depth, depth); + #endif +} + +inline float Falloff(float distanceSquare) { + // 1 scalar mad instruction + return distanceSquare * _NegInvRadius2 + 1.0; +} + +inline float ComputeAO(float3 P, float3 N, float3 S) { + float3 V = S - P; + float VdotV = dot(V, V); + float NdotV = dot(N, V) * rsqrt(VdotV); + + // Use saturate(x) instead of max(x,0.f) because that is faster on Kepler + return saturate(NdotV - _AngleBias) * saturate(Falloff(VdotV)); +} + +inline float2 RotateDirections(float2 dir, float2 rot) { + return float2(dir.x * rot.x - dir.y * rot.y, + dir.x * rot.y + dir.y * rot.x); +} + +inline float InterleavedGradientNoise(float2 screenPos) { + // http://www.iryoku.com/downloads/Next-Generation-Post-Processing-in-Call-of-Duty-Advanced-Warfare-v18.pptx (slide 123) + float3 magic = float3(0.06711056, 0.00583715, 52.9829189); + return frac(magic.z * frac(dot(screenPos, magic.xy))); +} + +inline float2 FetchNoise(float2 screenPos) { + #if INTERLEAVED_GRADIENT_NOISE + // Use Jorge Jimenez's IGN noise and GTAO spatial offsets distribution + // https://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf (slide 93) + return float2(InterleavedGradientNoise(screenPos), UNITY_SAMPLE_TEX2D(_NoiseTex, screenPos / 4.0).g); + #else + // (cos(alpha), sin(alpha), jitter) + return UNITY_SAMPLE_TEX2D(_NoiseTex, screenPos / 4.0).rg; + #endif +} + +float4 AO_Frag(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + #ifdef DEINTERLEAVED + float3 P = FetchLayerViewPos(input.uv); + #else + float3 P = FetchViewPos(input.uv); + #endif + + #ifndef DEBUG_VIEWNORMALS + clip(_MaxDistance - P.z); + #endif + + #if ORTHOGRAPHIC_PROJECTION + float stepSize = min(_Radius[unity_StereoEyeIndex], _MaxRadiusPixels) / (STEPS + 1.0); + #else + float stepSize = min((_Radius[unity_StereoEyeIndex] / P.z), _MaxRadiusPixels) / (STEPS + 1.0); + #endif + + #ifdef DEINTERLEAVED + float3 N = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_NormalsTex, input.uv).rgb * 2.0 - 1.0; + float2 rand = _Jitter; // angle, jitter + #else + float3 N = FetchViewNormals(input.uv, _AO_TexelSize.xy, P); + float2 rand = FetchNoise(input.uv * _AO_TexelSize.zw); // angle, jitter + #endif + + const float alpha = 2.0 * UNITY_PI / DIRECTIONS; + float ao = 0; + + #if COLOR_BLEEDING + static float2 cbUVs[DIRECTIONS * STEPS]; + static float cbContribs[DIRECTIONS * STEPS]; + #endif + + UNITY_UNROLL + for (int d = 0; d < DIRECTIONS; ++d) { + float angle = alpha * (float(d) + rand.x + _TemporalParams.x); + + // Compute normalized 2D direction + float cosA, sinA; + sincos(angle, sinA, cosA); + float2 direction = float2(cosA, sinA); + + // Jitter starting sample within the first step + float rayPixels = (frac(rand.y + _TemporalParams.y) * stepSize + 1.0); + + UNITY_UNROLL + for (int s = 0; s < STEPS; ++s) { + + #ifdef DEINTERLEAVED + float2 snappedUV = round(rayPixels * direction) * _DeinterleavedAO_TexelSize.xy + input.uv; + float3 S = FetchLayerViewPos(snappedUV); + #else + float2 snappedUV = round(rayPixels * direction) * _Input_TexelSize.xy + input.uv; + float3 S = FetchViewPos(snappedUV); + #endif + rayPixels += stepSize; + + float contrib = ComputeAO(P, N, S); + + #if OFFSCREEN_SAMPLES_CONTRIBUTION + float2 offscreenAmount = _OffscreenSamplesContrib * (snappedUV - saturate(snappedUV) != 0 ? 1 : 0); + contrib = max(contrib, offscreenAmount.x); + contrib = max(contrib, offscreenAmount.y); + #endif + ao += contrib; + + #if COLOR_BLEEDING + int sampleIdx = d * s; + cbUVs[sampleIdx] = snappedUV; + cbContribs[sampleIdx] = contrib; + #endif + } + } + + #ifdef DEBUG_VIEWNORMALS + N = float3(N.x, -N.y, N.z); + return float4(N * 0.5 + 0.5, 1); + #else + + #if COLOR_BLEEDING + half3 col = half3(0, 0, 0); + UNITY_UNROLL + for (int s = 0; s < DIRECTIONS * STEPS; s += 2) { + half3 emission = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, cbUVs[s]).rgb; + half average = (emission.x + emission.y + emission.z) / 3; + half scaledAverage = saturate((average - _ColorBleedBrightnessMaskRange.x) / (_ColorBleedBrightnessMaskRange.y - _ColorBleedBrightnessMaskRange.x + 1e-6)); + half maskMultiplier = 1 - (scaledAverage * _ColorBleedBrightnessMask); + col += emission * cbContribs[s] * maskMultiplier; + } + #if DEFERRED_SHADING + half3 albedo = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraGBufferTexture0, input.uv).rgb * 0.8 + 0.2; + albedo *= _AlbedoMultiplier; + #else + half3 albedo = half3(1, 1, 1); + #endif + float4 aoOutput = float4(col, ao); + #else + float aoOutput = ao; + #endif + + // apply bias multiplier + aoOutput *= (_AOmultiplier / (STEPS * DIRECTIONS)); + + float fallOffStart = _MaxDistance - _DistanceFalloff; + float distFactor = saturate((P.z - fallOffStart) / (_MaxDistance - fallOffStart)); + + #if COLOR_BLEEDING + //aoOutput.rgb = saturate(1 - lerp(dot(aoOutput.rgb, 0.333).xxx, aoOutput.rgb * albedo, _ColorBleedSaturation)); + aoOutput.rgb = saturate(lerp(dot(aoOutput.rgb, 0.333).xxx, aoOutput.rgb * albedo, _ColorBleedSaturation)); + aoOutput = lerp(saturate(float4(aoOutput.rgb, 1 - aoOutput.a)), float4(0, 0, 0, 1), distFactor); + return aoOutput; + #else + aoOutput = lerp(saturate(1 - aoOutput), 1, distFactor); + return float4(EncodeFloatRG(saturate(P.z * (1.0 / _ProjectionParams.z))), 1.0, aoOutput); + #endif + + #endif // DEBUG_VIEWNORMALS +} +#endif // HBAO_AO_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_AO.cginc.meta b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_AO.cginc.meta new file mode 100644 index 00000000..6c170ca0 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_AO.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: aa7be86dd68319442ac4a9c85bb21c81 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Blur.cginc b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Blur.cginc new file mode 100644 index 00000000..1b1fb138 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Blur.cginc @@ -0,0 +1,139 @@ +//---------------------------------------------------------------------------------- +// +// Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//---------------------------------------------------------------------------------- + +#ifndef HBAO_BLUR_INCLUDED +#define HBAO_BLUR_INCLUDED + +#include "HBAO_Common.cginc" + +#if COLOR_BLEEDING + +inline void FetchAoAndDepth(float2 uv, inout half4 ao, inout float depth) { + ao = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, uv); + depth = LinearizeDepth(FetchRawDepth(uv)); +} + +inline float CrossBilateralWeight(float r, float d, float d0) { + const float BlurSigma = (float)KERNEL_RADIUS * 0.5; + const float BlurFalloff = 1.0 / (2.0*BlurSigma*BlurSigma); + + float dz = (d0 - d) * _BlurSharpness; + return exp2(-r*r*BlurFalloff - dz*dz); +} + +inline void ProcessSample(float4 ao, float z, float r, float d0, inout half4 totalAO, inout float totalW) { + float w = CrossBilateralWeight(r, d0, z); + totalW += w; + totalAO += w * ao; +} + +inline void ProcessRadius(float2 uv0, float2 deltaUV, float d0, inout half4 totalAO, inout float totalW) { + half4 ao; + float z; + float2 uv; + UNITY_UNROLL + for (int r = 1; r <= KERNEL_RADIUS; r++) { + uv = uv0 + r * deltaUV; + FetchAoAndDepth(uv, ao, z); + ProcessSample(ao, z, r, d0, totalAO, totalW); + } +} + +inline half4 ComputeBlur(float2 uv0, float2 deltaUV) { + half4 totalAO; + float depth; + FetchAoAndDepth(uv0, totalAO, depth); + float totalW = 1.0; + + ProcessRadius(uv0, -deltaUV, depth, totalAO, totalW); + ProcessRadius(uv0, deltaUV, depth, totalAO, totalW); + + totalAO /= totalW; + return totalAO; +} + +#else + +inline void FetchAoAndDepth(float2 uv, inout half ao, inout float2 depth) { + float3 aod = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, uv).rga; + ao = aod.z; + depth = aod.xy; +} + +inline float CrossBilateralWeight(float r, float d, float d0) { + const float BlurSigma = (float)KERNEL_RADIUS * 0.5; + const float BlurFalloff = 1.0 / (2.0*BlurSigma*BlurSigma); + + float dz = (d0 - d) * _ProjectionParams.z * _BlurSharpness; + return exp2(-r*r*BlurFalloff - dz*dz); +} + +inline void ProcessSample(float2 aoz, float r, float d0, inout half totalAO, inout float totalW) { + float w = CrossBilateralWeight(r, d0, aoz.y); + totalW += w; + totalAO += w * aoz.x; +} + +inline void ProcessRadius(float2 uv0, float2 deltaUV, float d0, inout half totalAO, inout float totalW) { + half ao; + float z; + float2 d, uv; + UNITY_UNROLL + for (int r = 1; r <= KERNEL_RADIUS; r++) { + uv = uv0 + r * deltaUV; + FetchAoAndDepth(uv, ao, d); + z = DecodeFloatRG(d); + ProcessSample(float2(ao, z), r, d0, totalAO, totalW); + } +} + +inline float4 ComputeBlur(float2 uv0, float2 deltaUV) { + half totalAO; + float2 depth; + FetchAoAndDepth(uv0, totalAO, depth); + float d0 = DecodeFloatRG(depth); + float totalW = 1.0; + + ProcessRadius(uv0, -deltaUV, d0, totalAO, totalW); + ProcessRadius(uv0, deltaUV, d0, totalAO, totalW); + + totalAO /= totalW; + return float4(depth, 1.0, totalAO); +} +#endif // COLOR_BLEEDING + +float4 Blur_Frag(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + return ComputeBlur(input.uv, _BlurDeltaUV); +} + +#endif // HBAO_BLUR_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Blur.cginc.meta b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Blur.cginc.meta new file mode 100644 index 00000000..c1a18e69 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Blur.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6fd3fc8e7b174414084ef2a2f3ce7cc0 +timeCreated: 1453540070 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Common.cginc b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Common.cginc new file mode 100644 index 00000000..280e9fae --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Common.cginc @@ -0,0 +1,67 @@ +#ifndef HBAO_COMMON_INCLUDED +#define HBAO_COMMON_INCLUDED + +#include "UnityCG.cginc" + +inline float FetchRawDepth(float2 uv) { + return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv * _TargetScale.xy); +} + +inline float LinearizeDepth(float depth) { + // References: https://docs.unity3d.com/Manual/SL-PlatformDifferences.html +#if ORTHOGRAPHIC_PROJECTION +#if UNITY_REVERSED_Z + depth = 1 - depth; +#endif // UNITY_REVERSED_Z + float linearDepth = _ProjectionParams.y + depth * (_ProjectionParams.z - _ProjectionParams.y); // near + depth * (far - near) +#else + float linearDepth = LinearEyeDepth(depth); +#endif // ORTHOGRAPHIC_PROJECTION + return linearDepth; +} + +inline float3 FetchViewPos(float2 uv) { + uv = clamp(uv, 0, 1 - _Input_TexelSize.xy * 0.5); // uv guard + float depth = LinearizeDepth(FetchRawDepth(uv)); +#if ORTHOGRAPHIC_PROJECTION + return float3((uv * _UVToView[unity_StereoEyeIndex].xy + _UVToView[unity_StereoEyeIndex].zw), depth); +#else + return float3((uv * _UVToView[unity_StereoEyeIndex].xy + _UVToView[unity_StereoEyeIndex].zw) * depth, depth); +#endif +} + +inline float3 MinDiff(float3 P, float3 Pr, float3 Pl) { + float3 V1 = Pr - P; + float3 V2 = P - Pl; + return (dot(V1, V1) < dot(V2, V2)) ? V1 : V2; +} + +inline float3 FetchViewNormals(float2 uv, float2 delta, float3 P) { + #if NORMALS_RECONSTRUCT + float3 Pr, Pl, Pt, Pb; + Pr = FetchViewPos(uv + float2(delta.x, 0)); + Pl = FetchViewPos(uv + float2(-delta.x, 0)); + Pt = FetchViewPos(uv + float2(0, delta.y)); + Pb = FetchViewPos(uv + float2(0, -delta.y)); + float3 N = normalize(cross(MinDiff(P, Pr, Pl), MinDiff(P, Pt, Pb))); + #else + #if NORMALS_CAMERA + float3 N = DecodeViewNormalStereo(UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv * _TargetScale.xy)); + #else + float3 N = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraGBufferTexture2, uv * _TargetScale.xy).rgb * 2.0 - 1.0; + //N = mul((float3x3)_WorldToCameraMatrix, N); + N = mul((float3x3)UNITY_MATRIX_V, N); + #endif // NORMALS_CAMERA + N = float3(N.x, -N.yz); + #endif // NORMALS_RECONSTRUCT + + return N; +} + +inline float3 FetchViewNormals(float2 uv, float2 delta) { + + float3 P = FetchViewPos(uv); + return FetchViewNormals(uv, delta, P); +} + +#endif // HBAO_COMMON_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Common.cginc.meta b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Common.cginc.meta new file mode 100644 index 00000000..64b6e886 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Common.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bd898bf629326454b8b704ad339d0312 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Composite.cginc b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Composite.cginc new file mode 100644 index 00000000..cfcc9fe6 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Composite.cginc @@ -0,0 +1,150 @@ +#ifndef HBAO_COMPOSITE_INCLUDED +#define HBAO_COMPOSITE_INCLUDED + +#include "UnityCG.cginc" +#include "HBAO_Common.cginc" + +inline half4 FetchOcclusion(float2 uv) { + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_HBAOTex, uv * _TargetScale.zw); +} + +inline half4 FetchSceneColor(float2 uv) { + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, uv); +} + +inline half4 FetchGBuffer0(float2 uv) { + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_TempTex, uv); +} + +inline half4 FetchGBuffer3(float2 uv) { + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, uv); +} + +inline half3 MultiBounceAO(float visibility, half3 albedo) { + half3 a = 2.0404 * albedo - 0.3324; + half3 b = -4.7951 * albedo + 0.6417; + half3 c = 2.7552 * albedo + 0.6903; + + float x = visibility; + return max(x, ((x * a + b) * x + c) * x); +} + +half4 Composite_Frag(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + //uint2 positionSS = input.uv * _ScreenSize.xy; + + half4 ao = FetchOcclusion(input.uv); + + ao.a = saturate(pow(abs(ao.a), _Intensity)); + half3 aoColor = lerp(_BaseColor.rgb, half3(1.0, 1.0, 1.0), ao.a); + + half4 col = FetchSceneColor(input.uv); + + #if LIGHTING_LOG_ENCODED + col.rgb = -log2(col.rgb); + #endif + + #if MULTIBOUNCE + aoColor = lerp(aoColor, MultiBounceAO(ao.a, lerp(col.rgb, _BaseColor.rgb, _BaseColor.rgb)), _MultiBounceInfluence); + #endif + + col.rgb *= aoColor; + + #if COLOR_BLEEDING + //col.rgb += 1 - ao.rgb; + col.rgb += ao.rgb; + #endif + + #if LIGHTING_LOG_ENCODED + col.rgb = exp2(-col.rgb); + #endif + + #if DEBUG_AO + col.rgb = aoColor; + #elif DEBUG_COLORBLEEDING && COLOR_BLEEDING + //col.rgb = 1 - ao.rgb; + col.rgb = ao.rgb; + #elif DEBUG_NOAO_AO || DEBUG_AO_AOONLY || DEBUG_NOAO_AOONLY + if (input.uv.x <= 0.4985) { + #if DEBUG_NOAO_AO || DEBUG_NOAO_AOONLY + col = FetchSceneColor(input.uv); + #endif // DEBUG_NOAO_AO || DEBUG_NOAO_AOONLY + return col; + } + if (input.uv.x > 0.4985 && input.uv.x < 0.5015) { + return half4(0, 0, 0, 1); + } + #if DEBUG_AO_AOONLY || DEBUG_NOAO_AOONLY + col.rgb = aoColor; + #endif // DEBUG_AO_AOONLY) || DEBUG_NOAO_AOONLY + #endif // DEBUG_AO + return col; +} + +half4 Composite_Frag_BlendAO(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + half4 ao = FetchOcclusion(input.uv); + + ao.a = saturate(pow(abs(ao.a), _Intensity)); + half3 aoColor = lerp(_BaseColor.rgb, half3(1.0, 1.0, 1.0), ao.a); + + #if MULTIBOUNCE + half4 col = FetchSceneColor(input.uv); + aoColor = lerp(aoColor, MultiBounceAO(ao.a, lerp(col.rgb, _BaseColor.rgb, _BaseColor.rgb)), _MultiBounceInfluence); + #endif + + return float4(aoColor, 1); +} + +half4 Composite_Frag_BlendCB(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + half4 ao = FetchOcclusion(input.uv); + + return float4(ao.rgb, 1); +} + + +struct CombinedOutput { + half4 gbuffer0 : SV_Target0; // albedo (RGB), occlusion (A) + half4 gbuffer3 : SV_Target1; // emission (RGB), unused(A) +}; + +CombinedOutput Composite_Lit_Frag(Varyings input) +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + half4 ao = FetchOcclusion(input.uv); + + ao.a = saturate(pow(abs(ao.a), _Intensity)); + half3 aoColor = lerp(_BaseColor.rgb, half3(1.0, 1.0, 1.0), ao.a); + + half4 albedoOcc = FetchGBuffer0(input.uv); + half4 emission = FetchGBuffer3(input.uv); + + #if LIGHTING_LOG_ENCODED + emission.rgb = -log2(emission.rgb); + #endif + + CombinedOutput o; + o.gbuffer0 = half4(albedoOcc.rgb, albedoOcc.a * ao.a); + o.gbuffer3 = half4(emission.rgb * lerp(aoColor, half3(1.0, 1.0, 1.0), saturate((emission.r + emission.g + emission.b) / 3)), emission.a); + + #if COLOR_BLEEDING + //o.gbuffer3.rgb += 1 - ao.rgb; + o.gbuffer3.rgb += ao.rgb; + #endif + + #if LIGHTING_LOG_ENCODED + o.gbuffer3.rgb = exp2(-o.gbuffer3.rgb); + #endif + + return o; +} + +#endif // HBAO_COMPOSITE_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Composite.cginc.meta b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Composite.cginc.meta new file mode 100644 index 00000000..67f92c29 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Composite.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fccaaf1b3dbd6e74d80289679d2d1e5a +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Deinterleaving.cginc b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Deinterleaving.cginc new file mode 100644 index 00000000..54193e35 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Deinterleaving.cginc @@ -0,0 +1,62 @@ +#ifndef HBAO_DEINTERLEAVING_INCLUDED +#define HBAO_DEINTERLEAVING_INCLUDED + +#include "HBAO_Common.cginc" + +struct DeinterleavedOutput { + float4 Z00 : SV_Target0; + float4 Z10 : SV_Target1; + float4 Z01 : SV_Target2; + float4 Z11 : SV_Target3; +}; + +DeinterleavedOutput DeinterleaveDepth_Frag(Varyings input) +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + DeinterleavedOutput o; + + float2 pos = floor(input.uv * _DeinterleavedAO_TexelSize.zw) * 4.0; + float2 uv00 = (pos + _Deinterleave_Offset00 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv10 = (pos + _Deinterleave_Offset10 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv01 = (pos + _Deinterleave_Offset01 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv11 = (pos + _Deinterleave_Offset11 + 0.5) * _ReinterleavedAO_TexelSize.xy; + + o.Z00 = FetchRawDepth(uv00).rrrr; + o.Z10 = FetchRawDepth(uv10).rrrr; + o.Z01 = FetchRawDepth(uv01).rrrr; + o.Z11 = FetchRawDepth(uv11).rrrr; + return o; +} + +DeinterleavedOutput DeinterleaveNormals_Frag(Varyings input) +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + DeinterleavedOutput o; + + float2 pos = floor(input.uv * _DeinterleavedAO_TexelSize.zw) * 4.0; + float2 uv00 = (pos + _Deinterleave_Offset00 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv10 = (pos + _Deinterleave_Offset10 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv01 = (pos + _Deinterleave_Offset01 + 0.5) * _ReinterleavedAO_TexelSize.xy; + float2 uv11 = (pos + _Deinterleave_Offset11 + 0.5) * _ReinterleavedAO_TexelSize.xy; + + o.Z00 = float4(FetchViewNormals(uv00, _ReinterleavedAO_TexelSize.xy) * 0.5 + 0.5, 0); + o.Z10 = float4(FetchViewNormals(uv10, _ReinterleavedAO_TexelSize.xy) * 0.5 + 0.5, 0); + o.Z01 = float4(FetchViewNormals(uv01, _ReinterleavedAO_TexelSize.xy) * 0.5 + 0.5, 0); + o.Z11 = float4(FetchViewNormals(uv11, _ReinterleavedAO_TexelSize.xy) * 0.5 + 0.5, 0); + + return o; +} + +half4 ReinterleaveAO_Frag(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 offset = fmod(floor(input.uv * _ReinterleavedAO_TexelSize.zw), 4.0); + float2 uv = (floor(input.uv * _DeinterleavedAO_TexelSize.zw) + (offset * _DeinterleavedAO_TexelSize.zw) + 0.5) * _ReinterleavedAO_TexelSize.xy; + + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, uv); +} + +#endif // HBAO_DEINTERLEAVING_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Deinterleaving.cginc.meta b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Deinterleaving.cginc.meta new file mode 100644 index 00000000..cd16cfa0 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_Deinterleaving.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 87df896bfe60ae541ae6565690473297 +timeCreated: 1467102228 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_TemporalFilter.cginc b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_TemporalFilter.cginc new file mode 100644 index 00000000..a103aa1c --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_TemporalFilter.cginc @@ -0,0 +1,171 @@ +#ifndef HBAO_TEMPORALFILTER_INCLUDED +#define HBAO_TEMPORALFILTER_INCLUDED + +#include "HBAO_Common.cginc" + +struct HistoryOutput { + float4 aoHistory : SV_Target0; + #if COLOR_BLEEDING + half4 colorBleedingHistory : SV_Target1; + #endif +}; + +#if COLOR_BLEEDING +#define CTYPE half4 +#else +#define CTYPE half +#endif + +inline void FetchAoAndDepth(float2 uv, inout CTYPE ao, inout float2 depth) { + #if COLOR_BLEEDING + ao = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_HBAOTex, uv); + depth = EncodeFloatRG(saturate(LinearizeDepth(FetchRawDepth(uv)) * (1.0 / _ProjectionParams.z))); + #else + float3 aod = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_HBAOTex, uv).rga; + ao = aod.z; + depth = aod.xy; + #endif +} + +inline float2 FetchMotionVectors(float2 uv) { + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraMotionVectorsTexture, uv * _TargetScale.xy).rg; +} + +inline float4 FetchAoHistory(float2 uv) { + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, uv); +} + +inline half4 FetchColorBleedingHistory(float2 uv) { + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_TempTex, uv); +} + +inline CTYPE FetchNeighbor(float2 uv, float2 offset) { + #if COLOR_BLEEDING + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_HBAOTex, uv + _AO_TexelSize.xy * offset); + #else + return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_HBAOTex, uv + _AO_TexelSize.xy * offset).a; + #endif +} + +inline half DisocclusionTest(float2 uvm1, float2 depth, float2 depthm1) { + + // disocclusion test + // https://developer.nvidia.com/sites/default/files/akamai/gamedev/files/gdc12/GDC12_Bavoil_Stable_SSAO_In_BF3_With_STF.pdf (Page 19) + float z = DecodeFloatRG(depth); + float zm1 = DecodeFloatRG(depthm1); + // for fetching zi-1, use clamp-to-border to discard out-of-frame data, with borderZ = 0.f + // https://developer.nvidia.com/sites/default/files/akamai/gamedev/files/gdc12/GDC12_Bavoil_Stable_SSAO_In_BF3_With_STF.pdf (Page 39) + // if (uvm1.x < 0 || uvm1.y < 0 || uvm1.x > 1 || uvm1.y > 1) zm1 = 0; + // if (uvm1.x < 0 || uvm1.y < 0 || uvm1.x > 1 || uvm1.y > 1) => dot(step(half4(uvm1, 1, 1), half4(0, 0, uvm1)), 1) is 1 if out-of-frame, so + zm1 *= 1.0 - dot(step(float4(uvm1, 1, 1), float4(0, 0, uvm1)), 1); + // relaxed disocclusion test: abs(1.0 - (z / zm1)) > 0.1 => 10% + // float disocclusion = max(sign(abs(1.0 - (z / zm1)) - 0.1), 0.0); + float disocclusion = abs(1.0 - (z / zm1)) > 0.1; + + return disocclusion; +} + +inline CTYPE VarianceClipping(float2 uv, CTYPE ao, CTYPE aom1, float velocityWeight) { + + // neighborhood clamping + // http://twvideo01.ubm-us.net/o1/vault/gdc2016/Presentations/Pedersen_LasseJonFuglsang_TemporalReprojectionAntiAliasing.pdf // (pages 26-28) + // superseded by variance clipping + // http://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf (page 23-29) + #if VARIANCE_CLIPPING_4TAP + CTYPE cT = FetchNeighbor(uv, float2(0, 1)); + CTYPE cR = FetchNeighbor(uv, float2(1, 0)); + CTYPE cB = FetchNeighbor(uv, float2(0, -1)); + CTYPE cL = FetchNeighbor(uv, float2(-1, 0)); + // compute 1st and 2nd color moments + CTYPE m1 = ao + cT + cR + cB + cL; + CTYPE m2 = ao * ao + cT * cT + cR * cR + cB * cB + cL * cL; + // aabb from mean u and variance sigma2 + CTYPE mu = m1 / 5.0; + CTYPE sigma = sqrt(m2 / 5.0 - mu * mu); + + #elif VARIANCE_CLIPPING_8TAP + CTYPE cTL = FetchNeighbor(uv, float2(-1, 1)); + CTYPE cT = FetchNeighbor(uv, float2(0, 1)); + CTYPE cTR = FetchNeighbor(uv, float2(1, 1)); + CTYPE cR = FetchNeighbor(uv, float2(1, 0)); + CTYPE cBR = FetchNeighbor(uv, float2(1, -1)); + CTYPE cB = FetchNeighbor(uv, float2(0, -1)); + CTYPE cBL = FetchNeighbor(uv, float2(-1, -1)); + CTYPE cL = FetchNeighbor(uv, float2(-1, 0)); + // compute 1st and 2nd color moments + CTYPE m1 = ao + cTL + cT + cTR + cR + cBR + cB + cBL + cL; + CTYPE m2 = ao * ao + cTL * cTL + cT * cT + cTR * cTR + cR * cR + cBR * cBR + cB * cB + cBL * cBL + cL * cL; + // aabb from mean u and variance sigma2 + CTYPE mu = m1 / 9.0; + CTYPE sigma = sqrt(m2 / 9.0 - mu * mu); + #endif + + #if VARIANCE_CLIPPING_4TAP || VARIANCE_CLIPPING_8TAP + float gamma = lerp(75.0, 0.75, velocityWeight); // scale down sigma for reduced ghosting + CTYPE cmin = mu - gamma * sigma; + CTYPE cmax = mu + gamma * sigma; + + // clipping + return clamp(aom1, cmin, cmax); + #else + return aom1; + #endif +} + +HistoryOutput TemporalFilter_Frag(Varyings input) +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + // fetch current frame data + CTYPE ao; float2 depth; + FetchAoAndDepth(input.uv, ao, depth); + + // fetch motion vectors, calculate previous frame uv + float2 mv = FetchMotionVectors(input.uv); + float2 uvm1 = input.uv - mv; + float mvl = length(mv); + + // fetch history + float4 aoHistory = FetchAoHistory(uvm1); + #if COLOR_BLEEDING + half4 colorBleedingHistory = FetchColorBleedingHistory(uvm1); + CTYPE aom1 = colorBleedingHistory; + #else + CTYPE aom1 = aoHistory.w; + #endif + float2 depthm1 = aoHistory.xy; + float mvlm1 = aoHistory.z; + + // velocity weight + float velocityWeight = saturate(abs(mvl - mvlm1) * 300.0); + + // do disocclusion test + half disocclusion = DisocclusionTest(uvm1, depth, depthm1); + + // apply velocity weight and disocclusion + #if COLOR_BLEEDING + aom1.a = aom1.a + saturate(dot(float2(velocityWeight, disocclusion), 1.0)) * (ao.a - aom1.a); + #else + aom1 = aom1 + saturate(dot(float2(velocityWeight, disocclusion), 1.0)) * (ao - aom1); + #endif + + // do variance clipping + aom1 = VarianceClipping(input.uv, ao, aom1, velocityWeight); + + // exponential accumulation buffer + // http://www.klayge.org/material/4_11/Filmic%20SMAA%20v7.pdf (page 54) + // http://developer.download.nvidia.com/gameworks/events/GDC2016/msalvi_temporal_supersampling.pdf (page 13) + ao = aom1 + 0.1 * (ao - aom1); + + HistoryOutput o; + #if COLOR_BLEEDING + o.aoHistory = float4(depth, mvl, ao.a); + o.colorBleedingHistory = ao; + #else + o.aoHistory = float4(depth, mvl, ao); + #endif + + return o; +} + +#endif // HBAO_TEMPORALFILTER_INCLUDED diff --git a/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_TemporalFilter.cginc.meta b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_TemporalFilter.cginc.meta new file mode 100644 index 00000000..bfbeff83 --- /dev/null +++ b/Assets/External/Horizon Based Ambient Occlusion/Shaders/HBAO_TemporalFilter.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 5fb134650ee52e041b4eb742f0f5e6fc +timeCreated: 1583930399 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ResourcesData/Background/Cathedral_medieval_Fantastic/Scene/Cathedral_medieval_Fantastic.unity b/Assets/ResourcesData/Background/Cathedral_medieval_Fantastic/Scene/Cathedral_medieval_Fantastic.unity index 53ad4605..35bdb8a3 100644 --- a/Assets/ResourcesData/Background/Cathedral_medieval_Fantastic/Scene/Cathedral_medieval_Fantastic.unity +++ b/Assets/ResourcesData/Background/Cathedral_medieval_Fantastic/Scene/Cathedral_medieval_Fantastic.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c206836fa355ddeccdeb50737ca6c0d97db3f061b17cf26331b8a5f58c264717 -size 305249 +oid sha256:792c6806644076ee13b3e5fbcb97fe81dfa3a5ccdde3a4b27d74c16729a193dc +size 133067 diff --git a/Assets/ResourcesData/Background/Cathedral_medieval_Fantastic/Scene/Cathedral_medieval_Fantastic/Global Volume Profile.asset b/Assets/ResourcesData/Background/Cathedral_medieval_Fantastic/Scene/Cathedral_medieval_Fantastic/Global Volume Profile.asset index 84711ddb..4177febd 100644 --- a/Assets/ResourcesData/Background/Cathedral_medieval_Fantastic/Scene/Cathedral_medieval_Fantastic/Global Volume Profile.asset +++ b/Assets/ResourcesData/Background/Cathedral_medieval_Fantastic/Scene/Cathedral_medieval_Fantastic/Global Volume Profile.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cfb3538ed2d35f5b0b2a665a6b8b513e02e53865dc8481ccdae330410feddc6b -size 1473 +oid sha256:1d7512f02efc7d62c8cb502dcc7443e186c63893aae504b8c01b6848abeb9f17 +size 5686