ADD : 케비티 렌더링하는 쉐이더 추가

This commit is contained in:
qsxft258@gmail.com 2025-08-24 19:33:41 +09:00
parent 4bf67212e1
commit 2c4c4cc300
58 changed files with 3158 additions and 4 deletions

View File

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

View File

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

BIN
Assets/External/Screen Space Cavity Curvature/Demo/Demo.unity (Stored with Git LFS) vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 57d9676b747e04a54943269ac00aa478
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/Demo/Demo.unity
uploadId: 664239

BIN
Assets/External/Screen Space Cavity Curvature/Demo/Demo_Readme.txt (Stored with Git LFS) vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: ade6b4cfebd3fb848a02000f8e236d59
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/Demo/Demo_Readme.txt
uploadId: 664239

View File

@ -0,0 +1,333 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-9139891969420624701
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: 1
--- !u!114 &-6363685895679108359
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: da692e001514ec24dbc4cca1949ff7e8, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 2
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Grey
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords: _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
- DistortionVectors
- MOTIONVECTORS
- TransparentDepthPrepass
- TransparentDepthPostpass
- TransparentBackface
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AnisotropyMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _CoatMaskMap:
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}
- _DetailMap:
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}
- _DistortionVectorMap:
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}
- _EmissiveColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _HeightMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMapOS:
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}
- _SpecularColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TangentMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TangentMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TransmittanceColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AORemapMax: 1
- _AORemapMin: 0
- _ATDistance: 1
- _AddPrecomputedVelocity: 0
- _AlbedoAffectEmissive: 0
- _AlphaClip: 0
- _AlphaCutoff: 0.5
- _AlphaCutoffEnable: 0
- _AlphaCutoffPostpass: 0.5
- _AlphaCutoffPrepass: 0.5
- _AlphaCutoffShadow: 0.5
- _AlphaDstBlend: 0
- _AlphaSrcBlend: 1
- _Anisotropy: 0
- _Blend: 0
- _BlendMode: 0
- _BumpScale: 1
- _CoatMask: 0
- _Cull: 2
- _CullMode: 2
- _CullModeForward: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAlbedoScale: 1
- _DetailNormalMapScale: 1
- _DetailNormalScale: 1
- _DetailSmoothnessScale: 1
- _DiffusionProfile: 0
- _DiffusionProfileHash: 0
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 0
- _DistortionBlendMode: 0
- _DistortionBlurBlendMode: 0
- _DistortionBlurDstBlend: 1
- _DistortionBlurRemapMax: 1
- _DistortionBlurRemapMin: 0
- _DistortionBlurScale: 1
- _DistortionBlurSrcBlend: 1
- _DistortionDepthTest: 1
- _DistortionDstBlend: 1
- _DistortionEnable: 0
- _DistortionScale: 1
- _DistortionSrcBlend: 1
- _DistortionVectorBias: -1
- _DistortionVectorScale: 2
- _DoubleSidedEnable: 0
- _DoubleSidedNormalMode: 1
- _DstBlend: 0
- _EmissiveColorMode: 1
- _EmissiveExposureWeight: 1
- _EmissiveIntensity: 1
- _EmissiveIntensityUnit: 0
- _EnableBlendModePreserveSpecularLighting: 1
- _EnableFogOnTransparent: 1
- _EnableGeometricSpecularAA: 0
- _EnergyConservingSpecularColor: 1
- _EnvironmentReflections: 1
- _GlossMapScale: 1
- _Glossiness: 0.261
- _GlossyReflections: 1
- _HeightAmplitude: 0.02
- _HeightCenter: 0.5
- _HeightMapParametrization: 0
- _HeightMax: 1
- _HeightMin: -1
- _HeightOffset: 0
- _HeightPoMAmplitude: 2
- _HeightTessAmplitude: 2
- _HeightTessCenter: 0.5
- _InvTilingScale: 1
- _Ior: 1.5
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _LinkDetailsWithBase: 1
- _MaterialID: 1
- _Metallic: 0
- _Mode: 0
- _NormalMapSpace: 0
- _NormalScale: 1
- _OcclusionStrength: 1
- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMinSamples: 5
- _PPDPrimitiveLength: 1
- _PPDPrimitiveWidth: 1
- _Parallax: 0.02
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ReceivesSSR: 1
- _RefractionModel: 0
- _SSRefractionProjectionModel: 0
- _Smoothness: 0.261
- _SmoothnessRemapMax: 1
- _SmoothnessRemapMin: 0
- _SmoothnessTextureChannel: 0
- _SpecularAAScreenSpaceVariance: 0.1
- _SpecularAAThreshold: 0.2
- _SpecularHighlights: 1
- _SpecularOcclusionMode: 1
- _SrcBlend: 1
- _StencilRef: 0
- _StencilRefDepth: 8
- _StencilRefDistortionVec: 4
- _StencilRefGBuffer: 10
- _StencilRefMV: 40
- _StencilWriteMask: 6
- _StencilWriteMaskDepth: 8
- _StencilWriteMaskDistortionVec: 4
- _StencilWriteMaskGBuffer: 14
- _StencilWriteMaskMV: 40
- _SubsurfaceMask: 1
- _SupportDecals: 1
- _Surface: 0
- _SurfaceType: 0
- _TexWorldScale: 1
- _TexWorldScaleEmissive: 1
- _Thickness: 1
- _TransmissionEnable: 1
- _TransparentBackfaceEnable: 0
- _TransparentCullMode: 2
- _TransparentDepthPostpassEnable: 0
- _TransparentDepthPrepassEnable: 0
- _TransparentSortPriority: 0
- _TransparentWritingMotionVec: 0
- _TransparentZWrite: 0
- _UVBase: 0
- _UVDetail: 0
- _UVEmissive: 0
- _UVSec: 0
- _UseEmissiveIntensity: 0
- _UseShadowThreshold: 0
- _WorkflowMode: 1
- _ZTestDepthEqualForOpaque: 3
- _ZTestGBuffer: 4
- _ZTestModeDistortion: 4
- _ZTestTransparent: 4
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 0.7519999, g: 0.7519999, b: 0.7519999, a: 1}
- _BaseColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0}
- _Color: {r: 0.496, g: 0.496, b: 0.496, a: 1}
- _DiffusionProfileAsset: {r: 0, g: 0, b: 0, a: 0}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColorLDR: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMaskEmissive: {r: 1, g: 0, b: 0, a: 0}

View File

@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 8b69337571b906e4fa155f23ea29714f
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/Demo/Grey.mat
uploadId: 664239

BIN
Assets/External/Screen Space Cavity Curvature/README.txt (Stored with Git LFS) vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 80618c7fb55148147b616bb1a96ad689
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/README.txt
uploadId: 664239

View File

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

View File

@ -0,0 +1,15 @@
{
"name": "SSCC.Runtime",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"UNITY_2019_1_OR_NEWER"
],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 85820f79590499445879fb52e62eb068
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/Runtime/SSCC.Runtime.asmdef
uploadId: 664239

View File

@ -0,0 +1,441 @@
using UnityEngine;
using UnityEngine.Rendering;
#if ENABLE_VR
using XRSettings = UnityEngine.XR.XRSettings;
#endif
#if UNITY_EDITOR
using UnityEditor;
#endif
using System;
using System.Collections.Generic;
using UnityEngine.Experimental.Rendering;
namespace ScreenSpaceCavityCurvature
{
[ExecuteInEditMode, ImageEffectAllowedInSceneView, AddComponentMenu("SSCC Screen Space Cavity Curvature")]
[RequireComponent(typeof(Camera))]
public class SSCC : MonoBehaviour
{
public enum PerPixelNormals { DeferredGBuffer, Camera, ReconstructedFromDepth }
public enum DebugMode { Disabled, EffectOnly, ViewNormals }
public enum CavitySamples { Low6, Medium8, High12, VeryHigh20 }
public enum CavityResolution { Full, [InspectorName("Half Upscaled")] HalfUpscaled, Half }
public enum OutputEffectTo { Screen, [InspectorName("_SSCCTexture in shaders")] _SSCCTexture }
[HideInInspector] public Shader ssccShader;
//
[Tooltip("Lerps the whole effect from 0 to 1.")] [Range(0f, 1f)] public float effectIntensity = 1f;
[Tooltip("Divides effect intensity by (depth * distanceFade).\nZero means effect doesn't fade with distance.")] [Range(0f, 1f)] public float distanceFade = 0f;
[Space(6)]
[Tooltip("The radius of curvature calculations in pixels.")] [Range(0, 4)] public int curvaturePixelRadius = 2;
[Tooltip("How bright does curvature get.")] [Range(0f, 5f)] public float curvatureBrights = 2f;
[Tooltip("How dark does curvature get.")] [Range(0f, 5f)] public float curvatureDarks = 3f;
[Space(6)]
[Tooltip("The amount of samples used for cavity calculation.")] public CavitySamples cavitySamples = CavitySamples.High12;
[Tooltip("True: Use pow() blending to make colors more saturated in bright/dark areas of cavity.\nFalse: Use additive blending.\n\nWarning: This option being enabled may mess with bloom post processing.")] public bool saturateCavity = true;
[Tooltip("The radius of cavity calculations in world units.")] [Range(0f, 0.5f)] public float cavityRadius = 0.25f;
[Tooltip("How bright does cavity get.")] [Range(0f, 5f)] public float cavityBrights = 3f;
[Tooltip("How dark does cavity get.")] [Range(0f, 5f)] public float cavityDarks = 2f;
[Tooltip("With this option enabled, cavity can be downsampled to massively improve performance at a cost to visual quality. Recommended for mobile platforms.\n\nNon-upscaled half may introduce aliasing.")] public CavityResolution cavityResolution = CavityResolution.Full;
[Space(6)]
[Tooltip("Where to get normals from.")] public PerPixelNormals normalsSource = PerPixelNormals.Camera;
[Tooltip("May be useful to check what objects contribute normals, as objects that do not contribute their normals will not contribute to the effect.")] public DebugMode debugMode = DebugMode.Disabled;
[Space(6)]
[Tooltip("Screen: Applies the effect over the entire screen.\n\n_SSCCTexture: Instead of writing the effect to the screen, will write the effect into a global shader texture named _SSCCTexture, so you can sample it selectively in your shaders and exclude certain objects from receiving outlines etc. See \"Output To Texture Examples\" folder for example shaders.")] public OutputEffectTo output = OutputEffectTo.Screen;
//
void CheckParameters()
{
if (GraphicsSettings.defaultRenderPipeline != null)
{
Debug.LogWarning("Please follow the SRP usage instructions.");
enabled = false;
}
ssccCamera.depthTextureMode |= DepthTextureMode.Depth;
if (normalsSource == PerPixelNormals.Camera) ssccCamera.depthTextureMode |= DepthTextureMode.DepthNormals;
if (ssccCamera.actualRenderingPath != RenderingPath.DeferredShading && normalsSource == PerPixelNormals.DeferredGBuffer) normalsSource = PerPixelNormals.Camera;
if (stereoActive && ssccCamera.actualRenderingPath != RenderingPath.DeferredShading && normalsSource != PerPixelNormals.ReconstructedFromDepth) normalsSource = PerPixelNormals.ReconstructedFromDepth;
if (output == OutputEffectTo._SSCCTexture && ssccCamera.actualRenderingPath == RenderingPath.DeferredShading) normalsSource = PerPixelNormals.ReconstructedFromDepth; //cant get correct normals texture in deferred
}
OutputEffectTo Output => debugMode != DebugMode.Disabled ? OutputEffectTo.Screen : output;
static class Pass
{
public const int Copy = 0;
public const int GenerateCavity = 1;
public const int HorizontalBlur = 2;
public const int VerticalBlur = 3;
public const int Final = 4;
}
static class ShaderProperties
{
public static int mainTex = Shader.PropertyToID("_MainTex");
public static int cavityTex = Shader.PropertyToID("_CavityTex");
public static int cavityTex1 = Shader.PropertyToID("_CavityTex1");
public static int tempTex = Shader.PropertyToID("_TempTex");
public static int uvTransform = Shader.PropertyToID("_UVTransform");
public static int inputTexelSize = Shader.PropertyToID("_Input_TexelSize");
public static int cavityTexTexelSize = Shader.PropertyToID("_CavityTex_TexelSize");
public static int worldToCameraMatrix = Shader.PropertyToID("_WorldToCameraMatrix");
//public static int uvToView = Shader.PropertyToID("_UVToView");
public static int effectIntensity = Shader.PropertyToID("_EffectIntensity");
public static int distanceFade = Shader.PropertyToID("_DistanceFade");
public static int curvaturePixelRadius = Shader.PropertyToID("_CurvaturePixelRadius");
public static int curvatureRidge = Shader.PropertyToID("_CurvatureBrights");
public static int curvatureValley = Shader.PropertyToID("_CurvatureDarks");
public static int cavityWorldRadius = Shader.PropertyToID("_CavityWorldRadius");
public static int cavityRidge = Shader.PropertyToID("_CavityBrights");
public static int cavityValley = Shader.PropertyToID("_CavityDarks");
public static int globalSSCCTexture = Shader.PropertyToID("_SSCCTexture");
}
Material mat;
Camera ssccCamera;
CommandBuffer cmdBuffer;
int width;
int height;
bool stereoActive;
XRSettings.StereoRenderingMode stereoRenderingMode;
int screenWidth;
int screenHeight;
CameraEvent cameraEvent => Output == OutputEffectTo.Screen ? CameraEvent.BeforeImageEffectsOpaque : CameraEvent.BeforeForwardOpaque;
CameraEvent[] possibleCameraEvents = new[] { CameraEvent.BeforeImageEffectsOpaque, CameraEvent.BeforeForwardOpaque };
Mesh fullscreenTriangle
{
get
{
if (m_FullscreenTriangle != null) return m_FullscreenTriangle;
m_FullscreenTriangle = new Mesh { name = "Fullscreen Triangle" };
m_FullscreenTriangle.SetVertices(new List<Vector3> { 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;
}
}
bool isCommandBufferDirty
{
get
{
if (m_PreviousCameraEvent != cameraEvent || m_IsCommandBufferDirty || m_PreviousDebugMode != debugMode || m_PreviousWidth != width || m_PreviousHeight != height || m_PreviousRenderingPath != ssccCamera.actualRenderingPath || m_PreviousOutputEffectTo != Output || m_PreviousCavityResolution != cavityResolution)
{
m_PreviousCameraEvent = cameraEvent; m_PreviousDebugMode = debugMode; m_PreviousWidth = width; m_PreviousHeight = height; m_PreviousRenderingPath = ssccCamera.actualRenderingPath; m_PreviousOutputEffectTo = Output; m_PreviousCavityResolution = cavityResolution;
return true;
}
return false;
}
set
{
m_IsCommandBufferDirty = value;
}
}
RenderTextureDescriptor m_sourceDescriptor;
bool m_IsCommandBufferDirty;
Mesh m_FullscreenTriangle;
CameraEvent m_PreviousCameraEvent;
DebugMode? m_PreviousDebugMode;
int m_PreviousWidth;
int m_PreviousHeight;
RenderingPath m_PreviousRenderingPath;
OutputEffectTo m_PreviousOutputEffectTo;
CavityResolution m_PreviousCavityResolution;
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
if (SystemInfo.SupportsRenderTextureFormat(format))
return format;
#endif
return RenderTextureFormat.DefaultHDR;
}
}
RenderTextureFormat sourceFormat { get { return ssccCamera.allowHDR ? defaultHDRRenderTextureFormat : RenderTextureFormat.Default; } }
static RenderTextureFormat colorFormat { get { return SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default; } }
void OnEnable()
{
if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.Depth))
{
Debug.LogWarning("SSCC shader is not supported on this platform.");
this.enabled = false;
return;
}
if (ssccShader == null) ssccShader = Shader.Find("Hidden/SSCC");
if (ssccShader == null)
{
Debug.LogError("SSCC shader was not found...");
return;
}
if (!ssccShader.isSupported)
{
Debug.LogWarning("SSCC shader is not supported on this platform.");
this.enabled = false;
return;
}
Initialize();
}
void OnDisable()
{
ClearCommandBuffer(cmdBuffer);
if (mat != null)
DestroyImmediate(mat);
if (fullscreenTriangle != null)
DestroyImmediate(fullscreenTriangle);
}
void OnPreRender()
{
if (ssccShader == null || ssccCamera == null) return;
FetchRenderParameters();
CheckParameters();
UpdateMaterialProperties();
UpdateShaderKeywords();
if (isCommandBufferDirty)
{
ClearCommandBuffer(cmdBuffer);
BuildCommandBuffer(cmdBuffer);
ssccCamera.AddCommandBuffer(cameraEvent, cmdBuffer);
isCommandBufferDirty = false;
}
}
void OnValidate()
{
if (ssccShader == null || ssccCamera == null) return;
CheckParameters();
}
void Initialize()
{
m_sourceDescriptor = new RenderTextureDescriptor(0, 0);
ssccCamera = GetComponent<Camera>();
ssccCamera.forceIntoRenderTexture = true;
mat = new Material(ssccShader);
mat.hideFlags = HideFlags.HideAndDontSave;
cmdBuffer = new CommandBuffer { name = "SSCC" };
isCommandBufferDirty = true;
}
void FetchRenderParameters()
{
#if !UNITY_SWITCH && ENABLE_VR
if (ssccCamera.stereoEnabled)
{
var xrDesc = XRSettings.eyeTextureDesc;
stereoRenderingMode = XRSettings.StereoRenderingMode.SinglePass;
if (XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.MultiPass)
stereoRenderingMode = XRSettings.StereoRenderingMode.MultiPass;
#if UNITY_STANDALONE || UNITY_EDITOR || UNITY_PS4
if (xrDesc.dimension == TextureDimension.Tex2DArray)
stereoRenderingMode = XRSettings.StereoRenderingMode.SinglePassInstanced;
#endif
if (stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePass)
{
//xrDesc.width /= 2;
xrDesc.vrUsage = VRTextureUsage.None;
}
width = xrDesc.width;
height = xrDesc.height;
m_sourceDescriptor = xrDesc;
screenWidth = XRSettings.eyeTextureWidth;
screenHeight = XRSettings.eyeTextureHeight;
if (stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePass)
screenWidth /= 2;
stereoActive = true;
}
else
#endif
{
width = ssccCamera.pixelWidth;
height = ssccCamera.pixelHeight;
m_sourceDescriptor.width = width;
m_sourceDescriptor.height = height;
screenWidth = width;
screenHeight = height;
stereoActive = false;
}
}
void ClearCommandBuffer(CommandBuffer cmd)
{
if (cmd != null)
{
//if (ssccCamera != null) ssccCamera.RemoveCommandBuffer(cameraEvent, cmd);
if (ssccCamera != null) foreach (var camEvent in possibleCameraEvents) ssccCamera.RemoveCommandBuffer(camEvent, cmd);
cmd.Clear();
}
}
void BuildCommandBuffer(CommandBuffer cmd)
{
cmd.SetGlobalVector(ShaderProperties.uvTransform, SystemInfo.graphicsUVStartsAtTop ? new Vector4(1f, -1f, 0f, 1f) : new Vector4(1f, 1f, 0f, 0f));
int div = cavityResolution == CavityResolution.Full ? 1 : cavityResolution == CavityResolution.HalfUpscaled ? 2 : 2;
cmd.GetTemporaryRT(ShaderProperties.cavityTex, width / div, height / div, 0, FilterMode.Bilinear, GraphicsFormat.R32G32B32A32_SFloat);
cmd.GetTemporaryRT(ShaderProperties.cavityTex1, width / div, height / div, 0, FilterMode.Bilinear, GraphicsFormat.R32G32B32A32_SFloat);
Render(ShaderProperties.cavityTex, cmd, mat, Pass.GenerateCavity);
if (Output == OutputEffectTo._SSCCTexture)
{
cmd.ReleaseTemporaryRT(ShaderProperties.globalSSCCTexture);
cmd.GetTemporaryRT(ShaderProperties.globalSSCCTexture, width, height, 0, FilterMode.Bilinear, GraphicsFormat.R16G16B16A16_SFloat);
cmd.SetGlobalTexture(ShaderProperties.globalSSCCTexture, new RenderTargetIdentifier(ShaderProperties.globalSSCCTexture));
Render(ShaderProperties.globalSSCCTexture, cmd, mat, Pass.Final);
}
else
{
cmd.SetGlobalTexture(ShaderProperties.globalSSCCTexture, BuiltinRenderTextureType.None);
GetScreenSpaceTemporaryRT(cmd, ShaderProperties.tempTex, colorFormat: sourceFormat);
if (stereoActive && ssccCamera.actualRenderingPath != RenderingPath.DeferredShading)
cmd.Blit(BuiltinRenderTextureType.CameraTarget, ShaderProperties.tempTex);
else
RenderWith(BuiltinRenderTextureType.CameraTarget, ShaderProperties.tempTex, cmd, mat, Pass.Copy);
RenderWith(ShaderProperties.tempTex, BuiltinRenderTextureType.CameraTarget, cmd, mat, Pass.Final);
cmd.ReleaseTemporaryRT(ShaderProperties.tempTex);
}
cmd.ReleaseTemporaryRT(ShaderProperties.cavityTex);
cmd.ReleaseTemporaryRT(ShaderProperties.cavityTex1);
}
void UpdateMaterialProperties()
{
//float tanHalfFovY = Mathf.Tan(0.5f * ssccCamera.fieldOfView * Mathf.Deg2Rad);
//float invFocalLenX = 1.0f / (1.0f / tanHalfFovY * (screenHeight / (float)screenWidth));
//float invFocalLenY = 1.0f / (1.0f / tanHalfFovY);
//mat.SetVector(ShaderProperties.uvToView, new Vector4(2.0f * invFocalLenX, -2.0f * invFocalLenY, -1.0f * invFocalLenX, 1.0f * invFocalLenY));
mat.SetVector(ShaderProperties.inputTexelSize, new Vector4(1f / width, 1f / height, width, height));
int div = cavityResolution == SSCC.CavityResolution.Full ? 1 : cavityResolution == SSCC.CavityResolution.HalfUpscaled ? 2 : 2;
mat.SetVector(ShaderProperties.cavityTexTexelSize, new Vector4(1f / (width / div), 1f / (height / div), width / div, height / div));
mat.SetMatrix(ShaderProperties.worldToCameraMatrix, ssccCamera.worldToCameraMatrix);
mat.SetFloat(ShaderProperties.effectIntensity, effectIntensity);
mat.SetFloat(ShaderProperties.distanceFade, distanceFade);
mat.SetFloat(ShaderProperties.curvaturePixelRadius, new float[] { 0f, 0.5f, 1f, 1.5f, 2.5f }[curvaturePixelRadius]);
mat.SetFloat(ShaderProperties.curvatureRidge, curvatureBrights == 0f ? 999f : (5f - curvatureBrights));
mat.SetFloat(ShaderProperties.curvatureValley, curvatureDarks == 0f ? 999f : (5f - curvatureDarks));
mat.SetFloat(ShaderProperties.cavityWorldRadius, cavityRadius);
mat.SetFloat(ShaderProperties.cavityRidge, cavityBrights * 2f);
mat.SetFloat(ShaderProperties.cavityValley, cavityDarks * 2f);
}
void UpdateShaderKeywords()
{
mat.shaderKeywords = new string[]
{
ssccCamera.orthographic ? "ORTHOGRAPHIC_PROJECTION" : "__",
debugMode == DebugMode.EffectOnly ? "DEBUG_EFFECT" : debugMode == DebugMode.ViewNormals ? "DEBUG_NORMALS" : "__",
normalsSource == PerPixelNormals.Camera ? "NORMALS_CAMERA" : normalsSource == PerPixelNormals.ReconstructedFromDepth ? "NORMALS_RECONSTRUCT" : "__",
cavitySamples == CavitySamples.Low6 ? "CAVITY_SAMPLES_6" : cavitySamples == CavitySamples.Medium8 ? "CAVITY_SAMPLES_8" : cavitySamples == CavitySamples.High12 ? "CAVITY_SAMPLES_12" : cavitySamples == CavitySamples.VeryHigh20 ? "CAVITY_SAMPLES_20" : "",
saturateCavity ? "SATURATE_CAVITY" : "__",
Output == OutputEffectTo._SSCCTexture ? "OUTPUT_TO_TEXTURE" : "__",
cavityResolution == CavityResolution.HalfUpscaled ? "UPSCALE_CAVITY" : "__"
};
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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 (ssccCamera.allowDynamicResolution)
modifiedDesc.useDynamicScale = true; //IF YOU ARE GETTING AN ERROR HERE, UNFORTUNATELY YOUR UNITY VERSION IS TOO LOW FOR THIS ASSET
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 = QualitySettings.activeColorSpace == ColorSpace.Linear;
return modifiedDesc;
}
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;
if (stereoActive && desc.dimension == TextureDimension.Tex2DArray) desc.dimension = TextureDimension.Tex2D;
cmd.GetTemporaryRT(nameID, desc, filter);
}
void RenderWith(RenderTargetIdentifier source, RenderTargetIdentifier destination, CommandBuffer cmd, Material material, int pass = 0)
{
cmd.SetGlobalTexture(ShaderProperties.mainTex, source);
cmd.SetRenderTarget(destination);
cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, pass);
}
void Render(RenderTargetIdentifier destination, CommandBuffer cmd, Material material, int pass = 0)
{
cmd.SetRenderTarget(destination);
cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, material, 0, pass);
}
}
}

View File

@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 1d35af20b508d5546ba80581bc1b979a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- ssccShader: {fileID: 4800000, guid: 89ec5ce1bd95ed946a65b649164a9c1d, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/Runtime/SSCC.cs
uploadId: 664239

View File

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

BIN
Assets/External/Screen Space Cavity Curvature/SRP/HDRP.unitypackage (Stored with Git LFS) vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 7dd73fb2fec8fb642be983cf08cfd6b1
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/SRP/HDRP.unitypackage
uploadId: 664239

BIN
Assets/External/Screen Space Cavity Curvature/SRP/README HDRP & URP.txt (Stored with Git LFS) vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: a4f2c4eda6a6d854386932e5059c70f4
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/SRP/README HDRP & URP.txt
uploadId: 664239

View File

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

BIN
Assets/External/Screen Space Cavity Curvature/SRP/URP.unitypackage (Stored with Git LFS) vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 1c45d0aac2834f14db81b11cdbcec705
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/SRP/URP.unitypackage
uploadId: 664239

View File

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

Binary file not shown.

View File

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

Binary file not shown.

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d16d1fb8798b3ad40a771b9f3856c197
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,360 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &-9139891969420624701
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 10
--- !u!114 &-3737353351393463922
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: da692e001514ec24dbc4cca1949ff7e8, type: 3}
m_Name:
m_EditorClassIdentifier:
version: 2
--- !u!21 &2100000
Material:
serializedVersion: 8
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Grey_URP
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:
- DistortionVectors
- MOTIONVECTORS
- TransparentDepthPrepass
- TransparentDepthPostpass
- TransparentBackface
m_LockedProperties:
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AnisotropyMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BentNormalMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _CoatMaskMap:
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}
- _DetailMap:
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}
- _DistortionVectorMap:
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}
- _EmissiveColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _HeightMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _IridescenceThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMapOS:
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}
- _SpecularColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubsurfaceMaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TangentMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TangentMapOS:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ThicknessMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TransmittanceColorMap:
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:
- _AORemapMax: 1
- _AORemapMin: 0
- _ATDistance: 1
- _AddPrecomputedVelocity: 0
- _AlbedoAffectEmissive: 0
- _AlphaClip: 0
- _AlphaCutoff: 0.5
- _AlphaCutoffEnable: 0
- _AlphaCutoffPostpass: 0.5
- _AlphaCutoffPrepass: 0.5
- _AlphaCutoffShadow: 0.5
- _AlphaDstBlend: 0
- _AlphaSrcBlend: 1
- _AlphaToMask: 0
- _Anisotropy: 0
- _Blend: 0
- _BlendMode: 0
- _BlendModePreserveSpecular: 1
- _BumpScale: 1
- _ClearCoatMask: 0
- _ClearCoatSmoothness: 0
- _CoatMask: 0
- _Cull: 2
- _CullMode: 2
- _CullModeForward: 2
- _Cutoff: 0.5
- _DepthOffsetEnable: 0
- _DetailAlbedoMapScale: 1
- _DetailAlbedoScale: 1
- _DetailNormalMapScale: 1
- _DetailNormalScale: 1
- _DetailSmoothnessScale: 1
- _DiffusionProfile: 0
- _DiffusionProfileHash: 0
- _DisplacementLockObjectScale: 1
- _DisplacementLockTilingScale: 1
- _DisplacementMode: 0
- _DistortionBlendMode: 0
- _DistortionBlurBlendMode: 0
- _DistortionBlurDstBlend: 1
- _DistortionBlurRemapMax: 1
- _DistortionBlurRemapMin: 0
- _DistortionBlurScale: 1
- _DistortionBlurSrcBlend: 1
- _DistortionDepthTest: 1
- _DistortionDstBlend: 1
- _DistortionEnable: 0
- _DistortionScale: 1
- _DistortionSrcBlend: 1
- _DistortionVectorBias: -1
- _DistortionVectorScale: 2
- _DoubleSidedEnable: 0
- _DoubleSidedNormalMode: 1
- _DstBlend: 0
- _DstBlendAlpha: 0
- _EmissiveColorMode: 1
- _EmissiveExposureWeight: 1
- _EmissiveIntensity: 1
- _EmissiveIntensityUnit: 0
- _EnableBlendModePreserveSpecularLighting: 1
- _EnableFogOnTransparent: 1
- _EnableGeometricSpecularAA: 0
- _EnergyConservingSpecularColor: 1
- _EnvironmentReflections: 1
- _GlossMapScale: 1
- _Glossiness: 0.261
- _GlossyReflections: 1
- _HeightAmplitude: 0.02
- _HeightCenter: 0.5
- _HeightMapParametrization: 0
- _HeightMax: 1
- _HeightMin: -1
- _HeightOffset: 0
- _HeightPoMAmplitude: 2
- _HeightTessAmplitude: 2
- _HeightTessCenter: 0.5
- _InvTilingScale: 1
- _Ior: 1.5
- _IridescenceMask: 1
- _IridescenceThickness: 1
- _LinkDetailsWithBase: 1
- _MaterialID: 1
- _Metallic: 0
- _Mode: 0
- _NormalMapSpace: 0
- _NormalScale: 1
- _OcclusionStrength: 1
- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMinSamples: 5
- _PPDPrimitiveLength: 1
- _PPDPrimitiveWidth: 1
- _Parallax: 0.02
- _QueueOffset: 0
- _ReceiveShadows: 1
- _ReceivesSSR: 1
- _RefractionModel: 0
- _SSRefractionProjectionModel: 0
- _Smoothness: 0.261
- _SmoothnessRemapMax: 1
- _SmoothnessRemapMin: 0
- _SmoothnessTextureChannel: 0
- _SpecularAAScreenSpaceVariance: 0.1
- _SpecularAAThreshold: 0.2
- _SpecularHighlights: 1
- _SpecularOcclusionMode: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _StencilRef: 0
- _StencilRefDepth: 8
- _StencilRefDistortionVec: 4
- _StencilRefGBuffer: 10
- _StencilRefMV: 40
- _StencilWriteMask: 6
- _StencilWriteMaskDepth: 8
- _StencilWriteMaskDistortionVec: 4
- _StencilWriteMaskGBuffer: 14
- _StencilWriteMaskMV: 40
- _SubsurfaceMask: 1
- _SupportDecals: 1
- _Surface: 0
- _SurfaceType: 0
- _TexWorldScale: 1
- _TexWorldScaleEmissive: 1
- _Thickness: 1
- _TransmissionEnable: 1
- _TransparentBackfaceEnable: 0
- _TransparentCullMode: 2
- _TransparentDepthPostpassEnable: 0
- _TransparentDepthPrepassEnable: 0
- _TransparentSortPriority: 0
- _TransparentWritingMotionVec: 0
- _TransparentZWrite: 0
- _UVBase: 0
- _UVDetail: 0
- _UVEmissive: 0
- _UVSec: 0
- _UseEmissiveIntensity: 0
- _UseShadowThreshold: 0
- _WorkflowMode: 1
- _ZTestDepthEqualForOpaque: 3
- _ZTestGBuffer: 4
- _ZTestModeDistortion: 4
- _ZTestTransparent: 4
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 0.504, g: 0.504, b: 0.504, a: 1}
- _BaseColorMap_MipInfo: {r: 0, g: 0, b: 0, a: 0}
- _Color: {r: 0.504, g: 0.504, b: 0.504, a: 1}
- _DiffusionProfileAsset: {r: 0, g: 0, b: 0, a: 0}
- _DoubleSidedConstants: {r: 1, g: 1, b: -1, a: 0}
- _EmissionColor: {r: 1, g: 1, b: 1, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColorLDR: {r: 0, g: 0, b: 0, a: 1}
- _InvPrimScale: {r: 1, g: 1, b: 0, a: 0}
- _IridescenceThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1}
- _SpecularColor: {r: 1, g: 1, b: 1, a: 1}
- _ThicknessRemap: {r: 0, g: 1, b: 0, a: 0}
- _TransmittanceColor: {r: 1, g: 1, b: 1, a: 1}
- _UVDetailsMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMask: {r: 1, g: 0, b: 0, a: 0}
- _UVMappingMaskEmissive: {r: 1, g: 0, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1

View File

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

View File

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

View File

@ -0,0 +1,24 @@
{
"name": "SSCC.Universal.Runtime",
"references": [
"GUID:df380645f10b7bc4b97d4f5eb6303d95",
"GUID:15fc0a57446b3144c949da3e2b9737a9"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [
"UNITY_2019_3_OR_NEWER"
],
"versionDefines": [
{
"name": "com.unity.render-pipelines.universal",
"expression": "10.0.0-preview",
"define": "URP_10_0_0_OR_NEWER"
}
],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d677d4c7cb4775748ba9aec34639fc81
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,82 @@
//#define URP_10_0_0_OR_NEWER
//#define UNITY_2021_2_OR_NEWER
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace ScreenSpaceCavityCurvature.Universal
{
[ExecuteInEditMode, VolumeComponentMenu("ScreenSpaceCavityCurvature")]
public class SSCC : VolumeComponent, IPostProcessComponent
{
public enum PerPixelNormals
{
ReconstructedFromDepth,
#if URP_10_0_0_OR_NEWER
Camera
#else
Camera_URP_VER_TOO_LOW
#endif
}
public enum DebugMode { Disabled, EffectOnly, ViewNormals }
public enum CavitySamples { Low6, Medium8, High12, VeryHigh20 }
public enum CavityResolution { Full, [InspectorName("Half Upscaled")] HalfUpscaled, Half }
public enum OutputEffectTo
{
Screen,
#if URP_10_0_0_OR_NEWER
[InspectorName("_SSCCTexture in shaders")] _SSCCTexture
#else
[InspectorName("_SSCCTexture (URP 10+)")] _SSCCTexture
#endif
}
[Serializable] public sealed class DebugModeParameter : VolumeParameter<DebugMode> { public DebugModeParameter(DebugMode value, bool overrideState = false) : base(value, overrideState) { } }
[Serializable] public sealed class GetNormalsFromParameter : VolumeParameter<PerPixelNormals> { public GetNormalsFromParameter(PerPixelNormals value, bool overrideState = false) : base(value, overrideState) { } }
[Serializable] public sealed class CavitySamplesParameter : VolumeParameter<CavitySamples> { public CavitySamplesParameter(CavitySamples value, bool overrideState = false) : base(value, overrideState) { } }
[Serializable] public sealed class CavityResolutionParameter : VolumeParameter<CavityResolution> { public CavityResolutionParameter(CavityResolution value, bool overrideState = false) : base(value, overrideState) { } }
[Serializable] public sealed class OutputParameter : VolumeParameter<OutputEffectTo> { public OutputParameter(OutputEffectTo value, bool overrideState = false) : base(value, overrideState) { } }
//
[Header("(Make sure Post Processing and Depth Texture are enabled.)")]
[Tooltip("Lerps the whole effect from 0 to 1.")] public ClampedFloatParameter effectIntensity = new ClampedFloatParameter(1f, 0f, 1f);
[Tooltip("Divides effect intensity by (depth * distanceFade).\nZero means effect doesn't fade with distance.")] public ClampedFloatParameter distanceFade = new ClampedFloatParameter(0f, 0f, 1f);
[Space(6)]
[Tooltip("The radius of curvature calculations in pixels.")] public ClampedIntParameter curvaturePixelRadius = new ClampedIntParameter(2, 0, 4);
[Tooltip("How bright does curvature get.")] public ClampedFloatParameter curvatureBrights = new ClampedFloatParameter(2f, 0f, 5f);
[Tooltip("How dark does curvature get.")] public ClampedFloatParameter curvatureDarks = new ClampedFloatParameter(3f, 0f, 5f);
[Space(6)]
[Tooltip("The amount of samples used for cavity calculation.")] public CavitySamplesParameter cavitySamples = new CavitySamplesParameter(CavitySamples.High12);
[Tooltip("True: Use pow() blending to make colors more saturated in bright/dark areas of cavity.\nFalse: Use additive blending.\n\nWarning: This option being enabled may mess with bloom post processing.")] public BoolParameter saturateCavity = new BoolParameter(true);
[Tooltip("The radius of cavity calculations in world units.")] public ClampedFloatParameter cavityRadius = new ClampedFloatParameter(0.25f, 0f, 0.5f);
[Tooltip("How bright does cavity get.")] public ClampedFloatParameter cavityBrights = new ClampedFloatParameter(3f, 0f, 5f);
[Tooltip("How dark does cavity get.")] public ClampedFloatParameter cavityDarks = new ClampedFloatParameter(2f, 0f, 5f);
[Tooltip("With this option enabled, cavity can be downsampled to massively improve performance at a cost to visual quality. Recommended for mobile platforms.\n\nNon-upscaled half may introduce aliasing.")] public CavityResolutionParameter cavityResolution = new CavityResolutionParameter(CavityResolution.Full);
[Space(6)]
[Tooltip("Where to get normals from.")]
#if URP_10_0_0_OR_NEWER
public GetNormalsFromParameter normalsSource = new GetNormalsFromParameter(PerPixelNormals.Camera);
#else
public GetNormalsFromParameter normalsSource = new GetNormalsFromParameter(PerPixelNormals.ReconstructedFromDepth);
#endif
[Tooltip("May be useful to check what objects contribute normals, as objects that do not contribute their normals will not contribute to the effect.")] public DebugModeParameter debugMode = new DebugModeParameter(DebugMode.Disabled);
[Space(6)]
[Tooltip("Screen: Applies the effect over the entire screen.\n\n_SSCCTexture: Instead of writing the effect to the screen, will write the effect into a global shader texture named _SSCCTexture, so you can sample it selectively in your shaders and exclude certain objects from receiving outlines etc. See \"Output To Texture Examples\" folder for example shaders.")] public OutputParameter output = new OutputParameter(OutputEffectTo.Screen);
//
public bool IsActive() => effectIntensity.value > 0f;
public bool IsTileCompatible() => true;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d468b943de483f641a8eb80fcd52e584
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,338 @@
//#define URP_10_0_0_OR_NEWER
//#define UNITY_2021_2_OR_NEWER
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
namespace ScreenSpaceCavityCurvature.Universal
{
public class SSCCRendererFeature : ScriptableRendererFeature
{
private class SSCCRenderPass : ScriptableRenderPass
{
void CheckParameters()
{
#if !URP_10_0_0_OR_NEWER
if (sscc.normalsSource.value == SSCC.PerPixelNormals.Camera_URP_VER_TOO_LOW)
{
sscc.normalsSource.value = SSCC.PerPixelNormals.ReconstructedFromDepth;
Debug.LogWarning("URP version too low for Camera based normals, only available in URP 10+ (Unity 2020+).");
}
if (sscc.output.value == SSCC.OutputEffectTo._SSCCTexture)
{
sscc.output.value = SSCC.OutputEffectTo.Screen;
Debug.LogWarning("URP version too low for texture output mode, only available in URP 10+ (Unity 2020+).");
}
#endif
}
SSCC.OutputEffectTo Output => sscc.debugMode.value != SSCC.DebugMode.Disabled ? SSCC.OutputEffectTo.Screen : sscc.output.value;
public SSCC sscc;
static class Pass
{
public const int Copy = 0;
public const int GenerateCavity = 1;
public const int HorizontalBlur = 2;
public const int VerticalBlur = 3;
public const int Final = 4;
}
static class ShaderProperties
{
public static int mainTex = Shader.PropertyToID("_MainTex");
public static int cavityTex = Shader.PropertyToID("_CavityTex");
public static int cavityTex1 = Shader.PropertyToID("_CavityTex1");
public static int tempTex = Shader.PropertyToID("_TempTex");
public static int uvTransform = Shader.PropertyToID("_UVTransform");
public static int inputTexelSize = Shader.PropertyToID("_Input_TexelSize");
public static int cavityTexTexelSize = Shader.PropertyToID("_CavityTex_TexelSize");
public static int worldToCameraMatrix = Shader.PropertyToID("_WorldToCameraMatrix");
//public static int uvToView = Shader.PropertyToID("_UVToView");
public static int effectIntensity = Shader.PropertyToID("_EffectIntensity");
public static int distanceFade = Shader.PropertyToID("_DistanceFade");
public static int curvaturePixelRadius = Shader.PropertyToID("_CurvaturePixelRadius");
public static int curvatureRidge = Shader.PropertyToID("_CurvatureBrights");
public static int curvatureValley = Shader.PropertyToID("_CurvatureDarks");
public static int cavityWorldRadius = Shader.PropertyToID("_CavityWorldRadius");
public static int cavityRidge = Shader.PropertyToID("_CavityBrights");
public static int cavityValley = Shader.PropertyToID("_CavityDarks");
public static int globalSSCCTexture = Shader.PropertyToID("_SSCCTexture");
}
Material mat { get; set; }
RenderTargetIdentifier source { get; set; }
CameraData cameraData { get; set; }
RenderTextureDescriptor sourceDesc { get; set; }
public void Setup(Shader shader, ScriptableRenderer renderer, RenderingData renderingData)
{
if (mat == null) mat = CoreUtils.CreateEngineMaterial(shader);
#if !URP_10_0_0_OR_NEWER
source = renderer.cameraColorTarget;
cameraData = renderingData.cameraData;
FetchVolumeComponent();
renderPassEvent = Output == SSCC.OutputEffectTo.Screen ? RenderPassEvent.BeforeRenderingTransparents : RenderPassEvent.BeforeRenderingOpaques;
#endif
}
#if URP_10_0_0_OR_NEWER
#if UNITY_2022_1_OR_NEWER
static RTHandle noneRTHandle = RTHandles.Alloc(BuiltinRenderTextureType.None);
#endif
public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
{
#if UNITY_2022_1_OR_NEWER
source = renderingData.cameraData.renderer.cameraColorTargetHandle; //implicit conversion hopefully will exist for forseable future
#else
source = renderingData.cameraData.renderer.cameraColorTarget;
#endif
cameraData = renderingData.cameraData;
FetchVolumeComponent();
var passInput = ScriptableRenderPassInput.Depth;
if (sscc.normalsSource.value == SSCC.PerPixelNormals.Camera)
passInput |= ScriptableRenderPassInput.Normal;
ConfigureInput(passInput);
#if UNITY_2021_2_OR_NEWER
ConfigureColorStoreAction(RenderBufferStoreAction.DontCare);
#endif
renderPassEvent = Output == SSCC.OutputEffectTo.Screen ? RenderPassEvent.BeforeRenderingTransparents : RenderPassEvent.BeforeRenderingOpaques;
if (Output == SSCC.OutputEffectTo._SSCCTexture)
#if UNITY_2022_1_OR_NEWER
ConfigureTarget(noneRTHandle);
#else
ConfigureTarget(BuiltinRenderTextureType.None);
#endif
}
#endif
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
if (mat == null) return;
FetchVolumeComponent();
if (!sscc.IsActive()) return;
cameraTextureDescriptor.msaaSamples = 1;
cameraTextureDescriptor.depthBufferBits = 0;
sourceDesc = cameraTextureDescriptor;
CheckParameters();
UpdateMaterialProperties();
UpdateShaderKeywords();
if (Output == SSCC.OutputEffectTo._SSCCTexture)
#if UNITY_2022_1_OR_NEWER
ConfigureTarget(noneRTHandle);
#else
ConfigureTarget(BuiltinRenderTextureType.None);
#endif
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
if (mat == null)
{
Debug.LogError("SSCC material has not been correctly initialized...");
return;
}
if (!sscc.IsActive()) return;
var cmd = CommandBufferPool.Get("SSCC");
int div = sscc.cavityResolution.value == SSCC.CavityResolution.Full ? 1 : sscc.cavityResolution.value == SSCC.CavityResolution.HalfUpscaled ? 2 : 2;
cmd.GetTemporaryRT(ShaderProperties.cavityTex, sourceDesc.width / div, sourceDesc.height / div, 0, FilterMode.Bilinear, GraphicsFormat.R32G32B32A32_SFloat);
cmd.GetTemporaryRT(ShaderProperties.cavityTex1, sourceDesc.width / div, sourceDesc.height / div, 0, FilterMode.Bilinear, GraphicsFormat.R32G32B32A32_SFloat);
Render(ShaderProperties.cavityTex, cmd, mat, Pass.GenerateCavity);
//RenderWith(ShaderProperties.cavityTex, ShaderProperties.cavityTex1, cmd, mat, Pass.HorizontalBlur);
//RenderWith(ShaderProperties.cavityTex1, ShaderProperties.cavityTex, cmd, mat, Pass.VerticalBlur);
if (Output == SSCC.OutputEffectTo._SSCCTexture)
{
cmd.ReleaseTemporaryRT(ShaderProperties.globalSSCCTexture);
cmd.GetTemporaryRT(ShaderProperties.globalSSCCTexture, sourceDesc.width, sourceDesc.height, 0, FilterMode.Bilinear, GraphicsFormat.R16G16B16A16_SFloat);
cmd.SetGlobalTexture(ShaderProperties.globalSSCCTexture, new RenderTargetIdentifier(ShaderProperties.globalSSCCTexture));
Render(ShaderProperties.globalSSCCTexture, cmd, mat, Pass.Final);
}
else
{
cmd.GetTemporaryRT(ShaderProperties.tempTex, sourceDesc);
RenderWith(source, ShaderProperties.tempTex, cmd, mat, Pass.Copy);
RenderWith(ShaderProperties.tempTex, source, cmd, mat, Pass.Final);
cmd.ReleaseTemporaryRT(ShaderProperties.tempTex);
}
cmd.ReleaseTemporaryRT(ShaderProperties.cavityTex);
cmd.ReleaseTemporaryRT(ShaderProperties.cavityTex1);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
public void Cleanup()
{
CoreUtils.Destroy(mat);
}
private void FetchVolumeComponent()
{
if (sscc == null)
sscc = VolumeManager.instance.stack.GetComponent<SSCC>();
}
void UpdateMaterialProperties()
{
var sourceWidth = cameraData.cameraTargetDescriptor.width;
var sourceHeight = cameraData.cameraTargetDescriptor.height;
//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);
//material.SetVector(ShaderProperties.uvToView, new Vector4(2.0f * invFocalLenX, -2.0f * invFocalLenY, -1.0f * invFocalLenX, 1.0f * invFocalLenY));
mat.SetVector(ShaderProperties.inputTexelSize, new Vector4(1f / sourceWidth, 1f / sourceHeight, sourceWidth, sourceHeight));
int div = sscc.cavityResolution.value == SSCC.CavityResolution.Full ? 1 : sscc.cavityResolution.value == SSCC.CavityResolution.HalfUpscaled ? 2 : 2;
mat.SetVector(ShaderProperties.cavityTexTexelSize, new Vector4(1f / (sourceWidth / div), 1f / (sourceHeight / div), sourceWidth / div, sourceHeight / div));
mat.SetMatrix(ShaderProperties.worldToCameraMatrix, cameraData.camera.worldToCameraMatrix);
mat.SetFloat(ShaderProperties.effectIntensity, sscc.effectIntensity.value);
mat.SetFloat(ShaderProperties.distanceFade, sscc.distanceFade.value);
mat.SetFloat(ShaderProperties.curvaturePixelRadius, new float[] { 0f, 0.5f, 1f, 1.5f, 2.5f }[sscc.curvaturePixelRadius.value]);
mat.SetFloat(ShaderProperties.curvatureRidge, sscc.curvatureBrights.value == 0f ? 999f : (5f - sscc.curvatureBrights.value));
mat.SetFloat(ShaderProperties.curvatureValley, sscc.curvatureDarks.value == 0f ? 999f : (5f - sscc.curvatureDarks.value));
mat.SetFloat(ShaderProperties.cavityWorldRadius, sscc.cavityRadius.value);
mat.SetFloat(ShaderProperties.cavityRidge, sscc.cavityBrights.value * 2f);
mat.SetFloat(ShaderProperties.cavityValley, sscc.cavityDarks.value * 2f);
}
void UpdateShaderKeywords()
{
mat.shaderKeywords = new string[]
{
cameraData.camera.orthographic ? "ORTHOGRAPHIC_PROJECTION" : "__",
sscc.debugMode.value == SSCC.DebugMode.EffectOnly ? "DEBUG_EFFECT" : sscc.debugMode.value == SSCC.DebugMode.ViewNormals ? "DEBUG_NORMALS" : "__",
sscc.normalsSource.value == SSCC.PerPixelNormals.ReconstructedFromDepth ? "NORMALS_RECONSTRUCT" : "__",
sscc.cavitySamples.value == SSCC.CavitySamples.Low6 ? "CAVITY_SAMPLES_6" : sscc.cavitySamples.value == SSCC.CavitySamples.Medium8 ? "CAVITY_SAMPLES_8" : sscc.cavitySamples.value == SSCC.CavitySamples.High12 ? "CAVITY_SAMPLES_12" : sscc.cavitySamples.value == SSCC.CavitySamples.VeryHigh20 ? "CAVITY_SAMPLES_20" : "",
sscc.saturateCavity.value ? "SATURATE_CAVITY" : "__",
Output == SSCC.OutputEffectTo._SSCCTexture ? "OUTPUT_TO_TEXTURE" : "__",
sscc.cavityResolution.value == SSCC.CavityResolution.HalfUpscaled ? "UPSCALE_CAVITY" : "__"
};
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static Mesh s_FullscreenMesh = null;
static Mesh fullscreenMesh
{
get
{
if (s_FullscreenMesh != null) return s_FullscreenMesh;
float topV = 1.0f;
float bottomV = 0.0f;
s_FullscreenMesh = new Mesh { name = "Fullscreen Quad" };
s_FullscreenMesh.SetVertices(new List<Vector3>
{
new Vector3(-1.0f, -1.0f, 0.0f),
new Vector3(-1.0f, 1.0f, 0.0f),
new Vector3(1.0f, -1.0f, 0.0f),
new Vector3(1.0f, 1.0f, 0.0f)
});
s_FullscreenMesh.SetUVs(0, new List<Vector2>
{
new Vector2(0.0f, bottomV),
new Vector2(0.0f, topV),
new Vector2(1.0f, bottomV),
new Vector2(1.0f, topV)
});
s_FullscreenMesh.SetIndices(new[] { 0, 1, 2, 2, 1, 3 }, MeshTopology.Triangles, 0, false);
s_FullscreenMesh.UploadMeshData(true);
return s_FullscreenMesh;
}
}
public void RenderWith(RenderTargetIdentifier source, RenderTargetIdentifier destination, CommandBuffer cmd, Material material, int passIndex = 0)
{
cmd.SetGlobalTexture(ShaderProperties.mainTex, source);
cmd.SetRenderTarget(destination, 0, CubemapFace.Unknown, -1);
cmd.DrawMesh(fullscreenMesh, Matrix4x4.identity, material, 0, passIndex);
}
public void Render(RenderTargetIdentifier destination, CommandBuffer cmd, Material material, int passIndex = 0)
{
cmd.SetRenderTarget(destination, 0, CubemapFace.Unknown, -1);
cmd.DrawMesh(fullscreenMesh, Matrix4x4.identity, material, 0, passIndex);
}
}
[SerializeField]
[Space(15)]
[Header("You can now add SSCC to your Post Process Volume.")]
Shader shader;
private SSCCRenderPass renderPass;
public override void Create()
{
if (!isActive)
{
renderPass?.Cleanup();
renderPass = null;
return;
}
name = "SSCC";
renderPass = new SSCCRenderPass();
}
void OnDisable()
{
renderPass?.Cleanup();
}
#if URP_10_0_0_OR_NEWER
protected override void Dispose(bool disposing)
{
renderPass?.Cleanup();
renderPass = null;
}
#endif
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
shader = Shader.Find("Hidden/Universal Render Pipeline/SSCC");
if (shader == null)
{
Debug.LogWarning("SSCC shader was not found. Please ensure it compiles correctly");
return;
}
if (renderingData.cameraData.postProcessEnabled)
{
renderPass.Setup(shader, renderer, renderingData);
renderer.EnqueuePass(renderPass);
}
}
}
}

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 55e6184d2ea958044a6434dca151c688
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- shader: {fileID: 4800000, guid: 62449f654265cf94e81275e55a4b1823, type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,332 @@
#if HLSL
#define SAMPLE(texture, sampler, uv) SAMPLE_TEXTURE2D_X(texture, sampler, uv)
#else
#define SAMPLE(texture, sampler, uv) UNITY_SAMPLE_SCREENSPACE_TEXTURE(texture, uv)
#endif
//CAVITY V
#ifdef CAVITY_SAMPLES_6
#define CAVITY_SAMPLES 6
#endif
#ifdef CAVITY_SAMPLES_8
#define CAVITY_SAMPLES 8
#endif
#ifdef CAVITY_SAMPLES_12
#define CAVITY_SAMPLES 12
#endif
#ifdef CAVITY_SAMPLES_20
#define CAVITY_SAMPLES 20
#endif
#ifdef SSCC_HDRP
#define ACTUAL_CAVITY_SAMPLES (CAVITY_SAMPLES+2)
#else
#define ACTUAL_CAVITY_SAMPLES (CAVITY_SAMPLES)
#endif
float _InterleavedGradientNoise(float2 pixCoord, int frameCount)
{
const float3 magic = float3(0.06711056f, 0.00583715f, 52.9829189f);
float2 frameMagicScale = float2(2.083f, 4.867f);
pixCoord += frameCount * frameMagicScale;
return frac(magic.z * frac(dot(pixCoord, magic.xy)));
}
float3 PickSamplePoint(float2 uv, float randAddon, int index)
{
float2 positionSS = uv * _CavityTex_TexelSize.zw;
float gn = _InterleavedGradientNoise(positionSS, index);
float u = frac(gn) * 2.0 - 1.0;
float theta = gn * 6.28318530717958647693;
float sn, cs;
sincos(theta, sn, cs);
return float3(float2(cs, sn) * sqrt(1.0 - u * u), u);
}
float3x3 GetCoordinateConversionParameters(out float2 p11_22, out float2 p13_31)
{
float3x3 camProj = (float3x3)unity_CameraProjection;
//float3x3 camProj = (float3x3)/*UNITY_MATRIX_P*/_Projection;
p11_22 = rcp(float2(camProj._11, camProj._22));
p13_31 = float2(camProj._13, camProj._23);
return camProj;
}
float3 ReconstructViewPos(float2 uv, float depth, float2 p11_22, float2 p13_31)
{
#if ORTHOGRAPHIC_PROJECTION
float3 viewPos = float3(((uv.xy * 2.0 - 1.0 - p13_31) * p11_22), depth);
#else
float3 viewPos = float3(depth * ((uv.xy * 2.0 - 1.0 - p13_31) * p11_22), depth);
#endif
return viewPos;
}
void SampleDepthAndViewpos(float2 uv, float2 p11_22, float2 p13_31, out float depth, out float3 vpos)
{
depth = LinearizeDepth(FetchRawDepth(uv));
vpos = ReconstructViewPos(uv, depth, p11_22, p13_31);
}
void Cavity(float2 uv, float3 normal, out float cavity, out float edges)
{
cavity = edges = 0.0;
float2 p11_22, p13_31;
float3x3 camProj = GetCoordinateConversionParameters(p11_22, p13_31);
float depth;
float3 vpos;
SampleDepthAndViewpos(uv, p11_22, p13_31, depth, vpos);
float randAddon = uv.x * 1e-10;
float rcpSampleCount = rcp(ACTUAL_CAVITY_SAMPLES);
//UNITY_LOOP
UNITY_UNROLL
for (int i = 0; i < int(ACTUAL_CAVITY_SAMPLES); i++)
{
#if defined(SHADER_API_D3D11)
i = floor(1.0001 * i);
#endif
#if 0
float3 v_s1 = PickSamplePoint(uv.yx, randAddon, i);
#else
float3 v_s1 = PickSamplePoint(uv, randAddon, i);
#endif
v_s1 *= sqrt((i + 1.0) * rcpSampleCount) * _CavityWorldRadius * 0.5;
float3 vpos_s1 = vpos + v_s1;
float3 spos_s1 = mul(camProj, vpos_s1);
#if ORTHOGRAPHIC_PROJECTION
float2 uv_s1_01 = clamp((spos_s1.xy + 1.0) * 0.5, 0.0, 1.0);
#else
float2 uv_s1_01 = clamp((spos_s1.xy * rcp(vpos_s1.z) + 1.0) * 0.5, 0.0, 1.0);
#endif
float depth_s1 = LinearizeDepth(FetchRawDepth(uv_s1_01));
float3 vpos_s2 = ReconstructViewPos(uv_s1_01, depth_s1, p11_22, p13_31);
float3 dir = vpos_s2 - vpos;
float len = length(dir);
float f_dot = dot(dir, normal);
//float kBeta = 0.002;
float kBeta = 0.002 * 4;
float f_cavities = f_dot - kBeta * depth;
float f_edge = -f_dot - kBeta * depth;
float f_bias = 0.05 * len + 0.0001;
if (f_cavities > -f_bias)
{
float attenuation = 1.0 / (len * (1.0 + len * len * 3.));
cavity += f_cavities * attenuation;
}
if (f_edge > f_bias)
{
float attenuation = 1.0 / (len * (1.0 + len * len * 0.01));
edges += f_edge * attenuation;
}
}
//cavity *= 1.0 / ACTUAL_CAVITY_SAMPLES;
//edges *= 1.0 / ACTUAL_CAVITY_SAMPLES;
cavity *= 1.0 * _CavityWorldRadius * 0.5;
edges *= 1.0 * _CavityWorldRadius * 0.5;
float kContrast = 0.6;
cavity = pow(abs(cavity * rcpSampleCount), kContrast);
edges = pow(abs(edges * rcpSampleCount), kContrast);
cavity = clamp(cavity * _CavityDarks, 0.0, 1.0);
edges = edges * _CavityBrights;
}
//CAVITY ^
//CURVATURE V
float CurvatureSoftClamp(float curvature, float control)
{
if (curvature < 0.5 / control)
return curvature * (1.0 - curvature * control);
return 0.25 / control;
}
float Curvature(float2 uv, float3 P)
{
float3 offset = float3(_Input_TexelSize.xy, 0.0) * (_CurvaturePixelRadius);
float normal_up = FetchViewNormals(P, uv + offset.zy).g;
float normal_down = FetchViewNormals(P, uv - offset.zy).g;
float normal_right = FetchViewNormals(P, uv + offset.xz).r;
float normal_left = FetchViewNormals(P, uv - offset.xz).r;
float normal_diff = (normal_up - normal_down) + (normal_right - normal_left);
//if (abs(normal_diff) <= 0.1) return 0; //slight low pass filter to remove noise from camera normals precision
//new and improved low pass filter:
//if (uv.x < 0.5)
{
if (normal_diff > 0.0) normal_diff = sign(normal_diff) * pow(normal_diff, 2.0);
_CavityBrights += 0.5;
}
if (normal_diff >= 0.0)
return 2.0 * CurvatureSoftClamp(normal_diff, _CurvatureBrights);
else
return -2.0 * CurvatureSoftClamp(-normal_diff, _CurvatureDarks);
}
//CURVATURE ^
float invLerp(float from, float to, float value) {
return (value - from) / (to - from);
}
float remap(float origFrom, float origTo, float targetFrom, float targetTo, float value) {
float rel = invLerp(origFrom, origTo, value);
return lerp(targetFrom, targetTo, rel);
}
float4 Cavity_Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#ifdef UnityStereoTransformScreenSpaceTex
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#else
float2 uv = input.uv;
#endif
float3 P = FetchViewPos(uv);
float3 N = FetchViewNormals(P, uv);
float cavity = 0.0, edges = 0.0;
Cavity(uv, N, cavity, edges);
return float4(cavity, edges, FetchRawDepth(uv), 1.0);
}
float2 GaussianBlur(float2 uv, float2 pixelOffset)
{
const float gWeights[2] =
{
0.44908,
0.05092
};
const float gOffsets[2] =
{
0.53805,
2.06278
};
float2 colOut = 0.0;
UNITY_UNROLL
for(int i = 0; i < 2; i++)
{
float2 texCoordOffset = pixelOffset * gOffsets[i];
float2 p1 = SAMPLE(_MainTex, sampler_LinearClamp, uv + texCoordOffset).xy;
float2 p2 = SAMPLE(_MainTex, sampler_LinearClamp, uv - texCoordOffset).xy;
colOut += gWeights[i] * (p1 + p2);
}
return colOut;
}
float4 HorizontalBlur_Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return float4
(
GaussianBlur(input.uv, float2(_CavityTex_TexelSize.x, 0.0)),
SAMPLE(_MainTex, sampler_LinearClamp, input.uv).z,
1.0
);
}
float4 VerticalBlur_Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return float4
(
GaussianBlur(input.uv, float2(0.0, _CavityTex_TexelSize.y)),
SAMPLE(_MainTex, sampler_LinearClamp, input.uv).z,
1.0
);
}
float4 Composite_Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#ifdef UnityStereoTransformScreenSpaceTex
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#else
float2 uv = input.uv;
#endif
float3 P = FetchViewPos(uv);
float3 N = FetchViewNormals(P, uv);
float4 col = FetchSceneColor(uv);
float4 untouchedCol = FetchSceneColor(uv);
//float depth01 = FetchRawDepth(uv);
//if (depth01 == 1.0 || depth01 == 0.0) return col;
float curvature = 0.0;
curvature = Curvature(uv, P);
//float cavity = 0.0, edges = 0.0;
//Cavity(uv, N, cavity, edges);
float2 cavityTex;
#if UPSCALE_CAVITY
float2 LowResTexelSize = _CavityTex_TexelSize.xy;
float2 LowResBufferSize = _CavityTex_TexelSize.zw;
float2 Corner00UV = floor(uv * LowResBufferSize - .5f) / LowResBufferSize + .5f * LowResTexelSize;
float2 BilinearWeights = (uv - Corner00UV) * LowResBufferSize;
//xy is signal, z is depth it used
float3 TextureValues00 = SAMPLE(_CavityTex, sampler_LinearClamp, Corner00UV).xyz;
float3 TextureValues10 = SAMPLE(_CavityTex, sampler_LinearClamp, Corner00UV + float2(LowResTexelSize.x, 0)).xyz;
float3 TextureValues01 = SAMPLE(_CavityTex, sampler_LinearClamp, Corner00UV + float2(0, LowResTexelSize.y)).xyz;
float3 TextureValues11 = SAMPLE(_CavityTex, sampler_LinearClamp, Corner00UV + LowResTexelSize).xyz;
float4 CornerWeights = float4(
(1 - BilinearWeights.y) * (1 - BilinearWeights.x),
(1 - BilinearWeights.y) * BilinearWeights.x,
BilinearWeights.y * (1 - BilinearWeights.x),
BilinearWeights.y * BilinearWeights.x);
float Epsilon = .0001f/*-.0001f*//*0.0f*/;
float4 CornerDepths = abs(float4(TextureValues00.z, TextureValues10.z, TextureValues01.z, TextureValues11.z));
float SceneDepth = FetchRawDepth(uv);
float4 DepthWeights = 1.0f / (abs(CornerDepths - SceneDepth.xxxx) + Epsilon);
float4 FinalWeights = CornerWeights * DepthWeights;
cavityTex = (FinalWeights.x*TextureValues00.xy + FinalWeights.y*TextureValues10.xy + FinalWeights.z*TextureValues01.xy + FinalWeights.w*TextureValues11.xy) / dot(FinalWeights, 1);
#else
cavityTex = SAMPLE(_CavityTex, sampler_LinearClamp, uv).xy;
#endif
float cavity = cavityTex.r, edges = cavityTex.g;
if (uv.x < _Input_TexelSize.x * 2 || uv.y < _Input_TexelSize.y * 2 || 1 - uv.x < _Input_TexelSize.x * 2 || 1 - uv.y < _Input_TexelSize.y * 2) { curvature = cavity = edges = 0; };
col.rgb += (curvature * 0.4);
#if SATURATE_CAVITY
//float3 extra = col.rgb - saturate(col.rgb);
col.rgb = pow(saturate(col.rgb), 1 - (edges * 0.5));
col.rgb = pow(saturate(col.rgb), 1 + (cavity * 1));
//col.rgb += extra;
#else
col.rgb += (edges * 0.2);
col.rgb -= (cavity * 0.2);
#endif
//Uncomment this block of code for on/off back and forth effect preview
//if (uv.x < sin(_Time.y+(3.1415/2)) * 0.5 + 0.5)
//{
// if (uv.x > (sin(_Time.y+(3.1415/2)) * 0.5 + 0.5) - 0.002) return 0;
// return untouchedCol;
//}
#if DEBUG_EFFECT
return ((1.0 - cavity) * (1.0 + edges) * (1.0 + curvature)) * 0.25;
#elif DEBUG_NORMALS
return float4(N * 0.5 + 0.5, 1);
#endif
#if OUTPUT_TO_TEXTURE
float r = curvature * 0.4;
float g = (edges * 0.2) - (cavity * 0.2);
return float4(r * rcp(max(1, P.z * _DistanceFade)) * _EffectIntensity, g * rcp(max(1, P.z * _DistanceFade)) * _EffectIntensity, 1, 1);
//Values rescaled so they're more consistent to work with, if you just +curvature+edges it should match 'screen' output
#else
return lerp(untouchedCol, col, rcp(max(1, P.z * _DistanceFade)) * _EffectIntensity);
#endif
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0a48fac26b03eea4ba7e6585b25b1d2e
ShaderIncludeImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,236 @@
Shader "Hidden/Universal Render Pipeline/SSCC"
{
Properties
{
_MainTex("", any) = "" {}
_SSCCTexture("", any) = "" {}
}
HLSLINCLUDE
#define HLSL 1
#pragma target 3.0
#pragma editor_sync_compilation
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma multi_compile_local __ DEBUG_EFFECT DEBUG_NORMALS
#pragma multi_compile_local __ ORTHOGRAPHIC_PROJECTION
#pragma multi_compile_local __ NORMALS_RECONSTRUCT
#pragma multi_compile_fragment __ _GBUFFER_NORMALS_OCT
#pragma multi_compile_local CAVITY_SAMPLES_6 CAVITY_SAMPLES_8 CAVITY_SAMPLES_12 CAVITY_SAMPLES_20
#pragma multi_compile_local __ SATURATE_CAVITY
#pragma multi_compile_local __ OUTPUT_TO_TEXTURE
#pragma multi_compile_local __ UPSCALE_CAVITY
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.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
TEXTURE2D_X(_MainTex);
TEXTURE2D_X(_CavityTex);
//Unity 6.0's urp #includes themselves define sampler_LinearClamp
#if UNITY_VERSION < 600000
SAMPLER(sampler_LinearClamp);
SAMPLER(sampler_PointClamp);
#endif
CBUFFER_START(FrequentlyUpdatedUniforms)
//float4 _UVToView;
float4 _Input_TexelSize;
float4 _CavityTex_TexelSize;
float4x4 _WorldToCameraMatrix;
float _EffectIntensity;
float _DistanceFade;
float _CurvaturePixelRadius;
float _CurvatureBrights;
float _CurvatureDarks;
float _CavityWorldRadius;
float _CavityBrights;
float _CavityDarks;
CBUFFER_END
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
Varyings Vert(Attributes input)
{
Varyings output;
UNITY_SETUP_INSTANCE_ID(input);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.positionCS = float4(input.positionOS.xyz, 1.0);
#if UNITY_UV_STARTS_AT_TOP
output.positionCS.y *= -1;
#endif
output.uv = input.uv;
return output;
}
//
inline half4 FetchSceneColor(float2 uv) {
return SAMPLE_TEXTURE2D_X(_MainTex, sampler_PointClamp, uv);
}
inline float FetchRawDepth(float2 uv) {
return SampleSceneDepth(uv);
}
inline float LinearizeDepth(float depth) {
#if ORTHOGRAPHIC_PROJECTION
#if UNITY_REVERSED_Z
depth = 1 - depth;
#endif
float linearDepth = _ProjectionParams.y + depth * (_ProjectionParams.z - _ProjectionParams.y);
#else
float linearDepth = LinearEyeDepth(depth, _ZBufferParams);
#endif
return linearDepth;
}
inline float3 FetchViewPos(float2 uv) {
float depth = LinearizeDepth(FetchRawDepth(uv));
//return float3((uv * _UVToView.xy + _UVToView.zw) * depth, depth);
float4 UVToView = float4(2 / unity_CameraProjection._m00, -2 / unity_CameraProjection._m11, -1 / unity_CameraProjection._m00, 1 / unity_CameraProjection._m11);
#if ORTHOGRAPHIC_PROJECTION
return float3((uv * UVToView.xy + UVToView.zw), depth);
#else
return float3((uv * UVToView.xy + UVToView.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(float3 P, float2 uv) {
#if NORMALS_RECONSTRUCT
float c = FetchRawDepth(uv);
half3 viewSpacePos_c = FetchViewPos(uv);
// get data at 1 pixel offsets in each major direction
half3 viewSpacePos_l = FetchViewPos(uv + float2(-1.0, 0.0) * _Input_TexelSize.xy);
half3 viewSpacePos_r = FetchViewPos(uv + float2(+1.0, 0.0) * _Input_TexelSize.xy);
half3 viewSpacePos_d = FetchViewPos(uv + float2(0.0, -1.0) * _Input_TexelSize.xy);
half3 viewSpacePos_u = FetchViewPos(uv + float2(0.0, +1.0) * _Input_TexelSize.xy);
half3 l = viewSpacePos_c - viewSpacePos_l;
half3 r = viewSpacePos_r - viewSpacePos_c;
half3 d = viewSpacePos_c - viewSpacePos_d;
half3 u = viewSpacePos_u - viewSpacePos_c;
half4 H = half4(
FetchRawDepth(uv + float2(-1.0, 0.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(+1.0, 0.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(-2.0, 0.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(+2.0, 0.0) * _Input_TexelSize.xy)
);
half4 V = half4(
FetchRawDepth(uv + float2(0.0, -1.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(0.0, +1.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(0.0, -2.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(0.0, +2.0) * _Input_TexelSize.xy)
);
half2 he = abs((2 * H.xy - H.zw) - c);
half2 ve = abs((2 * V.xy - V.zw) - c);
half3 hDeriv = he.x < he.y ? l : r;
half3 vDeriv = ve.x < ve.y ? d : u;
float3 N = normalize(cross(hDeriv, vDeriv));
#else
#if VERSION_GREATER_EQUAL(10, 0)
float3 N = SampleSceneNormals(uv);
#if UNITY_VERSION >= 202110 || VERSION_GREATER_EQUAL(10, 9)
N = mul((float3x3)_WorldToCameraMatrix, N);
#else
N = float3(N.x, N.y, -N.z); //?
#endif
#else
float3 N = float3(0, 0, 0);
#endif
N = float3(N.x, -N.yz);
#endif
N = float3(N.x, -N.y, N.z);
return N;
}
//
ENDHLSL
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
LOD 100
ZWrite Off ZTest Always Blend Off Cull Off
Pass // 0
{
Name "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 // 1
{
Name "GenerateCavity"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Cavity_Frag
#include "Shared.cginc"
ENDHLSL
}
Pass // 2
{
Name "HorizontalBlur"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment HorizontalBlur_Frag
#include "Shared.cginc"
ENDHLSL
}
Pass // 3
{
Name "VerticalBlur"
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment VerticalBlur_Frag
#include "Shared.cginc"
ENDHLSL
}
Pass // 4
{
Name "Final"
ColorMask RGB
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment Composite_Frag
#include "Shared.cginc"
ENDHLSL
}
}
Fallback Off
}

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 62449f654265cf94e81275e55a4b1823
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,253 @@
Shader "Hidden/SSCC"
{
Properties
{
_MainTex("", any) = "" {}
_SSCCTexture("", any) = "" {}
}
CGINCLUDE
#define HLSL 0
#pragma target 3.0
#pragma editor_sync_compilation
#pragma multi_compile_local __ DEBUG_EFFECT DEBUG_NORMALS
#pragma multi_compile_local __ ORTHOGRAPHIC_PROJECTION
#pragma multi_compile_local __ NORMALS_CAMERA NORMALS_RECONSTRUCT
#pragma multi_compile_local CAVITY_SAMPLES_6 CAVITY_SAMPLES_8 CAVITY_SAMPLES_12 CAVITY_SAMPLES_20
#pragma multi_compile_local __ SATURATE_CAVITY
#pragma multi_compile_local __ OUTPUT_TO_TEXTURE
#pragma multi_compile_local __ UPSCALE_CAVITY
#include "UnityCG.cginc"
UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
UNITY_DECLARE_SCREENSPACE_TEXTURE(_CavityTex);
UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture);
UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraGBufferTexture2);
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
SamplerState sampler_LinearClamp;
SamplerState sampler_PointClamp;
CBUFFER_START(FrequentlyUpdatedUniforms)
//float4 _UVToView;
float4 _Input_TexelSize;
float4 _CavityTex_TexelSize;
float4x4 _WorldToCameraMatrix;
float _EffectIntensity;
float _DistanceFade;
float _CurvaturePixelRadius;
float _CurvatureBrights;
float _CurvatureDarks;
float _CavityWorldRadius;
float _CavityBrights;
float _CavityDarks;
CBUFFER_END
CBUFFER_START(PerPassUpdatedUniforms)
float4 _UVTransform;
CBUFFER_END
struct Attributes
{
float3 vertex : POSITION;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
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.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.uv = TransformStereoScreenSpaceTex(o.uv, 1.0);
return o;
}
//
inline half4 FetchSceneColor(float2 uv) {
return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, uv);
}
inline float FetchRawDepth(float2 uv) {
return SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv);
}
inline float LinearizeDepth(float depth) {
#if ORTHOGRAPHIC_PROJECTION
#if UNITY_REVERSED_Z
depth = 1 - depth;
#endif
float linearDepth = _ProjectionParams.y + depth * (_ProjectionParams.z - _ProjectionParams.y);
#else
float linearDepth = LinearEyeDepth(depth);
#endif
return linearDepth;
}
inline float3 FetchViewPos(float2 uv) {
float depth = LinearizeDepth(FetchRawDepth(uv));
//return float3((uv * _UVToView.xy + _UVToView.zw) * depth, depth);
float4 UVToView = float4(2 / unity_CameraProjection._m00, -2 / unity_CameraProjection._m11, -1 / unity_CameraProjection._m00, 1 / unity_CameraProjection._m11);
#if ORTHOGRAPHIC_PROJECTION
return float3((uv * UVToView.xy + UVToView.zw), depth);
#else
return float3((uv * UVToView.xy + UVToView.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(float3 P, float2 uv) {
#if NORMALS_RECONSTRUCT
float c = FetchRawDepth(uv);
half3 viewSpacePos_c = FetchViewPos(uv);
// get data at 1 pixel offsets in each major direction
half3 viewSpacePos_l = FetchViewPos(uv + float2(-1.0, 0.0) * _Input_TexelSize.xy);
half3 viewSpacePos_r = FetchViewPos(uv + float2(+1.0, 0.0) * _Input_TexelSize.xy);
half3 viewSpacePos_d = FetchViewPos(uv + float2(0.0, -1.0) * _Input_TexelSize.xy);
half3 viewSpacePos_u = FetchViewPos(uv + float2(0.0, +1.0) * _Input_TexelSize.xy);
half3 l = viewSpacePos_c - viewSpacePos_l;
half3 r = viewSpacePos_r - viewSpacePos_c;
half3 d = viewSpacePos_c - viewSpacePos_d;
half3 u = viewSpacePos_u - viewSpacePos_c;
half4 H = half4(
FetchRawDepth(uv + float2(-1.0, 0.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(+1.0, 0.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(-2.0, 0.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(+2.0, 0.0) * _Input_TexelSize.xy)
);
half4 V = half4(
FetchRawDepth(uv + float2(0.0, -1.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(0.0, +1.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(0.0, -2.0) * _Input_TexelSize.xy),
FetchRawDepth(uv + float2(0.0, +2.0) * _Input_TexelSize.xy)
);
half2 he = abs((2 * H.xy - H.zw) - c);
half2 ve = abs((2 * V.xy - V.zw) - c);
half3 hDeriv = he.x < he.y ? l : r;
half3 vDeriv = ve.x < ve.y ? d : u;
float3 N = normalize(cross(hDeriv, vDeriv));
#else
#if NORMALS_CAMERA
float3 N = DecodeViewNormalStereo(UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthNormalsTexture, uv));
#else
float3 N = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraGBufferTexture2, uv).rgb * 2.0 - 1.0;
N = mul((float3x3)_WorldToCameraMatrix, N);
#endif
N = float3(N.x, -N.yz);
#endif
N = float3(N.x, -N.y, N.z);
return N;
}
//
ENDCG
SubShader
{
LOD 100
ZWrite Off ZTest Always Cull Off
Pass // 0
{
Name "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
}
Pass // 1
{
Name "GenerateCavity"
CGPROGRAM
#pragma vertex Vert_Default
#pragma fragment Cavity_Frag
#include "Shared.cginc"
ENDCG
}
Pass // 2
{
Name "HorizontalBlur"
CGPROGRAM
#pragma vertex Vert_Default
#pragma fragment HorizontalBlur_Frag
#include "Shared.cginc"
ENDCG
}
Pass // 3
{
Name "VerticalBlur"
CGPROGRAM
#pragma vertex Vert_Default
#pragma fragment VerticalBlur_Frag
#include "Shared.cginc"
ENDCG
}
Pass // 4
{
Name "Final"
ColorMask RGB
CGPROGRAM
#pragma vertex Vert_Default
#pragma fragment Composite_Frag
#include "Shared.cginc"
ENDCG
}
}
Fallback Off
}

View File

@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 89ec5ce1bd95ed946a65b649164a9c1d
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/Shaders/Builtin_SSCC.shader
uploadId: 664239

View File

@ -0,0 +1,332 @@
#if HLSL
#define SAMPLE(texture, sampler, uv) SAMPLE_TEXTURE2D_X(texture, sampler, uv)
#else
#define SAMPLE(texture, sampler, uv) UNITY_SAMPLE_SCREENSPACE_TEXTURE(texture, uv)
#endif
//CAVITY V
#ifdef CAVITY_SAMPLES_6
#define CAVITY_SAMPLES 6
#endif
#ifdef CAVITY_SAMPLES_8
#define CAVITY_SAMPLES 8
#endif
#ifdef CAVITY_SAMPLES_12
#define CAVITY_SAMPLES 12
#endif
#ifdef CAVITY_SAMPLES_20
#define CAVITY_SAMPLES 20
#endif
#ifdef SSCC_HDRP
#define ACTUAL_CAVITY_SAMPLES (CAVITY_SAMPLES+2)
#else
#define ACTUAL_CAVITY_SAMPLES (CAVITY_SAMPLES)
#endif
float _InterleavedGradientNoise(float2 pixCoord, int frameCount)
{
const float3 magic = float3(0.06711056f, 0.00583715f, 52.9829189f);
float2 frameMagicScale = float2(2.083f, 4.867f);
pixCoord += frameCount * frameMagicScale;
return frac(magic.z * frac(dot(pixCoord, magic.xy)));
}
float3 PickSamplePoint(float2 uv, float randAddon, int index)
{
float2 positionSS = uv * _CavityTex_TexelSize.zw;
float gn = _InterleavedGradientNoise(positionSS, index);
float u = frac(gn) * 2.0 - 1.0;
float theta = gn * 6.28318530717958647693;
float sn, cs;
sincos(theta, sn, cs);
return float3(float2(cs, sn) * sqrt(1.0 - u * u), u);
}
float3x3 GetCoordinateConversionParameters(out float2 p11_22, out float2 p13_31)
{
float3x3 camProj = (float3x3)unity_CameraProjection;
//float3x3 camProj = (float3x3)/*UNITY_MATRIX_P*/_Projection;
p11_22 = rcp(float2(camProj._11, camProj._22));
p13_31 = float2(camProj._13, camProj._23);
return camProj;
}
float3 ReconstructViewPos(float2 uv, float depth, float2 p11_22, float2 p13_31)
{
#if ORTHOGRAPHIC_PROJECTION
float3 viewPos = float3(((uv.xy * 2.0 - 1.0 - p13_31) * p11_22), depth);
#else
float3 viewPos = float3(depth * ((uv.xy * 2.0 - 1.0 - p13_31) * p11_22), depth);
#endif
return viewPos;
}
void SampleDepthAndViewpos(float2 uv, float2 p11_22, float2 p13_31, out float depth, out float3 vpos)
{
depth = LinearizeDepth(FetchRawDepth(uv));
vpos = ReconstructViewPos(uv, depth, p11_22, p13_31);
}
void Cavity(float2 uv, float3 normal, out float cavity, out float edges)
{
cavity = edges = 0.0;
float2 p11_22, p13_31;
float3x3 camProj = GetCoordinateConversionParameters(p11_22, p13_31);
float depth;
float3 vpos;
SampleDepthAndViewpos(uv, p11_22, p13_31, depth, vpos);
float randAddon = uv.x * 1e-10;
float rcpSampleCount = rcp(ACTUAL_CAVITY_SAMPLES);
//UNITY_LOOP
UNITY_UNROLL
for (int i = 0; i < int(ACTUAL_CAVITY_SAMPLES); i++)
{
#if defined(SHADER_API_D3D11)
i = floor(1.0001 * i);
#endif
#if 0
float3 v_s1 = PickSamplePoint(uv.yx, randAddon, i);
#else
float3 v_s1 = PickSamplePoint(uv, randAddon, i);
#endif
v_s1 *= sqrt((i + 1.0) * rcpSampleCount) * _CavityWorldRadius * 0.5;
float3 vpos_s1 = vpos + v_s1;
float3 spos_s1 = mul(camProj, vpos_s1);
#if ORTHOGRAPHIC_PROJECTION
float2 uv_s1_01 = clamp((spos_s1.xy + 1.0) * 0.5, 0.0, 1.0);
#else
float2 uv_s1_01 = clamp((spos_s1.xy * rcp(vpos_s1.z) + 1.0) * 0.5, 0.0, 1.0);
#endif
float depth_s1 = LinearizeDepth(FetchRawDepth(uv_s1_01));
float3 vpos_s2 = ReconstructViewPos(uv_s1_01, depth_s1, p11_22, p13_31);
float3 dir = vpos_s2 - vpos;
float len = length(dir);
float f_dot = dot(dir, normal);
//float kBeta = 0.002;
float kBeta = 0.002 * 4;
float f_cavities = f_dot - kBeta * depth;
float f_edge = -f_dot - kBeta * depth;
float f_bias = 0.05 * len + 0.0001;
if (f_cavities > -f_bias)
{
float attenuation = 1.0 / (len * (1.0 + len * len * 3.));
cavity += f_cavities * attenuation;
}
if (f_edge > f_bias)
{
float attenuation = 1.0 / (len * (1.0 + len * len * 0.01));
edges += f_edge * attenuation;
}
}
//cavity *= 1.0 / ACTUAL_CAVITY_SAMPLES;
//edges *= 1.0 / ACTUAL_CAVITY_SAMPLES;
cavity *= 1.0 * _CavityWorldRadius * 0.5;
edges *= 1.0 * _CavityWorldRadius * 0.5;
float kContrast = 0.6;
cavity = pow(abs(cavity * rcpSampleCount), kContrast);
edges = pow(abs(edges * rcpSampleCount), kContrast);
cavity = clamp(cavity * _CavityDarks, 0.0, 1.0);
edges = edges * _CavityBrights;
}
//CAVITY ^
//CURVATURE V
float CurvatureSoftClamp(float curvature, float control)
{
if (curvature < 0.5 / control)
return curvature * (1.0 - curvature * control);
return 0.25 / control;
}
float Curvature(float2 uv, float3 P)
{
float3 offset = float3(_Input_TexelSize.xy, 0.0) * (_CurvaturePixelRadius);
float normal_up = FetchViewNormals(P, uv + offset.zy).g;
float normal_down = FetchViewNormals(P, uv - offset.zy).g;
float normal_right = FetchViewNormals(P, uv + offset.xz).r;
float normal_left = FetchViewNormals(P, uv - offset.xz).r;
float normal_diff = (normal_up - normal_down) + (normal_right - normal_left);
//if (abs(normal_diff) <= 0.1) return 0; //slight low pass filter to remove noise from camera normals precision
//new and improved low pass filter:
//if (uv.x < 0.5)
{
if (normal_diff > 0.0) normal_diff = sign(normal_diff) * pow(normal_diff, 2.0);
_CavityBrights += 0.5;
}
if (normal_diff >= 0.0)
return 2.0 * CurvatureSoftClamp(normal_diff, _CurvatureBrights);
else
return -2.0 * CurvatureSoftClamp(-normal_diff, _CurvatureDarks);
}
//CURVATURE ^
float invLerp(float from, float to, float value) {
return (value - from) / (to - from);
}
float remap(float origFrom, float origTo, float targetFrom, float targetTo, float value) {
float rel = invLerp(origFrom, origTo, value);
return lerp(targetFrom, targetTo, rel);
}
float4 Cavity_Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#ifdef UnityStereoTransformScreenSpaceTex
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#else
float2 uv = input.uv;
#endif
float3 P = FetchViewPos(uv);
float3 N = FetchViewNormals(P, uv);
float cavity = 0.0, edges = 0.0;
Cavity(uv, N, cavity, edges);
return float4(cavity, edges, FetchRawDepth(uv), 1.0);
}
float2 GaussianBlur(float2 uv, float2 pixelOffset)
{
const float gWeights[2] =
{
0.44908,
0.05092
};
const float gOffsets[2] =
{
0.53805,
2.06278
};
float2 colOut = 0.0;
UNITY_UNROLL
for(int i = 0; i < 2; i++)
{
float2 texCoordOffset = pixelOffset * gOffsets[i];
float2 p1 = SAMPLE(_MainTex, sampler_LinearClamp, uv + texCoordOffset).xy;
float2 p2 = SAMPLE(_MainTex, sampler_LinearClamp, uv - texCoordOffset).xy;
colOut += gWeights[i] * (p1 + p2);
}
return colOut;
}
float4 HorizontalBlur_Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return float4
(
GaussianBlur(input.uv, float2(_CavityTex_TexelSize.x, 0.0)),
SAMPLE(_MainTex, sampler_LinearClamp, input.uv).z,
1.0
);
}
float4 VerticalBlur_Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
return float4
(
GaussianBlur(input.uv, float2(0.0, _CavityTex_TexelSize.y)),
SAMPLE(_MainTex, sampler_LinearClamp, input.uv).z,
1.0
);
}
float4 Composite_Frag(Varyings input) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
#ifdef UnityStereoTransformScreenSpaceTex
float2 uv = UnityStereoTransformScreenSpaceTex(input.uv);
#else
float2 uv = input.uv;
#endif
float3 P = FetchViewPos(uv);
float3 N = FetchViewNormals(P, uv);
float4 col = FetchSceneColor(uv);
float4 untouchedCol = FetchSceneColor(uv);
//float depth01 = FetchRawDepth(uv);
//if (depth01 == 1.0 || depth01 == 0.0) return col;
float curvature = 0.0;
curvature = Curvature(uv, P);
//float cavity = 0.0, edges = 0.0;
//Cavity(uv, N, cavity, edges);
float2 cavityTex;
#if UPSCALE_CAVITY
float2 LowResTexelSize = _CavityTex_TexelSize.xy;
float2 LowResBufferSize = _CavityTex_TexelSize.zw;
float2 Corner00UV = floor(uv * LowResBufferSize - .5f) / LowResBufferSize + .5f * LowResTexelSize;
float2 BilinearWeights = (uv - Corner00UV) * LowResBufferSize;
//xy is signal, z is depth it used
float3 TextureValues00 = SAMPLE(_CavityTex, sampler_LinearClamp, Corner00UV).xyz;
float3 TextureValues10 = SAMPLE(_CavityTex, sampler_LinearClamp, Corner00UV + float2(LowResTexelSize.x, 0)).xyz;
float3 TextureValues01 = SAMPLE(_CavityTex, sampler_LinearClamp, Corner00UV + float2(0, LowResTexelSize.y)).xyz;
float3 TextureValues11 = SAMPLE(_CavityTex, sampler_LinearClamp, Corner00UV + LowResTexelSize).xyz;
float4 CornerWeights = float4(
(1 - BilinearWeights.y) * (1 - BilinearWeights.x),
(1 - BilinearWeights.y) * BilinearWeights.x,
BilinearWeights.y * (1 - BilinearWeights.x),
BilinearWeights.y * BilinearWeights.x);
float Epsilon = .0001f/*-.0001f*//*0.0f*/;
float4 CornerDepths = abs(float4(TextureValues00.z, TextureValues10.z, TextureValues01.z, TextureValues11.z));
float SceneDepth = FetchRawDepth(uv);
float4 DepthWeights = 1.0f / (abs(CornerDepths - SceneDepth.xxxx) + Epsilon);
float4 FinalWeights = CornerWeights * DepthWeights;
cavityTex = (FinalWeights.x*TextureValues00.xy + FinalWeights.y*TextureValues10.xy + FinalWeights.z*TextureValues01.xy + FinalWeights.w*TextureValues11.xy) / dot(FinalWeights, 1);
#else
cavityTex = SAMPLE(_CavityTex, sampler_LinearClamp, uv).xy;
#endif
float cavity = cavityTex.r, edges = cavityTex.g;
if (uv.x < _Input_TexelSize.x * 2 || uv.y < _Input_TexelSize.y * 2 || 1 - uv.x < _Input_TexelSize.x * 2 || 1 - uv.y < _Input_TexelSize.y * 2) { curvature = cavity = edges = 0; };
col.rgb += (curvature * 0.4);
#if SATURATE_CAVITY
//float3 extra = col.rgb - saturate(col.rgb);
col.rgb = pow(saturate(col.rgb), 1 - (edges * 0.5));
col.rgb = pow(saturate(col.rgb), 1 + (cavity * 1));
//col.rgb += extra;
#else
col.rgb += (edges * 0.2);
col.rgb -= (cavity * 0.2);
#endif
//Uncomment this block of code for on/off back and forth effect preview
//if (uv.x < sin(_Time.y+(3.1415/2)) * 0.5 + 0.5)
//{
// if (uv.x > (sin(_Time.y+(3.1415/2)) * 0.5 + 0.5) - 0.002) return 0;
// return untouchedCol;
//}
#if DEBUG_EFFECT
return ((1.0 - cavity) * (1.0 + edges) * (1.0 + curvature)) * 0.25;
#elif DEBUG_NORMALS
return float4(N * 0.5 + 0.5, 1);
#endif
#if OUTPUT_TO_TEXTURE
float r = curvature * 0.4;
float g = (edges * 0.2) - (cavity * 0.2);
return float4(r * rcp(max(1, P.z * _DistanceFade)) * _EffectIntensity, g * rcp(max(1, P.z * _DistanceFade)) * _EffectIntensity, 1, 1);
//Values rescaled so they're more consistent to work with, if you just +curvature+edges it should match 'screen' output
#else
return lerp(untouchedCol, col, rcp(max(1, P.z * _DistanceFade)) * _EffectIntensity);
#endif
}

View File

@ -0,0 +1,16 @@
fileFormatVersion: 2
guid: 320b7d4bebad59e4ead8d08b151d6a7f
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/Shaders/Shared.cginc
uploadId: 664239

View File

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

View File

@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 0e83bea63c06f674eb5018b4edaaa234
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/_SSCCTexture Examples/Builtin _SSCCTexture
Example.unitypackage
uploadId: 664239

Binary file not shown.

View File

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 9673b087a168cd34984bd85711945362
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/_SSCCTexture Examples/Readme.txt
uploadId: 664239

View File

@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: c2a3494b77a23b54aa8b5ad80b580749
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/_SSCCTexture Examples/URP2020 _SSCCTexture
Example.unitypackage
uploadId: 664239

View File

@ -0,0 +1,15 @@
fileFormatVersion: 2
guid: 63fa4c6385d5807478747f832fef4a20
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 216995
packageName: Screen Space Cavity & Curvature (Built-In/URP/HDRP)
packageVersion: 1.1.7
assetPath: Assets/Screen Space Cavity Curvature/_SSCCTexture Examples/URP2021+
_SSCCTexture Example.unitypackage
uploadId: 664239

Binary file not shown.