diff --git a/Assets/External/HTraceWSGI.meta b/Assets/External/HTraceWSGI.meta new file mode 100644 index 000000000..5d5476cea --- /dev/null +++ b/Assets/External/HTraceWSGI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d612ac72bbff16f4a9258a3c05222013 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/HTraceWSGI Quick-Start Manual.pdf b/Assets/External/HTraceWSGI/HTraceWSGI Quick-Start Manual.pdf new file mode 100644 index 000000000..16855fdf8 --- /dev/null +++ b/Assets/External/HTraceWSGI/HTraceWSGI Quick-Start Manual.pdf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:262d672a20c060f8a547c825f5cd27e17b63de8d88db84898a14898cfdfd751c +size 175141 diff --git a/Assets/External/HTraceWSGI/HTraceWSGI Quick-Start Manual.pdf.meta b/Assets/External/HTraceWSGI/HTraceWSGI Quick-Start Manual.pdf.meta new file mode 100644 index 000000000..749ca9530 --- /dev/null +++ b/Assets/External/HTraceWSGI/HTraceWSGI Quick-Start Manual.pdf.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 0f08f08fbf1ae3840a4a7f5f80d0a98a +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/HTraceWSGI Quick-Start Manual.pdf + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/HTraceWSGI.asmdef b/Assets/External/HTraceWSGI/HTraceWSGI.asmdef new file mode 100644 index 000000000..d40f54eee --- /dev/null +++ b/Assets/External/HTraceWSGI/HTraceWSGI.asmdef @@ -0,0 +1,22 @@ +{ + "name": "HTraceWSGI", + "rootNamespace": "", + "references": [ + "GUID:3eae0364be2026648bf74846acb8a731", + "GUID:15fc0a57446b3144c949da3e2b9737a9", + "GUID:78bd2ddd6e276394a9615c203e574844", + "GUID:457756d89b35d2941b3e7b37b4ece6f1", + "GUID:c579267770062bf448e75eb160330b7f", + "GUID:df380645f10b7bc4b97d4f5eb6303d95", + "GUID:75469ad4d38634e559750d17036d5f7c" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/HTraceWSGI.asmdef.meta b/Assets/External/HTraceWSGI/HTraceWSGI.asmdef.meta new file mode 100644 index 000000000..f28e3c557 --- /dev/null +++ b/Assets/External/HTraceWSGI/HTraceWSGI.asmdef.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 626dce77c9ae402892d1309f34bad18e +timeCreated: 1674796741 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/HTraceWSGI.asmdef + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Icons.meta b/Assets/External/HTraceWSGI/Icons.meta new file mode 100644 index 000000000..fb92fdf5d --- /dev/null +++ b/Assets/External/HTraceWSGI/Icons.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0f64d29cd4984bd4eae7217cd0d67bef +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Icons/Icon (160 x 160).png b/Assets/External/HTraceWSGI/Icons/Icon (160 x 160).png new file mode 100644 index 000000000..16a69bc27 --- /dev/null +++ b/Assets/External/HTraceWSGI/Icons/Icon (160 x 160).png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abc55d5ba2d6efb4d6a34151843a15c2c33065274fbd5d2507c25fd1b821d810 +size 4545 diff --git a/Assets/External/HTraceWSGI/Icons/Icon (160 x 160).png.meta b/Assets/External/HTraceWSGI/Icons/Icon (160 x 160).png.meta new file mode 100644 index 000000000..e77115a54 --- /dev/null +++ b/Assets/External/HTraceWSGI/Icons/Icon (160 x 160).png.meta @@ -0,0 +1,131 @@ +fileFormatVersion: 2 +guid: 0915864a167b66048872805a749c4360 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + resizeAlgorithm: 1 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Icons/Icon (160 x 160).png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources.meta b/Assets/External/HTraceWSGI/Resources.meta new file mode 100644 index 000000000..304b50a99 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +<<<<<<<< HEAD:HTrace_HDRP/Assets/Menu.meta +guid: 9f50f6899e69be4478ddbfccc33ecedf +======== +guid: 4ff4d07345483c542b3c5e943310c782 +>>>>>>>> Update_2.0:HTrace_HDRP/Assets/H-Trace/Resources.meta +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI.meta new file mode 100644 index 000000000..aaf90df5c --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 927af83b7c1ea7946af7638bb0db4959 +timeCreated: 1738083188 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP.meta new file mode 100644 index 000000000..a0b2e925a --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 798f9d88589541baa1fde7e634d42d0c +timeCreated: 1763045111 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes.meta new file mode 100644 index 000000000..c9bc34b97 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 355c48594db44a63b285f9a382858eb8 +timeCreated: 1763045117 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/HLightClusterURP.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/HLightClusterURP.compute new file mode 100644 index 000000000..647437baa --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/HLightClusterURP.compute @@ -0,0 +1,231 @@ +#pragma kernel ClearBuffer +#pragma kernel FillLightCluster +#pragma kernel DebugLightCluster +#pragma kernel FillLightClusterDebugBuffer +#pragma kernel LightDataCompaction +#pragma kernel TransferPreviousPosition + +#define HAS_LIGHTLOOP + +struct LightInfo +{ + float3 Position; +}; + +#include "../../_Shared/Headers/HMain.hlsl" +#include "../../_Shared/Includes/LightCluster.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +RWStructuredBuffer _PrevBuffer; +StructuredBuffer _SceneLightsBuffer; +RWStructuredBuffer _LightClusterDebugBuffer; +RWStructuredBuffer _LightClusterIndexesBuffer; +RWStructuredBuffer _LightClusterCounterBuffer; +RWStructuredBuffer _LightDatasCompactedBuffer; + +H_RW_TEXTURE(float4, _LightClusterDebug_Output); + +[numthreads(64, 1, 1)] +void ClearBuffer(uint Index : SV_DispatchThreadID) +{ + _LightClusterCounterBuffer[Index] = 0; +} + +[numthreads(64, 1, 1)] +void TransferPreviousPosition(uint Index : SV_DispatchThreadID) +{ + // LightData Light = _LightDatas[Index]; + // LightLoopContext Context; + // + // Context.shadowContext = InitShadowContext(); + // HDShadowData ShadowData = Context.shadowContext.shadowDatas[Light.shadowIndex]; + // + // //_PrevBuffer[Index] = ShadowData.pos; +} + + +// ------------------------ LIGHT DATA COMPACTION ------------------------ +[numthreads(64, 1, 1)] +void LightDataCompaction(uint dispatchThreadID : SV_DispatchThreadID) +{ + float3 LightPositionWS = _AdditionalLightsPosition[dispatchThreadID].xyz; + + // Protection against HPunctualLights.cs script being set on a wrong light type + // if (PunctualLightData.lightType != GPULIGHTTYPE_POINT && PunctualLightData.lightType != GPULIGHTTYPE_SPOT) + // return; + + for (uint CompactedLightIndex = 0; CompactedLightIndex < g_SceneLightsBufferSize; CompactedLightIndex++) + { + if (all(abs(_SceneLightsBuffer[CompactedLightIndex].Position - LightPositionWS.xyz) < 0.001f)) + { + _LightDatasCompactedBuffer[CompactedLightIndex] = dispatchThreadID; + break; + } + } +} + + +// ------------------------ LIGHT CLUSTER FILL ------------------------ +[numthreads(4, 4, 4)] +void FillLightCluster(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + float3 MinCellAABB = g_MinLightClusterPosition + (dispatchThreadID) * g_LightCluterCellSize; + float3 MaxCellAABB = g_MinLightClusterPosition + (dispatchThreadID + 1) * g_LightCluterCellSize; + + uint CellLightCount = 0; + uint FlattenedGridIndex = GetFlattenedIndex(dispatchThreadID); + + for (uint CompactedLightIndex = 0; CompactedLightIndex < g_SceneLightsBufferSize; CompactedLightIndex++) + { + if (CellLightCount >= g_MaxLightsPerCell) + break; + + int LightDataIndex = _LightDatasCompactedBuffer[CompactedLightIndex]; + + float3 LightPositionWS = _AdditionalLightsPosition[LightDataIndex].xyz; + float4 LightAtten = _AdditionalLightsAttenuation[LightDataIndex]; + float LightRange = 1.0 / sqrt(LightAtten.x); + + if (ClusterCellSphereIntersection(LightPositionWS, LightRange, MinCellAABB, MaxCellAABB)) + { + // Spot lights: cull with cone-AABB test to avoid assigning cells outside the cone + // LightAtten.z = invAngleRange (0 for point lights), LightAtten.w = -cosOuter * invAngleRange + if (LightAtten.z > 0) + { + float3 SpotDir = _AdditionalLightsSpotDir[LightDataIndex].xyz; + float CosHalfOuter = -LightAtten.w / LightAtten.z; + float ConeAngle = degrees(acos(CosHalfOuter)) * 2.0; + if (!ClusterCellConeIntersection(LightPositionWS, SpotDir, ConeAngle, LightRange, MinCellAABB, MaxCellAABB)) + continue; + } + + if (CellLightCount < g_MaxLightsPerCell) + _LightClusterIndexesBuffer[FlattenedGridIndex * g_MaxLightsPerCell + CellLightCount] = LightDataIndex; + + CellLightCount++; + } + } + + _LightClusterCounterBuffer[FlattenedGridIndex] = CellLightCount; +} + + +// ------------------------ LIGHT CLUSTER DEBUG BUFFER FILL ------------------------ +[numthreads(4, 4, 4)] +void FillLightClusterDebugBuffer(int3 dispatchThreadID : SV_DispatchThreadID) +{ + uint FlattenedGridIndex = GetFlattenedIndex(dispatchThreadID); + uint CellLightCount = _LightClusterCounterBuffer[FlattenedGridIndex]; + + // Early out in heatmap mode + if (g_HeatmapDebug) + { + _LightClusterDebugBuffer[FlattenedGridIndex] = CellLightCount == g_MaxLightsPerCell; + return; + } + + bool IsEdgeCell = false; + bool IsCellFilled = CellLightCount > 0 ? true : false; + + // Early out on empty cells + if (!IsCellFilled) + { + _LightClusterDebugBuffer[FlattenedGridIndex] = 0; + return; + } + + const static int3 NeighborOffsets[6] = {int3( 1, 0, 0), int3(-1, 0, 0), int3(0, 1, 0), int3(0, -1, 0), int3(0, 0, 1), int3(0, 0, -1)}; + + UNITY_UNROLL + for (int i = 0; i < 6; i++) + { + uint3 GridSampleIndex = dispatchThreadID + NeighborOffsets[i]; + uint FlattenedGridSampleIndex = GetFlattenedIndex(GridSampleIndex); + + if (any(GridSampleIndex >= g_LightClusterDimensions)) + IsEdgeCell = true; + + // If the lightcount is different between the neighboring cells it means we are on the edge of some light's radius + if (_LightClusterCounterBuffer[FlattenedGridSampleIndex] != CellLightCount) + IsEdgeCell = true; + } + + _LightClusterDebugBuffer[FlattenedGridIndex] = IsCellFilled & IsEdgeCell; +} + +#define ADDITIONAL_LIGHT_CALCULATE_SHADOWS + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl" +// ------------------------ LIGHT CLUSTER DEBUG ------------------------ +[numthreads(8, 8, 1)] +void DebugLightCluster(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID, uint2 groupId : SV_GroupID) +{ + float Depth = HBUFFER_DEPTH(pixCoord.xy); + + float Background = clamp(H_LINEAR_EYE_DEPTH(Depth) / 100, 0.02f, 0.85f); + + // Set background (sky) pixels to black + if (Depth == UNITY_RAW_FAR_CLIP_VALUE) + { + _LightClusterDebug_Output[H_COORD(pixCoord.xy)] = float4(0.0, 0.0, 0.0, 1.0f); + return; + } + + float3 PositionWS = H_COMPUTE_POSITION_WS((pixCoord.xy + 0.5) / _ScreenSize.xy, Depth, H_MATRIX_I_VP); + //PositionWS = H_GET_ABSOLUTE_POSITION_WS(PositionWS + 0.005f); + + // Set pixels outside cluster bounds to dark gray + if (!IsInsideLightCluster(PositionWS)) + { + _LightClusterDebug_Output[H_COORD(pixCoord.xy)] = Background; + return; + } + + // Compute the grid position + uint3 GridPosition = (uint3)((PositionWS - g_MinLightClusterPosition) / (g_MaxLightClusterPosition - g_MinLightClusterPosition) * float3(g_LightClusterDimensions)); + + // Fetch the light count in this cell + uint CellLightCount = _LightClusterCounterBuffer[GetFlattenedIndex(GridPosition)]; + float3 CellLightColor = 0; + + // Accumulate all light colors within the cell + for (uint i = 0; i < CellLightCount; i++) + { + float3 PunctualLightColor = _AdditionalLightsColor[_LightClusterIndexesBuffer[GetFlattenedIndex(GridPosition * g_MaxLightsPerCell) + i]].xyz; + float3 PunctualLightPosition = _AdditionalLightsPosition[_LightClusterIndexesBuffer[GetFlattenedIndex(GridPosition * g_MaxLightsPerCell) + i]].xyz; + float PunctualLightRangte = _AdditionalLightsAttenuation[_LightClusterIndexesBuffer[GetFlattenedIndex(GridPosition * g_MaxLightsPerCell) + i]].xyz; PunctualLightRangte = 1 / sqrt(PunctualLightRangte); + + float MaxLightColor = max(PunctualLightColor.r, max(PunctualLightColor.g, PunctualLightColor.b)); + float3 LightColor = (MaxLightColor > 0) ? PunctualLightColor / MaxLightColor : float3(0,0,0); + + float3 CellSize = (g_MaxLightClusterPosition - g_MinLightClusterPosition) / g_LightClusterDimensions; + float3 CellCenterWS = g_MinLightClusterPosition + (GridPosition + 0.5) * CellSize; + + // Uniform faloff + float Distance = length(H_GET_ABSOLUTE_POSITION_WS(PunctualLightPosition) - CellCenterWS); + float Attenuation = lerp(0.1, 1, saturate(1.0 - Distance / PunctualLightRangte)); + + CellLightColor += LightColor * pow(Attenuation, 1.25); + } + + if (CellLightCount == 0) + { + _LightClusterDebug_Output[H_COORD(pixCoord.xy)] = Background; + return; + } + + _LightClusterDebug_Output[H_COORD(pixCoord.xy)] = float4(CellLightColor, 1.0); + + if (g_HeatmapDebug) + { + float3 CellHeat = lerp(float3(0,1,0), float3(0.9,0,0), float(CellLightCount) / g_MaxLightsPerCell); + + if (CellLightCount == 1) + CellHeat = float3(0,1,0); + + if (CellLightCount == g_MaxLightsPerCell) + CellHeat = float3(1,0,0); + + _LightClusterDebug_Output[H_COORD(pixCoord.xy)] = float4(CellHeat, 1); + } +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/HLightClusterURP.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/HLightClusterURP.compute.meta new file mode 100644 index 000000000..6bf8a8051 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/HLightClusterURP.compute.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e4679a5c749144f9b585a4920b80e54b +timeCreated: 1763045122 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/HLightClusterURP.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/NewBrush.brush b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/NewBrush.brush new file mode 100644 index 000000000..b5d840397 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/NewBrush.brush @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 12146, guid: 0000000000000000e000000000000000, type: 0} + m_Name: NewBrush + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.Brush + m_Mask: {fileID: 0} + m_Falloff: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 0 + value: 0 + inSlope: 0 + outSlope: 1 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: 1 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_RadiusScale: 1 + m_BlackWhiteRemapMin: 0 + m_BlackWhiteRemapMax: 1 + m_InvertRemapRange: 0 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/NewBrush.brush.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/NewBrush.brush.meta new file mode 100644 index 000000000..b30663d0f --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/NewBrush.brush.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: ee3eb903dbf5b0c4ebe012eb9c6e98b2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/URP/Computes/NewBrush.brush + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders.meta new file mode 100644 index 000000000..728a1870e --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: db13b70fb74348c6ad25624f5f165d2c +timeCreated: 1764077239 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ColorComposeURP.shader b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ColorComposeURP.shader new file mode 100644 index 000000000..22ca9f2b4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ColorComposeURP.shader @@ -0,0 +1,212 @@ +Shader "Hidden/HTraceWSGI/ColorComposeURP" +{ + SubShader + { + HLSLINCLUDE + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl" + + struct Attributes + { + uint VertexID : SV_VertexID; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 PositionCS : POSITION; + float2 TexCoord : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO + }; + + Varyings SharedVertexStage(Attributes input) + { + Varyings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + output.PositionCS = GetFullScreenTriangleVertexPosition(input.VertexID); + output.TexCoord = GetFullScreenTriangleTexCoord(input.VertexID); + + return output; + } + + ENDHLSL + + Pass + { + Name "Copy Color Buffer" + + Cull Off + ZWrite Off + + HLSLPROGRAM + + #pragma vertex SharedVertexStage + #pragma fragment FragmentStage + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl" + #include "../../_Shared/Headers/HMain.hlsl" + + float4 FragmentStage(Varyings input) : SV_Target + { + return float4(HBUFFER_COLOR(input.TexCoord * _ScreenSize.xy).xyz, 1); + } + + ENDHLSL + } + + Pass + { + Name "Override Indirect Lighting" + + Cull Off + ZWrite Off + + // Doesn't seem to work for the R16G16A16B16 Color Buffer + // Blend One One + // BlendOp RevSub + + HLSLPROGRAM + + #pragma vertex SharedVertexStage + #pragma fragment FragmentStage + + #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 + #pragma multi_compile _ _GBUFFER_NORMALS_OCT + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" + #include "../../_Shared/Headers/HMain.hlsl" + #include "../../_Shared/Headers/HSpaceTransforms.hlsl" + #include "../../_Shared/Includes/FallbackAPV.hlsl" + + H_TEXTURE(_ColorCopy); + + #define kMaterialFlagSpecularSetup 8 + uint UnpackMaterialFlags(float packedMaterialFlags) + { return uint((packedMaterialFlags * 255.0h) + 0.5h); } + + float4 FragmentStage(Varyings input) : SV_Target + { + uint2 pixCoord = input.TexCoord * _ScreenSize.xy; + float3 ColorCopy = H_LOAD(_ColorCopy, pixCoord).xyz; + + float DepthCenter = HBUFFER_DEPTH(pixCoord); + float3 NormalCenterWS = HBUFFER_NORMAL_WS(pixCoord); + float3 PositionCenterWS = H_COMPUTE_POSITION_WS(input.TexCoord, DepthCenter, H_MATRIX_I_VP); + + float4 GBuffer0 = H_LOAD(g_HTraceGBuffer0, pixCoord); + float4 Gbuffer1 = H_LOAD(g_HTraceGBuffer1, pixCoord); + + float3 IndirectLighting = 0; + float Metallic = Gbuffer1.r; + + // This seems to make everything worse. + // if ((UnpackMaterialFlags(GBuffer0.a) & kMaterialFlagSpecularSetup) != 0) + // Metallic = (ReflectivitySpecular(Gbuffer1.rgb)); + + if (_EnableProbeVolumes) + { + if (PROBE_VOLUMES_L1 || PROBE_VOLUMES_L2) + { IndirectLighting = EvaluateAPV(PositionCenterWS, NormalCenterWS, H_GET_VIEW_DIRECTION_WS(PositionCenterWS), pixCoord); } + } + else + { + unity_SHAr = H_SHAr; + unity_SHAg = H_SHAg; + unity_SHAb = H_SHAb; + unity_SHBr = H_SHBr; + unity_SHBg = H_SHBg; + unity_SHBb = H_SHBb; + unity_SHC = H_SHC; + IndirectLighting = EvaluateAmbientProbe(NormalCenterWS); + } + + IndirectLighting = IndirectLighting * GBuffer0.rgb * Gbuffer1.a * (1.0 - Metallic); + + return float4(max(ColorCopy - IndirectLighting, 0), 1); + } + + ENDHLSL + } + + Pass + { + Name "Final Output" + + Cull Off + ZWrite Off + Blend One One + + HLSLPROGRAM + + #pragma vertex SharedVertexStage + #pragma fragment FragmentStage + + #pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 + #pragma multi_compile _ _GBUFFER_NORMALS_OCT + #pragma multi_compile _ USE_RECEIVE_LAYER_MASK + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" + + #include "../../_Shared/Headers/HMain.hlsl" + #include "../../_Shared/Headers/HSpaceTransforms.hlsl" + #include "../../_Shared/Includes/FallbackAPV.hlsl" + + H_TEXTURE(_HTraceBufferGI); + + uint _MetallicIndirectFallback; + uint _ExcludeReceivingLayerMaskSSGI; + float _IndirectLightingIntensity; + float4 _APVParams; + + float4 FragmentStage(Varyings input) : SV_Target + { + uint2 pixCoord = input.TexCoord * _ScreenSize.xy; + + if (HBUFFER_DEPTH(pixCoord) <= 1e-7) return 0; + + float3 IndirectLighting = H_LOAD(_HTraceBufferGI, pixCoord).xyz; + +// #if UNITY_VERSION >= 600000 +// // Restore indirect lighting on masked out objects +// if (USE_RECEIVE_LAYER_MASK) +// { +// if (HBUFFER_RENDER_LAYER_MASK(input.TexCoord * _ScreenSize.xy) & _ExcludeReceivingLayerMaskSSGI) +// { +// float3 NormalCenterWS = HBUFFER_NORMAL_WS(pixCoord); +// if (_EnableProbeVolumes) +// { +// float DepthCenter = HBUFFER_DEPTH(pixCoord); +// float3 PositionCenterWS = H_COMPUTE_POSITION_WS(input.TexCoord, DepthCenter, H_MATRIX_I_VP); +// +// if (PROBE_VOLUMES_L1 || PROBE_VOLUMES_L2) +// { IndirectLighting = EvaluateFallbackAPV(_APVParams, PositionCenterWS, NormalCenterWS, H_GET_VIEW_DIRECTION_WS(PositionCenterWS), pixCoord); } +// } +// else +// IndirectLighting = EvaluateFallbackSky(NormalCenterWS); +// } +// } +// #endif + float4 GBuffer0 = H_LOAD(g_HTraceGBuffer0, pixCoord); + float4 Gbuffer1 = H_LOAD(g_HTraceGBuffer1, pixCoord); + + // This works reliably only with Render Graph, so we'll use Unity's _ScreenSpaceOcclusionTexture texture directly here + // float SSAO = H_SAMPLE(g_HTraceSSAO, H_SAMPLER_POINT_CLAMP, input.TexCoord); + float SSAO = _AmbientOcclusionParam.x == 0 ? 1 : H_SAMPLE(_ScreenSpaceOcclusionTexture, H_SAMPLER_POINT_CLAMP, input.TexCoord).x; + + float Metallic = _MetallicIndirectFallback ? 0 : MetallicFromReflectivity(ReflectivitySpecular(Gbuffer1.rgb)); + float3 FinalIndirectLighting = IndirectLighting * _IndirectLightingIntensity * GBuffer0.rgb * Gbuffer1.a * (1 - Metallic) * SSAO; + if (AnyIsNaN(FinalIndirectLighting)) + FinalIndirectLighting = 0; + + return float4(FinalIndirectLighting, 1); + } + + ENDHLSL + } + } +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ColorComposeURP.shader.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ColorComposeURP.shader.meta new file mode 100644 index 000000000..7895ab510 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ColorComposeURP.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1fa31432553d47d5a7b5be6bc675e199 +timeCreated: 1760460287 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ColorComposeURP.shader + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/LightClusterVisualizationURP.shader b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/LightClusterVisualizationURP.shader new file mode 100644 index 000000000..43f58b406 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/LightClusterVisualizationURP.shader @@ -0,0 +1,360 @@ +Shader "Hidden/HTraceWSGI/LightClusterVisualizationURP" +{ + SubShader + { + //Tags { "RenderPipeline" = "HDRenderPipeline" "Queue"="Transparent+0" "IgnoreProjector"="True" "RenderType"="Transparent" } + + HLSLINCLUDE + + static const float3 CubeVertices[24] = + { + // Bottom Face + float3(0.0, 0.0, 0.0), + float3(0.0, 1.0, 0.0), + float3(1.0, 1.0, 0.0), + float3(1.0, 0.0, 0.0), + + // Left Face + float3(0.0, 0.0, 0.0), + float3(1.0, 0.0, 0.0), + float3(1.0, 0.0, 1.0), + float3(0.0, 0.0, 1.0), + + // Front Face + float3(1.0, 0.0, 0.0), + float3(1.0, 1.0, 0.0), + float3(1.0, 1.0, 1.0), + float3(1.0, 0.0, 1.0), + + // Right Face + float3(0.0, 1.0, 0.0), + float3(0.0, 1.0, 1.0), + float3(1.0, 1.0, 1.0), + float3(1.0, 1.0, 0.0), + + // Back Face + float3(0.0, 0.0, 0.0), + float3(0.0, 0.0, 1.0), + float3(0.0, 1.0, 1.0), + float3(0.0, 1.0, 0.0), + + // Top Face + float3(0.0, 0.0, 1.0), + float3(1.0, 0.0, 1.0), + float3(1.0, 1.0, 1.0), + float3(0.0, 1.0, 1.0) + }; + + static const int CubeLines[48] = + { + // Bottom Face + 0, 1, 1, 2, 2, 3, 3, 0, + + // Left Face + 4, 5, 5, 6, 6, 7, 7, 4, + + // Front Face + 8, 9, 9, 10, 10, 11, 11, 8, + + // Right Face + 12, 13, 13, 14, 14, 15, 15, 12, + + // Back Face + 16, 17, 17, 18, 18, 19, 19, 16, + + // Top Face + 20, 21, 21, 22, 22, 23, 23, 20 + }; + + static const int CubeTriangles[36] = + { + // Bottom Face + 0, 1, 2, 2, 3, 0, + + // Left Face + 4, 5, 6, 4, 6, 7, + + // Front Face + 8, 9, 10, 8, 10, 11, + + // Right Face + 12, 13, 14, 12, 14, 15, + + // Back Face + 16, 17, 18, 16, 18, 19, + + // Top Face + 20, 21, 22, 20, 22, 23 + }; + + + ENDHLSL + + Pass + { + Name "Cell Debug Color" + + Cull Back + ZWrite Off + Blend One One + + HLSLPROGRAM + #pragma vertex CubeVertexStage + #pragma fragment CubeFragmentStage + + #include "../../_Shared/Headers/HMain.hlsl" + #include "../../_Shared/Includes/LightCluster.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl" + + StructuredBuffer _LightClusterCounterBuffer; + StructuredBuffer _LightClusterIndexesBuffer; + + struct AttributesDefault + { + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct VaryingsDefault + { + float4 positionCS : SV_POSITION; + float4 PositionNDC : TEXCOORD0; + float3 CellColor : TEXCOORD1; + uint CellCount : TEXCOORD2; + + UNITY_VERTEX_OUTPUT_STEREO + }; + + VaryingsDefault CubeVertexStage(AttributesDefault Attributes, uint vertexID : SV_VertexID, uint instanceID: SV_InstanceID) + { + VaryingsDefault Output; + UNITY_SETUP_INSTANCE_ID(Attributes); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + float3 PositionOS = CubeVertices[CubeTriangles[vertexID % 48]] * g_LightCluterCellSize; + float3 PositionRWS = TransformObjectToWorld(PositionOS); + + uint X = instanceID % g_LightClusterDimensions.x; + uint Y = (instanceID / g_LightClusterDimensions.x) % g_LightClusterDimensions.y; + uint Z = instanceID / (g_LightClusterDimensions.x * g_LightClusterDimensions.y); + uint CellIndex = GetFlattenedIndex(uint3(X, Y, Z)); + + PositionRWS += g_MinLightClusterPosition + float3(g_LightCluterCellSize.x * X, g_LightCluterCellSize.y * Y, g_LightCluterCellSize.z * Z); + + float3 CellLightColor = 0; + uint CellLightCount = _LightClusterCounterBuffer[CellIndex]; + + // Accumulate all light colors within the cell + for (uint i = 0; i < CellLightCount; i++) + { + uint LightIndex = _LightClusterIndexesBuffer[CellIndex * g_MaxLightsPerCell + i]; + float3 PunctualLightColor = _AdditionalLightsColor[LightIndex].xyz; + float4 PunctualLightAtten = _AdditionalLightsAttenuation[LightIndex]; + float PunctualLightRange = 1.0 / sqrt(PunctualLightAtten.x); + + float MaxLightColor = max(PunctualLightColor.r, max(PunctualLightColor.g, PunctualLightColor.b)); + float3 LightColor = (MaxLightColor > 0) ? PunctualLightColor / MaxLightColor : float3(0,0,0); + + CellLightColor += LightColor * lerp(0.1, 0.025, saturate(PunctualLightRange / (g_LightCluterCellSize.x * 10))); + } + + if (CellLightCount > 0) + CellLightColor /= float(CellLightCount); + + Output.CellCount = CellLightCount; + Output.CellColor = CellLightColor; + Output.positionCS = TransformWorldToHClip(PositionRWS); + Output.PositionNDC = float4(H_COMPUTE_NDC_Z(PositionRWS, UNITY_MATRIX_VP), 1); + return Output; + } + + float4 CubeFragmentStage(VaryingsDefault Input) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varying); + + // Cull against scene depth + if (Input.PositionNDC.z < HBUFFER_DEPTH(Input.positionCS.xy).x) + return 0; + + if (g_HeatmapDebug) + { + if (Input.CellCount == 0) return 0; + if (Input.CellCount == 1) return float4(0,0.035,0,1); + if (Input.CellCount == g_MaxLightsPerCell) return float4(1,0,0,1); + + float3 CellHeat = lerp(float3(0,0.035,0), float3(0.15,0,0), float(Input.CellCount) / float(g_MaxLightsPerCell)); + return float4(CellHeat, 1); + } + + return float4(Input.CellColor.xyz, 1.0); + } + + ENDHLSL + } + + Pass + { + Name "Cell Debug Depth" + + Cull Back + ZWrite On + + HLSLPROGRAM + #pragma vertex CubeVertexStage + #pragma fragment CubeFragmentStage + + #include "../../_Shared/Headers/HMain.hlsl" + #include "../../_Shared/Includes/LightCluster.hlsl" + + StructuredBuffer _LightClusterDebugBuffer; + + struct AttributesDefault + { + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct VaryingsDefault + { + float4 PositionCS : SV_POSITION; + float4 PositionNDC : TEXCOORD0; + float CellCulling : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO + }; + + VaryingsDefault CubeVertexStage(AttributesDefault Attributes, uint vertexID : SV_VertexID, uint instanceID: SV_InstanceID) + { + VaryingsDefault Output; + UNITY_SETUP_INSTANCE_ID(Attributes); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + float3 PositionOS = CubeVertices[CubeTriangles[vertexID % 48]] * g_LightCluterCellSize; + float3 PositionRWS = TransformObjectToWorld(PositionOS); + + uint X = instanceID % g_LightClusterDimensions.x; + uint Y = (instanceID / g_LightClusterDimensions.x) % g_LightClusterDimensions.y; + uint Z = instanceID / (g_LightClusterDimensions.x * g_LightClusterDimensions.y); + uint CellIndex = GetFlattenedIndex(uint3(X, Y, Z)); + + PositionRWS += g_MinLightClusterPosition + float3(g_LightCluterCellSize.x * X, g_LightCluterCellSize.y * Y, g_LightCluterCellSize.z * Z); + + // Load edge cells filled earlier by the compute shader + Output.CellCulling = _LightClusterDebugBuffer[CellIndex]; + Output.PositionCS = TransformWorldToHClip(PositionRWS); + Output.PositionNDC = float4(H_COMPUTE_NDC_Z(PositionRWS, UNITY_MATRIX_VP), 1); + return Output; + } + + void CubeFragmentStage(VaryingsDefault Input, out float OutDepth : SV_Depth) + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(Input); + + // Output Depth of the cells that survived culling in the vertex stage + OutDepth = Input.PositionNDC.z * Input.CellCulling; + } + + ENDHLSL + } + + Pass + { + Name "Cell Debug Line" + + Cull Back + ZWrite Off + Blend One One + + HLSLPROGRAM + #pragma vertex LineVertexStage + #pragma fragment LineFragmentStage + + StructuredBuffer _LightClusterCounterBuffer; + StructuredBuffer _LightClusterIndexesBuffer; + + #include "../../_Shared/Headers/HMain.hlsl" + #include "../../_Shared/Includes/LightCluster.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl" + + H_TEXTURE(_LightClusterDebugDepth); + + struct AttributesDefault + { + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct VaryingsDefault + { + float4 positionCS : SV_POSITION; + float4 PositionNDC : TEXCOORD0; + float3 CellColor : TEXCOORD1; + UNITY_VERTEX_OUTPUT_STEREO + }; + + VaryingsDefault LineVertexStage(AttributesDefault Attributes, uint vertexID : SV_VertexID, uint instanceID: SV_InstanceID) + { + VaryingsDefault Output; + UNITY_SETUP_INSTANCE_ID(Attributes); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + float3 PositionOS = CubeVertices[CubeLines[vertexID % 48]] * g_LightCluterCellSize; + float3 PositionRWS = TransformObjectToWorld(PositionOS); + + uint X = instanceID % g_LightClusterDimensions.x; + uint Y = (instanceID / g_LightClusterDimensions.x) % g_LightClusterDimensions.y; + uint Z = instanceID / (g_LightClusterDimensions.x * g_LightClusterDimensions.y); + uint CellIndex = GetFlattenedIndex(uint3(X, Y, Z)); + + PositionRWS += g_MinLightClusterPosition + float3(g_LightCluterCellSize.x * X, g_LightCluterCellSize.y * Y, g_LightCluterCellSize.z * Z); + + float3 CellLightColor = 0; + uint CellLightCount = _LightClusterCounterBuffer[CellIndex]; + + // Accumulate all light colors within the cell + for (uint i = 0; i < CellLightCount; i++) + { + uint LightIndex = _LightClusterIndexesBuffer[CellIndex * g_MaxLightsPerCell + i]; + float3 PunctualLightColor = _AdditionalLightsColor[LightIndex].xyz; + + float MaxLightColor = max(PunctualLightColor.r, max(PunctualLightColor.g, PunctualLightColor.b)); + float3 LightColor = (MaxLightColor > 0) ? PunctualLightColor / MaxLightColor : float3(0,0,0); + + CellLightColor += LightColor; + } + + if (CellLightCount > 0) + CellLightColor /= float(CellLightCount); + + float DistanceMultiplier = length(H_GET_CAMERA_POSITION_WS() - H_GET_ABSOLUTE_POSITION_WS(PositionRWS)); + DistanceMultiplier = lerp(0.1f, 0.025f, saturate(DistanceMultiplier / 50.0f)); + + Output.CellColor = CellLightColor * DistanceMultiplier; + Output.positionCS = TransformWorldToHClip(PositionRWS); + Output.PositionNDC = float4(H_COMPUTE_NDC_Z(PositionRWS, UNITY_MATRIX_VP), 1); + return Output; + } + + float4 LineFragmentStage(VaryingsDefault Input) : SV_Target + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varying); + + float SceneDepth = HBUFFER_DEPTH(Input.positionCS.xy); + float CellDepth = H_LOAD(_LightClusterDebugDepth, Input.positionCS.xy).x; + float3 CellSize = (g_MaxLightClusterPosition - g_MinLightClusterPosition) / float3(g_LightClusterDimensions); + + // Cull against cell depth + if (abs(H_LINEAR_EYE_DEPTH(CellDepth) - H_LINEAR_EYE_DEPTH(Input.PositionNDC.z)) > min(CellSize.x, 0.0025 * H_LINEAR_EYE_DEPTH(Input.PositionNDC.z))) + return 0; + + // Cull against scene depth + if (Input.PositionNDC.z < SceneDepth) + return 0; + + if (g_HeatmapDebug) + return float4(0.5,0,0,1); + + return float4(Input.CellColor.xyz, 1.0); + } + + ENDHLSL + } + } + Fallback Off +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/LightClusterVisualizationURP.shader.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/LightClusterVisualizationURP.shader.meta new file mode 100644 index 000000000..98925bd6c --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/LightClusterVisualizationURP.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2991b564835a4e03b8f03b88f34d0bc6 +timeCreated: 1763045222 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/LightClusterVisualizationURP.shader + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/MotionVectorsURP.shader b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/MotionVectorsURP.shader new file mode 100644 index 000000000..227aa4307 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/MotionVectorsURP.shader @@ -0,0 +1,231 @@ +Shader "Hidden/HTraceWSGI/MotionVectorsURP" +{ + SubShader + { + Pass + { + Name "Camera Motion Vectors" + + Cull Off + ZWrite Off + + HLSLPROGRAM + + #pragma vertex VertexStage + #pragma fragment FragmentStage + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl" + #include "../../_Shared/Headers/HMain.hlsl" + + H_TEXTURE(_ObjectMotionVectors); + H_TEXTURE(_ObjectMotionVectorsDepth); + + float _BiasOffset; + + struct Attributes + { + uint VertexID : SV_VertexID; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 PositionCS : SV_POSITION; + float2 TexCoord : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO + }; + + struct FragOutput + { + float2 MotionVectors : SV_Target0; + float Mask : SV_Target1; + }; + + Varyings VertexStage(Attributes Input) + { + Varyings Output; + UNITY_SETUP_INSTANCE_ID(Input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + Output.PositionCS = GetFullScreenTriangleVertexPosition(Input.VertexID); + Output.TexCoord = GetFullScreenTriangleTexCoord(Input.VertexID); + + return Output; + } + + FragOutput FragmentStage(Varyings Input) + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + FragOutput Output = (FragOutput)0; + + float2 ObjectMotionVectorsColor = H_LOAD(_ObjectMotionVectors, Input.PositionCS.xy).xy; + float ObjectMotionVectorsDepth = H_LOAD(_ObjectMotionVectorsDepth, Input.PositionCS.xy).x; + float CameraDepth = LoadSceneDepth(Input.PositionCS.xy); + + #if !UNITY_REVERSED_Z + CameraDepth = lerp(UNITY_NEAR_CLIP_VALUE, 1, LoadSceneDepth(Input.PositionCS.xy).x); + #endif + + if (ObjectMotionVectorsDepth >= CameraDepth + _BiasOffset) + { + Output.MotionVectors = ObjectMotionVectorsColor; + Output.Mask = 1; + return Output; + } + + // Reconstruct world position + float3 PositionWS = ComputeWorldSpacePosition(Input.PositionCS.xy * _ScreenSize.zw, CameraDepth, UNITY_MATRIX_I_VP); + + // Multiply with current and previous non-jittered view projection + float4 PositionCS = mul(H_MATRIX_VP, float4(PositionWS.xyz, 1.0)); + float4 PreviousPositionCS = mul(H_MATRIX_PREV_VP, float4(PositionWS.xyz, 1.0)); + + // Non-uniform raster needs to keep the posNDC values in float to avoid additional conversions + // since uv remap functions use floats + float2 PositionNDC = PositionCS.xy * rcp(PositionCS.w); + float2 PreviousPositionNDC = PreviousPositionCS.xy * rcp(PreviousPositionCS.w); + + // Calculate forward velocity + float2 Velocity = (PositionNDC - PreviousPositionNDC); + + // TODO: test that velocity.y is correct + #if UNITY_UV_STARTS_AT_TOP + Velocity.y = -Velocity.y; + #endif + + // Convert velocity from NDC space (-1..1) to screen UV 0..1 space + // Note: It doesn't mean we don't have negative values, we store negative or positive offset in the UV space. + // Note: ((posNDC * 0.5 + 0.5) - (prevPosNDC * 0.5 + 0.5)) = (velocity * 0.5) + Velocity.xy *= 0.5; + + Output.MotionVectors = Velocity; + Output.Mask = 0; + + return Output; + } + + ENDHLSL + } + + + Pass + { + Name "Object Motion Vectors" + + Tags { "LightMode" = "MotionVectors" } + + HLSLPROGRAM + + #pragma vertex vert + #pragma fragment frag + #pragma multi_compile_instancing + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl" + #include "../../_Shared/Headers/HMain.hlsl" + + #ifndef HAVE_VFX_MODIFICATION + #pragma multi_compile _ DOTS_INSTANCING_ON + #if UNITY_PLATFORM_ANDROID || UNITY_PLATFORM_WEBGL || UNITY_PLATFORM_UWP + #pragma target 3.5 DOTS_INSTANCING_ON + #else + #pragma target 4.5 DOTS_INSTANCING_ON + #endif + #endif + + struct Attributes + { + float4 Position : POSITION; + float3 PositionOld : TEXCOORD4; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + struct Varyings + { + float4 PositionCS : SV_POSITION; + float4 PositionCSNoJitter : TEXCOORD0; + float4 PreviousPositionCSNoJitter : TEXCOORD1; + float MotionMask : TEXCOORD2; + UNITY_VERTEX_INPUT_INSTANCE_ID + UNITY_VERTEX_OUTPUT_STEREO + }; + + Varyings vert(Attributes Input) + { + UNITY_SETUP_INSTANCE_ID(Input); + Varyings Output = (Varyings)0; + UNITY_TRANSFER_INSTANCE_ID(Input, Output); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(Output); + + VertexPositionInputs VertexInput = GetVertexPositionInputs(Input.Position.xyz); + + // Jittered. Match the frame. + Output.PositionCS = VertexInput.positionCS; + + // This is required to avoid artifacts ("gaps" in the _MotionVectorTexture) on some platforms + #if defined(UNITY_REVERSED_Z) + Output.PositionCS.z -= unity_MotionVectorsParams.z * Output.PositionCS.w; + #else + Output.PositionCS.z += unity_MotionVectorsParams.z * Output.PositionCS.w; + #endif + + const float4 PreviousPosition = (unity_MotionVectorsParams.x == 1) ? float4(Input.PositionOld, 1) : Input.Position; + const float4 PositionWS = mul(UNITY_MATRIX_M, Input.Position); + const float4 PreviousPositionWS = mul(UNITY_PREV_MATRIX_M, PreviousPosition); + + Output.PositionCSNoJitter = mul(H_MATRIX_VP, PositionWS); + Output.PreviousPositionCSNoJitter = mul(H_MATRIX_PREV_VP, PreviousPositionWS); + Output.MotionMask = length(PositionWS - PreviousPositionWS) > 0.0001 ? 1 : 0; + + return Output; + } + + struct FragOutput + { + float2 MotionVectors : SV_Target0; + float Mask : SV_Target1; + }; + + FragOutput frag(Varyings Input) + { + UNITY_SETUP_INSTANCE_ID(Input); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(Input); + FragOutput Output = (FragOutput)0; + + // Note: unity_MotionVectorsParams.y is 0 is forceNoMotion is enabled + bool ForceNoMotion = unity_MotionVectorsParams.y == 0.0; + if (ForceNoMotion) + { + Output.MotionVectors = 0; + Output.Mask = 0; + return Output; + } + + // Calculate positions + float4 PositionCS = Input.PositionCSNoJitter; + float4 PreviousPositionCS = Input.PreviousPositionCSNoJitter; + + float2 PositionNDC = PositionCS.xy * rcp(PositionCS.w); + float2 PreviousPositionNDC = PreviousPositionCS.xy * rcp(PreviousPositionCS.w); + + float2 Velocity = (PositionNDC.xy - PreviousPositionNDC.xy); + #if UNITY_UV_STARTS_AT_TOP + Velocity.y = -Velocity.y; + #endif + + // Convert velocity from NDC space (-1..1) to UV 0..1 space + // Note: It doesn't mean we don't have negative values, we store negative or positive offset in UV space. + // Note: ((posNDC * 0.5 + 0.5) - (prevPosNDC * 0.5 + 0.5)) = (velocity * 0.5) + Velocity.xy *= 0.5; + + Output.MotionVectors = Velocity; + Output.Mask = Input.MotionMask; + return Output; + } + ENDHLSL + } + } +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/MotionVectorsURP.shader.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/MotionVectorsURP.shader.meta new file mode 100644 index 000000000..37c26ebbb --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/MotionVectorsURP.shader.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 6f7f91bedc42bda418c5a03b4b7e3f2a +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/MotionVectorsURP.shader + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ShadowmapURP.shader b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ShadowmapURP.shader new file mode 100644 index 000000000..0683e5072 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ShadowmapURP.shader @@ -0,0 +1,64 @@ +Shader "Hidden/HTraceWSGI/ShadowmapURP" +{ + SubShader + { + HLSLINCLUDE + + #pragma target 4.5 + #pragma multi_compile_instancing + #pragma multi_compile _ DOTS_INSTANCING_ON + + ENDHLSL + + Pass + { + Name "SHADOWMAP_COPY" + + Blend Off + ZTest LEqual + Cull Back + + HLSLPROGRAM + #pragma vertex FullScreenVert + #pragma fragment FullScreenFrag + + #include "../../_Shared/Headers/HMain.hlsl" + + + H_TEXTURE_DX(float, _DirectionalShadowmapStatic); + + struct FullScreenAttributes + { + uint vertexID : SV_VertexID; + }; + + struct FullScreenVaryings + { + float4 positionCS : SV_POSITION; + }; + + struct Attributes + { + uint vertexID : SV_VertexID; + UNITY_VERTEX_INPUT_INSTANCE_ID + }; + + FullScreenVaryings FullScreenVert(Attributes input) + { + FullScreenVaryings output; + output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID, UNITY_RAW_FAR_CLIP_VALUE); + + return output; + } + + + float FullScreenFrag(FullScreenVaryings varyings, out float Depth_Output : SV_Depth) : SV_Target + { + Depth_Output = H_LOAD(_DirectionalShadowmapStatic, varyings.positionCS.xy).x; + return 0; + } + + ENDHLSL + } + } +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ShadowmapURP.shader.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ShadowmapURP.shader.meta new file mode 100644 index 000000000..1a94f6ab3 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ShadowmapURP.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c3a0cd0caf5f43149c1e3177309b8223 +timeCreated: 1764077361 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/ShadowmapURP.shader + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelVisualizationURP.shader b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelVisualizationURP.shader new file mode 100644 index 000000000..197b25802 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelVisualizationURP.shader @@ -0,0 +1,83 @@ +Shader "Hidden/HTraceWSGI/VoxelVisualizationURP" +{ + SubShader + { + HLSLINCLUDE + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl" + + float4x4 _DebugCameraFrustum; + float4 _DebugCameraFrustumArray[8]; + + struct Attributes + { + UNITY_VERTEX_INPUT_INSTANCE_ID + uint VertexID : SV_VertexID; + }; + + + struct FullScreenVaryings + { + UNITY_VERTEX_OUTPUT_STEREO + float4 positionCS : SV_POSITION; + float3 ray : TEXCOORD0; + }; + + + ENDHLSL + + Pass + { + Name "Copy Color Buffer" + + ZWrite Off + ZTest Always + Blend SrcAlpha OneMinusSrcAlpha + Cull Off + + HLSLPROGRAM + + #pragma vertex FullScreenVert + #pragma fragment FragmentStage + + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl" + #include "../../_Shared/Headers/HMain.hlsl" + + FullScreenVaryings FullScreenVert(Attributes input) + { + FullScreenVaryings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + + float4 PositionCS = GetFullScreenTriangleVertexPosition(input.VertexID, UNITY_RAW_FAR_CLIP_VALUE); + output.positionCS = PositionCS; + + PositionCS = PositionCS * 0.5 + 0.5; + int index = (PositionCS.x / 2.0f) + PositionCS.y; + + + output.ray = (_DebugCameraFrustum[index].xyz); + // output.ray = ( _DebugCameraFrustumArray[0 * 4 + vertexID].xyz); + return output; + } + + + float4 FragmentStage(FullScreenVaryings input) : SV_Target + { + float3 Test = HBUFFER_DEPTH(input.positionCS.xy); + // return float4(Test, 1); + + // UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(FullScreenVaryings); + return float4(input.ray, 1); + } + + ENDHLSL + } + + + + } +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelVisualizationURP.shader.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelVisualizationURP.shader.meta new file mode 100644 index 000000000..f0814b76a --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelVisualizationURP.shader.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: e492117e834a6544a875878581bb0c4a +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelVisualizationURP.shader + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelizationURP.shader b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelizationURP.shader new file mode 100644 index 000000000..b1bd24c7a --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelizationURP.shader @@ -0,0 +1,33 @@ +Shader "Hidden/HTraceWSGI/VoxelizationURP" +{ + SubShader + { + Pass + { + Name "HTrace Voxelization" + Cull Off + ZClip Off + ZWrite Off + Conservative False + + HLSLPROGRAM + + #pragma require geometry + #pragma require randomwrite + + #pragma multi_compile_instancing + #pragma multi_compile _ DOTS_INSTANCING_ON + #pragma multi_compile CONSTANT_VOXELIZATION PARTIAL_VOXELIZATION DYNAMIC_VOXELIZATION + + #include "../../_Shared/Includes/VoxelizationStagesURP.hlsl" + + #pragma vertex VoxelizationVert + #pragma geometry VoxelizationGeom + #pragma fragment VoxelizationFrag + + ENDHLSL + } + } + + Fallback Off +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelizationURP.shader.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelizationURP.shader.meta new file mode 100644 index 000000000..7782f6f65 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelizationURP.shader.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: e862d8907c85cbc4ea109bfe71614ea9 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/URP/Shaders/VoxelizationURP.shader + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/Volume Profile HTrace WSGI URP.asset b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/Volume Profile HTrace WSGI URP.asset new file mode 100644 index 000000000..aca0308dd --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/Volume Profile HTrace WSGI URP.asset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e265885a9bb3d23d678ae9026db635daf380d9eb5ad34af9f6cf93c7de539a0 +size 1557 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/Volume Profile HTrace WSGI URP.asset.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/Volume Profile HTrace WSGI URP.asset.meta new file mode 100644 index 000000000..66ee400b4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/Volume Profile HTrace WSGI URP.asset.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 354b90c2ceb7df149b2fc1d4fe328838 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/Volume Profile HTrace WSGI URP.asset + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared.meta new file mode 100644 index 000000000..4cef4810c --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 55fee9bbd30d4af79c883c6b5baeb500 +timeCreated: 1764080232 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise.meta new file mode 100644 index 000000000..1f545208e --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bd0a5f0cd24c19145af4c7d02400ef5d +timeCreated: 1747995745 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise256.png b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise256.png new file mode 100644 index 000000000..3e7481332 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise256.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34c0f9e47cbc0fd00904eb92e6ee24cee2985dd6fec529e1caecffbbe98ab173 +size 65960 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise256.png.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise256.png.meta new file mode 100644 index 000000000..2dec9243b --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise256.png.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: bcd52ea3c2ac332418c61d8e65a2c252 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 3 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise256.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise4.png b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise4.png new file mode 100644 index 000000000..76782e403 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2dd7e59bb9464ba9f79534b88f1a5e4dacf5917f8aecdc3313cf99a0c366173 +size 1117 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise4.png.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise4.png.meta new file mode 100644 index 000000000..44e5ed68e --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise4.png.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: 7105725bc431f7b4a9c36b57724d6c18 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 3 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise4.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile1SPP.png b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile1SPP.png new file mode 100644 index 000000000..62d3a8da7 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile1SPP.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:881f8fed39a1f9d973d34b1e423e7f7f2262f697fe01a9e6bc9b14018d3845cb +size 96 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile1SPP.png.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile1SPP.png.meta new file mode 100644 index 000000000..90a7b8d19 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile1SPP.png.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: 4cdfcda66efc7c74c9e67bdd53e48fba +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 3 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile1SPP.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile256SPP.png b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile256SPP.png new file mode 100644 index 000000000..389ebbc3a --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile256SPP.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:323f9032345aa202ddc69449214b54947ec9f4180011dae77925b63b500e340c +size 85522 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile256SPP.png.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile256SPP.png.meta new file mode 100644 index 000000000..b42ca0ad2 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile256SPP.png.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: 876f3102cad6769479a91bdb085e43af +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 3 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile256SPP.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile8SPP.png b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile8SPP.png new file mode 100644 index 000000000..1d5078ede --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile8SPP.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c39a8aad1611cf90150e1fc9f9c9a5b02f903bc00c205e5186f2f492ed70a341 +size 29706 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile8SPP.png.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile8SPP.png.meta new file mode 100644 index 000000000..280681542 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile8SPP.png.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: 08374171679a7e040b21ce3a82786e6d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 3 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/RankingTile8SPP.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScrambleNoise.png b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScrambleNoise.png new file mode 100644 index 000000000..207122ad1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScrambleNoise.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d7224912da4a7560a6ba80273492ae49e73084e01b1c9d1e8afe14ac38c4714 +size 154779 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScrambleNoise.png.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScrambleNoise.png.meta new file mode 100644 index 000000000..afa29fd92 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScrambleNoise.png.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: adf16ddb85aed6846b00cb6ea5f69ee0 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 3 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScrambleNoise.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile1SPP.png b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile1SPP.png new file mode 100644 index 000000000..eb6c249cc --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile1SPP.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c17c4bac7aa4441aca519450dacb62a37e81195f3fba70fb58f377aaff488dc +size 132316 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile1SPP.png.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile1SPP.png.meta new file mode 100644 index 000000000..98cb50f55 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile1SPP.png.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: ae95ac3876de5774caa3de35d227b631 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 3 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile1SPP.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile256SPP.png b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile256SPP.png new file mode 100644 index 000000000..4460ade27 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile256SPP.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40342eea86411c118719d8adcf794b951cbaea2b183c9462cbcae2bf91925484 +size 132320 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile256SPP.png.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile256SPP.png.meta new file mode 100644 index 000000000..0cf8f5afb --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile256SPP.png.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: 0e53c38031c2bff45a2428c44c181436 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 3 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile256SPP.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile8SPP.png b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile8SPP.png new file mode 100644 index 000000000..c8a4f69e4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile8SPP.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02f9569f739a355700df6fc0ca7e9fc032ca5f78b2e04563bcd323a6301f911e +size 132319 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile8SPP.png.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile8SPP.png.meta new file mode 100644 index 000000000..83fa6ee9f --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile8SPP.png.meta @@ -0,0 +1,134 @@ +fileFormatVersion: 2 +guid: f9c63c94bb48b6a49a8c685d8d474482 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 0 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: 3 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/BlueNoise/ScramblingTile8SPP.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes.meta new file mode 100644 index 000000000..db398ca53 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 31a45e77d5c4e984398280d1697ed939 +timeCreated: 1719664117 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/CopyBuffersBIRP.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/CopyBuffersBIRP.compute new file mode 100644 index 000000000..beee3f815 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/CopyBuffersBIRP.compute @@ -0,0 +1,24 @@ +#pragma kernel CopyColor +#pragma kernel CopyEmissives + +#include "../Headers/HMain.hlsl" + +H_TEXTURE(_ColorInput); +H_TEXTURE(_EmissivesInput); + +H_RW_TEXTURE(float3, _ColorOutput); +H_RW_TEXTURE(float3, _EmissivesOutput); + +// ------------------------ COPY COLOR (BIRP ONLY) ------------------------ +[numthreads(8, 8, 1)] +void CopyColor(uint3 pixCoord : SV_DispatchThreadID) +{ + _ColorOutput[H_COORD(pixCoord.xy)] = H_LOAD(_ColorInput, pixCoord.xy); +} + +// ------------------------ COPY EMISSIVES (BIRP ONLY) ------------------------ +[numthreads(8, 8, 1)] +void CopyEmissives(uint3 pixCoord : SV_DispatchThreadID) +{ + _EmissivesOutput[H_COORD(pixCoord.xy)] = H_LOAD(_EmissivesInput, pixCoord.xy); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/CopyBuffersBIRP.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/CopyBuffersBIRP.compute.meta new file mode 100644 index 000000000..287870f4a --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/CopyBuffersBIRP.compute.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1615930f75214d8286118bfcd908eca6 +timeCreated: 1759140972 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/CopyBuffersBIRP.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HCopy.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HCopy.compute new file mode 100644 index 000000000..6d5631e9d --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HCopy.compute @@ -0,0 +1,48 @@ +#pragma kernel CopyProbeAtlases +#pragma kernel CopyProbeBuffers +#pragma kernel CopyFullResBuffers + + +#include "../Headers/HMain.hlsl" + +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(g_GeometryNormal); +H_TEXTURE(_ShadowGuidanceMask); +H_TEXTURE(_ShadowGuidanceMask_Samplecount); +H_TEXTURE(_ShadowGuidanceMask_Accumulated); + +H_RW_TEXTURE(uint2, _NormalDepth_HistoryOutput); +H_RW_TEXTURE(float, _ShadowGuidanceMask_HistoryOutput); +H_RW_TEXTURE(float, _ShadowGuidanceMask_SamplecountHistoryOutput); +H_RW_TEXTURE(float, _ShadowGuidanceMask_CheckerboardHistoryOutput); + + +// ------------------------ PROBE ATLAS COPY ------------------------ +[numthreads(8, 8, 1)] +void CopyProbeAtlases(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + _ShadowGuidanceMask_CheckerboardHistoryOutput[H_COORD(pixCoord.xy)] = H_LOAD(_ShadowGuidanceMask, pixCoord.xy).x; + _ShadowGuidanceMask_HistoryOutput[H_COORD(pixCoord.xy)] = H_LOAD(_ShadowGuidanceMask_Accumulated, pixCoord.xy).x; +} + + +// ------------------------ PROBE BUFFER COPY ------------------------ +[numthreads(8, 8, 1)] +void CopyProbeBuffers(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + _ShadowGuidanceMask_SamplecountHistoryOutput[H_COORD(pixCoord.xy)] = H_LOAD(_ShadowGuidanceMask_Samplecount, pixCoord.xy).x; +} + + +// ------------------------ FULL RES BUFFER COPY ------------------------ +[numthreads(8, 8, 1)] +void CopyFullResBuffers(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + float DepthForHistory = HBUFFER_DEPTH(pixCoord.xy); + float3 NormalForHistory = H_LOAD(g_GeometryNormal, pixCoord.xy).xyz; + // _NormalDepth_HistoryOutput[H_COORD(pixCoord.xy)] = PackNormalDepth(NormalForHistory, DepthForHistory); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HCopy.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HCopy.compute.meta new file mode 100644 index 000000000..f8eb3673d --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HCopy.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: ddf1b1e824de7ca4a87d4a6fc22d0f32 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HCopy.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebug.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebug.compute new file mode 100644 index 000000000..9f8549622 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebug.compute @@ -0,0 +1,118 @@ +#pragma kernel Debug + + +#include "../Headers/HMain.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +// Input bufferes +H_TEXTURE(_HTraceBufferGI); +H_TEXTURE(g_GeometryNormal); +H_TEXTURE(_HTraceBufferVoxelVisualization); +//H_TEXTURE(g_HTraceShadowmap); +H_TEXTURE(g_LightClusterDebug); + + + +//UNITY_DECLARE_SHADOWMAP (g_HTraceShadowmap); +SamplerComparisonState sampler_g_HTraceShadowmap; +Texture2D g_HTraceShadowmap; +float4x4 g_DirLightMatrix; +// sampler_ShadowMapTexture; +//H_TEXTURE(_ShadowmapAtlas); + +float4 g_HTraceShadowmap_TexelSize; +#define SHADOWMAPSAMPLER_AND_TEXELSIZE_DEFINED + +// Output buffers +H_RW_TEXTURE(float4, _Debug_Output); + +int _DebugSwitch; +int _BuffersSwitch; + +void DebugFinal(uint3 pixCoord) +{ + if (_DebugSwitch == 1) // MainBuffers + { + if (_BuffersSwitch == 0) // Multi + { + uint2 quadSize = _ScreenSize / 2; + uint2 quadIndex = pixCoord.xy / quadSize; // (0,0), (1,0), (0,1), (1,1) + uint2 localCoord = pixCoord.xy % quadSize; + uint2 sampleCoord = localCoord * 2; + + float4 outputColor = float4(0, 0, 0, 1); + + if (HBUFFER_DEPTH(sampleCoord.xy) <= UNITY_RAW_FAR_CLIP_VALUE) + { + _Debug_Output[H_COORD(pixCoord.xy)] = outputColor; + return; + } + + if (quadIndex.x == 0 && quadIndex.y == 0) // Bot Left + { + outputColor = float4(HBUFFER_NORMAL_WS(sampleCoord).xyz, 1); + } + else if (quadIndex.x == 1 && quadIndex.y == 0) // Bot right + { + float2 motionVector = HBUFFER_MOTION_VECTOR(sampleCoord).xy; + float motionMask = HBUFFER_MOTION_MASK(sampleCoord).x; + outputColor = float4(motionVector * 5, motionMask * 0.05, 1); + } + else if (quadIndex.x == 0 && quadIndex.y == 1) // Top left + { + outputColor = float4(H_LINEAR_EYE_DEPTH(HBUFFER_DEPTH(sampleCoord).x).xxx / 20.0f, 1); + } + else if (quadIndex.x == 1 && quadIndex.y == 1) // Top right + { + outputColor = float4(HBUFFER_DIFFUSE(sampleCoord).xyz, 1); + } + + _Debug_Output[H_COORD(pixCoord.xy)] = outputColor; + } + if (_BuffersSwitch == 1) // Depth + { + _Debug_Output[H_COORD(pixCoord.xy)] = float4(HBUFFER_DEPTH(pixCoord.xy).xxx, 1); + } + if (_BuffersSwitch == 2) // Diffuse + { + _Debug_Output[H_COORD(pixCoord.xy)] = float4(HBUFFER_DIFFUSE(pixCoord.xy).xyz, 1); + } + if (_BuffersSwitch == 3) // Normal + { + _Debug_Output[H_COORD(pixCoord.xy)] = float4(HBUFFER_NORMAL_WS(pixCoord.xy).xyz, 1); + } + if (_BuffersSwitch == 4) // Motion Mask + { + _Debug_Output[H_COORD(pixCoord.xy)] = float4(HBUFFER_MOTION_MASK(pixCoord.xy).xxx, 1); + } + if (_BuffersSwitch == 5) // MV + { + _Debug_Output[H_COORD(pixCoord.xy)] = float4(HBUFFER_MOTION_VECTOR(pixCoord.xy).xy, 0, 1); + } + } + + if (_DebugSwitch == 2) // GlobalIllumination + _Debug_Output[H_COORD(pixCoord.xy)] = H_LOAD(_HTraceBufferGI, pixCoord.xy); + + if (_DebugSwitch == 3) // GeometryNormals + _Debug_Output[H_COORD(pixCoord.xy)] = H_LOAD(g_GeometryNormal, pixCoord.xy); + + if (_DebugSwitch == 4) // Shadowmap + _Debug_Output[H_COORD(pixCoord.xy)] = H_LOAD(g_HTraceShadowmap, pixCoord.xy * (2048 / _ScreenSize.y)).x; + + if (_DebugSwitch == 5) // VoxelizedColor + _Debug_Output[H_COORD(pixCoord.xy)] = H_LOAD(_HTraceBufferGI, pixCoord.xy); + + if (_DebugSwitch == 6) // VoxelizedLighting + _Debug_Output[H_COORD(pixCoord.xy)] = H_LOAD(_HTraceBufferGI, pixCoord.xy); + + if (_DebugSwitch == 7 || _DebugSwitch == 8) // LightCluster + _Debug_Output[H_COORD(pixCoord.xy)] = H_LOAD(g_LightClusterDebug, pixCoord.xy); +} + +[numthreads(8, 8, 1)] +void Debug(uint3 pixCoord : SV_DispatchThreadID) +{ + + DebugFinal(pixCoord); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebug.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebug.compute.meta new file mode 100644 index 000000000..40f34b281 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebug.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 6e81537dfc967764694c7747f08cf20e +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebug.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebugPassthrough.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebugPassthrough.compute new file mode 100644 index 000000000..e83302906 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebugPassthrough.compute @@ -0,0 +1,19 @@ +#include "../Headers/HMain.hlsl" + +#pragma kernel DebugPassthrough + +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_InputA); +H_TEXTURE(_InputB); +H_TEXTURE(_ReprojectionCoords); + +H_RW_TEXTURE(float3, _Output); + +[numthreads(8, 8, 1)] +void DebugPassthrough(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint2 groupId : SV_GroupID) +{ + + _Output[H_COORD(pixCoord.xy)] = H_LOAD(_InputA, pixCoord.xy).xyz ; + +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebugPassthrough.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebugPassthrough.compute.meta new file mode 100644 index 000000000..63bc11d4a --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebugPassthrough.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 94a5f9a2dfc71004ebb53009d1179d9c +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDebugPassthrough.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDepthPyramid.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDepthPyramid.compute new file mode 100644 index 000000000..1ffdfb8ff --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDepthPyramid.compute @@ -0,0 +1,176 @@ +#pragma kernel GenerateDepthPyramid_1 +#pragma kernel GenerateDepthPyramid_2 + +#include "../Headers/HMain.hlsl" + +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_DepthIntermediate); + +H_RW_TEXTURE(float, _DepthPyramid_OutputMIP0); +H_RW_TEXTURE(float, _DepthPyramid_OutputMIP1); +H_RW_TEXTURE(float, _DepthPyramid_OutputMIP2); +H_RW_TEXTURE(float, _DepthPyramid_OutputMIP3); +H_RW_TEXTURE(float, _DepthPyramid_OutputMIP4); +H_RW_TEXTURE(float, _DepthPyramid_OutputMIP5); +H_RW_TEXTURE(float, _DepthPyramid_OutputMIP6); +H_RW_TEXTURE(float, _DepthPyramid_OutputMIP7); +H_RW_TEXTURE(float, _DepthPyramid_OutputMIP8); +H_RW_TEXTURE(float, _DepthIntermediate_Output); + +groupshared float MipDepthLDS[8][8]; + +// ------------------------ MIP LEVEL 0-4 GENERATIONS ------------------------ +[numthreads(8, 8, 1)] +void GenerateDepthPyramid_1(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) +{ + + + const uint2 baseCoord = pixCoord.xy; + pixCoord.xy = baseCoord * 2; + + float Depth_00 = any(pixCoord.xy + uint2(0,0) >= uint2(_ScreenSize.xy)) ? 0 : HBUFFER_DEPTH(pixCoord.xy + uint2(0,0)); + float Depth_10 = any(pixCoord.xy + uint2(1,0) >= uint2(_ScreenSize.xy)) ? 0 : HBUFFER_DEPTH(pixCoord.xy + uint2(1,0)); + float Depth_01 = any(pixCoord.xy + uint2(0,1) >= uint2(_ScreenSize.xy)) ? 0 : HBUFFER_DEPTH(pixCoord.xy + uint2(0,1)); + float Depth_11 = any(pixCoord.xy + uint2(1,1) >= uint2(_ScreenSize.xy)) ? 0 : HBUFFER_DEPTH(pixCoord.xy + uint2(1,1)); + + Depth_00 = Depth_00 >= 0.9999f ? 0 : Depth_00; + Depth_10 = Depth_10 >= 0.9999f ? 0 : Depth_10; + Depth_01 = Depth_01 >= 0.9999f ? 0 : Depth_01; + Depth_11 = Depth_11 >= 0.9999f ? 0 : Depth_11; + + // Write to MIP0 + _DepthPyramid_OutputMIP0[H_COORD(pixCoord.xy + uint2(0, 0))] = Depth_00; + _DepthPyramid_OutputMIP0[H_COORD(pixCoord.xy + uint2(1, 0))] = Depth_10; + _DepthPyramid_OutputMIP0[H_COORD(pixCoord.xy + uint2(0, 1))] = Depth_01; + _DepthPyramid_OutputMIP0[H_COORD(pixCoord.xy + uint2(1, 1))] = Depth_11; + + float DepthMIP1 = max(max(Depth_00, Depth_10), max(Depth_01, Depth_11)); + + // Write to MIP1 + _DepthPyramid_OutputMIP1[H_COORD(baseCoord)] = DepthMIP1; + + MipDepthLDS[groupThreadID.x][groupThreadID.y] = DepthMIP1; + GroupMemoryBarrierWithGroupSync(); + + // Write to MIP2 + [branch] + if (all((groupThreadID.xy % int2(2, 2)) == 0)) + { + float DepthLDS_00 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 0]; + float DepthLDS_10 = MipDepthLDS[groupThreadID.x + 1][groupThreadID.y + 0]; + float DepthLDS_01 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 1]; + float DepthLDS_11 = MipDepthLDS[groupThreadID.x + 1][groupThreadID.y + 1]; + + float DepthMIP2 = max(max(DepthLDS_00, DepthLDS_10), max(DepthLDS_01, DepthLDS_11)); + + _DepthPyramid_OutputMIP2[H_COORD(baseCoord / 2)] = DepthMIP2; + MipDepthLDS[groupThreadID.x][groupThreadID.y] = DepthMIP2; + } + + GroupMemoryBarrierWithGroupSync(); + + // Write to MIP3 + [branch] + if (all((groupThreadID.xy % int2(4, 4)) == 0)) + { + float DepthLDS_00 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 0]; + float DepthLDS_10 = MipDepthLDS[groupThreadID.x + 2][groupThreadID.y + 0]; + float DepthLDS_01 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 2]; + float DepthLDS_11 = MipDepthLDS[groupThreadID.x + 2][groupThreadID.y + 2]; + + float DepthMIP3 = max(max(DepthLDS_00, DepthLDS_10), max(DepthLDS_01, DepthLDS_11)); + + _DepthPyramid_OutputMIP3[H_COORD(baseCoord / 4)] = DepthMIP3; + MipDepthLDS[groupThreadID.x][groupThreadID.y] = DepthMIP3; + } + + GroupMemoryBarrierWithGroupSync(); + + // Write to MIP4 + [branch] + if (all((groupThreadID.xy % int2(8, 8)) == 0)) + { + float DepthLDS_00 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 0]; + float DepthLDS_10 = MipDepthLDS[groupThreadID.x + 4][groupThreadID.y + 0]; + float DepthLDS_01 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 4]; + float DepthLDS_11 = MipDepthLDS[groupThreadID.x + 4][groupThreadID.y + 4]; + + float DepthMIP4 = max(max(DepthLDS_00, DepthLDS_10), max(DepthLDS_01, DepthLDS_11)); + + _DepthPyramid_OutputMIP4[H_COORD(baseCoord / 8)] = DepthMIP4; + _DepthIntermediate_Output[H_COORD(baseCoord / 8)] = DepthMIP4; + } +} + + +// ------------------------ MIP LEVEL 5-7 GENERATIONS ------------------------ +[numthreads(8, 8, 1)] +void GenerateDepthPyramid_2(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) +{ + + + const uint2 baseCoord = pixCoord.xy; + pixCoord.xy = baseCoord * 2; + + float Depth_00 = H_LOAD_LOD(_DepthIntermediate, pixCoord.xy + uint2(0,0), 0).x; + float Depth_10 = H_LOAD_LOD(_DepthIntermediate, pixCoord.xy + uint2(1,0), 0).x; + float Depth_01 = H_LOAD_LOD(_DepthIntermediate, pixCoord.xy + uint2(0,1), 0).x; + float Depth_11 = H_LOAD_LOD(_DepthIntermediate, pixCoord.xy + uint2(1,1), 0).x; + + float DepthMIP5 = max(max(Depth_00, Depth_10), max(Depth_01, Depth_11)); + + // Write to MIP5 + _DepthPyramid_OutputMIP5[H_COORD(baseCoord)] = DepthMIP5; + + MipDepthLDS[groupThreadID.x][groupThreadID.y] = DepthMIP5; + GroupMemoryBarrierWithGroupSync(); + + // Write to MIP6 + [branch] + if (all((groupThreadID.xy % int2(2, 2)) == 0)) + { + float DepthLDS_00 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 0]; + float DepthLDS_10 = MipDepthLDS[groupThreadID.x + 1][groupThreadID.y + 0]; + float DepthLDS_01 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 1]; + float DepthLDS_11 = MipDepthLDS[groupThreadID.x + 1][groupThreadID.y + 1]; + + float DepthMIP6 = max(max(DepthLDS_00, DepthLDS_10), max(DepthLDS_01, DepthLDS_11)); + + _DepthPyramid_OutputMIP6[H_COORD(baseCoord / 2)] = DepthMIP6; + MipDepthLDS[groupThreadID.x][groupThreadID.y] = DepthMIP6; + } + + GroupMemoryBarrierWithGroupSync(); + + // Write to MIP7 + [branch] + if (all((groupThreadID.xy % int2(4, 4)) == 0)) + { + float DepthLDS_00 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 0]; + float DepthLDS_10 = MipDepthLDS[groupThreadID.x + 2][groupThreadID.y + 0]; + float DepthLDS_01 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 2]; + float DepthLDS_11 = MipDepthLDS[groupThreadID.x + 2][groupThreadID.y + 2]; + + float DepthMIP7 = max(max(DepthLDS_00, DepthLDS_10), max(DepthLDS_01, DepthLDS_11)); + + _DepthPyramid_OutputMIP7[H_COORD(baseCoord / 4)] = DepthMIP7; + MipDepthLDS[groupThreadID.x][groupThreadID.y] = DepthMIP7; + } + + // GroupMemoryBarrierWithGroupSync(); + // + // // Write to MIP8 + // [branch] + // if (all((groupThreadID.xy % int2(8, 8)) == 0)) + // { + // float DepthLDS_00 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 0]; + // float DepthLDS_10 = MipDepthLDS[groupThreadID.x + 4][groupThreadID.y + 0]; + // float DepthLDS_01 = MipDepthLDS[groupThreadID.x + 0][groupThreadID.y + 4]; + // float DepthLDS_11 = MipDepthLDS[groupThreadID.x + 4][groupThreadID.y + 4]; + // + // float DepthMIP8 = max(max(DepthLDS_00, DepthLDS_10), max(DepthLDS_01, DepthLDS_11)); + // + // _DepthPyramid_OutputMIP8[H_COORD(baseCoord / 8)] = DepthMIP8; + // } +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDepthPyramid.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDepthPyramid.compute.meta new file mode 100644 index 000000000..60a5ba772 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDepthPyramid.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: ea1b07ce290d9b74090fc5ecf236697e +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HDepthPyramid.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HInterpolation.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HInterpolation.compute new file mode 100644 index 000000000..319fec94d --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HInterpolation.compute @@ -0,0 +1,266 @@ +#pragma kernel GatherSH +#pragma kernel Interpolation + +#pragma multi_compile _ USE_DIRECTIONAL_OCCLUSION + +#include "../Includes/Config.hlsl" +#include "../Includes/Reservoir.hlsl" +#include "../Includes/SpatialFilteringFunctions.hlsl" +#include "../Includes/SphericalHarmonics.hlsl" + +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_ShadowGuidanceMask); + +H_TEXTURE(_ProbeSSAO); +H_TEXTURE(_PackedSH_A); +H_TEXTURE(_PackedSH_B); +H_TEXTURE(_BentNormalsAO); +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(g_GeometryNormal); + +H_TEXTURE(_Temp); + +H_RW_TEXTURE(uint, _Radiance_Output); +H_RW_TEXTURE(uint4, _PackedSH_A_Output); +H_RW_TEXTURE(uint4, _PackedSH_B_Output); + +float _AO_Intensity; + +// ------------------------ SH GATHER ----------------------- +[numthreads(8, 8, 1)] +void GatherSH(uint3 pixCoord : SV_DispatchThreadID) +{ + + + // Initialize SH storage + SH_L2_Color CoefficientsSH; + InitializeSH(CoefficientsSH); + + uint2 Unused; + float3 Normal = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy)).xy, Unused).xyz; + + // Accumulate all cells to SH + for (int x = 0; x < _OctahedralSize; x++) + { + for (int y = 0; y < _OctahedralSize; y++) + { + int2 TapCoord = pixCoord.xy * _OctahedralSize + uint2(x,y); + + // Load packed radiance data reservoir + uint2 RadianceDataPacked = asuint(H_LOAD(_ReservoirAtlasRadianceData, TapCoord).xy); + + // Unpack radiance and W + float3 ReservoirRadiance = UnpackTonemappedColor24bit(RadianceDataPacked.x); + float ReservoirW = f16tof32(RadianceDataPacked.y >> 16); + + // Calculate octahedral ray direction + float3 RayDirection = OrientedOctahedronToDirection((float2(x, y) + 0.5f) / float(_OctahedralSize), Normal); + + // Use reservoir ray direction instead (optional) + if (USE_RESERVOIR_RAY_DIRECTION) + { + uint2 RayDataPacked = asuint(H_LOAD(_ReservoirAtlasRayData, TapCoord).xy); + RayDirection = UnpackDirection24bit(RayDataPacked.x); + } + + // Add radiance to SH + AddSampleSH(CoefficientsSH, RayDirection, ReservoirRadiance * ReservoirW * 2.0f); + } + } + + // Normalize SH coefficients + CoefficientsSH.R.V0 /= float(_OctahedralSize * _OctahedralSize); + CoefficientsSH.R.V1 /= float(_OctahedralSize * _OctahedralSize); + CoefficientsSH.R.V2 /= float(_OctahedralSize * _OctahedralSize); + CoefficientsSH.G.V0 /= float(_OctahedralSize * _OctahedralSize); + CoefficientsSH.G.V1 /= float(_OctahedralSize * _OctahedralSize); + CoefficientsSH.G.V2 /= float(_OctahedralSize * _OctahedralSize); + CoefficientsSH.B.V0 /= float(_OctahedralSize * _OctahedralSize); + CoefficientsSH.B.V1 /= float(_OctahedralSize * _OctahedralSize); + CoefficientsSH.B.V2 /= float(_OctahedralSize * _OctahedralSize); + + // Pack SH coefficients + uint4 PackedSH_A, PackedSH_B; + PackInterpolationSH(PackedSH_A, PackedSH_B, CoefficientsSH); + + _PackedSH_A_Output[H_COORD(pixCoord.xy)] = PackedSH_A; + _PackedSH_B_Output[H_COORD(pixCoord.xy)] = PackedSH_B; +} + + +// ------------------------ INTERPOLATION KERNEL ------------------------ +[numthreads(8,8,1)] +void Interpolation(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint2 groupId : SV_GroupID) +{ + + + // Load center full-res depth + float DepthCenter = HBUFFER_DEPTH(pixCoord.xy); + + // Early-out on the skybox + if (DepthCenter <= 1e-7) + { + _Radiance_Output[H_COORD(pixCoord.xy)] = 0; + return; + } + + float2 pixCoordNDC = (pixCoord.xy + 0.5f) * _ScreenSize.zw; + int2 InterpolationCoord = pixCoord.xy; + + // Load and prepare other center full-res data + float DepthLinearCenter = H_LINEAR_EYE_DEPTH(DepthCenter); + float3 GeometryNormalCenter = H_LOAD(g_GeometryNormal, pixCoord.xy).xyz; + float3 WorldPosCenter = H_COMPUTE_POSITION_WS(pixCoordNDC, DepthCenter, H_MATRIX_I_VP); + float4 NormalPlane = float4(GeometryNormalCenter, dot(WorldPosCenter, GeometryNormalCenter)); + + // Get interpolation jitter to hide grid-like artifacts + float2 Jitter; + Jitter.x = GetBNDSequenceSample(pixCoord.xy, uint(_FrameCount) % 16, 7); + Jitter.y = GetBNDSequenceSample(pixCoord.xy, uint(_FrameCount) % 16, 8); + float2 InterpolationJitter = Jitter.xy * float(_ProbeSize); + // float2 InterpolationJitter = (Jitter.xy * 2 - 1 ) * float(_ProbeSize / 2); + + // Jitter interpolation coords and calculate jittered position at these coords + float2 JitteredCoord = pixCoord.xy + InterpolationJitter; + float3 JitteredWorldPos = H_COMPUTE_POSITION_WS((JitteredCoord + 0.5f) * _ScreenSize.zw, HBUFFER_DEPTH(JitteredCoord), H_MATRIX_I_VP); + + // Use the jittered position only if it's on the same plane with our initial positon + if (ProbePlaneWeighting(NormalPlane, JitteredWorldPos, H_LINEAR_EYE_DEPTH(DepthCenter), 10000.0f) > 0.01) + { + InterpolationCoord = JitteredCoord; + } + + float4 BentNormalsSSAO = 0; + float CosThetaSSAO = 0; + float CenterSSAO = 0; + + // Use bent normals and ssao to evaluate directional occlusion and assist interpolation + if (USE_DIRECTIONAL_OCCLUSION) + { + BentNormalsSSAO = H_LOAD(_BentNormalsAO, pixCoord.xy); + CosThetaSSAO = lerp(1.0f - BentNormalsSSAO.w, 1 - acos(sqrt(saturate(1.0f - BentNormalsSSAO.w))), 0.5); + CenterSSAO = BentNormalsSSAO.w; + } + + // Prepare 5x5 spatial offsets for interpolation search + int2 SampleOffsets[25] = {int2( 0, 0), int2( 0, 1), int2( 1, 0), int2( 1, 1), int2(-1, 0), int2(-1, 1), int2(-1, -1), int2( 0, -1), int2( 1, -1), + int2(-2, 0), int2( 0, -2), int2( 2, 0), int2( 0, 2), int2(-1, 2), int2(-2, 1), int2( 1, -2), int2( 2, -1), + int2(-2, -1), int2(-1, -2), int2( 2, 1), int2( 1, 2), int2(-2, 2), int2( 2, 2), int2( 2, -2), int2(-2, 2)}; + + // Initialize interpolation sample weights with zero + float SampleWeights[INTERPOLATION_SAMPLES]; + + for (int s = 0; s < INTERPOLATION_SAMPLES; s++) + { + SampleWeights[s] = 0; + } + + // Do the interpolation search + for (int i = 0; i < INTERPOLATION_SAMPLES; i++) + { + // Calculate sample coord + int2 TapCoord = floor(uint2(InterpolationCoord) / _ProbeSize) + SampleOffsets[i]; + + // Load sample low-res normal, depth & SSAO + uint2 ProbeOffset; + float4 NormalDepthSample = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, TapCoord)).xy, ProbeOffset); + + // Calculate low-res world position + float2 TapCoordNDC = (TapCoord * float(_ProbeSize) + float2(ProbeOffset) + 0.5f / float(_ProbeSize)) * _ScreenSize.zw; + float3 WorldPosSample = H_COMPUTE_POSITION_WS(TapCoordNDC, NormalDepthSample.w, H_MATRIX_I_VP); + + // Calculate spatial sample weights + float WeightPlane = ProbePlaneWeighting(NormalPlane, WorldPosSample, DepthLinearCenter, 10000); + float WeightNormal = saturate(dot(NormalDepthSample.xyz, GeometryNormalCenter)); + + float PixelDistanceWeight = distance(float2(pixCoord.xy), (float2(TapCoord * _ProbeSize) + float2(ProbeOffset))) / (float(_ProbeSize + _ProbeSize) - 1.0f); + PixelDistanceWeight = 1 - PixelDistanceWeight; + + // Combine all weights and store + SampleWeights[i] = WeightPlane * WeightNormal * PixelDistanceWeight; + + if (USE_DIRECTIONAL_OCCLUSION) + { + float SampleSSAO = H_LOAD(_ProbeSSAO, TapCoord).x; + float WeightSSAO = exp2(-20.0 * abs(pow(SampleSSAO, 2) - pow(CenterSSAO, 2))); + SampleWeights[i] *= WeightSSAO; + } + } + + // Stochastically pick one sample + int2 SelectedSampleOffset = 0; + float RandomValue = GetBNDSequenceSample(pixCoord.xy, uint(_FrameCount) % 16, 5); + + float WeightSumm = 0; + for (int t = 0; t < INTERPOLATION_SAMPLES; t++) + { + WeightSumm += SampleWeights[t]; + } + + RandomValue *= WeightSumm; + + UNITY_UNROLL + for (int k = INTERPOLATION_SAMPLES; k > 0; k--) + { + float WeightSumm = 0; + + UNITY_UNROLL + for (int j = 0; j < k - 1; j++) + { + WeightSumm += SampleWeights[j]; + } + + if (RandomValue >= WeightSumm) + { + SelectedSampleOffset = SampleOffsets[k - 1]; + break; + } + } + + // Select normal that will be used for interpolation + float3 InterpolationNormal = HBUFFER_NORMAL_WS(pixCoord.xy); + if (USE_DIRECTIONAL_OCCLUSION) + { + InterpolationNormal = BentNormalsSSAO.w > 0.8 ? lerp(BentNormalsSSAO.xyz, InterpolationNormal, BentNormalsSSAO.w) : BentNormalsSSAO.xyz; + } + + // Boost normal map details (be careful, it's just an approximation) + if (INTERPOLATION_NORMAL_BOOST > 1) + { + float3 NormalOriginal = InterpolationNormal; + float3 NormalDifference = NormalOriginal - GeometryNormalCenter; + + NormalDifference *= INTERPOLATION_NORMAL_BOOST; + InterpolationNormal = (NormalDifference + GeometryNormalCenter); + + if (dot(normalize(NormalDifference + GeometryNormalCenter), NormalOriginal) > 0.97) + InterpolationNormal = NormalOriginal; + + if (USE_DIRECTIONAL_OCCLUSION) + InterpolationNormal = lerp(NormalOriginal, InterpolationNormal, pow(BentNormalsSSAO.w, 3)); + } + + // Calculate final interpolation coord + InterpolationCoord = floor(uint2(InterpolationCoord) / _ProbeSize) + SelectedSampleOffset; + + // Bypass interpolation (for debug) + if (DISABLE_INTERPOLATION) + { + InterpolationCoord = floor(pixCoord.xy / _ProbeSize); + InterpolationNormal = UnpackNormal(asuint(H_LOAD(_ProbeNormalDepth, InterpolationCoord).xy)); + } + + // Load packed SH coefficients + uint4 PackedSH_A = asuint(H_LOAD(_PackedSH_A, InterpolationCoord)); + uint4 PackedSH_B = asuint(H_LOAD(_PackedSH_B, InterpolationCoord)); + + // Unpack SH coefficients + SH_L2_Color LightingSH; + UnpackInterpolationSH(PackedSH_A, PackedSH_B, LightingSH); + + // Evaluate SH coefficients to get the final lighting + float3 RadianceInterpolated = EvaluateSHIrradiance(InterpolationNormal.xyz, CosThetaSSAO, LightingSH); + + _Radiance_Output[H_COORD(pixCoord.xy)] = PackToR11G10B10A1f(RadianceInterpolated, WeightSumm > 0.01); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HInterpolation.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HInterpolation.compute.meta new file mode 100644 index 000000000..e741dc2b4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HInterpolation.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: a38055874f454a342bc27fc1d5517895 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HInterpolation.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HProbeAmbientOcclusion.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HProbeAmbientOcclusion.compute new file mode 100644 index 000000000..f04eab420 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HProbeAmbientOcclusion.compute @@ -0,0 +1,163 @@ +#pragma kernel ProbeAmbientOcclusion +#pragma kernel ProbeAmbientOcclusionSpatialFilter +#pragma kernel ProbeAmbientOcclusionHistoryUpdate + +#include "../Includes/Config.hlsl" +#include "../Includes/Reservoir.hlsl" +#include "../Includes/VoxelizationCommon.hlsl" +//#include "../Includes/VoxelTraversal.hlsl" + +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_RayDirection); +H_TEXTURE(_RayDistanceSS); +H_TEXTURE(_RayDistanceWS); +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(_ReprojectionWeights); +H_TEXTURE(_ProbeAmbientOcclusion); +H_TEXTURE(_PersistentReprojectionCoord); +H_TEXTURE_ARRAY(_ProbeAmbientOcclusion_History); + +H_TEXTURE_ARRAY(_SpatialWeightsPacked); +H_TEXTURE_ARRAY(_SpatialOffsetsPacked); + +H_RW_TEXTURE_ARRAY(uint, _ProbeAmbientOcclusion_ArrayOutput); +H_RW_TEXTURE(float, _ProbeAmbientOcclusion_OutputFiltered); +H_RW_TEXTURE(uint, _ProbeAmbientOcclusion_Output); + +// ------------------------ PROBE AMBIENT OCCLUSION GATHER & ACCUMULATION ------------------------ +[numthreads(8, 8, 1)] +void ProbeAmbientOcclusion(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) +{ + + + // Load probe normal, depth & offset + uint2 ProbeOffset; + float4 NormalDepth = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy)).xy, ProbeOffset); + float2 ProbeCoordNDC = (pixCoord.xy * _ProbeSize + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw; + float3 PositionWS = H_COMPUTE_POSITION_WS(ProbeCoordNDC.xy, NormalDepth.w, H_MATRIX_I_VP); + + float WeightGathered = 0; + float OcclusionGathered = 0; + float MaxClampDistance = PROBE_AO_CLAMP_DISTANCE; + + // Scale max + MaxClampDistance = lerp(MaxClampDistance * 0.1, MaxClampDistance, saturate(length(PositionWS) / 5.0f)); + + // Gather hit ray distance across all probe cells + for (int x = 0; x < _OctahedralSize; x++) + { + for (int y = 0; y < _OctahedralSize; y++) + { + int2 SampleCoord = pixCoord.xy * _OctahedralSize + uint2(x,y); + + // Load SS and WS hit distances and other data + bool TracedWorldRay, IsOutsideFrame; + float HitDistancWS = H_LOAD(_RayDistanceWS, SampleCoord).x; + float HitDistancSS = abs(UnpackHitDistance(asuint(H_LOAD(_RayDistanceSS, SampleCoord).x), IsOutsideFrame, TracedWorldRay)); + + // Out ambient occlusion sample is simply our WS hit distance in this case + float OcclusionSample = HitDistancWS; + + // We can discard too short WS rays to avoid darkening around the corners and behind objects + if (HitDistancWS <= _VoxelSize.x && TracedWorldRay) + { + OcclusionSample = IsOutsideFrame ? MaxClampDistance : OcclusionSample; + OcclusionSample = lerp(MaxClampDistance, OcclusionSample, saturate(length(PositionWS) / 1.0f)); + } + + // Clamp our sample to the maximum occlusion distance + OcclusionSample = clamp(OcclusionSample, 0, MaxClampDistance); + + // Calculate octahedral direction and get cosine weight for this sample + float3 RayDirection = OrientedOctahedronToDirection((float2(x, y) + 0.5f) / float(_OctahedralSize), NormalDepth.xyz); + float Weight = saturate(dot(RayDirection, NormalDepth.xyz)); + + // Of sample (distance) <= 0 - it means that it's a cell culled by checkerboarding + if (OcclusionSample > 0) + { + WeightGathered += MaxClampDistance * Weight; + OcclusionGathered += OcclusionSample * Weight; + } + } + } + + // Weighted average + OcclusionGathered = saturate(OcclusionGathered / WeightGathered); + + // Load reprojection coords and weights and normalize them + uint ReprojectionIndex; + float4 ReprojectionWeights = H_LOAD(_ReprojectionWeights, pixCoord.xy); + int2 ReprojectionCoordPacked = asuint(H_LOAD(_PersistentReprojectionCoord, pixCoord.xy).xy); + int2 ReprojectionCoord = UnpackPersistentReprojectionCoord(ReprojectionCoordPacked, ReprojectionIndex); + + // Normalize reprojection weights + float WeightsSumm = max(ReprojectionWeights.x + ReprojectionWeights.y + ReprojectionWeights.z + ReprojectionWeights.w, 1.0e-3); + ReprojectionWeights /= WeightsSumm; + + // Load packed occlusion history samples + uint OcclusionHistoryPacked00 = asuint(H_LOAD_ARRAY(_ProbeAmbientOcclusion_History, ReprojectionCoord + uint2(0, 0), GetHistoryIndex(ReprojectionIndex)).x); + uint OcclusionHistoryPacked01 = asuint(H_LOAD_ARRAY(_ProbeAmbientOcclusion_History, ReprojectionCoord + uint2(1, 0), GetHistoryIndex(ReprojectionIndex)).x); + uint OcclusionHistoryPacked10 = asuint(H_LOAD_ARRAY(_ProbeAmbientOcclusion_History, ReprojectionCoord + uint2(0, 1), GetHistoryIndex(ReprojectionIndex)).x); + uint OcclusionHistoryPacked11 = asuint(H_LOAD_ARRAY(_ProbeAmbientOcclusion_History, ReprojectionCoord + uint2(1, 1), GetHistoryIndex(ReprojectionIndex)).x); + + // Unpack occlusion history (.x channel) and its samplecount (.y channel) + float2 OcclusionHistory00 = UnpackProbeAO(OcclusionHistoryPacked00, PROBE_AO_MAX_TEMPORAL_SAMPLES) * ReprojectionWeights.xx; + float2 OcclusionHistory01 = UnpackProbeAO(OcclusionHistoryPacked01, PROBE_AO_MAX_TEMPORAL_SAMPLES) * ReprojectionWeights.yy; + float2 OcclusionHistory10 = UnpackProbeAO(OcclusionHistoryPacked10, PROBE_AO_MAX_TEMPORAL_SAMPLES) * ReprojectionWeights.zz; + float2 OcclusionHistory11 = UnpackProbeAO(OcclusionHistoryPacked11, PROBE_AO_MAX_TEMPORAL_SAMPLES) * ReprojectionWeights.ww; + + // Combine bilinear samples + float2 OcclusionHistoryReprojected = OcclusionHistory00 + OcclusionHistory01 + OcclusionHistory10 + OcclusionHistory11; + + // Temporally accumulate + float SampleCount = min(PROBE_AO_MAX_TEMPORAL_SAMPLES, OcclusionHistoryReprojected.y + 1); + OcclusionGathered = lerp(OcclusionGathered, OcclusionHistoryReprojected.x, 1.0f - (1.0f / float(SampleCount))); + + // Output + _ProbeAmbientOcclusion_Output[H_COORD(pixCoord.xy)] = PackProbeAO(OcclusionGathered, SampleCount, PROBE_AO_MAX_TEMPORAL_SAMPLES); +} + + +// ------------------------ PROBE AMBIENT OCCLUSION SPATIAL FILTER ------------------------ +[numthreads(8, 8, 1)] +void ProbeAmbientOcclusionSpatialFilter(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + + // Load packed sample weights and coords + float SampleWeights[8]; int2 SampleOffsets[8]; + uint4 PackedSampleOffsets = asuint(H_LOAD_ARRAY(_SpatialOffsetsPacked, pixCoord.xy, 0)); + uint4 PackedSampleWeights = asuint(H_LOAD_ARRAY(_SpatialWeightsPacked, pixCoord.xy, 0)); + + // Unpack sample weights and coords + UnpackFilteringOffsetsX8(PackedSampleOffsets, SampleOffsets); + UnpackFilteringWeightsX8(PackedSampleWeights, SampleWeights); + + // Unpack center occlusion and samplecount + uint ProbeAmbientOcclusionPacked = asuint(H_LOAD(_ProbeAmbientOcclusion, pixCoord.xy).x); + float2 ProbeAmbientOcclusion = UnpackProbeAO(ProbeAmbientOcclusionPacked, PROBE_AO_MAX_TEMPORAL_SAMPLES); + + // Scale filter weight based on the accumulated samplecount + float SpatialWeight = ProbeAmbientOcclusion.y == PROBE_AO_MAX_TEMPORAL_SAMPLES ? 0 : lerp(1, 0, 1.0f - (1.0f / float(ProbeAmbientOcclusion.y))); + + float AccumulatedWeight = 1; + for (int i = 0; i < 8; i++) + { + uint ProbeAmbientOcclusionSamplePacked = asuint(H_LOAD(_ProbeAmbientOcclusion, pixCoord.xy + SampleOffsets[i]).x); + + AccumulatedWeight += SampleWeights[i] * SpatialWeight; + ProbeAmbientOcclusion.x += UnpackProbeAO(ProbeAmbientOcclusionSamplePacked, 0).x * SampleWeights[i] * SpatialWeight; + } + + _ProbeAmbientOcclusion_OutputFiltered[H_COORD(pixCoord.xy)] = ProbeAmbientOcclusion.x / AccumulatedWeight; +} + + +// ------------------------ PROBE AMBIENT OCCLUSION HISTORY UPDATE ------------------------ +[numthreads(8, 8, 1)] +void ProbeAmbientOcclusionHistoryUpdate(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + _ProbeAmbientOcclusion_ArrayOutput[uint3(pixCoord.xy, H_INDEX_ARRAY(uint(_FrameCount) % _PersistentHistorySamples))] = asuint(H_LOAD(_ProbeAmbientOcclusion, pixCoord.xy).x); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HProbeAmbientOcclusion.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HProbeAmbientOcclusion.compute.meta new file mode 100644 index 000000000..7de15d721 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HProbeAmbientOcclusion.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: dbaeb07454d061d4587d648190df361d +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HProbeAmbientOcclusion.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRadianceCache.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRadianceCache.compute new file mode 100644 index 000000000..7adcbf1e6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRadianceCache.compute @@ -0,0 +1,396 @@ +#pragma kernel CacheDataUpdate +#pragma kernel CachePrimarySpawn +#pragma kernel CacheTracingUpdate +#pragma kernel CacheLightEvaluation +#pragma kernel CacheDataClear + +#pragma multi_compile _ EVALUATE_PUNCTUAL_LIGHTS +#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS + +#include "../Includes/Config.hlsl" +#include "../Includes/VoxelTraversal.hlsl" +#include "../Includes/SpatialHash.hlsl" +#include "../Includes/VoxelLightingEvaluation.hlsl" +#include "../Includes/SpatialFilteringFunctions.hlsl" +#include "../Includes/ScreenProbesCommon.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_ReprojectionCoords); +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(g_GeometryNormal); +H_TEXTURE(_RadianceAtlas); + +H_RW_TEXTURE3D(float3, _RadianceCacheFiltered_Output); + +float _RayLength; + +uint _HashUpdateFrameIndex; +int _FreezeCache; + + +// ------------------------ FUNCTIONS -------------------------- +float3 AccumulateCache(float3 RadianceCurr, float3 RadiancePrev, float Min, float Max) +{ + if (!ADAPTIVE_TEMPORAL_WEIGHT) + return lerp(RadianceCurr, RadiancePrev, Max); + + float LumaCurr = Luminance(RadianceCurr / min(HGetInverseCurrentExposureMultiplier, 5.0f)); + float LumaPrev = Luminance(RadiancePrev / min(HGetInverseCurrentExposureMultiplier, 5.0f)); + + float Difference = abs(LumaCurr - LumaPrev) / max(LumaCurr, max(LumaPrev, 0.2f)); + float Weight = 1.0 - Difference; + float Feedback = lerp(Max, Min, Weight * Weight); + + return lerp(RadianceCurr, RadiancePrev, Feedback); +} + + +// ------------------------ CACHE SPAWN & UPDATE ON PRIMARY SURFACES -------------------------- +[numthreads(8, 8, 1)] +void CachePrimarySpawn(uint3 pixCoord : SV_DispatchThreadID) +{ + // We jitter pixel every frame to cover full frame over time + float2 Jitter; + Jitter.x = GetBNDSequenceSample(pixCoord.xy, uint(_FrameCount) % 36, 3); + Jitter.y = GetBNDSequenceSample(pixCoord.xy, uint(_FrameCount) % 36, 4); + float2 PixelJitter = Jitter.xy * float(_ProbeSize); + + uint2 ProbeOffset; + float4 NormalDepth = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy).xy), ProbeOffset); + float3 WorldPos = H_COMPUTE_POSITION_WS((pixCoord.xy * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw, NormalDepth.w, H_MATRIX_I_VP); + float4 NormalPlane = float4(NormalDepth.xyz, dot(WorldPos, NormalDepth.xyz)); + + float3 NormalJittered = H_LOAD(g_GeometryNormal, pixCoord.xy * _ProbeSize + PixelJitter).xyz; + float DepthJitterd = HBUFFER_DEPTH(pixCoord.xy * _ProbeSize + PixelJitter); + float3 WorldPosJittered = H_COMPUTE_POSITION_WS((pixCoord.xy * float(_ProbeSize) + float2(PixelJitter) + 0.5f) * _ScreenSize.zw, DepthJitterd, H_MATRIX_I_VP); + + // Use the jittered position only if it's on the same plane with our initial positon + if (ProbePlaneWeighting(NormalPlane, WorldPosJittered, H_LINEAR_EYE_DEPTH(NormalDepth.w), 1000.0f) > 0.01) + { + NormalDepth.xyz = NormalJittered; + NormalDepth.w = DepthJitterd; + WorldPos = WorldPosJittered; + } + + // Early out on skybox + if (NormalDepth.w <= 1e-7) + return; + + float4 CacheRadiance = 0; + + // Gather radiance and evaluate temporal invalidity acrosss an octahedral screen probe + for (int x = 0; x < _OctahedralSize; x++) + { + for (int y = 0; y < _OctahedralSize; y++) + { + uint2 TapCoord = pixCoord.xy * _OctahedralSize + uint2(x,y); + + // Calculate average ray direction for this octahedral cell + float3 RayDirection = OrientedOctahedronToDirection((float2(x, y) + 0.5f) / float(_OctahedralSize), NormalDepth.xyz); + + float4 RadianceSample = H_LOAD(_RadianceAtlas, TapCoord) * 2.0f * saturate(dot(RayDirection, NormalDepth.xyz)); + + if (RadianceSample.w > 0) + CacheRadiance += float4(RadianceSample.xyz, 1); + } + } + + // Average cache radiance + if (CacheRadiance.w > 0) + CacheRadiance.xyz /= CacheRadiance.w; + + if (AnyIsNaN(CacheRadiance) || AnyIsInf(CacheRadiance)) + CacheRadiance = 0; + + // Calculate cache coords from visible world space position of the primary surface + float3 AbsolutePositionWS = H_GET_ABSOLUTE_POSITION_WS(WorldPos); + int3 HitCoord = floor((AbsolutePositionWS) * _VoxelPerMeter) + (_VoxelResolution.xzy / 2.0f); + int3 VoxelSpans = floor(HitCoord / (_VoxelResolution.xzy)); + int3 CacheCoord = HitCoord - (VoxelSpans * _VoxelResolution.xzy); + + int3 VoxelCoordAbsolute = floor((AbsolutePositionWS) * _VoxelPerMeter); + float3 VoxelHitOffset = float3(VoxelCoordAbsolute) * _VoxelSize - AbsolutePositionWS; + + // Evaluate spatial hash + if (!FREEZE_CACHE) + { + uint HashKey = PackHashKey(CacheCoord, NormalDepth.xyz); + + bool IsEmpty; + uint HashRank = 3; + uint HashProbingIndex, HashLowestRankIndex; + uint HashIndex = HashGetIndex(CacheCoord, PackVoxelNormalIndex(NormalDepth.xyz)); + bool HashFound = HashFindAny(HashIndex, HashKey, HashRank, HashLowestRankIndex, HashProbingIndex, IsEmpty); + + if (HashFound) + { + // Load packed radiance cache + uint3 RadiancePacked = _HashBuffer_Radiance[HashProbingIndex].xyz; + + // Unpack both near and full caches + float3 CacheRadianceFull = UnpackCacheRadianceFull(RadiancePacked.xyz); + float3 CacheRadianceNear = UnpackCacheRadianceNear(RadiancePacked.xyz); + + // Accumulate to full range radiance cache + CacheRadianceFull = AccumulateCache(CacheRadiance.xyz, CacheRadianceFull, 0.83f, 0.93f); + + _HashBuffer_Radiance[HashProbingIndex] = uint4(PackCacheRadiance(CacheRadianceFull, CacheRadianceNear), 0); + _HashBuffer_Counter[HashProbingIndex] = 255; + _HashBuffer_Key[HashProbingIndex] = HashKey | 0x3; + } + else if (IsEmpty) // If we didn't find a valid entry but found an empty cell, we spawn a new entry with radiance in it + { + _HashBuffer_Position[HashProbingIndex] = uint4(asuint(VoxelCoordAbsolute.xyz), PackHitOffset(VoxelHitOffset)); + _HashBuffer_Radiance[HashProbingIndex] = 0; //uint4(PackCacheRadiance(CacheRadiance, 0), 0); + _HashBuffer_Counter[HashProbingIndex] = 255; + _HashBuffer_Key[HashProbingIndex] = HashKey | 0x3; + } + else if (HashRank != 3) // If neither a valid nor an empty entry was found, we recycle the lowest ranked cell to spawn a new entry with radiance in it + { + _HashBuffer_Position[HashLowestRankIndex] = uint4(asuint(VoxelCoordAbsolute.xyz), PackHitOffset(VoxelHitOffset)); + _HashBuffer_Radiance[HashLowestRankIndex] = 0; //uint4(PackCacheRadiance(CacheRadiance, 0), 0); + _HashBuffer_Counter[HashLowestRankIndex] = 255; + _HashBuffer_Key[HashLowestRankIndex] = HashKey | 0x3; + } + } +} + + +// ------------------------ CACHE TRACING UPDATE -------------------------- +[numthreads(64, 1, 1)] +void CacheTracingUpdate(uint dispatchThreadId : SV_DispatchThreadID) +{ + uint PayloadIndex = dispatchThreadId.x; + + // Offset index to process a new section of the hash + dispatchThreadId.x = dispatchThreadId.x + ((_HashUpdateFrameIndex % _HashUpdateFraction) * (_HashStorageSize / _HashUpdateFraction)); + + // Read our hash key + uint HashKey = _HashBuffer_Key[dispatchThreadId.x]; + + // Extract hash rank from hash key + int HashRank = HashKey & 0x3; + HashKey = HashKey & 0xFFFFFFFC; + + // If hash key is 0 - it's an empty hash cell and we can early out + if (HashKey == 0 || FREEZE_CACHE) + { + _HashBuffer_Payload[PayloadIndex] = 0u; + return; + } + + // Unpack ray coord and normal from hash key + uint3 HitCoord = UnpackHitCoordFromHashKey(HashKey); + float3 HitNormal = UnpackHitNormalFromHashKey(HashKey); + + // Pick coordinates for random generator based on the normal + float3 HitNormalAbs = abs(HitNormal); + float HitNormalMax = max(max(HitNormalAbs.x, HitNormalAbs.y), HitNormalAbs.z); + + // Swizzle coordinates for ray jitter based on the dominant normal + uint2 HitRandomCoord = 0; + if (HitNormalMax == HitNormalAbs.x) + HitRandomCoord = HitCoord.yz; + if (HitNormalMax == HitNormalAbs.y) + HitRandomCoord = HitCoord.xz; + if (HitNormalMax == HitNormalAbs.z) + HitRandomCoord = HitCoord.xy; + + // Generate random ray jitter + float2 RayJitter; + RayJitter.x = GetBNDSequenceSample(HitRandomCoord, _FrameCount, 4); + RayJitter.y = GetBNDSequenceSample(HitRandomCoord, _FrameCount, 5); + + // Calculate hash cell tracing position + uint4 HashPositionPacked = _HashBuffer_Position[dispatchThreadId.x].xyzw; + float3 RayOrigin = asint(HashPositionPacked.xyz) * _VoxelSize; + // RayOrigin += UnpackHitOffset(HashPositionPacked.w); + RayOrigin += 0.5 * _VoxelSize; + + // Generate new ray direction + float3 RayDirection = HSampleHemisphereCosine(RayJitter.x, RayJitter.y, HitNormal); + + // Apply ray bias + RayOrigin += RayDirection * _VoxelSize * 0.5f; + RayOrigin += HitNormal * _VoxelSize * 0.5f; //(0.6f * (1.0f - max(0.0f, dot(RayDirection, HitNormal)))); + + // Initialize voxel ray payload + VoxelPayload Payload; + InitializePayload(Payload); + + // Calculate ray distance + float MaxRayDistance = MaxVoxelRayDistance(RayOrigin, RayDirection); + float RayDistance = _RayLength == 0 ? MaxRayDistance : _RayLength; + + // Trace into voxels + bool HitFound = TraceVoxelsDiffuse(RayOrigin, RayDirection, RayDistance, 128, Payload); + + // Evaluate sky occlusion + float SkyOcclusion = HitFound ? 1 : EvaluateDirectionalShadowOcclusion(RayOrigin + MaxRayDistance * RayDirection); + + // Set hit flag (HitFound & short distance for near field split, !HitFound and direction up for skybox read) + bool HitFlag = false; + if (HitFound) HitFlag = (Payload.HitDistance < _VoxelSize.x * 4) ? true : false; + if (!HitFound) HitFlag = (dot(float3(0,1,0), RayDirection) > _SkyOcclusionCone + 0.05f) ? true : false; + + // Pack and write cache payload + float3 VoxelHitOffset = VoxelCoordToAbsoluteWorldPosition(Payload.HitCoord) - Payload.HitPosition; + _HashBuffer_Payload[PayloadIndex] = PackCacheHitPayload(VoxelHitOffset, RayDirection, Payload.HitNormal, Payload.HitCoord, SkyOcclusion, HashRank, HitFound, HitFlag); +} + + +// ------------------------ CACHE LIGHT EVALUATION -------------------------- +[numthreads(64, 1, 1)] +void CacheLightEvaluation(uint dispatchThreadId : SV_DispatchThreadID) +{ + uint WriteIndex = dispatchThreadId.x + ((_HashUpdateFrameIndex % _HashUpdateFraction) * (_HashStorageSize / _HashUpdateFraction)); + + // Read packed cache payload + uint2 CachePayloadPacked = _HashBuffer_Payload[dispatchThreadId.x]; + + // If payload is 0 - it's an empty hash cell and we can early out + if (CachePayloadPacked.y == 0 || FREEZE_CACHE) + return; + + // Initialize voxel payload + VoxelPayload Payload; + InitializePayload(Payload); + + // Unpack cache payload + float3 RayDirection; float3 HitOffset; float SkyOcclusion; uint HashRank; bool HitFlag; + bool HitFound = UnpackCacheHitPayload(CachePayloadPacked, RayDirection, HitOffset, Payload.HitNormal, Payload.HitCoord, SkyOcclusion, HashRank, HitFlag); + + // Calculate hit position + Payload.HitPosition = VoxelCoordToAbsoluteWorldPosition(Payload.HitCoord) + HitOffset; + + // This is our cached radiance that we aim to update + uint3 RadiancePacked = _HashBuffer_Radiance[WriteIndex].xyz; + + // Deal with hash at the hit point + if (HitFound) + { + uint3 HitCacheCoord = ComputeRadianceCacheCoord(Payload.HitCoord); + uint HitHashKey = PackHashKey(HitCacheCoord, Payload.HitNormal); ; + + bool IsEmpty; + uint HitHashRank = HashRank; + uint HashProbingIndex, HashLowestRankIndex; + uint HashIndex = HashGetIndex(HitCacheCoord, PackVoxelNormalIndex(Payload.HitNormal)); + bool HashFound = HashFindAny(HashIndex, HitHashKey, HitHashRank, HashLowestRankIndex, HashProbingIndex, IsEmpty); + + int3 VoxelCoordAbsolute = VoxelCoordToAbsoluteVoxelCoord(Payload.HitCoord); + float3 VoxelHitOffset = (float3(VoxelCoordAbsolute) * _VoxelSize) - Payload.HitPosition; + + if (HashFound) // If a valid entry was found we use it to add cache to our ray origin radiance cell + { + Payload.HitCache = UnpackCacheRadianceFull(_HashBuffer_Radiance[HashProbingIndex].xyz); + } + else if (IsEmpty) // && HashRank > 0) // If we didn't find a valid entry but found an empty cell, we spawn a new entry + { + _HashBuffer_Position[HashProbingIndex] = uint4(asuint(VoxelCoordAbsolute.xyz), PackHitOffset(VoxelHitOffset)); + _HashBuffer_Radiance[HashProbingIndex] = 0; + _HashBuffer_Counter[HashProbingIndex] = 255; + _HashBuffer_Key[HashProbingIndex] = HitHashKey | max(0, HashRank - 1); + } + else if (HitHashRank != HashRank) // && HashRank > 0) // If neither a valid nor an empty entry was found, we recycle the lowest ranked cell to spawn a new entry + { + _HashBuffer_Position[HashLowestRankIndex] = uint4(asuint(VoxelCoordAbsolute.xyz), PackHitOffset(VoxelHitOffset)); + _HashBuffer_Radiance[HashLowestRankIndex] = 0; + _HashBuffer_Counter[HashLowestRankIndex] = 255; + _HashBuffer_Key[HashLowestRankIndex] = HitHashKey | max(0, HashRank - 1); + } + } + + // Evaluate lighting at hit point + bool DirectLightingHit = true; + if (HitFound) + DirectLightingHit = EvaluateHitLighting(Payload); + + // Evaluate sky lighting if missed + if (!HitFound && HitFlag) + Payload.HitColor += EvaluateSky(RayDirection) * SkyOcclusion; + + // Unpack both near and full caches + float3 CacheRadianceFull = UnpackCacheRadianceFull(RadiancePacked.xyz); + float3 CacheRadianceNear = UnpackCacheRadianceNear(RadiancePacked.xyz); + + // Clip cache + Payload.HitCache *= HGetCurrentExposureMultiplier; + Payload.HitCache = HClipRadiance(Payload.HitCache, 10); + Payload.HitCache *= HGetInverseCurrentExposureMultiplier; + + // Add cache + Payload.HitColor += Payload.HitCache * Payload.HitDiffuse; + + // Accumulate to full range radiance cache + CacheRadianceFull = AccumulateCache(Payload.HitColor, CacheRadianceFull, MIN_TEMPORAL_WEIGHT, MAX_TEMPORAL_WEIGHT); + + // Accumulate to near range radiance cache + if (!DirectLightingHit || (!HitFound && HitFlag)) + CacheRadianceNear = AccumulateCache(Payload.HitColor, CacheRadianceNear, 0.3f, 0.90f); + + // Write updated cache + _HashBuffer_Radiance[WriteIndex] = uint4(PackCacheRadiance(CacheRadianceFull, CacheRadianceNear), 0); +} + + +// ------------------------ CACHE DATA UPDATE -------------------------- +[numthreads(64, 1, 1)] +void CacheDataUpdate(uint dispatchThreadId : SV_DispatchThreadID) +{ + if (FREEZE_CACHE) + return; + + // Load position buffer + float3 AbsoluteVoxelPosition = asint(_HashBuffer_Position[dispatchThreadId.x].xyz) * _VoxelSize - _VoxelCameraPos.xyz; + + // Calculate voxel coord from position + int3 VoxelCoord = AbsoluteWorldPositionToVoxelCoord(AbsoluteVoxelPosition); + + // If position.xyz is 0 - it's an empty hash cell and we can early out + if (AbsoluteVoxelPosition.x + AbsoluteVoxelPosition.y + AbsoluteVoxelPosition.z == 0) + return; + + // Use "VoxelOccupancy == 0" below to deallocate hash cells on moving objects. This has a perfromance impact. + uint VoxelOccupancy = H_LOAD3D_LOD(_VoxelPositionPyramid, VoxelCoord, 0); + + // Clear the cell in all hash buffers if its position is outside bounds and early out + if (!IsVoxelCoordInBounds(VoxelCoord) || VoxelOccupancy == 0 ) + { + _HashBuffer_Radiance[dispatchThreadId.x] = 0; + _HashBuffer_Position[dispatchThreadId.x] = 0; + _HashBuffer_Counter[dispatchThreadId.x] = 0; + _HashBuffer_Key[dispatchThreadId.x] = 0; + return; + } + + // Load other hash bufffers + uint HashKey = _HashBuffer_Key[dispatchThreadId.x]; + + // Unpack and decrement decay counter + int DecayCounter = _HashBuffer_Counter[dispatchThreadId.x]; + DecayCounter = max(0, DecayCounter - 1); + + // If the cache entry is old enough - lower its rank + if (DecayCounter <= 200) + { + int Rank = HashKey & 0x3; // Must keep it as int + + // Lower cache rank + _HashBuffer_Key[dispatchThreadId.x] = (HashKey & 0xFFFFFFFC) | max(0, Rank - 1); + } + + // Update decay counter + _HashBuffer_Counter[dispatchThreadId.x] = DecayCounter; +} + + +// ------------------------ CACHE DATA CLEAR -------------------------- +[numthreads(64, 1, 1)] +void CacheDataClear(uint dispatchThreadId : SV_DispatchThreadID) +{ + _HashBuffer_Radiance[dispatchThreadId.x] = 0; + _HashBuffer_Position[dispatchThreadId.x] = 0; + _HashBuffer_Counter[dispatchThreadId.x] = 0; + _HashBuffer_Key[dispatchThreadId.x] = 0; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRadianceCache.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRadianceCache.compute.meta new file mode 100644 index 000000000..19836c80e --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRadianceCache.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 41218a2257905b649ab7793dc12019d4 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRadianceCache.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRayGeneration.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRayGeneration.compute new file mode 100644 index 000000000..ec15c111e --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRayGeneration.compute @@ -0,0 +1,144 @@ +#pragma kernel RayGeneration +#pragma kernel RayCompaction +#pragma kernel IndirectArguments + +#include "../Includes/Config.hlsl" +#include "../Includes/Reservoir.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_HitDistance); +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(_ReprojectionCoords); + +H_RW_TEXTURE(float, _HitDistance_Output); +H_RW_TEXTURE(float4, _RayDirectionsJittered_Output); + +RWStructuredBuffer _RayCounter; +RWStructuredBuffer _TracingCoords; + +RWStructuredBuffer _RayCounter_Output; +RWStructuredBuffer _TracingRayCounter_Output; +RWStructuredBuffer _IndirectArguments_Output; + +RWStructuredBuffer _TracingCoords_Output; +RWStructuredBuffer _IndirectCoordsSS_Output; +RWStructuredBuffer _IndirectCoordsOV_Output; +RWStructuredBuffer _IndirectCoordsSF_Output; + +int _IndexXR; +int _HFrameIndex; +uint _RayCounterIndex; +uint _ReprojectSkippedFrame; + + +// ------------------------ RAY COMPACTION ------------------------- +[numthreads(8, 8, 1)] +void RayCompaction(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + uint ArrayOffsetXR = _ScreenSize.x * _ScreenSize.y; + + uint RayIndex = groupID * 64 + groupIndex; + if (RayIndex >= _RayCounter[0 + 4 + 10 * _IndexXR]) + return; + + pixCoord.xy = _TracingCoords[RayIndex + ArrayOffsetXR * _IndexXR]; + + bool Unused, TraceWorldRay; + uint HitDistancePacked = asuint(H_LOAD(_HitDistance, pixCoord.xy).x); + float HitDistance = UnpackHitDistance(HitDistancePacked, Unused, TraceWorldRay); + + if (TraceWorldRay) + { + uint Index = 0; + InterlockedAdd(_TracingRayCounter_Output[0 + 10 * _IndexXR], 1, Index); + _TracingCoords_Output[Index + ArrayOffsetXR * _IndexXR] = pixCoord.xy; + } + + _HitDistance_Output[H_COORD(pixCoord.xy)] = HitDistance; +} + + +// ------------------------ INDIRECT ARGUMENTS GENERATION ------------------------- +[numthreads(1, 1, 1)] +void IndirectArguments(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint2 groupID : SV_GroupID) +{ + + uint IndirectArgumentsOffsetVR = 3 * pixCoord.z; + uint RayCounterOffsetVR = 10 * pixCoord.z; + + uint RayCounterBuffer = _RayCounter[_RayCounterIndex + RayCounterOffsetVR]; + + _IndirectArguments_Output[0 + IndirectArgumentsOffsetVR] = (RayCounterBuffer + 63) / 64; + _IndirectArguments_Output[1 + IndirectArgumentsOffsetVR] = 1; + _IndirectArguments_Output[2 + IndirectArgumentsOffsetVR] = 1; + + _RayCounter[_RayCounterIndex + 0 + RayCounterOffsetVR] = 0; + _RayCounter[_RayCounterIndex + 4 + RayCounterOffsetVR] = RayCounterBuffer; +} + + +// ------------------------ RAY GENERATION ------------------------- +[numthreads(8, 8, 1)] +void RayGeneration(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint2 groupID : SV_GroupID) +{ + + uint IndirectCoordOffsetVR = _ScreenSize.x * _ScreenSize.y * pixCoord.z; + uint RayCounterOffsetVR = 10 * pixCoord.z; + + // Calculate probe and cell coord + uint2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + float2 CellCoord = pixCoord.xy - floor(pixCoord.xy / _OctahedralSize) * _OctahedralSize; + + // Load depth and normal + uint2 Unused; + float4 NormalDepth = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, ProbeCoord).xy), Unused); + + // Early out on the skybox + if (NormalDepth.w <= 1e-7) + return; + + // Generate ray jitter for tracing direction + float2 RayJitter; + RayJitter.x = GetBNDSequenceSample(pixCoord.xy, _HFrameIndex, 0); + RayJitter.y = GetBNDSequenceSample(pixCoord.xy, _HFrameIndex, 1); + + // Calculate jittered ray direction for the octahedral cell + float3 OctahedralDirectionJittered = OrientedOctahedronToDirection(float2(CellCoord + RayJitter) / float(_OctahedralSize), NormalDepth.xyz); + + uint2 BestOffset; bool ReprojectionFailed; + uint2 ReprojectionCoordPacked = asuint(H_LOAD(_ReprojectionCoords, ProbeCoord).xy); + uint2 ReprojectionCoord = UnpackBestReprojectionCoord(ReprojectionCoordPacked, BestOffset, ReprojectionFailed); + + bool CullCheckerboard = false; + if (((pixCoord.x + pixCoord.y) % 2 == 0 && uint(_FrameCount) % 2 == 0) || ReprojectionFailed) + CullCheckerboard = true; + if (((pixCoord.x + pixCoord.y) % 2 != 0 && uint(_FrameCount) % 2 != 0) || ReprojectionFailed) + CullCheckerboard = true; + + // Tracing indirection + if (CullCheckerboard) + { + uint Index = 0; + InterlockedAdd(_RayCounter_Output[0 + RayCounterOffsetVR], 1, Index); + _IndirectCoordsSS_Output[Index + IndirectCoordOffsetVR] = pixCoord.xy; + } + + // Occlusion validation indirection + if (CullCheckerboard) + { + uint Index = 0; + InterlockedAdd(_RayCounter_Output[1 + RayCounterOffsetVR], 1, Index); + _IndirectCoordsOV_Output[Index + IndirectCoordOffsetVR] = pixCoord.xy; + } + + // Spatial filer indirection + if (ReprojectionFailed) + { + uint Index = 0; + InterlockedAdd(_RayCounter_Output[2 + RayCounterOffsetVR], 1, Index); + _IndirectCoordsSF_Output[Index + IndirectCoordOffsetVR] = pixCoord.xy; + } + + // Output jittered ray directions + _RayDirectionsJittered_Output[H_COORD(pixCoord.xy)] = float4(OctahedralDirectionJittered * 0.5f + 0.5f, 1); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRayGeneration.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRayGeneration.compute.meta new file mode 100644 index 000000000..e0e7f5db4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRayGeneration.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: c8024557b4b500549ba603a5cf9cc018 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRayGeneration.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReSTIR.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReSTIR.compute new file mode 100644 index 000000000..6455682d8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReSTIR.compute @@ -0,0 +1,422 @@ +#pragma kernel ProbeAtlasTemporalReuse +#pragma kernel ProbeAtlasSpatialReuse +#pragma kernel ProbeAtlasSpatialReuseDisocclusion +#pragma kernel ReservoirHistoryUpdate + +#include "../Includes/Config.hlsl" +#include "../Includes/Reservoir.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_ShadowGuidanceMask); +H_TEXTURE(_ReprojectionCoords); + +H_TEXTURE(_SampleCount); +H_TEXTURE(_RayDistance); +H_TEXTURE(_RayDirection); +H_TEXTURE(_RadianceAtlas); +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(_ReprojectionWeights); +H_TEXTURE(_PersistentReprojectionCoord); + +H_TEXTURE_ARRAY(_SpatialWeightsPacked); +H_TEXTURE_ARRAY(_SpatialOffsetsPacked); + +H_RW_TEXTURE(float, _ShadowGuidanceMaskTest_Output); + +RWStructuredBuffer _TracingCoords; +RWStructuredBuffer _RayCounter; + +int _IndexXR; +int _PassNumber; +int _DisocclusionPass; + + +// ------------------------ PROBE ATLAS TEMPORAL REUSE ------------------------ +[numthreads(8, 8, 1)] +void ProbeAtlasTemporalReuse(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + + // Calculate probe coords + int2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + int2 CellCoord = pixCoord.xy - floor(pixCoord.xy / _OctahedralSize) * _OctahedralSize; + + // Load and clip center radiance + bool Unused; + float3 Radiance = H_LOAD(_RadianceAtlas, pixCoord.xy).xyz; // UnpackFromR11G10B10A1f(asuint(H_LOAD(_RadianceAtlas, pixCoord.xy)), Unused); + Radiance *= HGetCurrentExposureMultiplier; + Radiance = HClipRadiance(Radiance, 10.0f); + + // Load reprojection coords and weights and normalize them + uint ReprojectionIndex; + float4 ReprojectionWeights = H_LOAD(_ReprojectionWeights, ProbeCoord); + int2 ReprojectionCoordPacked = asuint(H_LOAD(_PersistentReprojectionCoord, ProbeCoord).xy); + int2 ReprojectionCoord = UnpackPersistentReprojectionCoord(ReprojectionCoordPacked, ReprojectionIndex); + + // Normalize reprojection weights + float WeightsSumm = max(ReprojectionWeights.x + ReprojectionWeights.y + ReprojectionWeights.z + ReprojectionWeights.w, 1.0e-3); + ReprojectionWeights /= WeightsSumm; + + uint2 ProbeOffset; + float3 RayOriginNormal = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, ProbeCoord).xy), ProbeOffset).xyz; + + // Prepare diffuse and random values for reservoir exchange + float3 Diffuse = GetReservoirDiffuse(ProbeCoord); + uint ReservoirUpdateRandom = Hash3(uint3(pixCoord.xy, _FrameCount)); + + // Initialize and fill main reservoir + Reservoir Reservoir; + ReservoirInitialize(pixCoord.xy, Reservoir); + + Reservoir.Radiance.Color = Radiance; + Reservoir.Radiance.Wsum = Luminance(Radiance * Diffuse); + Reservoir.Radiance.W = 0; + Reservoir.Radiance.M = 1; + + Reservoir.Ray.OriginNormal = RayOriginNormal; + Reservoir.Ray.Direction = H_LOAD(_RayDirection, pixCoord.xy).xyz * 2 - 1; + Reservoir.Ray.Distance = H_LOAD(_RayDistance, pixCoord.xy).x; + + float ReservoirHistoryClamp = RESTIR_MAX_HISTORY; + ReservoirHistoryClamp = (ReservoirHistoryClamp / float(ReprojectionIndex + 1)); + + // Checkerboard handling: + // 1. If ray distance > 0 - this cell is not culled by checkerboarding (we have a minimum dist 0.001 for active cells) + // 2. If the reproj. index > 0 - this cell is also not culled by checkerboarding (we trace new rays if we couldn't reproject from N-1 frame) + if (Reservoir.Ray.Distance <= 0 && ReprojectionIndex == 0) + { + Reservoir.Radiance.M = 0; // Kills reservoir weight, allowing history reservoirs take precedence + ReservoirHistoryClamp /= 2; + } + + // Calculate cell coordinates + int2 CellTapCoord00 = ReprojectionCoord * _OctahedralSize + uint2(0, 0) * _OctahedralSize + CellCoord; + int2 CellTapCoord01 = ReprojectionCoord * _OctahedralSize + uint2(1, 0) * _OctahedralSize + CellCoord; + int2 CellTapCoord10 = ReprojectionCoord * _OctahedralSize + uint2(0, 1) * _OctahedralSize + CellCoord; + int2 CellTapCoord11 = ReprojectionCoord * _OctahedralSize + uint2(1, 1) * _OctahedralSize + CellCoord; + + // Load packed history reservoir samples + uint4 ReservoirHistoryPacked00 = asuint(H_LOAD_ARRAY(_ReservoirAtlas_History, CellTapCoord00, GetHistoryIndex(ReprojectionIndex))); + uint4 ReservoirHistoryPacked01 = asuint(H_LOAD_ARRAY(_ReservoirAtlas_History, CellTapCoord01, GetHistoryIndex(ReprojectionIndex))); + uint4 ReservoirHistoryPacked10 = asuint(H_LOAD_ARRAY(_ReservoirAtlas_History, CellTapCoord10, GetHistoryIndex(ReprojectionIndex))); + uint4 ReservoirHistoryPacked11 = asuint(H_LOAD_ARRAY(_ReservoirAtlas_History, CellTapCoord11, GetHistoryIndex(ReprojectionIndex))); + + float4 NormalWeights; + NormalWeights.x = saturate(dot(UnpackDirection24bit(ReservoirHistoryPacked00.w), RayOriginNormal)); + NormalWeights.y = saturate(dot(UnpackDirection24bit(ReservoirHistoryPacked01.w), RayOriginNormal)); + NormalWeights.z = saturate(dot(UnpackDirection24bit(ReservoirHistoryPacked10.w), RayOriginNormal)); + NormalWeights.w = saturate(dot(UnpackDirection24bit(ReservoirHistoryPacked11.w), RayOriginNormal)); + + // Continious disocclusion check based on the normal stored in the resevoir, helps with reducing reprojection artifacts over time + if (any(NormalWeights * ReprojectionWeights > 0.25)) + ReprojectionWeights *= NormalWeights; + + + // Merge with center reservoir + uint4 Merged = 0; + if (!DISABLE_RESTIR_TEMPORAL) + { + Merged.x = ReservoirMergeTemporal(CellTapCoord00, ReservoirHistoryPacked00, GetHistoryIndex(ReprojectionIndex), ReprojectionWeights.x, Diffuse, ReservoirUpdateRandom, Reservoir); + Merged.y = ReservoirMergeTemporal(CellTapCoord01, ReservoirHistoryPacked01, GetHistoryIndex(ReprojectionIndex), ReprojectionWeights.y, Diffuse, ReservoirUpdateRandom, Reservoir); + Merged.z = ReservoirMergeTemporal(CellTapCoord10, ReservoirHistoryPacked10, GetHistoryIndex(ReprojectionIndex), ReprojectionWeights.z, Diffuse, ReservoirUpdateRandom, Reservoir); + Merged.w = ReservoirMergeTemporal(CellTapCoord11, ReservoirHistoryPacked11, GetHistoryIndex(ReprojectionIndex), ReprojectionWeights.w, Diffuse, ReservoirUpdateRandom, Reservoir); + } + + float3 ResDirection = Reservoir.Ray.Direction; + float ResDistance = Reservoir.Ray.Distance; + + // Load probe normal, depth & offset + float4 RayOriginNormalDepth = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, ProbeCoord).xy), ProbeOffset); + float2 ProbeCoordNDC = (ProbeCoord.xy * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw; + + float3 PositionWS = H_COMPUTE_POSITION_WS(ProbeCoordNDC.xy, RayOriginNormalDepth.w, H_MATRIX_I_VP); + + float3 PositionOriginal = PositionWS; + + // PositionWS += 0.01 * RayOriginNormalDepth.xyz; + // PositionWS += 0.01 * ResDirection; + + // float3 NormalForBias = GeometryNormalWS; + float3 NormalForBias = dot(RayOriginNormalDepth.xyz, Reservoir.Ray.Direction) < 0 ? -RayOriginNormalDepth.xyz : RayOriginNormalDepth.xyz; + + // Calculate normal bias + float2 CornerCoordNDC = ProbeCoordNDC + 0.5f * _ScreenSize.zw * float(_OctahedralSize); + float3 CornerPositionWS = H_COMPUTE_POSITION_WS(CornerCoordNDC.xy, RayOriginNormalDepth.w, H_MATRIX_I_VP); + float NormalBias = abs(dot(CornerPositionWS - PositionWS, NormalForBias)) * 2.0f; + + // This can push the ray origin off-screen causing black pixels on the border + PositionWS += NormalForBias * NormalBias; + PositionWS += 0.01 * ResDirection; + + float Dist = 0; + + bool IsHit = false; + float3 PosPrev = PositionWS; + for (int i = 0; i < 40; i++) + { + // if (length(PositionWS - PositionOriginal) >= ResDistance) + // break; + + // Move along the ray with fixed steps + float3 PositionLocalWS = PositionWS + ResDirection * 0.01 * float(i); + float3 PositionNDC = H_COMPUTE_NDC_Z(PositionLocalWS, UNITY_MATRIX_VP).xyz; + + if (all(PositionNDC.xy > 0) && all(PositionNDC.xy < 1)) + { + // Sample depth along the ray + float Depth = HBUFFER_DEPTH(PositionNDC.xy * _ScreenSize.xy); //(_DepthPyramid, PositionNDC.xy * _ScreenSize.xy); + Depth = H_LOAD(g_HTraceDepthPyramidWSGI, PositionNDC.xy * _ScreenSize.xy).x; + + float DepthLinear = H_LINEAR_EYE_DEPTH(Depth); + float PositionLinear = H_LINEAR_EYE_DEPTH(PositionNDC.z); + + if (Depth <= 1e-7) + break; + + // Decrement thickness counter each time the ray is above surface + if (DepthLinear < PositionLinear) + { + if ( abs(PositionLinear - DepthLinear) < 0.035) + { + Dist = length(PositionOriginal - PositionLocalWS); + IsHit = true; + } + + + break; + } + + PosPrev = PositionLocalWS; + + } + else + { + break; + } + } + + float HitDistanceWS = ResDistance; + + float DebugOutput = 1; + + if (IsHit) + HitDistanceWS = length(PositionOriginal - PositionWS); + + float Test = 1; + // If the distance difference is relatively high + if (abs(Dist - ResDistance) / (ResDistance + ResDistance) > 0.35) + { + if (IsHit && Dist <= ResDistance ) + { + // Reservoir.Radiance.Color = float3(1,0,0); + // Test = 0; + // ReservoirHistoryClamp = 0; + } + } + + // Clamp reservoir history + if (Reservoir.Radiance.M > ReservoirHistoryClamp) + { + Reservoir.Radiance.Wsum *= ReservoirHistoryClamp / Reservoir.Radiance.M; + Reservoir.Radiance.M = ReservoirHistoryClamp; + } + + // Recalculate W + Reservoir.Radiance.W = Reservoir.Radiance.Wsum / max(Reservoir.Radiance.M * Luminance(Reservoir.Radiance.Color * Diffuse), 1e-7) ; + + // Apply exposure control + if (RESTIR_EXPOSURE_CONTROL) + { + float ExposurePrevious = HGetPreviousExposureMultiplier; + float ExposureCurrent = HGetCurrentExposureMultiplier; + + float ExposureRatio = (ExposurePrevious * ExposureCurrent) != 0.0 ? ExposureCurrent / ExposurePrevious : 100.0; + + if (max(ExposureRatio, 1.0 / ExposureRatio) < 2.0) + Reservoir.Radiance.W = Reservoir.Radiance.W * HGetInversePreviousExposureMultiplier * ExposureCurrent; + } + + // Pack radiance and ray datas + uint2 RadianceDataPacked = PackRadianceData(Reservoir.Radiance); + uint2 RayDataPacked = PackRayData(Reservoir.Ray); + + // float ShadowGuidanceMask = H_LOAD(_ShadowGuidanceMask, pixCoord.xy); + + // Output reservoir atlas for history + _ReservoirAtlas_Output[H_COORD(pixCoord.xy)] = uint4(RadianceDataPacked.xy, RayDataPacked.xy); + + // if (all(Merged == 0)) + // Test = 1; + + RadianceDataPacked.x |= PackOcclusion(1, 1-Test); + + // Output radiance & ray datas for spatial reuse passes + _ReservoirAtlasRadianceData_Output[H_COORD(pixCoord.xy)] = RadianceDataPacked.xy; + _ReservoirAtlasRayData_Output[H_COORD(pixCoord.xy)] = RayDataPacked.x; +} + + +// ------------------------ PROBE ATLAS SPATIAL REUSE ------------------------ +[numthreads(8, 8, 1)] +void ProbeAtlasSpatialReuse(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint2 groupID : SV_GroupID) +{ + + + // Calculate probe and cell coord + int2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + int2 CellCoord = pixCoord.xy - floor(pixCoord.xy / _OctahedralSize) * _OctahedralSize; + + // Prepare diffuse and random values for reservoir exchange + float3 Diffuse = GetReservoirDiffuse(ProbeCoord); + uint ReservoirUpdateRandom = Hash3(uint3(pixCoord.xy, _FrameCount)); + + // Initialize reservoir + Reservoir Reservoir; + ReservoirInitialize(pixCoord.xy, Reservoir); + + // Load and unpack radiance data to reservoir + uint2 RadianceDataPacked = asuint(H_LOAD(_ReservoirAtlasRadianceData, pixCoord.xy).xy); + UnpackRadianceData(RadianceDataPacked, Diffuse, Reservoir.Radiance); + + // Unpack occlusion (passed with packed radiance data) + bool IsDisocclusionCenter; + float ReservoirCenterOcclusion = UnpackOcclusion(RadianceDataPacked.x, IsDisocclusionCenter); + + // Load packed sample weights and coords + float SampleWeights[8]; int2 SampleOffsets[8]; + uint4 PackedSampleOffsets = asuint(H_LOAD_ARRAY(_SpatialOffsetsPacked, ProbeCoord, _PassNumber)); + uint4 PackedSampleWeights = asuint(H_LOAD_ARRAY(_SpatialWeightsPacked, ProbeCoord, _PassNumber)); + + // Unpack sample weights and coords + UnpackFilteringOffsetsX8(PackedSampleOffsets, SampleOffsets); + UnpackFilteringWeightsX8(PackedSampleWeights, SampleWeights); + + for (int i = 0; i < 8; i++) + { + if (DISABLE_RESTIR_SPATIAL) + continue; + + // Calculate sample cell coord + uint2 CellTapCoord = ProbeCoord * _OctahedralSize + SampleOffsets[i] * _OctahedralSize + CellCoord; + + // Load packed sample reservoir and extract occlusion value from it + bool IsDisocclusionSample; + uint2 ReservoirSamplePacked = asuint(H_LOAD(_ReservoirAtlasRadianceData, CellTapCoord).xy); + float ReservoirSampleOcclusion = UnpackOcclusion(ReservoirSamplePacked.x, IsDisocclusionSample); + + // Calculate shadow guidance cutoff + float ShadowGuidanceWeight = exp2(-min(Reservoir.Radiance.M, 20) * abs(ReservoirCenterOcclusion - ReservoirSampleOcclusion)); + + // Merge with center reservoir + ReservoirMergeSpatial(CellTapCoord, ReservoirSamplePacked, SampleWeights[i] * ShadowGuidanceWeight, Diffuse, Reservoir, ReservoirUpdateRandom); + } + + // Recalculate W + Reservoir.Radiance.W = Reservoir.Radiance.Wsum / max(Reservoir.Radiance.M * Luminance(Reservoir.Radiance.Color * Diffuse), 1e-7) ; + + // Pack radiance data and occlusion back + RadianceDataPacked = PackRadianceData(Reservoir.Radiance); + RadianceDataPacked.x |= PackOcclusion(ReservoirCenterOcclusion, IsDisocclusionCenter); + + // Output main and data reservoirs + _ReservoirAtlasRadianceData_Output[H_COORD(pixCoord.xy)] = RadianceDataPacked; + _ReservoirAtlasRayData_Output[H_COORD(pixCoord.xy)] = asuint(H_LOAD(_ReservoirAtlasRayData, Reservoir.MergedCoord).x); +} + + +// ------------------------ PROBE ATLAS SPATIAL REUSE DISOCCLUSION------------------------ +[numthreads(8, 8, 1)] +void ProbeAtlasSpatialReuseDisocclusion(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + uint IndirectCoordOffsetVR = _ScreenSize.x * _ScreenSize.y * _IndexXR; + uint RayCounterOffsetVR = 10 * _IndexXR; + + uint RayIndex = groupID * 64 + groupIndex; + if (RayIndex >= _RayCounter[2 + 4 + RayCounterOffsetVR]) + return; + + pixCoord.xy = _TracingCoords[RayIndex + IndirectCoordOffsetVR]; + + // Calculate probe and cell coord + int2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + int2 CellCoord = pixCoord.xy - floor(pixCoord.xy / _OctahedralSize) * _OctahedralSize; + + // Prepare diffuse and random values for reservoir exchange + float3 Diffuse = GetReservoirDiffuse(ProbeCoord); + uint ReservoirUpdateRandom = Hash3(uint3(pixCoord.xy, _FrameCount)); + + // Initialize reservoir + Reservoir Reservoir; + ReservoirInitialize(pixCoord.xy, Reservoir); + + // Load and unpack radiance data to reservoir + uint2 RadianceDataPacked = asuint(H_LOAD(_ReservoirAtlasRadianceData, pixCoord.xy).xy); + UnpackRadianceData(RadianceDataPacked, Diffuse, Reservoir.Radiance); + + // Load packed sample weights and coords + float SampleWeights[8]; int2 SampleOffsets[8]; + uint4 PackedSampleOffsets = asuint(H_LOAD_ARRAY(_SpatialOffsetsPacked, ProbeCoord, 1)); + uint4 PackedSampleWeights = asuint(H_LOAD_ARRAY(_SpatialWeightsPacked, ProbeCoord, 1)); + + // Unpack sample weights and coords + UnpackFilteringOffsetsX8(PackedSampleOffsets, SampleOffsets); + UnpackFilteringWeightsX8(PackedSampleWeights, SampleWeights); + + for (int i = 0; i < 4; i++) + { + // Calculate sample cell coord + uint2 CellTapCoord = ProbeCoord * _OctahedralSize + SampleOffsets[i] * _OctahedralSize + CellCoord; + + uint2 ReservoirSamplePacked = asuint(H_LOAD(_ReservoirAtlasRadianceData, CellTapCoord).xy); + + // Merge with center reservoir + ReservoirMergeSpatial(CellTapCoord, ReservoirSamplePacked, SampleWeights[i], Diffuse, Reservoir, ReservoirUpdateRandom); + } + + PackedSampleOffsets = asuint(H_LOAD_ARRAY(_SpatialOffsetsPacked, ProbeCoord, 2)); + PackedSampleWeights = asuint(H_LOAD_ARRAY(_SpatialWeightsPacked, ProbeCoord, 2)); + + // Unpack sample weights and coords + UnpackFilteringOffsetsX8(PackedSampleOffsets, SampleOffsets); + UnpackFilteringWeightsX8(PackedSampleWeights, SampleWeights); + + for (int t = 0; t < 4; t++) + { + // Calculate sample cell coord + uint2 CellTapCoord = ProbeCoord * _OctahedralSize + SampleOffsets[t] * _OctahedralSize + CellCoord; + + uint2 ReservoirSamplePacked = asuint(H_LOAD(_ReservoirAtlasRadianceData, CellTapCoord).xy); + + // Merge with center reservoir + ReservoirMergeSpatial(CellTapCoord, ReservoirSamplePacked, SampleWeights[t], Diffuse, Reservoir, ReservoirUpdateRandom); + } + + PackedSampleOffsets = asuint(H_LOAD_ARRAY(_SpatialOffsetsPacked, ProbeCoord, 3)); + PackedSampleWeights = asuint(H_LOAD_ARRAY(_SpatialWeightsPacked, ProbeCoord, 3)); + + // Unpack sample weights and coords + UnpackFilteringOffsetsX8(PackedSampleOffsets, SampleOffsets); + UnpackFilteringWeightsX8(PackedSampleWeights, SampleWeights); + + for (int k = 0; k < 4; k++) + { + // Calculate sample cell coord + uint2 CellTapCoord = ProbeCoord * _OctahedralSize + SampleOffsets[k] * _OctahedralSize + CellCoord; + + uint2 ReservoirSamplePacked = asuint(H_LOAD(_ReservoirAtlasRadianceData, CellTapCoord).xy); + + // Merge with center reservoir + ReservoirMergeSpatial(CellTapCoord, ReservoirSamplePacked, SampleWeights[k], Diffuse, Reservoir, ReservoirUpdateRandom); + } + + _ReservoirAtlasRayData_Output[H_COORD(pixCoord.xy)] = asuint(H_LOAD(_ReservoirAtlasRayData, Reservoir.MergedCoord).x); +} + + +// ------------------------ RESERVOIR HISTORY UPDATE ------------------------ +[numthreads(8, 8, 1)] +void ReservoirHistoryUpdate(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + _ReservoirAtlas_ArrayOutput[uint3(pixCoord.xy, H_INDEX_ARRAY(uint(_FrameCount) % _PersistentHistorySamples))] = asuint(H_LOAD(_ReservoirAtlas, pixCoord.xy)); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReSTIR.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReSTIR.compute.meta new file mode 100644 index 000000000..194eb855e --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReSTIR.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 3e71db818c55e8d4caee42bbcc86f664 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReSTIR.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReflectionProbeCompose.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReflectionProbeCompose.compute new file mode 100644 index 000000000..d7068487f --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReflectionProbeCompose.compute @@ -0,0 +1,147 @@ +#pragma kernel RenderVoxelsForReflectionProbes + +#include "../Includes/Config.hlsl" +#include "../Includes/SpatialHash.hlsl" +#include "../Includes/VoxelTraversal.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +// Output Buffers +H_RW_TEXTURE(float3, _Output); + +[numthreads(8, 8, 1)] +void RenderVoxelsForReflectionProbes(uint3 pixCoord : SV_DispatchThreadID) +{ + // Get world space position + float3 WorldPosition = H_COMPUTE_POSITION_WS((pixCoord.xy + 0.5) * _ScreenSize.zw, HBUFFER_DEPTH(pixCoord.xy), H_MATRIX_I_VP); + float3 AbsolutePositionWS = H_GET_ABSOLUTE_POSITION_WS(WorldPosition); + + // Calculate voxel coord from position + int3 VoxelBoxCenter = int3(_VoxelResolution.xzy / 2); + int3 VoxelPosition = floor((AbsolutePositionWS - _VoxelCameraPos) / _VoxelSize); + float3 VoxelCoord = VoxelBoxCenter + VoxelPosition; + + // Load normal + float3 Normal = HBUFFER_NORMAL_WS(pixCoord.xy); + float3 NormalAbs = abs(Normal); + float NormalMax = max(max(NormalAbs.x, NormalAbs.y), NormalAbs.z); + + float3 CacheNormal = 0; + float3 CacheNormalSign = 0; + float3 GatherDirection = 0; + + if (NormalMax == NormalAbs.x) + { + CacheNormal = float3(1,0,0); + GatherDirection = float3(0,1,1); + CacheNormalSign.x = sign(Normal.x); + } + if (NormalMax == NormalAbs.y) + { + CacheNormal = float3(0,1,0); + GatherDirection = float3(1,0,1); + CacheNormalSign.y = sign(Normal.y); + + } + if (NormalMax == NormalAbs.z) + { + CacheNormal = float3(0,0,1); + GatherDirection = float3(1,1,0); + CacheNormalSign.z = sign(Normal.z); + } + + // Offsets used for gather + int2 Offsets5x5[25] = {int2( 0, 0), int2( 0, 1), int2( 1, 0), int2( 1, 1), int2(-1, 0), + int2(-1, 1), int2(-1, -1), int2( 0, -1), int2( 1, -1), int2(-2, 0), + int2( 0, -2), int2( 2, 0), int2( 0, 2), int2(-1, 2), int2(-2, 1), + int2( 1, -2), int2( 2, -1), int2(-2, -1), int2(-1, -2), int2( 2, 1), + int2( 1, 2), int2(-2, 2), int2( 2, 2), int2( 2, -2), int2(-2, -2)}; + + + // Check neighbours for occlusions + if (OCCLUSION_CHECK) + { + int2 Offsets3x3[12] = { int2( 0, 1), int2( 1, 0), int2( 1, 1), int2(-1, 0), + int2(-1, 1), int2(-1, -1), int2( 0, -1), int2( 1, -1), + int2(-2, 0), int2( 2, 0), int2( 0, -2), int2( 0, 2) }; + + for (int i = 0; i < 12; i++) + { + float3 Offset; + Offset.x = Offsets3x3[i].x; + Offset.y = Offsets3x3[i].y; + Offset.z = Offsets3x3[i][GatherDirection.x]; + + Offset.x *= GatherDirection.x; + Offset.y *= GatherDirection.y; + Offset.z *= GatherDirection.z; + + uint VoxelOccupancy = asuint(H_LOAD3D_LOD(_VoxelPositionPyramid, VoxelCoord + Offset + float3(1,1,1) * CacheNormal * CacheNormalSign, 0)); + + if (VoxelOccupancy > 0) + { + Offsets5x5[i + 1] = 0; + + if (i == 0) { Offsets5x5[13] = 0; Offsets5x5[12] = 0; Offsets5x5[20] = 0; } + if (i == 1) { Offsets5x5[19] = 0; Offsets5x5[11] = 0; Offsets5x5[16] = 0; } + if (i == 2) { Offsets5x5[20] = 0; Offsets5x5[22] = 0; Offsets5x5[19] = 0; } + if (i == 3) { Offsets5x5[14] = 0; Offsets5x5[ 9] = 0; Offsets5x5[17] = 0; } + if (i == 4) { Offsets5x5[13] = 0; Offsets5x5[21] = 0; Offsets5x5[14] = 0; } + if (i == 5) { Offsets5x5[17] = 0; Offsets5x5[24] = 0; Offsets5x5[18] = 0; } + if (i == 6) { Offsets5x5[18] = 0; Offsets5x5[10] = 0; Offsets5x5[15] = 0; } + if (i == 7) { Offsets5x5[15] = 0; Offsets5x5[23] = 0; Offsets5x5[16] = 0; } + + if (i == 8) { Offsets5x5[14] = 0; Offsets5x5[ 9] = 0; Offsets5x5[17] = 0; } + if (i == 9) { Offsets5x5[19] = 0; Offsets5x5[11] = 0; Offsets5x5[16] = 0; } + if (i == 10) { Offsets5x5[18] = 0; Offsets5x5[10] = 0; Offsets5x5[15] = 0; } + if (i == 11) { Offsets5x5[13] = 0; Offsets5x5[12] = 0; Offsets5x5[20] = 0; } + } + } + } + + + float3 AccumulateCache = 0; + float AccumulatedWeight = 0; + + // Accumulate radiance cache spatially + for (int i = 0; i < SPATIAL_SAMPLES; i++) + { + int3 SampleCoord = VoxelCoord; + + // Apply sample offset + float3 Offset; + Offset.x = Offsets5x5[i].x; + Offset.y = Offsets5x5[i].y; + Offset.z = Offsets5x5[i][GatherDirection.x]; + + // Apply per-pixel jitter + float PixelJitter = GetBNDSequenceSample(pixCoord.xy, _FrameCount * JITTER_TEMPORAL, 0); + Offset.x += Offsets5x5[PixelJitter * JITTER_STRENGTH].x; + Offset.y += Offsets5x5[PixelJitter * JITTER_STRENGTH].y; + Offset.z += Offsets5x5[PixelJitter * JITTER_STRENGTH][GatherDirection.x]; + + SampleCoord.x += Offset.x * GatherDirection.x; + SampleCoord.y += Offset.y * GatherDirection.y; + SampleCoord.z += Offset.z * GatherDirection.z; + + // Get hash cell + uint HashIndex = HashGetIndex(ComputeRadianceCacheCoord(SampleCoord), PackVoxelNormalIndex(Normal)); + + uint HashIndexFound; + uint HashKey = PackHashKey(ComputeRadianceCacheCoord(SampleCoord), Normal); + bool HashFound = HashFindValid(HashIndex, HashKey, HashIndexFound); + + if (HashFound) + { + float3 RadianceCacheSample = UnpackCacheRadianceFull(_HashBuffer_Radiance[HashIndexFound].xyz); + AccumulateCache += RadianceCacheSample * HGetCurrentExposureMultiplier; + AccumulatedWeight += 1; + } + } + + // Normalize + if (AccumulatedWeight > 0) + AccumulateCache /= AccumulatedWeight; + + // Combine and output + _Output[H_COORD(pixCoord.xy)] = AccumulateCache * HBUFFER_DIFFUSE(pixCoord.xy).xyz + HBUFFER_COLOR(pixCoord.xy).xyz; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReflectionProbeCompose.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReflectionProbeCompose.compute.meta new file mode 100644 index 000000000..2268afe62 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReflectionProbeCompose.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 1bdf55fd1904a124caff462bdbc29873 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReflectionProbeCompose.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRenderAO.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRenderAO.compute new file mode 100644 index 000000000..7a133d823 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRenderAO.compute @@ -0,0 +1,364 @@ +#pragma kernel HorizonTracing +#pragma kernel OcclusionInterpolation +#pragma kernel OcclusionAccumulation + +#include "../Includes/SpatialFilteringFunctions.hlsl" +#include "../Includes/VoxelTraversal.hlsl" +#include "../Includes/Reservoir.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +// Properties +float _Camera_FOV; + +H_TEXTURE(_SampleCount_History); +H_TEXTURE(_NormalDepthHalf); +H_TEXTURE(_AmbientOcclusion); +H_TEXTURE(_AmbientOcclusion_History); +H_TEXTURE(_Depth_History); +H_TEXTURE(_Normal_History); +H_TEXTURE(_NormalDepth_History); + + +// Output Buffers +H_RW_TEXTURE(float4, _NormalDepthDownsampled_Output); +H_RW_TEXTURE(uint ,_NormalDepthDownsampledPacked_Output); +H_RW_TEXTURE(float3 ,_NormalDepthDownsampled2_Output); +H_RW_TEXTURE(float, _DepthDownsampled_Output); +H_RW_TEXTURE(float4, _BentNormalAmbientOcclusion_Output); +H_RW_TEXTURE(float4, _NormalDepthHalf_Output); +H_RW_TEXTURE(float4, _BentNormalAO_Output); +H_RW_TEXTURE(uint, _SampleCount_Output); +H_RW_TEXTURE(float4, _GeometryNormal_Output); +H_RW_TEXTURE(float4, _RayDirectionTest_Output); +H_RW_TEXTURE(float, _AmbientOcclusion_Output); + +H_RW_TEXTURE(uint4, _NormalTBN_Output); + +RWStructuredBuffer _RayCounter; +RWStructuredBuffer _TracingCoords; + +// ------------------------ FUNCTIONS ------------------------ + + +float PrepareHorizon(float Horizon, float Sign, float N) +{ + float PreparedHorizon = HFastACos(clamp(Horizon, -1, 1)); + PreparedHorizon = saturate(((Sign * -PreparedHorizon) + N + H_PI_HALF) / H_PI); // TODO: +PreparedHorizon ? + return max(PreparedHorizon, 1e-7); +} + +float IntegrateHalfArc(float AcosHorizon, float n, float cosN, float sinN) +{ + float HalfArc = (cosN + 2.0f * AcosHorizon * sinN - cos(2.0f * AcosHorizon - n)) / 4.0f; + return HalfArc; +} + +float TestConeIntersection(float FirstHorizon, float SecondHorizon, inout uint Mask) +{ + uint FirstHorizonToInt = FirstHorizon * 32; // TODO: ceil(FirstHorizon * 32) ? + uint SecondHorizonToInt = ceil(saturate(SecondHorizon - FirstHorizon) * 32); + uint HorizonsToBit = SecondHorizonToInt > 0 ? (0xFFFFFFFF >> (32 - SecondHorizonToInt)) : 0; + uint AngleToBit = HorizonsToBit << FirstHorizonToInt; + + uint MaskTest = AngleToBit & (~Mask);; + Mask = Mask | MaskTest; + + return countbits(MaskTest); +} + +float2 PrepareHorizonPair(float HorizonAcos1, float HorizonAcos2, float N, float Side) +{ + float HorizonPrepared1 = saturate((N - HorizonAcos1 + H_PI_HALF) / H_PI); + float HorizonPrepared2 = saturate((N - HorizonAcos2 + H_PI_HALF) / H_PI); + + HorizonPrepared1 = max(HorizonPrepared1, 1e-7); + HorizonPrepared2 = max(HorizonPrepared2, 1e-7); + + float2 HorizonPair = Side > 0 ? float2(HorizonPrepared2, HorizonPrepared1) : float2(HorizonPrepared1, HorizonPrepared2); + return HorizonPair; +} + +// Accepts Linear Depth and pixCoord, returns World Position in View Space +float3 GetPosition(float2 UV, float Depth) +{ + float2 p11_22 = float2(UNITY_MATRIX_P._11, UNITY_MATRIX_P._22); + float2 p13_31 = float2(UNITY_MATRIX_P._13, UNITY_MATRIX_P._23); + float3 Position = float3((UV * 2 - 1 - p13_31) / p11_22 , 1) * Depth; + return Position; +} + +float CalculateScreenSpaceRadius(float CameraFOV, float DepthLinear, float Radius) +{ + float FovRadians = radians(CameraFOV); + float TanHalfFOVY = tan(FovRadians * 0.5f); + float TanHalfFOVX = TanHalfFOVY * (_ScreenSize.x / _ScreenSize.y); + float2 CameraTanHalfFOV = float2(TanHalfFOVX, TanHalfFOVY); + float2 NDCToViewMul = float2(CameraTanHalfFOV.x * 2.0f, CameraTanHalfFOV.y * -2.0f); + float2 NDCToViewMul_X_PixelSize = float2(NDCToViewMul.x * _ScreenSize.z, NDCToViewMul.y * _ScreenSize.w); + return Radius / (DepthLinear * NDCToViewMul_X_PixelSize.x); +} + +// ------------------------ RESTIR TEMPORAL KERNEL ------------------------ + +[numthreads(8, 8, 1)] +void HorizonTracing(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + + pixCoord.xy *= 2; + float2 pixCoordNDC = (pixCoord.xy + 0.5f) * _ScreenSize.zw; + + // Load center depth and mask data + float DepthCenterRaw = HBUFFER_DEPTH(pixCoord.xy); + + // Load main center pixel data + float DepthCenterLinear = H_LINEAR_EYE_DEPTH(DepthCenterRaw); + float3 NormalCenterWS = HBUFFER_NORMAL_WS(pixCoord.xy); + float3 NormalCenterVS = H_TRANSFORM_WORLD_TO_VIEW_NORMAL(NormalCenterWS) * float3(1, -1, -1); + float3 WorldPosCenterVS = GetPosition(pixCoordNDC, DepthCenterLinear); + float3 ViewDirection = normalize(-WorldPosCenterVS); + + // Main constants + float Radius = 0.5; //_Radius; // TODO: expose in UI + float DistributionPower = 3.2; + float FalloffRange = 0.6f * Radius; + float FalloffFrom = Radius * (1.0f - 0.615f); + float FalloffMul = -1.0f / FalloffRange; + float FalloffAdd = FalloffFrom / FalloffRange + 1.0f; + float SliceCount = 2; + + // Calculate sampling radius in meters + float ScreenSpaceRadius = CalculateScreenSpaceRadius(_Camera_FOV, DepthCenterLinear, Radius); + + // Prepare noise + float NoiseSlice = GetBNDSequenceSample(pixCoord.xy / 1, uint(_FrameCount) % 16, 0); + float NoiseSample = GetBNDSequenceSample(pixCoord.xy / 1, uint(_FrameCount) % 16, 1); + float JitterSample = Random(pixCoordNDC) * 2.0f - 1.0f; + + // Initialize ambient occlusion values + float AmbientOcclusion = 0 + saturate((10 - ScreenSpaceRadius) / 100) * 0.5f; + float2 BentHorizons = 0; + float3 BentNormal = 0; + + float BitfieldAO = 0; + + + // ------------------------ BEGIN MAIN LOOP ------------------------ + UNITY_LOOP + for (int Slice = 0; Slice < SliceCount; Slice++) + { + float SliceSeed = float(Slice + NoiseSlice) / float(SliceCount); + float Phi = SliceSeed * 1 * H_PI; + float cosPhi = cos(Phi); + float sinPhi = sin(Phi); + + float3 SliceDirection = float3(cosPhi, sinPhi, 0); + float2 SamplingDirection = float2(SliceDirection.x, -SliceDirection.y); + + float3 OrthoDirectionVec = SliceDirection - (dot(SliceDirection, ViewDirection) * ViewDirection); + float3 AxisVec = normalize(cross(OrthoDirectionVec, ViewDirection)); + float3 ProjectedNormal = NormalCenterVS - AxisVec * dot(NormalCenterVS , AxisVec); + float signNorm = sign(dot(OrthoDirectionVec, ProjectedNormal)); + float ProjectedNormalLength = length(ProjectedNormal); + float cosN = saturate(dot(ProjectedNormal, ViewDirection) / ProjectedNormalLength); + float N = signNorm * HFastACos(cosN); + float sinN = sin(N); + + float OcclusionAccumulation = 0; + uint OcclusionMaskSSGI = 0; + + for (int Side = 0; Side < 2; Side++) + { + float SideDirection = -1 + 2 * Side; + float LowestHorizon = cos(N + (H_PI_HALF * SideDirection)); + float MaxHorizonAO = LowestHorizon; + + float StepCount = 10; + + for (int Step = 0; Step < StepCount; Step ++) + { + // Jitter step + float StepSeed = float(Step * StepCount) * JitterSample; + float StepNoise = frac(NoiseSample + StepSeed); + + float StepStride = (Step + StepNoise) / (StepCount); + StepStride = pow(abs(StepStride), DistributionPower); + float2 SampleOffset = StepStride * SamplingDirection * ScreenSpaceRadius; + float SampleOffsetLength = length(SampleOffset); + SampleOffset = round(SampleOffset) * _ScreenSize.zw; + float2 SampleCoordNDC = pixCoordNDC + SampleOffset * SideDirection; + + // Early-out if we are outside the frame + if (SampleCoordNDC.x <= 0 || SampleCoordNDC.y <= 0 || SampleCoordNDC.x >= 1 || SampleCoordNDC.y >= 1) + break; + + // Texture LOD acceleration structure + uint DepthLOD = clamp(log2(SampleOffsetLength) - 4, 0, 4) ; + + // Read FRONT and BACK depth buffers + float2 DepthFrontBackRaw = H_LOAD_LOD(g_HTraceDepthPyramidWSGI, (SampleCoordNDC * _ScreenSize.xy) / pow(2, DepthLOD) , DepthLOD).x; //H_SAMPLE_LOD(_DepthPyramid, H_SAMPLER_POINT_CLAMP, SampleCoordNDC * _RTHandleScale, DepthLOD).xy; + + // Compute FRONT horizon + float DepthFrontRaw = DepthFrontBackRaw.x; + bool IsMoving = DepthFrontRaw < 0 ? true : false; + DepthFrontRaw = abs(DepthFrontRaw) * 0.9992f; + float DepthFrontLinear = H_LINEAR_EYE_DEPTH(DepthFrontRaw); + float3 SampleDeltaFront = GetPosition(SampleCoordNDC, DepthFrontLinear) - WorldPosCenterVS; //TransformWorldToView(H_COMPUTE_POSITION_WS(SampleCoordNDC, DepthFrontRaw, H_MATRIX_I_VP)); // GetPosition(SampleCoordNDC, DepthFrontLinear) - WorldPosCenterVS; + float HorizonFront = dot(normalize(SampleDeltaFront), ViewDirection); //ViewDirection + float HorizonAcosFront = HFastACos(clamp(HorizonFront, -1, 1)) * SideDirection; + + + // Calculate BACK horizon with standard depth + // float DepthBackLinear = DepthFrontLinear + 0.1; // / _TraceThickness.x + _TraceThickness.y + 0.01f; + // float3 Position = GetPosition(SampleCoordNDC, DepthBackLinear); + // float3 SampleDeltaBack = Position - WorldPosCenterVS; + // float HorizonBack = dot(normalize(SampleDeltaBack), ViewDirection); //ViewDirection + // float HorizonAcosBack = HFastACos(clamp(HorizonBack, -1, 1)) * SideDirection; + // float2 HorizonPair = PrepareHorizonPair(HorizonAcosFront, HorizonAcosBack, N, SideDirection); + // + //float ConeIntersection = TestConeIntersection(HorizonPair.x, HorizonPair.y, OcclusionMaskSSGI); + + float WeightBase = length(float3(SampleDeltaFront.x, SampleDeltaFront.y, SampleDeltaFront.z * 4.0f)) * Radius; + float HorizonWeight = saturate(WeightBase * min(FalloffMul * (0.5f / 0.3), FalloffMul) + FalloffAdd); + // float HorizonWeight = saturate(WeightBase * FalloffMul * 3.0 + FalloffAdd); + HorizonFront = lerp(LowestHorizon, HorizonFront, HorizonWeight); + MaxHorizonAO = max(MaxHorizonAO, HorizonFront); + } + + // Integrate Ambient Occlusion + OcclusionAccumulation += IntegrateHalfArc(HFastACos(MaxHorizonAO) * SideDirection, N, cosN, sinN); + + if (Side == 0) BentHorizons.x = MaxHorizonAO; + else BentHorizons.y = MaxHorizonAO; + } + + AmbientOcclusion += OcclusionAccumulation * ProjectedNormalLength; + + BitfieldAO += float(countbits(OcclusionMaskSSGI)) / 32.0f; + + // ------------------------ BENT NORMALS ------------------------ + + float h0 = -HFastACos(BentHorizons.x); + float h1 = HFastACos(BentHorizons.y); + float t0 = (6*sin(h0-N)-sin(3*h0-N)+6*sin(h1-N)-sin(3*h1-N)+16*sin(N)-3*(sin(h0+N)+sin(h1+N)))/12; + float t1 = (-cos(3*h0-N)-cos(3*h1-N)+8*cos(N)-3*(cos(h0+N)+cos(h1+N)))/12; + float3 LocalBentNormal = float3( SliceDirection.x * t0, SliceDirection.y * t0, - t1); + LocalBentNormal = mul(RotFromToMatrix(float3(0,0,-1), ViewDirection), LocalBentNormal ) * ProjectedNormalLength; + BentNormal += LocalBentNormal; + + // ------------------------ RAY CULLING ------------------------ + + + } + + // Finalize values + AmbientOcclusion /= SliceCount; + BentNormal = normalize(BentNormal); + AmbientOcclusion = saturate(AmbientOcclusion); + AmbientOcclusion = pow(AmbientOcclusion, 1); + + BitfieldAO /= SliceCount; + BitfieldAO = 1 - saturate(BitfieldAO); + //AmbientOcclusion = pow(BitfieldAO, 3); + + // Calculate specular occlusion + float3 ViewDirWS = H_TRANSFORM_VIEW_TO_WORLD_DIR(float3(ViewDirection * float3(1, -1, -1))); + float3 BentNormalWS = H_TRANSFORM_VIEW_TO_WORLD_NORMAL(float3(BentNormal * float3(1, -1, -1))); + float Roughness = HBUFFER_ROUGHNESS(pixCoord.xy); + // float ReflectionOcclusion = SpecularOcclusion(ViewDirWS, BentNormalWS, NormalCenterWS, saturate(AmbientOcclusion), Roughness); + // ReflectionOcclusion = max(ReflectionOcclusion, 0); + + _NormalDepthHalf_Output[H_COORD(pixCoord.xy / 2)] = float4(NormalCenterWS.xyz, DepthCenterRaw.x); + _BentNormalAmbientOcclusion_Output[H_COORD(pixCoord.xy / 2)] = float4(BentNormalWS, AmbientOcclusion); +} + +[numthreads(8, 8, 1)] +void OcclusionInterpolation(uint3 pixCoord : SV_DispatchThreadID) +{ + + + float DepthCenter = HBUFFER_DEPTH(pixCoord.xy); + float DepthCenterLinear = H_LINEAR_EYE_DEPTH(DepthCenter); + float3 NormalCenter = HBUFFER_NORMAL_WS(pixCoord.xy); + + float2 pixCoordNDC = (pixCoord.xy + 0.5f) * _ScreenSize.zw; + float3 WorldPosCenter = H_COMPUTE_POSITION_WS(pixCoordNDC, DepthCenter, H_MATRIX_I_VP); + float4 Plane = float4(NormalCenter.xyz, dot(WorldPosCenter, NormalCenter.xyz)); + + float AccumulatedWeight = 0; + float4 InterpolatedOcclusion = 0; + + for (int x = 0; x < 2; x++) + { + for (int y = 0; y < 2; y++) + { + int2 TapCoord = pixCoord.xy / 2 + uint2(x, y); + float2 TapCoordNDC = (floor(pixCoord.xy / 2) * 2 + 0.5f) * _ScreenSize.zw; + + float4 NormalDepthSample = H_LOAD(_NormalDepthHalf, TapCoord); + + float DepthSample = H_LINEAR_EYE_DEPTH(NormalDepthSample.w); + float DepthWeight = DepthWeighting(DepthCenterLinear, DepthSample, 1.0f); + float3 WorldPos = H_COMPUTE_POSITION_WS(TapCoordNDC, NormalDepthSample.w, H_MATRIX_I_VP); + float PlaneWeight = ProbePlaneWeighting(Plane, WorldPos, DepthCenterLinear, 100); + float NormalWeight = saturate(dot(NormalDepthSample.xyz, NormalCenter)); + + float4 OcclusionSample = H_LOAD(_AmbientOcclusion, TapCoord); + + InterpolatedOcclusion += OcclusionSample * PlaneWeight * NormalWeight; + + float Weight = 1 * PlaneWeight * NormalWeight; + AccumulatedWeight += Weight; + } + } + + if (AccumulatedWeight > 0) + InterpolatedOcclusion /= AccumulatedWeight; + + + float3 GeometryNormal = HBUFFER_GEOMETRICAL_NORMAL_FROM_DEPTH(pixCoord.xy); + _GeometryNormal_Output[H_COORD(pixCoord.xy)] = float4(GeometryNormal, 1); + + _BentNormalAO_Output[H_COORD(pixCoord.xy)] = InterpolatedOcclusion; // H_LOAD(_AmbientOcclusion, pixCoord.xy / 2);; +} + +[numthreads(8, 8, 1)] +void OcclusionAccumulation(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) +{ + + + float2 MotionVectors = HBUFFER_MOTION_VECTOR(pixCoord.xy); + float2 ReprojectionCoordNDC = (pixCoord.xy + 0.5f) * _ScreenSize.zw - MotionVectors; + + float DepthCurrent = HBUFFER_DEPTH(pixCoord.xy); + float3 NormalCurrent = HBUFFER_NORMAL_WS(pixCoord.xy); + float3 WorldPosCurrent = H_COMPUTE_POSITION_WS((pixCoord.xy + 0.5f) * _ScreenSize.zw, DepthCurrent, H_MATRIX_I_VP); + float4 NormalPlane = float4(NormalCurrent.xyz, dot(WorldPosCurrent, NormalCurrent.xyz)); + + float4 AmbientOcclusionHistory = 0; + float4 AmbientOcclusion = H_LOAD(_AmbientOcclusion, pixCoord.xy); + + uint SampleCount = 1; + if (all(ReprojectionCoordNDC > 0) && all(ReprojectionCoordNDC < 1)) + { + uint2 NormalDepthHistoryPacked = asuint(H_SAMPLE_LOD(_NormalDepth_History, H_SAMPLER_LINEAR_CLAMP, ReprojectionCoordNDC * HRenderScale.xy, 0).xy); + float4 NormalDepthReprojected = UnpackNormalDepthFull(NormalDepthHistoryPacked); + + float3 WorldPosPrevious = H_COMPUTE_POSITION_WS(ReprojectionCoordNDC, NormalDepthReprojected.w, H_MATRIX_PREV_I_VP); + float PlaneWeight = ProbePlaneWeighting(NormalPlane, WorldPosPrevious, H_LINEAR_EYE_DEPTH(DepthCurrent), 100); + + if (PlaneWeight > 0.1f) + { + AmbientOcclusionHistory = H_SAMPLE_LOD(_AmbientOcclusion_History, H_SAMPLER_LINEAR_CLAMP, ReprojectionCoordNDC * HRenderScale.xy, 0); + uint SampleCountHistory = asuint(H_SAMPLE_LOD(_SampleCount_History, H_SAMPLER_LINEAR_CLAMP, ReprojectionCoordNDC * HRenderScale.xy, 0).x); + SampleCount = min(8, SampleCountHistory + 1); + } + } + + float TemporalWeight = 1.0f - (1.0f / float(SampleCount)); + AmbientOcclusion = lerp(AmbientOcclusion, AmbientOcclusionHistory, 0); + + _AmbientOcclusion_Output[H_COORD(pixCoord.xy)] = AmbientOcclusion.w; + _SampleCount_Output[H_COORD(pixCoord.xy)] = SampleCount; + _BentNormalAO_Output[H_COORD(pixCoord.xy)] = AmbientOcclusion; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRenderAO.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRenderAO.compute.meta new file mode 100644 index 000000000..30bd903ea --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRenderAO.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 370dd8403c3da0b4cacbfcec52a69468 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HRenderAO.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReservoirValidation.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReservoirValidation.compute new file mode 100644 index 000000000..e5d227b97 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReservoirValidation.compute @@ -0,0 +1,306 @@ +#pragma kernel OcclusionValidation +#pragma kernel OcclusionReprojection +#pragma kernel OcclusionSpatialFilter +#pragma kernel OcclusionTemporalFilter + +#pragma warning (disable : 3206) + +#include "../Includes/Config.hlsl" +#include "../Includes/Reservoir.hlsl" +#include "../Includes/ScreenTraversal.hlsl" +#include "../Includes/VoxelTraversal.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_SampleCount); +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(_ShadowGuidanceMask); +H_TEXTURE(_ReprojectionCoords); +H_TEXTURE(_SampleCount_History); +H_TEXTURE(_ReprojectionWeights); +H_TEXTURE(_ProbeAmbientOcclusion); +H_TEXTURE(_ShadowGuidanceMask_History); + +H_TEXTURE_ARRAY(_SpatialWeightsPacked); +H_TEXTURE_ARRAY(_SpatialOffsetsPacked); + +H_TEXTURE(_ShadowGuidanceMaskTest); + +H_RW_TEXTURE(float, _SampleCount_Output); +H_RW_TEXTURE(float, _ShadowGuidanceMask_Output); + +RWStructuredBuffer _RayCounter; +RWStructuredBuffer _TracingCoords; +StructuredBuffer _PointDistribution; + +int _IndexXR; + +// ------------------------ OCCLUSION CHECKERBOARD REPROJECTION ----------------------- +[numthreads(8, 8, 1)] +void OcclusionReprojection(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + + // Calculate probe coords + int2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + int2 CellCoord = pixCoord.xy - floor(pixCoord.xy / _OctahedralSize) * _OctahedralSize; + + // Get reprojection coords for previous frame + uint2 BestOffset; bool ReprojectionFailed; + uint2 ReprojectionCoordPacked = asuint(H_LOAD(_ReprojectionCoords, ProbeCoord)).xy; + uint2 ReprojectionCoord = UnpackBestReprojectionCoord(ReprojectionCoordPacked, BestOffset, ReprojectionFailed); + + ReprojectionCoord = ReprojectionCoord * _OctahedralSize + BestOffset * _OctahedralSize + CellCoord; + + // Reproject if possible, otherwise use probe ambient occlusion as a fallback instead + if (!ReprojectionFailed && all((float2)ReprojectionCoord < _ScreenSize.xy / _ProbeSize * _OctahedralSize) && all(ReprojectionCoord > 0)) + { + _ShadowGuidanceMask_Output[H_COORD(pixCoord.xy)] = H_LOAD(_ShadowGuidanceMask_History, ReprojectionCoord).x; + } + else + { + _ShadowGuidanceMask_Output[H_COORD(pixCoord.xy)] = 0; //H_LOAD(_ProbeAmbientOcclusion, ProbeCoord); + } +} + + +// ------------------------ OCCLUSION VALIDATION ----------------------- +[numthreads(8, 8, 1)] +void OcclusionValidation(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + uint IndirectCoordOffsetVR = _ScreenSize.x * _ScreenSize.y * _IndexXR; + uint RayCounterOffsetVR = 10 * _IndexXR; + + uint RayIndex = groupID * 64 + groupIndex; + if (RayIndex >= _RayCounter[1 + 4 + RayCounterOffsetVR]) + return; + + pixCoord.xy = _TracingCoords[RayIndex + IndirectCoordOffsetVR]; + + int2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + int2 CellCoord = pixCoord.xy - floor(pixCoord.xy / _OctahedralSize) * _OctahedralSize; + + // Load probe normal, depth & offset + uint2 ProbeOffset; + float4 NormalDepth = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, ProbeCoord).xy), ProbeOffset); + float2 ProbeCoordNDC = (ProbeCoord.xy * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw; + + // Get reprojection coords for previous frame + uint2 BestOffset; bool ReprojectionFailed; + uint2 ReprojectionCoordPacked = asuint(H_LOAD(_ReprojectionCoords, ProbeCoord).xy); + uint2 ReprojectionCoord = UnpackBestReprojectionCoord(ReprojectionCoordPacked, BestOffset, ReprojectionFailed); + ReprojectionCoord = ReprojectionCoord * _OctahedralSize + BestOffset * _OctahedralSize + CellCoord; + + // Initialize center reservoir + Reservoir ReprojectedReservoir; + ReservoirInitialize(pixCoord.xy, ReprojectedReservoir); + + // Load ray data + uint2 RayDataPacked = asuint(H_LOAD(_ReservoirAtlasRayData, ReprojectionCoord).xy); + if (ReprojectionFailed) + RayDataPacked = asuint(H_LOAD(_ReservoirAtlasRayData_Disocclusion, pixCoord.xy).xy); + + // Unpack ray data + UnpackRayData(RayDataPacked, ReprojectedReservoir.Ray); + + // Get max ray distance for tracing + float OcclusionTracingDistance = min(MAX_OCCLUSION_TRACING_DISTANCE, ReprojectedReservoir.Ray.Distance); + + // Initialize both screen-space and world-space hits to false + bool HitFoundWS = false; + bool HitFoundSS = false; + + // Load center pixel data + float3 RayDirectionWS = ReprojectedReservoir.Ray.Direction; + float3 PositionWS = H_COMPUTE_POSITION_WS(ProbeCoordNDC.xy, NormalDepth.w, H_MATRIX_I_VP); + + // Calculate biased ray origin and ray directrion in NDC space + float3 RayStartPositionNDC, RayDirectionNDC; + GetRayOriginAndDirectionNDC(NormalDepth.w, OcclusionTracingDistance, ProbeCoordNDC, PositionWS, RayDirectionWS, NormalDepth.xyz, RayStartPositionNDC, RayDirectionNDC); + + // Raymarch Hi-Z depth buffer + float3 HitPositionNDC, LastAboveSurfacePositionNDC; + HierarchicalRaymarch(RayStartPositionNDC, RayDirectionNDC, 30, HitPositionNDC, LastAboveSurfacePositionNDC); + HitPositionNDC.xy = floor(HitPositionNDC.xy * _ScreenSize.xy) * _ScreenSize.zw + (0.5 * _ScreenSize.zw); + + // Get hit point depth, position & ray distance + float3 HitPositionWS = HitPositionNDC.z > 1e-7 ? H_COMPUTE_POSITION_WS(HitPositionNDC.xy, HitPositionNDC.z, H_MATRIX_I_VP) : PositionWS; + float HitSurfaceLinear = H_LINEAR_EYE_DEPTH(H_LOAD(g_HTraceDepthPyramidWSGI, HitPositionNDC.xy * _ScreenSize.xy).x); + float HitDepthLinear = H_LINEAR_EYE_DEPTH(HitPositionNDC.z); + float HitDistanceWS = length(PositionWS - HitPositionWS); + + // Evaluate occluder thickness + float Thickness = AdaptiveThicknessSearch(HitPositionWS, RayDirectionWS); + + // Evaluate validity of the screen-space hit + if (abs(HitDepthLinear - HitSurfaceLinear) < Thickness && HitDepthLinear > HitSurfaceLinear) + HitFoundSS = true; + + // Initialize voxel ray payload + VoxelPayload Payload; + InitializePayload(Payload); + + // If our screen-space hit is invalid and the remaining tracing distance is larger than a voxel - continue in world-space + if (HitFoundSS != true && HitDistanceWS < OcclusionTracingDistance - _VoxelSize) + { + // Start world space tracing where the screen space part finished + float3 RayOriginWS = PositionWS + HitDistanceWS * RayDirectionWS; + + //If the ray travelled less than half a voxel - reset it to origin + if (HitDistanceWS <= _VoxelSize * 0.5f) + { + RayOriginWS = PositionWS; + HitDistanceWS = 0; + } + + // Apply voxel bias + VoxelBias(pixCoord.xy, _PointDistribution, NormalDepth.w, HitDistanceWS, NormalDepth.xyz, RayDirectionWS, RayOriginWS); + + // Trace into Voxels + HitFoundWS = TraceVoxelsOcclusion(RayOriginWS, RayDirectionWS.xyz, OcclusionTracingDistance - HitDistanceWS, 50, Payload.HitDistance); + + // If hit wasn't found + if (!HitFoundWS) + Payload.HitDistance = OcclusionTracingDistance; + + HitDistanceWS += Payload.HitDistance; + } + + float ShadowGuidanceMask = 1; + + // If we have a hit either in screen-space or in world-space + if (HitFoundWS || HitFoundSS) + { + // If the distance difference is relatively high + if (abs(HitDistanceWS - ReprojectedReservoir.Ray.Distance) / (ReprojectedReservoir.Ray.Distance + ReprojectedReservoir.Ray.Distance) > 0.25) + { + ShadowGuidanceMask = lerp(0, 1, saturate(HitDistanceWS / OcclusionTracingDistance)); + } + } + + // This helps to hide voxel artifacts which appear when ss rays go behind surfaces or offscreen + if (HitDistanceWS <= _VoxelSize.x && !HitFoundSS) + ShadowGuidanceMask = lerp(1, ShadowGuidanceMask, saturate(length(PositionWS) / 5.0f)); + + // if (ReprojectionFailed) // && (pixCoord.y / 4 * 6 > _ScreenSize.y * 0.5)) + // ShadowGuidanceMask = 1; //H_LOAD(_ProbeAmbientOcclusion, ProbeCoord); + // + + // Output + _ShadowGuidanceMask_Output[H_COORD(pixCoord.xy)] = ShadowGuidanceMask; +} + + +// ------------------------ OCCLUSION TEMPORAL FILTER ---------------------- +[numthreads(8, 8, 1)] +void OcclusionTemporalFilter(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + // Calculate probe coords + int2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + int2 CellCoord = pixCoord.xy - floor(pixCoord.xy / _OctahedralSize) * _OctahedralSize; + + // Load reprojection coords and weights + int2 ReprojectionCoord = UnpackReprojectionCoord(asuint(H_LOAD(_ReprojectionCoords, ProbeCoord)).xy); + float4 ReprojectionWeights = H_LOAD(_ReprojectionWeights, ProbeCoord); + + // Normalize reprojection weights + float WeightsSumm = max(ReprojectionWeights.x + ReprojectionWeights.y + ReprojectionWeights.z + ReprojectionWeights.w, 1.0e-3); + ReprojectionWeights /= WeightsSumm; + + // Reproject samplecount + float4 SampleCountHistory; + SampleCountHistory.x = H_LOAD(_SampleCount_History, ReprojectionCoord).x * ReprojectionWeights.x; + SampleCountHistory.y = H_LOAD(_SampleCount_History, ReprojectionCoord).x * ReprojectionWeights.y; + SampleCountHistory.z = H_LOAD(_SampleCount_History, ReprojectionCoord).x * ReprojectionWeights.z; + SampleCountHistory.w = H_LOAD(_SampleCount_History, ReprojectionCoord).x * ReprojectionWeights.w; + float SampleCountReprojected = SampleCountHistory.x + SampleCountHistory.y + SampleCountHistory.z + SampleCountHistory.w; + + // Reproject shadow guidance mask + float4 ShadowGuidanceMaskHistory; + ShadowGuidanceMaskHistory.x = H_LOAD(_ShadowGuidanceMask_History, ReprojectionCoord * _OctahedralSize + uint2(0, 0) * _OctahedralSize + CellCoord).x * ReprojectionWeights.x; + ShadowGuidanceMaskHistory.y = H_LOAD(_ShadowGuidanceMask_History, ReprojectionCoord * _OctahedralSize + uint2(1, 0) * _OctahedralSize + CellCoord).x * ReprojectionWeights.y; + ShadowGuidanceMaskHistory.z = H_LOAD(_ShadowGuidanceMask_History, ReprojectionCoord * _OctahedralSize + uint2(0, 1) * _OctahedralSize + CellCoord).x * ReprojectionWeights.z; + ShadowGuidanceMaskHistory.w = H_LOAD(_ShadowGuidanceMask_History, ReprojectionCoord * _OctahedralSize + uint2(1, 1) * _OctahedralSize + CellCoord).x * ReprojectionWeights.w; + float ShadowGuidanceMaskReprojected = ShadowGuidanceMaskHistory.x + ShadowGuidanceMaskHistory.y + ShadowGuidanceMaskHistory.z + ShadowGuidanceMaskHistory.w; + + // Update samplecount + float SampleCount = min(MAX_OCCLUSION_TEMPORAL_SAMPLES, SampleCountReprojected + 1); + float TemporalWeight = 1.0f - (1.0f / float(SampleCount)); + + // Temporally accumulate shadow guidance mask + float ShadowGuidanceMask = H_LOAD(_ShadowGuidanceMask, pixCoord.xy).x; + ShadowGuidanceMask = lerp(ShadowGuidanceMask, ShadowGuidanceMaskReprojected, TemporalWeight); + + // Output + _ShadowGuidanceMask_Output[H_COORD(pixCoord.xy)] = ShadowGuidanceMask; + _SampleCount_Output[H_COORD(pixCoord.xy / _OctahedralSize)] = SampleCount; +} + + +// ------------------------ OCCLUSION SPATIAL FILTER ----------------------- +[numthreads(8, 8, 1)] +void OcclusionSpatialFilter(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + + // Calculate probe and cell coord + int2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + int2 CellCoord = pixCoord.xy - floor(pixCoord.xy / _OctahedralSize) * _OctahedralSize; + + // Unpack occlusion (passed with packed radiance data) + float ShadowGuidanceMask = H_LOAD(_ShadowGuidanceMask, pixCoord.xy).x; + float WeightAccumualated = 1; + + // Scale filter weight based on the accumulated samplecount + float SampleCount = H_LOAD(_SampleCount, ProbeCoord).x; + float SpatialWeight = lerp(1, 0, (SampleCount / 16)); + + // Load packed sample weights and coords + float SampleWeights[8]; int2 SampleOffsets[8]; + uint4 PackedSampleOffsets = asuint(H_LOAD_ARRAY(_SpatialOffsetsPacked, ProbeCoord, 0)); + uint4 PackedSampleWeights = asuint(H_LOAD_ARRAY(_SpatialWeightsPacked, ProbeCoord, 0)); + + // Unpack sample weights and coords + UnpackFilteringOffsetsX8(PackedSampleOffsets, SampleOffsets); + UnpackFilteringWeightsX8(PackedSampleWeights, SampleWeights); + + for (int i = 0; i < 8; i++) + { + int2 CellTapCoord = ProbeCoord * _OctahedralSize + SampleOffsets[i] * _OctahedralSize + CellCoord; + ShadowGuidanceMask += H_LOAD(_ShadowGuidanceMask, CellTapCoord).x * SampleWeights[i] * SpatialWeight; + WeightAccumualated += SampleWeights[i] * SpatialWeight; + } + + ShadowGuidanceMask /= WeightAccumualated; + + // Load packed reservoir with radiance data + uint2 RadianceDataPacked = asuint(H_LOAD(_ReservoirAtlasRadianceData_Inout, pixCoord.xy).xy); + + bool TemporalInvalidation; + UnpackOcclusion(RadianceDataPacked.x, TemporalInvalidation); + + RadianceDataPacked.x &= 0xFFFFFF; + + float Gathered; + int2 TestCoord = floor(pixCoord.xy / _OctahedralSize); + // for (int x = 0; x < 4; x++) + // { + // for (int y = 0; y < 4; y++) + // { + // Gathered += H_LOAD(_ShadowGuidanceMask, TestCoord * 4 + int2(x,y)); + // } + // } + + Gathered /= 16.0f; + + // if (SampleCount == 1) + // ShadowGuidanceMask = 1; + + // Combine radiance data with shadow guidance mask + RadianceDataPacked.x |= PackOcclusion(ShadowGuidanceMask, TemporalInvalidation); + + // Output for reservoir spatial reuse + _ReservoirAtlasRadianceData_Inout[H_COORD(pixCoord.xy)] = RadianceDataPacked.xy; + + _ShadowGuidanceMask_Output[H_COORD(pixCoord.xy)] = ShadowGuidanceMask; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReservoirValidation.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReservoirValidation.compute.meta new file mode 100644 index 000000000..955cd0713 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReservoirValidation.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 9d0510465eff9c14ebfa427c933f197a +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HReservoirValidation.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HSpatialPrepass.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HSpatialPrepass.compute new file mode 100644 index 000000000..bbe36f969 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HSpatialPrepass.compute @@ -0,0 +1,297 @@ +#pragma kernel SpatialPrepass +#pragma kernel GeometryNormals +#pragma kernel GBufferDownsample +#pragma kernel PointDistributionFill +#pragma kernel SpatialOffsetsBufferFill +#pragma kernel GeometryNormalsSmoothing + +#pragma multi_compile _ USE_DIRECTIONAL_OCCLUSION +#pragma multi_compile _ DIFFUSE_BUFFER_UNAVAILABLE + +#include "../Includes/Config.hlsl" +#include "../Includes/Reservoir.hlsl" +#include "../Includes/SpatialFilteringFunctions.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + + +H_TEXTURE(_SSAO); +H_TEXTURE(g_GeometryNormal); +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(_ProbeAmbientOcclusion); +H_TEXTURE(_NormalDepthDownsampled); + +H_RW_TEXTURE_ARRAY(uint4, _SpatialOffsets_Output); +H_RW_TEXTURE_ARRAY(uint4, _SpatialWeights_Output); + +H_RW_TEXTURE(float, _ProbeSSAO_Output); +H_RW_TEXTURE(float3, _ProbeDiffuse_Output); +H_RW_TEXTURE(float4, _GeometryNormal_Output); +H_RW_TEXTURE(uint2, _ProbeNormalDepth_Output); + +StructuredBuffer _PointDistribution; +StructuredBuffer _SpatialOffsetsBuffer; +RWStructuredBuffer _PointDistribution_Output; +RWStructuredBuffer _SpatialOffsetsBuffer_Output; + +uint _DiffuseBufferUnavailable; + +void ClearArrays(inout int2 SampleCoords[8], inout float SampleWeights[8]) +{ + for (int i = 0; i < 8; i++) + { + SampleCoords[i] = int2(0, 0); + SampleWeights[i] = 0.0f; + } +} + + +// ------------------------ POINT DISTRIBUTION BUFFER ------------------------ +[numthreads(128, 1, 1)] +void PointDistributionFill(uint pixCoord : SV_DispatchThreadID) +{ + _PointDistribution_Output[pixCoord.x] = HSampleDiskCubic(GetLDSequenceSampleFloat(pixCoord.x, 0), GetLDSequenceSampleFloat(pixCoord.x, 1)); +} + + +// ------------------------ SPATIAL OFFSETS BUFFER ------------------------ +[numthreads(1, 1, 1)] +void SpatialOffsetsBufferFill(uint pixCoord : SV_DispatchThreadID) +{ + int2 SampleOffsets[80] = {int2( 0, 1), int2( 1, 0), int2( 1, 1), int2(-1, 0), int2(-1, 1), int2(-1, -1), int2( 0, -1), int2( 1, -1), + int2(-2, 0), int2( 0, -2), int2( 2, 0), int2( 0, 2), int2(-1, 2), int2(-2, 1), int2( 1, -2), int2( 2, -1), + int2(-2, -1), int2(-1, -2), int2( 2, 1), int2( 1, 2), int2(-2, 2), int2( 2, 2), int2( 2, -2), int2(-2, 2), + int2( 0, -3), int2( 0, 3), int2(-3, 0), int2( 3, 0), int2(-3, -1), int2( 3, 1), int2(-1, -3), int2( 1, 3), + int2(-3, 1), int2( 3, -1), int2(-1, 3), int2( 1, -3), int2(-2, 3), int2( 3, -2), int2( 3, 2), int2(-3, -2), + int2( 2, 3), int2(-2, -3), int2(-3, 2), int2( 2, -3), int2(-3, 3), int2( 3, -3), int2( 3, 3), int2(-3, -3), + int2( 0, 4), int2( 0, -4), int2(-4, 0), int2( 4, 0), int2(-4, 1), int2( 1, -4), int2(-1, 4), int2( 4, -1), + int2(-4, 1), int2( 1, 4), int2(-1, -4), int2( 4, 1), int2(-4, 2), int2( 4, 2), int2( 4, -2), int2(-4, 2), + int2( 2, -4), int2(-2, 4), int2(-2, -4), int2( 2, 4), int2(-3, -4), int2( 4, 3), int2(-4, -3), int2( 3, 4), + int2( 3, -4), int2(-4, 3), int2( 4, -3), int2(-3, 4), int2( 4, -4), int2(-4, -4), int2( 4, 4), int2(-4, 4)}; + + for (int i = 0; i < 80; i++) + { + _SpatialOffsetsBuffer_Output[i] = SampleOffsets[i]; + } +} + + +// ------------------------ GEOMETRY NORMALS ------------------------ +[numthreads(8, 8, 1)] +void GeometryNormals(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) +{ + + + float3 GeometryNormal = HBUFFER_GEOMETRICAL_NORMAL_FROM_DEPTH(pixCoord.xy); + _GeometryNormal_Output[H_COORD(pixCoord.xy)] = float4(GeometryNormal, 1); +} + + +// ------------------------ GBUFFER DOWNSAMPLE ------------------------ +[numthreads(8, 8, 1)] +void GBufferDownsample(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) +{ + + + uint2 ProbeOffset = CalculateHaltonSequence(uint(_FrameCount) % _PersistentHistorySamples) * float(_ProbeSize); + + if (DISABLE_PROBE_JITTER) + ProbeOffset = uint2(0,0); + + float Depth = HBUFFER_DEPTH(pixCoord.xy * _ProbeSize + ProbeOffset); + float3 GeometryNormal = H_LOAD(g_GeometryNormal, pixCoord.xy * _ProbeSize + ProbeOffset).xyz; + float3 Diffuse = float3(1.0f, 1.0f, 1.0f); + + #ifndef DIFFUSE_BUFFER_UNAVAILABLE + Diffuse = HBUFFER_DIFFUSE(pixCoord.xy * _ProbeSize + ProbeOffset).xyz; + #endif + + #if USE_DIRECTIONAL_OCCLUSION + _ProbeSSAO_Output[H_COORD(pixCoord.xy)] = H_LOAD(_SSAO, pixCoord.xy * _ProbeSize + ProbeOffset).w; + #endif + + _ProbeDiffuse_Output[H_COORD(pixCoord.xy)] = Diffuse; + _ProbeNormalDepth_Output[H_COORD(pixCoord.xy)] = PackNormalDepth2(GeometryNormal, Depth, ProbeOffset); +} + + +// ------------------------ SMOOTH GEOMETRY NORMALS ------------------------ +[numthreads(8, 8, 1)] +void GeometryNormalsSmoothing(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) +{ + + + uint2 ProbeOffset; + float4 NormalDepthCenter = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy).xy), ProbeOffset); + float3 WorldPosCenter = H_COMPUTE_POSITION_WS((pixCoord.xy * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw, NormalDepthCenter.w, H_MATRIX_I_VP); + + float3 NormalGathered = NormalDepthCenter.xyz; + + for (int x = -4; x <= 4; x++) + { + for (int y = -5; y <= 4; y++) + { + if (x == 0 && y == 0) + continue; + + int2 TapOffset = int2(x,y); + int2 TapCoord = pixCoord.xy + TapOffset; + + // if (any(TapCoord.xy < 0) || any(TapCoord.xy > _ScreenSize.xy * _ProbeSize)) + // continue; + + uint2 ProbeOffset; + float4 NormalDepthSample = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, TapCoord.xy).xy), ProbeOffset); + float3 WorldPosSample = H_COMPUTE_POSITION_WS((TapCoord * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw, NormalDepthSample.w, H_MATRIX_I_VP); + + float NormalWeight = saturate(dot(NormalDepthCenter.xyz, NormalDepthSample.xyz)); + float PlaneWeight = PlaneWeighting(WorldPosCenter, WorldPosSample, NormalDepthCenter.xyz, NormalDepthSample.xyz, 1); + + NormalGathered += NormalDepthSample.xyz * PlaneWeight * pow(NormalWeight, 2); + } + } + + float3 NormalDepthSmoothed = HSafeNormalize(NormalGathered); + + _ProbeNormalDepth_Output[H_COORD(pixCoord.xy)] = PackNormalDepth2(NormalDepthSmoothed.xyz, NormalDepthCenter.w, ProbeOffset); +} + + +// ------------------------ FILTERING WEIGHTS & OFFSETS RPEPASS ------------------------ +[numthreads(8, 8, 1)] +void SpatialPrepass(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) +{ + + + // Load center pixel data + uint2 ProbeOffset; + float4 NormalDepthCenter = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy).xy), ProbeOffset); + float2 pixCoordNDC = (pixCoord.xy * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw; + + float2 AmbientOcclusion = UnpackProbeAO(asuint(H_LOAD(_ProbeAmbientOcclusion, pixCoord.xy).x), PROBE_AO_MAX_TEMPORAL_SAMPLES); + float3 WorldPosCenter = H_COMPUTE_POSITION_WS(pixCoordNDC, NormalDepthCenter.w, H_MATRIX_I_VP); + float4 NormalPlane = float4(NormalDepthCenter.xyz, dot(WorldPosCenter, NormalDepthCenter.xyz)); + float3 NormalCenter = NormalDepthCenter.xyz; + + // Prepare offset and weight buffers + int2 BoxTapOffsets[8] = {int2(0, 1), int2(1, 0), int2(0, -1), int2(-1, 0), int2(-1, 1), int2(-1, -1), int2(1, 1), int2(1, -1)}; + int2 SampleOffsetsX8[8] = {int2(0, 0), int2(0, 0), int2(0, 0), int2(0, 0), int2(0, 0), int2(0, 0), int2(0, 0), int2(0, 0)}; + float SampleWeightsX8[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; + + // -------------------------- BOX PASS -------------------------- // + int NumSamplesFound = 0; + for (int i = 0; i < 8; i++) + { + // if (NumSamplesFound >= 8) + // break; + + int2 TapOffset = BoxTapOffsets[i]; + int2 TapCoord = pixCoord.xy + TapOffset; + + // if (any(TapCoord.xy < 0) || any(TapCoord.xy > _ScreenSize.xy * _ProbeSize)) // TODO: do we need this? + // continue; + + uint2 ProbeOffset; + float4 NormalDepthSample = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, TapCoord).xy), ProbeOffset); + float3 WorldPosSample = H_COMPUTE_POSITION_WS((TapCoord * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw, NormalDepthSample.w, H_MATRIX_I_VP); + + float NormalWeight = saturate(dot(NormalCenter, NormalDepthSample.xyz)); + float PlaneWeight = ProbePlaneWeighting(NormalPlane, WorldPosSample, H_LINEAR_EYE_DEPTH(NormalDepthSample.w), 1000.0f); + //PlaneWeight = PlaneWeighting(WorldPosCenter, WorldPosSample, NormalCenter, NormalDepthSample.xyz, 4); + + float Weight = NormalWeight * PlaneWeight; + + // if (Weight > BOX_FILTER_MINIMUM_ACCEPT_WEIGHT) + // { + // SampleOffsetsX8[NumSamplesFound] = TapCoord - pixCoord.xy; + // SampleWeightsX8[NumSamplesFound] = Weight; + // NumSamplesFound++; + // } + + SampleOffsetsX8[i] = TapCoord - pixCoord.xy; + SampleWeightsX8[i] = Weight; + } + + _SpatialWeights_Output[uint3(pixCoord.xy, H_INDEX_ARRAY(0))] = PackFilteringWeightsX8(SampleWeightsX8); + _SpatialOffsets_Output[uint3(pixCoord.xy, H_INDEX_ARRAY(0))] = PackFilteringOffsetsX8(SampleOffsetsX8); + + + // -------------------------- DISK PASSES -------------------------- // + float DistanceToPoint = length(H_GET_ABSOLUTE_POSITION_WS(WorldPosCenter) - H_GET_CAMERA_POSITION_WS());// length(WorldPosCenter); + float3x3 OrthoBasis = HGetLocalFrame(NormalCenter); + + float RadiusScale = lerp(5.0f, 50.0f, saturate(DistanceToPoint / 500.0f)); + float AmbientOcclusionRadiusScale = lerp(0.3f, 1.0f, pow(AmbientOcclusion.x, 3)); + float TemporalAccumulationWeight = AmbientOcclusion.y / float(PROBE_AO_MAX_TEMPORAL_SAMPLES); + + float FilterRadius = DISK_FILTER_MIN_RADIUS; + float RadiusStep = DISK_FILTER_STEP_SIZE; + + UNITY_UNROLL + for (int k = 0; k < 3; k++) + { + float Jitter = GetBNDSequenceSample(pixCoord.xy, 0, 3 + k); + float Radius = DistanceToPoint * FilterRadius / RadiusScale * lerp(1.5, 1, TemporalAccumulationWeight); + // ClearArrays(SampleOffsetsX8, SampleWeightsX8); // TODO: do we need this? + + if (DISK_FILTER_USE_AO_GUIDED_RADIUS) + { + float RadiusUnscaled = Radius; + Radius *= AmbientOcclusionRadiusScale; + Radius = min(max(Radius, 0.05), RadiusUnscaled); + } + + float Sigma = 0.9f * Radius; + + int NumSamplesFound = 0; + for (int i = 0; i < DISK_FILTER_MAX_SEARCH_SAMPLES; i++) + { + if (NumSamplesFound >= 8) + break; + + // Calculate sample coords + float2 Sample = _PointDistribution[i + Jitter * 56] * Radius; + float3 SamplePosWS = WorldPosCenter + OrthoBasis[0] * Sample.x + OrthoBasis[1] * Sample.y; + float4 SamplePosHC = H_TRANSFORM_WORLD_TO_H_CLIP(SamplePosWS); + SamplePosHC.xyz /= SamplePosHC.w; + float2 SamplePosSS = SamplePosHC.xy * 0.5f + 0.5f; + SamplePosSS.y = 1.0f - SamplePosSS.y; + int2 TapCoord = (SamplePosSS * _ScreenSize.xy) / _ProbeSize; + float2 TapCoordNDC = (TapCoord + 0.5f) * _ScreenSize.zw * float(_ProbeSize); + + if (any(SamplePosHC.xy > 1.0f) || any(SamplePosHC.xy < -1.0f)) // TODO: do we need this? + continue; + + // Load sample data + uint2 ProbeOffset; + float4 NormalDepthSample = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, TapCoord).xy), ProbeOffset); //npackNormalDepth(asuint(H_LOAD(_NormalDepthDownsampled, TapCoord))); + float3 WorldPosSample = H_COMPUTE_POSITION_WS((TapCoord * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw, NormalDepthSample.w, H_MATRIX_I_VP); + + float SampleRadius = length(Sample); + + // Calculate sample normal & plane weights + float NormalWeight = saturate(dot(NormalCenter, NormalDepthSample.xyz)); + float PlaneWeight = ProbePlaneWeighting(NormalPlane, WorldPosSample, H_LINEAR_EYE_DEPTH(NormalDepthSample.w), 1000.0f); + float GaussianWeight = SampleRadius > 0.001f ? GaussianWeighting(SampleRadius, Sigma) : 1.0f; + + // If the distance to the sample is acceptable - use more accurate plane estimation + if (abs(H_LINEAR_EYE_DEPTH(NormalDepthSample.w) - SamplePosHC.w) < 0.1) + PlaneWeight = PlaneWeighting(WorldPosCenter, WorldPosSample, NormalCenter, NormalDepthSample.xyz, 4); + + // Combine all weights + float Weight = NormalWeight * PlaneWeight * lerp(1, GaussianWeight, TemporalAccumulationWeight); + + // Store sample weight & offset if it is above the threshold + if (Weight > DISK_FILTER_MINIMUM_ACCEPT_WEIGHT) + { + SampleOffsetsX8[NumSamplesFound] = TapCoord - pixCoord.xy; + SampleWeightsX8[NumSamplesFound] = Weight; + NumSamplesFound++; + } + } + + _SpatialWeights_Output[uint3(pixCoord.xy, H_INDEX_ARRAY(1 + k))] = PackFilteringWeightsX8(SampleWeightsX8); + _SpatialOffsets_Output[uint3(pixCoord.xy, H_INDEX_ARRAY(1 + k))] = PackFilteringOffsetsX8(SampleOffsetsX8); + + FilterRadius += RadiusStep; + } +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HSpatialPrepass.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HSpatialPrepass.compute.meta new file mode 100644 index 000000000..f875f9ce3 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HSpatialPrepass.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 1a7c84891a83d924996e32cd4dd8502a +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HSpatialPrepass.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalDenoiser.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalDenoiser.compute new file mode 100644 index 000000000..21d59715f --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalDenoiser.compute @@ -0,0 +1,247 @@ +#pragma kernel TemporalDenoising +#pragma kernel SpatialCleanup + +#include "../Includes/Config.hlsl" +#include "../Includes/Reservoir.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_Radiance); +H_TEXTURE(g_GeometryNormal); +H_TEXTURE(_Radiance_History); +H_TEXTURE(_NormalDepth_History); +H_RW_TEXTURE(float4, _Radiance_Output); + +groupshared uint RadianceLDS[16][16]; + + +void FillRadianceLDS(int2 pixCoord, int2 groupThreadID) +{ + pixCoord.xy -= 4; + + RadianceLDS[groupThreadID.x + 0][groupThreadID.y + 0] = asuint(H_LOAD(_Radiance, pixCoord.xy + int2(0, 0)).x); + RadianceLDS[groupThreadID.x + 8][groupThreadID.y + 0] = asuint(H_LOAD(_Radiance, pixCoord.xy + int2(8, 0)).x); + RadianceLDS[groupThreadID.x + 0][groupThreadID.y + 8] = asuint(H_LOAD(_Radiance, pixCoord.xy + int2(0, 8)).x); + RadianceLDS[groupThreadID.x + 8][groupThreadID.y + 8] = asuint(H_LOAD(_Radiance, pixCoord.xy + int2(8, 8)).x); +} + +float DisocclusionDetection(CurrentFrameData CurrentData, PrevFrameData PrevData) +{ + float PlaneMultiplier = CurrentData.MovingPixel ? 100.0f : 100000.0f; //TODO: make it 5000 for the editor window + float DepthMultiplier = CurrentData.MovingPixel ? 20.0f : 1.0f; + + float PlaneDistance = abs(dot(PrevData.WorldPos - CurrentData.WorldPos, CurrentData.Normal)); + float RelativeDepthDifference = PlaneDistance / CurrentData.DepthLinear; + if (exp2(-PlaneMultiplier * (RelativeDepthDifference * RelativeDepthDifference )) < 0.1f) + return 0; + + float DepthThreshold = lerp(1e-2f, 1e-1f, CurrentData.AligmentZ); + if (abs((PrevData.DepthLinear - CurrentData.DepthLinear) / CurrentData.DepthLinear) >= DepthThreshold * DepthMultiplier) + return 0; + + if (USE_NORMAL_REJECTION) + { + float NormalThreshold = lerp(1, CurrentData.AligmentZ, saturate(length(CurrentData.WorldPos) / 5)); + if (dot(PrevData.Normal, CurrentData.Normal) < lerp(0.0, 0.95, NormalThreshold)) + return 0; + } + + return 1; +} + + + +// ------------------------ TEMPORAL DENOISING KERNEL ------------------------ +[numthreads(8, 8, 1)] +void TemporalDenoising(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint2 groupId : SV_GroupID) +{ + + + // Transfer data to LDS + FillRadianceLDS(pixCoord.xy, groupThreadID); + GroupMemoryBarrierWithGroupSync(); + groupThreadID += 4; + + // Fetch current center radiance from LDS + bool IsValid; + float3 Radiance = UnpackFromR11G10B10A1f(RadianceLDS[groupThreadID.x][groupThreadID.y], IsValid); + + // Calculate history coord + float2 CoordHistoryNDC = ((pixCoord.xy - HBUFFER_MOTION_VECTOR(pixCoord.xy) * _ScreenSize.xy) + 0.5f) / _ScreenSize.xy; + + // If history coords are off screen - early out + if (any(CoordHistoryNDC < 0) || any(CoordHistoryNDC > 1)) + { + _Radiance_Output[H_COORD(pixCoord.xy)] = float4(Radiance, 1); + return; + } + + // Load current frame data + CurrentFrameData CurrentData; + CurrentData.DepthRaw = HBUFFER_DEPTH(pixCoord.xy); + CurrentData.Normal = H_LOAD(g_GeometryNormal, pixCoord.xy).xyz; + CurrentData.WorldPos = H_COMPUTE_POSITION_WS((pixCoord.xy + 0.5f) * _ScreenSize.zw, CurrentData.DepthRaw, H_MATRIX_I_VP); + CurrentData.DepthLinear = H_LINEAR_EYE_DEPTH(CurrentData.WorldPos, H_MATRIX_V); + CurrentData.AligmentZ = 1.0f - dot(-normalize(H_GET_ABSOLUTE_POSITION_WS((CurrentData.WorldPos)) - _WorldSpaceCameraPos), CurrentData.Normal); + CurrentData.MovingPixel = HBUFFER_MOTION_MASK(pixCoord.xy); + + // Early-out on the skybox + if (CurrentData.DepthRaw <= 1e-7) + { + _Radiance_Output[H_COORD(pixCoord.xy)] = 0; + return; + } + + // Calculate manual bilinear sample offsets and weights + float UVx = frac(float(_ScreenSize.x) * CoordHistoryNDC.x + 0.5); + float UVy = frac(float(_ScreenSize.y) * CoordHistoryNDC.y + 0.5); + int2 ReprojectionCoord = int2(_ScreenSize.xy * CoordHistoryNDC - 0.5); + + float4 ReprojectionWeights; + ReprojectionWeights.x = (1.0f - UVx) * (1.0f - UVy); + ReprojectionWeights.y = (UVx) * (1.0f - UVy); + ReprojectionWeights.z = (1.0f - UVx) * (UVy); + ReprojectionWeights.w = (UVx) * (UVy); + + uint2 ReprojectionOffsets[4] = {uint2(0, 0), uint2(1, 0), uint2(0, 1), uint2(1, 1)}; + + UNITY_UNROLL // Go through all bilinear samples and check disocclusion for each sample + for (int i = 0; i < 4; i++) + { + int2 SampleCoord = ReprojectionCoord + ReprojectionOffsets[i]; + float4 NormalDepthHistory = UnpackNormalDepthFull(asuint(H_LOAD(_NormalDepth_History, SampleCoord).xy)); + + PrevFrameData PrevData; + PrevData.WorldPos = H_COMPUTE_POSITION_WS((SampleCoord + 0.5f) / _ScreenSize.xy, NormalDepthHistory.w, H_MATRIX_PREV_I_VP); + PrevData.DepthLinear = H_LINEAR_EYE_DEPTH(PrevData.WorldPos, H_MATRIX_V); + PrevData.Normal = NormalDepthHistory.xyz; + + ReprojectionWeights[i] *= DisocclusionDetection(CurrentData, PrevData); + } + + // Normalize reprojection weights + float WeightsSumm = max(ReprojectionWeights.x + ReprojectionWeights.y + ReprojectionWeights.z + ReprojectionWeights.w, 1.0e-3); + ReprojectionWeights /= WeightsSumm; + + // Load 4 bilinear samples of our history + float4 RadianceHistory = 0; + RadianceHistory += H_LOAD(_Radiance_History, ReprojectionCoord + uint2(0, 0)) * ReprojectionWeights.x; + RadianceHistory += H_LOAD(_Radiance_History, ReprojectionCoord + uint2(1, 0)) * ReprojectionWeights.y; + RadianceHistory += H_LOAD(_Radiance_History, ReprojectionCoord + uint2(0, 1)) * ReprojectionWeights.z; + RadianceHistory += H_LOAD(_Radiance_History, ReprojectionCoord + uint2(1, 1)) * ReprojectionWeights.w; + + // SampleCount is stored in the alpha channel + float SampleCount = RadianceHistory.w; + + float3 Moment1; + float3 Moment2; + float GatheredWeight = 0; + + // Gather local statistics + for (int x = -3; x <= 3; x++) + { + for (int y = -3; y <= 3; y++) + { + float3 RadianceSample = UnpackFromR11G10B10A1f(RadianceLDS[groupThreadID.x + x][groupThreadID.y + y]); + + float Weight = exp(-3.0 * float(x * x + y * y) / float((3 + 1) * (3 + 1))); + + Moment1 += RadianceSample * Weight; + Moment2 += RadianceSample * RadianceSample * Weight; + + GatheredWeight += Weight; + } + } + + Moment1 /= GatheredWeight; + Moment2 /= GatheredWeight; + + float3 StdDev = sqrt(abs(Moment2 - Moment1 * Moment1)); + + // Calculates AABB box extents + float3 ClampMin = Radiance - StdDev * AABB_CLIP_EXTENT; + float3 ClampMax = Radiance + StdDev * AABB_CLIP_EXTENT; + + // Backup unclamped history + float3 RadianceHistoryUnclamped = RadianceHistory.xyz; + + + // Clamp history to AABB box + RadianceHistory.xyz = DirectClipToAABB(RadianceHistory.xyz, ClampMin, ClampMax); + + float lum0 = Luminance(Radiance.rgb); + float lum1 = Luminance(RadianceHistory.rgb); + + float unbiased_diff = abs(lum0 - lum1) / max(lum0, max(lum1, 0.2)); + float unbiased_weight = 1.0 - unbiased_diff; + float unbiased_weight_sqr = unbiased_weight * unbiased_weight; + float MaxSampleCount = lerp(MAX_SAMPLECOUNT / 2, MAX_SAMPLECOUNT, unbiased_weight_sqr); + + SampleCount = min(MaxSampleCount, SampleCount + 1); + + float TemporalWeight = 1.0f - (1.0f / float(SampleCount)); + + // If current radiance is invalid (interpolation has failed) then we replace it with the history radiance if possible + if (!IsValid && any(ReprojectionWeights > 0.1)) + { + // Trade off between reconstruction accuracy and lighting response speed + float MaxLumaDifference = 2; + RadianceHistoryUnclamped *= clamp(Luminance(RadianceHistory.xyz) / max(1e-8, Luminance(RadianceHistoryUnclamped)) * MaxLumaDifference, 0.01, 1.0); + + + // We must use unclamped history radiance as our replacement. + RadianceHistory.xyz = RadianceHistoryUnclamped; + SampleCount = MAX_SAMPLECOUNT; + TemporalWeight = 0.99f; + } + + if (DISABLE_TEMPORAL_DENOISER) + TemporalWeight = 0; + + if (TEMPORAL_DENOISER_EXPOSURE_CONTROL) + { + // Grab the previous frame and current frame exposures + float ExposurePrevious = HGetPreviousExposureMultiplier; + float ExposureCurrent = HGetCurrentExposureMultiplier; + + // Compute the exposure ratio (while avoiding zeros) + float ExposureRatio = (ExposurePrevious * ExposureCurrent) != 0.0 ? ExposureCurrent / ExposurePrevious : 100.0; + + // Evaluate if the exposure multiplier was at least twice bigger or smaller + bool IsExposureValid = max(ExposureRatio, 1.0 / ExposureRatio) < 2.0; + + // If the exposure change was considered valid, we can keep the result and re-exposed it. Otherwise, we cannot use the history buffer + if (IsExposureValid) + { + } + else + { + TemporalWeight = 0; + } + } + + // Blend with history + + Radiance = lerp(Radiance, RadianceHistory.xyz, TemporalWeight) ; //TemporalWeight); + if (AnyIsNaN(Radiance.xyz)) //Black waves in SceneView after entering Runtime + Radiance.xyz = 0; + + // Output radiance & samplecount + _Radiance_Output[H_COORD(pixCoord.xy)] = float4(Radiance, SampleCount); +} + + +H_RW_TEXTURE(uint2, _NormalDepth_HistoryOutput); +H_RW_TEXTURE(float4, _Radiance_HistoryOutput); + +[numthreads(8, 8, 1)] +void SpatialCleanup(uint3 pixCoord : SV_DispatchThreadID, int2 groupThreadID : SV_GroupThreadID, uint2 groupId : SV_GroupID) +{ + + + float Depth = HBUFFER_DEPTH(pixCoord.xy); + float3 Normal = float4(H_LOAD(g_GeometryNormal, pixCoord.xy)).xyz; + _NormalDepth_HistoryOutput[H_COORD(pixCoord.xy)] = PackNormalDepth(Normal, Depth); + + float4 Radiance = H_LOAD(_Radiance, pixCoord.xy); + _Radiance_HistoryOutput[H_COORD(pixCoord.xy)] = Radiance; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalDenoiser.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalDenoiser.compute.meta new file mode 100644 index 000000000..a95226e4c --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalDenoiser.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: e764d5314f178c1499151299696dcfb9 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalDenoiser.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalReprojection.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalReprojection.compute new file mode 100644 index 000000000..52cad5cc8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalReprojection.compute @@ -0,0 +1,299 @@ +#pragma kernel ProbeReprojection +#pragma kernel HistoryIndirectionScroll +#pragma kernel HistoryIndirectionUpdate +#pragma kernel HistoryProbeBuffersUpdate +#pragma kernel CopyHistoryURP +#pragma kernel CopyHistoryBIRP + +#pragma warning (disable : 3206) + +#include "../Includes/Config.hlsl" +#include "../Includes/Reservoir.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(_ReprojectionCoord); +H_TEXTURE_ARRAY(_ProbeWorldPosNormal_History); + +H_RW_TEXTURE(float4, _ReprojectionWeights_Output); +H_RW_TEXTURE(float4, _PersistentReprojectionWeights_Output); +H_RW_TEXTURE(uint2, _ReprojectionCoords_Output); +H_RW_TEXTURE(uint2, _PersistentReprojectionCoord_Output); + +H_RW_TEXTURE_ARRAY(uint2, _HistoryIndirection); +H_RW_TEXTURE_ARRAY(uint4, _ProbeWorldPosNormal_HistoryOutput); + +int _HistoryArrayIndex; + + +// ------------------------ PROBE TEMPORAL REPROJECTION ------------------------ +[numthreads(8, 8, 1)] +void ProbeReprojection(int3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID) +{ + + uint2 ProbeOffset; + float4 NormalDepthDownsampled = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy).xy), ProbeOffset); + + // Fill current frame data + CurrentFrameData CurrentData; + CurrentData.Normal = NormalDepthDownsampled.xyz; + CurrentData.DepthRaw = NormalDepthDownsampled.w; + CurrentData.DepthLinear = H_LINEAR_EYE_DEPTH(CurrentData.DepthRaw); + CurrentData.WorldPos = H_COMPUTE_POSITION_WS((pixCoord.xy * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) / _ScreenSize.xy, CurrentData.DepthRaw, H_MATRIX_I_VP); + CurrentData.WorldPos = H_GET_ABSOLUTE_POSITION_WS(CurrentData.WorldPos); + CurrentData.AligmentZ = 1.0f - dot(-normalize((CurrentData.WorldPos) - _WorldSpaceCameraPos), CurrentData.Normal); + CurrentData.MovingPixel = HBUFFER_MOTION_MASK(pixCoord.xy * float(_ProbeSize)); + + float4 RelaxedWeights[4]; // Relaxed weights are equal to reprojection weights but with a less strict normal cutoff + float4 ReprojectionWeights; float4 BilinearWeights; + int2 PersistentHistoryCoord; int2 ReprojectionCoord; + + // Load and dilate motion vectors + float2 MotionVectors; float ClosestDepth = FLT_MAX; + for (int x = -1; x <= 1; x++) + { + for (int y = -1; y <= 1; y++) + { + uint2 Unused; + float2 MotionVectorsSample = HBUFFER_MOTION_VECTOR(pixCoord.xy * _ProbeSize + int2(x,y) * _ProbeSize); + float4 NormalDepthDownsampled = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy + int2(x,y)).xy), Unused); + + if (NormalDepthDownsampled.w < ClosestDepth && NormalDepthDownsampled.w > 0) + { + ClosestDepth = NormalDepthDownsampled.w; + MotionVectors = MotionVectorsSample; + } + } + } + + // Get initial reprojection (for N-1 frame) and bilinear reprojection weights + GetReprojectionCoord(pixCoord.xy, MotionVectors, BilinearWeights, ReprojectionCoord); + + // Reprojection weights start with simple bilinear weights and will be later multiplied by disocclusion rejection weights + RelaxedWeights[0] = BilinearWeights; + ReprojectionWeights = BilinearWeights; + PersistentHistoryCoord = ReprojectionCoord; + + // Find best reprojection offset based on the highest reprojection (still only bilinear) weight + uint2 ReprojectionOffsets[4] = {uint2(0, 0), uint2(1, 0), uint2(0, 1), uint2(1, 1)}; + float BestReprojectionWeight = 0; + uint2 BestReprojectionOffset = 0; + + // Cycle through all weigths + for (int i = 0; i < 4; i++) + { + if (ReprojectionWeights[i] > BestReprojectionWeight) + { + BestReprojectionWeight = ReprojectionWeights[i]; + BestReprojectionOffset = ReprojectionOffsets[i]; + } + } + + // Get reprojection weights for N-1 frame + bool IsDisocclusion = GetReprojectionWeights(_ProbeWorldPosNormal_History, CurrentData, ReprojectionCoord, GetHistoryIndex(0), ReprojectionWeights, RelaxedWeights[0]); + float BestWeightSumm = ReprojectionWeights.x + ReprojectionWeights.y + ReprojectionWeights.z + ReprojectionWeights.w; + uint ReprojectionIndex = 0; + + // If reprojection weights summ is 0 or reprojection coords lead outside probe atlas - it means we couldn't reproject N-1 frame + bool ReprojectionFailed = false; + int2 MaxAtlasReprojectionCoord = ReprojectionCoord * _OctahedralSize + BestReprojectionOffset * _OctahedralSize + _OctahedralSize; + if (any(MaxAtlasReprojectionCoord > _ScreenSize.xy / _ProbeSize * _OctahedralSize) || BestWeightSumm <= 0.1) + ReprojectionFailed = true; + + // Output reprojection coords and weights and coords for N-1 frame + _ReprojectionWeights_Output[H_COORD(pixCoord.xy)] = ReprojectionWeights; + _ReprojectionCoords_Output[H_COORD(pixCoord.xy)] = PackReprojectionCoord(ReprojectionCoord, BestReprojectionOffset, ReprojectionFailed); + + uint MaxHistoryFrames = DISABLE_PROBE_JITTER ? 1 : _PersistentHistorySamples; + + // Search candidates in persistant history frames (up to N - MaxIterations), starting with (N-2) + for (uint t = 1; t < MaxHistoryFrames; t++) + { + // Good enough, stop the search + if (BestWeightSumm > 0.1) + break; + + RelaxedWeights[t] = BilinearWeights; + float4 SampleReprojectionWeights = BilinearWeights; + + // Get persistant history coordinates + int2 SamplePersistentHistoryCoord = asuint(H_LOAD_ARRAY(_HistoryIndirection, ReprojectionCoord, t).xy); + + // Calculate new reprojection weights + IsDisocclusion = GetReprojectionWeights(_ProbeWorldPosNormal_History, CurrentData, SamplePersistentHistoryCoord, GetHistoryIndex(t), SampleReprojectionWeights, RelaxedWeights[t]); + float SampleBestWeightSumm = SampleReprojectionWeights.x + SampleReprojectionWeights.y + SampleReprojectionWeights.z + SampleReprojectionWeights.w; + + // Accept this sample if it's better than previous samples + if (SampleBestWeightSumm > BestWeightSumm) + { + ReprojectionIndex = t; + BestWeightSumm = SampleBestWeightSumm; + ReprojectionWeights = SampleReprojectionWeights; + PersistentHistoryCoord = SamplePersistentHistoryCoord; + + // Prevents sampling outside of persistant history frames + if (SamplePersistentHistoryCoord.x + SamplePersistentHistoryCoord.y == 0) + ReprojectionWeights = 0; + } + } + + // Search reprojection candidate in 3x3 neighbourhood + if (REPROJECTION_AREA_SEARCH) + { + int2 BoxSampleOffsets[8] = {int2(0, 1), int2(1, 0), int2(0, -1), int2(-1, 0), int2(-1, 1), int2(-1, -1), int2(1, 1), int2(1, -1)}; + + // Do the search only if the current reprojection weight is too low and it's not an obvious disocclusion + if (BestWeightSumm < 0.1 && !IsDisocclusion) + { + for (uint i = 0; i < MaxHistoryFrames; i++) + { + for (int s = 0; s < 8; s++) + { + int2 SampleReprojectionCoord; + float4 SampleReprojectionWeights, WeightsUnused; + + // Get new reprojection coordinates with offset + GetReprojectionCoord(pixCoord.xy + BoxSampleOffsets[s], MotionVectors, SampleReprojectionWeights, SampleReprojectionCoord); + int2 SamplePersistentHistoryCoord = asuint(H_LOAD_ARRAY(_HistoryIndirection, SampleReprojectionCoord, i)); + + if (any(SampleReprojectionCoord * _OctahedralSize + int2(0, 0) * _OctahedralSize + _OctahedralSize >= _ScreenSize.xy / _ProbeSize * _OctahedralSize)) + SampleReprojectionWeights.x = 0; + + if (any(SampleReprojectionCoord * _OctahedralSize + int2(1, 0) * _OctahedralSize + _OctahedralSize >= _ScreenSize.xy / _ProbeSize * _OctahedralSize)) + SampleReprojectionWeights.y = 0; + + if (any(SampleReprojectionCoord * _OctahedralSize + int2(0, 1) * _OctahedralSize + _OctahedralSize >= _ScreenSize.xy / _ProbeSize * _OctahedralSize)) + SampleReprojectionWeights.z = 0; + + if (any(SampleReprojectionCoord * _OctahedralSize + int2(1, 1) * _OctahedralSize + _OctahedralSize >= _ScreenSize.xy / _ProbeSize * _OctahedralSize)) + SampleReprojectionWeights.w = 0; + + // Calculate new reprojection weights + GetReprojectionWeights(_ProbeWorldPosNormal_History, CurrentData, SamplePersistentHistoryCoord, GetHistoryIndex(i), SampleReprojectionWeights, WeightsUnused); + float SampleBestWeightSumm = SampleReprojectionWeights.x + SampleReprojectionWeights.y + SampleReprojectionWeights.z + SampleReprojectionWeights.w; + + // Accept this sample if it's better than previous samples + if (SampleBestWeightSumm > BestWeightSumm) + { + ReprojectionIndex = i; + BestWeightSumm = SampleBestWeightSumm; + ReprojectionWeights = SampleReprojectionWeights; + PersistentHistoryCoord = SamplePersistentHistoryCoord; + + // Prevents sampling outside of persistant history frames + if (SamplePersistentHistoryCoord.x + SamplePersistentHistoryCoord.y == 0) + ReprojectionWeights = 0; + + // Good enough, stop the search + if (SampleBestWeightSumm > 0.1) + break; + } + } + } + } + } + + // Use best relaxed weight (meaning soft normal cutoff) as a last-ditch effort + if (REPROJECTION_WITH_RELAXED_WEIGHTS) + { + for (uint i = 0; i < MaxHistoryFrames; i++) + { + // Good enough, stop the search + if (BestWeightSumm > 0.1) + break; + + float SampleBestWeightSumm = RelaxedWeights[i].x + RelaxedWeights[i].y + RelaxedWeights[i].z + RelaxedWeights[i].w; + + // Accept this sample if it's better than previous samples + if (SampleBestWeightSumm > BestWeightSumm) + { + ReprojectionIndex = i; + BestWeightSumm = SampleBestWeightSumm; + ReprojectionWeights = RelaxedWeights[i]; + PersistentHistoryCoord = asuint(H_LOAD_ARRAY(_HistoryIndirection, ReprojectionCoord, i)); + + // Prevents sampling outside of persistant history frames + if (PersistentHistoryCoord.x + PersistentHistoryCoord.y == 0) + ReprojectionWeights = 0; + } + } + } + + if (any(PersistentHistoryCoord * _OctahedralSize + int2(0, 0) * _OctahedralSize + _OctahedralSize > _ScreenSize.xy / _ProbeSize * _OctahedralSize)) + ReprojectionWeights.x = 0; + + if (any(PersistentHistoryCoord * _OctahedralSize + int2(1, 0) * _OctahedralSize + _OctahedralSize > _ScreenSize.xy / _ProbeSize * _OctahedralSize)) + ReprojectionWeights.y = 0; + + if (any(PersistentHistoryCoord * _OctahedralSize + int2(0, 1) * _OctahedralSize + _OctahedralSize > _ScreenSize.xy / _ProbeSize * _OctahedralSize)) + ReprojectionWeights.z = 0; + + if (any(PersistentHistoryCoord * _OctahedralSize + int2(1, 1) * _OctahedralSize + _OctahedralSize > _ScreenSize.xy / _ProbeSize * _OctahedralSize)) + ReprojectionWeights.w = 0; + + // Output reprojection weights and coords + _PersistentReprojectionWeights_Output[H_COORD(pixCoord.xy)] = ReprojectionWeights; + _PersistentReprojectionCoord_Output[H_COORD(pixCoord.xy)] = PackPersistentReprojectionCoord(PersistentHistoryCoord, ReprojectionIndex); +} + + +// ------------------------ HISTORY INDIRECTION SCROLL ------------------------ +[numthreads(8, 8, 1)] +void HistoryIndirectionScroll(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + + uint2 BestOffset; bool ReprojectionFailed; + uint2 ReprojectionCoordPacked = asuint(H_LOAD(_ReprojectionCoord, pixCoord.xy).xy); + uint2 ReprojectionCoord = UnpackBestReprojectionCoord(ReprojectionCoordPacked, BestOffset, ReprojectionFailed); + + _HistoryIndirection[uint3(pixCoord.xy, H_INDEX_ARRAY(_HistoryArrayIndex))] = asuint(H_LOAD_ARRAY(_HistoryIndirection, ReprojectionCoord + BestOffset, _HistoryArrayIndex - 1)); +} + + +// ------------------------ HISTORY INDIRECTION UPDATE ------------------------ +[numthreads(8, 8, 1)] +void HistoryIndirectionUpdate(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + + _HistoryIndirection[uint3(pixCoord.xy, H_INDEX_ARRAY(0))] = pixCoord.xy; +} + + +// ------------------------ HISTORY PROBE BUFFERS UPDATE ------------------------ +[numthreads(8, 8, 1)] +void HistoryProbeBuffersUpdate(uint3 pixCoord : SV_DispatchThreadID, uint2 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + + + uint2 ProbeOffset; + float4 NormalDepthDownsampled = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy).xy), ProbeOffset); + float3 WorldPosition = H_COMPUTE_POSITION_WS((pixCoord.xy * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) / _ScreenSize.xy, NormalDepthDownsampled.w, H_MATRIX_I_VP); + WorldPosition = H_GET_ABSOLUTE_POSITION_WS(WorldPosition); + + _ProbeWorldPosNormal_HistoryOutput[uint3(pixCoord.xy, H_INDEX_ARRAY(uint(_FrameCount) % _PersistentHistorySamples))] = PackWorldPosNormal(WorldPosition.xyz, NormalDepthDownsampled.xyz); +} + + +H_TEXTURE(_HTraceBufferGI); +H_RW_TEXTURE(float3, _Radiance_Output); + +// ------------------------ HISTORY COPYING ----------------------- +[numthreads(8, 8, 1)] +void CopyHistoryURP(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + float3 IndirectLighting = H_LOAD(_HTraceBufferGI, pixCoord.xy).xyz; + float3 DiffuseColor = HBUFFER_DIFFUSE(pixCoord.xy).xyz; + float Metallic = H_LOAD(g_HTraceGBuffer1, pixCoord.xy).x; + + // No Indirect Intensity multiplier here to avoid overblown lighting through the temporal loop + float3 FinalIndirectLighting = IndirectLighting * DiffuseColor * (1 - Metallic); + + _Radiance_Output[H_COORD(pixCoord.xy)] = float4(HBUFFER_COLOR(pixCoord.xy).xyz + FinalIndirectLighting, 0); +} + +[numthreads(8, 8, 1)] +void CopyHistoryBIRP(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalReprojection.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalReprojection.compute.meta new file mode 100644 index 000000000..10c2c60a6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalReprojection.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 852fce6b91aadfb44909f00fe7e0c637 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTemporalReprojection.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingScreenSpace.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingScreenSpace.compute new file mode 100644 index 000000000..a946abf33 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingScreenSpace.compute @@ -0,0 +1,277 @@ +#pragma kernel LightEvaluation +#pragma kernel ScreenSpaceTracing + +#pragma warning (disable : 4000) + +#pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 +#pragma multi_compile _ HIT_SCREEN_SPACE_LIGHTING + +#include "../Includes/Config.hlsl" + +#include "../Includes/VoxelTraversal.hlsl" +#include "../Includes/ScreenTraversal.hlsl" +#include "../Includes/SpatialFilteringFunctions.hlsl" +#include "../Includes/VoxelLightingEvaluation.hlsl" +#include "../Includes/FallbackAPV.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +#define AO_IN_GBUFFER3_TAG float3((1 << 11), 1, (1 << 10)) + +H_TEXTURE(_ColorPyramid_History); +H_TEXTURE(_NormalDepth_History); +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(_Radiance_History); +H_TEXTURE(g_GeometryNormal); +H_TEXTURE(_RayDirection); +H_TEXTURE(_HitCoord); +H_TEXTURE(_ProbeSeed); +H_TEXTURE(_GBufferTexture3); + +H_RW_TEXTURE(float, _TracingTemporalValidity_Output); +H_RW_TEXTURE(float4, _HitRadiance_Output); +H_RW_TEXTURE(float3, _HitNormal_Output); +H_RW_TEXTURE(uint, _HitDistance_Output); +H_RW_TEXTURE(uint2, _HitCoord_Output); + +RWStructuredBuffer _TracingCoords; +RWStructuredBuffer _RayCounter; + +int _IndexXR; + +// ------------------------ FUNCTIONS ------------------------ +bool RadianceValidation(uint2 pixCoord, float3 HitPositionNDC, float3 RayDirectionWS, float3 HitPositionWS, float3 PositionWS, float Thickness, bool IsInsideVoxelBound, inout float3 HitRadiance) +{ + // Reject hits outside the frame + if (all(HitPositionNDC.xy > 0) && all(HitPositionNDC.xy < 1)) + { + float HitSurface = H_LOAD(g_HTraceDepthPyramidWSGI, HitPositionNDC.xy * _ScreenSize.xy).x; + + // Reject hits on sky (or other) infinitely distant pixels + if (HitSurface > 1e-7) + { + float HitSurfaceLinear = H_LINEAR_EYE_DEPTH(HitSurface); + float HitDepthLinear = H_LINEAR_EYE_DEPTH(HitPositionNDC.z); + + // Reject hits that are too deep beneath the surface (or above it) + Thickness = IsInsideVoxelBound ? Thickness : 0.05f * max(HitSurfaceLinear, 0.00001f); + if (abs(HitDepthLinear - HitSurfaceLinear) < Thickness && HitSurfaceLinear < HitDepthLinear) + { + float3 HitNormal = H_LOAD(g_GeometryNormal, HitPositionNDC.xy * _ScreenSize.xy).xyz; + float HitDistance = length(PositionWS - HitPositionWS); + + float2 ReprojectedHitNDC = HitPositionNDC.xy - HBUFFER_MOTION_VECTOR(HitPositionNDC.xy * _ScreenSize.xy).xy; + if (any(ReprojectedHitNDC < 0) || any(ReprojectedHitNDC > 1)) + return false; + + // Load previous normal and depth + uint2 NormalDepthHistoryPacked = asuint(H_LOAD(_NormalDepth_History, ReprojectedHitNDC * _ScreenSize.xy).xy); + float4 NormalDepthReprojected = UnpackNormalDepthFull(NormalDepthHistoryPacked); + float3 HitNormalReprojected = NormalDepthReprojected.xyz; + float HitSurfaceReprojected = NormalDepthReprojected.w; + float HitSurfaceReprojectedLinear = H_LINEAR_EYE_DEPTH(HitSurfaceReprojected); + + // Accept previous color buffer based on depth and normal differences + float ReprojectionDepthWeight = PixelDepthWeighting(HitSurfaceReprojectedLinear, HitSurfaceLinear, 35); + float ReprojectionNormalWeight = dot(HitNormalReprojected, HitNormal); + if (ReprojectionDepthWeight <= 0 || ReprojectionNormalWeight < 0.25f) + if (HitDistance > _VoxelSize) return false; else return true; + + // TODO: check if we can use higher LODs + int RadianceLOD = 0; //lerp(0, 4, saturate(HitDistance / 5.0f)); + + // If the surface is hit from behind - skip reading color buffer and output zero + if (dot(RayDirectionWS, HitNormal) < 0) + { + #ifdef HIT_SCREEN_SPACE_LIGHTING + _HitCoord_Output[H_COORD(pixCoord.xy)] = floor(HitPositionNDC.xy * _ScreenSize.xy); + #else + // Calculate dimming value proprtional to the viewing angle + float3 HitToCameraDir = -normalize(H_GET_ABSOLUTE_POSITION_WS(HitPositionWS) - _WorldSpaceCameraPos); + float AngleDimming =(sqrt(sqrt(sqrt(dot(HitToCameraDir, HitNormal))))); + + HitRadiance = H_LOAD(_ColorPyramid_History, ReprojectedHitNDC * _ScreenSize.xy); // HBUFFER_COLOR(ReprojectedHitNDC * _ScreenSize.xy); + // #ifdef H_BIRP + // HitRadiance = HBUFFER_COLOR(HitPositionNDC.xy * _ScreenSize.xy); + // #endif + + HitRadiance *= HGetInversePreviousExposureMultiplier; + HitRadiance *= AngleDimming; + #endif + } + + return true; + } + } + } + + return false; +} + + +// ------------------------ SCREEN SPACE TRACING ------------------------ +[numthreads(8, 8, 1)] +void ScreenSpaceTracing(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + uint IndirectCoordOffsetVR = _ScreenSize.x * _ScreenSize.y * _IndexXR; + uint RayCounterOffsetVR = 10 * _IndexXR; + + uint RayIndex = groupID * 64 + groupIndex; + if (RayIndex >= _RayCounter[0 + 4 + RayCounterOffsetVR]) + return; + + pixCoord.xy = _TracingCoords[RayIndex + IndirectCoordOffsetVR]; + + // Load normal, depth and offset + uint2 ProbeOffset; + float4 NormalDepth = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy / _OctahedralSize).xy), ProbeOffset); + + // Calculate probe coord + int2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + float2 ProbeCoordNDC = (ProbeCoord.xy * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw ; + + // Load center pixel data + float3 RayDirectionWS = H_LOAD(_RayDirection, pixCoord.xy).xyz * 2 - 1; + float3 PositionWS = H_COMPUTE_POSITION_WS(ProbeCoordNDC.xy, NormalDepth.w, H_MATRIX_I_VP); + + // Calculate biased ray origin and ray directrion in NDC space + float3 RayStartPositionNDC, RayDirectionNDC; + GetRayOriginAndDirectionNDC(NormalDepth.w, 50, ProbeCoordNDC.xy, PositionWS, RayDirectionWS, NormalDepth.xyz, RayStartPositionNDC, RayDirectionNDC); + + // Raymarch Hi-Z depth buffer + float3 HitPositionNDC, LastAboveSurfacePositionNDC; + bool HitFound = HierarchicalRaymarch(RayStartPositionNDC, RayDirectionNDC, 55, HitPositionNDC, LastAboveSurfacePositionNDC); + + if (HitFound) + { + // Center hit coord + HitPositionNDC.xy = floor(HitPositionNDC.xy * _ScreenSize.xy) * _ScreenSize.zw + (0.5 * _ScreenSize.zw); + + // Calculate hit position in world space + float3 HitPositionWS = HitPositionNDC.z > 1e-7 ? H_COMPUTE_POSITION_WS(HitPositionNDC.xy, HitPositionNDC.z, H_MATRIX_I_VP) : PositionWS; + + // Evaluate occluder thickness + float Thickness = AdaptiveThicknessSearch(HitPositionWS, RayDirectionWS); + + // Check if ss ray's end is outside voxel bounds + bool IsInsideVoxelBound = IsWorldPositionInBounds(H_GET_ABSOLUTE_POSITION_WS(HitPositionWS)); + + float3 HitRadiance = 0; + bool HitIsValid = RadianceValidation(pixCoord.xy, HitPositionNDC, RayDirectionWS, HitPositionWS, PositionWS, Thickness, IsInsideVoxelBound, HitRadiance); + + // Calculate hit distance in world space + float HitDistanceWS = length(PositionWS - HitPositionWS); + + // If ss ray's end is outside voxel bounds - do not trace ws ray from there, use fallback + if (IsInsideVoxelBound == false) + { + // We use fallback only if ss ray failed + if (!HitIsValid) + { + if (_EnableProbeVolumes) + { + if (APV_FALLBACK && (PROBE_VOLUMES_L1 || PROBE_VOLUMES_L2)) + { + // Evaluate APV + HitRadiance = EvaluateAPV(H_GET_ABSOLUTE_POSITION_WS(PositionWS), NormalDepth.xyz, H_GET_VIEW_DIRECTION_WS(PositionWS), 100); + } + } + + //Use skybox as fallback and dim it with sky occlusion approximation + else if (dot(float3(0,1,0), RayDirectionWS) > _SkyOcclusionCone + 0.05f) + { + float SkyOcclusion = EvaluateDirectionalShadowOcclusion(H_GET_ABSOLUTE_POSITION_WS(HitPositionWS)); + HitRadiance = EvaluateSky(RayDirectionWS) * SkyOcclusion; + } + } + + HitIsValid = true; + } + + // Tracing toggles + if (DISABLE_SS_TRACING) { HitIsValid = false; HitDistanceWS = 0; } + if (DISABLE_WS_TRACING) { HitIsValid = true; } + + // If the ray went outside the frame but travelled a short distance - it may be unreliable (important for probe ao) + bool IsOutsideFrame = false; + if ((any(HitPositionNDC.xy > 0.99) || any(HitPositionNDC.xy < 0.01)) && HitDistanceWS < _VoxelSize.x) + IsOutsideFrame = true; + + _HitRadiance_Output[H_COORD(pixCoord.xy)] = float4(HitRadiance, 1); + _HitDistance_Output[H_COORD(pixCoord.xy)] = PackHitDistance(max(HitDistanceWS, 0.001f), IsOutsideFrame, !HitIsValid); + + // _HitRadiance_Output [H_COORD(pixCoord.xy)] = float4(HitRadiance.xyz, 1); + } +} + + +// ------------------------ SCREEN SPACE HIT LIGHTING EVALUATION ------------------------ +[numthreads(8, 8, 1)] +void LightEvaluation(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + uint IndirectCoordOffsetVR = _ScreenSize.x * _ScreenSize.y * _IndexXR; + uint RayCounterOffsetVR = 10 * _IndexXR; + + uint RayIndex = groupID * 64 + groupIndex; + if (RayIndex >= _RayCounter[0 + 4 + RayCounterOffsetVR]) + return; + + pixCoord.xy = _TracingCoords[RayIndex + IndirectCoordOffsetVR]; + + // Load hit coords + uint2 HitCoord = asuint(H_LOAD(_HitCoord, pixCoord.xy).xy); + float2 HitCoordNDC = (HitCoord + 0.5f) * _ScreenSize.zw; + + // Hit validation in screen tracing shader failed, early out; + if (HitCoord.x + HitCoord.y <= 0) + return; + + // Compute reprojected hit coords (for those buffers that come from previous frames) + float2 HitCoordReprojectedNDC = HitCoordNDC - HBUFFER_MOTION_VECTOR(HitCoordNDC.xy * _ScreenSize.xy); + uint2 HitCoordReprojected = HitCoordReprojectedNDC * _ScreenSize.xy; + + // Load gbuffer data at hit point + float3 HitNormal = HBUFFER_NORMAL_WS(HitCoord).xyz; + float3 HitDiffuse = HBUFFER_DIFFUSE(HitCoord).xyz; + + float3 HitColor = 0; + + // If diffuse is 0 - use color buffer directly instead. TODO: consider metallics + if (HitDiffuse.x + HitDiffuse.y + HitDiffuse.z == 0) + { + // Load color buffer + HitColor = H_LOAD(_ColorPyramid_History, HitCoordReprojected).xyz * HGetInverseCurrentExposureMultiplier; + + // Calculate additional gbuffer data at hit point + float HitDepth = HBUFFER_DEPTH(HitCoord); + float3 HitNormal = H_LOAD(g_GeometryNormal, HitCoord).xyz; + float3 HitPosition = H_COMPUTE_POSITION_WS(HitCoordNDC.xy, HitDepth, H_MATRIX_I_VP); + float3 HitToCameraDir = -normalize(H_GET_ABSOLUTE_POSITION_WS(HitPosition) - _WorldSpaceCameraPos); + + // Calculate dimming value proprtional to the viewing angle + HitColor *= sqrt(sqrt(sqrt(sqrt(dot(HitToCameraDir, HitNormal))))); + + _HitRadiance_Output[H_COORD(pixCoord.xy)] = float4(HitColor, 1); + return; + } + + // Add directional light contribution + + // Add emissive contribution + float3 Emissive = H_LOAD(_GBufferTexture3, HitCoord).xyz; + if (any(Emissive.xz != AO_IN_GBUFFER3_TAG.xz)) + { + HitColor = Emissive; + bool Unused; + uint HitColorPacked = PackVoxelColor(HitColor, true); + HitColor = UnpackVoxelColor(HitColorPacked, Unused); + + HitColor *= HGetInverseCurrentExposureMultiplier; + } + + // Add indirect lighting contribution (via reprojected screen space radiance cache) + HitColor += H_LOAD(_Radiance_History, HitCoordReprojected).xyz * HGetInversePreviousExposureMultiplier * HitDiffuse; + + _HitRadiance_Output[H_COORD(pixCoord.xy)] = float4(HitColor, 1); + + +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingScreenSpace.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingScreenSpace.compute.meta new file mode 100644 index 000000000..741a57b92 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingScreenSpace.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 3bb2f3354bd27ba4796d0f9722c9c4fb +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingScreenSpace.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingWorldSpace.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingWorldSpace.compute new file mode 100644 index 000000000..1ee2b8254 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingWorldSpace.compute @@ -0,0 +1,251 @@ +#pragma kernel WorldSpaceTracing +#pragma kernel LightEvaluation + +#pragma multi_compile MULTIBOUNCE_OFF MULTIBOUNCE_CACHE MULTIBOUNCE_APV +#pragma multi_compile _ EVALUATE_PUNCTUAL_LIGHTS +#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS +#pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 + +#include "../Includes/Config.hlsl" + +#include "../Includes/VoxelTraversal.hlsl" +#include "../Includes/VoxelLightingEvaluation.hlsl" +#include "../Includes/SpatialHash.hlsl" +#include "../Includes/Reservoir.hlsl" +#include "../Includes/ScreenProbesCommon.hlsl" +#include "../Includes/FallbackAPV.hlsl" +#pragma multi_compile _ _GBUFFER_NORMALS_OCT + +H_TEXTURE3D(float3, _RadianceCacheFiltered); +H_TEXTURE(_ProbeNormalDepth); +H_TEXTURE(_VoxelPayload); +H_TEXTURE(g_GeometryNormal); +H_TEXTURE(_RayDirection); +H_TEXTURE(_HitDistance); +H_TEXTURE(_ProbeSeed); + +H_RW_TEXTURE(uint2, _VoxelPayload_Output); +H_RW_TEXTURE(uint, _VoxelBiasOffset_Output); +H_RW_TEXTURE(float, _HitDistance_Output); +H_RW_TEXTURE(float4, _HitRadiance_Output); + +StructuredBuffer _PointDistribution; +RWStructuredBuffer _TracingCoords; +RWStructuredBuffer _RayCounter; + +float _RayLength; + +int _IndexXR; +int _HFrameIndex; +int _FreezeCache; + +// ------------------------ FUNCTIONS ------------------------ + +// ------------------------ WORLD SPACE TRACING ------------------------- +[numthreads(8, 8, 1)] +void WorldSpaceTracing(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + uint IndirectCoordOffsetVR = _ScreenSize.x * _ScreenSize.y * _IndexXR; + uint RayCounterOffsetVR = 10 * _IndexXR; + + uint RayIndex = groupID * 64 + groupIndex; + if (RayIndex >= _RayCounter[0 + 4 + RayCounterOffsetVR]) + return; + + pixCoord.xy = _TracingCoords[RayIndex + IndirectCoordOffsetVR]; + + // Calculate probe coords + uint2 ProbeOffset; + int2 ProbeCoord = floor(pixCoord.xy / _OctahedralSize); + int2 CellCoord = pixCoord.xy - floor(pixCoord.xy / _OctahedralSize) * _OctahedralSize; + float4 NormalDepth = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, ProbeCoord).xy), ProbeOffset); + + float2 ProbeCoordNDC = (ProbeCoord.xy * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw ; + + // Load tracing data + float Depth = NormalDepth.w; + float3 RayDirectionWS = H_LOAD(_RayDirection, pixCoord.xy).xyz * 2 - 1; + float3 PositionWS = H_COMPUTE_POSITION_WS(ProbeCoordNDC, Depth, H_MATRIX_I_VP); + + // Start world space tracing where the screen space part finished + bool Unused; + uint HitDistancePacked = asuint(H_LOAD(_HitDistance, pixCoord.xy).x); + float HitDistanceWS = abs(UnpackHitDistance(HitDistancePacked, Unused, Unused)); + float3 RayOriginWS = PositionWS + HitDistanceWS * RayDirectionWS; + + // If the ray travelled less than half a voxel - reset it to origin + if (HitDistanceWS <= _VoxelSize * 0.5f) + { + RayOriginWS = PositionWS; + HitDistanceWS = 0; + } + + // Apply voxel bias + VoxelBias(pixCoord.xy, _PointDistribution, Depth, HitDistanceWS, NormalDepth.xyz, RayDirectionWS, RayOriginWS); + + // Initialize voxel ray payload + VoxelPayload Payload; + InitializePayload(Payload); + + // Calculate ray distance + float MaxRayDistance = MaxVoxelRayDistance(H_GET_ABSOLUTE_POSITION_WS(RayOriginWS), RayDirectionWS.xyz); + float RayDistance = _RayLength == 0 ? MaxRayDistance : _RayLength; + + // Trace into Voxels + bool HitFound = TraceVoxelsDiffuse(H_GET_ABSOLUTE_POSITION_WS(RayOriginWS), RayDirectionWS.xyz, RayDistance, 128, Payload); + + if (!HitFound) + Payload.HitDistance = 100; // TODO: check this + + // Total distance travelled by the ray in screen-space + world-space + float TotalDistance = HitDistanceWS + Payload.HitDistance; + + // Write total (screen-space + world-space) hit distance + _HitDistance_Output[H_COORD(pixCoord.xy)] = max(TotalDistance, 0.001f); + + // Pack voxel payload + float3 VoxelHitOffset = VoxelCoordToAbsoluteWorldPosition(Payload.HitCoord) - Payload.HitPosition; + _VoxelPayload_Output[H_COORD(pixCoord.xy)] = PackVoxelHitPayload(VoxelHitOffset, TotalDistance, Payload.HitNormal, Payload.HitCoord, HitFound); + + // Add skylight if we missed + if (!HitFound && dot(float3(0,1,0), RayDirectionWS) > _SkyOcclusionCone + 0.05f) + { + // Evaluate sky occlusion + float SkyOcclusion = HitFound ? 1 : EvaluateDirectionalShadowOcclusion(H_GET_ABSOLUTE_POSITION_WS(RayOriginWS) + MaxRayDistance * RayDirectionWS); + Payload.HitColor += EvaluateSky(RayDirectionWS) * SkyOcclusion; + + // Write evaluated hit radiance + _HitRadiance_Output[H_COORD(pixCoord.xy)] = float4(Payload.HitColor.xyz, 1); + } +} + + +// ---------------------- WORLD SPACE HIT LIGHTING EVALUATION ----------------------- +[numthreads(8, 8, 1)] +void LightEvaluation(uint3 pixCoord : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex, uint groupID : SV_GroupID) +{ + uint IndirectCoordOffsetVR = _ScreenSize.x * _ScreenSize.y * _IndexXR; + uint RayCounterOffsetVR = 10 * _IndexXR; + + uint RayIndex = groupID * 64 + groupIndex; + if (RayIndex >= _RayCounter[0 + 4 + RayCounterOffsetVR]) + return; + + pixCoord.xy = _TracingCoords[RayIndex + IndirectCoordOffsetVR]; + + // Initialize voxel ray payload + VoxelPayload Payload; + InitializePayload(Payload); + + // Read packed voxel payload + uint2 PayloadPacked = asuint(H_LOAD(_VoxelPayload, pixCoord.xy).xy); + + // Unpack voxel payload + float3 HitOffset; float TotalRayDistance; + bool HitFound = UnpackVoxelHitPayload(PayloadPacked, TotalRayDistance, HitOffset, Payload.HitNormal, Payload.HitCoord); + + // Early-out on the miss with APV evaluation (if available) + if (!HitFound) + { + if (_EnableProbeVolumes) + { + if (APV_FALLBACK && (PROBE_VOLUMES_L1 || PROBE_VOLUMES_L2)) + { + // Prepare Normal, Depth and PositionWS for APV evaluation + uint2 ProbeOffset; + float4 NormalDepth = UnpackNormalDepth(asuint(H_LOAD(_ProbeNormalDepth, pixCoord.xy / _OctahedralSize).xy), ProbeOffset); + float2 ProbeCoordNDC = (floor(pixCoord.xy / _OctahedralSize) * float(_ProbeSize) + float2(ProbeOffset) + 0.5f) * _ScreenSize.zw ; + float3 PositionWS = H_COMPUTE_POSITION_WS(ProbeCoordNDC.xy, NormalDepth.w, H_MATRIX_I_VP); + + // Evaluate APV + float3 HitRadiance = EvaluateAPV(H_GET_ABSOLUTE_POSITION_WS(PositionWS), NormalDepth.xyz, H_GET_VIEW_DIRECTION_WS(PositionWS), 100); + + // Output hit radiance and early out + _HitRadiance_Output[H_COORD(pixCoord.xy)] = float4(HitRadiance, 1); + } + } + return; + } + + // Calculate hit position + Payload.HitPosition = VoxelCoordToAbsoluteWorldPosition(Payload.HitCoord) + HitOffset; + + // Read & spawn hash entries if it is a hit + if (HitFound) + { + // Evauluate lighting on hit point + EvaluateHitLighting(Payload); + + #ifdef MULTIBOUNCE_CACHE + { + uint3 CacheCoord = ComputeRadianceCacheCoord(Payload.HitCoord); + uint HashKey = PackHashKey(CacheCoord, Payload.HitNormal); + + bool IsEmpty; + uint HashRank = 2; + uint HashProbingIndex, HashLowestRankIndex; + uint HashIndex = HashGetIndex(CacheCoord, PackVoxelNormalIndex(Payload.HitNormal)); + bool HashFound = HashFindAny(HashIndex, HashKey, HashRank, HashLowestRankIndex, HashProbingIndex, IsEmpty); + + int3 VoxelCoordAbsolute = VoxelCoordToAbsoluteVoxelCoord(Payload.HitCoord); + float3 VoxelHitOffset = (float3(VoxelCoordAbsolute) * _VoxelSize) - (Payload.HitPosition) ; + + if (HashFound) // If a valid entry was found we reset the decay counter to max value and use cache (it's main purpose) + { + uint3 HitCachePacked = _HashBuffer_Radiance[HashProbingIndex].xyz; + + float3 RadianceFullRange = UnpackCacheRadianceFull(HitCachePacked.xyz); + float3 RadianceNearRange = UnpackCacheRadianceNear(HitCachePacked.xyz); + + // Choose far / near field cache based on the travelled ray distance + Payload.HitCache = TotalRayDistance > _VoxelSize.x * 4 ? RadianceFullRange : min(RadianceNearRange, RadianceFullRange); + + // Progressively dim cache at a distance smaller than a voxel size + Payload.HitCache *= lerp(0, 1, saturate(TotalRayDistance / 1 / _VoxelSize)); + + // Clip cache + Payload.HitCache *= HGetCurrentExposureMultiplier; + Payload.HitCache = HClipRadiance(Payload.HitCache, 10); + Payload.HitCache *= HGetInverseCurrentExposureMultiplier; + + // Add cache to hit radiance + Payload.HitColor += Payload.HitCache * Payload.HitDiffuse; + + // Reset decay counter back to 255 as we hit this cache cell - it is useful + _HashBuffer_Counter[HashProbingIndex] = 255; + } + else if (IsEmpty && !FREEZE_CACHE) // If we didn't find a valid entry but found an empty cell, we spawn a new entry + { + _HashBuffer_Position[HashProbingIndex] = uint4(asuint(VoxelCoordAbsolute.xyz), PackHitOffset(VoxelHitOffset)); + _HashBuffer_Radiance[HashProbingIndex] = 0; + _HashBuffer_Counter[HashProbingIndex] = 255; + _HashBuffer_Key[HashProbingIndex] = HashKey | 0x2; + } + else if (HashRank != 2 && !FREEZE_CACHE) // If neither a valid nor an empty entry was found, we recycle the lowest ranked cell to spawn a new entry + { + _HashBuffer_Position[HashLowestRankIndex] = uint4(asuint(VoxelCoordAbsolute.xyz), PackHitOffset(VoxelHitOffset)); + _HashBuffer_Radiance[HashLowestRankIndex] = 0; + _HashBuffer_Counter[HashLowestRankIndex] = 255; + _HashBuffer_Key[HashLowestRankIndex] = HashKey | 0x2; + } + } + #else + if (MULTIBOUNCE_APV) + { + if (_EnableProbeVolumes) + { + if (APV_FALLBACK && (PROBE_VOLUMES_L1 || PROBE_VOLUMES_L2)) + { + float3 Unused = 0; + Payload.HitCache = EvaluateAPV(Payload.HitPosition, Payload.HitNormal, H_GET_VIEW_DIRECTION_WS(Payload.HitPosition), 100); + Payload.HitCache *= smoothstep(0.15f, 1.0f, saturate(TotalRayDistance / 4.0f / _VoxelSize)); + Payload.HitColor += Payload.HitCache * Payload.HitDiffuse; + } + } + } + #endif + } + + // Write evaluated hit radiance + _HitRadiance_Output[H_COORD(pixCoord.xy)] = float4(Payload.HitColor.xyz, 1); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingWorldSpace.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingWorldSpace.compute.meta new file mode 100644 index 000000000..8254cf102 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingWorldSpace.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: af9d6971513146b4ca1294937cf1b8f0 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/HTracingWorldSpace.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Shadowmap.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Shadowmap.compute new file mode 100644 index 000000000..3346346b3 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Shadowmap.compute @@ -0,0 +1,19 @@ +#pragma kernel ShadowmapMerge + +#include "../Headers/HMain.hlsl" + +Texture2D _Shadowmap; +RWTexture2D _Shadowmap_Output; + +float2 _OctantShadowOffset; + +[numthreads(8, 8, 1)] +void ShadowmapMerge(uint3 pixCoord : SV_DispatchThreadID, uint3 groupThreadID : SV_GroupThreadID) +{ + int2 ShadowmapSize = int2(2048, 2048); + int2 WriteCoord = pixCoord.xy + _OctantShadowOffset.xy; + + float ShadowmapOctant = _Shadowmap.Load(int3(pixCoord.xy, 0)).x; /// LOAD_TEXTURE2D(_Shadowmap, pixCoord.xy).x; + + _Shadowmap_Output[WriteCoord] = ShadowmapOctant; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Shadowmap.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Shadowmap.compute.meta new file mode 100644 index 000000000..e8ade0ff7 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Shadowmap.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 9c03eda2e389436448aa6be833b4c9cf +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Shadowmap.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/VoxelVisualization.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/VoxelVisualization.compute new file mode 100644 index 000000000..d5848b996 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/VoxelVisualization.compute @@ -0,0 +1,111 @@ +#pragma kernel VisualizeVoxels +#pragma once + + +#include "../Includes/Config.hlsl" + +#include "../Includes/VoxelTraversal.hlsl" +#include "../Includes/VoxelLightingEvaluation.hlsl" +#include "../Includes/SpatialHash.hlsl" + +#pragma multi_compile_local _ VISUALIZE_LIGHTING +#pragma multi_compile _ EVALUATE_PUNCTUAL_LIGHTS +#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS +#pragma multi_compile _ _GBUFFER_NORMALS_OCT +#pragma multi_compile _ PROBE_VOLUMES_L1 PROBE_VOLUMES_L2 + + + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "../Includes/FallbackAPV.hlsl" + +// Input Buffers +H_TEXTURE(_DebugRayDirection); + +// Output Buffers +H_RW_TEXTURE(float3, _Visualization_Output); + +int _MultibounceMode; + +[numthreads(8, 8, 1)] +void VisualizeVoxels(uint3 pixCoord : SV_DispatchThreadID) +{ + + // We have deleted "_RTHandleScale" here because when switching from Game to Scene view we got a strecthed and distorted debug image. + //float3 RayDirection = H_SAMPLE_LOD(_DebugRayDirection, H_SAMPLER_LINEAR_CLAMP, (pixCoord.xy + 0.5) * _ScreenSize.zw, 0).xyz; + + float2 pixCoordNDC = (pixCoord.xy + 0.5) * _ScreenSize.zw; + float4 PositionVS = mul(UNITY_MATRIX_I_P, float4(pixCoordNDC * 2.0 - 1.0, 1.0, 1.0)); + float3 DirectionVS = normalize(float3(PositionVS.x, -PositionVS.y, PositionVS.z)); + float3 RayDirection = normalize(mul((float3x3)H_MATRIX_I_V, DirectionVS)); + + float3 RayOrigin = + GetCameraPositionWS(); + + + // TODO: do we need this? + float Depth = HBUFFER_DEPTH(pixCoord.xy); + if (Depth >= UNITY_RAW_FAR_CLIP_VALUE) + _Visualization_Output[H_COORD(pixCoord.xy)] = 0; + + // Initialize voxel ray payload + VoxelPayload Payload; + InitializePayload(Payload); + + float DepthLinear = H_LINEAR_01_DEPTH(Depth); + DepthLinear *= length(RayDirection); + + DepthLinear = Depth <= UNITY_RAW_FAR_CLIP_VALUE ? _VoxelBounds.x : DepthLinear; + RayDirection = normalize(RayDirection); + + // Trace into voxels + bool HitFound = TraceVoxelsDiffuse(RayOrigin, RayDirection, MaxVoxelRayDistance(RayOrigin, RayDirection), 1000, Payload); + + if (HitFound) + { + EvaluateHitLighting(Payload); + + #ifdef VISUALIZE_LIGHTING + if (_MultibounceMode == 1) + { + uint HashIndex = HashGetIndex(ComputeRadianceCacheCoord(Payload.HitCoord), PackVoxelNormalIndex(Payload.HitNormal)); + + uint HashIndexFound; + uint HashKey = PackHashKey(ComputeRadianceCacheCoord(Payload.HitCoord), Payload.HitNormal); + bool HashFound = HashFindValid(HashIndex, HashKey, HashIndexFound); + + if (HashFound) + { + float3 RadianceCache = UnpackCacheRadianceFull(_HashBuffer_Radiance[HashIndexFound].xyz); + Payload.HitCache = RadianceCache; + Payload.HitCache *= HGetCurrentExposureMultiplier; + } + } + + else if (_MultibounceMode == 2) + { + if (_EnableProbeVolumes) + { + if (APV_FALLBACK && (PROBE_VOLUMES_L1 || PROBE_VOLUMES_L2)) + { + Payload.HitCache = EvaluateAPV(Payload.HitPosition, Payload.HitNormal.xyz, 0, 100); + Payload.HitCache *= HGetCurrentExposureMultiplier; + } + } + } + + float3 payload = Payload.HitColor; + + payload *= HGetCurrentExposureMultiplier; + + _Visualization_Output[H_COORD(pixCoord.xy)] = payload + Payload.HitCache * Payload.HitDiffuse; + #else + _Visualization_Output[H_COORD(pixCoord.xy)] = Payload.HitDiffuse; + #endif + } + else + { + _Visualization_Output[H_COORD(pixCoord.xy)] = EvaluateSky(RayDirection) * HGetCurrentExposureMultiplier; + } + +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/VoxelVisualization.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/VoxelVisualization.compute.meta new file mode 100644 index 000000000..20177823f --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/VoxelVisualization.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: d33f390ebf3831f479f55f9b3b91876c +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/VoxelVisualization.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Voxelization.compute b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Voxelization.compute new file mode 100644 index 000000000..cf7e426e4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Voxelization.compute @@ -0,0 +1,193 @@ +#pragma kernel GeneratePositionPyramid1 +#pragma kernel GeneratePositionPyramid2 +#pragma kernel ClearPositionPyramid +#pragma kernel CopyData + +#pragma enable_d3d11_debug_symbols +#pragma warning (disable : 3206) + +#include "../Includes/VoxelTraversal.hlsl" + +H_TEXTURE3D(uint, _VoxelPositionIntermediate); + +H_RW_TEXTURE3D(uint, _VoxelData_A); +H_RW_TEXTURE3D(uint, _VoxelData_B); +H_RW_TEXTURE3D(uint, _VoxelPositionPyramid_MIP0); +H_RW_TEXTURE3D(uint, _VoxelPositionPyramid_MIP1); +H_RW_TEXTURE3D(uint, _VoxelPositionPyramid_MIP2); +H_RW_TEXTURE3D(uint, _VoxelPositionPyramid_MIP3); +H_RW_TEXTURE3D(uint, _VoxelPositionPyramid_MIP4); +H_RW_TEXTURE3D(uint, _VoxelPositionPyramid_MIP5); +H_RW_TEXTURE3D(uint, _VoxelPositionIntermediate_Output); +H_RW_TEXTURE3D(uint, _ClearTexture); + +float3 _VoxelOffset; +float3 _OctantCopyOffset; + +groupshared bool PositionLDS[4][4][4]; + +// ------------------------ SCROLLING DATA COPY ------------------------- +[numthreads(4,4,4)] +void CopyData(uint3 pixCoord : SV_DispatchThreadID, uint3 groupThreadID : SV_GroupThreadID) +{ + pixCoord.xyz *= uint3(2,2,2); + + int3 CopyCoord = pixCoord.xyz + _OctantCopyOffset.xyz; + int3 CameraDelta = round((_VoxelOffset) * _VoxelPerMeter); + + int3 TapOffsets[8] = {int3(0,0,0), int3(0,0,1), int3(0,1,0), int3(1,0,0), int3(0,1,1), int3(1,0,1), int3(1,1,0), int3(1,1,1)}; + + for (int i = 0; i < 8; i++) + { + int3 TapCoord = CopyCoord + TapOffsets[i]; + + uint VoxelDataB = _VoxelData_B[TapCoord + CameraDelta]; + bool IsDynamic = (VoxelDataB >> 23) & 0x1; // Dynamic bit flat (0 - dynamic, 1 - static) + + if (VoxelDataB * IsDynamic != 0u) + _VoxelData_A[TapCoord] = VoxelDataB; // Copy and clear dynamic voxels + } +} + +// ------------------------ MIP LEVEL 0-2 GENERATION ------------------------- +[numthreads(4,4,4)] +void GeneratePositionPyramid1(uint3 pixCoord : SV_DispatchThreadID, uint3 groupThreadID : SV_GroupThreadID) +{ + pixCoord.xyz *= uint3(2,2,2); + + int3 TapOffsets[8] = {int3(0,0,0), int3(0,0,1), int3(0,1,0), int3(1,0,0), int3(0,1,1), int3(1,0,1), int3(1,1,0), int3(1,1,1)}; + + uint VoxelPositionMIP1 = 0; + for (int i = 0; i < 8; i++) + { + int3 TapCoord = pixCoord.xyz + TapOffsets[i]; + uint VoxelPosition = asuint(H_LOAD3D(_VoxelData, TapCoord)) & 0xFF000000; + VoxelPosition = VoxelPosition >> 24; + + if (VoxelPosition != 0u) + _VoxelPositionPyramid_MIP0[TapCoord] = VoxelPosition; + + VoxelPosition = VoxelPosition > 0 ? 1 : 0; + VoxelPositionMIP1 += VoxelPosition; + } + + // Kills voxels that are less than half filled (4 out of 8 bricks) by rounding ? + // VoxelPosition_MIP1 /= 8.0f; + + PositionLDS[groupThreadID.x][groupThreadID.y][groupThreadID.z] = VoxelPositionMIP1; + GroupMemoryBarrierWithGroupSync(); + + if (VoxelPositionMIP1 > 0) + _VoxelPositionPyramid_MIP1[pixCoord / int3(2, 2, 2)] = VoxelPositionMIP1; + + [branch] + if (all((groupThreadID.xyz % int3(2, 2, 2)) == 0)) + { + uint VoxelPositionMIP2 = 0; + for (int i = 0; i < 8; i++) + { + int3 TapCoord = groupThreadID.xyz + TapOffsets[i]; + + uint VoxelPosition = PositionLDS[TapCoord.x][TapCoord.y][TapCoord.z]; + VoxelPositionMIP2 += VoxelPosition; + } + + if (VoxelPositionMIP2 > 0) + { + _VoxelPositionPyramid_MIP2[pixCoord / int3(4, 4, 4)] = VoxelPositionMIP2; + _VoxelPositionIntermediate_Output[pixCoord / int3(4, 4, 4)] = VoxelPositionMIP2; + } + } +} + +// ------------------------ MIP LEVEL 3-5 GENERATION ------------------------- +[numthreads(4,4,4)] +void GeneratePositionPyramid2(uint3 pixCoord : SV_DispatchThreadID, uint3 groupThreadID : SV_GroupThreadID) +{ + pixCoord.xyz *= uint3(2,2,2); + + int3 TapOffsets[8] = {int3(0,0,0), int3(0,0,1), int3(0,1,0), int3(1,0,0), int3(0,1,1), int3(1,0,1), int3(1,1,0), int3(1,1,1)}; + + uint VoxelPositionMIP3 = 0; + for (int i = 0; i < 8; i++) + { + int3 TapCoord = pixCoord.xyz + TapOffsets[i]; + uint VoxelPosition = H_LOAD3D(_VoxelPositionIntermediate, TapCoord); // & 0x000000FF; + + if (VoxelPosition > 0) + _VoxelPositionPyramid_MIP3[pixCoord / int3(2, 2, 2)] = VoxelPosition; + + VoxelPositionMIP3 += VoxelPosition; + } + + if (VoxelPositionMIP3 > 0) + _VoxelPositionPyramid_MIP3[pixCoord / int3(2, 2, 2)] = VoxelPositionMIP3; + + PositionLDS[groupThreadID.x][groupThreadID.y][groupThreadID.z] = VoxelPositionMIP3; + GroupMemoryBarrierWithGroupSync(); + + [branch] + if (all((groupThreadID.xyz % int3(2, 2, 2)) == 0)) + { + uint VoxelPositionMIP4 = 0; + for (int i = 0; i < 8; i++) + { + int3 TapCoord = groupThreadID.xyz + TapOffsets[i]; + VoxelPositionMIP4 += PositionLDS[TapCoord.x][TapCoord.y][TapCoord.z]; + } + + if (VoxelPositionMIP4 > 0) + _VoxelPositionPyramid_MIP4[pixCoord / int3(4, 4, 4)] = VoxelPositionMIP4; + + PositionLDS[groupThreadID.x / 2][groupThreadID.y / 2][groupThreadID.z / 2] = VoxelPositionMIP4; + } + + GroupMemoryBarrierWithGroupSync(); + + [branch] + if (all((groupThreadID.xyz % int3(4, 4, 4)) == 0)) + { + uint VoxelPositionMIP5 = 0; + for (int i = 0; i < 8; i++) + { + int3 TapCoord = groupThreadID.xyz + TapOffsets[i]; + VoxelPositionMIP5 += PositionLDS[TapCoord.x][TapCoord.y][TapCoord.z]; + } + + if (VoxelPositionMIP5 > 0) + _VoxelPositionPyramid_MIP5[pixCoord / int3(8, 8, 8)] = VoxelPositionMIP5; + } +} + + +// ------------------------ MIP CLEAR ------------------------- +[numthreads(4,4,4)] +void ClearPositionPyramid(uint3 pixCoord : SV_DispatchThreadID, uint3 groupThreadID : SV_GroupThreadID) +{ + _VoxelPositionPyramid_MIP1[pixCoord.xyz] = 0; + + [branch] + if (all((pixCoord.xyz % int3(2, 2, 2)) == 0)) + { + _VoxelPositionPyramid_MIP2[pixCoord.xyz / 2] = 0; + } + + [branch] + if (all((pixCoord.xyz % int3(4, 4, 4)) == 0)) + { + _VoxelPositionPyramid_MIP3[pixCoord.xyz / 4] = 0; + } + + [branch] + if (all((pixCoord.xyz % int3(8, 8, 8)) == 0)) + { + _VoxelPositionPyramid_MIP4[pixCoord.xyz / 8] = 0; + } + + [branch] + if (all((pixCoord.xyz % int3(16, 16, 16)) == 0)) + { + _VoxelPositionPyramid_MIP5[pixCoord.xyz / 16] = 0; + } + +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Voxelization.compute.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Voxelization.compute.meta new file mode 100644 index 000000000..5ed1913f5 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Voxelization.compute.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 3635833b8a6926147b07a731e8e627a9 +ComputeShaderImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Computes/Voxelization.compute + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers.meta new file mode 100644 index 000000000..5cebda9bc --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 697435c2517ac764da60b59f984553e9 +timeCreated: 1659620468 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files.meta new file mode 100644 index 000000000..bfef1116e --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9ec9ca9ef5c9e8649a6466cb9b34ff5b +timeCreated: 1747747307 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files/CommonCore.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files/CommonCore.hlsl new file mode 100644 index 000000000..be62c1543 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files/CommonCore.hlsl @@ -0,0 +1,44 @@ +//Common.hlsl in Core RP +#pragma once + + +// Intrinsic isnan can't be used because it require /Gic to be enabled on fxc that we can't do. So use AnyIsNan instead +bool IsNaN(float x) +{ + return (asuint(x) & 0x7FFFFFFF) > 0x7F800000; +} + +bool AnyIsNaN(float2 v) +{ + return (IsNaN(v.x) || IsNaN(v.y)); +} + +bool AnyIsNaN(float3 v) +{ + return (IsNaN(v.x) || IsNaN(v.y) || IsNaN(v.z)); +} + +bool AnyIsNaN(float4 v) +{ + return (IsNaN(v.x) || IsNaN(v.y) || IsNaN(v.z) || IsNaN(v.w)); +} + +bool IsInf(float x) +{ + return (asuint(x) & 0x7FFFFFFF) == 0x7F800000; +} + +bool AnyIsInf(float2 v) +{ + return (IsInf(v.x) || IsInf(v.y)); +} + +bool AnyIsInf(float3 v) +{ + return (IsInf(v.x) || IsInf(v.y) || IsInf(v.z)); +} + +bool AnyIsInf(float4 v) +{ + return (IsInf(v.x) || IsInf(v.y) || IsInf(v.z) || IsInf(v.w)); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files/CommonCore.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files/CommonCore.hlsl.meta new file mode 100644 index 000000000..ca45bb59c --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files/CommonCore.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2ab0191fa0b7a8a4ab5733ad477b7581 +timeCreated: 1747747319 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/Core Files/CommonCore.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files.meta new file mode 100644 index 000000000..465c1b066 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a21a67c353591a84aac943a77a445a1f +timeCreated: 1747747214 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/Color.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/Color.hlsl new file mode 100644 index 000000000..0cedd1ae0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/Color.hlsl @@ -0,0 +1,21 @@ +// Hue, Saturation, Value +// Ranges: +// Hue [0.0, 1.0] +// Sat [0.0, 1.0] +// Lum [0.0, HALF_MAX] +float3 RgbToHsv(float3 c) +{ + const float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g)); + float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r)); + float d = q.x - min(q.w, q.y); + const float e = 1.0e-4; + return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +float3 HsvToRgb(float3 c) +{ + const float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * lerp(K.xxx, saturate(p - K.xxx), c.y); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/Color.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/Color.hlsl.meta new file mode 100644 index 000000000..625ab26f8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/Color.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4068ebe30e5787b4a9e5657a542e998f +timeCreated: 1747747218 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/Color.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/RaytracingSampling.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/RaytracingSampling.hlsl new file mode 100644 index 000000000..741610c87 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/RaytracingSampling.hlsl @@ -0,0 +1,79 @@ +#ifndef RAYTRACING_SAMPLING_INCLUDED +#define RAYTRACING_SAMPLING_INCLUDED + +Texture2D g_OwenScrambledTexture; +Texture2D g_ScramblingTileXSPP; +Texture2D g_RankingTileXSPP; +Texture2D g_ScramblingTexture; + +float ScramblingValueFloat(uint2 pixelCoord) +{ + pixelCoord = pixelCoord & 255; + return g_ScramblingTexture[uint2(pixelCoord.x, pixelCoord.y)].x; +} + +float2 ScramblingValueFloat2(uint2 pixelCoord) +{ + pixelCoord = pixelCoord & 255; + return g_ScramblingTexture[uint2(pixelCoord.x, pixelCoord.y)].xy; +} + +uint ScramblingValueUInt(uint2 pixelCoord) +{ + pixelCoord = pixelCoord & 255; + return clamp((uint)(g_ScramblingTexture[uint2(pixelCoord.x, pixelCoord.y)].x * 256.0), 0, 255); +} + +uint2 ScramblingValueUInt2(uint2 pixelCoord) +{ + pixelCoord = pixelCoord & 255; + return clamp((uint2)(g_ScramblingTexture[uint2(pixelCoord.x, pixelCoord.y)] * 256.0), uint2(0,0), uint2(255, 255)); +} + +// Wrapper to sample the scrambled low Low-Discrepancy sequence (returns a float) +float GetLDSequenceSampleFloat(uint sampleIndex, uint sampleDimension) +{ + // Make sure arguments are in the right range + sampleIndex = sampleIndex & 255; + // sampleDimension = sampleDimension & 255; + + // Fetch the sequence value and return it + return g_OwenScrambledTexture[uint2(sampleDimension, sampleIndex)]; +} + +// Wrapper to sample the scrambled low Low-Discrepancy sequence (returns an unsigned int) +uint GetLDSequenceSampleUInt(uint sampleIndex, uint sampleDimension) +{ + // Make sure arguments are in the right range + sampleIndex = sampleIndex & 255; + // sampleDimension = sampleDimension & 255; + + // Fetch the sequence value and return it + return clamp((uint)(g_OwenScrambledTexture[uint2(sampleDimension, sampleIndex)] * 256.0), 0, 255); +} + +// This is an implementation of the method from the paper +// "A Low-Discrepancy Sampler that Distributes Monte Carlo Errors as a Blue Noise in Screen Space" by Heitz et al. +float GetBNDSequenceSample(uint2 pixelCoord, uint sampleIndex, uint sampleDimension) +{ + // wrap arguments + pixelCoord = pixelCoord & 127; + sampleIndex = sampleIndex & 255; + sampleDimension = sampleDimension & 255; + + // xor index based on optimized ranking + uint rankingIndex = (pixelCoord.x + pixelCoord.y * 128) * 8 + (sampleDimension & 7); + uint rankedSampleIndex = sampleIndex ^ clamp((uint)(g_RankingTileXSPP[uint2(rankingIndex & 127, rankingIndex / 128)] * 256.0), 0, 255); + + // fetch value in sequence + uint value = clamp((uint)(g_OwenScrambledTexture[uint2(sampleDimension, rankedSampleIndex.x)] * 256.0), 0, 255); + + // If the dimension is optimized, xor sequence value based on optimized scrambling + uint scramblingIndex = (pixelCoord.x + pixelCoord.y * 128) * 8 + (sampleDimension & 7); + float scramblingValue = min(g_ScramblingTileXSPP[uint2(scramblingIndex & 127, scramblingIndex / 128)], 0.999); + value = value ^ uint(scramblingValue * 256.0); + + // Convert to float (to avoid the same 1/256th quantization everywhere, we jitter by the pixel scramblingValue) + return (scramblingValue + value) / 256.0; +} +#endif // RAYTRACING_SAMPLING_INCLUDED diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/RaytracingSampling.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/RaytracingSampling.hlsl.meta new file mode 100644 index 000000000..34e7686b8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/RaytracingSampling.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f9b6c743ede223248807806f7c4793d2 +timeCreated: 1747748282 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HDRP Files/RaytracingSampling.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMain.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMain.hlsl new file mode 100644 index 000000000..43d364b98 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMain.hlsl @@ -0,0 +1,252 @@ +//pipelinedefine +#define H_URP + +#ifndef HMAIN_INCLUDED +#define HMAIN_INCLUDED + +// TODO: check if we need all these includes or some can be removed? +// --------------------------------- INCLUDE FILES ----------------------------- // + + + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareOpaqueTexture.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Sampling/Sampling.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl" +#include "../Headers/HDRP files/RaytracingSampling.hlsl" + +#include "../Includes/Config.hlsl" +#include "HMath.hlsl" +#include "HPacking.hlsl" + +// --------------------------------- INCLUDE FILES BELOW ALSO!!!!!!!!!! ----------------------------- // + +// ---------------------------------- MATRICES ----------------------------- // + + +float4x4 _H_MATRIX_PREV_VP; +float4x4 _H_MATRIX_PREV_I_VP; +#define H_MATRIX_PREV_VP _H_MATRIX_PREV_VP +#define H_MATRIX_PREV_I_VP _H_MATRIX_PREV_I_VP +#define H_MATRIX_I_VP UNITY_MATRIX_I_VP +#define H_MATRIX_VP UNITY_MATRIX_VP +#define H_MATRIX_V UNITY_MATRIX_V +#define H_MATRIX_I_V UNITY_MATRIX_I_V + +// --------------------------------- ADDITIONAL INCLUDE FILES ----------------------------- // + +#include "HSpaceTransforms.hlsl" + +// --------------------------------- VALUES ----------------------------- // + +float4 _HRenderScale; +float4 _HRenderScalePrevious; + +#define HRenderScale _HRenderScale +#define HRenderScalePrevious _HRenderScalePrevious +//Unity's _RTHandleScale in URP always (1,1,1,1)? + + + +int _FrameCount; + + +// --------------------------------- CONSTANTS ----------------------------- // +#define H_TWO_PI (6.28318530718f) +#define H_PI (3.1415926535897932384626433832795) +#define H_PI_HALF (1.5707963267948966192313216916398) + + +// --------------------------------- TEXTURE SAMPLERS ----------------------------- // + + +SamplerState sampler_point_clamp; +SamplerState sampler_linear_clamp; +SamplerState sampler_point_repeat; +SamplerState sampler_point_mirror; +SamplerState sampler_linear_repeat; +SamplerState sampler_trilinear_clamp; + +#define H_SAMPLER SAMPLER +#define H_SAMPLER_POINT_CLAMP sampler_point_clamp +#define H_SAMPLER_LINEAR_CLAMP sampler_linear_clamp +#define H_SAMPLER_LINEAR_REPEAT sampler_linear_repeat +#define H_SAMPLER_TRILINEAR_CLAMP sampler_trilinear_clamp +#define H_SAMPLER_LINEAR_CLAMP_COMPARE sampler_LinearClampCompare + + +// --------------------------------- TEXTURE READ / WRITE HELPERS ----------------------------- // + + +#define H_COORD(pixelCoord) uint2(pixelCoord) //todo: do we need defines for VR? +#define H_INDEX_ARRAY(slot) (slot) + + +// ----------------------------- TEXTURE PROPERTY DECLARATIONS ----------------------------- // + + +#define H_TEXTURE(textureName) TEXTURE2D_X(textureName) //todo: do we need defines for VR? +#define H_TEXTURE_ARRAY(textureName) TEXTURE2D_ARRAY(textureName) +#define H_TEXTURE_DX(type, textureName) Texture2D textureName +#define H_TEXTURE_UINT2(textureName) Texture2D textureName //todo: do we need defines for VR? +#define H_TEXTURE3D(type, textureName) Texture3D textureName + +#define H_RW_TEXTURE(type, textureName) RW_TEXTURE2D(type, textureName) //todo: do we need defines for VR? +#define H_RW_TEXTURE3D(type, textureName) RWTexture3D textureName +#define H_RW_TEXTURE_ARRAY(type, textureName) RW_TEXTURE2D_ARRAY(type, textureName) +#define H_RW_TEXTURE_UINT2(textureName) RW_TEXTURE2D_X_UINT2(textureName) + + +// ----------------------------- TEXTURE FETCH ----------------------------- // + + +#define H_LOAD(textureName, unCoord2) LOAD_TEXTURE2D_X(textureName, unCoord2) +#define H_LOAD_LOD(textureName, unCoord2, lod) LOAD_TEXTURE2D_X_LOD(textureName, unCoord2, lod) +#define H_LOAD_ARRAY(textureName, unCoord2, index) LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) +#define H_LOAD_ARRAY_LOD(textureName, unCoord2, index, lod) LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) + +#define H_SAMPLE(textureName, samplerName, coord2) SAMPLE_TEXTURE2D_X(textureName, samplerName, coord2) +#define H_SAMPLE_2D(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2) +#define H_SAMPLE_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_X_LOD(textureName, samplerName, coord2, lod) +#define H_SAMPLE_ARRAY(textureName, samplerName, coord2, index) SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, H_INDEX_ARRAY(index)) +#define H_SAMPLE_ARRAY_LOD(textureName, samplerName, coord2, index, lod) SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, H_INDEX_ARRAY(index), lod) +#define H_SAMPLE_SHADOW(textureName, samplerName, coord3) SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) +#define H_SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) + +#define H_GATHER_RED(textureName, samplerName, coord2, offset) GATHER_RED_TEXTURE2D_X(textureName, samplerName, coord2) +#define H_GATHER_BLUE(textureName, samplerName, coord2, offset) GATHER_BLUE_TEXTURE2D_X(textureName, samplerName, coord2) +#define H_GATHER_GREEN(textureName, samplerName, coord2, offset) GATHER_GREEN_TEXTURE2D_X(textureName, samplerName, coord2) +#define H_GATHER_ALPHA(textureName, samplerName, coord2, offset) GATHER_ALPHA_TEXTURE2D_X(textureName, samplerName, coord2) + +#define H_LOAD3D(textureName, unCoord3) LOAD_TEXTURE3D(textureName, unCoord3) +#define H_LOAD3D_LOD(textureName, unCoord3, lod) LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) + +// ------------------------------------- GBUFFER RESOURCES ----------------------------- // + +float4 H_SHAr; +float4 H_SHAg; +float4 H_SHAb; +float4 H_SHBr; +float4 H_SHBg; +float4 H_SHBb; +float4 H_SHC; + +H_TEXTURE(g_HTraceGBuffer0); +H_TEXTURE(g_HTraceGBuffer1); +H_TEXTURE(g_HTraceGBuffer2); +H_TEXTURE(g_HTraceGBuffer3); + +H_TEXTURE(g_HTraceDepth); +H_TEXTURE(g_HTraceDepthPyramidWSGI); +H_TEXTURE(g_HTraceColor); +H_TEXTURE(g_HTraceMotionMask); +H_TEXTURE(g_HTraceMotionVectors); + + + + +// --------------------------------- GBUFFER FETCH ----------------------------- // +#define HBUFFER_NORMAL_WS(pixCoord) GetNormalWS(pixCoord) +#define HBUFFER_ROUGHNESS(pixCoord) GetRoughness(pixCoord) +#define HBUFFER_DEPTH(pixCoord) H_LOAD(g_HTraceDepth, pixCoord).x +#define HBUFFER_COLOR(pixCoord) H_LOAD(g_HTraceColor, pixCoord) +#define HBUFFER_DIFFUSE(pixCoord) H_LOAD(g_HTraceGBuffer0, pixCoord).xyz +#define HBUFFER_MOTION_VECTOR(pixCoord) H_LOAD(g_HTraceMotionVectors, pixCoord).xy +#define HBUFFER_MOTION_MASK(pixCoord) GetMotionMask(pixCoord) +#define HBUFFER_GEOMETRICAL_NORMAL_FROM_DEPTH(pixCoord) GeometricalNormalFromDepth(pixCoord) + +float3 GetNormalWS(uint2 pixCoord) +{ + + + float3 Normal = H_LOAD(g_HTraceGBuffer2, pixCoord).xyz; + #if defined(_GBUFFER_NORMALS_OCT) + float2 RemappedOctNormalWS = Unpack888ToFloat2(Normal); + float2 OctNormalWS = RemappedOctNormalWS.xy * 2.0 - 1.0; + Normal = UnpackNormalOctQuadEncode(OctNormalWS); + #endif + return Normal; +} + +float GetRoughness(uint2 pixCoord) +{ + + + return LOAD_TEXTURE2D_X(g_HTraceGBuffer0, pixCoord).w; +} + +float3 GeometricalNormalFromDepth(float2 pixCoord) +{ + // Option 1: Protect borders by dilation + // if (pixCoord.x == 0) pixCoord.x += 2; + // if (pixCoord.y == 0) pixCoord.y += 2; + + // Option 2: Protect borders by culling out-of-frame samples + float CullX = 1; + float CullY = 1; + if (pixCoord.x == 0) CullX = 0; + if (pixCoord.y == 0) CullY = 0; + + // TODO: find out why do we need to protect borders < 0 (Left, Bottom) while going above _ScreenSize is okay (Top, Right) + + float DepthC = HBUFFER_DEPTH(pixCoord); + + // Early-out on the sky + if (DepthC <= 1e-7) + return 0; + + float DepthL = HBUFFER_DEPTH(pixCoord + int2(-1, 0)) * CullX; + float DepthR = HBUFFER_DEPTH(pixCoord + int2( 1, 0)); + float DepthD = HBUFFER_DEPTH(pixCoord + int2( 0, -1)) * CullY; + float DepthU = HBUFFER_DEPTH(pixCoord + int2( 0, 1)); + + float3 WorldPosC = H_COMPUTE_POSITION_WS((pixCoord + 0.5 + float2( 0.0, 0.0)) * _ScreenSize.zw, DepthC, H_MATRIX_I_VP); + float3 WorldPosL = H_COMPUTE_POSITION_WS((pixCoord + 0.5 + float2(-1.0, 0.0)) * _ScreenSize.zw, DepthL, H_MATRIX_I_VP) * CullX; + float3 WorldPosR = H_COMPUTE_POSITION_WS((pixCoord + 0.5 + float2( 1.0, 0.0)) * _ScreenSize.zw, DepthR, H_MATRIX_I_VP); + float3 WorldPosD = H_COMPUTE_POSITION_WS((pixCoord + 0.5 + float2( 0.0, -1.0)) * _ScreenSize.zw, DepthD, H_MATRIX_I_VP) * CullY; + float3 WorldPosU = H_COMPUTE_POSITION_WS((pixCoord + 0.5 + float2( 0.0, 1.0)) * _ScreenSize.zw, DepthU, H_MATRIX_I_VP); + + float3 L = WorldPosC - WorldPosL; + float3 R = WorldPosR - WorldPosC; + float3 D = WorldPosC - WorldPosD; + float3 U = WorldPosU - WorldPosC; + + float4 H = float4(HBUFFER_DEPTH(pixCoord + int2(-1, 0)) * CullX, + HBUFFER_DEPTH(pixCoord + int2( 1, 0)), + HBUFFER_DEPTH(pixCoord + int2(-2, 0)) * CullX, + HBUFFER_DEPTH(pixCoord + int2( 2, 0))); + + float4 V = float4(HBUFFER_DEPTH(pixCoord + int2(0, -1)) * CullY, + HBUFFER_DEPTH(pixCoord + int2(0, 1)), + HBUFFER_DEPTH(pixCoord + int2(0, -2)) * CullY, + HBUFFER_DEPTH(pixCoord + int2(0, 2))); + + float2 HE = abs((2 * H.xy - H.zw) - DepthC); + float2 VE = abs((2 * V.xy - V.zw) - DepthC); + + half3 DerivH = HE.x < HE.y ? L : R; + half3 DerivV = VE.x < VE.y ? D : U; + + return -normalize(cross(DerivH, DerivV)); +} + + +float GetMotionMask(uint2 pixCoord) +{ + + + return any(H_LOAD(g_HTraceMotionMask, pixCoord).xy != 0); +} + +// ---------------------------------- OTHER ----------------------------------------- + + +#define HGetInversePreviousExposureMultiplier 1 +#define HGetInverseCurrentExposureMultiplier 1 +#define HEnableProbeVolumes 0 +#define HGetCurrentExposureMultiplier 1 +#define HGetPreviousExposureMultiplier 1 + +#endif // HMAIN_INCLUDED diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMain.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMain.hlsl.meta new file mode 100644 index 000000000..2bc893de0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMain.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: bb95f9cc17963024782e495f2e5351f7 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMain.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMath.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMath.hlsl new file mode 100644 index 000000000..7c1b0e3b6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMath.hlsl @@ -0,0 +1,397 @@ +#ifndef HMATH_INCLUDED +#define HMATH_INCLUDED + +//#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl" + + +#define FLT_MIN 1.175494351e-38 +#define FLT_MAX 3.402823466e+38 + +#define H_PI (3.1415926535897932384626433832795) +#define H_PI_HALF (1.5707963267948966192313216916398) +#define H_PI_QUARTER 0.78539816339744830961566084581988 + + +float3 HSafeNormalize(float3 inVec) +{ + float dp3 = max(FLT_MIN, dot(inVec, inVec)); + return inVec * rsqrt(dp3); +} + +float HSinFromCos(float cosX) +{ + return sqrt(saturate(1 - cosX * cosX)); +} + +float Random(float2 Seed) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt = dot(Seed.xy, float2(a, b)); + float sn = fmod(dt, 3.14); + return frac(sin(sn) * c); +} + +//------------------------ Hash Random functions. + +uint Hash1(uint x) +{ + x += (x << 10u); + x ^= (x >> 6u); + x += (x << 3u); + x ^= (x >> 11u); + x += (x << 15u); + return x; +} + +uint Hash1Mutate(inout uint h) +{ + uint res = h; + h = Hash1(h); + return res; +} + +uint Hash_Combine(uint x, uint y) +{ + static const uint M = 1664525u, C = 1013904223u; + uint seed = (x * M + y + C) * M; + + seed ^= (seed >> 11u); + seed ^= (seed << 7u) & 0x9d2c5680u; + seed ^= (seed << 15u) & 0xefc60000u; + seed ^= (seed >> 18u); + return seed; +} + +uint Hash2(uint2 v) +{ + return Hash_Combine(v.x, Hash1(v.y)); +} + +uint Hash3(uint3 v) +{ + return Hash_Combine(v.x, Hash2(v.yz)); +} + +float UintToFloat01(uint h) +{ + static const uint mantissaMask = 0x007FFFFFu; + static const uint one = 0x3F800000u; + + h &= mantissaMask; + h |= one; + + float r2 = asfloat( h ); + return r2 - 1.0; +} + +float3 HClipRadiance(float3 Radiance, float MaxLuminance) +{ + if (AnyIsNaN(Radiance) || AnyIsInf(Radiance)) + Radiance = 0.0f; + + Radiance = RgbToHsv(Radiance); + Radiance.z = clamp(Radiance.z, 0.0, MaxLuminance); + Radiance = HsvToRgb(Radiance); + + return Radiance; +} + +float3x3 RotFromToMatrix( float3 from, float3 to ) +{ + const float e = dot(from, to); + const float f = abs(e); + const float3 v = cross( from, to ); + const float h = (1.0)/(1.0 + e); + const float hvx = h * v.x; + const float hvz = h * v.z; + const float hvxy = hvx * v.y; + const float hvxz = hvx * v.z; + const float hvyz = hvz * v.y; + + float3x3 mtx; + mtx[0][0] = e + hvx * v.x; + mtx[0][1] = hvxy - v.z; + mtx[0][2] = hvxz + v.y; + + mtx[1][0] = hvxy + v.z; + mtx[1][1] = e + h * v.y * v.y; + mtx[1][2] = hvyz - v.x; + + mtx[2][0] = hvxz - v.y; + mtx[2][1] = hvyz + v.x; + mtx[2][2] = e + hvz * v.z; + + return mtx; +} + +float HFastSqrt(float x) +{ + return (asfloat(0x1fbd1df5 + (asint(x) >> 1))); +} + +float HFastACos( float inX ) +{ + float pi = 3.141593; + float half_pi = 1.570796; + float x = abs(inX); + float res = -0.156583 * x + half_pi; + res *= HFastSqrt(1.0 - x); + return (inX >= 0) ? res : pi - res; +} + + +float CalculateHaltonNumber(in uint index, in uint base) +{ + float f = 1.0f; + float result = 0.0f; + + for (uint i = index; i > 0;) + { + f /= base; + result = result + f * (i % base); + i = uint(i / float(base)); + } + + return result; +} + +float2 CalculateHaltonSequence(in uint index) +{ + return float2(CalculateHaltonNumber((index & 0xFFu) + 1, 2), + CalculateHaltonNumber((index & 0xFFu) + 1, 3)); +} + +float3x3 ConstructTBN(float3 Normal) +{ + float3 CrossZ = cross(Normal, float3(0.0, 0.0, 1.0)); + float3 CrossY = cross(Normal, float3(0.0, 1.0, 0.0)); + + float3 Tangent = length(CrossZ) > length(CrossY) ? CrossZ : CrossY; + Tangent = normalize(Tangent); + + float3 Bitangent = normalize(cross(Tangent, Normal)); + + return float3x3(Tangent, Bitangent, Normal); +} + +float3 OrientedOctahedronToDirectionFast(float2 Coord, float3 Normal) +{ + Coord = 2.0f * Coord - 1.0f; + + Coord = float2(Coord.x + Coord.y, Coord.x - Coord.y) * 0.5; + float3 CellDirection = float3(Coord, 1.0 - abs(Coord.x) - abs(Coord.y)); + CellDirection = normalize(CellDirection); + CellDirection = mul(CellDirection, ConstructTBN(Normal)); + + return normalize(CellDirection); +} + +float2 DirectionToOrientedOctahedronFast(float3 Direction, float3 Normal) +{ + Direction = mul(ConstructTBN(Normal.xyz), Direction); + Direction = normalize(Direction); + Direction.z = saturate(Direction.z); + + float2 Coord = Direction.xy * (1.0 / (abs(Direction.x) + abs(Direction.y) + Direction.z)); + Coord = float2(Coord.x + Coord.y, Coord.x - Coord.y); + + Coord = 0.5 * Coord + 0.5f; + + return Coord * 4; +} + +float3 OrientedOctahedronToDirection(float2 Coord, float3 Normal) +{ + Coord = 2.0f * Coord - 1.0f; + + Coord = float2(Coord.x + Coord.y, Coord.x - Coord.y) * 0.5f; + float2 AbsCoord = abs(Coord); + float Distance = 1.0f - (AbsCoord.x + AbsCoord.y); + float Radius = 1.0f - abs(Distance); + float Phi = (Radius == 0.0f) ? 0.0f : H_PI_QUARTER * ((AbsCoord.y - AbsCoord.x) / Radius + 1.0f); + float RadiusSqr = Radius * Radius; + float SinTheta = Radius * sqrt(2.0f - RadiusSqr); + float SinPhi, CosPhi; + sincos(Phi, SinPhi, CosPhi); + float x = SinTheta * sign(Coord.x) * CosPhi; + float y = SinTheta * sign(Coord.y) * SinPhi; + float z = sign(Distance) * (1.0f - RadiusSqr); + + float3 CellDirection = float3(x, y, z); + CellDirection = normalize(CellDirection); + + //CellDirection = mul(CreateTBN(Normal), CellDirection); + CellDirection = mul(CellDirection, ConstructTBN(Normal)); + + return normalize(CellDirection); +} + +float2 DirectionToOrientedOctahedron(float3 Direction, float3 Normal) +{ + Direction = mul(ConstructTBN(Normal.xyz), Direction); + Direction = normalize(Direction); + + float3 AbsDir = abs(Direction); + float Radius = sqrt(1.0f - AbsDir.z); + float Epsilon = 5.42101086243e-20; // 2^-64 (this avoids 0/0 without changing the rest of the mapping) + float x = min(AbsDir.x, AbsDir.y) / (max(AbsDir.x, AbsDir.y) + Epsilon); + + // Coefficients for 6th degree minimax approximation of atan(x)*2/pi, x=[0,1]. + const float t1 = 0.406758566246788489601959989e-5f; + const float t2 = 0.636226545274016134946890922156f; + const float t3 = 0.61572017898280213493197203466e-2f; + const float t4 = -0.247333733281268944196501420480f; + const float t5 = 0.881770664775316294736387951347e-1f; + const float t6 = 0.419038818029165735901852432784e-1f; + const float t7 = -0.251390972343483509333252996350e-1f; + + // Polynomial approximation of atan(x)*2/pi + float Phi = t6 + t7 * x; + Phi = t5 + Phi * x; + Phi = t4 + Phi * x; + Phi = t3 + Phi * x; + Phi = t2 + Phi * x; + Phi = t1 + Phi * x; + + Phi = (AbsDir.x >= AbsDir.y) ? Phi : 1.0f - Phi; + float t = Phi * Radius; + float s = Radius - t; + float2 Coord = float2(s, t); + Coord *= sign(Direction).xy; + Coord = float2(Coord.x + Coord.y, Coord.x - Coord.y); + + Coord = 0.5 * Coord + 0.5f; + //Coord = clamp(Coord, 0.0f, 0.99f); + + return Coord * 4; +} + + +// This simplified version assume that we care about the result only when we are inside the box +float RayBoxIntersect(float3 start, float3 dir, float3 boxMin, float3 boxMax) +{ + float3 invDir = rcp(dir); + + // Find the ray intersection with box plane + float3 rbmin = (boxMin - start) * invDir; + float3 rbmax = (boxMax - start) * invDir; + + float3 rbminmax = (dir > 0.0) ? rbmax : rbmin; + + return min(min(rbminmax.x, rbminmax.y), rbminmax.z); +} + +float2 LineBoxIntersect(float3 RayOrigin, float3 RayEnd, float3 BoxMin, float3 BoxMax) +{ + float3 InvRayDir = 1.0f / (RayEnd - RayOrigin); + + //find the ray intersection with each of the 3 planes defined by the minimum extrema. + float3 FirstPlaneIntersections = (BoxMin - RayOrigin) * InvRayDir; + //find the ray intersection with each of the 3 planes defined by the maximum extrema. + float3 SecondPlaneIntersections = (BoxMax - RayOrigin) * InvRayDir; + //get the closest of these intersections along the ray + float3 ClosestPlaneIntersections = min(FirstPlaneIntersections, SecondPlaneIntersections); + //get the furthest of these intersections along the ray + float3 FurthestPlaneIntersections = max(FirstPlaneIntersections, SecondPlaneIntersections); + + float2 BoxIntersections; + //find the furthest near intersection + BoxIntersections.x = max(ClosestPlaneIntersections.x, max(ClosestPlaneIntersections.y, ClosestPlaneIntersections.z)); + //find the closest far intersection + BoxIntersections.y = min(FurthestPlaneIntersections.x, min(FurthestPlaneIntersections.y, FurthestPlaneIntersections.z)); + //clamp the intersections to be between RayOrigin and RayEnd on the ray + return saturate(BoxIntersections); +} + + + +float3x3 HGetLocalFrame(float3 localZ) +{ + float x = localZ.x; + float y = localZ.y; + float z = localZ.z; + + + float sz = FastSign(z); + float a = 1 / (sz + z); + float ya = y * a; + float b = x * ya; + float c = x * sz; + + float3 localX = float3(c * x * a - 1, sz * b, c); + float3 localY = float3(b, y * ya - sz, y); + + return float3x3(localX, localY, localZ); +} + +float2 HSampleDiskCubic(float u1, float u2) +{ + float r = u1; + float phi = 2 * H_PI * u2; + + float sinPhi, cosPhi; + sincos(phi, sinPhi, cosPhi); + + return r * float2(cosPhi, sinPhi); +} + + +float3 HSphericalToCartesian(float cosPhi, float sinPhi, float cosTheta) +{ + float sinTheta = HSinFromCos(cosTheta); + return float3(float2(cosPhi, sinPhi) * sinTheta, cosTheta); +} + +float3 HSphericalToCartesian(float phi, float cosTheta) +{ + float sinPhi, cosPhi; + sincos(phi, sinPhi, cosPhi); + return HSphericalToCartesian(cosPhi, sinPhi, cosTheta); +} + +float3 HSampleSphereUniform(float u1, float u2) +{ + float phi = 6.28318530718f * u2; + float cosTheta = 1.0 - 2.0 * u1; + return HSphericalToCartesian(phi, cosTheta); +} + +float3 HSampleHemisphereCosine(float u1, float u2, float3 normal) +{ + float3 pointOnSphere = HSampleSphereUniform(u1, u2); + return HSafeNormalize(normal + pointOnSphere); +} + + +float2 HLineBoxIntersect(float3 RayOrigin, float3 RayEnd, float3 BoxMin, float3 BoxMax) +{ + float3 InvRayDir = 1.0f / (RayEnd - RayOrigin); + + float3 FirstPlaneIntersections = (BoxMin - RayOrigin) * InvRayDir; + float3 SecondPlaneIntersections = (BoxMax - RayOrigin) * InvRayDir; + float3 ClosestPlaneIntersections = min(FirstPlaneIntersections, SecondPlaneIntersections); + float3 FurthestPlaneIntersections = max(FirstPlaneIntersections, SecondPlaneIntersections); + + float2 BoxIntersections; + BoxIntersections.x = max(ClosestPlaneIntersections.x, max(ClosestPlaneIntersections.y, ClosestPlaneIntersections.z)); + BoxIntersections.y = min(FurthestPlaneIntersections.x, min(FurthestPlaneIntersections.y, FurthestPlaneIntersections.z)); + return saturate(BoxIntersections); +} + +float HUintToFloat01(uint h) +{ + static const uint MantissaMask = 0x007FFFFFu; + static const uint One = 0x3F800000u; + + h &= MantissaMask; + h |= One; + + float r2 = asfloat(h); + return r2 - 1.0; +} + +#endif //HMATH_INCLUDED + +//--------------------------------------------------------------> diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMath.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMath.hlsl.meta new file mode 100644 index 000000000..6f2f78d91 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMath.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: abe48ccf0412419488069215e8f28ff8 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HMath.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HPacking.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HPacking.hlsl new file mode 100644 index 000000000..7670e3287 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HPacking.hlsl @@ -0,0 +1,680 @@ +#ifndef HPACKING_INCLUDED +#define HPACKING_INCLUDED + +float3 HFastTonemap(float3 Color) +{ + float T = rcp(1.0f + max(max(Color.r, Color.g), Color.b)); + return saturate(Color * float(T)); +} + +float3 HFastTonemapInverse(float3 Color) +{ + float T = rcp(max(float(1.0 / 256.0), saturate(float(1.0 / 1.0f) - max(max(Color.r, Color.g), Color.b)) * float(1.0 / 1.0f))); + return Color * T; +} + +uint PackTonemappedColor24bit(float3 Color) +{ + Color = Color * rcp(max(max(Color.r, Color.g), Color.b) + 1.0f); + uint RadianceR = uint(Color.r * 255.0f + 0.5f) & 0xFF; + uint RadianceG = uint(Color.g * 255.0f + 0.5f) & 0xFF; + uint RadianceB = uint(Color.b * 255.0f + 0.5f) & 0xFF; + + return (RadianceR << 16) | (RadianceG << 8) | (RadianceB << 0); +} + +float3 UnpackTonemappedColor24bit(uint ColorPacked) +{ + float3 Color; + Color.r = ((ColorPacked >> 16) & 0xFF) / 255.0f; + Color.g = ((ColorPacked >> 8) & 0xFF) / 255.0f; + Color.b = ((ColorPacked >> 0) & 0xFF) / 255.0f; + + return Color * rcp(1.0 - max(max(Color.r, Color.g), Color.b)); +} + +uint PackVoxelColor(float3 Color, bool IsEmissive) +{ + uint3 ColorPacked; + if (IsEmissive) + { + Color = HFastTonemap(Color); + ColorPacked.r = uint(Color.r * 255.0f + 0.5f) & 0xFF; + ColorPacked.g = uint(Color.g * 127.0f + 0.5f) & 0x7F; + ColorPacked.b = uint(Color.b * 127.0f + 0.5f) & 0x7F; + return (ColorPacked.r << 15) | (ColorPacked.g << 8) | (ColorPacked.b << 1) | IsEmissive; + } + + ColorPacked.r = uint(Color.x * 255.0f + 0.5f) & 0xFF; + ColorPacked.g = uint(Color.y * 127.0f + 0.5f) & 0x7F; + ColorPacked.b = uint(Color.z * 127.0f + 0.5f) & 0x7F; + + return (ColorPacked.r << 15) | (ColorPacked.g << 8) | (ColorPacked.b << 1) | IsEmissive; +} + +float3 UnpackVoxelColor(uint Input, out bool IsEmissive) +{ + IsEmissive = Input & 0x1; + + float3 Color; + + if (IsEmissive) + { + // float H = ((Input >> 0) & 0x3F) / 63.0f; + // float S = ((Input >> 6) & 0x3F) / 63.0f; + // float V = f16tof32((Input >> 12) << 5); + // return HsvToRgb(float3(H, S, V)); + + Color.r = ((Input >> 15) & 0xFF) / 255.0f; + Color.g = ((Input >> 8) & 0x7F) / 127.0f; + Color.b = ((Input >> 1) & 0x7F) / 127.0f; + return Color = HFastTonemapInverse(Color); + } + + Color.r = float((Input >> 15) & 0xFF) / 255.0f; + Color.g = float((Input >> 8) & 0x7F) / 127.0f; + Color.b = float((Input >> 1) & 0x7F) / 127.0f; + //Color = SRGBToLinear(Color); + + return Color; + +} + +uint PackToR11G10B10A1f(float3 InputF3, float InputB) +{ + uint r = (f32tof16(InputF3.x) << 17) & 0xFFE00000; // 11111111.11100000.00000000.00000000 + uint g = (f32tof16(InputF3.y) << 6) & 0x001FF800; // 00000000.00011111.11111000.00000000 + uint b = (f32tof16(InputF3.z) >> 4) & 0x000007FE; // 00000000.00000000.00000111.11111110 + uint a = InputB == 1.0f ? 0x00000001 : 0x00000000; + return r | g | b | a; +} + +float3 UnpackFromR11G10B10A1f(uint InputU, inout bool InoutB) +{ + float r = f16tof32((InputU >> 17) & 0x7FF0); // 00000000.00000000.01111111.11110000 + float g = f16tof32((InputU >> 6) & 0x7FF0); // 00000000.00000000.01111111.11110000 + float b = f16tof32((InputU << 4) & 0x7FE0); // 00000000.00000000.01111111.11110000 + InoutB = (InputU & 0x00000001) == 0x00000001 ? 1.0f : 0.0f; + return float3(r, g, b); +} + +float3 UnpackFromR11G10B10A1f(uint InputU) +{ + float r = f16tof32((InputU >> 17) & 0x7FF0); // 00000000.00000000.01111111.11110000 + float g = f16tof32((InputU >> 6) & 0x7FF0); // 00000000.00000000.01111111.11110000 + float b = f16tof32((InputU << 4) & 0x7FE0); // 00000000.00000000.01111111.11110000 + return float3(r, g, b); +} + + +uint3 PackCacheRadiance(float3 RadianceFull, float3 RadianceNear) +{ + uint PackedR = (uint(f32tof16(RadianceFull.r)) << 16) | uint(f32tof16(RadianceNear.r)); + uint PackedG = (uint(f32tof16(RadianceFull.g)) << 16) | uint(f32tof16(RadianceNear.g)); + uint PackedB = (uint(f32tof16(RadianceFull.b)) << 16) | uint(f32tof16(RadianceNear.b)); + + return uint3(PackedR, PackedG, PackedB); +} + +float3 UnpackCacheRadianceFull(uint3 RadiancePacked) +{ + float3 Radiance; + Radiance.r = f16tof32(((RadiancePacked.r) >> 16) & 0xFFFF); + Radiance.g = f16tof32(((RadiancePacked.g) >> 16) & 0xFFFF); + Radiance.b = f16tof32(((RadiancePacked.b) >> 16) & 0xFFFF); + + return Radiance; +} + +float3 UnpackCacheRadianceNear(uint3 RadiancePacked) +{ + float3 Radiance; + Radiance.r = f16tof32((RadiancePacked.r) & 0xFFFF); + Radiance.g = f16tof32((RadiancePacked.g) & 0xFFFF); + Radiance.b = f16tof32((RadiancePacked.b) & 0xFFFF); + + return Radiance; +} + +uint PackVoxelNormalIndex(float3 Normal) +{ + float3 AbsDirection = abs(Normal); + float MaxDirection = max(max(AbsDirection.x, AbsDirection.y), AbsDirection.z); + + if (MaxDirection == AbsDirection.z) + { + uint Sign = saturate(sign(Normal.z)); + return 4 + Sign; + } + else + { + uint Max = step(AbsDirection.x, AbsDirection.y); + uint Sign = saturate(sign(Normal[Max])); + return 2 * Max + Sign; + } + + // Anisotropy Layout: + // X- == 0 (Buffer_B[0] / .x) + // X+ == 1 (Buffer_B[1] / .y) + // Y- == 2 (Buffer_B[2] / .z) + // Y+ == 3 (Buffer_B[3] / .w) + // Z- == 4 (Buffer_A[0] / .x) + // Z+ == 5 (Buffer_A[1] / .y) + + // This is the same but in a more illustrative (and probably slow) way: + + // if (MaxDirection == AbsDirection.x) + // { + // if (Normal.x < 0) + // return 0; + // else + // return 1; + // } + // else if (MaxDirection == AbsDirection.y) + // { + // if (Normal.y < 0) + // return 2; + // else + // return 3; + // } + // else + // { + // if (Normal.z < 0) + // return 4; + // else + // return 5; + // } +} + +float3 UnpackVoxelNormalIndex(uint NormalIndex) +{ + float3 VoxelNormals[6] = {float3(-1, 0, 0), float3(1, 0, 0), float3(0, -1, 0), float3(0, 1, 0), float3(0, 0, -1), float3(0, 0, 1)}; + return VoxelNormals[NormalIndex]; +} + +uint2 PackCacheHitPayload(float3 HitOffset, float3 RayDirection, float3 HitNormal, uint3 HitCoord, float SkyOcclusion, uint HashRank, bool HitFound, bool HitFlag) +{ + uint PackedX; + + // If hit found we pack an offset from voxel coord + if (HitFound) + { + float HitOffsetLength = length(HitOffset); + HitOffset = -normalize(HitOffset) * 0.5f + 0.5f; + + uint OffsetX = uint(HitOffset.x * 127.0f + 0.5f) & 0x7F; + uint OffsetY = uint(HitOffset.y * 127.0f + 0.5f) & 0x7F; + uint OffsetZ = uint(HitOffset.z * 127.0f + 0.5f) & 0x7F; + + uint OffsetLength = uint(HitOffsetLength * 255.0f + 0.5f) & 0xFF; + + PackedX = (OffsetX << 25) | (OffsetY << 18) | (OffsetZ << 11) | (OffsetLength << 3) | (HitFlag << 2) | HitFound; + } + else + { + RayDirection = RayDirection * 0.5 + 0.5; + uint RayDirectionX = uint(RayDirection.x * 255.0f + 0.5f) & 0xFF; + uint RayDirectionY = uint(RayDirection.y * 255.0f + 0.5f) & 0xFF; + uint RayDirectionZ = uint(RayDirection.z * 255.0f + 0.5f) & 0xFF; + + uint SkyOcclusionPacked = uint(SkyOcclusion * 31.0f + 0.5f) & 0x1F; + + PackedX = (RayDirectionX << 24) | (RayDirectionY << 16) | (RayDirectionZ << 8) | (SkyOcclusionPacked << 3) | (HitFlag << 2); + } + + uint HitNormalIndex = (PackVoxelNormalIndex(HitNormal) & 0x7) << 2; + + uint CoordX = ((HitCoord.x - 1) & 0x1FF) << 5; + uint CoordY = ((HitCoord.y - 1) & 0x1FF) << 14; + uint CoordZ = ((HitCoord.z - 1) & 0x1FF) << 23; + + uint PackedY = CoordX | CoordY | CoordZ | HitNormalIndex | HashRank; + + return uint2(PackedX, PackedY); +} + +bool UnpackCacheHitPayload(uint2 PayloadPacked, inout float3 RayDirection, inout float3 HitOffset, inout float3 HitNormal, inout uint3 HitCoord, inout float SkyOcclusion, inout uint HashRank, inout bool HitFlag) +{ + HitFlag = (PayloadPacked.x >> 2) & 0x1; + bool IsHit = PayloadPacked.x & 0x1; + + HitOffset = 0; + RayDirection = 0; + SkyOcclusion = 0; + + if (IsHit) + { + HitOffset.x = float((PayloadPacked.x >> 25) & 0x7F) / 127.0f; + HitOffset.y = float((PayloadPacked.x >> 18) & 0x7F) / 127.0f; + HitOffset.z = float((PayloadPacked.x >> 11) & 0x7F) / 127.0f; + HitOffset = HitOffset * 2 - 1; + + float HitOffsetLength = float((PayloadPacked.x >> 3) & 0xFF) / 255.0f; + HitOffset *= HitOffsetLength; + } + else + { + RayDirection.x = float((PayloadPacked.x >> 25) & 0xFF) / 255.0f; + RayDirection.y = float((PayloadPacked.x >> 18) & 0xFF) / 255.0f; + RayDirection.z = float((PayloadPacked.x >> 11) & 0xFF) / 255.0f; + RayDirection = RayDirection * 2 - 1; + + SkyOcclusion = float((PayloadPacked.x >> 3) & 0x1F) / 31.0f; + } + + HitNormal = UnpackVoxelNormalIndex(((PayloadPacked.y) >> 2) & 0x7); + + HashRank = PayloadPacked.y & 0x3; + PayloadPacked.y &= 0xFFFFFFE0; + + HitCoord.x = ((PayloadPacked.y >> 5) & 0x1FF) + 1; + HitCoord.y = ((PayloadPacked.y >> 14) & 0x1FF) + 1; + HitCoord.z = ((PayloadPacked.y >> 23) & 0x1FF) + 1; + + return IsHit; +} + + +uint2 PackVoxelHitPayload(float3 HitOffset, float HitDistance, float3 HitNormal, uint3 HitCoord, bool HitFound) +{ + float HitOffsetLength = length(HitOffset); + HitOffset = -normalize(HitOffset) * 0.5f + 0.5f; + + uint OffsetX = uint(HitOffset.x * 127.0f + 0.5f) & 0x7F; + uint OffsetY = uint(HitOffset.y * 127.0f + 0.5f) & 0x7F; + uint OffsetZ = uint(HitOffset.z * 127.0f + 0.5f) & 0x7F; + uint OffsetLength = uint(HitOffsetLength * 127.0f + 0.5f) & 0x7F; + + // Approximate distance for cache dimming + uint DistanceApprox = uint(saturate(HitDistance) * 15.0f + 0.5f) & 0xF; + + uint PackedX = (OffsetX << 25) | (OffsetY << 18) | (OffsetZ << 11) | (OffsetLength << 4) | DistanceApprox; + + uint HitNormalIndex = (PackVoxelNormalIndex(HitNormal) & 0x7) << 2; + + uint CoordX = ((HitCoord.x - 1) & 0x1FF) << 5; + uint CoordY = ((HitCoord.y - 1) & 0x1FF) << 14; + uint CoordZ = ((HitCoord.z - 1) & 0x1FF) << 23; + + uint PackedY = CoordX | CoordY | CoordZ | HitNormalIndex | HitFound; // 1 bit is free + + return uint2(PackedX, PackedY); +} + +bool UnpackVoxelHitPayload(uint2 PayloadPacked, inout float HitDistanceApprox, inout float3 HitOffset, inout float3 HitNormal, inout uint3 HitCoord) +{ + bool IsHit = PayloadPacked.y & 0x1; + + HitOffset = 0; + HitOffset.x = float((PayloadPacked.x >> 25) & 0x7F) / 127.0f; + HitOffset.y = float((PayloadPacked.x >> 18) & 0x7F) / 127.0f; + HitOffset.z = float((PayloadPacked.x >> 11) & 0x7F) / 127.0f; + HitOffset = HitOffset * 2 - 1; + + float HitOffsetLength = float((PayloadPacked.x >> 4) & 0x7F) / 127.0f; + HitOffset *= HitOffsetLength; + + HitDistanceApprox = float(PayloadPacked.x & 0xF) / 15.0f; + + HitNormal = UnpackVoxelNormalIndex(((PayloadPacked.y) >> 2) & 0x7); + + PayloadPacked.y &= 0xFFFFFFE0; + + HitCoord.x = ((PayloadPacked.y >> 5) & 0x1FF) + 1; + HitCoord.y = ((PayloadPacked.y >> 14) & 0x1FF) + 1; + HitCoord.z = ((PayloadPacked.y >> 23) & 0x1FF) + 1; + + return IsHit; +} + +uint PackHitOffset(float3 HitOffset) +{ + float HitOffsetLength = length(HitOffset); + HitOffset = -normalize(HitOffset) * 0.5f + 0.5f; + + uint OffsetX = uint(HitOffset.x * 255.0f + 0.5f) & 0xFF; + uint OffsetY = uint(HitOffset.y * 255.0f + 0.5f) & 0xFF; + uint OffsetZ = uint(HitOffset.z * 255.0f + 0.5f) & 0xFF; + + uint OffsetLength = uint(HitOffsetLength * 255.0f + 0.5f) & 0xFF; + + return (OffsetX << 24) | (OffsetY << 16) | (OffsetZ << 8) | (OffsetLength << 0); +} + +float3 UnpackHitOffset(uint HitOffsetPacked) +{ + float3 HitOffset; + HitOffset.x = float((HitOffsetPacked >> 24) & 0xFF) / 255.0f; + HitOffset.y = float((HitOffsetPacked >> 16) & 0xFF) / 255.0f; + HitOffset.z = float((HitOffsetPacked >> 8) & 0xFF) / 255.0f; + HitOffset = HitOffset * 2 - 1; + + float HitOffsetLength = float(HitOffsetPacked & 0xFF) / 255.0f; + + return HitOffset * HitOffsetLength; +} + +uint PackHashKey(uint3 HitCoord, float3 HitNormal) +{ + uint HitNormalIndex = (PackVoxelNormalIndex(HitNormal) & 0x7) << 2; // 00000000.00000000.00000000.00011100 + + uint HitCoordX = ((HitCoord.x - 1) & 0x1FF) << 5; // 00000000.00000000.00111111.11100000 + uint HitCoordY = ((HitCoord.y - 1) & 0x1FF) << 14; // 00000000.01111111.11000000.00000000 + uint HitCoordZ = ((HitCoord.z - 1) & 0x1FF) << 23; // 11111111.10000000.00000000.00000000 + + return HitCoordX | HitCoordY | HitCoordZ | HitNormalIndex; +} + +uint3 UnpackHitCoordFromHashKey(uint HashKey) +{ + HashKey = HashKey & 0xFFFFFFE0; + + uint3 HitCoord; + HitCoord.x = ((HashKey >> 5) & 0x1FF) + 1; + HitCoord.y = ((HashKey >> 14) & 0x1FF) + 1; + HitCoord.z = ((HashKey >> 23) & 0x1FF) + 1; + + return HitCoord; +} + +float3 UnpackHitNormalFromHashKey(uint HashKey) +{ + return UnpackVoxelNormalIndex(((HashKey) >> 2) & 0x7); +} + +uint PackHitDistance(float input1, bool input2, bool input3) +{ + uint f1 = f32tof16(input1) & 0xFFFC; + uint b1 = input2 == true ? 1 : 0; + uint b2 = input3 == true ? 1 : 0; + return f1 | b1 << 1 | b2; +} + +float UnpackHitDistance(uint input, out bool b1, out bool b2) +{ + float out1 = f16tof32(input & 0xFFFC); + b1 = (input & 0x2) == 0x2; + b2 = (input & 0x1) == 0x1; + return out1; +} + +uint4 PackFilteringOffsetsX8(int2 Coords[8]) +{ + uint4 PackedCoords; + uint2 CoordsA, CoordsB; + + CoordsA.x = (abs(Coords[0].x) & 0x7F) | (sign(Coords[0].x) < 0 ? 0x80 : 0x0); + CoordsA.y = (abs(Coords[0].y) & 0x7F) | (sign(Coords[0].y) < 0 ? 0x80 : 0x0); + CoordsB.x = (abs(Coords[1].x) & 0x7F) | (sign(Coords[1].x) < 0 ? 0x80 : 0x0); + CoordsB.y = (abs(Coords[1].y) & 0x7F) | (sign(Coords[1].y) < 0 ? 0x80 : 0x0); + + PackedCoords.x = (CoordsA.x << 0) | (CoordsA.y << 8) | (CoordsB.x << 16) | (CoordsB.y << 24); + + CoordsA.x = (abs(Coords[2].x) & 0x7F) | (sign(Coords[2].x) < 0 ? 0x80 : 0x0); + CoordsA.y = (abs(Coords[2].y) & 0x7F) | (sign(Coords[2].y) < 0 ? 0x80 : 0x0); + CoordsB.x = (abs(Coords[3].x) & 0x7F) | (sign(Coords[3].x) < 0 ? 0x80 : 0x0); + CoordsB.y = (abs(Coords[3].y) & 0x7F) | (sign(Coords[3].y) < 0 ? 0x80 : 0x0); + + PackedCoords.y = (CoordsA.x << 0) | (CoordsA.y << 8) | (CoordsB.x << 16) | (CoordsB.y << 24); + + CoordsA.x = (abs(Coords[4].x) & 0x7F) | (sign(Coords[4].x) < 0 ? 0x80 : 0x0); + CoordsA.y = (abs(Coords[4].y) & 0x7F) | (sign(Coords[4].y) < 0 ? 0x80 : 0x0); + CoordsB.x = (abs(Coords[5].x) & 0x7F) | (sign(Coords[5].x) < 0 ? 0x80 : 0x0); + CoordsB.y = (abs(Coords[5].y) & 0x7F) | (sign(Coords[5].y) < 0 ? 0x80 : 0x0); + + PackedCoords.z = (CoordsA.x << 0) | (CoordsA.y << 8) | (CoordsB.x << 16) | (CoordsB.y << 24); + + CoordsA.x = (abs(Coords[6].x) & 0x7F) | (sign(Coords[6].x) < 0 ? 0x80 : 0x0); + CoordsA.y = (abs(Coords[6].y) & 0x7F) | (sign(Coords[6].y) < 0 ? 0x80 : 0x0); + CoordsB.x = (abs(Coords[7].x) & 0x7F) | (sign(Coords[7].x) < 0 ? 0x80 : 0x0); + CoordsB.y = (abs(Coords[7].y) & 0x7F) | (sign(Coords[7].y) < 0 ? 0x80 : 0x0); + + PackedCoords.w = (CoordsA.x << 0) | (CoordsA.y << 8) | (CoordsB.x << 16) | (CoordsB.y << 24); + + return PackedCoords; +} + +void UnpackFilteringOffsetsX8(uint4 OffsetsPacked, inout int2 Offsets[8]) +{ + Offsets[0].x = ((OffsetsPacked.x >> 0) & 0x7F) * (((OffsetsPacked.x >> 0) & 0x80) ? -1 : 1); + Offsets[0].y = ((OffsetsPacked.x >> 8) & 0x7F) * (((OffsetsPacked.x >> 8) & 0x80) ? -1 : 1); + Offsets[1].x = ((OffsetsPacked.x >> 16) & 0x7F) * (((OffsetsPacked.x >> 16) & 0x80) ? -1 : 1); + Offsets[1].y = ((OffsetsPacked.x >> 24) & 0x7F) * (((OffsetsPacked.x >> 24) & 0x80) ? -1 : 1); + Offsets[2].x = ((OffsetsPacked.y >> 0) & 0x7F) * (((OffsetsPacked.y >> 0) & 0x80) ? -1 : 1); + Offsets[2].y = ((OffsetsPacked.y >> 8) & 0x7F) * (((OffsetsPacked.y >> 8) & 0x80) ? -1 : 1); + Offsets[3].x = ((OffsetsPacked.y >> 16) & 0x7F) * (((OffsetsPacked.y >> 16) & 0x80) ? -1 : 1); + Offsets[3].y = ((OffsetsPacked.y >> 24) & 0x7F) * (((OffsetsPacked.y >> 24) & 0x80) ? -1 : 1); + Offsets[4].x = ((OffsetsPacked.z >> 0) & 0x7F) * (((OffsetsPacked.z >> 0) & 0x80) ? -1 : 1); + Offsets[4].y = ((OffsetsPacked.z >> 8) & 0x7F) * (((OffsetsPacked.z >> 8) & 0x80) ? -1 : 1); + Offsets[5].x = ((OffsetsPacked.z >> 16) & 0x7F) * (((OffsetsPacked.z >> 16) & 0x80) ? -1 : 1); + Offsets[5].y = ((OffsetsPacked.z >> 24) & 0x7F) * (((OffsetsPacked.z >> 24) & 0x80) ? -1 : 1); + Offsets[6].x = ((OffsetsPacked.w >> 0) & 0x7F) * (((OffsetsPacked.w >> 0) & 0x80) ? -1 : 1); + Offsets[6].y = ((OffsetsPacked.w >> 8) & 0x7F) * (((OffsetsPacked.w >> 8) & 0x80) ? -1 : 1); + Offsets[7].x = ((OffsetsPacked.w >> 16) & 0x7F) * (((OffsetsPacked.w >> 16) & 0x80) ? -1 : 1); + Offsets[7].y = ((OffsetsPacked.w >> 24) & 0x7F) * (((OffsetsPacked.w >> 24) & 0x80) ? -1 : 1); +} + +uint4 PackFilteringWeightsX8(float Weights[8]) +{ + uint4 PackedWeights; + PackedWeights.x = ((uint(Weights[0] * 255.0f + 0.5f) & 0xFF) << 0) | ((uint(Weights[1] * 255.0f + 0.5f) & 0xFF) << 8); + PackedWeights.y = ((uint(Weights[2] * 255.0f + 0.5f) & 0xFF) << 0) | ((uint(Weights[3] * 255.0f + 0.5f) & 0xFF) << 8); + PackedWeights.z = ((uint(Weights[4] * 255.0f + 0.5f) & 0xFF) << 0) | ((uint(Weights[5] * 255.0f + 0.5f) & 0xFF) << 8); + PackedWeights.w = ((uint(Weights[6] * 255.0f + 0.5f) & 0xFF) << 0) | ((uint(Weights[7] * 255.0f + 0.5f) & 0xFF) << 8); + + return PackedWeights.xyzw; +} + +void UnpackFilteringWeightsX8(uint4 PackedWeights, inout float Weights[8]) +{ + Weights[0] = ((PackedWeights.x >> 0) & 0xFF) / 255.0f; + Weights[1] = ((PackedWeights.x >> 8) & 0xFF) / 255.0f; + Weights[2] = ((PackedWeights.y >> 0) & 0xFF) / 255.0f; + Weights[3] = ((PackedWeights.y >> 8) & 0xFF) / 255.0f; + Weights[4] = ((PackedWeights.z >> 0) & 0xFF) / 255.0f; + Weights[5] = ((PackedWeights.z >> 8) & 0xFF) / 255.0f; + Weights[6] = ((PackedWeights.w >> 0) & 0xFF) / 255.0f; + Weights[7] = ((PackedWeights.w >> 8) & 0xFF) / 255.0f; +} + +uint PackProbeAO(float Mask, float Samplecount, float MaxSamplecount) +{ + uint MaskPacked = uint(Mask * 255.0f + 0.5f) & 0xFF; + uint SamplecountPacked = uint(Samplecount / MaxSamplecount * 255.0f + 0.5f) & 0xFF; + + return (MaskPacked << 8) | (SamplecountPacked << 0); +} + +float2 UnpackProbeAO(uint GuidanceMaskPacked, float MaxSamplecount) +{ + float2 GuidanceMask; + GuidanceMask.x = ((GuidanceMaskPacked >> 8) & 0xFF) / 255.0f; + GuidanceMask.y = ((GuidanceMaskPacked >> 0) & 0xFF) / 255.0f * MaxSamplecount; + return GuidanceMask; +} + +uint PackDirection24bit(float3 Direction) +{ + Direction = Direction * 0.5 + 0.5; + uint DirectionX = uint(Direction.x * 255.0f + 0.5f) & 0xFF; + uint DirectionY = uint(Direction.y * 255.0f + 0.5f) & 0xFF; + uint DirectionZ = uint(Direction.z * 255.0f + 0.5f) & 0xFF; + + return (DirectionX << 16) | (DirectionY << 8) | (DirectionZ << 0); +} + +float3 UnpackDirection24bit(uint DirectionPacked) +{ + float3 Direction; + Direction.x = float((DirectionPacked >> 16) & 0xFF) / 255.0f; + Direction.y = float((DirectionPacked >> 8) & 0xFF) / 255.0f; + Direction.z = float((DirectionPacked >> 0) & 0xFF) / 255.0f; + Direction = Direction * 2 - 1; + + return Direction; +} + +uint4 PackWorldPosNormal(float3 WorldPos, float3 Normal) +{ + Normal = Normal * 0.5f + 0.5f; + uint NormalPackedX = uint(Normal.x * 1023.0f + 0.5f) & 0x3FF; // 11111111.11000000.00000000.00000000 + uint NormalPackedY = uint(Normal.y * 1023.0f + 0.5f) & 0x3FF; // 00000000.00111111.11110000.00000000 + uint NormalPackedZ = uint(Normal.z * 1023.0f + 0.5f) & 0x3FF; // 00000000.00000000.00001111.11111100 + + uint NormalPacked = (NormalPackedX << 22) | (NormalPackedY << 12) | (NormalPackedZ << 2); + + return uint4(asuint(WorldPos.x), asuint(WorldPos.y), asuint(WorldPos.z), NormalPacked); +} + +void UnpackWorldPosNormal(uint4 WorldPosNormalPacked, inout float3 WorldPos, inout float3 Normal) +{ + Normal.x = ((WorldPosNormalPacked.w >> 22) & 0x3FF) / 1023.0f; + Normal.y = ((WorldPosNormalPacked.w >> 12) & 0x3FF) / 1023.0f; + Normal.z = ((WorldPosNormalPacked.w >> 2) & 0x3FF) / 1023.0f; + Normal = Normal * 2.0f - 1.0f; + + WorldPos.x = asfloat(WorldPosNormalPacked.x); + WorldPos.y = asfloat(WorldPosNormalPacked.y); + WorldPos.z = asfloat(WorldPosNormalPacked.z); +} + +uint2 PackNormalDepth(float3 Normal, float Depth) +{ + Normal = Normal * 0.5f + 0.5f; + uint NormalPackedX = uint(Normal.x * 1023.0f + 0.5f) & 0x3FF; // 11111111.11000000.00000000.00000000 + uint NormalPackedY = uint(Normal.y * 1023.0f + 0.5f) & 0x3FF; // 00000000.00111111.11110000.00000000 + uint NormalPackedZ = uint(Normal.z * 1023.0f + 0.5f) & 0x3FF; // 00000000.00000000.00001111.11111100 + + uint NormalPacked = (NormalPackedX << 22) | (NormalPackedY << 12) | (NormalPackedZ << 2); + + return uint2(NormalPacked, asuint(Depth)); +} + +float4 UnpackNormalDepthFull(uint2 NormalDepthPacked) +{ + float3 Normal; + Normal.x = ((NormalDepthPacked.x >> 22) & 0x3FF) / 1023.0f; + Normal.y = ((NormalDepthPacked.x >> 12) & 0x3FF) / 1023.0f; + Normal.z = ((NormalDepthPacked.x >> 2) & 0x3FF) / 1023.0f; + Normal = Normal * 2.0f - 1.0f; + + return float4(Normal.xyz, asfloat(NormalDepthPacked.y)); +} + +uint2 PackNormalDepth2(float3 Normal, float Depth, uint2 Offset) +{ + uint3 NormalPacked; + Normal = Normal * 0.5f + 0.5f; + NormalPacked.x = uint(Normal.x * 255.0f + 0.5f) & 0xFF; // 11111111.00000000.00000000.00000000 + NormalPacked.y = uint(Normal.y * 255.0f + 0.5f) & 0xFF; // 00000000.11111111.00000000.00000000 + NormalPacked.z = uint(Normal.z * 255.0f + 0.5f) & 0xFF; // 00000000.00000000.11111111.00000000 + + uint NormalOffsetPacked = (NormalPacked.x << 24) | (NormalPacked.y << 16) | (NormalPacked.z << 8) | (Offset.x << 4) | (Offset.y << 0); + + return uint2(NormalOffsetPacked, asuint(Depth)); +} + +float3 UnpackNormal(uint2 NormalDepthPacked) +{ + float3 Normal; + Normal.x = ((NormalDepthPacked.x >> 24) & 0xFF) / 255.0f; + Normal.y = ((NormalDepthPacked.x >> 16) & 0xFF) / 255.0f; + Normal.z = ((NormalDepthPacked.x >> 8) & 0xFF) / 255.0f; + Normal = Normal * 2.0f - 1.0f; + + return Normal; +} + +float4 UnpackNormalDepth(uint2 NormalDepthPacked, inout float2 Offset) +{ + float3 Normal; + Normal.x = ((NormalDepthPacked.x >> 24) & 0xFF) / 255.0f; + Normal.y = ((NormalDepthPacked.x >> 16) & 0xFF) / 255.0f; + Normal.z = ((NormalDepthPacked.x >> 8) & 0xFF) / 255.0f; + Normal = Normal * 2.0f - 1.0f; + + Offset.x = (NormalDepthPacked.x >> 4) & 0xF; + Offset.y = (NormalDepthPacked.x >> 0) & 0xF; + + return float4(Normal.xyz, asfloat(NormalDepthPacked.y)); +} + +uint2 PackReprojectionCoord(uint2 ReprojectionCoord, uint2 BestOffset, bool ReprojectionFailed) +{ + uint PackedX = (ReprojectionCoord.x & 0x3FFF) | (BestOffset.x << 15) | (ReprojectionFailed << 14); + uint PackedY = (ReprojectionCoord.y & 0x3FFF) | (BestOffset.y << 15) | (ReprojectionFailed << 14); + + return uint2(PackedX, PackedY); +} + +uint2 UnpackReprojectionCoord(uint2 ReprojectionCoordPacked) +{ + uint2 ReprojectionCoord; + ReprojectionCoord.x = ReprojectionCoordPacked.x & 0x3FFF; + ReprojectionCoord.y = ReprojectionCoordPacked.y & 0x3FFF; + + return ReprojectionCoord; +} + +uint2 UnpackBestReprojectionCoord(uint2 ReprojectionCoordPacked, inout uint2 BestOffset, inout bool ReprojectionFailed) +{ + uint2 ReprojectionCoord; + ReprojectionCoord.x = ReprojectionCoordPacked.x & 0x3FFF; + ReprojectionCoord.y = ReprojectionCoordPacked.y & 0x3FFF; + + BestOffset.x = (ReprojectionCoordPacked.x >> 15) & 0x1; + BestOffset.y = (ReprojectionCoordPacked.y >> 15) & 0x1; + + ReprojectionFailed = (ReprojectionCoordPacked.x >> 14) & 0x1; + + return ReprojectionCoord; +} + +uint2 PackPersistentReprojectionCoord(uint2 ReprojectionCoord, uint ReprojectionIndex) +{ + uint PackedX = (ReprojectionCoord.x & 0x1FFF) | (ReprojectionIndex << 13); + uint PackedY = (ReprojectionCoord.y & 0x1FFF) | (ReprojectionIndex << 13); + + return uint2(PackedX, PackedY); +} + + +uint2 UnpackPersistentReprojectionCoord(uint2 ReprojectionCoordPacked, inout uint ReprojectionIndex) +{ + uint2 ReprojectionCoord; + ReprojectionCoord.x = ReprojectionCoordPacked.x & 0x1FFF; + ReprojectionCoord.y = ReprojectionCoordPacked.y & 0x1FFF; + + ReprojectionIndex = (ReprojectionCoordPacked.x >> 13) & 0x7; + + return ReprojectionCoord; +} + +uint PackVoxelBiasOffset(float3 RayOriginBiasedWS, float3 RayOriginUnbiasedWS) +{ + float Distance = length(RayOriginBiasedWS - RayOriginUnbiasedWS); + float3 Direction = normalize(RayOriginBiasedWS - RayOriginUnbiasedWS) * 0.5 + 0.5; + + uint DirectionX = uint(Direction.x * 255.0f + 0.5f) & 0xFF; + uint DirectionY = uint(Direction.y * 255.0f + 0.5f) & 0xFF; + uint DirectionZ = uint(Direction.z * 255.0f + 0.5f) & 0xFF; + uint DistancePacked = uint(Distance * 255.0f + 0.5f) & 0xFF; + + return (DirectionX << 24) | (DirectionY << 16) | (DirectionZ << 8) | (DistancePacked << 0); +} + +float4 UnpackVoxelBiasOffset(uint BiasDataPacked) +{ + float3 Direction; + Direction.x = float((BiasDataPacked >> 24) & 0xFF) / 255.0f; + Direction.y = float((BiasDataPacked >> 16) & 0xFF) / 255.0f; + Direction.z = float((BiasDataPacked >> 8) & 0xFF) / 255.0f; + Direction = Direction * 2 - 1; + + float Distance = float((BiasDataPacked >> 0) & 0xFF) / 255.0f; + + return float4(Direction.xyz, Distance); +} + + +#endif // HPACKING_INCLUDED diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HPacking.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HPacking.hlsl.meta new file mode 100644 index 000000000..d8c4abf97 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HPacking.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b24382b4f3e0e2a46b7da64a8df4b862 +timeCreated: 1691505704 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HPacking.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HSpaceTransforms.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HSpaceTransforms.hlsl new file mode 100644 index 000000000..d0a41c3db --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HSpaceTransforms.hlsl @@ -0,0 +1,151 @@ +#ifndef HSPACETRANFORM_INCLUDED +#define HSPACETRANFORM_INCLUDED + + + + +// --------------------------------- GET CAMERA POSITION +float3 H_GET_CAMERA_POSITION_WS() +{ + + + return _WorldSpaceCameraPos; +} + + +// --------------------------------- GET ABSOLUTE WS POSITION +float3 H_GET_ABSOLUTE_POSITION_WS(float3 PositionWS) +{ + + + return PositionWS; +} + + +// --------------------------------- GET RELATIVE WS POSITION +float3 H_GET_RELATIVE_POSITION_WS(float3 PositionWS) +{ + + + return GetCameraRelativePositionWS(PositionWS); +} + + +// --------------------------------- GET NORMALIZED WS VIEW DIRECTION +float3 H_GET_VIEW_DIRECTION_WS(float3 PositionWS) +{ + float3 ViewDirectionWS = H_GET_CAMERA_POSITION_WS() - H_GET_ABSOLUTE_POSITION_WS(PositionWS); + return normalize(ViewDirectionWS); +} + + +// --------------------------------- COMPUTE CLIP SPACE POSITION +float4 H_COMPUTE_POSITION_CS(float2 pixCoordNDC, float Depth) +{ + float4 PositionCS = float4(pixCoordNDC * 2.0 - 1.0, Depth, 1.0); + + #if UNITY_UV_STARTS_AT_TOP + PositionCS.y = -PositionCS.y; + #endif + + return PositionCS; +} + + +// --------------------------------- COMPUTE CLIP SPACE POSITION +float3 H_COMPUTE_NDC_Z(float3 Position, float4x4 InvViewProjMatrix) +{ + + return ComputeNormalizedDeviceCoordinatesWithZ(Position, InvViewProjMatrix); + +} +//ComputeNormalizedDeviceCoordinatesWithZ + + +// --------------------------------- COMPUTE WORLD SPACE POSITION +float3 H_COMPUTE_POSITION_WS(float2 pixCoordNDC, float Depth, float4x4 InvViewProjMatrix) +{ + + return ComputeWorldSpacePosition(pixCoordNDC, Depth, InvViewProjMatrix); + +} + + +// --------------------------------- WORLD TO VIEW DIRECTION +float3 H_TRANSFORM_WORLD_TO_VIEW_DIR(float3 DirectionWS, bool Normalize = false) +{ + float3 DirectionVS = mul((float3x3)H_MATRIX_V, DirectionWS).xyz; + if (Normalize) return normalize(DirectionVS); + + return DirectionVS; +} +// TransformWorldToViewDir + + +// --------------------------------- VIEW TO WORLD DIRECTION +float3 H_TRANSFORM_VIEW_TO_WORLD_DIR(float3 DirectionVS, bool Normalize = false) +{ + float3 DirectionWS = mul((float3x3)H_MATRIX_I_V, DirectionVS).xyz; + if (Normalize) return normalize(Normalize); + + return DirectionWS; +} +// TransformViewToWorldDir + + +// --------------------------------- WORLD TO VIEW NOWMAL +float3 H_TRANSFORM_WORLD_TO_VIEW_NORMAL(float3 NormalWS, bool Normalize = false) +{ + + return TransformWorldToViewNormal(NormalWS); + +} +// TransformWorldToViewNormal + + +// --------------------------------- WORLD TO VIEW NOWMAL +float4 H_TRANSFORM_WORLD_TO_H_CLIP(float3 positionWS) +{ + + return TransformWorldToHClip(positionWS); + +} + + + +// --------------------------------- VIEW TO WORLD NOWMAL +float3 H_TRANSFORM_VIEW_TO_WORLD_NORMAL(float3 NormalVS, bool Normalize = false) +{ + + return TransformViewToWorldNormal(NormalVS); + +} +// TransformViewToWorldNormal + + +// --------------------------------- RAW TO 01 LINEAR DEPTH +float H_LINEAR_01_DEPTH(float Depth) +{ + + + return Linear01Depth(Depth, _ZBufferParams); +} + + +// --------------------------------- RAW TO EYE LINEAR DEPTH +float H_LINEAR_EYE_DEPTH(float3 PositionWS, float4x4 ViewMatrix) +{ + + + return LinearEyeDepth(PositionWS, ViewMatrix); +} + + +float H_LINEAR_EYE_DEPTH(float Depth) +{ + + + return LinearEyeDepth(Depth, _ZBufferParams); +} + +#endif // HSPACETRANFORM_INCLUDED diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HSpaceTransforms.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HSpaceTransforms.hlsl.meta new file mode 100644 index 000000000..9038cf9c9 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HSpaceTransforms.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8505ab98b43172840b18cb8f72bed2cf +timeCreated: 1747748089 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Headers/HSpaceTransforms.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes.meta new file mode 100644 index 000000000..263576ff4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fae6e70ada49f914587d5501074bb8c9 +timeCreated: 1719664127 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Config.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Config.hlsl new file mode 100644 index 000000000..58b548b7b --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Config.hlsl @@ -0,0 +1,75 @@ + +#ifndef HCONFIG_INCLUDED +#define HCONFIG_INCLUDED + +// Screen Probe Reprojection // +#define REPROJECTION_AREA_SEARCH 1 +#define REPROJECTION_WITH_RELAXED_WEIGHTS 1 + +// Spatial Reservoir Prepass // +#define DISK_FILTER_USE_AO_GUIDED_RADIUS 1 +#define DISK_FILTER_MIN_RADIUS 0.35 +#define DISK_FILTER_STEP_SIZE 0.15 +#define DISK_FILTER_MAX_SEARCH_SAMPLES 32 +#define DISK_FILTER_MINIMUM_ACCEPT_WEIGHT 0.05 + +// Probe Ambient Occlusion +#define PROBE_AO_CLAMP_DISTANCE 0.5 +#define PROBE_AO_MAX_TEMPORAL_SAMPLES 8 + +// ReSTIR settings // +#define RESTIR_EXPOSURE_CONTROL 1 +#define RESTIR_MAX_HISTORY 20 + +// Occlusion Validation // +#define MAX_OCCLUSION_TRACING_DISTANCE 5 +#define MAX_OCCLUSION_TEMPORAL_SAMPLES 16 + +// Screen Probe Interpolation +#define USE_RESERVOIR_RAY_DIRECTION 0 +#define INTERPOLATION_NORMAL_BOOST 1 +#define INTERPOLATION_SAMPLES 9 + +// Denoiser +#define TEMPORAL_DENOISER_EXPOSURE_CONTROL 1 +#define USE_NORMAL_REJECTION 1 +#define AABB_CLIP_EXTENT 4 +#define MAX_SAMPLECOUNT 32 + +// Radiance Cache +#define FREEZE_CACHE 0 +#define ADAPTIVE_TEMPORAL_WEIGHT 1 +#define MAX_TEMPORAL_WEIGHT 0.85 +#define MIN_TEMPORAL_WEIGHT 0.30 + +// Sky Occlusion // +#define EVALUATE_SKY_OCCLUSION 1 +#define MINIMAL_SKY_LIGHTING 0 + +// Reflection Probes +#define OCCLUSION_CHECK 1 // Helps to mitigate light leaks +#define SPATIAL_SAMPLES 25 // 1 - no filtering, 9 - 3x3 filter, 25 - 5x5 filter +#define JITTER_STRENGTH 25 // 0 - no jitter, 9 - 3x3 jitter, 25 - 5x5 jitter +#define JITTER_TEMPORAL 1 // 1 - enable temporal noise + +float _DirectionalLightIntensity; +float _SurfaceDiffuseIntensity; +float _SkyLightIntensity; + +// Indirect Intensity Multipliers (values higher than 1.0 are NOT physically correct!) +#define DIRECTIONAL_LIGHT_INTENSITY _DirectionalLightIntensity +#define SURFACE_DIFFUSE_INTENSITY _SurfaceDiffuseIntensity +#define SKY_LIGHT_INTENSITY _SkyLightIntensity + +// Fallback +#define APV_FALLBACK 1 + +// Disable Features +#define DISABLE_WS_TRACING 0 +#define DISABLE_SS_TRACING 0 +#define DISABLE_PROBE_JITTER 0 +#define DISABLE_RESTIR_TEMPORAL 0 +#define DISABLE_RESTIR_SPATIAL 0 +#define DISABLE_INTERPOLATION 0 +#define DISABLE_TEMPORAL_DENOISER 0 +#endif diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Config.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Config.hlsl.meta new file mode 100644 index 000000000..896d53df8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Config.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: e63fa30afd333614cb82e3e09a5f3e3c +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Config.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/FallbackAPV.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/FallbackAPV.hlsl new file mode 100644 index 000000000..6ba1ee841 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/FallbackAPV.hlsl @@ -0,0 +1,24 @@ +//pipelinedefine +#define H_URP + +#include "Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl" + +float3 EvaluateAPV(float3 PositionWS, float3 NormalWS, float3 ViewDirection, float2 pixCoord) +{ + float3 BakedAPV = 0; + float3 Unused = 0; + + unity_SHAr = H_SHAr; + unity_SHAg = H_SHAg; + unity_SHAb = H_SHAb; + unity_SHBr = H_SHBr; + unity_SHBg = H_SHBg; + unity_SHBb = H_SHBb; + unity_SHC = H_SHC; + + EvaluateAdaptiveProbeVolume(PositionWS, NormalWS, -NormalWS, ViewDirection, pixCoord, BakedAPV, Unused); + + return BakedAPV; +} + + diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/FallbackAPV.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/FallbackAPV.hlsl.meta new file mode 100644 index 000000000..e80332a3a --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/FallbackAPV.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 6bf27d4f72a33134b88393615a0a19a0 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/FallbackAPV.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/LightCluster.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/LightCluster.hlsl new file mode 100644 index 000000000..fb35a2152 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/LightCluster.hlsl @@ -0,0 +1,167 @@ +#ifndef LIGHT_CLUSTER_INCLUDED +#define LIGHT_CLUSTER_INCLUDED + +uint g_HeatmapDebug; +uint g_MaxLightsPerCell; +uint g_SceneLightsBufferSize; +uint3 g_LightClusterDimensions; + +float3 g_LightCluterCellSize; +float3 g_MinLightClusterPosition; +float3 g_MaxLightClusterPosition; + +bool IsInsideLightCluster(float3 PositionWS) +{ + return all(PositionWS >= g_MinLightClusterPosition && PositionWS <= g_MaxLightClusterPosition); +} + +uint GetFlattenedIndex(uint3 Index3D) +{ + return Index3D.x + (Index3D.y * g_LightClusterDimensions.x) + (Index3D.z * g_LightClusterDimensions.x * g_LightClusterDimensions.y); +} + +bool ClusterCellSphereIntersection(float3 SphereCenterPosition, float SphereRadius, float3 CellMinCorner, float3 CellMaxCorner) +{ + float ClosestX = max(CellMinCorner.x, min(SphereCenterPosition.x, CellMaxCorner.x)); + float ClosestY = max(CellMinCorner.y, min(SphereCenterPosition.y, CellMaxCorner.y)); + float ClosestZ = max(CellMinCorner.z, min(SphereCenterPosition.z, CellMaxCorner.z)); + + float DistanceSquared = + (ClosestX - SphereCenterPosition.x) * (ClosestX - SphereCenterPosition.x) + + (ClosestY - SphereCenterPosition.y) * (ClosestY - SphereCenterPosition.y) + + (ClosestZ - SphereCenterPosition.z) * (ClosestZ - SphereCenterPosition.z); + + return DistanceSquared < SphereRadius * SphereRadius; +} + +bool ClusterCellConeIntersection( + float3 ConeTipPosition, // Tip of the cone (spotlight position) + float3 ConeDirection, // Normalized direction vector + float ConeAngleDegrees, // Full cone angle in degrees + float ConeLength, // Cone length + float3 CellMinCorner, // AABB minimum corner + float3 CellMaxCorner // AABB maximum corner +) +{ + // Check if cone tip is inside the AABB + if (all(ConeTipPosition >= CellMinCorner) && all(ConeTipPosition <= CellMaxCorner)) + return true; + + // Precompute cone parameters + float HalfAngleRadians = radians(ConeAngleDegrees * 0.5); + float CosHalfAngle = cos(HalfAngleRadians); + float SinHalfAngle = sin(HalfAngleRadians); + float CosHalfAngleSquared = CosHalfAngle * CosHalfAngle; + float ConeLengthSquared = ConeLength * ConeLength; + + // Generate all 8 corners of the AABB + float3 CellCorners[8]; + + UNITY_UNROLL + for (int i = 0; i < 8; i++) + { + CellCorners[i] = float3( + (i & 1) ? CellMaxCorner.x : CellMinCorner.x, + (i & 2) ? CellMaxCorner.y : CellMinCorner.y, + (i & 4) ? CellMaxCorner.z : CellMinCorner.z + ); + } + + // Test 1: Check if any corner is inside the cone + UNITY_UNROLL + for (int Index = 0; Index < 8; Index++) + { + float3 VectorToCorner = CellCorners[Index] - ConeTipPosition; + float DistanceSquared = dot(VectorToCorner, VectorToCorner); + + if (DistanceSquared > ConeLengthSquared) continue; + + float ProjectionOnConeDirection = dot(VectorToCorner, ConeDirection); + if (ProjectionOnConeDirection <= 0) continue; + + float ProjectionSquared = ProjectionOnConeDirection * ProjectionOnConeDirection; + if (ProjectionSquared >= DistanceSquared * CosHalfAngleSquared) + return true; + } + + // Test 2: Check if cone axis intersects the AABB + // Ray-AABB intersection for the cone's central axis + float3 InvConeDir = 1.0 / (ConeDirection + 1e-6); // Avoid division by zero + float3 t0 = (CellMinCorner - ConeTipPosition) * InvConeDir; + float3 t1 = (CellMaxCorner - ConeTipPosition) * InvConeDir; + + float3 tmin = min(t0, t1); + float3 tmax = max(t0, t1); + + float tNear = max(max(tmin.x, tmin.y), tmin.z); + float tFar = min(min(tmax.x, tmax.y), tmax.z); + + if (tNear <= tFar && tFar >= 0 && tNear <= ConeLength) + return true; + + // Test 3: Check AABB edges against cone + // Define the 12 edges of the AABB + int EdgeIndices[12][2] = { + {0, 1}, {2, 3}, {4, 5}, {6, 7}, // X-aligned edges + {0, 2}, {1, 3}, {4, 6}, {5, 7}, // Y-aligned edges + {0, 4}, {1, 5}, {2, 6}, {3, 7} // Z-aligned edges + }; + + UNITY_UNROLL + for (int EdgeIndex = 0; EdgeIndex < 12; EdgeIndex++) + { + float3 EdgeStart = CellCorners[EdgeIndices[EdgeIndex][0]]; + float3 EdgeEnd = CellCorners[EdgeIndices[EdgeIndex][1]]; + float3 EdgeDir = EdgeEnd - EdgeStart; + float EdgeLength = length(EdgeDir); + EdgeDir /= EdgeLength; + + // Find closest point on edge to cone axis + float3 W = EdgeStart - ConeTipPosition; + float a = dot(EdgeDir, EdgeDir); + float b = dot(EdgeDir, ConeDirection); + float c = dot(ConeDirection, ConeDirection); + float d = dot(EdgeDir, W); + float e = dot(ConeDirection, W); + + float Denominator = a * c - b * b; + float EdgeT, ConeT; + + if (abs(Denominator) < 1e-6) + { + // Lines are parallel + EdgeT = 0; + ConeT = e / c; + } + else + { + EdgeT = (b * e - c * d) / Denominator; + ConeT = (a * e - b * d) / Denominator; + } + + // Clamp to edge bounds + EdgeT = clamp(EdgeT, 0.0, EdgeLength); + + // Check if closest point on edge is within cone + if (ConeT >= 0 && ConeT <= ConeLength) + { + float3 PointOnEdge = EdgeStart + EdgeDir * EdgeT; + float3 VectorToPoint = PointOnEdge - ConeTipPosition; + float DistSq = dot(VectorToPoint, VectorToPoint); + + if (DistSq <= ConeLengthSquared) + { + float Projection = dot(VectorToPoint, ConeDirection); + if (Projection > 0) + { + float ProjSq = Projection * Projection; + if (ProjSq >= DistSq * CosHalfAngleSquared) + return true; + } + } + } + } + + return false; +} +#endif // LIGHT_CLUSTER_INCLUDED diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/LightCluster.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/LightCluster.hlsl.meta new file mode 100644 index 000000000..ba3696f21 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/LightCluster.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 4344098fe68bdaa4da4887d9dffdbaae +timeCreated: 1743097516 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/LightCluster.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ReflectionGI.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ReflectionGI.hlsl new file mode 100644 index 000000000..35e81aeab --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ReflectionGI.hlsl @@ -0,0 +1,226 @@ +#ifndef REFLECTION_GI_INCLUDED +#define REFLECTION_GI_INCLUDED + +#include "../Includes/VoxelTraversal.hlsl" +#include "../Includes/VoxelLightingEvaluation.hlsl" +#include "../Includes/SpatialHash.hlsl" + + +uint _HTraceReflectionsGI_JitterRadius; +uint _HTraceReflectionsGI_TemporalJitter; +uint _HTraceReflectionsGI_SpatialFilteringRadius; + +float _HTraceReflectionsGI_RayBias; +float _HTraceReflectionsGI_MaxRayLength; + +float3 HTraceIndirectLighting(uint2 pixCoord, float3 RayOriginWS, float3 NormalWS, float3 DiffuseColor) +{ + //TORELEASE: patreoncode, delete, regionstart + float3 IndirectLighting = 0; + float3 AbsolutePositionWS = GetAbsolutePositionWS(RayOriginWS); + + #ifdef GI_APPROXIMATION_IN_REFLECTIONS + + // Calculate voxel coord from position + int3 VoxelBoxCenter = int3(_VoxelResolution.xzy / 2); + int3 VoxelPosition = floor((AbsolutePositionWS - _VoxelCameraPos) / _VoxelSize); + float3 VoxelCoord = VoxelBoxCenter + VoxelPosition; + + // Load normal + float3 NormalAbs = abs(NormalWS); + float NormalMax = max(max(NormalAbs.x, NormalAbs.y), NormalAbs.z); + + float3 CacheNormal = 0; + float3 CacheNormalSign = 0; + float3 GatherDirection = 0; + + if (NormalMax == NormalAbs.x) + { + CacheNormal = float3(1,0,0); + GatherDirection = float3(0,1,1); + CacheNormalSign.x = sign(NormalWS.x); + } + if (NormalMax == NormalAbs.y) + { + CacheNormal = float3(0,1,0); + GatherDirection = float3(1,0,1); + CacheNormalSign.y = sign(NormalWS.y); + + } + if (NormalMax == NormalAbs.z) + { + CacheNormal = float3(0,0,1); + GatherDirection = float3(1,1,0); + CacheNormalSign.z = sign(NormalWS.z); + } + + // Offsets used for gather + int2 Offsets5x5[25] = {int2( 0, 0), int2( 0, 1), int2( 1, 0), int2( 1, 1), int2(-1, 0), + int2(-1, 1), int2(-1, -1), int2( 0, -1), int2( 1, -1), int2(-2, 0), + int2( 0, -2), int2( 2, 0), int2( 0, 2), int2(-1, 2), int2(-2, 1), + int2( 1, -2), int2( 2, -1), int2(-2, -1), int2(-1, -2), int2( 2, 1), + int2( 1, 2), int2(-2, 2), int2( 2, 2), int2( 2, -2), int2(-2, -2)}; + + // Check neighbours for occlusions + #ifdef GI_APPROXIMATION_IN_REFLECTIONS_OCCLUSION_CHECK + { + int2 Offsets3x3[12] = { int2( 0, 1), int2( 1, 0), int2( 1, 1), int2(-1, 0), + int2(-1, 1), int2(-1, -1), int2( 0, -1), int2( 1, -1), + int2(-2, 0), int2( 2, 0), int2( 0, -2), int2( 0, 2) }; + + for (int i = 0; i < 12; i++) + { + float3 Offset; + Offset.x = Offsets3x3[i].x; + Offset.y = Offsets3x3[i].y; + Offset.z = Offsets3x3[i][GatherDirection.x]; + + Offset.x *= GatherDirection.x; + Offset.y *= GatherDirection.y; + Offset.z *= GatherDirection.z; + + uint VoxelOccupancy = asuint(H_LOAD3D_LOD(_VoxelPositionPyramid, VoxelCoord + Offset + float3(1,1,1) * CacheNormal * CacheNormalSign, 0)); + + if (VoxelOccupancy > 0) + { + Offsets5x5[i + 1] = 0; + + if (i == 0) { Offsets5x5[13] = 0; Offsets5x5[12] = 0; Offsets5x5[20] = 0; } + if (i == 1) { Offsets5x5[19] = 0; Offsets5x5[11] = 0; Offsets5x5[16] = 0; } + if (i == 2) { Offsets5x5[20] = 0; Offsets5x5[22] = 0; Offsets5x5[19] = 0; } + if (i == 3) { Offsets5x5[14] = 0; Offsets5x5[ 9] = 0; Offsets5x5[17] = 0; } + if (i == 4) { Offsets5x5[13] = 0; Offsets5x5[21] = 0; Offsets5x5[14] = 0; } + if (i == 5) { Offsets5x5[17] = 0; Offsets5x5[24] = 0; Offsets5x5[18] = 0; } + if (i == 6) { Offsets5x5[18] = 0; Offsets5x5[10] = 0; Offsets5x5[15] = 0; } + if (i == 7) { Offsets5x5[15] = 0; Offsets5x5[23] = 0; Offsets5x5[16] = 0; } + + if (i == 8) { Offsets5x5[14] = 0; Offsets5x5[ 9] = 0; Offsets5x5[17] = 0; } + if (i == 9) { Offsets5x5[19] = 0; Offsets5x5[11] = 0; Offsets5x5[16] = 0; } + if (i == 10) { Offsets5x5[18] = 0; Offsets5x5[10] = 0; Offsets5x5[15] = 0; } + if (i == 11) { Offsets5x5[13] = 0; Offsets5x5[12] = 0; Offsets5x5[20] = 0; } + } + } + } + #endif + + float3 AccumulateCache = 0; + float AccumulatedWeight = 0; + + // Accumulate radiance cache spatially + for (int i = 0; i < _HTraceReflectionsGI_SpatialFilteringRadius; i++) + { + int3 SampleCoord = VoxelCoord; + + // Apply sample offset + float3 Offset; + Offset.x = Offsets5x5[i].x; + Offset.y = Offsets5x5[i].y; + Offset.z = Offsets5x5[i][GatherDirection.x]; + + // Apply per-pixel jitter + float PixelJitter = GetBNDSequenceSample(pixCoord.xy, (_FrameCount % 8) * _HTraceReflectionsGI_TemporalJitter, i); + Offset.x += Offsets5x5[PixelJitter * _HTraceReflectionsGI_JitterRadius].x; + Offset.y += Offsets5x5[PixelJitter * _HTraceReflectionsGI_JitterRadius].y; + Offset.z += Offsets5x5[PixelJitter * _HTraceReflectionsGI_JitterRadius][GatherDirection.x]; + + SampleCoord.x += Offset.x * GatherDirection.x; + SampleCoord.y += Offset.y * GatherDirection.y; + SampleCoord.z += Offset.z * GatherDirection.z; + + // Get hash cell + uint HashIndex = HashGetIndex(ComputeRadianceCacheCoord(SampleCoord), PackVoxelNormalIndex(NormalWS)); + + uint HashIndexFound; + uint HashKey = PackHashKey(ComputeRadianceCacheCoord(SampleCoord), NormalWS); + bool HashFound = HashFindValid(HashIndex, HashKey, HashIndexFound); + + if (HashFound) + { + float3 RadianceCacheSample = UnpackCacheRadianceFull(_HashBuffer_Radiance[HashIndexFound].xyz); + AccumulateCache += RadianceCacheSample; + AccumulatedWeight += 1; + } + } + + // Normalize + if (AccumulatedWeight > 0) + AccumulateCache /= AccumulatedWeight; + + IndirectLighting = AccumulateCache; + #endif + + #ifdef GI_TRACING_IN_REFLECTIONS + VoxelPayload Payload; + InitializePayload(Payload); + + uint SampleIndex = _FrameCount % 16; + + float2 RayJitter; + RayJitter.x = GetBNDSequenceSample(pixCoord.xy, SampleIndex, 0); + RayJitter.y = GetBNDSequenceSample(pixCoord.yx, SampleIndex, 1); + + float3 RayDirection = SampleHemisphereCosine(RayJitter.x, RayJitter.y, NormalWS); + AbsolutePositionWS += (_VoxelSize * _HTraceReflectionsGI_RayBias * RayDirection) + (_VoxelSize * _HTraceReflectionsGI_RayBias * NormalWS); + + // Calculate ray distance + float MaxRayDistance = MaxVoxelRayDistance(AbsolutePositionWS, RayDirection.xyz); + float RayDistance = _HTraceReflectionsGI_MaxRayLength == 0 ? MaxRayDistance : _HTraceReflectionsGI_MaxRayLength; + + // Trace into Voxels + bool HitFound = TraceVoxelsDiffuse(AbsolutePositionWS, RayDirection.xyz, RayDistance, 128, Payload); + + if (HitFound) + { + // Evauluate lighting on hit point + EvaluateHitLighting(Payload); + + float TotalRayDistance = Payload.HitDistance; + + uint3 CacheCoord = ComputeRadianceCacheCoord(Payload.HitCoord); + uint HashKey = PackHashKey(CacheCoord, Payload.HitNormal); + + bool IsEmpty; + uint HashRank = 2; + uint HashProbingIndex, HashLowestRankIndex; + uint HashIndex = HashGetIndex(CacheCoord, PackVoxelNormalIndex(Payload.HitNormal)); + bool HashFound = HashFindAny(HashIndex, HashKey, HashRank, HashLowestRankIndex, HashProbingIndex, IsEmpty); + + int3 VoxelCoordAbsolute = VoxelCoordToAbsoluteVoxelCoord(Payload.HitCoord); + float3 VoxelHitOffset = (float3(VoxelCoordAbsolute) * _VoxelSize) - (Payload.HitPosition) ; + + if (HashFound) // If a valid entry was found we reset the decay counter to max value and use cache (it's main purpose) + { + uint3 HitCachePacked = _HashBuffer_Radiance[HashProbingIndex].xyz; + + float3 RadianceFullRange = UnpackCacheRadianceFull(HitCachePacked.xyz); + float3 RadianceNearRange = UnpackCacheRadianceNear(HitCachePacked.xyz); + + // Choose far / near field cache based on the travelled ray distance + Payload.HitCache = TotalRayDistance > _VoxelSize.x * 4 ? RadianceFullRange : min(RadianceNearRange, RadianceFullRange); + + // Progressively dim cache at a distance smaller than a voxel size + Payload.HitCache *= lerp(0, 1, saturate(TotalRayDistance / 1 / _VoxelSize)); + + // Clip cache + Payload.HitCache *= GetCurrentExposureMultiplier(); + Payload.HitCache = HClipRadiance(Payload.HitCache, 10); + Payload.HitCache *= GetInverseCurrentExposureMultiplier(); + + // Add cache to hit radiance + Payload.HitColor += Payload.HitCache * Payload.HitDiffuse; + } + + IndirectLighting += Payload.HitColor; + } + else + { + IndirectLighting += SAMPLE_TEXTURECUBE_ARRAY_LOD(_SkyTexture, H_SAMPLER_TRILINEAR_CLAMP, RayDirection, 0, 2).xyz; + } + + #endif + + return IndirectLighting * DiffuseColor; + //TORELEASE: regionend + return float3(0, 0, 0); +} +#endif diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ReflectionGI.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ReflectionGI.hlsl.meta new file mode 100644 index 000000000..bef6abf91 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ReflectionGI.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a59ee92ba8c2f11418cbc300fc4e708a +timeCreated: 1750672896 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ReflectionGI.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Reservoir.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Reservoir.hlsl new file mode 100644 index 000000000..f1a001fed --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Reservoir.hlsl @@ -0,0 +1,363 @@ +#pragma once +#include "../Headers/HMain.hlsl" +#include "ScreenProbesCommon.hlsl" + +H_TEXTURE(_ProbeDiffuse); + +// Only Ray data +H_TEXTURE(_ReservoirAtlasRayData); +H_TEXTURE(_ReservoirAtlasRayData_Disocclusion); +H_RW_TEXTURE(uint, _ReservoirAtlasRayData_Output); + +// Only Radiance data +H_TEXTURE(_ReservoirAtlasRadianceData); +H_RW_TEXTURE(uint2, _ReservoirAtlasRadianceData_Inout); +H_RW_TEXTURE(uint2, _ReservoirAtlasRadianceData_Output); + +// Full reservoir with Radiance & Ray datas +H_TEXTURE(_ReservoirAtlas); +H_TEXTURE_ARRAY(_ReservoirAtlas_History); +H_RW_TEXTURE(uint4, _ReservoirAtlas_Output); +H_RW_TEXTURE_ARRAY(uint4, _ReservoirAtlas_ArrayOutput); + +uint _UseDiffuseWeight; + +// ------------------------ RESERVOIR STRUCTS ----------------------- +struct RadianceData +{ + float3 Color; + float Wsum; + float M; + float W; +}; + +struct OriginData +{ + // Empty for now, but we will need it for validation +}; + +struct RayData +{ + float3 OriginNormal; + float3 Direction; + float Distance; +}; + +struct Reservoir +{ + uint2 MergedCoord; + + RadianceData Radiance; + RayData Ray; +}; + + + +// ------------------------ RESERVOIR PACKING FUNCTIONS----------------------- + +uint2 PackRadianceData(RadianceData Radiance) +{ + uint W = f32tof16(Radiance.W); + uint M = f32tof16(Radiance.M); + uint PackedMW = (W << 16) | (M << 0); + uint PackedColor = PackTonemappedColor24bit(Radiance.Color); + + return uint2(PackedColor, PackedMW); +} + +uint2 PackRayData(RayData Ray) +{ + uint DirectionPacked = PackDirection24bit(Ray.Direction); + uint DistancePacked = (f32tof16(Ray.Distance) >> 8) & 0xFF; + + uint DistanceDirectionPacked = (DistancePacked << 24) | DirectionPacked; + uint OriginNormalPacked = PackDirection24bit(Ray.OriginNormal); + + return uint2(DistanceDirectionPacked, OriginNormalPacked); +} + +void UnpackRadianceData(uint2 RadianceDataPacked, float3 Diffuse, inout RadianceData Radiance) +{ + Radiance.Color = UnpackTonemappedColor24bit(RadianceDataPacked.x); + Radiance.W = f16tof32(RadianceDataPacked.y >> 16); + Radiance.M = f16tof32(RadianceDataPacked.y >> 0); + Radiance.Wsum = Radiance.W * Radiance.M * Luminance(Radiance.Color * Diffuse); +} + +void UnpackRayData(uint2 RayDataPacked, inout RayData Ray) +{ + Ray.Direction = UnpackDirection24bit(RayDataPacked.x); + Ray.Distance = f16tof32(((RayDataPacked.x >> 24) & 0xFF) << 8); + Ray.OriginNormal = UnpackDirection24bit(RayDataPacked.y); +} + +uint PackOcclusion(float Occlusion, bool IsDisocclusion) +{ + uint OcclusionPacked = uint(Occlusion * 127.0f + 0.5f) & 0x7F; + return (OcclusionPacked << 24) | (IsDisocclusion << 31); +} + +float UnpackOcclusion(uint OcclusionPacked, out bool IsDisocclusion) +{ + IsDisocclusion = OcclusionPacked >> 31; + return ((OcclusionPacked >> 24) & 0x7F) / 127.0f; +} + + +// ------------------------ RESERVOIR FUNCTIONS ----------------------- +float3 GetReservoirDiffuse(uint2 pixCoord) +{ + float3 DiffuseBuffer = _UseDiffuseWeight ? H_LOAD(_ProbeDiffuse, pixCoord).xyz : 1.0f; + + if (DiffuseBuffer.x + DiffuseBuffer.y + DiffuseBuffer.z == 0) + DiffuseBuffer = float3(0.05, 0.05, 0.05); + + return DiffuseBuffer; +} + +// Reservoir update +bool ReservoirUpdate(uint2 SampleCoord, float3 SampleColor, float SampleW, float SampleM, inout Reservoir Reservoir, inout uint Random) +{ + float RandomValue = UintToFloat01(Hash1Mutate(Random)); + + Reservoir.Radiance.Wsum += SampleW; + Reservoir.Radiance.M += SampleM; + + if (RandomValue < SampleW / Reservoir.Radiance.Wsum) + { + Reservoir.Radiance.Color = SampleColor; + Reservoir.MergedCoord = SampleCoord; + + return true; + } + + return false; +} + +// Reservoir update with RayData +bool ReservoirUpdate(uint2 SampleCoord, float3 SampleColor, float SampleW, float SampleM, RayData SampleRay, inout Reservoir Reservoir, inout uint Random) +{ + float RandomValue = UintToFloat01(Hash1Mutate(Random)); + + Reservoir.Radiance.Wsum += SampleW; + Reservoir.Radiance.M += SampleM; + + if (RandomValue < SampleW / Reservoir.Radiance.Wsum) + { + Reservoir.Radiance.Color = SampleColor; + Reservoir.MergedCoord = SampleCoord; + + Reservoir.Ray.OriginNormal = SampleRay.OriginNormal; + Reservoir.Ray.Direction = SampleRay.Direction; + Reservoir.Ray.Distance = SampleRay.Distance; + + return true; + } + + return false; +} + +// Merges central reservoir with a temporal neighbour (Radiance & Ray datas are exhanged) loaded externally +bool ReservoirMergeTemporal(uint2 SampleCoord, uint4 SampleReservoirPacked, uint ArrayIndex, float SampleWeight, float3 Diffuse, inout uint Random, inout Reservoir Reservoir) +{ + RadianceData SampleRadiance; + OriginData SampleOrigin; + RayData SampleRay; + + UnpackRadianceData(SampleReservoirPacked.xy, Diffuse, SampleRadiance); + UnpackRayData(SampleReservoirPacked.zw, SampleRay); + + SampleRadiance.Wsum *= SampleWeight; + SampleRadiance.M *= SampleWeight; + + return ReservoirUpdate(SampleCoord, SampleRadiance.Color, SampleRadiance.Wsum, SampleRadiance.M, SampleRay, Reservoir, Random); +} + +// Merges central reservoir with a spatial neighbour (only RadianceData is exchanged) loaded externally +bool ReservoirMergeSpatial(uint2 SampleCoord, uint2 SampleReservoirPacked, float SampleWeight, float3 Diffuse, inout Reservoir Reservoir, inout uint Random) +{ + RadianceData SampleRadiance; + UnpackRadianceData(SampleReservoirPacked, Diffuse, SampleRadiance); + + SampleRadiance.Wsum *= SampleWeight; + SampleRadiance.M *= SampleWeight; + + return ReservoirUpdate(SampleCoord, SampleRadiance.Color, SampleRadiance.Wsum, SampleRadiance.M, Reservoir, Random); +} + + +// Empty RadianceData initialization +void RadianceDataInitialize(out RadianceData Radiance) +{ + Radiance.Color = 0; + Radiance.Wsum = 0; + Radiance.M = 0; + Radiance.W = 0; +} + +// Empty RayData initialization +void RayDataInitialize(out RayData Ray) +{ + Ray.OriginNormal = 0; + Ray.Direction = 0; + Ray.Distance = 0; +} + +// Empty reservoir initialization +void ReservoirInitialize(uint2 Coord, out Reservoir Reservoir) +{ + Reservoir.MergedCoord = Coord; + + RadianceDataInitialize(Reservoir.Radiance); + RayDataInitialize(Reservoir.Ray); +} + + + + +// ------------------------ COMMON VARIABLES ----------------------- +int _PersistentHistorySamples; + + +// ------------------------ TEMPORAL REPROJECTION STRUCTS ----------------------- +struct CurrentFrameData +{ + float3 Normal; + float3 WorldPos; + float DepthRaw; + float AligmentZ; + float DepthLinear; + bool MovingPixel; +}; + +struct PrevFrameData +{ + float3 Normal; + float3 WorldPos; + float DepthLinear; +}; + + +// ------------------------ TEMPORAL REPROJECTION FUNCTIONS ----------------------- +int GetHistoryIndex(int Index) +{ + Index += 1; + + int HistoryIndex = uint(_FrameCount) % _PersistentHistorySamples - Index; + + if (HistoryIndex < 0) + HistoryIndex = _PersistentHistorySamples - abs(HistoryIndex); + + return HistoryIndex; +} + + +float3 DirectClipToAABB(float3 History, float3 Min, float3 Max) +{ + float3 Center = 0.5 * (Max + Min); + float3 Extents = 0.5 * (Max - Min); + + float3 Offset = History - Center; + float3 Vunit = Offset.xyz / Extents.xyz; + float3 AbsUnit = abs(Vunit); + float MaxUnit = max(max(AbsUnit.x, AbsUnit.y), AbsUnit.z); + + if (MaxUnit > 1.0) return Center + (Offset / MaxUnit); + else return History; +} + + +float DisocclusionDetection(CurrentFrameData CurrentData, PrevFrameData PrevData, bool MovingIntersection, out float RelaxedWeight, out float DisocclusionWeight) +{ + RelaxedWeight = 1; + DisocclusionWeight = 1; + + float PlaneMultiplier = CurrentData.MovingPixel ? 100.0f : 100000.0f; //TODO: make it 5000 for the editor window + float DepthMultiplier = CurrentData.MovingPixel ? 20.0f : 1.0f; + + // Depth-based rejection with an adaptive threshold + float DepthThreshold = lerp(1e-2f, 1e-1f, CurrentData.AligmentZ); + if (abs((PrevData.DepthLinear - CurrentData.DepthLinear) / CurrentData.DepthLinear) >= DepthThreshold * DepthMultiplier) + { + if (CurrentData.DepthLinear > PrevData.DepthLinear) + DisocclusionWeight = 0; + + RelaxedWeight = 0; + return 0.0f; + } + + // Plane-based rejection + float PlaneDistance = abs(dot(PrevData.WorldPos - CurrentData.WorldPos, CurrentData.Normal)); + float RelativeDepthDifference = PlaneDistance / CurrentData.DepthLinear; + if (exp2(-PlaneMultiplier * (RelativeDepthDifference * RelativeDepthDifference )) < 0.1f) + { + RelaxedWeight = 0; + return 0.0f; + } + + // Normal-based rejection + if (CurrentData.DepthLinear > PrevData.DepthLinear) + { + if (saturate(dot(CurrentData.Normal, PrevData.Normal)) < 0.75) + { + RelaxedWeight = 0; + return 0.0f; + } + } + else + { + if (saturate(dot(CurrentData.Normal, PrevData.Normal)) < 0.75) + return 0.0f; + } + + return 1.0f; +} + + +bool GetReprojectionCoord(int2 pixCoord, float2 MotionVectors, out float4 BilinearWeights, out int2 ReprojectionCoord) +{ + float2 ReprojectionCoordNDC = (pixCoord.xy + 0.5f) - MotionVectors * floor(_ScreenSize.xy / _ProbeSize); + ReprojectionCoord = ReprojectionCoordNDC - 0.5f; + + float UVx = frac(ReprojectionCoordNDC.x + 0.5f); + float UVy = frac(ReprojectionCoordNDC.y + 0.5f); + + BilinearWeights.x = (1.0f - UVx) * (1.0f - UVy); + BilinearWeights.y = (UVx) * (1.0f - UVy); + BilinearWeights.z = (1.0f - UVx) * (UVy); + BilinearWeights.w = (UVx) * (UVy); + + if (any(ReprojectionCoord * _ProbeSize >= _ScreenSize.xy) || any(ReprojectionCoordNDC < 0)) + { + BilinearWeights = float4(0,0,0,0); + return false; + } + + return true; +} + + +bool GetReprojectionWeights(H_TEXTURE_ARRAY(_HistoryBuffer), CurrentFrameData CurrentData, int2 ReprojectionCoord, uint ArrayIndex, inout float4 Weights, inout float4 RelaxedWeights) +{ + PrevFrameData PrevData00, PrevData01, PrevData10, PrevData11; + + UnpackWorldPosNormal(asuint(H_LOAD_ARRAY(_HistoryBuffer, ReprojectionCoord + int2(0, 0), ArrayIndex)), PrevData00.WorldPos, PrevData00.Normal); + UnpackWorldPosNormal(asuint(H_LOAD_ARRAY(_HistoryBuffer, ReprojectionCoord + int2(1, 0), ArrayIndex)), PrevData10.WorldPos, PrevData10.Normal); + UnpackWorldPosNormal(asuint(H_LOAD_ARRAY(_HistoryBuffer, ReprojectionCoord + int2(0, 1), ArrayIndex)), PrevData01.WorldPos, PrevData01.Normal); + UnpackWorldPosNormal(asuint(H_LOAD_ARRAY(_HistoryBuffer, ReprojectionCoord + int2(1, 1), ArrayIndex)), PrevData11.WorldPos, PrevData11.Normal); + + PrevData00.DepthLinear = H_LINEAR_EYE_DEPTH(H_GET_RELATIVE_POSITION_WS(PrevData00.WorldPos), H_MATRIX_V); + PrevData10.DepthLinear = H_LINEAR_EYE_DEPTH(H_GET_RELATIVE_POSITION_WS(PrevData10.WorldPos), H_MATRIX_V); + PrevData01.DepthLinear = H_LINEAR_EYE_DEPTH(H_GET_RELATIVE_POSITION_WS(PrevData01.WorldPos), H_MATRIX_V); + PrevData11.DepthLinear = H_LINEAR_EYE_DEPTH(H_GET_RELATIVE_POSITION_WS(PrevData11.WorldPos), H_MATRIX_V); + + float4 BilinearWeights = Weights; + + float4 DisocclusionWeights; + Weights.x *= DisocclusionDetection(CurrentData, PrevData00, false, RelaxedWeights.x, DisocclusionWeights.x); + Weights.y *= DisocclusionDetection(CurrentData, PrevData10, false, RelaxedWeights.y, DisocclusionWeights.y); + Weights.z *= DisocclusionDetection(CurrentData, PrevData01, false, RelaxedWeights.z, DisocclusionWeights.z); + Weights.w *= DisocclusionDetection(CurrentData, PrevData11, false, RelaxedWeights.w, DisocclusionWeights.w); + + return any(DisocclusionWeights <= 0) ? true : false; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Reservoir.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Reservoir.hlsl.meta new file mode 100644 index 000000000..a112316c2 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Reservoir.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 29131afe42204804c8e5e5ba938f3ad2 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/Reservoir.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenProbesCommon.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenProbesCommon.hlsl new file mode 100644 index 000000000..ca1647f0c --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenProbesCommon.hlsl @@ -0,0 +1,7 @@ +#ifndef SCREEN_PROBES_COMMON_INCLUDED +#define SCREEN_PROBES_COMMON_INCLUDED + +int _OctahedralSize; +int _ProbeSize; + +#endif diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenProbesCommon.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenProbesCommon.hlsl.meta new file mode 100644 index 000000000..7021251a8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenProbesCommon.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 345ceccf5cfd86145a9c3e7ba45ff532 +timeCreated: 1748007079 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenProbesCommon.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenTraversal.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenTraversal.hlsl new file mode 100644 index 000000000..347089885 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenTraversal.hlsl @@ -0,0 +1,184 @@ +#pragma once +#include "../Headers/HMain.hlsl" +#include "ScreenProbesCommon.hlsl" + +// ------------------------ RAY SETUP FUNCTIONS ------------------------ + +// Approximates object thickness in screen-space +float AdaptiveThicknessSearch(float3 PositionWS, float3 RayDirectionWS) +{ + float StepSize = 0.01; + float StepCount = 4; + float InsideSurfaceCount = StepCount; + + bool IsOffscreen = false; + for (float i = 0; i < StepCount + 1; i++) + { + // Move along the ray with fixed steps + PositionWS += RayDirectionWS * StepSize; + float3 PositionNDC = H_COMPUTE_NDC_Z(PositionWS, UNITY_MATRIX_VP).xyz; + + if (all(PositionNDC.xy > 0) && all(PositionNDC.xy < 1)) + { + // Sample depth along the ray + float Depth = H_LOAD(g_HTraceDepthPyramidWSGI, PositionNDC.xy * _ScreenSize.xy).x; + + // Decrement thickness counter each time the ray is above surface + if (PositionNDC.z > Depth) + InsideSurfaceCount--; + } + else + { + IsOffscreen = true; + break; + } + } + + // Occluder thickness is decreased by the number of times the ray appeared above surface + return IsOffscreen ? 0.03f : lerp(0.015f, 0.05f, saturate(InsideSurfaceCount / StepCount)); +} + +// Calculates ray origin (with bias) and ray direction in NDC coordinates +void GetRayOriginAndDirectionNDC(float Depth, float MaxDistance, float2 ProbeCoordNDC, float3 PositionWS, float3 RayDirectionWS, float3 GeometryNormalWS, inout float3 RayStartPositionNDC, inout float3 RayDirectionNDC) +{ + float3 ViewDirectionWS = H_GET_VIEW_DIRECTION_WS(PositionWS); + + // Bias ray origin in world space + float3 PositionBiasedWS; + { + // Calculate view direction bias // TODO: may create artifacrs at grazing angles. Seems unnecessary. + PositionBiasedWS = PositionWS; // CameraPositionWS + (PositionWS - CameraPositionWS) * (1 - 0.001f * rcp(max(dot(GeometryNormalWS, ViewDirectionWS), FLT_EPS))); + + // float3 NormalForBias = GeometryNormalWS; + float3 NormalForBias = dot(GeometryNormalWS, RayDirectionWS) < 0 ? -GeometryNormalWS : GeometryNormalWS; + + // Calculate normal bias + float2 CornerCoordNDC = ProbeCoordNDC + 0.5f * _ScreenSize.zw * float(_OctahedralSize); + float3 CornerPositionWS = H_COMPUTE_POSITION_WS(CornerCoordNDC.xy, Depth, H_MATRIX_I_VP); + float NormalBias = abs(dot(CornerPositionWS - PositionWS, NormalForBias)) * 2.0f; + + // This can push the ray origin off-screen causing black pixels on the border + PositionBiasedWS += NormalForBias * NormalBias; + } + + // Calculate ray start position in screen space + RayStartPositionNDC = H_COMPUTE_NDC_Z(PositionBiasedWS, UNITY_MATRIX_VP).xyz; + + // Calculate ray end clipped position in screen space + float3 RayEndPositionNDC; + { + // Calculate clipped ray distance in world space + float MaxRayDistanceWS = 100.0f; + float3 RayDirectionVS = H_TRANSFORM_WORLD_TO_VIEW_DIR(-RayDirectionWS, true); + float SceneDepth = H_LINEAR_EYE_DEPTH(PositionBiasedWS, UNITY_MATRIX_V); + float RayClippedDistanceWS = RayDirectionVS.z < 0.0 ? min(-0.99f * SceneDepth / RayDirectionVS.z, MaxRayDistanceWS) : MaxRayDistanceWS; + + // Calculate ray end position in screen space + RayEndPositionNDC.xyz = H_COMPUTE_NDC_Z(PositionBiasedWS + RayDirectionWS * RayClippedDistanceWS, UNITY_MATRIX_VP).xyz; + + // Recalculate ray end position where it leaves the screen + float2 ScreenEdgeIntersections = LineBoxIntersect(RayStartPositionNDC, RayEndPositionNDC, 0, 1); + RayEndPositionNDC = RayStartPositionNDC + (RayEndPositionNDC - RayStartPositionNDC) * ScreenEdgeIntersections.y; + } + + // Ray direction in screen space + RayDirectionNDC = RayEndPositionNDC - RayStartPositionNDC; +} + + +// ------------------------ RAY TRAVERSAL FUNCTIONS ------------------------ +bool AdvanceRay(float3 RayOrigin, float3 RayDirection, float3 RayDirectionInverse, float2 CurrentMipLevelPosition, float2 CurrentMipResolutionInverse, float2 OffsetFloor, float2 OffsetUV, float SurfaceZ, inout float3 RayPosition, inout float CurrentIntersectionTime) +{ + // Create boundary planes + float2 PlaneXY = floor(CurrentMipLevelPosition) + OffsetFloor; + PlaneXY = PlaneXY * CurrentMipResolutionInverse + OffsetUV; + float3 BoundaryPlanes = float3(PlaneXY, SurfaceZ); + + // Intersect ray with the half box that is pointing away from the ray RayOrigin. + float3 IntersectionTimes = BoundaryPlanes * RayDirectionInverse - RayOrigin * RayDirectionInverse; + + // Prevent using z plane when shooting out of the depth buffer. + IntersectionTimes.z = RayDirection.z < 0 ? IntersectionTimes.z : FLT_MAX; + + // Choose nearest intersection with a boundary. + float ClosestIntersectionTime = min(min(IntersectionTimes.x, IntersectionTimes.y), IntersectionTimes.z); + + // Larger z means closer to the camera. + bool AboveSurface = SurfaceZ < RayPosition.z; + + // Decide whether we are able to advance the ray until we hit the xy boundaries or if we had to clamp it at the surface. + bool SkippedTile = asuint(ClosestIntersectionTime) != asuint(IntersectionTimes.z) && AboveSurface; + + // Make sure to only advance the ray if we're still above the surface. + CurrentIntersectionTime = AboveSurface ? ClosestIntersectionTime : CurrentIntersectionTime; + + // Advance ray + RayPosition = RayOrigin + CurrentIntersectionTime * RayDirection; + + return SkippedTile; +} + +bool HierarchicalRaymarch(float3 RayOrigin, float3 RayDirection, uint StepCount, inout float3 HitPositionNDC, inout float3 LastAboveSurfacePositionNDC) +{ + float3 RayDirectionInverse = RayDirection != float3(0.0f, 0.0f, 0.0f) ? float3(1.0f, 1.0f, 1.0f) / RayDirection : float3(FLT_MAX, FLT_MAX, FLT_MAX); + + int BaseMipLevel = 0; + int CurrentMipLevel = BaseMipLevel; + + float2 CurrentMipResolution = _ScreenSize.xy / pow(2.0, CurrentMipLevel); + float2 CurrentMipResolutionInverse = 1.0f / CurrentMipResolution; + + // Offset to the bounding boxes uv space to intersect the ray with the center of the next pixel. This means we ever so slightly over shoot into the next region. + float2 OffsetUV = 0.005f * exp2(BaseMipLevel) / _ScreenSize.xy; + OffsetUV.x = RayDirection.x < 0.0f ? -OffsetUV.x : OffsetUV.x; + OffsetUV.y = RayDirection.y < 0.0f ? -OffsetUV.y : OffsetUV.y; + + // Offset applied depending on current mip resolution to move the boundary to the left/right upper/lower border depending on ray RayDirection. + float2 OffsetFloor; + OffsetFloor.x = RayDirection.x < 0.0f ? 0 : 1.0f; + OffsetFloor.y = RayDirection.y < 0.0f ? 0 : 1.0f; + + float CurrentIntersectionTime; + float3 RayPosition; + + // Step out of the current tile to avoid self intersection + { + float2 CurrentMipLevelPosition = CurrentMipResolution * RayOrigin.xy; + + // Intersect ray with the half box that is pointing away from the ray RayOrigin. + float2 PlaneXY = floor(CurrentMipLevelPosition) + OffsetFloor; + PlaneXY = PlaneXY * CurrentMipResolutionInverse + OffsetUV; + + // o + d * t = p' => t = (p' - o) / d + float2 IntersectionTimes = PlaneXY * RayDirectionInverse.xy - RayOrigin.xy * RayDirectionInverse.xy; + CurrentIntersectionTime = min(IntersectionTimes.x, IntersectionTimes.y); + RayPosition = RayOrigin + CurrentIntersectionTime * RayDirection; + } + + float LastAboveSurfaceTime = CurrentIntersectionTime; + + uint i = 0; + while (i < StepCount && CurrentMipLevel >= BaseMipLevel && CurrentIntersectionTime < 1.0f) + { + float2 CurrentMipLevelPosition = CurrentMipResolution * RayPosition.xy; + float SurfaceZ = H_LOAD_LOD(g_HTraceDepthPyramidWSGI, CurrentMipLevelPosition, CurrentMipLevel).x; + + bool SkippedTile = AdvanceRay(RayOrigin, RayDirection, RayDirectionInverse, CurrentMipLevelPosition, CurrentMipResolutionInverse, OffsetFloor, OffsetUV, SurfaceZ, RayPosition, CurrentIntersectionTime); + + if (!SkippedTile || CurrentMipLevel < 3) + { + CurrentMipLevel += SkippedTile ? 1 : -1; + CurrentMipResolution *= SkippedTile ? 0.5 : 2.0f; + CurrentMipResolutionInverse *= SkippedTile ? 2.0f : 0.5; + } + + LastAboveSurfaceTime = SkippedTile ? CurrentIntersectionTime : LastAboveSurfaceTime; + + i++; + } + + HitPositionNDC = RayOrigin + CurrentIntersectionTime * RayDirection; + LastAboveSurfacePositionNDC = CurrentMipLevel > -1 ? RayOrigin + LastAboveSurfaceTime * RayDirection : HitPositionNDC; + + return i <= StepCount ? true : false; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenTraversal.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenTraversal.hlsl.meta new file mode 100644 index 000000000..fc04d30d0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenTraversal.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 154672c408a555e4da654ae27e279a88 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/ScreenTraversal.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialFilteringFunctions.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialFilteringFunctions.hlsl new file mode 100644 index 000000000..1fb5f72ce --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialFilteringFunctions.hlsl @@ -0,0 +1,103 @@ +#pragma once +float ProbePlaneWeighting(float4 Plane, float3 WorldPosSample, float DepthLinearCenter, float Multiplier) +{ + float PlaneDistance = abs(dot(float4(WorldPosSample, -1), Plane)); + float DepthDifference = PlaneDistance / DepthLinearCenter; + float PlaneWeight = exp2(-100.0f * Multiplier * (DepthDifference * DepthDifference)); + return PlaneWeight; +} + +float ProbePlaneWeighting2(float3 Normal, float3 WorldPosCenter, float3 WorldPosSample, float DepthLinearCenter, float Multiplier) +{ + float PlaneDistance = abs(dot((WorldPosCenter - WorldPosSample), Normal.xyz)); + float DepthDifference = PlaneDistance / DepthLinearCenter; + float PlaneWeight = exp2(-100.0f * Multiplier * (DepthDifference * DepthDifference)); + return PlaneWeight; +} + +float ProbePlaneWeighting3(float3 Normal, float3 WorldPos, float3 WorldPosPrev, float DepthLinearCenter) +{ + // Plane-based rejection + float4 ScenePlane = float4(Normal, dot(WorldPos, Normal)); + float PlaneDistance = abs(dot(WorldPosPrev - WorldPos, Normal)); + float RelativeDepthDifference = PlaneDistance / DepthLinearCenter; + return exp2(-100000 * (RelativeDepthDifference * RelativeDepthDifference)); +} + +float ProbeDepthWeighting(float DepthRawCenter, float DepthRawSample, float Multiplier) +{ + if (DepthRawCenter <= 0) + return 1.0f; + // + // DepthRawCenter = H_LINEAR_01_DEPTH(DepthRawCenter); + // DepthRawSample = H_LINEAR_01_DEPTH(DepthRawSample); + + //return exp(-abs(DepthRawCenter - DepthRawSample) * DepthRawCenter * 4.0f); + + //return max(0.0, 1.0 - abs(DepthRawSample - DepthRawCenter) * 1); + + float DepthDifference = abs(DepthRawCenter - DepthRawSample); + float RelativeDepthDifference = DepthDifference / DepthRawCenter; + float DepthWeight = DepthRawSample >= 0 ? exp2(-10.0f * Multiplier * (RelativeDepthDifference * RelativeDepthDifference)) : 0; + return DepthWeight; +} + + + +float ProbeAngleWeighting(float DistanceCenter, float DistanceSample, float3 WorldPosCenter, float3 WorldPosSample, float3 Direction, float MaxAngle) +{ + // if (DistanceCenter > 0) + // DistanceSample = min(DistanceSample, DistanceCenter); + // + // float3 HitPosSample = WorldPosSample + Direction * DistanceSample; + // float3 ToSampleHit = HitPosSample - WorldPosCenter; + // float Angle = FastACos(dot(ToSampleHit, Direction) / length(ToSampleHit)); + // float AngleWeight = 1 - saturate(Angle / MaxAngle); + // + // return AngleWeight; +} + + +float PixelDepthWeighting(float DeptLinearCenter, float DepthLinearSample, float Multiplier) +{ + float DepthDifference = abs(DepthLinearSample - DeptLinearCenter); + float RelativeDepthDifference = DepthDifference / DeptLinearCenter; + float DepthWeightNear = exp2(-100.0f * Multiplier * (RelativeDepthDifference * RelativeDepthDifference)); + return DepthWeightNear; +} + +// ------------------------ SPATIAL FILTERING FUNCTIONS ------------------------ + +float PlaneWeighting(float3 WorldPosCenter, float3 WorldPosSample, float3 NormalCenter, float3 NormalSample, float FilterStrength) +{ + float3 SampleDistance = WorldPosCenter - WorldPosSample; + float SampleDistanceDouble = dot(SampleDistance, SampleDistance); + float PlaneError = max(abs(dot(SampleDistance, NormalSample)), abs(dot(SampleDistance, NormalCenter))); + float PlaneWeight = pow(max(0.0, 1.0 - 2.0 * PlaneError / sqrt(SampleDistanceDouble)), FilterStrength); + return PlaneWeight; +} + +float DepthWeighting(float DepthCenter, float DepthSample, float FilterStrength) +{ + float DepthDifference = abs(DepthSample - DepthCenter); + float RelativeDepthDifference = DepthDifference / DepthCenter; + float DepthWeight = exp2(-100 * FilterStrength * (RelativeDepthDifference * RelativeDepthDifference)); + return DepthWeight; +} + +float NormalWeighting(float3 NormalCenter, float3 NormalSample, float FilterStrength) +{ + float NormalWeight = saturate(dot(normalize(NormalCenter), normalize(NormalSample))); + NormalWeight = pow(NormalWeight, FilterStrength); + return NormalWeight; +} + +float sqr(float value) +{ + return value * value; +} + +float GaussianWeighting(float Radius, float Sigma) +{ + return exp(-sqr(Radius / Sigma)); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialFilteringFunctions.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialFilteringFunctions.hlsl.meta new file mode 100644 index 000000000..2b758aa40 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialFilteringFunctions.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: c95dcf64f181d804ebe53722c0bf0317 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialFilteringFunctions.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialHash.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialHash.hlsl new file mode 100644 index 000000000..2d7e49875 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialHash.hlsl @@ -0,0 +1,82 @@ +#pragma once + +RWStructuredBuffer _HashBuffer_Key; +RWStructuredBuffer _HashBuffer_Counter; +RWStructuredBuffer _HashBuffer_Payload; +RWStructuredBuffer _HashBuffer_Radiance; +RWStructuredBuffer _HashBuffer_Position; + +#define MAX_LOOKUP_ITERATIONS 16 + +uint _HashStorageSize; +uint _HashUpdateFraction; + +uint HashPCG(uint Value) +{ + uint State = Value * 747796405u + 2891336453u; + uint Word = ((State >> ((State >> 28u) + 4u)) ^ State) * 277803737u; + return (Word >> 22u) ^ Word; +} + +uint HashGetIndex(uint3 Coord, uint AnisotropyIndex) +{ + return HashPCG(Coord.x + HashPCG(Coord.y + HashPCG(Coord.z + HashPCG(AnisotropyIndex) ))) % _HashStorageSize; +} + + +bool HashFindAny(uint Index, uint Key, inout uint Rank, out uint LowestRankedIndex, out uint ProbingIndex, out bool IsEmpty) +{ + IsEmpty = false; + + for (int i = 0; i < MAX_LOOKUP_ITERATIONS; i++) + { + uint CurrentKey = _HashBuffer_Key[Index]; + uint CurrentRank = CurrentKey & 0x3; + + CurrentKey = CurrentKey & 0xFFFFFFFC; //0xFFFFFFE0; + Key = Key & 0xFFFFFFFC; + + if (CurrentKey == Key) + { + ProbingIndex = Index; + Rank = CurrentRank; + IsEmpty = false; + return true; + } + else if (CurrentKey == 0) + { + ProbingIndex = Index; + IsEmpty = true; + } + else if (CurrentRank < Rank) + { + LowestRankedIndex = Index; + Rank = CurrentRank; + } + + Index++; + } + + return false; +} + +bool HashFindValid(uint Index, uint Key, out uint IndexFound) +{ + for (int i = 0; i < MAX_LOOKUP_ITERATIONS; i++) + { + uint CurrentKey = _HashBuffer_Key[Index]; + + CurrentKey = CurrentKey & 0xFFFFFFFC; + Key = Key & 0xFFFFFFFC; + + if (CurrentKey == Key && CurrentKey!= 0) + { + IndexFound = Index; + return true; + } + + Index++; + } + + return false; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialHash.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialHash.hlsl.meta new file mode 100644 index 000000000..f2479be43 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialHash.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 9dcad3e11bb22fd479d0f84141371991 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SpatialHash.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SphericalHarmonics.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SphericalHarmonics.hlsl new file mode 100644 index 000000000..43b49b035 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SphericalHarmonics.hlsl @@ -0,0 +1,208 @@ +#pragma once + + +struct SH_L2_Vector +{ + float4 V0; + float4 V1; + float V2; +}; + +struct SH_L2_Color +{ + SH_L2_Vector R; + SH_L2_Vector G; + SH_L2_Vector B; +}; + +SH_L2_Vector BasisSH(float3 Direction) +{ + SH_L2_Vector Result; + + Result.V0.x = 0.282095f; + Result.V0.y = -0.488603f * Direction.y; + Result.V0.z = 0.488603f * Direction.z; + Result.V0.w = -0.488603f * Direction.x; + + float3 DirectionSquared = Direction * Direction; + Result.V1.x = 1.092548f * Direction.x * Direction.y; + Result.V1.y = -1.092548f * Direction.y * Direction.z; + Result.V1.z = 0.315392f * (3.0f * DirectionSquared.z - 1.0f); + Result.V1.w = -1.092548f * Direction.x * Direction.z; + Result.V2 = 0.546274f * (DirectionSquared.x - DirectionSquared.y); + + return Result; +} + +void InitializeSH(inout SH_L2_Color CoefficientsSH) +{ + CoefficientsSH.R.V0 = 0; + CoefficientsSH.R.V1 = 0; + CoefficientsSH.R.V2 = 0; + CoefficientsSH.G.V0 = 0; + CoefficientsSH.G.V1 = 0; + CoefficientsSH.G.V2 = 0; + CoefficientsSH.B.V0 = 0; + CoefficientsSH.B.V1 = 0; + CoefficientsSH.B.V2 = 0; +} + +void PackInterpolationSH(inout uint4 PackedA, inout uint4 PackedB, SH_L2_Color LightingSH) +{ + float4 AmbientSH = float4(LightingSH.R.V0.x , LightingSH.G.V0.x, LightingSH.B.V0.x, 1); + + float4 DirectionalSH0_0 = float4(LightingSH.R.V0.yzw, LightingSH.R.V1.x); + float4 DirectionalSH0_1 = float4(LightingSH.G.V0.yzw, LightingSH.G.V1.x); + float4 DirectionalSH0_2 = float4(LightingSH.B.V0.yzw, LightingSH.B.V1.x); + + float4 DirectionalSH1_0 = float4(LightingSH.R.V1.yzw, LightingSH.R.V2); + float4 DirectionalSH1_1 = float4(LightingSH.G.V1.yzw, LightingSH.G.V2); + float4 DirectionalSH1_2 = float4(LightingSH.B.V1.yzw, LightingSH.B.V2); + + float4 NormalizationScale0 = float4(1,1,1,1); + float4 NormalizationScale1 = float4(1,1,1,1); + + NormalizationScale0 = float4(0.282095f / 0.488603f, 0.282095f / 0.488603f, 0.282095f / 0.488603f, 0.282095f / 1.092548f); + NormalizationScale1 = float4(0.282095f / 1.092548f, 0.282095f / (4.0f * 0.315392f), 0.282095f / 1.092548f, 0.282095f / (2.0f * 0.546274f)); + + DirectionalSH0_0 = DirectionalSH0_0 * NormalizationScale0 / max(AmbientSH[0], .00001f) * 0.5f + 0.5f; + DirectionalSH0_1 = DirectionalSH0_1 * NormalizationScale0 / max(AmbientSH[1], .00001f) * 0.5f + 0.5f; + DirectionalSH0_2 = DirectionalSH0_2 * NormalizationScale0 / max(AmbientSH[2], .00001f) * 0.5f + 0.5f; + + DirectionalSH1_0 = DirectionalSH1_0 * NormalizationScale1 / max(AmbientSH[0], .00001f) * 0.5f + 0.5f; + DirectionalSH1_1 = DirectionalSH1_1 * NormalizationScale1 / max(AmbientSH[1], .00001f) * 0.5f + 0.5f; + DirectionalSH1_2 = DirectionalSH1_2 * NormalizationScale1 / max(AmbientSH[2], .00001f) * 0.5f + 0.5f; + + PackedA.x = ((uint(DirectionalSH0_0.x * 255.0f + 0.5f) & 0xFF) << 24) | + ((uint(DirectionalSH0_0.y * 255.0f + 0.5f) & 0xFF) << 16) | + ((uint(DirectionalSH0_0.z * 255.0f + 0.5f) & 0xFF) << 8) | + ((uint(DirectionalSH0_0.w * 255.0f + 0.5f) & 0xFF) << 0); + + PackedA.y = ((uint(DirectionalSH0_1.x * 255.0f + 0.5f) & 0xFF) << 24) | + ((uint(DirectionalSH0_1.y * 255.0f + 0.5f) & 0xFF) << 16) | + ((uint(DirectionalSH0_1.z * 255.0f + 0.5f) & 0xFF) << 8) | + ((uint(DirectionalSH0_1.w * 255.0f + 0.5f) & 0xFF) << 0); + + PackedA.z = ((uint(DirectionalSH0_2.x * 255.0f + 0.5f) & 0xFF) << 24) | + ((uint(DirectionalSH0_2.y * 255.0f + 0.5f) & 0xFF) << 16) | + ((uint(DirectionalSH0_2.z * 255.0f + 0.5f) & 0xFF) << 8) | + ((uint(DirectionalSH0_2.w * 255.0f + 0.5f) & 0xFF) << 0); + + PackedA.w = ((uint(DirectionalSH1_0.x * 255.0f + 0.5f) & 0xFF) << 24) | + ((uint(DirectionalSH1_0.y * 255.0f + 0.5f) & 0xFF) << 16) | + ((uint(DirectionalSH1_0.z * 255.0f + 0.5f) & 0xFF) << 8) | + ((uint(DirectionalSH1_0.w * 255.0f + 0.5f) & 0xFF) << 0); + + PackedB.x = ((uint(DirectionalSH1_1.x * 255.0f + 0.5f) & 0xFF) << 24) | + ((uint(DirectionalSH1_1.y * 255.0f + 0.5f) & 0xFF) << 16) | + ((uint(DirectionalSH1_1.z * 255.0f + 0.5f) & 0xFF) << 8) | + ((uint(DirectionalSH1_1.w * 255.0f + 0.5f) & 0xFF) << 0); + + PackedB.y = ((uint(DirectionalSH1_2.x * 255.0f + 0.5f) & 0xFF) << 24) | + ((uint(DirectionalSH1_2.y * 255.0f + 0.5f) & 0xFF) << 16) | + ((uint(DirectionalSH1_2.z * 255.0f + 0.5f) & 0xFF) << 8) | + ((uint(DirectionalSH1_2.w * 255.0f + 0.5f) & 0xFF) << 0); + + PackedB.z = PackToR11G11B10f(AmbientSH.xyz); + + PackedB.w = 0; +} + +void UnpackInterpolationSH(uint4 PackedA, uint4 PackedB, inout SH_L2_Color CoefficientsSH) +{ + float4 DirectionalSH0[3], DirectionalSH1[3], AmbientSH; + + DirectionalSH0[0].x = ((PackedA.x >> 24) & 0xFF) / 255.0f; + DirectionalSH0[0].y = ((PackedA.x >> 16) & 0xFF) / 255.0f; + DirectionalSH0[0].z = ((PackedA.x >> 8) & 0xFF) / 255.0f; + DirectionalSH0[0].w = ((PackedA.x >> 0) & 0xFF) / 255.0f; + + DirectionalSH0[1].x = ((PackedA.y >> 24) & 0xFF) / 255.0f; + DirectionalSH0[1].y = ((PackedA.y >> 16) & 0xFF) / 255.0f; + DirectionalSH0[1].z = ((PackedA.y >> 8) & 0xFF) / 255.0f; + DirectionalSH0[1].w = ((PackedA.y >> 0) & 0xFF) / 255.0f; + + DirectionalSH0[2].x = ((PackedA.z >> 24) & 0xFF) / 255.0f; + DirectionalSH0[2].y = ((PackedA.z >> 16) & 0xFF) / 255.0f; + DirectionalSH0[2].z = ((PackedA.z >> 8) & 0xFF) / 255.0f; + DirectionalSH0[2].w = ((PackedA.z >> 0) & 0xFF) / 255.0f; + + DirectionalSH1[0].x = ((PackedA.w >> 24) & 0xFF) / 255.0f; + DirectionalSH1[0].y = ((PackedA.w >> 16) & 0xFF) / 255.0f; + DirectionalSH1[0].z = ((PackedA.w >> 8) & 0xFF) / 255.0f; + DirectionalSH1[0].w = ((PackedA.w >> 0) & 0xFF) / 255.0f; + + DirectionalSH1[1].x = ((PackedB.x >> 24) & 0xFF) / 255.0f; + DirectionalSH1[1].y = ((PackedB.x >> 16) & 0xFF) / 255.0f; + DirectionalSH1[1].z = ((PackedB.x >> 8) & 0xFF) / 255.0f; + DirectionalSH1[1].w = ((PackedB.x >> 0) & 0xFF) / 255.0f; + + DirectionalSH1[2].x = ((PackedB.y >> 24) & 0xFF) / 255.0f; + DirectionalSH1[2].y = ((PackedB.y >> 16) & 0xFF) / 255.0f; + DirectionalSH1[2].z = ((PackedB.y >> 8) & 0xFF) / 255.0f; + DirectionalSH1[2].w = ((PackedB.y >> 0) & 0xFF) / 255.0f; + + AmbientSH = float4(UnpackFromR11G11B10f(PackedB.z), 1); + + float4 DenormalizationScales0 = float4(1,1,1,1); + float4 DenormalizationScales1 = float4(1,1,1,1); + + DenormalizationScales0 = float4(0.488603f / 0.282095f, 0.488603f / 0.282095f, 0.488603f / 0.282095f, 1.092548f / 0.282095f); + DenormalizationScales1 = float4(1.092548f / 0.282095f, 4.0f * 0.315392f / 0.282095f, 1.092548f / 0.282095f, 2.0f * 0.546274f / 0.282095f); + + DirectionalSH0[0] = (DirectionalSH0[0] * 2 - 1) * AmbientSH.x * DenormalizationScales0; + DirectionalSH0[1] = (DirectionalSH0[1] * 2 - 1) * AmbientSH.y * DenormalizationScales0; + DirectionalSH0[2] = (DirectionalSH0[2] * 2 - 1) * AmbientSH.z * DenormalizationScales0; + + DirectionalSH1[0] = (DirectionalSH1[0] * 2 - 1) * AmbientSH.x * DenormalizationScales1; + DirectionalSH1[1] = (DirectionalSH1[1] * 2 - 1) * AmbientSH.y * DenormalizationScales1; + DirectionalSH1[2] = (DirectionalSH1[2] * 2 - 1) * AmbientSH.z * DenormalizationScales1; + + CoefficientsSH.R.V0 = float4(AmbientSH.x, DirectionalSH0[0].xyz); + CoefficientsSH.G.V0 = float4(AmbientSH.y, DirectionalSH0[1].xyz); + CoefficientsSH.B.V0 = float4(AmbientSH.z, DirectionalSH0[2].xyz); + + CoefficientsSH.R.V1 = float4(DirectionalSH0[0].w, DirectionalSH1[0].xyz); + CoefficientsSH.G.V1 = float4(DirectionalSH0[1].w, DirectionalSH1[1].xyz); + CoefficientsSH.B.V1 = float4(DirectionalSH0[2].w, DirectionalSH1[2].xyz); + + CoefficientsSH.R.V2 = DirectionalSH1[0].w; + CoefficientsSH.G.V2 = DirectionalSH1[1].w; + CoefficientsSH.B.V2 = DirectionalSH1[2].w; +} + +void AddSampleSH(inout SH_L2_Color Result, float3 Direction, float3 Color) +{ + SH_L2_Vector Basis = BasisSH(Direction); + + Result.R.V0 += Basis.V0 * Color.r; + Result.R.V1 += Basis.V1 * Color.r; + Result.R.V2 += Basis.V2 * Color.r; + Result.G.V0 += Basis.V0 * Color.g; + Result.G.V1 += Basis.V1 * Color.g; + Result.G.V2 += Basis.V2 * Color.g; + Result.B.V0 += Basis.V0 * Color.b; + Result.B.V1 += Basis.V1 * Color.b; + Result.B.V2 += Basis.V2 * Color.b; +} + +float3 EvaluateSHIrradiance(float3 Direction, float CosThetaAO, SH_L2_Color SH) +{ + float t2 = CosThetaAO * CosThetaAO; + float t3 = t2 * CosThetaAO; + float t4 = t2 * t2; + + float c0 = 0.5f * sqrt(H_PI); + float c1 = sqrt(H_PI / 3.0f); + float c2 = sqrt(5.0f * H_PI) / 16.0f * (3.0f - 2.0f); + + c0 = c0 * (1 - t2); + c1 = c1 * (1 - t3); + c2 = c2 / 16.0f * (3.0f * (1.0f - t4) - 2.0f * (1.0f - t2)); + + return max(0.0f, c0 * float3(SH.R.V0.x, SH.G.V0.x, SH.B.V0.x) + + c1 * (-float3(SH.R.V0.y, SH.G.V0.y, SH.B.V0.y) * Direction.y + float3(SH.R.V0.z, SH.G.V0.z, SH.B.V0.z) * Direction.z - float3(SH.R.V0.w, SH.G.V0.w, SH.B.V0.w) * Direction.x) + + c2 * (float3(SH.R.V1.z, SH.G.V1.z, SH.B.V1.z) * (3.0f * Direction.z * Direction.z - 1.0f) + + sqrt(3.0f) * (float3(SH.R.V2, SH.G.V2, SH.B.V2) * (Direction.x * Direction.x - Direction.y * Direction.y) + + 2.0f * (float3(SH.R.V1.x, SH.G.V1.x, SH.B.V1.x) * Direction.x * Direction.y - float3(SH.R.V1.y, SH.G.V1.y, SH.B.V1.y) * Direction.y * Direction.z - float3(SH.R.V1.w, SH.G.V1.w, SH.B.V1.w) * Direction.z * Direction.x)))); +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SphericalHarmonics.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SphericalHarmonics.hlsl.meta new file mode 100644 index 000000000..26402ed71 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SphericalHarmonics.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: fa91ff8077b504042908bd3e190a5f33 +timeCreated: 1729096925 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/SphericalHarmonics.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelLightingEvaluation.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelLightingEvaluation.hlsl new file mode 100644 index 000000000..92f1dcff4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelLightingEvaluation.hlsl @@ -0,0 +1,164 @@ +#include "config.hlsl" +#include "VoxelizationCommon.hlsl" +#include "../Includes/LightCluster.hlsl" + +#define HAS_LIGHTLOOP + + + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/AmbientProbe.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl" + +// Since we use slope-scale bias, the constant bias is for now set as a small fixed value +#define FIXED_UNIFORM_BIAS (1.0f / 65536.0f) + +#pragma warning (disable : 3206) + +StructuredBuffer _PrevBuffer; +StructuredBuffer _LightClusterCounterBuffer; +StructuredBuffer _LightClusterIndexesBuffer; + +H_TEXTURE_DX(float, g_HTraceShadowmap); +float4x4 g_DirLightMatrix; +float4 _PreviousCameraPosition; + +float3 EvaluateSky(float3 Direction) +{ + + + unity_SHAr = H_SHAr; + unity_SHAg = H_SHAg; + unity_SHAb = H_SHAb; + unity_SHBr = H_SHBr; + unity_SHBg = H_SHBg; + unity_SHBb = H_SHBb; + unity_SHC = H_SHC; + + return EvaluateAmbientProbe(Direction) * SKY_LIGHT_INTENSITY; +} + + +float EvaluateShadowmap(float3 PositionTC) +{ + return H_SAMPLE_SHADOW(g_HTraceShadowmap, H_SAMPLER_LINEAR_CLAMP_COMPARE, PositionTC).x; + +} + +float EvaluateDirectionalShadowOcclusion(float3 WorldPos) +{ + if (!EVALUATE_SKY_OCCLUSION) + return 1; + + // Calculate shadowmap coordinates + float4 PosCS = mul(g_DirLightMatrix, float4(WorldPos, 1.0)); + float3 PosTC = float3(saturate(PosCS.xy * 0.5f + 0.5f), PosCS.z); + + if (any(PosTC < 0.0f) || any(PosTC > 1.0f)) + return 1.0f; + + float SkyOcclusion = 0; + SkyOcclusion = EvaluateShadowmap(PosTC.xyz); + return lerp(SkyOcclusion, 1.0f, MINIMAL_SKY_LIGHTING); +} + +float EvaluateDirectionalShadowHDRP(float3 LightDirection, float3 WorldPos, float3 Normal) +{ + // Initialize shadow to 1 + float DirectionalShadow = 1.0f; + + // Normal *= FastSign(dot(Normal, DirLightDirection)); //TODO: do we need this? + + // Detect if we can early out on zero dot product + float NdotL = saturate(dot(Normal, LightDirection)); + if (NdotL == 0) + return 0; + + + // Calculate normal bias + float WorldTexelSize = 0.025f; // ~for 2048 shadowmap; + float NormalBias = 1.5f; //_VoxelSize * 10.0f * 3.5f; // 1.5f; + WorldPos += Normal * NormalBias * WorldTexelSize * lerp(0.35, 1, NdotL); + + // Calculate shadowmap coordinates + float4 PosCS = mul(g_DirLightMatrix, float4(WorldPos, 1.0)); + float3 PosTC = float3(saturate(PosCS.xy * 0.5f + 0.5f), PosCS.z); + PosTC.z += FIXED_UNIFORM_BIAS; + + DirectionalShadow *= NdotL; + DirectionalShadow *= EvaluateShadowmap(PosTC.xyz); + + return DirectionalShadow; +} + + + +float3 EvaluateClusterLighting(float3 PositionWS, float3 NormalWS) +{ + uint3 GridPosition = uint3((PositionWS - g_MinLightClusterPosition) / (g_MaxLightClusterPosition - g_MinLightClusterPosition) * g_LightClusterDimensions); + uint CellLightStartIndex = GetFlattenedIndex(GridPosition * g_MaxLightsPerCell); + uint CellLightCount = _LightClusterCounterBuffer[GetFlattenedIndex(GridPosition)]; + + float3 PunctualLighting = 0; + + for (uint i = 0; i < CellLightCount; i++) + { + uint LightIndex = _LightClusterIndexesBuffer[CellLightStartIndex + i]; + + float3 LightPositionWS = _AdditionalLightsPosition[LightIndex].xyz; + float3 LightColor = _AdditionalLightsColor[LightIndex].rgb; + float4 LightAtten = _AdditionalLightsAttenuation[LightIndex]; + float3 SpotDir = _AdditionalLightsSpotDir[LightIndex].xyz; + + float3 LightVector = LightPositionWS - PositionWS; + float DistanceSqr = max(dot(LightVector, LightVector), HALF_MIN); + float3 LightDirection = LightVector * rsqrt(DistanceSqr); + + float NdotL = saturate(dot(NormalWS, LightDirection)); + if (NdotL <= 0) + continue; + + // Use URP's own attenuation functions so falloff matches rasterized lighting exactly + float DistAttenuation = DistanceAttenuation(DistanceSqr, LightAtten.xy); + float SpotAttenuation = AngleAttenuation(SpotDir, LightDirection, LightAtten.zw); + half ShadowAttenuation = AdditionalLightRealtimeShadow((int)LightIndex, PositionWS, LightDirection); + + PunctualLighting += LightColor * NdotL * DistAttenuation * SpotAttenuation * ShadowAttenuation; + } + + return PunctualLighting; +} + + +bool EvaluateHitLighting(inout VoxelPayload Payload) +{ + bool IsEmissive = false; + Payload.HitDiffuse = UnpackVoxelColor(asuint(H_LOAD3D(_VoxelData, Payload.HitCoord)), IsEmissive); + + Payload.HitColor = 0; + float DirectionalLightShadow = 1; + + + + Light light = GetMainLight(); + Payload.HitColor += light.color * DIRECTIONAL_LIGHT_INTENSITY; + DirectionalLightShadow = EvaluateDirectionalShadowHDRP(light.direction, Payload.HitPosition, Payload.HitNormal); + Payload.HitColor *= DirectionalLightShadow; + + #ifdef EVALUATE_PUNCTUAL_LIGHTS + Payload.HitColor += EvaluateClusterLighting(Payload.HitPosition, Payload.HitNormal); + #endif + + Payload.HitColor *= Payload.HitDiffuse; + //Payload.HitColor /= H_PI; + + if (IsEmissive) + { + Payload.HitColor = Payload.HitDiffuse; + Payload.HitColor *= HGetInverseCurrentExposureMultiplier; + } + + //Payload.HitColor = 0; + return DirectionalLightShadow == 0 ? false : true; +} + + diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelLightingEvaluation.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelLightingEvaluation.hlsl.meta new file mode 100644 index 000000000..1f800a7dc --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelLightingEvaluation.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 683fca2464e605948915e5e7ff67f876 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelLightingEvaluation.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationBIRP.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationBIRP.hlsl new file mode 100644 index 000000000..3c97ef521 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationBIRP.hlsl @@ -0,0 +1,111 @@ +#define VOXEL_MATERIAL_EVALUATION_INCLUDE + +#pragma once +#include "../Headers/HMain.hlsl" + +// ------------------------ STRUCTS ------------------------ +struct VoxelSurfaceData +{ + // Inputs + float2 TexCoord0; + float2 TexCoord1; + float3 Normal; + + // Outputs + float3 Color; + float Alpha; + float IsEmissive; +}; + +// ------------------------ FUNCTIONS ------------------------ +float3 ClampDiffuseColor(float3 DiffuseColor) +{ + DiffuseColor *= SURFACE_DIFFUSE_INTENSITY; + + // DiffuseColor = FastLinearToSRGB(DiffuseColor); + // DiffuseColor = RgbToHsv(DiffuseColor); + // DiffuseColor.z = min(DiffuseColor.z, 0.9f); + // DiffuseColor = HsvToRgb(DiffuseColor); + // DiffuseColor = FastSRGBToLinear(DiffuseColor); + + return DiffuseColor; +} + + +// ------------------------ MATERIAL PROPERTIES ------------------------ + +// Standard Shader properties +float _Cutoff; +float4 _Color; +float4 _MainTex_ST; +float4 _EmissionMap_ST; +float4 _EmissionColor; +H_TEXTURE(_MainTex); +H_TEXTURE(_EmissionMap); +H_SAMPLER(sampler_MainTex); +H_SAMPLER(sampler_EmissionMap); + +// Props Shader properties +H_TEXTURE(_ColorCtrl); +float4 _Color1; +float4 _Color2; +float4 _ColorBG; + +// Simple Color properties +float3 _VoxelizationColor; + + + +// ------------------------ MATERIAL EVALUATION ------------------------ +bool EvaluateSurfaceColor(inout VoxelSurfaceData SurfaceData) +{ + SurfaceData.Color = 0; + SurfaceData.Alpha = 0; + SurfaceData.IsEmissive = 0; + + if (EVALUATE_SIMPLE_COLOR) + { + SurfaceData.Color = _VoxelizationColor * _Color; + SurfaceData.Alpha = 0; + } + + if (EVALUATE_PROPS) + { + if (length(SurfaceData.Color) > 0) + return true; + + float2 TextureCoord = SurfaceData.TexCoord0 * _MainTex_ST.xy + _MainTex_ST.zw; + float4 ColorCtrl = H_SAMPLE_2D (_ColorCtrl, sampler_MainTex, TextureCoord); + float4 FinalTexture = H_SAMPLE_2D(_MainTex, sampler_MainTex, TextureCoord) ; + float3 c1_to_cBG = lerp(_ColorBG, _Color1, ColorCtrl.r); + float3 FinalColor = lerp(c1_to_cBG, _Color2, ColorCtrl.g); + + SurfaceData.Alpha = FinalTexture.w < _Cutoff ? 1 : 0; + SurfaceData.Color = FinalTexture.rgb * FinalColor.rgb; + } + + if (EVALUATE_STANDARD) + { + if (length(SurfaceData.Color) > 0) + return true; + + float2 TextureCoord = SurfaceData.TexCoord0 * _MainTex_ST.xy + _MainTex_ST.zw; + float4 LitColor = H_SAMPLE_2D(_MainTex, sampler_MainTex, TextureCoord) * _Color; + + SurfaceData.Alpha = LitColor.w < _Cutoff ? 1 : 0; + SurfaceData.Color = LitColor.xyz; + } + + // Emission Evaluation + float2 TextureCoord = SurfaceData.TexCoord0 * _EmissionMap_ST.xy + _EmissionMap_ST.zw; + float4 EmissionColor = H_SAMPLE_2D(_EmissionMap, sampler_EmissionMap, TextureCoord) * _EmissionColor; + + // if (any(EmissionColor.xyz > 0)) + // { + // SurfaceData.IsEmissive = true; + // SurfaceData.Color = EmissionColor; + // return true; + // } + + return true; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationBIRP.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationBIRP.hlsl.meta new file mode 100644 index 000000000..3eb2d57a0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationBIRP.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 8aa78c42ce9a65543801b181514ff0b7 +timeCreated: 1748018708 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationBIRP.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationHDRP.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationHDRP.hlsl new file mode 100644 index 000000000..c8c96cfd7 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationHDRP.hlsl @@ -0,0 +1,252 @@ +#ifndef VOXEL_MATERIAL_EVALUATION_INCLUDE +#define VOXEL_MATERIAL_EVALUATION_INCLUDE + +#include "../Includes/Config.hlsl" +#include "../Headers/HMain.hlsl" + +// ------------------------ STRUCTS ------------------------ +struct VoxelSurfaceData +{ + // Inputs + float2 TexCoord0; + float2 TexCoord1; + + #if EXTRA_ATTRIBUTES + float3 VertexColor; + float3 PositionWS; + float3 NormalWS; + float3 PivotWS; + #endif + + // Outputs + float3 Color; + float Alpha; + float IsEmissive; +}; + +// ------------------------ FUNCTIONS ------------------------ +float3 ClampDiffuseColor(float3 DiffuseColor) +{ + DiffuseColor *= SURFACE_DIFFUSE_INTENSITY; + + DiffuseColor = FastLinearToSRGB(DiffuseColor); + DiffuseColor = RgbToHsv(DiffuseColor); + DiffuseColor.z = min(DiffuseColor.z, 0.9f); + DiffuseColor = HsvToRgb(DiffuseColor); + DiffuseColor = FastSRGBToLinear(DiffuseColor); + + return DiffuseColor; +} + + +float3 TerrainSplatColors[4]; + +#define FillSplatColors(i, Mask, TextureCoordBase) \ +UNITY_BRANCH \ +if (Mask > 0) \ +{ \ + float2 TextureCoord = TextureCoordBase * _Splat##i##_ST.xy + _Splat##i##_ST.zw; \ + TerrainSplatColors[i] = H_SAMPLE_2D(_Splat##i, sampler_Splat0, TextureCoord).xyz; \ +} \ +else \ +{ \ + TerrainSplatColors[i] = float3(0, 0, 0); \ +} + + +// ------------------------ MATERIAL PROPERTIES ------------------------ + +// Emissive properties +float _AlbedoAffectEmissive; + +// Lit Shader properties +float _UVBase; +float4 _BaseColor; +float4 _BaseColorMap_ST; +TEXTURE2D(_BaseColorMap); +H_SAMPLER(sampler_BaseColorMap); + +// Layered Lit Shader properties +float _UVBase0; +float _UVBase1; +float _UVBlendMask; +float4 _BaseColor0; +float4 _BaseColor1; +float4 _BaseColorMap0_ST; +float4 _BaseColorMap1_ST; +float4 _LayerMaskMap_ST; +TEXTURE2D(_BaseColorMap0); +TEXTURE2D(_BaseColorMap1); +TEXTURE2D(_LayerMaskMap); +H_SAMPLER(sampler_BaseColorMap0); +H_SAMPLER(sampler_BaseColorMap1); +H_SAMPLER(sampler_LayerMaskMap); + +// Terrain Shader properties +float4 _Splat0_ST; +float4 _Splat1_ST; +float4 _Splat2_ST; +float4 _Splat3_ST; +float4 _Control0_TexelSize; +TEXTURE2D(_Splat0); +TEXTURE2D(_Splat1); +TEXTURE2D(_Splat2); +TEXTURE2D(_Splat3); +TEXTURE2D(_Control0); +TEXTURE2D(_TerrainHolesTexture); +H_SAMPLER(sampler_Control0); +H_SAMPLER(sampler_Splat0); +H_SAMPLER(sampler_TerrainHolesTexture); + +// SpeedTree Shader properties +float4 _Color; +float _AlphaClipThreshold; +TEXTURE2D(_MainTex); + +// 3rd Party Shaders +H_SAMPLER(sampler_Point_Repeat); + +#if EVALUATE_TVE +#include "Assets/BOXOPHOBIC/The Visual Engine Modules/HTrace WSGI/Core/Shaders/Includes/TVEHTraceWSGISurface.hlsl" +#endif + +// ------------------------ MATERIAL EVALUATION ------------------------ +bool EvaluateSurfaceColor(inout VoxelSurfaceData SurfaceData) +{ + float3 DiffuseColor = 0; + + SurfaceData.Color = 0; + SurfaceData.Alpha = 0; + SurfaceData.IsEmissive = 0; + + #if EVALUATE_TVE + { + UNITY_BRANCH + if (TVEOverride() > 0) + { + TVESurface(SurfaceData); + return true; + } + } + #endif + + + if (EVALUATE_EMISSION) + { + float2 TextureCoord = SurfaceData.TexCoord0 * _EmissiveColorMap_ST.xy + _EmissiveColorMap_ST.zw; + float3 EmissiveMap = H_SAMPLE_2D(_EmissiveColorMap, sampler_EmissiveColorMap, TextureCoord).xyz; + + float3 Emission = _EmissiveColor * lerp(float3(1.0, 1.0, 1.0), DiffuseColor, _AlbedoAffectEmissive); + Emission = lerp(Emission, Emission * HGetCurrentExposureMultiplier, _EmissiveExposureWeight); + Emission *= EmissiveMap; + + if (Luminance(Emission) > 0) + { + SurfaceData.Color = Emission; + SurfaceData.IsEmissive = 1; + + // This is needed to match SS part which uses _GBufferTexture3 for Emissive which is R111G11B10 format + uint Packed = PackToR11G11B10f(SurfaceData.Color); + SurfaceData.Color = UnpackFromR11G11B10f(Packed); + + return true; + } + } + + if (EVALUATE_LIT) + { + float2 TextureCoordBase = _UVBase == 1 ? SurfaceData.TexCoord1 : SurfaceData.TexCoord0; + float2 TextureCoord = TextureCoordBase * _BaseColorMap_ST.xy + _BaseColorMap_ST.zw; + float4 LitColor = H_SAMPLE_2D(_BaseColorMap, sampler_BaseColorMap, TextureCoord) * _BaseColor; + SurfaceData.Alpha = LitColor.w < _AlphaCutoff ? 1 : 0; + + DiffuseColor += LitColor.xyz; + SurfaceData.Color = LitColor.xyz; + } + + if (EVALUATE_LAYERED_LIT) + { + UNITY_BRANCH + if (length(DiffuseColor) > 0) + return true; + + float2 TextureCoordBase0 = _UVBase0 == 1 ? SurfaceData.TexCoord1 : SurfaceData.TexCoord0; + float2 TextureCoordBase1 = _UVBase1 == 1 ? SurfaceData.TexCoord1 : SurfaceData.TexCoord0; + float2 TextureCoordBaseMask = _UVBlendMask == 1 ? SurfaceData.TexCoord1 : SurfaceData.TexCoord0; + + float2 TextureCoord0 = TextureCoordBase0 * _BaseColorMap0_ST.xy + _BaseColorMap0_ST.zw; + float2 TextureCoord1 = TextureCoordBase1 * _BaseColorMap1_ST.xy + _BaseColorMap1_ST.zw; + float2 TextureCoordMask = TextureCoordBaseMask * _LayerMaskMap_ST.xy + _LayerMaskMap_ST.zw; + + float Mask = H_SAMPLE_2D(_LayerMaskMap, sampler_LayerMaskMap, TextureCoordMask).x; + float4 LayerColor0 = H_SAMPLE_2D(_BaseColorMap0, sampler_BaseColorMap0, TextureCoord0) * _BaseColor0; + float4 LayerColor1 = H_SAMPLE_2D(_BaseColorMap1, sampler_BaseColorMap1, TextureCoord1) * _BaseColor1; + + float4 LayeredLitColor = lerp(LayerColor0, LayerColor1, Mask.r); + + DiffuseColor += LayeredLitColor.xyz; + SurfaceData.Color = LayeredLitColor.xyz; + SurfaceData.Alpha = LayeredLitColor.w < _AlphaCutoff ? 1 : 0; + } + + if (EVALUATE_UNLIT) + { + UNITY_BRANCH + if (length(DiffuseColor) > 0) + return true; + + float2 TextureCoord = SurfaceData.TexCoord0 * _UnlitColorMap_ST.xy + _UnlitColorMap_ST.zw; + float4 UnlitColor = H_SAMPLE_2D(_UnlitColorMap, sampler_UnlitColorMap, TextureCoord) * _UnlitColor; + + DiffuseColor += UnlitColor.xyz; + SurfaceData.Color = UnlitColor.xyz; + SurfaceData.Alpha = UnlitColor.w < _AlphaCutoff ? 1 : 0; + } + + if (EVALUATE_SPEEDTREE) + { + UNITY_BRANCH + if (length(DiffuseColor) > 0) + return true; + + float4 SpeedTreeColor = H_SAMPLE_2D(_MainTex, sampler_BaseColorMap, SurfaceData.TexCoord0) * _Color; + SurfaceData.Alpha = SpeedTreeColor.w < _AlphaClipThreshold ? 1 : 0; + + float Holes = H_SAMPLE_2D(_TerrainHolesTexture, sampler_TerrainHolesTexture, SurfaceData.TexCoord0).r; + if (abs(Holes.x - 0.5) == 0.5) + SurfaceData.Alpha = Holes < 0.5f; + + DiffuseColor += SpeedTreeColor.xyz; + SurfaceData.Color = SpeedTreeColor.xyz; + } + + if (EVALUATE_TERRAIN) + { + UNITY_BRANCH + if (length(DiffuseColor) > 0) + return true; + + float2 TextureCoordBase = SurfaceData.TexCoord0; + float2 ControlMapCoord = (SurfaceData.TexCoord0.xy * (_Control0_TexelSize.zw - 1.0f) + 0.5f) * _Control0_TexelSize.xy; + float4 ControlMap = H_SAMPLE_2D(_Control0, sampler_Control0, ControlMapCoord); + float Holes = H_SAMPLE_2D(_TerrainHolesTexture, sampler_TerrainHolesTexture, ControlMapCoord).r; + + FillSplatColors(0, ControlMap.x, TextureCoordBase); + FillSplatColors(1, ControlMap.y, TextureCoordBase); + FillSplatColors(2, ControlMap.z, TextureCoordBase); + FillSplatColors(3, ControlMap.w, TextureCoordBase); + + float3 TerrainColor = 0; + TerrainColor += TerrainSplatColors[0] * ControlMap.x; + TerrainColor += TerrainSplatColors[1] * ControlMap.y; + TerrainColor += TerrainSplatColors[2] * ControlMap.z; + TerrainColor += TerrainSplatColors[3] * ControlMap.w; + + DiffuseColor += TerrainColor; + SurfaceData.Color = TerrainColor; + SurfaceData.Alpha = Holes < 0.5f; + } + + return true; +} +#endif diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationHDRP.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationHDRP.hlsl.meta new file mode 100644 index 000000000..7e238d57d --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationHDRP.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 65cfb920bf1bcaf4e8e821a3dfe47c52 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationHDRP.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationURP.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationURP.hlsl new file mode 100644 index 000000000..e475f2122 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationURP.hlsl @@ -0,0 +1,151 @@ +#ifndef VOXEL_MATERIAL_EVALUATION_INCLUDE +#define VOXEL_MATERIAL_EVALUATION_INCLUDE + +#include "../Includes/Config.hlsl" +#include "../Headers/HMain.hlsl" + +// ------------------------ STRUCTS ------------------------ +struct VoxelSurfaceData +{ + // Inputs + float2 TexCoord0; + float2 TexCoord1; + + // Outputs + float3 Color; + float Alpha; + float IsEmissive; +}; + +// ------------------------ FUNCTIONS ------------------------ +float3 ClampDiffuseColor(float3 DiffuseColor) +{ + DiffuseColor *= SURFACE_DIFFUSE_INTENSITY; + + DiffuseColor = FastLinearToSRGB(DiffuseColor); + DiffuseColor = RgbToHsv(DiffuseColor); + DiffuseColor.z = min(DiffuseColor.z, 0.9f); + DiffuseColor = HsvToRgb(DiffuseColor); + DiffuseColor = FastSRGBToLinear(DiffuseColor); + + return DiffuseColor; +} + + +float3 TerrainSplatColors[4]; + +#define FillSplatColors(i, Mask, TextureCoordBase) \ +UNITY_BRANCH \ +if (Mask > 0) \ +{ \ + float2 TextureCoord = TextureCoordBase * _Splat##i##_ST.xy + _Splat##i##_ST.zw; \ + TerrainSplatColors[i] = H_SAMPLE_2D(_Splat##i, sampler_Splat0, TextureCoord).xyz; \ +} \ +else \ +{ \ + TerrainSplatColors[i] = float3(0, 0, 0); \ +} + + +// ------------------------ MATERIAL PROPERTIES ------------------------ + +// Emissive properties +float3 _EmissionColor; +float4 _EmissionMap_ST; +TEXTURE2D(_EmissionMap); +H_SAMPLER(sampler_EmissionMap); + +// Lit Shader properties +float _UVBase; +float4 _BaseColor; +float4 _BaseMap_ST; +TEXTURE2D(_BaseMap); +H_SAMPLER(sampler_BaseMap); +float _Cutoff; + +// Terrain Shader properties +float4 _Splat0_ST; +float4 _Splat1_ST; +float4 _Splat2_ST; +float4 _Splat3_ST; +float4 _Control0_TexelSize; +TEXTURE2D(_Splat0); +TEXTURE2D(_Splat1); +TEXTURE2D(_Splat2); +TEXTURE2D(_Splat3); +TEXTURE2D(_Control0); +TEXTURE2D(_TerrainHolesTexture); +H_SAMPLER(sampler_Control0); +H_SAMPLER(sampler_Splat0); +H_SAMPLER(sampler_TerrainHolesTexture); + + +// ------------------------ MATERIAL EVALUATION ------------------------ +bool EvaluateSurfaceColor(inout VoxelSurfaceData SurfaceData) +{ + float3 DiffuseColor = 0; + + SurfaceData.Color = 0; + SurfaceData.Alpha = 0; + SurfaceData.IsEmissive = 0; + + if (EVALUATE_EMISSION) + { + float2 TextureCoord = SurfaceData.TexCoord0 * _EmissionMap_ST.xy + _EmissionMap_ST.zw; + float3 Emission = H_SAMPLE_2D(_EmissionMap, sampler_EmissionMap, TextureCoord).xyz * _EmissionColor; + + if (Luminance(Emission) > 0 && all(_EmissionColor != 1.0f)) + { + SurfaceData.Color = Emission; + SurfaceData.IsEmissive = 1; + + // This is needed to match SS part which uses _GBufferTexture3 for Emissive which is R111G11B10 format + uint Packed = PackToR11G11B10f(SurfaceData.Color); + SurfaceData.Color = UnpackFromR11G11B10f(Packed); + + return true; + } + } + + if (EVALUATE_TERRAIN) + { + UNITY_BRANCH + if (all(_Control0_TexelSize.xy > 0)) + { + float2 TextureCoordBase = SurfaceData.TexCoord0; + float2 ControlMapCoord = (SurfaceData.TexCoord0.xy * (_Control0_TexelSize.zw - 1.0f) + 0.5f) * _Control0_TexelSize.xy; + float4 ControlMap = H_SAMPLE_2D(_Control0, sampler_Control0, ControlMapCoord); + float Holes = H_SAMPLE_2D(_TerrainHolesTexture, sampler_TerrainHolesTexture, ControlMapCoord).r; + + FillSplatColors(0, ControlMap.x, TextureCoordBase); + FillSplatColors(1, ControlMap.y, TextureCoordBase); + FillSplatColors(2, ControlMap.z, TextureCoordBase); + FillSplatColors(3, ControlMap.w, TextureCoordBase); + + float3 TerrainColor = 0; + TerrainColor += TerrainSplatColors[0] * ControlMap.x; + TerrainColor += TerrainSplatColors[1] * ControlMap.y; + TerrainColor += TerrainSplatColors[2] * ControlMap.z; + TerrainColor += TerrainSplatColors[3] * ControlMap.w; + + DiffuseColor += TerrainColor; + SurfaceData.Color = TerrainColor; + SurfaceData.Alpha = Holes < 0.5f; + return true; + } + } + + if (EVALUATE_LIT) + { + float2 TextureCoordBase = _UVBase == 1 ? SurfaceData.TexCoord1 : SurfaceData.TexCoord0; + float2 TextureCoord = TextureCoordBase * _BaseMap_ST.xy + _BaseMap_ST.zw; + float4 LitColor = H_SAMPLE_2D(_BaseMap, sampler_BaseMap, TextureCoord) * _BaseColor; + SurfaceData.Alpha = LitColor.w < _Cutoff ? 1 : 0; + + DiffuseColor += LitColor.xyz; + SurfaceData.Color = LitColor.xyz; + } + + return true; +} +#endif diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationURP.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationURP.hlsl.meta new file mode 100644 index 000000000..88412ca5d --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationURP.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 2a911454b2354d941abd9b74673f60fa +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelMaterialEvaluationURP.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelTraversal.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelTraversal.hlsl new file mode 100644 index 000000000..52ab1ea00 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelTraversal.hlsl @@ -0,0 +1,330 @@ +#ifndef VOXEL_TRAVERSAL_INCLUDED +#define VOXEL_TRAVERSAL_INCLUDED + +#include "../Headers/HMain.hlsl" +#include "VoxelizationCommon.hlsl" + +#define _VoxelResInverse (1.0f / _VoxelResolution.xyz) +#define _VoxelResInverseHalf ((1.0f / _VoxelResolution.xyz) * 0.5f) + +float _SkyOcclusionCone; + +// ------------------------ FUNCTIONS ------------------------ + +// Offsets tracing origin from a GBuffer surface to avoid voxel self-intersection +void VoxelBias(int2 pixCoord, StructuredBuffer _PointDistribution, float Depth, float HitDistanceWS, float3 GeometryNormalWS, float3 RayDirectionWS, inout float3 RayOriginWS) +{ + float JitterNoise = GetBNDSequenceSample(pixCoord.xy, _FrameCount, 0); + float DotWeight = saturate(dot(GeometryNormalWS, RayDirectionWS)); + + // bool IsRayOriginMoving = (GetStencilValue(H_LOAD(g_HTraceStencilBuffer, (pixCoord.xy) ) ) & 32) != 0; + // if (IsRayOriginMoving) + // { + // float MotionBias = min(0.5f / H_LINEAR_EYE_DEPTH(Depth), 0.5f); + // RayOriginWS += RayDirectionWS * MotionBias; + // } + + // Apply positive direction bias + if (HitDistanceWS <= _VoxelSize * 0.5f) + { + float3 DirectionBias = normalize(RayDirectionWS) * _VoxelSize; + RayOriginWS += DirectionBias * lerp(0.0f, 0.5f, DotWeight); + } + + // Jitter ray to hide voxel artifacts + if (true) + { + float3x3 OrthoBasis = HGetLocalFrame(GeometryNormalWS.xyz); + + for (int i = 0; i < 4; i++) + { + float2 Sample = _PointDistribution[JitterNoise.x * 64 - i] * 0.1f; + float3 SamplePosWS = RayOriginWS + OrthoBasis[0] * Sample.x + OrthoBasis[1] * Sample.y; + float4 SamplePosHC = H_TRANSFORM_WORLD_TO_H_CLIP(SamplePosWS); + SamplePosHC.xyz /= SamplePosHC.w; + float2 SamplePosSS = SamplePosHC.xy * 0.5f + 0.5f; + SamplePosSS.y = 1.0f - SamplePosSS.y; + + if (SamplePosHC.x > 1.0f || SamplePosHC.x < -1.0f || SamplePosHC.y > 1.0f || SamplePosHC.y < -1.0f) + continue; + + float BiasedSurface = H_LOAD(g_HTraceDepthPyramidWSGI, SamplePosSS * _ScreenSize.xy).x; + + if (SamplePosHC.z > BiasedSurface) + { + RayOriginWS = SamplePosWS; + break; + } + } + } + + // Apply normal bias + if (HitDistanceWS <= _VoxelSize * 3) + { + RayOriginWS += GeometryNormalWS * _VoxelSize * (1.0f - DotWeight); + } + + // Apply negative direction bias + if (HitDistanceWS >= _VoxelSize * 2.0f) + { + float MaxNegativeDistance = HitDistanceWS > _VoxelSize * 2.0f ? 1.0f : 0.5f; + RayOriginWS = RayOriginWS - RayDirectionWS * _VoxelSize * lerp(0.25f, 1.0f, DotWeight); + } +} + +// Calculates the distance of Ray-VoxelBound intersection in a given direction +float MaxVoxelRayDistance(float3 RayOrigin, float3 RayDirection) +{ + float3 BoundMin = _VoxelCameraPos - _VoxelBounds.xzy / 2; + float3 BoundMax = _VoxelCameraPos + _VoxelBounds.xzy / 2; + return RayBoxIntersect(RayOrigin, RayDirection, BoundMin, BoundMax); +} + + + +// ------------------------ STRUCTS ------------------------ +struct Step +{ + float3 Direction; + float3 Position; + float Distance; +}; + + +struct Ray +{ + float3 Origin; + float3 DirInv; + float3 Dir; +}; + +struct Traversal +{ + float3 DirSignZ; + float3 DirSign; + float3 Normal; + float3 Coord; + float3 Delta; + float3 Step; + float3 Pos; + float3 Max; + float Dist; +}; + + +// ------------------------ TRAVERSAL UPDATES ------------------------ +void UpdateStepParameters(inout Traversal Traversal, inout Ray Ray, float Scale) +{ + float TexelSize = _VoxelSize * Scale; + float3 ResolutionInv = _VoxelResInverse * Scale; + Traversal.Delta = Ray.DirInv * TexelSize; + Traversal.Pos = (Ray.Origin + Traversal.Dist * Ray.Dir) / TexelSize; + Traversal.Coord = floor(Traversal.Pos); + Traversal.Max = (Ray.DirInv * (Traversal.DirSignZ + Traversal.DirSign * (Traversal.Coord - Traversal.Pos))) * TexelSize + Traversal.Dist; + Traversal.Coord = (Traversal.Coord + 0.5) * ResolutionInv; + Traversal.Step = Traversal.DirSign * ResolutionInv; +} + +void IterateStep(inout Traversal Traversal, inout Ray Ray) +{ + Traversal.Normal = step(Traversal.Max.xyz, Traversal.Max.zxy) * step(Traversal.Max.xyz, Traversal.Max.yzx); + Traversal.Dist = dot(Traversal.Max, Traversal.Normal); + Traversal.Max += Traversal.Delta * Traversal.Normal; + Traversal.Coord += Traversal.Step * Traversal.Normal; +} + + +// ------------------------ SUPERCOVER TRAVERSAL + MIPS + OCTANTS ------------------------ +bool TraceVoxelsDiffuse(float3 RayOrigin, float3 RayDirection, float TraceDistance, uint MaxIterations, inout VoxelPayload Payload) +{ + float3 OriginWS = RayOrigin; + float Offset = (_VoxelBounds.y - _VoxelBounds.z) / 2.0f; + RayOrigin = RayOrigin - float3(0, Offset, -Offset) - _VoxelCameraPos; + + Traversal Traversal; + Ray Ray; + + Ray.Origin = RayOrigin + (_VoxelResolution.xyz / 2.0f) * _VoxelSize; + Ray.DirInv = 1.0f / (abs(RayDirection) + 0.00001f); + Ray.Dir = RayDirection; + + Traversal.DirSign = sign(RayDirection); + Traversal.DirSignZ = step(0.0f, Traversal.DirSign); + Traversal.Normal = RayDirection; + Traversal.Coord = 0; + Traversal.Dist = 0; + + int MipIndex = -1; + uint Iterations = 0; + + while (Traversal.Dist < TraceDistance && Iterations < MaxIterations) + { + if (MipIndex == -1) + { + UpdateStepParameters(Traversal, Ray, 0.5f); + Payload.HitDistance = Traversal.Dist; + + int i = 0; + while (Traversal.Dist < TraceDistance && i++ < 4) + { + uint3 VoxelTexCoord = Traversal.Coord * _VoxelResolution.xyz; + uint VoxelOccupancy = asuint(H_LOAD3D_LOD(_VoxelPositionPyramid, VoxelTexCoord, 0)); + + if (VoxelOccupancy > 0) + { + uint BitShift = 0u; + BitShift += fmod(Traversal.Coord.x, _VoxelResInverse.x) > _VoxelResInverseHalf.x ? 1u : 0u; + BitShift += fmod(Traversal.Coord.y, _VoxelResInverse.y) > _VoxelResInverseHalf.y ? 2u : 0u; + BitShift += fmod(Traversal.Coord.z, _VoxelResInverse.z) > _VoxelResInverseHalf.z ? 4u : 0u; + uint BitMask = 1u << BitShift; + + if ((BitMask & VoxelOccupancy) != 0u) + { + Payload.HitCoord = VoxelTexCoord; + Payload.HitDistance = Traversal.Dist; + Payload.HitNormal = normalize(-Traversal.Normal * Traversal.DirSign); + Payload.HitPosition = OriginWS + Traversal.Dist * RayDirection; + + return true; + } + } + + IterateStep(Traversal, Ray); + Iterations++; + } + + MipIndex = 0; + } + else + { + float MipIndexScale = float(1 << MipIndex); + UpdateStepParameters(Traversal, Ray, MipIndexScale); + Payload.HitDistance = Traversal.Dist; + + int i = (MipIndex < 5 ? 8 : 1024); + while (Traversal.Dist < TraceDistance) + { + if (i-- == 0) + { + MipIndex++; + break; + } + + float3 VoxelTexCoord = Traversal.Coord * _VoxelResolution.xyz / MipIndexScale; + uint VoxelOccupancy = asuint(H_LOAD3D_LOD(_VoxelPositionPyramid, VoxelTexCoord, MipIndex)); + + // if (!IsVoxelCoordInBounds(Traversal.Coord)) + // { + // Payload.HitDistance = Traversal.Dist; + // return false; + // } + + + if (VoxelOccupancy > 0) + { + MipIndex--; + break; + } + + IterateStep(Traversal, Ray); + Iterations++; + } + } + } + + return false; +} + + +// ------------------------ LINEAR TRAVERSAL + MIPS + OCTANTS ------------------------ +bool TraceVoxelsOcclusion(float3 RayOrigin, float3 RayDirection, float TraceDistance, uint MaxIterations, inout float Distance) +{ + float Offset = (_VoxelBounds.y - _VoxelBounds.z) / 2.0f; + RayOrigin = RayOrigin - float3(0, Offset, -Offset) + (_WorldSpaceCameraPos - _VoxelCameraPos); + RayOrigin = RayOrigin + (_VoxelResolution.xyz / 2.0f) * _VoxelSize; + + Step Step; + Step.Distance = _VoxelSize; + Step.Direction = RayDirection * (Step.Distance / _VoxelSize) * _VoxelResInverse; + Step.Position = (RayOrigin / _VoxelSize) * _VoxelResInverse; + + Step.Direction *= 0.5; + Step.Distance *= 0.5; + + int MipIndex = -1; + uint Iterations = 0; + float3 VoxelResInverseHalf = _VoxelResInverse * 0.5; + + Distance = 0; + while (Distance < TraceDistance && Iterations < MaxIterations) + { + uint MipIndexLocal = max(0, MipIndex); + float MipIndexScale = float(1 << MipIndexLocal); + uint3 VoxelTexCoord = Step.Position * _VoxelResolution.xyz; + uint VoxelOccupancy = asuint(H_LOAD3D_LOD(_VoxelPositionPyramid, VoxelTexCoord / MipIndexScale, MipIndexLocal)); + Iterations++; + + if (MipIndex == -1) + { + if (VoxelOccupancy != 0u) + { + uint BitShift = 0u; + BitShift += fmod(Step.Position.x, _VoxelResInverse.x) > VoxelResInverseHalf.x ? 1u : 0u; + BitShift += fmod(Step.Position.y, _VoxelResInverse.y) > VoxelResInverseHalf.y ? 2u : 0u; + BitShift += fmod(Step.Position.z, _VoxelResInverse.z) > VoxelResInverseHalf.z ? 4u : 0u; + uint BitMask = 1u << BitShift; + + if ((BitMask & VoxelOccupancy) != 0u) return true; + else + { + Step.Position += Step.Direction; + Distance += Step.Distance; + } + } + else + { + MipIndex++; + Step.Direction *= 2.0; + Step.Distance *= 2.0; + Step.Position += Step.Direction; + Distance += Step.Distance; + } + } + else + { + if (VoxelOccupancy != 0u) + { + MipIndex--; + Step.Direction *= 0.5; + Step.Distance *= 0.5; + Step.Position -= Step.Direction; + Distance -= Step.Distance; + } + else + { + if (MipIndex < 5) + { + uint MipIndexLocal = MipIndex + 1; + float MipIndexScale = float(1 << MipIndexLocal); + float3 VoxelTexCoord = Step.Position * _VoxelResolution.xyz ; + uint VoxelOccupancy = asuint(H_LOAD3D_LOD(_VoxelPositionPyramid, VoxelTexCoord / MipIndexScale, MipIndexLocal)); + Iterations++; + + if (VoxelOccupancy == 0u) + { + MipIndex++; + Step.Direction *= 2.0; + Step.Distance *= 2.0; + } + } + + Step.Position += Step.Direction; + Distance += Step.Distance; + } + } + } + + Distance = TraceDistance; + return false; +} +#endif diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelTraversal.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelTraversal.hlsl.meta new file mode 100644 index 000000000..2a322acef --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelTraversal.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 39769b2048607b04c8f97b274758de78 +timeCreated: 1681802468 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelTraversal.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationCommon.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationCommon.hlsl new file mode 100644 index 000000000..0772bc8f9 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationCommon.hlsl @@ -0,0 +1,90 @@ +#ifndef VOXELIZATION_COMMON_INCLUDED +#define VOXELIZATION_COMMON_INCLUDED + +#include "../Headers/HMain.hlsl" + +float3 _VoxelizationAABB_Min; +float3 _VoxelizationAABB_Max; +float3 _VoxelResolution; +float3 _VoxelCameraPos; +float _VoxelPerMeter; +float3 _VoxelBounds; +float _VoxelSize; + +H_RW_TEXTURE3D(uint, _VoxelData); +H_TEXTURE3D(uint, _VoxelPositionPyramid); + + +// ------------------------ STRUCTS ------------------------ +struct VoxelPayload +{ + uint3 HitCoord; + float3 HitColor; + float3 HitCache; + float3 HitNormal; + float3 HitDiffuse; + float3 HitPosition; + float HitDistance; +}; + +void InitializePayload(inout VoxelPayload Payload) +{ + Payload.HitCoord = 0; + Payload.HitColor = 0; + Payload.HitCache = 0; + Payload.HitNormal = 0; + Payload.HitDiffuse = 0; + Payload.HitPosition = 0; + Payload.HitDistance = 0; +} + + +// ------------------------ FUNCTIONS ------------------------ +bool IsWorldPositionInBounds(float3 WorldPositionAbsolute) +{ + float TestX = step(_VoxelizationAABB_Min.x, WorldPositionAbsolute.x) * step(WorldPositionAbsolute.x, _VoxelizationAABB_Max.x); + float TestY = step(_VoxelizationAABB_Min.y, WorldPositionAbsolute.y) * step(WorldPositionAbsolute.y, _VoxelizationAABB_Max.y); + float TestZ = step(_VoxelizationAABB_Min.z, WorldPositionAbsolute.z) * step(WorldPositionAbsolute.z, _VoxelizationAABB_Max.z); + + return TestX * TestY * TestZ; +} + +bool IsVoxelCoordInBounds(int3 VoxelCoord) +{ + VoxelCoord.xyz = VoxelCoord.xzy; + + float TestX = step(0.0f, VoxelCoord.x) * step(VoxelCoord.x, _VoxelResolution.x); + float TestY = step(0.0f, VoxelCoord.y) * step(VoxelCoord.y, _VoxelResolution.y); + float TestZ = step(0.0f, VoxelCoord.z) * step(VoxelCoord.z, _VoxelResolution.z); + + return TestX * TestY * TestZ; +} + + +int3 AbsoluteWorldPositionToVoxelCoord(float3 WorldPos) +{ + // TODO: seems like floor must be used instead of round here + int3 VoxelBoxCenter = int3(_VoxelResolution.xzy / 2); + int3 VoxelPosition = round(WorldPos * _VoxelPerMeter) - VoxelBoxCenter; // Must keep int here to detect going out of bounds + return _VoxelResolution.xzy + VoxelPosition; +} + +float3 VoxelCoordToAbsoluteWorldPosition(int3 VoxelPos) +{ + int3 VoxelBoxCenter = int3(_VoxelResolution.xzy / 2); + return float3(VoxelPos - VoxelBoxCenter) / _VoxelPerMeter + _VoxelCameraPos; +} + +int3 VoxelCoordToAbsoluteVoxelCoord(int3 HitCoord) +{ + int3 VoxelBoxCenter = int3(_VoxelResolution.xzy / 2); + return int3((HitCoord - VoxelBoxCenter) + round(_VoxelCameraPos / _VoxelSize)); +} + +float3 ComputeRadianceCacheCoord(int3 HitCoord) +{ + float3 CacheCoord = HitCoord + _VoxelCameraPos * _VoxelPerMeter; + int3 CacheSpans = floor(CacheCoord / int3(_VoxelResolution.xzy)); + return round(CacheCoord - CacheSpans * _VoxelResolution.xzy); +} +#endif // VOXELIZATION_COMMON_INCLUDED diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationCommon.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationCommon.hlsl.meta new file mode 100644 index 000000000..c818a4a4f --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationCommon.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: bebbe3d339e031f41adc7787336f02d5 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationCommon.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesHDRP.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesHDRP.hlsl new file mode 100644 index 000000000..8eb8bb71b --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesHDRP.hlsl @@ -0,0 +1,299 @@ +#pragma once + +#define ATTRIBUTES_NEED_NORMAL +#define ATTRIBUTES_NEED_TEXCOORD0 +#define ATTRIBUTES_NEED_TEXCOORD1 +#define ATTRIBUTES_NEED_COLOR + +#define EXTRA_ATTRIBUTES 1 + +#define EVALUATE_TVE 0 +#define EVALUATE_LIT 1 +#define EVALUATE_UNLIT 1 +#define EVALUATE_TERRAIN 1 +#define EVALUATE_EMISSION 1 +#define EVALUATE_SPEEDTREE 1 +#define EVALUATE_LAYERED_LIT 1 + +#define AXIS_X 0 +#define AXIS_Y 1 +#define AXIS_Z 2 + +#include "VoxelizationCommon.hlsl" +#include "VoxelMaterialEvaluationHDRP.hlsl" + +H_RW_TEXTURE3D(uint, _VoxelColor); + +// Terrain instancing properties +float4 _TerrainHeightmapRecipSize; +float4 _TerrainHeightmapScale; +UNITY_INSTANCING_BUFFER_START(Terrain) +UNITY_DEFINE_INSTANCED_PROP(float4, _TerrainPatchInstanceData) +UNITY_INSTANCING_BUFFER_END(Terrain) +TEXTURE2D(_TerrainHeightmapTexture); + +int _OffsetAxisIndex; +int2 _CullingTrim; +int2 _CullingTrimAxis; +float3 _AxisOffset; +float3 _OctantOffset; +float3 _VoxelCameraPosActual; + + +// ------------------------ SHARED STRUCTS ------------------------ +struct VertexToGeometry +{ + float4 PositionCS : POSITION; + float4 TextureCoords : TEXCOORD0; + + #ifdef PARTIAL_VOXELIZATION + int CullingTest : TEXCOORD1; + #endif + + #if EXTRA_ATTRIBUTES + float3 PositionWS : TEXCOORD2; + float3 PivotWS : TEXCOORD3; + float3 VertexColor : COLOR0; + #endif +}; + +struct GeometryToFragment +{ + float4 PositionCS : POSITION; + float4 TextureCoords : TEXCOORD0; + float Axis : TEXCOORD1; + + #if EXTRA_ATTRIBUTES + float3 PositionWS : TEXCOORD2; + float3 NormalWS : TEXCOORD3; + float3 PivotWS : TEXCOORD4; + float3 VertexColor : COLOR0; + #endif +}; + + +// ------------------------ SHARED FUNCTIONS ------------------------ +float3 SwizzleAxis(float3 Position, uint Axis) +{ + uint a = Axis + 1; + float3 p = Position; + Position.x = p[(0 + a) % 3]; + Position.y = p[(1 + a) % 3]; + Position.z = p[(2 + a) % 3]; + + return Position; +} + +float3 RestoreAxis(float3 Position, uint Axis) +{ + uint a = 2 - Axis; + float3 p = Position; + Position.x = p[(0 + a) % 3]; + Position.y = p[(1 + a) % 3]; + Position.z = p[(2 + a) % 3]; + + return Position; +} + +void ModifyForTerrainInstancing(inout AttributesMesh InputMesh) +{ + float2 PatchVertex = InputMesh.positionOS.xy; + float4 InstanceData = UNITY_ACCESS_INSTANCED_PROP(Terrain, _TerrainPatchInstanceData); + + float2 TextureCoord = (PatchVertex.xy + InstanceData.xy) * InstanceData.z; + float HeightmapTexture = UnpackHeightmap(_TerrainHeightmapTexture.Load(int3(TextureCoord, 0))); + float HolesTexture = _TerrainHolesTexture.Load(int3(TextureCoord, 0)).x; + + if (abs(HolesTexture.x - 0.5) == 0.5) //HolesTexture.x == 1 || HolesTexture.x == 0) + { + InputMesh.positionOS.xz = TextureCoord * _TerrainHeightmapScale.xz; + InputMesh.positionOS.y = HeightmapTexture * _TerrainHeightmapScale.y; + + float4 Scale = InstanceData.z * _TerrainHeightmapRecipSize; + float4 Offset = InstanceData.xyxy * Scale; + Offset.xy += 0.5f * _TerrainHeightmapRecipSize.xy; + InputMesh.uv0 = (PatchVertex.xy * Scale.zw + Offset.zw); + + InputMesh.positionOS.xyz = mul(GetRawUnityObjectToWorld(), float4(InputMesh.positionOS.xyz - _WorldSpaceCameraPos, 1.0)).xyz; + } + else + { + InputMesh.positionOS.xyz = mul(GetObjectToWorldMatrix(), float4(InputMesh.positionOS, 1.0)).xyz; + } +} + + +// --- Vertex Stage --- +VertexToGeometry VoxelizationVert(AttributesMesh inputMesh) +{ + VertexToGeometry Output; + + float3 PositionWS; + + // Process instancing + #ifdef UNITY_INSTANCING_ENABLED + UNITY_SETUP_INSTANCE_ID(inputMesh); + ModifyForTerrainInstancing(inputMesh); + Output.PositionCS = mul(GetWorldToHClipMatrix(), float4(inputMesh.positionOS, 1.0)); + PositionWS = inputMesh.positionOS; + #else + Output.PositionCS = TransformObjectToHClip(inputMesh.positionOS); + PositionWS = TransformObjectToWorld(inputMesh.positionOS); + #endif + + // Output uv channels + Output.TextureCoords = float4(inputMesh.uv0, inputMesh.uv1); + + #ifdef PARTIAL_VOXELIZATION + // Transform world position to voxel coordinate + float3 WorldPosition = PositionWS + (_WorldSpaceCameraPos - _VoxelCameraPosActual); + int3 VoxelCoord = AbsoluteWorldPositionToVoxelCoord(WorldPosition); + + // Check if the vertex is behind culling camera + Output.CullingTest = 0; + if ((VoxelCoord[_OffsetAxisIndex] < _CullingTrim.x) * _CullingTrimAxis.x || (VoxelCoord[_OffsetAxisIndex] > _CullingTrim.y + 1) * _CullingTrimAxis.y) + Output.CullingTest = 1; + #endif + + #ifdef UNITY_REVERSED_Z + Output.PositionCS.z = mad(Output.PositionCS.z, -2.0, 1.0); + #endif + + #if EXTRA_ATTRIBUTES + Output.PositionWS = PositionWS; + Output.PivotWS = GetAbsolutePositionWS(float3(UNITY_MATRIX_M[0].w, UNITY_MATRIX_M[1].w, UNITY_MATRIX_M[2].w)); + //Alternative if unity complains about using the matrix + //Output.PivotWS = GetAbsolutePositionWS((TransformObjectToWorld(float3(0, 0, 0)))); + Output.VertexColor = inputMesh.color.xyz; + #endif + + return Output; +} + +// --- Geometry Stage --- +[maxvertexcount(3)] +void VoxelizationGeom(triangle VertexToGeometry i[3], inout TriangleStream Stream) +{ + // If all 3 vertices are behind culling camera - early out + #ifdef PARTIAL_VOXELIZATION + if (i[0].CullingTest + i[1].CullingTest + i[2].CullingTest == 3) + return; + #endif + + float3 Normal = normalize(abs(cross(i[1].PositionCS.xyz - i[0].PositionCS.xyz, i[2].PositionCS.xyz - i[0].PositionCS.xyz))); + + uint Axis = AXIS_Z; + if (Normal.x > Normal.y && Normal.x > Normal.z) + Axis = AXIS_X; + else if (Normal.y > Normal.x && Normal.y > Normal.z) + Axis = AXIS_Y; + + [unroll] + for (int j = 0; j < 3; j++) + { + GeometryToFragment Output; + + Output.PositionCS = float4(SwizzleAxis(i[j].PositionCS.xyz, Axis), 1); + + #ifdef UNITY_UV_STARTS_AT_TOP + Output.PositionCS.y = -Output.PositionCS.y; + #endif + + #ifdef UNITY_REVERSED_Z + Output.PositionCS.z = mad(Output.PositionCS.z, 0.5, 0.5); + #endif + + Output.TextureCoords = i[j].TextureCoords; + Output.Axis = Axis; + + #if EXTRA_ATTRIBUTES + Output.VertexColor = i[j].VertexColor; + Output.PositionWS = i[j].PositionWS; + Output.PivotWS = i[j].PivotWS; + Output.NormalWS = Normal; + #endif + + Stream.Append(Output); + } +} + +// --- Fragment Stage --- +float VoxelizationFrag(GeometryToFragment Input) : SV_TARGET +{ + float VoxelRes = _VoxelResolution.x; + + #ifndef PARTIAL_VOXELIZATION + VoxelRes = _VoxelResolution.x * 2; + #endif + + float3 VoxelPos = float3(Input.PositionCS.x, Input.PositionCS.y, Input.PositionCS.z * VoxelRes); + VoxelPos = RestoreAxis(VoxelPos, Input.Axis); + + // Modify Axes for non-cubic bounds + VoxelPos.xyz = VoxelPos.xzy; + VoxelPos.y *= (_VoxelBounds.z / _VoxelBounds.y); + VoxelPos.xz = VoxelRes - VoxelPos.xz; + + // Calculate octants for the first 8 bits + uint3 VoxelPosInt = floor(VoxelPos); + uint BitShift = (1 * (VoxelPosInt.x % 2)) + (2 * (VoxelPosInt.y % 2)) + (4 * (VoxelPosInt.z % 2)); + uint OctantBits = (1 << BitShift) << 24; + int StaticBitFlag = 1 << 23; + + int3 VoxelPosRounded = floor(VoxelPos / 2); + + #ifdef PARTIAL_VOXELIZATION + //Offset by axis + VoxelPosRounded.xyz += _AxisOffset.xyz; + + // Culling trim + if (VoxelPosRounded[_OffsetAxisIndex] < _CullingTrim.x || VoxelPosRounded[_OffsetAxisIndex] > _CullingTrim.y) + return 0.0f; + + //Offset by octant + VoxelPosRounded.xyz += _OctantOffset.xyz; + #endif + + // Fill inout Surface Data with input information + VoxelSurfaceData SurfaceData = (VoxelSurfaceData)0; + SurfaceData.TexCoord0 = Input.TextureCoords.xy; + SurfaceData.TexCoord1 = Input.TextureCoords.zw; + + #if EXTRA_ATTRIBUTES + SurfaceData.VertexColor = Input.VertexColor; + SurfaceData.PositionWS = Input.PositionWS; + SurfaceData.NormalWS = Input.NormalWS; + SurfaceData.PivotWS = Input.PivotWS; + #endif + + // Evaluate all material attributes + EvaluateSurfaceColor(SurfaceData); + + if (!SurfaceData.IsEmissive) + SurfaceData.Color = ClampDiffuseColor(SurfaceData.Color); + + if (SurfaceData.Alpha == 1) + OctantBits = 0; + + //SurfaceData.Color = Input.VertexColor; + // Pack color for the last 24 bits + uint PackedColor = PackVoxelColor(SurfaceData.Color, SurfaceData.IsEmissive); + + #ifdef DYNAMIC_VOXELIZATION + uint OriginalValue; + InterlockedCompareExchange(_VoxelColor[VoxelPosRounded], 0, 0, OriginalValue); + + if (((OriginalValue >> 23) & 0x1) != 1) + { + InterlockedOr(_VoxelColor[VoxelPosRounded], OctantBits, OriginalValue); + InterlockedMax(_VoxelColor[VoxelPosRounded], PackedColor | (OriginalValue & 0xFF000000) | OctantBits ); + } + + #else + uint OriginalValue; + InterlockedOr(_VoxelColor[VoxelPosRounded], StaticBitFlag | OctantBits, OriginalValue); + InterlockedMax(_VoxelColor[VoxelPosRounded], StaticBitFlag | PackedColor | (OriginalValue & 0xFF000000) | OctantBits); + #endif + + return 0.0f; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesHDRP.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesHDRP.hlsl.meta new file mode 100644 index 000000000..900133124 --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesHDRP.hlsl.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 775a704a66d3f2c43ba25749cf004676 +timeCreated: 1733414973 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesHDRP.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesURP.hlsl b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesURP.hlsl new file mode 100644 index 000000000..e3c9ba93c --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesURP.hlsl @@ -0,0 +1,232 @@ +#pragma once + +#define EVALUATE_EMISSION 1 +#define EVALUATE_TERRAIN 1 +#define EVALUATE_LIT 1 + +#define AXIS_X 0 +#define AXIS_Y 1 +#define AXIS_Z 2 + +#include "VoxelizationCommon.hlsl" +#include "VoxelMaterialEvaluationURP.hlsl" + +H_RW_TEXTURE3D(uint, _VoxelColor); + +int _OffsetAxisIndex; +int2 _CullingTrim; +int2 _CullingTrimAxis; +float3 _AxisOffset; +float3 _OctantOffset; +float3 _VoxelCameraPosActual; + + +// ------------------------ SHARED STRUCTS ------------------------ +struct VertexToGeometry +{ + float4 PositionCS : POSITION; + float4 TextureCoords : TEXCOORD0; + + #ifdef PARTIAL_VOXELIZATION + int CullingTest : TEXCOORD1; + #endif + + #if EXTRA_ATTRIBUTES + float3 PositionWS : TEXCOORD2; + float3 PivotWS : TEXCOORD3; + float3 VertexColor : COLOR0; + #endif +}; + +struct GeometryToFragment +{ + float4 PositionCS : POSITION; + float4 TextureCoords : TEXCOORD0; + float Axis : TEXCOORD1; + + #if EXTRA_ATTRIBUTES + float3 PositionWS : TEXCOORD2; + float3 NormalWS : TEXCOORD3; + float3 PivotWS : TEXCOORD4; + float3 VertexColor : COLOR0; + #endif +}; + + +// ------------------------ SHARED FUNCTIONS ------------------------ +float3 SwizzleAxis(float3 Position, uint Axis) +{ + uint a = Axis + 1; + float3 p = Position; + Position.x = p[(0 + a) % 3]; + Position.y = p[(1 + a) % 3]; + Position.z = p[(2 + a) % 3]; + + return Position; +} + +float3 RestoreAxis(float3 Position, uint Axis) +{ + uint a = 2 - Axis; + float3 p = Position; + Position.x = p[(0 + a) % 3]; + Position.y = p[(1 + a) % 3]; + Position.z = p[(2 + a) % 3]; + + return Position; +} + +struct AttributesMesh +{ + float3 positionOS : POSITION; + float3 normalOS : NORMAL; + float2 uv0 : TEXCOORD0; + float2 uv1 : TEXCOORD1; + float4 color : COLOR; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + + +// --- Vertex Stage --- +VertexToGeometry VoxelizationVert(AttributesMesh inputMesh) +{ + VertexToGeometry Output; + + UNITY_SETUP_INSTANCE_ID(inputMesh); + + Output.PositionCS = TransformObjectToHClip(inputMesh.positionOS); + float3 PositionWS = TransformObjectToWorld(inputMesh.positionOS); + + // Output uv channels + Output.TextureCoords = float4(inputMesh.uv0, inputMesh.uv1); + + #ifdef PARTIAL_VOXELIZATION + // Transform world position to voxel coordinate + float3 WorldPosition = PositionWS - _VoxelCameraPosActual; + int3 VoxelCoord = AbsoluteWorldPositionToVoxelCoord(WorldPosition); + + // Check if the vertex is behind culling camera + Output.CullingTest = 0; + if ((VoxelCoord[_OffsetAxisIndex] < _CullingTrim.x) * _CullingTrimAxis.x || (VoxelCoord[_OffsetAxisIndex] > _CullingTrim.y + 1) * _CullingTrimAxis.y) + Output.CullingTest = 1; + #endif + + #ifdef UNITY_REVERSED_Z + Output.PositionCS.z = mad(Output.PositionCS.z, -2.0, 1.0); + #endif + + return Output; +} + +// --- Geometry Stage --- +[maxvertexcount(3)] +void VoxelizationGeom(triangle VertexToGeometry i[3], inout TriangleStream Stream) +{ + // If all 3 vertices are behind culling camera - early out + #ifdef PARTIAL_VOXELIZATION + if (i[0].CullingTest + i[1].CullingTest + i[2].CullingTest == 3) + return; + #endif + + float3 Normal = normalize(abs(cross(i[1].PositionCS.xyz - i[0].PositionCS.xyz, i[2].PositionCS.xyz - i[0].PositionCS.xyz))); + + uint Axis = AXIS_Z; + if (Normal.x > Normal.y && Normal.x > Normal.z) + Axis = AXIS_X; + else if (Normal.y > Normal.x && Normal.y > Normal.z) + Axis = AXIS_Y; + + [unroll] + for (int j = 0; j < 3; j++) + { + GeometryToFragment Output; + + Output.PositionCS = float4(SwizzleAxis(i[j].PositionCS.xyz, Axis), 1); + + #ifdef UNITY_UV_STARTS_AT_TOP + Output.PositionCS.y = -Output.PositionCS.y; + #endif + + #ifdef UNITY_REVERSED_Z + Output.PositionCS.z = mad(Output.PositionCS.z, 0.5, 0.5); + #endif + + Output.TextureCoords = i[j].TextureCoords; + Output.Axis = Axis; + + Stream.Append(Output); + } +} + +// --- Fragment Stage --- +float VoxelizationFrag(GeometryToFragment Input) : SV_TARGET +{ + float VoxelRes = _VoxelResolution.x; + + #ifndef PARTIAL_VOXELIZATION + VoxelRes = _VoxelResolution.x * 2; + #endif + + float3 VoxelPos = float3(Input.PositionCS.x, Input.PositionCS.y, Input.PositionCS.z * VoxelRes); + VoxelPos = RestoreAxis(VoxelPos, Input.Axis); + + // Modify Axes for non-cubic bounds + VoxelPos.xyz = VoxelPos.xzy; + VoxelPos.y *= (_VoxelBounds.z / _VoxelBounds.y); + VoxelPos.xz = VoxelRes - VoxelPos.xz; + + // Calculate octants for the first 8 bits + uint3 VoxelPosInt = floor(VoxelPos); + uint BitShift = (1 * (VoxelPosInt.x % 2)) + (2 * (VoxelPosInt.y % 2)) + (4 * (VoxelPosInt.z % 2)); + uint OctantBits = (1 << BitShift) << 24; + int StaticBitFlag = 1 << 23; + + int3 VoxelPosRounded = floor(VoxelPos / 2); + + #ifdef PARTIAL_VOXELIZATION + //Offset by axis + VoxelPosRounded.xyz += _AxisOffset.xyz; + + // Culling trim + if (VoxelPosRounded[_OffsetAxisIndex] < _CullingTrim.x || VoxelPosRounded[_OffsetAxisIndex] > _CullingTrim.y) + return 0.0f; + + //Offset by octant + VoxelPosRounded.xyz += _OctantOffset.xyz; + #endif + + // Fill inout Surface Data with input information + VoxelSurfaceData SurfaceData = (VoxelSurfaceData)0; + SurfaceData.TexCoord0 = Input.TextureCoords.xy; + SurfaceData.TexCoord1 = Input.TextureCoords.zw; + + // Evaluate all material attributes + EvaluateSurfaceColor(SurfaceData); + + if (!SurfaceData.IsEmissive) + SurfaceData.Color = ClampDiffuseColor(SurfaceData.Color); + + if (SurfaceData.Alpha == 1) + OctantBits = 0; + + // Pack color for the last 24 bits + uint PackedColor = PackVoxelColor(SurfaceData.Color, SurfaceData.IsEmissive); + + #ifdef DYNAMIC_VOXELIZATION + uint OriginalValue; + InterlockedCompareExchange(_VoxelColor[VoxelPosRounded], 0, 0, OriginalValue); + + if (((OriginalValue >> 23) & 0x1) != 1) + { + InterlockedOr(_VoxelColor[VoxelPosRounded], OctantBits, OriginalValue); + InterlockedMax(_VoxelColor[VoxelPosRounded], PackedColor | (OriginalValue & 0xFF000000) | OctantBits ); + } + + #else + uint OriginalValue; + InterlockedOr(_VoxelColor[VoxelPosRounded], StaticBitFlag | OctantBits, OriginalValue); + InterlockedMax(_VoxelColor[VoxelPosRounded], StaticBitFlag | PackedColor | (OriginalValue & 0xFF000000) | OctantBits); + #endif + + return 0.0f; +} diff --git a/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesURP.hlsl.meta b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesURP.hlsl.meta new file mode 100644 index 000000000..bc88f023c --- /dev/null +++ b/Assets/External/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesURP.hlsl.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: df06bb88ddf86eb4cbabd1b51a3ee19f +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Resources/HTraceWSGI/_Shared/Includes/VoxelizationStagesURP.hlsl + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box).meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box).meta new file mode 100644 index 000000000..1d6a41bfb --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box).meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0aad67e2166ecbd4495c8d1efa8ea23a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code.meta new file mode 100644 index 000000000..dafec6eb6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d396e9b4068b0640b7b869a0c4f5527 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/DayNightCycle.cs b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/DayNightCycle.cs new file mode 100644 index 000000000..0d62ce0d8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/DayNightCycle.cs @@ -0,0 +1,566 @@ +using UnityEngine; +using UnityEngine.Events; + +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace HTraceWSGI.SampleScene.Code +{ + [ExecuteInEditMode] + public class DayNightCycle : MonoBehaviour + { + [Header("Sun Light Settings")] + [Tooltip("The sun (directional light) to control. If null, will use Light component on this GameObject")] + public Light SunLight; + + [Header("Day/Night Cycle Settings")] + [Tooltip("Duration of a full day cycle in seconds")] + [Range(1f, 300f)] + public float DayDuration = 20f; + + [Range(1f, 5f)] + public float SpeedUpNight = 2f; + + [Tooltip("Current time of day in hours (0 = midnight, 12 = noon, 24 = midnight)")] + [Range(0f, 24f)] + public float CurrentTimeOfDay = 6f; // Start at sunrise + + [Space] + [Tooltip("Should the cycle automatically progress? (Only in Play Mode)")] + public bool AutoProgress = true; + + [Tooltip("Speed multiplier for time progression")] + [Range(0.1f, 5f)] + public float TimeSpeed = 1f; + + [Header("Time Event Settings")] + [Tooltip("Time when midnight event triggers (in hours)")] + [Range(0f, 24f)] + public float MidnightTime = 3f; + + [Tooltip("Time when sunrise event triggers (in hours)")] + [Range(0f, 24f)] + public float SunriseTime = 6f; + + [Tooltip("Time when noon event triggers (in hours)")] + [Range(0f, 24f)] + public float NoonTime = 15f; + + [Tooltip("Time when sunset event triggers (in hours)")] + [Range(0f, 24f)] + public float SunsetTime = 24f; + + [Header("Sun Rotation Settings")] + [Tooltip("Axis around which the sun rotates (usually X for east-west movement)")] + public Vector3 RotationAxis = Vector3.right; + + [Tooltip("Starting rotation offset")] + public Vector3 BaseRotation = new Vector3(16f, 668.47f, -6.23f); + + [Tooltip("How many degrees the sun travels in a full cycle")] + [Range(90f, 360f)] + public float RotationRange = 180f; // Half circle (sunrise to sunset) + + [Tooltip("Offset the sun's path (0 = horizon at noon, positive = higher)")] + [Range(-90f, 90f)] + public float ElevationOffset = 0f; + + [Header("Light Intensity (Lux)")] + [Tooltip("Enable automatic light intensity changes")] + public bool AdjustIntensity = true; + + [Tooltip("Light intensity curve based on time of day (in Lux)")] + public AnimationCurve IntensityCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); + + [Tooltip("Maximum light intensity in Lux")] + [Range(0f, 120000f)] + public float MaxIntensityLux = 120000f; // Typical bright sunlight + + [Header("Light Color & Temperature")] + [Tooltip("Enable automatic light color changes")] + public bool AdjustColor = true; + + [Tooltip("Light color gradient based on time of day")] + public Gradient ColorGradient = new Gradient(); + + [Space] + [Tooltip("Enable automatic color temperature changes")] + public bool AdjustColorTemperature = true; + + [Tooltip("Color temperature curve based on time of day (in Kelvin)")] + public AnimationCurve TemperatureCurve = new AnimationCurve( + new Keyframe(0f, 2000f), // Midnight - warm/reddish + new Keyframe(0.25f, 2500f), // Sunrise - warm orange + new Keyframe(0.5f, 5500f), // Noon - neutral white + new Keyframe(0.75f, 2800f), // Sunset - warm + new Keyframe(1f, 2000f) // Midnight - warm/reddish + ); + + [Tooltip("Minimum color temperature in Kelvin")] + [Range(1000f, 4000f)] + public float MinTemperature = 2000f; + + [Tooltip("Maximum color temperature in Kelvin")] + [Range(4000f, 20000f)] + public float MaxTemperature = 6500f; + + [Header("Time Control Buttons")] + [Space] + public bool SetSunrise = false; + public bool SetNoon = false; + public bool SetSunset = false; + public bool SetMidnight = false; + + [Header("Events")] + public UnityEvent OnSunrise; + public UnityEvent OnNoon; + public UnityEvent OnSunset; + public UnityEvent OnMidnight; + + [Header("Debug")] + [Tooltip("Show debug information")] + public bool ShowDebug = false; + + // Private variables + private float previousTimeOfDay; + private bool hasTriggeredSunrise, hasTriggeredNoon, hasTriggeredSunset, hasTriggeredMidnight; + + void OnEnable() + { + Initialize(); + } + + void Start() + { + Initialize(); + } + + void Initialize() + { + // Get Light component if not assigned + if (SunLight == null) + { + SunLight = GetComponent(); + } + + if (SunLight == null) + { + Debug.LogWarning("DayNightCycle: No Light component found! Please assign SunLight or add Light component to this GameObject."); + return; + } + + // Set light to use color temperature if adjusting temperature + if (AdjustColorTemperature) + { + SunLight.useColorTemperature = true; + } + + // Initialize default gradient if empty + InitializeDefaultGradient(); + + // Set initial state + previousTimeOfDay = CurrentTimeOfDay; + UpdateSun(); + + if (ShowDebug) + { + Debug.Log($"DayNightCycle initialized. Day duration: {DayDuration}s"); + } + } + + private bool IsNight => CurrentTimeOfDay > SunsetTime || CurrentTimeOfDay < SunriseTime; + + void Update() + { + if (SunLight == null) return; + + // Handle button presses + HandleButtonPresses(); + + // Progress time if auto-progress is enabled and in play mode + if (Application.isPlaying && AutoProgress) + { + float speedUpNight = IsNight ? SpeedUpNight : 1f; + CurrentTimeOfDay += (Time.deltaTime / DayDuration) * TimeSpeed * 24f * speedUpNight; + + // Wrap around at 24.0 + if (CurrentTimeOfDay >= 24f) + { + CurrentTimeOfDay -= 24f; + ResetEventFlags(); + } + } + + // Update sun rotation and properties + UpdateSun(); + + // Check for events (only in play mode) + if (Application.isPlaying) + { + CheckTimeEvents(); + } + + previousTimeOfDay = CurrentTimeOfDay; + + // Mark scene as dirty in editor + #if UNITY_EDITOR + if (!Application.isPlaying) + { + EditorUtility.SetDirty(this); + } + #endif + } + + void HandleButtonPresses() + { + if (SetSunrise) + { + SetToSunrise(); + SetSunrise = false; + } + + if (SetNoon) + { + SetToNoon(); + SetNoon = false; + } + + if (SetSunset) + { + SetToSunset(); + SetSunset = false; + } + + if (SetMidnight) + { + SetToMidnight(); + SetMidnight = false; + } + } + + void UpdateSun() + { + if (SunLight == null) return; + + // Convert time of day to normalized value (0-1) + float normalizedTime = CurrentTimeOfDay / 24f; + + // Calculate sun angle based on time of day + float sunAngle = (normalizedTime * RotationRange) - (RotationRange * 0.5f) + ElevationOffset; + + // Create rotation based on the specified axis + Quaternion sunRotation = Quaternion.AngleAxis(sunAngle, RotationAxis.normalized); + + // Apply base rotation and calculated sun rotation + if (SunLight.transform != null) + { + SunLight.transform.rotation = Quaternion.Euler(BaseRotation) * sunRotation; + } + + // Adjust light intensity in Lux + if (AdjustIntensity) + { + float intensityLux = IntensityCurve.Evaluate(normalizedTime) * MaxIntensityLux; + SunLight.intensity = intensityLux; + } + + // Adjust light color + if (AdjustColor) + { + SunLight.color = ColorGradient.Evaluate(normalizedTime); + } + + // Adjust color temperature + if (AdjustColorTemperature) + { + SunLight.useColorTemperature = true; + float temperature = TemperatureCurve.Evaluate(normalizedTime); + temperature = Mathf.Clamp(temperature, MinTemperature, MaxTemperature); + SunLight.colorTemperature = temperature; + } + } + + void CheckTimeEvents() + { + // Check each event with configurable timing + CheckTimeEvent(ref hasTriggeredMidnight, MidnightTime, OnMidnight, "Midnight"); + CheckTimeEvent(ref hasTriggeredSunrise, SunriseTime, OnSunrise, "Sunrise"); + CheckTimeEvent(ref hasTriggeredNoon, NoonTime, OnNoon, "Noon"); + CheckTimeEvent(ref hasTriggeredSunset, SunsetTime, OnSunset, "Sunset"); + } + + void CheckTimeEvent(ref bool hasTriggered, float eventTime, UnityEvent eventToTrigger, string eventName) + { + float tolerance = 0.5f; // Half hour tolerance + + // Handle special case for events at 24:00 (which is the same as 0:00) + float adjustedEventTime = eventTime >= 24f ? 0f : eventTime; + float adjustedCurrentTime = CurrentTimeOfDay; + float adjustedPreviousTime = previousTimeOfDay; + + // Check if we crossed the event time + bool crossedEvent = false; + + if (adjustedEventTime == 0f) // Event at midnight (0:00 or 24:00) + { + // Special handling for midnight crossing + crossedEvent = !hasTriggered && + ((adjustedCurrentTime >= (24f - tolerance) && adjustedPreviousTime < (24f - tolerance)) || + (adjustedCurrentTime <= tolerance && adjustedPreviousTime > (24f - tolerance))); + } + else + { + // Normal event timing + crossedEvent = !hasTriggered && + adjustedCurrentTime >= (adjustedEventTime - tolerance) && + adjustedCurrentTime < (adjustedEventTime + tolerance) && + adjustedPreviousTime < (adjustedEventTime - tolerance); + } + + if (crossedEvent) + { + eventToTrigger.Invoke(); + hasTriggered = true; + if (ShowDebug) Debug.Log($"{eventName} triggered at {GetCurrentTimeString()}!"); + } + } + + void ResetEventFlags() + { + hasTriggeredSunrise = false; + hasTriggeredNoon = false; + hasTriggeredSunset = false; + hasTriggeredMidnight = false; + } + + void InitializeDefaultGradient() + { + if (ColorGradient.colorKeys.Length == 0) + { + GradientColorKey[] colorKeys = new GradientColorKey[5]; + colorKeys[0] = new GradientColorKey(new Color(0.2f, 0.2f, 0.4f), 0f); // Midnight - dark blue + colorKeys[1] = new GradientColorKey(new Color(1f, 0.6f, 0.3f), 0.25f); // Sunrise - orange + colorKeys[2] = new GradientColorKey(new Color(1f, 1f, 0.9f), 0.5f); // Noon - bright white + colorKeys[3] = new GradientColorKey(new Color(1f, 0.4f, 0.2f), 0.75f); // Sunset - red + colorKeys[4] = new GradientColorKey(new Color(0.2f, 0.2f, 0.4f), 1f); // Midnight - dark blue + + GradientAlphaKey[] alphaKeys = new GradientAlphaKey[2]; + alphaKeys[0] = new GradientAlphaKey(1f, 0f); + alphaKeys[1] = new GradientAlphaKey(1f, 1f); + + ColorGradient.SetKeys(colorKeys, alphaKeys); + } + } + + // Public methods for external control + public void SetTimeOfDay(float hours) + { + CurrentTimeOfDay = Mathf.Clamp(hours, 0f, 24f); + if (CurrentTimeOfDay == 24f) CurrentTimeOfDay = 0f; + UpdateSun(); + } + + public void SetToSunrise() + { + SetTimeOfDay(SunriseTime); + } + + public void SetToNoon() + { + SetTimeOfDay(NoonTime); + } + + public void SetToSunset() + { + SetTimeOfDay(SunsetTime >= 24f ? 0f : SunsetTime); + } + + public void SetToMidnight() + { + SetTimeOfDay(MidnightTime); + } + + public void PauseTime() + { + AutoProgress = false; + } + + public void ResumeTime() + { + AutoProgress = true; + } + + public string GetCurrentTimeString() + { + int hours = Mathf.FloorToInt(CurrentTimeOfDay); + int minutes = Mathf.FloorToInt((CurrentTimeOfDay - hours) * 60f); + return $"{hours:00}:{minutes:00}"; + } + + public float GetCurrentTemperature() + { + float normalizedTime = CurrentTimeOfDay / 24f; + return TemperatureCurve.Evaluate(normalizedTime); + } + + public float GetCurrentIntensityLux() + { + float normalizedTime = CurrentTimeOfDay / 24f; + return IntensityCurve.Evaluate(normalizedTime) * MaxIntensityLux; + } + + // Debug visualization + void OnDrawGizmosSelected() + { + if (SunLight == null) return; + + // Draw sun path + Gizmos.color = Color.yellow; + Vector3 center = transform.position; + float radius = 10f; + Quaternion baseRot = Quaternion.Euler(BaseRotation); + + for (int i = 0; i < 36; i++) + { + float normalizedTime1 = i / 36f; + float normalizedTime2 = (i + 1) / 36f; + + float angle1 = (normalizedTime1 * RotationRange) - (RotationRange * 0.5f) + ElevationOffset; + float angle2 = (normalizedTime2 * RotationRange) - (RotationRange * 0.5f) + ElevationOffset; + + Quaternion sunRotation1 = Quaternion.AngleAxis(angle1, RotationAxis.normalized); + Quaternion sunRotation2 = Quaternion.AngleAxis(angle2, RotationAxis.normalized); + + Vector3 point1 = center + (baseRot * sunRotation1) * Vector3.forward * radius; + Vector3 point2 = center + (baseRot * sunRotation2) * Vector3.forward * radius; + + Gizmos.DrawLine(point1, point2); + } + + // Draw current sun position + Gizmos.color = Color.red; + float normalizedTime = CurrentTimeOfDay / 24f; + float currentAngle = (normalizedTime * RotationRange) - (RotationRange * 0.5f) + ElevationOffset; + Quaternion currentSunRotation = Quaternion.AngleAxis(currentAngle, RotationAxis.normalized); + Vector3 currentPos = center + (baseRot * currentSunRotation) * Vector3.forward * radius; + Gizmos.DrawWireSphere(currentPos, 0.5f); + + // Draw event time markers + DrawEventMarker(center, radius, MidnightTime, Color.blue, "M"); + DrawEventMarker(center, radius, SunriseTime, Color.yellow, "SR"); + DrawEventMarker(center, radius, NoonTime, Color.white, "N"); + DrawEventMarker(center, radius, SunsetTime, Color.red, "SS"); + + // Draw time labels + Gizmos.color = Color.white; + Vector3 labelOffset = Vector3.up * 2f; + + #if UNITY_EDITOR + string timeInfo = $"{GetCurrentTimeString()}\n{GetCurrentIntensityLux():F0} Lux\n{GetCurrentTemperature():F0}K"; + UnityEditor.Handles.Label(currentPos + labelOffset, timeInfo); + #endif + } + + void DrawEventMarker(Vector3 center, float radius, float eventTime, Color color, string label) + { + Gizmos.color = color; + float eventNormalized = (eventTime >= 24f ? 0f : eventTime) / 24f; + float eventAngle = (eventNormalized * RotationRange) - (RotationRange * 0.5f) + ElevationOffset; + + // Apply base rotation to the event marker position + Quaternion baseRot = Quaternion.Euler(BaseRotation); + Quaternion eventRotation = Quaternion.AngleAxis(eventAngle, RotationAxis.normalized); + Vector3 eventPos = center + (baseRot * eventRotation) * Vector3.forward * radius; + + Gizmos.DrawWireCube(eventPos, Vector3.one * 0.5f); + + #if UNITY_EDITOR + UnityEditor.Handles.Label(eventPos + Vector3.up * 0.5f, label); + #endif + } + + // Custom inspector validation + void OnValidate() + { + // Get Light component if not assigned + if (SunLight == null) + { + SunLight = GetComponent(); + } + + // Clamp current time of day + CurrentTimeOfDay = Mathf.Clamp(CurrentTimeOfDay, 0f, 24f); + if (CurrentTimeOfDay == 24f) CurrentTimeOfDay = 0f; + + // Clamp event times + MidnightTime = Mathf.Clamp(MidnightTime, 0f, 24f); + SunriseTime = Mathf.Clamp(SunriseTime, 0f, 24f); + NoonTime = Mathf.Clamp(NoonTime, 0f, 24f); + SunsetTime = Mathf.Clamp(SunsetTime, 0f, 24f); + + // Clamp temperature values + MinTemperature = Mathf.Clamp(MinTemperature, 1000f, 4000f); + MaxTemperature = Mathf.Clamp(MaxTemperature, 4000f, 20000f); + if (MinTemperature >= MaxTemperature) + { + MaxTemperature = MinTemperature + 1000f; + } + + if (SunLight != null) + { + UpdateSun(); + } + } + } + + // Custom Editor for better inspector experience + #if UNITY_EDITOR + [CustomEditor(typeof(DayNightCycle))] + public class DayNightCycleEditor : UnityEditor.Editor + { + public override void OnInspectorGUI() + { + DayNightCycle dayNight = (DayNightCycle)target; + + DrawDefaultInspector(); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Quick Time Controls", EditorStyles.boldLabel); + + EditorGUILayout.BeginHorizontal(); + if (GUILayout.Button($"Sunrise ({dayNight.SunriseTime:F0}:00)")) + { + dayNight.SetToSunrise(); + } + if (GUILayout.Button($"Noon ({dayNight.NoonTime:F0}:00)")) + { + dayNight.SetToNoon(); + } + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.BeginHorizontal(); + if (GUILayout.Button($"Sunset ({(dayNight.SunsetTime >= 24f ? 0 : dayNight.SunsetTime):F0}:00)")) + { + dayNight.SetToSunset(); + } + if (GUILayout.Button($"Midnight ({dayNight.MidnightTime:F0}:00)")) + { + dayNight.SetToMidnight(); + } + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Current Status", EditorStyles.boldLabel); + EditorGUILayout.LabelField($"Time: {dayNight.GetCurrentTimeString()}"); + EditorGUILayout.LabelField($"Intensity: {dayNight.GetCurrentIntensityLux():F0} Lux"); + EditorGUILayout.LabelField($"Temperature: {dayNight.GetCurrentTemperature():F0} K"); + + if (GUI.changed) + { + EditorUtility.SetDirty(target); + } + } + } + #endif +} diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/DayNightCycle.cs.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/DayNightCycle.cs.meta new file mode 100644 index 000000000..ed6c6812d --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/DayNightCycle.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a0c4d6c459d84433af5ba5ab4f855590 +timeCreated: 1757268238 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/Code/DayNightCycle.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/GameManager.cs b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/GameManager.cs new file mode 100644 index 000000000..3624a1b6f --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/GameManager.cs @@ -0,0 +1,245 @@ +//pipelinedefine +#define H_URP + +using System.Collections; +using HTraceWSGI.SampleScene.Code; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; +using UnityEngine.Rendering; + +public class GameManager : MonoBehaviour +{ + public HTraceWSGI.Scripts.HTraceWSGI HTraceWsgi; + public DayNightCycle DayNightCycle; + public Volume Volume; + public GameObject InstancingExample; + public Light[] Lights; + + [Space] + public float MaxLightIntensity = 10000; + public float MinSkyExposure = 7; + public float MaxSkyExposure = 11; + public float MinExposure = 7; + public float MaxExposure = 11.5f; + + [Header("UI Settings")] + [SerializeField] private bool showInstancingButton = true; + [SerializeField] private bool defaultButtonStyle = true; + [SerializeField] private GUIStyle buttonStyle; + + public System.Action OnInstancingEnabled; + public System.Action OnInstancingDisabled; + + private bool _instancingEnabledButton = false; + + private void Start() + { + Initialize(); + } + + private void Initialize() + { + DayNightCycle.AutoProgress = true; + DayNightCycle.CurrentTimeOfDay = 9; + StartCoroutine(ChangeVolumeProfile(true, 0.1f)); + } + + public void SetVolumeProfile(bool isDay) + { + StartCoroutine(ChangeVolumeProfile(isDay, 2)); + } + + private IEnumerator ChangeVolumeProfile(bool isDay, float timeInSeconds) + { + yield return null; + } + + public void IsEnableLights(bool isActive) + { + StartCoroutine(ChangeLightIntensity(isActive, 1)); + } + + private IEnumerator ChangeLightIntensity(bool isActive, float timeInSeconds) + { + if (Lights == null || Lights.Length == 0) yield break; + + float from = Lights[0].intensity; + float to = isActive ? MaxLightIntensity : 0f; + + foreach (var lightElem in Lights) + { + lightElem.gameObject.SetActive(true); + lightElem.intensity = from; + } + + float elapsed = 0f; + while (elapsed < timeInSeconds) + { + elapsed += Time.deltaTime; + float t = Mathf.Clamp01(elapsed / timeInSeconds); + foreach (var lightElem in Lights) + { + lightElem.intensity = Mathf.Lerp(from, to, t); + } + yield return null; + } + + if (!isActive) + { + foreach (var lightElem in Lights) + { + lightElem.gameObject.SetActive(false); + } + } + } + + // --- Day/Night/Auto dropdown --- + private int _selectedModeIndex = 2; // 0 = Day, 1 = Night, 2 = Auto + private int _prevSelectedModeIndex = 2; + private readonly string[] _modes = { "Day", "Night", "Auto" }; + + private void OnGUI() + { + if (!showInstancingButton) return; + + if (buttonStyle == null || defaultButtonStyle) + { + buttonStyle = new GUIStyle(GUI.skin.button) + { + fontSize = 16, + padding = new RectOffset(10, 10, 5, 5) + }; + } + + float buttonWidth = 300f; + float buttonHeight = 40f; + float margin = 10f; + + // Instancing toggle button + Rect buttonRect = new Rect( + margin, + Screen.height - buttonHeight - margin, + buttonWidth, + buttonHeight + ); + + string buttonText = _instancingEnabledButton ? "Disable Instancing Example" : "Enable Instancing Example"; + if (GUI.Button(buttonRect, buttonText, buttonStyle)) + { + ToggleInstancing(); + } + + // Day/Night/Auto dropdown + Rect dropdownRect = new Rect( + margin, + Screen.height - (buttonHeight * 2) - margin * 2, + buttonWidth, + buttonHeight + ); + + _prevSelectedModeIndex = _selectedModeIndex; + _selectedModeIndex = GUI.SelectionGrid(dropdownRect, _selectedModeIndex, _modes, 3, buttonStyle); + + if (_selectedModeIndex != _prevSelectedModeIndex) + { + StopAllCoroutines(); + + switch (_selectedModeIndex) + { + case 0: // Day + DayNightCycle.AutoProgress = false; + DayNightCycle.CurrentTimeOfDay = 10; + StartCoroutine(ChangeVolumeProfile(true, 0.25f)); + StartCoroutine(ChangeLightIntensity(false, 0.5f)); + break; + + case 1: // Night + DayNightCycle.AutoProgress = false; + DayNightCycle.CurrentTimeOfDay = 0; + StartCoroutine(ChangeVolumeProfile(false, 0.25f)); + StartCoroutine(ChangeLightIntensity(true, 0.5f)); + break; + + case 2: // Auto + DayNightCycle.AutoProgress = true; + + if (_prevSelectedModeIndex == 0) + { + StartCoroutine(ChangeVolumeProfile(false, 0.5f)); + StartCoroutine(ChangeLightIntensity(true, 0.5f)); + } + else if (_prevSelectedModeIndex == 1) + { + StartCoroutine(ChangeVolumeProfile(true, 0.5f)); + StartCoroutine(ChangeLightIntensity(false, 0.5f)); + } + break; + } + } + } + + // --- Instancing logic --- + public void ToggleInstancing() + { + _instancingEnabledButton = !_instancingEnabledButton; + + if (_instancingEnabledButton) + EnableInstancing(); + else + DisableInstancing(); + } + + public void EnableInstancing() + { + _instancingEnabledButton = true; + OnInstancingEnabled?.Invoke(); + HandleInstancingEnabled(); + } + + public void DisableInstancing() + { + _instancingEnabledButton = false; + OnInstancingDisabled?.Invoke(); + HandleInstancingDisabled(); + } + + private void HandleInstancingEnabled() + { + HTraceWsgi.VoxelizationSettings.VoxelizationUpdateMode = VoxelizationUpdateMode.Constant; + InstancingExample.SetActive(true); + } + + private void HandleInstancingDisabled() + { + InstancingExample.SetActive(false); + } + + public void ShowInstancingButton(bool show) + { + showInstancingButton = show; + } + + public bool IsInstancingEnabled() + { + return _instancingEnabledButton; + } + + public void SetButtonStyle(GUIStyle newStyle) + { + buttonStyle = newStyle; + } + + private void OnEnable() + { + OnInstancingEnabled += HandleCustomInstancingLogic; + OnInstancingDisabled += HandleCustomInstancingLogic; + } + + private void OnDisable() + { + OnInstancingEnabled -= HandleCustomInstancingLogic; + OnInstancingDisabled -= HandleCustomInstancingLogic; + } + + private void HandleCustomInstancingLogic() { } +} diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/GameManager.cs.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/GameManager.cs.meta new file mode 100644 index 000000000..0a358b50d --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/GameManager.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1a676563920f4f54e8e8128607b72f10 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/Code/GameManager.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/InstancingScriptTest.cs b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/InstancingScriptTest.cs new file mode 100644 index 000000000..19a77944d --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/InstancingScriptTest.cs @@ -0,0 +1,48 @@ + +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; + +public class InstancingScriptTest : MonoBehaviour +{ + public Material StandardMaterial; + + [Space] + public Mesh Mesh; + public float ObjectScale = 0.16f; + + [Space] + [Range(0,5)] + public float SpeedRadial = 1f; + [Range(0.1f,20f)] + public float Radius = 1f; + [Range(10,50)] + public int ObjectCount = 10; + + private readonly List _matrices = new List(); + + private void Update() + { + GenerateInstanceAnimatedMatrix(transform.position, in _matrices); + RenderParams rp1 = new RenderParams(StandardMaterial) { shadowCastingMode = ShadowCastingMode.On }; + Graphics.RenderMeshInstanced(rp1, Mesh, 0, _matrices); + } + + private void GenerateInstanceAnimatedMatrix(in Vector3 origin, in List matrices) + { + Matrix4x4 m = Matrix4x4.identity; + Vector3 pos = Vector3.zero; + + matrices.Clear(); + + for (int i = 0; i < ObjectCount; i++) + { + float angle = 2 * Mathf.PI * i / ObjectCount + Time.time * SpeedRadial; + pos.x = Radius * Mathf.Cos(angle); + pos.y = 0; + pos.z = Radius * Mathf.Sin(angle); + m.SetTRS(pos + origin, Quaternion.identity, Vector3.one * ObjectScale); + matrices.Add(m); + } + } +} diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/InstancingScriptTest.cs.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/InstancingScriptTest.cs.meta new file mode 100644 index 000000000..490b05f05 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/Code/InstancingScriptTest.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a9719aaf59a2489b9f992c102544b375 +timeCreated: 1733153102 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/Code/InstancingScriptTest.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP.meta new file mode 100644 index 000000000..dd6744715 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f560b21a3e303cd41a5eaf9b25c8c011 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP Volume Profile.asset b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP Volume Profile.asset new file mode 100644 index 000000000..786be36c4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP Volume Profile.asset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb3a5db8ddf5639388b662ea49e45feb74264ed6f686ad7f2c17237ce985419d +size 4002 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP Volume Profile.asset.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP Volume Profile.asset.meta new file mode 100644 index 000000000..462f4317e --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP Volume Profile.asset.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 418ddc786d4aedf4a9dc4e7200f09fa1 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP Volume + Profile.asset + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.meta new file mode 100644 index 000000000..cd7a6b12e --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fed067101324fe8428c8e572b4ca4aaa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.unity b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.unity new file mode 100644 index 000000000..4f7a2999c --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.unity @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb60ec5e8e7592cd27756ee55d0b6a9436389cbf1400a91708d9315eb3146a1e +size 58342 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.unity.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.unity.meta new file mode 100644 index 000000000..9f19bbead --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.unity.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: fd8af425016ce094e86ee988234ac399 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Cornell Box URP.unity + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials.meta new file mode 100644 index 000000000..4b332842f --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 574db54e26c9405449457aea027b96a3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Red.mat b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Red.mat new file mode 100644 index 000000000..08d860933 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Red.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Cornell Box Red + 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: -1 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 0, b: 0, a: 1} + - _Color: {r: 1, g: 0, b: 0, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &1725795980273820036 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Red.mat.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Red.mat.meta new file mode 100644 index 000000000..d0aecce8c --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Red.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 162125acec8699c40a16c91c76852a6c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box + Red.mat + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box White.mat b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box White.mat new file mode 100644 index 000000000..745c07d2b --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box White.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5255653457723613513 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Cornell Box White + 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: -1 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 0.93962264, g: 0.93962264, b: 0.93962264, a: 1} + - _Color: {r: 0.93962264, g: 0.93962264, b: 0.93962264, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box White.mat.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box White.mat.meta new file mode 100644 index 000000000..c2ff0ffb9 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box White.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: dd7b2b9ef81b86a46afce316a4dabfa3 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box + White.mat + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Yellow.mat b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Yellow.mat new file mode 100644 index 000000000..8ccdc4587 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Yellow.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Cornell Box Yellow + 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: -1 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 0.9924528, g: 0.75916755, b: 0, a: 1} + - _Color: {r: 0.9924528, g: 0.75916755, b: 0, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &452129208771830827 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Yellow.mat.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Yellow.mat.meta new file mode 100644 index 000000000..5e26194c6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box Yellow.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 4dc4f436cea016c4593a22eb2ba327f0 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Cornell Box + Yellow.mat + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Spheres Instanced.mat b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Spheres Instanced.mat new file mode 100644 index 000000000..b1d29c849 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Spheres Instanced.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Spheres Instanced + m_Shader: {fileID: 4800000, guid: 933532a4fcc9baf4fa0491de14d08ed7, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 1 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 0.19433957, g: 0.9620595, b: 1, a: 1} + - _Color: {r: 0.19433954, g: 0.96205944, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &6809873958124219606 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Spheres Instanced.mat.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Spheres Instanced.mat.meta new file mode 100644 index 000000000..d671f79bd --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Spheres Instanced.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: c40d77c8aa2a69d40ac1683c79bb9e27 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Materials/Spheres Instanced.mat + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain.meta new file mode 100644 index 000000000..b2c6d2c65 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c668b19b319cde84895e6ab53a069a28 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers.meta new file mode 100644 index 000000000..ba5b5e722 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 94aa0fb390379684eb47efe490497c25 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerGrass.png b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerGrass.png new file mode 100644 index 000000000..685627244 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerGrass.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47bd30264d2c8339151abc3327abdf050c5a36fa40b92021a97bd65bbcde0abb +size 59189 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerGrass.png.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerGrass.png.meta new file mode 100644 index 000000000..40fbe72a0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerGrass.png.meta @@ -0,0 +1,131 @@ +fileFormatVersion: 2 +guid: 2ac79a337739796468e30da516f2bfe2 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerGrass.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerSoil.png b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerSoil.png new file mode 100644 index 000000000..dc2f2896f --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerSoil.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d6de5328303c57b2c0ee441418cea384b5eac64be35f8bb38fa0ece1377f090 +size 58819 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerSoil.png.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerSoil.png.meta new file mode 100644 index 000000000..f3da65e63 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerSoil.png.meta @@ -0,0 +1,131 @@ +fileFormatVersion: 2 +guid: 844ea7f7214592344a376ffe13343b4d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerSoil.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerStone.png b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerStone.png new file mode 100644 index 000000000..2914fe57b --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerStone.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b53bc2930b94edec6d5e7d4bb47055d1b1f126442237cf37b38e80dfbef00ba +size 58993 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerStone.png.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerStone.png.meta new file mode 100644 index 000000000..2a1673c66 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerStone.png.meta @@ -0,0 +1,131 @@ +fileFormatVersion: 2 +guid: df43119a95d565b46b567600c329917f +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 1024 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/CheckerStone.png + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerGrass.terrainlayer b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerGrass.terrainlayer new file mode 100644 index 000000000..5be5f3611 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerGrass.terrainlayer @@ -0,0 +1,23 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1953259897 &8574412962073106934 +TerrainLayer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: LayerGrass + m_DiffuseTexture: {fileID: 2800000, guid: 292967087c7a484459b4b0997950da5e, type: 3} + m_NormalMapTexture: {fileID: 0} + m_MaskMapTexture: {fileID: 0} + m_TileSize: {x: 3, y: 3} + m_TileOffset: {x: 0, y: 0} + m_Specular: {r: 0, g: 0, b: 0, a: 0} + m_Metallic: 0 + m_Smoothness: 0 + m_NormalScale: 1 + m_DiffuseRemapMin: {x: 0, y: 0, z: 0, w: 0} + m_DiffuseRemapMax: {x: 1, y: 1, z: 1, w: 1} + m_MaskMapRemapMin: {x: 0, y: 0, z: 0, w: 0} + m_MaskMapRemapMax: {x: 1, y: 1, z: 1, w: 1} + m_SmoothnessSource: 1 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerGrass.terrainlayer.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerGrass.terrainlayer.meta new file mode 100644 index 000000000..4beac10c2 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerGrass.terrainlayer.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: a768d746c83893445b428a214778b973 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 8574412962073106934 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerGrass.terrainlayer + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerSoil.terrainlayer b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerSoil.terrainlayer new file mode 100644 index 000000000..a90ad9ebf --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerSoil.terrainlayer @@ -0,0 +1,22 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1953259897 &8574412962073106934 +TerrainLayer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: LayerSoil + m_DiffuseTexture: {fileID: 2800000, guid: 13611e9ddb7978d43807d86682a85448, type: 3} + m_NormalMapTexture: {fileID: 0} + m_MaskMapTexture: {fileID: 0} + m_TileSize: {x: 3, y: 3} + m_TileOffset: {x: 0, y: 0} + m_Specular: {r: 0, g: 0, b: 0, a: 0} + m_Metallic: 0 + m_Smoothness: 0 + m_NormalScale: 1 + m_DiffuseRemapMin: {x: 0, y: 0, z: 0, w: 0} + m_DiffuseRemapMax: {x: 1, y: 1, z: 1, w: 1} + m_MaskMapRemapMin: {x: 0, y: 0, z: 0, w: 0} + m_MaskMapRemapMax: {x: 1, y: 1, z: 1, w: 1} diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerSoil.terrainlayer.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerSoil.terrainlayer.meta new file mode 100644 index 000000000..144109b8b --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerSoil.terrainlayer.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: b810dd993e83b364193c5871f26fd2ca +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 8574412962073106934 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerSoil.terrainlayer + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerStone.terrainlayer b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerStone.terrainlayer new file mode 100644 index 000000000..29c1868b3 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerStone.terrainlayer @@ -0,0 +1,22 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1953259897 &8574412962073106934 +TerrainLayer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: LayerStone + m_DiffuseTexture: {fileID: 2800000, guid: 1a3b2b7aaed99594fb313d0cfd91c018, type: 3} + m_NormalMapTexture: {fileID: 0} + m_MaskMapTexture: {fileID: 0} + m_TileSize: {x: 3, y: 3} + m_TileOffset: {x: 0, y: 0} + m_Specular: {r: 0, g: 0, b: 0, a: 0} + m_Metallic: 0 + m_Smoothness: 0 + m_NormalScale: 1 + m_DiffuseRemapMin: {x: 0, y: 0, z: 0, w: 0} + m_DiffuseRemapMax: {x: 1, y: 1, z: 1, w: 1} + m_MaskMapRemapMin: {x: 0, y: 0, z: 0, w: 0} + m_MaskMapRemapMax: {x: 1, y: 1, z: 1, w: 1} diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerStone.terrainlayer.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerStone.terrainlayer.meta new file mode 100644 index 000000000..476c4e126 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerStone.terrainlayer.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 4ded06777bc5c3d4ab7648289edb2cb2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 8574412962073106934 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Layers/LayerStone.terrainlayer + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock.meta new file mode 100644 index 000000000..74a5f9849 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a0c80635e317ca94ca96e323fad46ae0 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock License.txt b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock License.txt new file mode 100644 index 000000000..eb3fc1b72 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock License.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfaa6b5638deac3ecbf3c882e2fcfe14d04e2f3c5e98b56217ea518b988d5180 +size 208 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock License.txt.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock License.txt.meta new file mode 100644 index 000000000..3c88145c7 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock License.txt.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 2981403a18b060942a56033e56835d32 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock License.txt + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock Material.mat b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock Material.mat new file mode 100644 index 000000000..951bca9de --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock Material.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Rock Material + 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: -1 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 0.2905661, g: 0.2905661, b: 0.2905661, a: 1} + - _Color: {r: 0.29056606, g: 0.29056606, b: 0.29056606, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 +--- !u!114 &2430883201690306553 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock Material.mat.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock Material.mat.meta new file mode 100644 index 000000000..1450b3725 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock Material.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 1a0eaf311a6a28e4c99bf5b4066599fe +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock Material.mat + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock.fbx b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock.fbx new file mode 100644 index 000000000..8b59040d1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1e75cb07b953037a5a6778dd459d5bc7a5ab671f6ba88edb9c35a8c5913fa44 +size 27980 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock.fbx.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock.fbx.meta new file mode 100644 index 000000000..5236af669 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock.fbx.meta @@ -0,0 +1,115 @@ +fileFormatVersion: 2 +guid: c51baff93bd26104eb81647eb9923342 +ModelImporter: + serializedVersion: 22200 + internalIDToNameTable: [] + externalObjects: {} + materials: + materialImportMode: 2 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + removeConstantScaleCurves: 0 + motionNodeName: + rigImportErrors: + rigImportWarnings: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 1 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 0 + meshes: + lODScreenPercentages: [] + globalScale: 100 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importVisibility: 1 + importBlendShapes: 1 + importCameras: 1 + importLights: 1 + nodeNameCollisionStrategy: 1 + fileIdsGeneration: 2 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + bakeAxisConversion: 0 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + optimizeBones: 1 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVMarginMethod: 1 + secondaryUVMinLightmapResolution: 40 + secondaryUVMinObjectScale: 1 + secondaryUVPackMargin: 4 + useFileScale: 1 + strictVertexDataChecks: 0 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 1 + humanDescription: + serializedVersion: 3 + human: [] + skeleton: [] + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 0 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 2 + humanoidOversampling: 1 + avatarSetup: 0 + addHumanoidExtraRootOnlyWhenUsingAvatar: 1 + importBlendShapeDeformPercent: 1 + remapMaterialsIfMaterialImportModeIsNone: 0 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/Rock.fbx + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/RockPrefab.prefab b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/RockPrefab.prefab new file mode 100644 index 000000000..0954a1be9 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/RockPrefab.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a2922592f7399c05e5c0b888b472244eb61c9004809e84ae3bb80725874dc70 +size 2692 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/RockPrefab.prefab.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/RockPrefab.prefab.meta new file mode 100644 index 000000000..e217e120f --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/RockPrefab.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 211c7bca12efbdc4e9598db4b6140f86 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Rock/RockPrefab.prefab + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Terrain.asset b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Terrain.asset new file mode 100644 index 000000000..1df570a78 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Terrain.asset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2a74c5b42aaaee18c23cc435d79126fb0c72d3285f2bffc2d634732c3cc0a47 +size 1422524 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Terrain.asset.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Terrain.asset.meta new file mode 100644 index 000000000..734b0b827 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Terrain.asset.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 15ede586730977a428c49034a3a266df +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 15600000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Terrain.asset + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/TerrainLitURP.mat b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/TerrainLitURP.mat new file mode 100644 index 000000000..927ecfa5e --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/TerrainLitURP.mat @@ -0,0 +1,204 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-8178403490727112842 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: TerrainLitURP + m_Shader: {fileID: 4800000, guid: 69c1f799e772cb6438f56c23efccb782, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Control: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Mask0: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Mask1: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Mask2: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Mask3: + 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} + - _Normal0: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Normal1: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Normal2: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Normal3: + 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} + - _Splat0: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Splat1: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Splat2: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _Splat3: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _TerrainHolesTexture: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnableHeightBlend: 0 + - _EnableInstancedPerPixelNormal: 1 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _HeightTransition: 0 + - _Metallic: 0 + - _Metallic0: 0 + - _Metallic1: 0 + - _Metallic2: 0 + - _Metallic3: 0 + - _NumLayersCount: 1 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0.5 + - _Smoothness0: 0.5 + - _Smoothness1: 0.5 + - _Smoothness2: 0.5 + - _Smoothness3: 0.5 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/TerrainLitURP.mat.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/TerrainLitURP.mat.meta new file mode 100644 index 000000000..23bbdc59d --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/TerrainLitURP.mat.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 60f569983c2dc984f841d9492b0e5e0e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/TerrainLitURP.mat + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees.meta new file mode 100644 index 000000000..cd67d66f9 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 21696f7c69544ff40954dadd04aa6f21 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Leaves.mat b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Leaves.mat new file mode 100644 index 000000000..3e65e4885 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Leaves.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-5281494130976717201 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Tree Leaves + 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: 1 + m_CustomRenderQueue: 2000 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 0 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 0.36216548, g: 0.4566037, b: 0.16110356, a: 1} + - _Color: {r: 0.36216545, g: 0.45660365, b: 0.16110352, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Leaves.mat.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Leaves.mat.meta new file mode 100644 index 000000000..3e9faa59f --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Leaves.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: bf6854f62c96f60498d9dd359c496f43 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree + Leaves.mat + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree License.txt b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree License.txt new file mode 100644 index 000000000..93e7641c3 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree License.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:037c8b3f495abc6fb95edd818e817eedc731a9bf0a76579d126dce2b75f72116 +size 145 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree License.txt.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree License.txt.meta new file mode 100644 index 000000000..2eaf3f120 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree License.txt.meta @@ -0,0 +1,15 @@ +fileFormatVersion: 2 +guid: 37270995fcac9a14895c3a1a7bf5fff8 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree + License.txt + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Trank.mat b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Trank.mat new file mode 100644 index 000000000..4e04c8d35 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Trank.mat @@ -0,0 +1,137 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-6688059995637908947 +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: Unity.RenderPipelines.Universal.Editor::UnityEditor.Rendering.Universal.AssetVersion + version: 10 +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Tree Trank + 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: -1 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: + - MOTIONVECTORS + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _AddPrecomputedVelocity: 0 + - _AlphaClip: 0 + - _AlphaToMask: 0 + - _Blend: 0 + - _BlendModePreserveSpecular: 1 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _DstBlendAlpha: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 1 + - _Smoothness: 0 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _SrcBlendAlpha: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _XRMotionVectorsPass: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 0.5471698, g: 0.32504824, b: 0.18066922, a: 1} + - _Color: {r: 0.5471698, g: 0.3250482, b: 0.18066919, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] + m_AllowLocking: 1 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Trank.mat.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Trank.mat.meta new file mode 100644 index 000000000..f7699d613 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree Trank.mat.meta @@ -0,0 +1,16 @@ +fileFormatVersion: 2 +guid: 91eb3ab7739b6cf43b3b4c64e47a3dbc +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree + Trank.mat + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree.fbx b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree.fbx new file mode 100644 index 000000000..26adbd83a --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a67882b1b76bcd033d2baf8126b92c477eaec566cfa47c7099e584fcf392afb +size 91888 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree.fbx.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree.fbx.meta new file mode 100644 index 000000000..342637c39 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree.fbx.meta @@ -0,0 +1,125 @@ +fileFormatVersion: 2 +guid: 037f432443e31f44cbf2e1d8d1dd61a4 +ModelImporter: + serializedVersion: 22200 + internalIDToNameTable: [] + externalObjects: + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Material #47 + second: {fileID: 2100000, guid: ed792773cb24bad4bb7a6f8692c86cfa, type: 2} + - first: + type: UnityEngine:Material + assembly: UnityEngine.CoreModule + name: Material #59 + second: {fileID: 2100000, guid: 29ad4c01a2e822c4d969e07c791cc6d1, type: 2} + materials: + materialImportMode: 2 + materialName: 0 + materialSearch: 1 + materialLocation: 1 + animations: + legacyGenerateAnimations: 4 + bakeSimulation: 0 + resampleCurves: 1 + optimizeGameObjects: 0 + removeConstantScaleCurves: 0 + motionNodeName: + rigImportErrors: + rigImportWarnings: + animationImportErrors: + animationImportWarnings: + animationRetargetingWarnings: + animationDoRetargetingWarnings: 0 + importAnimatedCustomProperties: 0 + importConstraints: 0 + animationCompression: 1 + animationRotationError: 0.5 + animationPositionError: 0.5 + animationScaleError: 0.5 + animationWrapMode: 0 + extraExposedTransformPaths: [] + extraUserProperties: [] + clipAnimations: [] + isReadable: 1 + meshes: + lODScreenPercentages: [] + globalScale: 1.85 + meshCompression: 0 + addColliders: 0 + useSRGBMaterialColor: 1 + sortHierarchyByName: 1 + importVisibility: 1 + importBlendShapes: 0 + importCameras: 0 + importLights: 0 + nodeNameCollisionStrategy: 1 + fileIdsGeneration: 2 + swapUVChannels: 0 + generateSecondaryUV: 0 + useFileUnits: 1 + keepQuads: 0 + weldVertices: 1 + bakeAxisConversion: 1 + preserveHierarchy: 0 + skinWeightsMode: 0 + maxBonesPerVertex: 4 + minBoneWeight: 0.001 + optimizeBones: 1 + meshOptimizationFlags: -1 + indexFormat: 0 + secondaryUVAngleDistortion: 8 + secondaryUVAreaDistortion: 15.000001 + secondaryUVHardAngle: 88 + secondaryUVMarginMethod: 1 + secondaryUVMinLightmapResolution: 40 + secondaryUVMinObjectScale: 1 + secondaryUVPackMargin: 4 + useFileScale: 0 + strictVertexDataChecks: 0 + tangentSpace: + normalSmoothAngle: 60 + normalImportMode: 0 + tangentImportMode: 3 + normalCalculationMode: 4 + legacyComputeAllNormalsFromSmoothingGroupsWhenMeshHasBlendShapes: 0 + blendShapeNormalImportMode: 1 + normalSmoothingSource: 0 + referencedClips: [] + importAnimation: 0 + humanDescription: + serializedVersion: 3 + human: [] + skeleton: [] + armTwist: 0.5 + foreArmTwist: 0.5 + upperLegTwist: 0.5 + legTwist: 0.5 + armStretch: 0.05 + legStretch: 0.05 + feetSpacing: 0 + globalScale: 1.85 + rootMotionBoneName: + hasTranslationDoF: 0 + hasExtraRoot: 0 + skeletonHasParents: 1 + lastHumanDescriptionAvatarSource: {instanceID: 0} + autoGenerateAvatarMappingIfUnspecified: 1 + animationType: 0 + humanoidOversampling: 1 + avatarSetup: 0 + addHumanoidExtraRootOnlyWhenUsingAvatar: 1 + importBlendShapeDeformPercent: 1 + remapMaterialsIfMaterialImportModeIsNone: 0 + additionalBone: 0 + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/Tree.fbx + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/TreePrefab.prefab b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/TreePrefab.prefab new file mode 100644 index 000000000..80f25d28b --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/TreePrefab.prefab @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f994f2239f2accffd23fd4f8f960467a968ef74faca3fd811bf984dd3b194a7e +size 4213 diff --git a/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/TreePrefab.prefab.meta b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/TreePrefab.prefab.meta new file mode 100644 index 000000000..fc4c4d5c4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/TreePrefab.prefab.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 0ea4f7b25a5a56b48999d0e67aa2128d +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Sample Scene (Cornell Box)/URP/Terrain/Trees/TreePrefab.prefab + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts.meta b/Assets/External/HTraceWSGI/Scripts.meta new file mode 100644 index 000000000..c22734b7e --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ec07482368d4b2149826b5307151f9c3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/External/HTraceWSGI/Scripts/Data.meta b/Assets/External/HTraceWSGI/Scripts/Data.meta new file mode 100644 index 000000000..65f06b5f1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 312c387d222beb446baabe8152e29a6b +timeCreated: 1674799562 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Private.meta b/Assets/External/HTraceWSGI/Scripts/Data/Private.meta new file mode 100644 index 000000000..2003b6ead --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Private.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5b57bd4a0aa60934a9f3f59d6160ae81 +timeCreated: 1743247400 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Private/HSettings.cs b/Assets/External/HTraceWSGI/Scripts/Data/Private/HSettings.cs new file mode 100644 index 000000000..92ab5a750 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Private/HSettings.cs @@ -0,0 +1,25 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Public; +using UnityEngine; +using LightingSettings = HTraceWSGI.Scripts.Data.Public.LightingSettings; + +namespace HTraceWSGI.Scripts.Data.Private +{ + internal static class HSettings + { + [SerializeField] + internal static GeneralSettings GeneralSettings; + [SerializeField] + internal static ScreenSpaceLightingSettings ScreenSpaceLightingSettings; + [SerializeField] + internal static DebugSettings DebugSettings; + [SerializeField] + internal static VoxelizationSettings VoxelizationSettings; + [SerializeField] + internal static LightingSettings LightingSettings; + [SerializeField] + internal static ReflectionIndirectLightingSettings ReflectionIndirectLightingSettings; + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Private/HSettings.cs.meta b/Assets/External/HTraceWSGI/Scripts/Data/Private/HSettings.cs.meta new file mode 100644 index 000000000..a6e6f730f --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Private/HSettings.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c3fc9a73e0a1ee8478ce35d3987583f8 +timeCreated: 1741077623 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Data/Private/HSettings.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationExactData.cs b/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationExactData.cs new file mode 100644 index 000000000..617665181 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationExactData.cs @@ -0,0 +1,47 @@ +//pipelinedefine +#define H_URP + +using System; +using HTraceWSGI.Scripts.Data.Public; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Data.Private +{ + [Serializable] + internal class VoxelizationExactData + { + public Vector3Int Resolution; + public Vector3 Bounds; + + public float VoxelSize + { + get { return Bounds.x / Resolution.x; } + } + + public float VoxelsPerMeter + { + get { return Resolution.x / Bounds.x; } + } + + public void UpdateData(VoxelizationSettings voxelizationSettings) + { + Vector3Int targetResolution = HMath.CalculateVoxelResolution(voxelizationSettings); + Vector3Int realBounds = new Vector3Int(voxelizationSettings.VoxelBounds, voxelizationSettings.VoxelBounds, + voxelizationSettings.OverrideBoundsHeightEnable == false ? voxelizationSettings.VoxelBounds : voxelizationSettings.OverrideBoundsHeight); + float realVoxelSize = (float)realBounds.x / targetResolution.x; + float exactVoxelSize = realVoxelSize.RoundToCeilTail(2); + + float maxVoxelSize = 0.16f; // default case + if (HConfig.MAX_VOXEL_BOUNDS != 80) //not default case + { + maxVoxelSize = ((float)realBounds.x / targetResolution.x).RoundToCeilTail(2); + } + exactVoxelSize = Mathf.Clamp(exactVoxelSize, 0.08f, maxVoxelSize); // we want voxel size between 8 and 16 cm + + var resultResolution = HMath.CalculateVoxelResolutionByVoxelSize(exactVoxelSize, realBounds); //targetResolution; + Resolution = resultResolution; + Bounds = new Vector3(resultResolution.x * exactVoxelSize, resultResolution.y * exactVoxelSize, resultResolution.z * exactVoxelSize); + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationExactData.cs.meta b/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationExactData.cs.meta new file mode 100644 index 000000000..aec38edd4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationExactData.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f78c43a2993ce0f48ab2f455b3308108 +timeCreated: 1694154676 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Data/Private/VoxelizationExactData.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationRuntimeData.cs b/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationRuntimeData.cs new file mode 100644 index 000000000..02f4d73d6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationRuntimeData.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Services.VoxelCameras; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Data.Private +{ + internal enum OffsetAxisIndex + { + AxisXPos = 0, + AxisYPos = 1, + AxisZPos = 2, + AxisXNeg = 3, + AxisYNeg = 4, + AxisZNeg = 5, + } + + internal enum OctantIndex + { + FullVoxelization = 0, + OctantA = 1, + OctantB = 2, + OctantC = 3, + OctantD = 4, + DynamicObjects = 5, + } + + [Serializable] + internal static class VoxelizationRuntimeData + { + public static VoxelCamera VoxelCamera { get; set; } = null; + public static VoxelCullingCamera CullingCamera { get; set; } = null; + public static VoxelOctantCamera VoxelOctantCamera { get; set; } = null; + + private static bool _fullVoxelization; + public static bool FullVoxelization + { + get => _fullVoxelization; + set + { + _fullVoxelization = value; + if (_fullVoxelization == true) + OctantIndex = OctantIndex.FullVoxelization; + } + } + + public static OffsetWorldPosition OffsetWorldPosition = OffsetWorldPosition.zero; + public static OctantIndex OctantIndex = OctantIndex.FullVoxelization; + public static OffsetAxisIndex OffsetAxisIndex = OffsetAxisIndex.AxisXPos; + public static int TextureSwapCounter; + public static int TextureOutputCounter; + + [SerializeField] private static float _prevDensityUI = 0f; + [SerializeField] private static int _prevVoxelBoundsUI = 0; + [SerializeField] private static int _prevOverrideBoundsHeightUI = 0; + + public static Action OnReallocTextures; + + public static void Initialize() + { + OffsetWorldPosition = OffsetWorldPosition.zero; + OctantIndex = OctantIndex.FullVoxelization; + OffsetAxisIndex = OffsetAxisIndex.AxisXPos; + + FullVoxelization = true; + TextureSwapCounter = 0; + TextureOutputCounter = 0; + } + + public static void SetParamsForApplyButton(float prevDensityUI, int prevVoxelBoundsUI, int prevOverrideBoundsHeightUI) + { + _prevDensityUI = prevDensityUI; + _prevVoxelBoundsUI = prevVoxelBoundsUI; + _prevOverrideBoundsHeightUI = prevOverrideBoundsHeightUI; + } + + public static bool CheckPrevParams(float voxelDensity, int voxelBounds, int overrideBoundsHeight) + { + return Mathf.Abs(voxelDensity - _prevDensityUI) > Mathf.Epsilon || voxelBounds != _prevVoxelBoundsUI || overrideBoundsHeight != _prevOverrideBoundsHeightUI; + } + + /// + /// We update OctantIndex after Voxelization and Shadowmap passes in Render stage, because it may have several calls during the frame? + /// + public static void UpdateOctantIndex() + { + OctantIndex = OctantIndex == OctantIndex.DynamicObjects ? OctantIndex.OctantA : OctantIndex.Next(); + +#if UNITY_EDITOR + if (UnityEditor.EditorApplication.isPaused) // Without this check octant counter gets corrupted during any pause and Frame Debugger flickers + { + OctantIndex = OctantIndex.Prev(); + } +#endif + } + } + + internal struct OffsetWorldPosition + { + public float AxisXPos; + public float AxisYPos; + public float AxisZPos; + public float AxisXNeg; + public float AxisYNeg; + public float AxisZNeg; + + public OffsetWorldPosition(float axisXPos, float axisYPos, float axisZPos, float axisXNeg, float axisYNeg, float axisZNeg) + { + AxisXPos = axisXPos; + AxisYPos = axisYPos; + AxisZPos = axisZPos; + AxisXNeg = axisXNeg; + AxisYNeg = axisYNeg; + AxisZNeg = axisZNeg; + } + + public static OffsetWorldPosition zero + { + get => OffsetWorldPosition.zeroVector; + } + + private static readonly OffsetWorldPosition zeroVector = new OffsetWorldPosition(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f); + + public static OffsetWorldPosition operator +(OffsetWorldPosition a, OffsetWorldPosition b) + { + return new OffsetWorldPosition( + a.AxisXPos + b.AxisXPos, + a.AxisYPos + b.AxisYPos, + a.AxisZPos + b.AxisZPos, + a.AxisXNeg + b.AxisXNeg, + a.AxisYNeg + b.AxisYNeg, + a.AxisZNeg + b.AxisZNeg + ); + } + + public OffsetAxisIndex MaxAxisOffset() + { + Dictionary dictionary = new Dictionary() + { + {OffsetAxisIndex.AxisXPos, AxisXPos}, + {OffsetAxisIndex.AxisYPos, AxisYPos}, + {OffsetAxisIndex.AxisZPos, AxisZPos}, + {OffsetAxisIndex.AxisXNeg, AxisXNeg}, + {OffsetAxisIndex.AxisYNeg, AxisYNeg}, + {OffsetAxisIndex.AxisZNeg, AxisZNeg}, + }; + + float maxValue = -1; + OffsetAxisIndex axisIndex = OffsetAxisIndex.AxisXPos; + foreach (var element in dictionary) + { + if (element.Value > maxValue) + { + axisIndex = element.Key; + maxValue = element.Value; + } + } + + return axisIndex; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationRuntimeData.cs.meta b/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationRuntimeData.cs.meta new file mode 100644 index 000000000..775f83073 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Private/VoxelizationRuntimeData.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 721f25ec4d9d57842bbff1962403f645 +timeCreated: 1717840079 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Data/Private/VoxelizationRuntimeData.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public.meta b/Assets/External/HTraceWSGI/Scripts/Data/Public.meta new file mode 100644 index 000000000..c95b79047 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 50b328c171626c64a83cfbd1625669af +timeCreated: 1743662817 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/DebugSettings.cs b/Assets/External/HTraceWSGI/Scripts/Data/Public/DebugSettings.cs new file mode 100644 index 000000000..b6080c920 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/DebugSettings.cs @@ -0,0 +1,34 @@ +//pipelinedefine +#define H_URP + +using System; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Data.Public +{ + [Serializable] + internal class DebugSettings + { + [SerializeField] + private bool _enableDebug = true; + + public bool EnableDebug + { + get { return _enableDebug; } + set { _enableDebug = value; } + } + public bool AttachToSceneCamera = false; + + //Devs: + public Camera CameraForTests; + public bool EnableCamerasVisualization = false; + public bool ShowBowels = false; + public bool ShowFullDebugLog = false; + + public bool TestCheckbox = false; + + public RenderTexture RenderTexture; + public LayerMask HTraceLayer = ~0; + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/DebugSettings.cs.meta b/Assets/External/HTraceWSGI/Scripts/Data/Public/DebugSettings.cs.meta new file mode 100644 index 000000000..73dff61c0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/DebugSettings.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 026a7e54b80f11c48980541e0e545cc4 +timeCreated: 1720030306 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Data/Public/DebugSettings.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/GeneralSettings.cs b/Assets/External/HTraceWSGI/Scripts/Data/Public/GeneralSettings.cs new file mode 100644 index 000000000..767a3871a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/GeneralSettings.cs @@ -0,0 +1,118 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Globals; +using System; +using HTraceWSGI.Scripts.Extensions; +using UnityEngine; +using UnityEngine.Serialization; + +namespace HTraceWSGI.Scripts.Data.Public +{ + [Serializable] + public class GeneralSettings + { + /// + /// Debug different stages and resources of HTrace. + /// + /// More information + public DebugModeWS DebugModeWS = DebugModeWS.None; + public HBuffer HBuffer = HBuffer.Multi; + public bool VolumetricDebug = true; + + [SerializeField] + private float _intensity = 1f; + /// + /// + /// + /// [0.1;5.0] + [HExtensions.HRangeAttribute(0.1f,5.0f)] + public float Intensity + { + get => _intensity; + set + { + if (Mathf.Abs(value - _intensity) < Mathf.Epsilon) + return; + + _intensity = HExtensions.Clamp(value, typeof(GeneralSettings), nameof(GeneralSettings.Intensity)); + } + } + [SerializeField] + public bool AmbientOverride = true; + [SerializeField] + public bool MetallicIndirectFallback = false; + + [SerializeField] + private float _renderScale = 1f; + /// + /// + /// + /// [0.5;1.0] + [HExtensions.HRangeAttribute(0.5f,1.0f)] + public float RenderScale + { + get => _renderScale; + set + { + if (Mathf.Abs(value - _renderScale) < Mathf.Epsilon) + return; + + _renderScale = HExtensions.Clamp(value, typeof(GeneralSettings), nameof(GeneralSettings.RenderScale)); + } + } + + public TracingMode TracingMode = TracingMode.SoftwareTracing; + + [SerializeField] + private RayCountMode _rayCountMode = RayCountMode.Quality; + /// + /// Defines the pixel spacing between screen-space probes, affecting the number of probes spawned. + /// Ray Count has the biggest impact on the overall performance , memory consumption and visual quality. + /// + /// More information + public RayCountMode RayCountMode + { + get + { + return _rayCountMode; + } + set + { + if (value == _rayCountMode) + return; + + _rayCountMode = value; + } + } + + [SerializeField] + private int _rayLength = 50; + + /// + /// The maximum distance a ray can travel in world space. + /// + /// [1;100] + /// More information + [HExtensions.HRangeAttribute(0, 100)] + public int RayLength + { + get { return _rayLength; } + set + { + if (value == _rayLength) + return; + + _rayLength = HExtensions.Clamp(value, typeof(GeneralSettings), nameof(GeneralSettings.RayLength)); + } + } + + + public Multibounce Multibounce = Multibounce.IrradianceCache; + +#if UNITY_2023_3_OR_NEWER + public RenderingLayerMask ExcludeCastingMask = 0; + public RenderingLayerMask ExcludeReceivingMask = 0; +#endif + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/GeneralSettings.cs.meta b/Assets/External/HTraceWSGI/Scripts/Data/Public/GeneralSettings.cs.meta new file mode 100644 index 000000000..00f3a6191 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/GeneralSettings.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7051943d02f16f943bbb29966dac1be2 +timeCreated: 1674799588 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Data/Public/GeneralSettings.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/LightingSettings.cs b/Assets/External/HTraceWSGI/Scripts/Data/Public/LightingSettings.cs new file mode 100644 index 000000000..f8ff460c6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/LightingSettings.cs @@ -0,0 +1,165 @@ +using System; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Data.Public +{ + [Serializable] + public class LightingSettings + { + /// + /// Main shadow-casting Directional light. It is usually set up automatically. + /// + /// More information + public Light DirectionalLight; + + [SerializeField] + private float _surfaceDiffuseIntensity = 1f; + + [HExtensions.HRangeAttribute(1f, 10)] + public float SurfaceDiffuseIntensity + { + get { return _surfaceDiffuseIntensity; } + set + { + if (Mathf.Abs(value - _surfaceDiffuseIntensity) < Mathf.Epsilon) + return; + + _surfaceDiffuseIntensity = HExtensions.Clamp(value, typeof(LightingSettings), nameof(LightingSettings.SurfaceDiffuseIntensity)); + } + } + + [SerializeField] + private float _directionalLightIntensity = 1f; + + [HExtensions.HRangeAttribute(1f, 10)] + public float DirectionalLightIntensity + { + get { return _directionalLightIntensity; } + set + { + if (Mathf.Abs(value - _directionalLightIntensity) < Mathf.Epsilon) + return; + + _directionalLightIntensity = HExtensions.Clamp(value, typeof(LightingSettings), nameof(LightingSettings.DirectionalLightIntensity)); + } + } + + [SerializeField] + private float _skyLightIntensity = 1f; + + [HExtensions.HRangeAttribute(1f, 10)] + public float SkyLightIntensity + { + get { return _skyLightIntensity; } + set + { + if (Mathf.Abs(value - _skyLightIntensity) < Mathf.Epsilon) + return; + + _skyLightIntensity = HExtensions.Clamp(value, typeof(LightingSettings), nameof(LightingSettings.SkyLightIntensity)); + } + } + + [SerializeField] + private float _expandShadowmap = 1f; + + /// + /// Controls the area covered by the custom directional shadowmap. The shadowmap is used to evaluate direct lighting and shadowing at hit points of world-space rays. + /// + /// [0.0;3.0] + /// More information + [HExtensions.HRangeAttribute(1.0f, 3.0f)] + public float ExpandShadowmap + { + get { return _expandShadowmap; } + set + { + if (Mathf.Abs(value - _expandShadowmap) < Mathf.Epsilon) + return; + + _expandShadowmap = HExtensions.Clamp(value, typeof(LightingSettings), nameof(LightingSettings.ExpandShadowmap)); + } + } + + [SerializeField] + private float _shadowmapRange = 100f; + + [HExtensions.HRangeAttribute(10f, 500f)] + public float ShadowmapRange + { + get { return _shadowmapRange; } + set + { + if (Mathf.Abs(value - _shadowmapRange) < Mathf.Epsilon) + return; + + _shadowmapRange = HExtensions.Clamp(value, typeof(LightingSettings), nameof(LightingSettings.ShadowmapRange)); + } + } + + public ShadowmapUpdateMode ShadowmapUpdateMode = ShadowmapUpdateMode.Default; + + // ------------------------------ Light Cluster ------------------------------ + + [SerializeField] + public bool EvaluatePunctualLights = false; + + [SerializeField] + private int _lightClusterCellLightCount = 8; + + [HExtensions.HRangeAttribute(2, 16)] + public int LightClusterCellLightCount + { + get { return _lightClusterCellLightCount; } + set + { + int roundedValue = Mathf.RoundToInt((float)value / 2) * 2; + + roundedValue = HExtensions.Clamp(roundedValue, typeof(LightingSettings), nameof(LightingSettings.LightClusterCellLightCount)); + + if (roundedValue == _lightClusterCellLightCount) + return; + + _lightClusterCellLightCount = roundedValue; + } + } + + [SerializeField] + private int _lightClusterCellDensity = 16; + + [HExtensions.HRangeAttribute(16, 64)] + public int LightClusterCellDensity + { + get { return _lightClusterCellDensity; } + set + { + int roundedValue = Mathf.RoundToInt((float)value / 4) * 4; + + roundedValue = HExtensions.Clamp(roundedValue, typeof(LightingSettings), nameof(LightingSettings.LightClusterCellDensity)); + + if (roundedValue == _lightClusterCellDensity) + return; + + _lightClusterCellDensity = roundedValue; + } + } + + [SerializeField] + private int _lightClusterRange = 100; + + [HExtensions.HRangeAttribute(10, 500)] + public int LightClusterRange + { + get { return _lightClusterRange; } + set + { + if (value == _lightClusterRange) + return; + + _lightClusterRange = HExtensions.Clamp(value, typeof(LightingSettings), nameof(LightingSettings.LightClusterRange)); + } + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/LightingSettings.cs.meta b/Assets/External/HTraceWSGI/Scripts/Data/Public/LightingSettings.cs.meta new file mode 100644 index 000000000..0127835fe --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/LightingSettings.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 84bfd85251ddd6144af8f591ccd5a6e0 +timeCreated: 1744047763 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Data/Public/LightingSettings.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/ReflectionIndirectLightingSettings.cs b/Assets/External/HTraceWSGI/Scripts/Data/Public/ReflectionIndirectLightingSettings.cs new file mode 100644 index 000000000..e4aa43f5d --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/ReflectionIndirectLightingSettings.cs @@ -0,0 +1,71 @@ +using System; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Data.Public +{ + [Serializable] + public class ReflectionIndirectLightingSettings + { + [SerializeField] + public IndirectEvaluationMethod IndirectEvaluationMethod = IndirectEvaluationMethod.None; + + [SerializeField] + private float _rayBias = 0.5f; + + [HExtensions.HRange(0.0f,1.0f)] + public float RayBias + { + get => _rayBias; + set + { + if (Mathf.Abs(value - _rayBias) < Mathf.Epsilon) + return; + + _rayBias = HExtensions.Clamp(value, typeof(ReflectionIndirectLightingSettings), nameof(ReflectionIndirectLightingSettings.RayBias)); + } + } + + [SerializeField] + private float _maxRayLength = 100f; + + [HExtensions.HRange(0.0f,100.0f)] + public float MaxRayLength + { + get => _maxRayLength; + set + { + if (Mathf.Abs(value - _maxRayLength) < Mathf.Epsilon) + return; + + _maxRayLength = HExtensions.Clamp(value, typeof(ReflectionIndirectLightingSettings), nameof(ReflectionIndirectLightingSettings.MaxRayLength)); + } + } + + [SerializeField] + public SpatialRadius SpatialRadius = SpatialRadius.Medium; + + [SerializeField] + private float _jitterRadius = 0.5f; + + [HExtensions.HRange(0.0f,1.0f)] + public float JitterRadius + { + get => _jitterRadius; + set + { + if (Mathf.Abs(value - _jitterRadius) < Mathf.Epsilon) + return; + + _jitterRadius = HExtensions.Clamp(value, typeof(ReflectionIndirectLightingSettings), nameof(ReflectionIndirectLightingSettings.JitterRadius)); + } + } + + [SerializeField] + public bool TemporalJitter = true; + + [SerializeField] + public bool OcclusionCheck = false; + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/ReflectionIndirectLightingSettings.cs.meta b/Assets/External/HTraceWSGI/Scripts/Data/Public/ReflectionIndirectLightingSettings.cs.meta new file mode 100644 index 000000000..95c3d3e58 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/ReflectionIndirectLightingSettings.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: aaaec40ca01aaa740a816dc1dc5f6209 +timeCreated: 1750673386 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Data/Public/ReflectionIndirectLightingSettings.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/ScreenSpaceLightingSettings.cs b/Assets/External/HTraceWSGI/Scripts/Data/Public/ScreenSpaceLightingSettings.cs new file mode 100644 index 000000000..4ccf3f07d --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/ScreenSpaceLightingSettings.cs @@ -0,0 +1,45 @@ +using System; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Data.Public +{ + [Serializable] + public class ScreenSpaceLightingSettings + { + /// + /// Allows to evaluate lighting at the hit points of screen-space rays instead of relying solely on the previous Color Buffer. + /// + /// More information + public bool EvaluateHitLighting = false; + + /// + /// Enable directional screen space occlusion. + /// + /// More information + public bool DirectionalOcclusion = true; + + [SerializeField] + private float _occlusionIntensity = 0.25f; + + /// + /// Occlusion Intensity + /// + /// [0.0;1.0] + /// More information + [HExtensions.HRange(0.0f,1.0f)] + public float OcclusionIntensity + { + get => _occlusionIntensity; + set + { + if (Mathf.Abs(value - _occlusionIntensity) < Mathf.Epsilon) + return; + + _occlusionIntensity = HExtensions.Clamp(value, typeof(ScreenSpaceLightingSettings), nameof(ScreenSpaceLightingSettings.OcclusionIntensity)); + } + } + + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/ScreenSpaceLightingSettings.cs.meta b/Assets/External/HTraceWSGI/Scripts/Data/Public/ScreenSpaceLightingSettings.cs.meta new file mode 100644 index 000000000..44b746db1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/ScreenSpaceLightingSettings.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 68304b2aac4de1b4daf8706007e5a7bd +timeCreated: 1675236321 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Data/Public/ScreenSpaceLightingSettings.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/VoxelizationSettings.cs b/Assets/External/HTraceWSGI/Scripts/Data/Public/VoxelizationSettings.cs new file mode 100644 index 000000000..d87a33b26 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/VoxelizationSettings.cs @@ -0,0 +1,239 @@ +using System; +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Data.Public +{ + [Serializable] + public class VoxelizationSettings + { + public VoxelizationSettings() + { + UpdateData(); + } + + internal void UpdateData() + { + ExactData.UpdateData(this); + } + + [SerializeField] + internal VoxelizationExactData ExactData = new VoxelizationExactData(); + + //Voxelization ------------------------------------------------------------------------------------------------ + + /// + /// Exclude objects (on a per-layer basis) from voxelization and has the highest priority over all other layer masks. + /// + /// More information + public LayerMask VoxelizationMask = ~0; + + /// + /// This mode defines how voxel data will be updated. + /// + /// More information + public VoxelizationUpdateMode VoxelizationUpdateMode = VoxelizationUpdateMode.Constant; + + [SerializeField] + private int _updatePeriod = 1; + + /// + /// Update Period + /// + /// [1;4] + /// More information + [HExtensions.HRangeAttribute(1, 4)] + public int UpdatePeriod + { + get { return _updatePeriod; } + set + { + if (value == _updatePeriod) + return; + + _updatePeriod = HExtensions.Clamp(value, typeof(VoxelizationSettings), nameof(VoxelizationSettings.UpdatePeriod)); + } + } + + /// + /// Anchor object for the voxelization bound. Voxelization will occur around this object and will follow it when it moves. + /// + /// More information + public Transform AttachTo; + + [SerializeField] + private int _lodMax = 0; + + /// + /// Maximum LOD level + /// + /// [0;10] + /// More information + [HExtensions.HRangeAttribute(0, HConstants.MAX_LOD_LEVEL)] + public int LODMax + { + get { return _lodMax; } + set + { + if (value == _lodMax) + return; + + _lodMax = HExtensions.Clamp(value, typeof(VoxelizationSettings), nameof(VoxelizationSettings.LODMax)); + } + } + + /// + /// + /// + public LayerMask InstancedTerrains = 0; + + //Update Options ------------------------------------------------------------------------------------------------ + + public LayerMask CulledObjectsMask = 0; + + [SerializeField] private int _expandCullFov = 0; + + /// + /// Expand Cull Fov + /// + /// [0;20] + [HExtensions.HRangeAttribute(0, 20)] + public int ExpandCullFov + { + get { return _expandCullFov; } + set + { + if (value == _expandCullFov) + return; + + _expandCullFov = HExtensions.Clamp(value, typeof(VoxelizationSettings), nameof(VoxelizationSettings.ExpandCullFov)); + } + } + + [SerializeField] + private float _expandCullRadius = 1f; + + /// + /// Expand Cull Radius + /// + /// [0.0;3.0] + [HExtensions.HRangeAttribute(0.0f, 3.0f)] + public float ExpandCullRadius + { + get { return _expandCullRadius; } + set + { + if (Mathf.Abs(value - _expandCullRadius) < Mathf.Epsilon) + return; + + _expandCullRadius = HExtensions.Clamp(value, typeof(VoxelizationSettings), nameof(VoxelizationSettings.ExpandCullRadius)); + } + } + + public LayerMask DynamicObjectsMask = 0; + + //Voxels parameters ------------------------------------------------------------------------------------------------ + + [SerializeField] + private float _voxelDensity = 0.64f; + + /// + /// Controls the resolution of the voxel volume (3D Texture). Lower values reduce the volume resolution, while higher values provide finer detail. The Voxel Density is limited by + /// the Voxel Bounds parameter to ensure voxel sizes remain between 4 and 8 centimeters. + /// + /// [0.0;1.0] + /// More information + [HExtensions.HRangeAttribute(0.0f, 1.0f)] + public float VoxelDensity + { + get { return _voxelDensity; } + set + { + if (Mathf.Abs(value - _voxelDensity) < Mathf.Epsilon) + return; + + _voxelDensity = HExtensions.Clamp(value, typeof(VoxelizationSettings), nameof(VoxelizationSettings.VoxelDensity)); + //ExactData.UpdateData(this); + } + } + + [SerializeField] private int _voxelBounds = 35; + + /// + /// Controls the maximum size (in meters) that the voxelization bound can cover. + /// + /// [1;80] + /// More information + [HExtensions.HRangeAttribute(5, HConfig.MAX_VOXEL_BOUNDS)] + public int VoxelBounds + { + get { return _voxelBounds; } + set + { + if (value == _voxelBounds) + return; + + _voxelBounds = HExtensions.Clamp(value, typeof(VoxelizationSettings), nameof(VoxelizationSettings.VoxelBounds)); + //ExactData.UpdateData(this); + } + } + + [SerializeField] + private bool _overrideBoundsHeightEnable = false; + + /// + /// Enable Bounds height override. + /// + /// [1;80] + /// More information + public bool OverrideBoundsHeightEnable + { + get { return _overrideBoundsHeightEnable; } + set { _overrideBoundsHeightEnable = value; } + } + + [SerializeField] + private int _overrideBoundsHeight = 10; + + /// + /// The maximum height of the voxelization bound. + /// This parameter is particularly useful for "flat" levels with low verticality, where the scene extends along the X and Z axes but has minimal content along the Y axis + /// (e.g., indoor scenes where the distance to walls is typically greater than the distance to the floor or ceiling). + /// + /// [1;200] + /// More information + [HExtensions.HRangeAttribute(1, 200)] + public int OverrideBoundsHeight + { + get { return _overrideBoundsHeight; } + set + { + if (value == _overrideBoundsHeight) + return; + + _overrideBoundsHeight = HExtensions.Clamp(value, typeof(VoxelizationSettings), nameof(VoxelizationSettings.OverrideBoundsHeight)); + //ExactData.UpdateData(this); + } + } + + /// + /// Shift Center of voxelization bound + /// + /// More information + public float CenterShift = 0f; + + /// + /// Enable Ground level for voxelization. + /// + /// More information + public bool GroundLevelEnable = false; + /// + /// Ensures that the voxelization bounds will always remain above this specified level. + /// This option is useful when you know the base level of your scene and there is no need to voxelize anything below it. + /// + /// More information + public float GroundLevel = 0f; + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Data/Public/VoxelizationSettings.cs.meta b/Assets/External/HTraceWSGI/Scripts/Data/Public/VoxelizationSettings.cs.meta new file mode 100644 index 000000000..cf788ca5a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Data/Public/VoxelizationSettings.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7615040a01913f64bb14061e640a5f76 +timeCreated: 1683905333 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Data/Public/VoxelizationSettings.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Editor.meta b/Assets/External/HTraceWSGI/Scripts/Editor.meta new file mode 100644 index 000000000..b17afc1c8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b627853c8ed3d35468badc6148f0faef +timeCreated: 1674796671 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/HDEditorUtilsWrapper.cs b/Assets/External/HTraceWSGI/Scripts/Editor/HDEditorUtilsWrapper.cs new file mode 100644 index 000000000..d3c528f6f --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/HDEditorUtilsWrapper.cs @@ -0,0 +1,312 @@ +#if UNITY_EDITOR +using System; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Editor +{ + public class HDEditorUtilsWrapper + { + #region Public Methods + + public static bool EnsureFrameSetting(int frameSettingsField) + { + try + { + Type hdEditorUtilsType = GetHDEditorUtilsType(); + if (hdEditorUtilsType == null) + { + Debug.LogError("Failed to find HDEditorUtils type"); + return false; + } + + Type frameSettingsFieldType = GetFrameSettingsFieldType(); + if (frameSettingsFieldType == null) + { + Debug.LogError("Failed to find FrameSettingsField type"); + return false; + } + + object frameSettingsFieldEnum = Enum.ToObject(frameSettingsFieldType, frameSettingsField); + + MethodInfo ensureFrameSettingMethod = hdEditorUtilsType.GetMethod("EnsureFrameSetting", + BindingFlags.NonPublic | BindingFlags.Static, + null, + new Type[] { frameSettingsFieldType }, + null); + + if (ensureFrameSettingMethod == null) + { + Debug.LogError("Failed to find EnsureFrameSetting method"); + return false; + } + + object result = ensureFrameSettingMethod.Invoke(null, new object[] { frameSettingsFieldEnum }); + return result != null && (bool)result; + } + catch (Exception ex) + { + Debug.LogError($"Error calling HDEditorUtils.EnsureFrameSetting: {ex.Message}"); + return false; + } + } + + public static void QualitySettingsHelpBox(string message, MessageType messageType, int expandableGroup, string propertyPath) + { + try + { + Type hdEditorUtilsType = GetHDEditorUtilsType(); + if (hdEditorUtilsType == null) + { + Debug.LogError("Failed to find HDEditorUtils type"); + return; + } + + Type messageTypeEnum = typeof(MessageType); + Type expandableGroupType = GetExpandableGroupType(); + + if (expandableGroupType == null) + { + Debug.LogError("Failed to find ExpandableGroup type"); + return; + } + + object messageTypeValue = Enum.ToObject(messageTypeEnum, messageType); + object expandableGroupValue = Enum.ToObject(expandableGroupType, expandableGroup); + + MethodInfo qualitySettingsHelpBoxMethod = hdEditorUtilsType.GetMethod("QualitySettingsHelpBox", + BindingFlags.NonPublic | BindingFlags.Static, + null, + new Type[] { typeof(string), messageTypeEnum, expandableGroupType, typeof(string) }, + null); + + if (qualitySettingsHelpBoxMethod == null) + { + Debug.LogError("Failed to find QualitySettingsHelpBox method with 4 parameters"); + return; + } + + qualitySettingsHelpBoxMethod.Invoke(null, new object[] { message, messageTypeValue, expandableGroupValue, propertyPath }); + } + catch (Exception ex) + { + //Debug.LogError($"Error calling HDEditorUtils.QualitySettingsHelpBox: {ex.Message}"); + } + } + + public static void QualitySettingsHelpBoxWithSection(string message, MessageType messageType, int expandableGroup, int expandableSection, string propertyPath) + { + try + { + Type hdEditorUtilsType = GetHDEditorUtilsType(); + if (hdEditorUtilsType == null) + { + Debug.LogError("Failed to find HDEditorUtils type"); + return; + } + + Type messageTypeEnum = typeof(MessageType); + Type expandableGroupType = GetExpandableGroupType(); + + if (expandableGroupType == null) + { + Debug.LogError("Failed to find ExpandableGroup type"); + return; + } + + object messageTypeValue = Enum.ToObject(messageTypeEnum, messageType); + object expandableGroupValue = Enum.ToObject(expandableGroupType, expandableGroup); + + MethodInfo[] methods = hdEditorUtilsType.GetMethods(BindingFlags.NonPublic | BindingFlags.Static); + MethodInfo genericMethod = null; + + foreach (var method in methods) + { + if (method.Name == "QualitySettingsHelpBox" && + method.IsGenericMethodDefinition && + method.GetParameters().Length == 5) + { + genericMethod = method; + break; + } + } + + if (genericMethod == null) + { + Debug.LogError("Failed to find generic QualitySettingsHelpBox method"); + return; + } + + Type expandableLightingType = GetExpandableLightingType(); + if (expandableLightingType == null) + { + expandableLightingType = expandableGroupType; + } + + MethodInfo concreteMethod = genericMethod.MakeGenericMethod(expandableLightingType); + + object expandableSectionValue = Enum.ToObject(expandableLightingType, expandableSection); + + concreteMethod.Invoke(null, new object[] { message, messageTypeValue, expandableGroupValue, expandableSectionValue, propertyPath }); + } + catch (Exception ex) + { + Debug.LogError($"Error calling HDEditorUtils.QualitySettingsHelpBox with section: {ex.Message}"); + } + } + + #endregion + + #region Helper Methods + + private static Type GetHDEditorUtilsType() + { + Type hdEditorUtilsType = Type.GetType("UnityEditor.Rendering.HighDefinition.HDEditorUtils, Unity.RenderPipelines.HighDefinition.Editor"); + + if (hdEditorUtilsType == null) + { + var assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in assemblies) + { + hdEditorUtilsType = assembly.GetType("UnityEditor.Rendering.HighDefinition.HDEditorUtils"); + if (hdEditorUtilsType != null) break; + } + } + + return hdEditorUtilsType; + } + + private static Type GetFrameSettingsFieldType() + { + Type frameSettingsFieldType = Type.GetType("UnityEngine.Rendering.HighDefinition.FrameSettingsField, Unity.RenderPipelines.HighDefinition.Runtime"); + + if (frameSettingsFieldType == null) + { + var assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in assemblies) + { + frameSettingsFieldType = assembly.GetType("UnityEngine.Rendering.HighDefinition.FrameSettingsField"); + if (frameSettingsFieldType != null) break; + } + } + + return frameSettingsFieldType; + } + + private static Type GetExpandableGroupType() + { + Type hdrpUIType = GetHDRPUIType(); + if (hdrpUIType == null) return null; + + return hdrpUIType.GetNestedType("ExpandableGroup", BindingFlags.NonPublic | BindingFlags.Public); + } + + private static Type GetExpandableLightingType() + { + Type hdrpUIType = GetHDRPUIType(); + if (hdrpUIType == null) return null; + + return hdrpUIType.GetNestedType("ExpandableLighting", BindingFlags.NonPublic | BindingFlags.Public); + } + + private static Type GetHDRPUIType() + { + Type hdrpUIType = Type.GetType("UnityEditor.Rendering.HighDefinition.HDRenderPipelineUI, Unity.RenderPipelines.HighDefinition.Editor"); + + if (hdrpUIType == null) + { + var assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in assemblies) + { + hdrpUIType = assembly.GetType("UnityEditor.Rendering.HighDefinition.HDRenderPipelineUI"); + if (hdrpUIType != null) break; + } + } + + return hdrpUIType; + } + + public static int GetFrameSettingsFieldValue(string fieldName) + { + try + { + Type frameSettingsFieldType = GetFrameSettingsFieldType(); + if (frameSettingsFieldType == null) + return -1; + + object enumValue = Enum.Parse(frameSettingsFieldType, fieldName); + return (int)enumValue; + } + catch (Exception ex) + { + Debug.LogError($"Error when get FrameSettingsField.{fieldName}: {ex.Message}"); + return -1; + } + } + + // internal enum ExpandableGroup + // { + // Rendering = 1 << 4, + // Lighting = 1 << 5, + // LightingTiers = 1 << 6, + // Material = 1 << 7, + // PostProcess = 1 << 8, + // PostProcessTiers = 1 << 9, + // XR = 1 << 10, + // VirtualTexturing = 1 << 11, + // Volumes = 1 << 12 + // } + + public static int GetExpandableGroupValue(string groupName) + { + try + { + Type expandableGroupType = GetExpandableGroupType(); + if (expandableGroupType == null) + return -1; + + object enumValue = Enum.Parse(expandableGroupType, groupName); + return (int)enumValue; + } + catch (Exception ex) + { + Debug.LogError($"Error when get ExpandableGroup.{groupName}: {ex.Message}"); + return -1; + } + } + + // internal enum ExpandableLighting + // { + // Volumetric = 1 << 0, + // ProbeVolume = 1 << 1, + // Cookie = 1 << 2, + // Reflection = 1 << 3, + // Sky = 1 << 4, + // // Illegal index 1 << 5 since parent Lighting section index is using it + // LightLoop = 1 << 6, + // Shadow = 1 << 7 + // } + + public static int GetExpandableLightingValue(string lightingName) + { + try + { + Type expandableLightingType = GetExpandableLightingType(); + if (expandableLightingType == null) + return -1; + + object enumValue = Enum.Parse(expandableLightingType, lightingName); + return (int)enumValue; + } + catch (Exception ex) + { + Debug.LogError($"Error when get ExpandableLighting.{lightingName}: {ex.Message}"); + return -1; + } + } + + #endregion + } +} +#endif diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/HDEditorUtilsWrapper.cs.meta b/Assets/External/HTraceWSGI/Scripts/Editor/HDEditorUtilsWrapper.cs.meta new file mode 100644 index 000000000..8a8534742 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/HDEditorUtilsWrapper.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ca217a7921944f24814bd9ebfe75b8a3 +timeCreated: 1758797524 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Editor/HDEditorUtilsWrapper.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/HEditorStyles.cs b/Assets/External/HTraceWSGI/Scripts/Editor/HEditorStyles.cs new file mode 100644 index 000000000..ac42d1ff5 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/HEditorStyles.cs @@ -0,0 +1,156 @@ +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Editor +{ + internal static class HEditorStyles + { + private static float defaultLineSpace = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + private static float additionalLineSpace = 10f; + private static float helpBoxHeight = EditorGUIUtility.singleLineHeight * 2; + private static float checkBoxOffsetWidth = 15f; + private static float checkBoxWidth = 15f; + private static float tabOffset = 8f; + + // Buttons name + public const string FixButtonName = "Fix"; + public const string OpenButtonName = "Open"; + + public static readonly GUIContent GlobalSettings = new GUIContent("Global Settings"); + public static readonly GUIContent Debug = new GUIContent("Debug"); + + // General Tab + public static readonly GUIContent MainCamera = new GUIContent("Main Camera"); + public static readonly GUIContent Tracing = new GUIContent("Tracing mode:"); + public static readonly GUIContent RayCountModeContent = new GUIContent("Ray Count", "Define the pixel spacing between screen-space probes, affecting the number of probes spawned. Ray Count has the biggest impact on the overall performance , memory consumption and visual quality."); + public static readonly GUIContent RayLengthContent = new GUIContent("Ray Length", "Define the maximum distance a ray can travel in world space. Lower values improve performance but may cause rays to miss surfaces, resulting in darker and noisier GI. " + + "Higher values can degrade performance when many rays travel long distances (e.g., toward the sky) without hitting any objects."); + public static readonly GUIContent IndirectIntensity = new GUIContent("Indirect Intensity"); + public static readonly GUIContent MultibounceContent = new GUIContent("Multibounce"); + public static readonly GUIContent Intensity = new GUIContent("Intensity"); + public static readonly GUIContent AmbientOverride = new GUIContent("Ambient Override"); + public static readonly GUIContent MetallicIndirectFallback = new GUIContent("Metallic Indirect Fallback"); + + public static readonly GUIContent DebugModeContent = new GUIContent("Debug Mode", "Visualizes the debug mode for different rendering components of HTraceWSGI."); + public static GUIContent HBuffer = new GUIContent("Buffer", "Visualizes the debug mode for different buffers"); + public static GUIContent VolumetricDebug = new("Volumetric Debug"); + public static GUIContent DepthPyramidLod = new GUIContent("Lod"); + + // Screen Space Lighting Tab + public static readonly GUIContent ScreenSpaceLightingContent = new GUIContent("Screen Space Lighting"); + public static readonly GUIContent EvaluateHitLightingContent = new GUIContent("Evaluate Hit Lighting", "Evaluate lighting at the hit points of screen-space rays instead of relying solely on the previous Color Buffer. Can be enabled only when Evaluate Punctual Light is disabled."); + public static readonly GUIContent DirectionalOcclusionContent = new GUIContent("Directional Occlusion", "Enable directional screen space occlusion"); + public static readonly GUIContent OcclusionIntensityContent = new GUIContent("Occlusion Intensity"); + + // Lighting Tab + public static readonly GUIContent Lighting = new("Lighting"); + public static readonly GUIContent DirectionalLightContent = new("Directional Light", "Main shadow-casting directional light."); + public static readonly GUIContent SurfaceDiffuseIntensity = new GUIContent("Surface Diffuse Intensity"); + public static readonly GUIContent DirectionalLightIntensity = new GUIContent("Directional Light Intensity"); + public static readonly GUIContent SkyLightIntensity = new GUIContent("Sky Light Intensity"); + public static readonly GUIContent ShadowmapRange = new("Shadowmap Range"); + public static readonly GUIContent ShadowmapUpdateMode = new("Shadowmap Update Mode"); + public static readonly GUIContent EvaluatePunctualLights = new ("Evaluate Punctual Lights"); + public static readonly GUIContent LightClusterCellLightCount = new ("Cell Light Count"); + public static readonly GUIContent LightClusterCellDensity = new("Cell Density"); + public static readonly GUIContent LightClusterRange = new("Range"); + + // Voxelization Tab + public static readonly GUIContent VoxelizationContent = new GUIContent("Voxelization"); + public static readonly GUIContent VoxelizationMaskContent = new GUIContent("Voxelization Mask", "Excludes objects (on a per-layer basis) from voxelization and has the highest priority over all other layer masks."); + public static readonly GUIContent InstancedTerrains = new GUIContent("Instanced Terrains"); + public static readonly GUIContent VoxelizationUpdateTypeContent = new GUIContent("Update Mode", "Define how voxel data will be updated."); + public static readonly GUIContent AttachToContent = new GUIContent("Attach To", "Anchor object for the voxelization bound. Voxelization will occur around this object and will follow it when it moves."); + public static readonly GUIContent ExpandShadowmapContent = new GUIContent("Expand Shadowmap", "Control the area covered by the custom directional shadowmap. The shadowmap is used to evaluate direct lighting and shadowing at hit points of world-space rays."); + public static readonly GUIContent MaximumLodContent = new GUIContent("Maximum LOD", "Maximum LOD used for the voxelization."); + + //Update Options + public static readonly GUIContent DynamicObjectsMaskContent = new GUIContent("Dynamic Objects"); + public static readonly GUIContent CulledObjectsMaskContent = new GUIContent("Culled Objects"); + public static readonly GUIContent ExpandCullFovContent = new GUIContent("Expand Cull Fov"); + public static readonly GUIContent ExpandCullRadiusContent = new GUIContent("Expand Cull Radius"); + + //Parameters voxels + public static readonly GUIContent CenterShiftContent = new GUIContent("Center Shift", "Shift center of voxelization."); + public static readonly GUIContent VoxelDensityContent = new GUIContent("Voxel Density", "Controls the resolution of the voxel volume (3D Texture). Lower values reduce the volume resolution, while higher values provide finer detail."); + public static readonly GUIContent VoxelBoundsContent = new GUIContent("Voxel Bounds", "Controls the maximum size (in meters) that the voxelization bound can cover."); + public static readonly GUIContent OverrideBoundsHeightEnableContent = new GUIContent("Cap Bounds Height", "The maximum height of the voxelization bound. This parameter is particularly useful for \"flat\" levels with low verticality."); + public static readonly GUIContent OverrideBoundsHeightEnableContent2 = new GUIContent(" Cap Bounds Height", "The maximum height of the voxelization bound. This parameter is particularly useful for \"flat\" levels with low verticality."); + public static readonly GUIContent GroundLevelEnableContent = new GUIContent("Ground Level", "Ensures that the voxelization bounds will always remain above this specified level."); + public static readonly GUIContent GroundLevelEnableContent2 = new GUIContent(" Ground Level", "Ensures that the voxelization bounds will always remain above this specified level."); + + // Reflection Indirect Lighting + public static readonly GUIContent IndirectEvaluationMethod = new GUIContent("Indirect Evaluation Method"); + public static readonly GUIContent RayBias = new GUIContent("Ray Bias"); + public static readonly GUIContent MaxRayLength = new GUIContent("Max Ray Length"); + public static readonly GUIContent SpatialRadius = new GUIContent("Spatial Radius"); + public static readonly GUIContent JitterRadius = new GUIContent("Jitter Radius"); + public static readonly GUIContent TemporalJitter = new GUIContent("Temporal Jitter"); + public static readonly GUIContent OcclusionCheck = new GUIContent("Occlusion Check"); + + public static GUIStyle bold = new GUIStyle() + { + alignment = TextAnchor.MiddleLeft, + margin = new RectOffset(), + padding = new RectOffset(2, 0, 0, 0), + fontSize = 12, + normal = new GUIStyleState() + { + textColor = new Color(0.903f, 0.903f, 0.903f, 1f), + }, + fontStyle = FontStyle.Bold, + }; + + public static GUIStyle hiddenFoldout = new GUIStyle() + { + alignment = TextAnchor.MiddleLeft, + margin = new RectOffset(), + padding = new RectOffset(), + fontSize = 12, + normal = new GUIStyleState() + { + //textColor = new Color(0.703f, 0.703f, 0.703f, 1f), //default color + textColor = new Color(0.500f, 0.500f, 0.500f, 1f), + }, + fontStyle = FontStyle.Bold, + }; + + public static GUIStyle headerFoldout = new GUIStyle() + { + alignment = TextAnchor.MiddleLeft, + margin = new RectOffset(), + padding = new RectOffset(), + fontSize = 12, + normal = new GUIStyleState() + { + textColor = new Color(0.903f, 0.903f, 0.903f, 1f), + }, + fontStyle = FontStyle.Bold, + }; + + public static GUIStyle foldout = EditorStyles.foldout; + + public static GUIStyle VersionStyle = new GUIStyle(GUI.skin.label) + { + //padding = new RectOffset(left: 10, right: 10, top: 2, bottom: 2), + fontStyle = FontStyle.Bold, + fontSize = 10, + }; + + public static Texture2D GetTexture2D(Color color) + { + Texture2D texture = new Texture2D(1, 1); + texture.SetPixel(0, 0, color); + texture.Apply(); + return texture; + } + + //buttons gui styles + public static Color warningBackgroundColor = new Color(2, 0, 0); + public static Color warningColor = new Color(1, 1, 1); + + public static GUIStyle standartButton = GUI.skin.button; + } +} +#endif \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/HEditorStyles.cs.meta b/Assets/External/HTraceWSGI/Scripts/Editor/HEditorStyles.cs.meta new file mode 100644 index 000000000..3371f1bca --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/HEditorStyles.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d4379d71b1771464db153e7662b19480 +timeCreated: 1675231640 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Editor/HEditorStyles.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/HEditorUtils.cs b/Assets/External/HTraceWSGI/Scripts/Editor/HEditorUtils.cs new file mode 100644 index 000000000..6f87240b0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/HEditorUtils.cs @@ -0,0 +1,250 @@ +#if UNITY_EDITOR +using System; +using UnityEditor; +using UnityEditor.AnimatedValues; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Editor +{ + public static class HEditorUtils + { + private static GUIStyle s_linkStyle; + private static GUIStyle s_separatorStyle; + + public static void DrawLinkRow(params (string label, Action onClick)[] links) + { + if (s_linkStyle == null) + { + s_linkStyle = new GUIStyle(GUI.skin.label) + { + fontStyle = FontStyle.Bold, + fontSize = 10, + alignment = TextAnchor.MiddleLeft, + normal = { textColor = new Color(0.35f, 0.55f, 0.75f) }, + hover = { textColor = EditorGUIUtility.isProSkin ? Color.white : Color.black }, + // padding = new RectOffset(0, 0, 0, 0), + // margin = new RectOffset(0, 0, 0, 0) + }; + } + + if (s_separatorStyle == null) + { + s_separatorStyle = new GUIStyle(GUI.skin.label) + { + fontSize = 12, + alignment = TextAnchor.MiddleCenter, + normal = { textColor = new Color(0.9f, 0.9f, 0.9f,1f) }, + padding = new RectOffset(0, 0, 1, 0), + margin = new RectOffset(0, 0, 0, 0) + }; + } + + float maxWidth = EditorGUIUtility.currentViewWidth - 40; // scroll + float currentLineWidth = 0; + + GUILayout.BeginVertical(); + GUILayout.BeginHorizontal(); + + for (int i = 0; i < links.Length; i++) + { + var content = new GUIContent(links[i].label); + Vector2 size = s_linkStyle.CalcSize(content); + float neededWidth = size.x + 8; // text + | + + // new line + if (currentLineWidth + neededWidth > maxWidth) + { + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + currentLineWidth = 0; + } + + if (DrawClickableButton(links[i].label, onClick: links[i].onClick)) + { + // nothing here + } + currentLineWidth += size.x; + + if (i < links.Length - 1) + { + GUILayout.Space(8); + // GUILayout.Label("|", s_separatorStyle, GUILayout.Width(12)); + // GUILayout.Space(2); + + currentLineWidth += 8; // width | + } + } + + GUILayout.EndHorizontal(); + GUILayout.EndVertical(); + } + + public static bool DrawClickableButton(string text, Action onClick = null, GUIStyle baseStyle = null) + { + if (s_linkStyle == null) + { + s_linkStyle = new GUIStyle(baseStyle ?? GUI.skin.label) + { + fontStyle = FontStyle.Bold, + fontSize = 10, + alignment = TextAnchor.MiddleLeft, + normal = { textColor = new Color(0.35f, 0.55f, 0.75f) }, + hover = { textColor = EditorGUIUtility.isProSkin ? Color.white : Color.black } + }; + } + + Rect rect = GUILayoutUtility.GetRect(new GUIContent(text), s_linkStyle, GUILayout.ExpandWidth(false)); + bool clicked = GUI.Button(rect, text, s_linkStyle); + + EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link); + + if (clicked) + onClick?.Invoke(); + + return clicked; + } + + public static bool DrawClickableLink(string text, string url, bool useEmoji = false, GUIStyle baseStyle = null) + { + if (s_linkStyle == null) + { + s_linkStyle = new GUIStyle(baseStyle ?? GUI.skin.label) + { + fontStyle = FontStyle.Bold, + fontSize = 10, + //normal = { textColor = new Color(0.20f, 0.50f, 0.80f) }, + normal = { textColor = new Color(0.35f, 0.55f, 0.75f) }, + hover = { textColor = EditorGUIUtility.isProSkin ? Color.white : Color.black } + }; + } + + if (useEmoji) + text += " \U0001F517"; //\U0001F310 + bool clicked = GUILayout.Button(text, s_linkStyle, GUILayout.ExpandWidth(false)); + EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link); + + if (clicked) + { + Application.OpenURL(url); + } + + return clicked; + } + + public static int IntSlider(GUIContent guiContent, int value, int min, int max, int step) + { + int newValue = EditorGUILayout.IntSlider(guiContent, value, min, max); + int roundedValue = Mathf.RoundToInt((float)newValue / step) * step; + return Mathf.Clamp(roundedValue, min, max); + } + + public readonly struct FoldoutScope : IDisposable + { + private readonly bool wasIndent; + + public FoldoutScope(AnimBool value, out bool shouldDraw, string label, bool indent = true, SerializedProperty toggle = null) + { + value.target = Foldout(value.target, label, toggle); + shouldDraw = EditorGUILayout.BeginFadeGroup(value.faded); + if (shouldDraw && indent) + { + Indent(); + wasIndent = true; + } + else + { + wasIndent = false; + } + } + + public void Dispose() + { + if (wasIndent) + EndIndent(); + EditorGUILayout.EndFadeGroup(); + } + } + + public static void HorizontalLine(float height = 1, float width = -1, Vector2 margin = new Vector2()) + { + GUILayout.Space(margin.x); + + var rect = EditorGUILayout.GetControlRect(false, height); + if (width > -1) + { + var centerX = rect.width / 2; + rect.width = width; + rect.x += centerX - width / 2; + } + + Color color = EditorStyles.label.active.textColor; + color.a = 0.5f; + EditorGUI.DrawRect(rect, color); + + GUILayout.Space(margin.y); + } + + public static bool Foldout(bool value, string label, SerializedProperty toggle = null) + { + bool _value; + EditorGUILayout.BeginVertical(EditorStyles.helpBox); + EditorGUILayout.BeginHorizontal(); + + if (toggle != null && !toggle.boolValue) + { + EditorGUI.BeginDisabledGroup(true); + _value = EditorGUILayout.Toggle(value, EditorStyles.foldout); + EditorGUI.EndDisabledGroup(); + + _value = false; + } + else + { + _value = EditorGUILayout.Toggle(value, EditorStyles.foldout); + } + + if (toggle != null) + { + EditorGUI.BeginChangeCheck(); + EditorGUILayout.PropertyField(toggle, GUIContent.none, GUILayout.Width(20)); + if (EditorGUI.EndChangeCheck() && toggle.boolValue) + _value = true; + } + + EditorGUILayout.EndHorizontal(); + EditorGUILayout.EndVertical(); + + var rect = GUILayoutUtility.GetLastRect(); + rect.x += 20; + rect.width -= 20; + + if (toggle != null && !toggle.boolValue) + { + EditorGUI.BeginDisabledGroup(true); + EditorGUI.LabelField(rect, label, EditorStyles.boldLabel); + EditorGUI.EndDisabledGroup(); + } + else + { + EditorGUI.LabelField(rect, label, EditorStyles.boldLabel); + } + + return _value; + } + + public static void Indent() + { + EditorGUILayout.BeginHorizontal(); + GUILayout.Space(16); + EditorGUILayout.BeginVertical(); + } + + public static void EndIndent() + { + GUILayout.Space(10); + EditorGUILayout.EndVertical(); + EditorGUILayout.EndHorizontal(); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/HEditorUtils.cs.meta b/Assets/External/HTraceWSGI/Scripts/Editor/HEditorUtils.cs.meta new file mode 100644 index 000000000..5ae229386 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/HEditorUtils.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3d4073239f33edc43a6c326a6be0874d +timeCreated: 1675348234 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Editor/HEditorUtils.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/HTraceWSGIEditor.cs b/Assets/External/HTraceWSGI/Scripts/Editor/HTraceWSGIEditor.cs new file mode 100644 index 000000000..13f04220c --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/HTraceWSGIEditor.cs @@ -0,0 +1,653 @@ +//pipelinedefine +#define H_URP + +#if UNITY_EDITOR + +using HTraceWSGI.Scripts.Infrastructure.URP; +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Editor.WindowsAndMenu; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Services.VoxelCameras; +using System; +using UnityEditor; +using UnityEditor.AnimatedValues; +using UnityEditor.IMGUI.Controls; +using UnityEditor.Rendering; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Editor +{ + [CustomEditor(typeof(Scripts.HTraceWSGI))] + internal class HTraceWSGIEditor : UnityEditor.Editor + { + SerializedProperty _globalSettingsTab; + SerializedProperty _ssLightingTab; + SerializedProperty _wsgiTab; + SerializedProperty _reflectionsTab; + SerializedProperty _lightingTab; + SerializedProperty _debugTab; + + SerializedProperty _showVoxelParams; + SerializedProperty _showUpdateOptions; + + private AnimBool AnimBoolGeneralTab; + private AnimBool AnimBoolWSGITab; + private AnimBool AnimBoolLightingTab; + private AnimBool AnimBoolSsLightingTab; + private AnimBool AnimBoolReflIndirLightingTab; + private AnimBool AnimBoolDebugTab; + private AnimBool AnimBoolEMPTY; + + SerializedProperty GeneralSettings; + SerializedProperty LightingSettings; + SerializedProperty VoxelizationSettings; + SerializedProperty ScreenSpaceLightingSettings; + SerializedProperty ReflectionIndirectLightingSettings; + SerializedProperty DebugSettings; + + // Debug Tab + SerializedProperty DebugModeWS; + SerializedProperty HBuffer; + SerializedProperty VolumetricDebug; + SerializedProperty AttachToSceneCamera; + + SerializedProperty EnableDebug; + SerializedProperty CameraForTests; + SerializedProperty EnableCamerasVisualization; + SerializedProperty ShowBowels; + SerializedProperty TestCheckbox; + SerializedProperty RenderTexture; + SerializedProperty HTraceLayer; + SerializedProperty HInjectionPoint; + SerializedProperty ShowFullDebugLog; + + + // General Tab + SerializedProperty RayCountMode; + SerializedProperty RayLength; + SerializedProperty Multibounce; + SerializedProperty Tracing; + // Pipeline Integration + SerializedProperty Intensity; + SerializedProperty AmbientOverride; + SerializedProperty MetallicIndirectFallback; + + // Lighting Tab + SerializedProperty DirectionalLight; + SerializedProperty SurfaceDiffuseIntensity; + SerializedProperty DirectionalLightIntensity; + SerializedProperty SkyLightIntensity; + SerializedProperty ExpandShadowmap; + SerializedProperty ShadowmapRange; + SerializedProperty ShadowmapUpdateMode; + SerializedProperty EvaluatePunctualLights; + SerializedProperty LightClusterCellLightCount; + SerializedProperty LightClusterCellDensity; + SerializedProperty LightClusterRange; + + // Voxelization Tab + SerializedProperty VoxelizationMask; + SerializedProperty VoxelizationUpdateMode; + SerializedProperty AttachTo; + SerializedProperty LodMax; + SerializedProperty InstancedTerrains; + + SerializedProperty CenterShift; + SerializedProperty VoxelDensity; + SerializedProperty VoxelBounds; + SerializedProperty OverrideBoundsHeightEnable; + SerializedProperty OverrideBoundsHeight; + SerializedProperty GroundLevelEnable; + SerializedProperty GroundLevel; + + //Update Options + SerializedProperty CulledObjectsMask; + SerializedProperty ExpandCullFov; + SerializedProperty ExpandCullRadius; + SerializedProperty DynamicObjectsMask; + + SerializedProperty ExactBounds; + SerializedProperty ExactResolution; + + // Screen space lighting Tab + SerializedProperty EvaluateHitLighting; + SerializedProperty DirectionalOcclusion; + SerializedProperty OcclusionIntensity; + + // Reflection Indirect Lighting Tab + SerializedProperty IndirectEvaluationMethod; + SerializedProperty RayBias; + SerializedProperty MaxRayLength; + SerializedProperty SpatialRadius; + SerializedProperty JitterRadius; + SerializedProperty TemporalJitter; + SerializedProperty OcclusionCheck; + + private bool _showStatistic; + + private string _isScreenSpaceShadowsDisabledMessage = "Screen Space Shadows must be active for Hit Lighting Evaluation!\nYou can enable it in HDRP Asset.\nProject Settings - Quality - HDRP - Lighting - Shadows - Screen Scape Shadows"; + private string _isDynamicRescaleDisabledMessage = "Dynamic Rescale must be not active for Punctual Light Shadows!\nYou can disable it in HDRP Asset.\nProject Settings - Quality - HDRP - Lighting - Shadows - Punctual Light Shadows - Light Atlas - Dynamic Rescale"; + + private void OnEnable() + { + PropertiesRelative(); + + AnimBoolGeneralTab = new AnimBool(_globalSettingsTab.boolValue); + AnimBoolGeneralTab.valueChanged.RemoveAllListeners(); + AnimBoolGeneralTab.valueChanged.AddListener(Repaint); + + AnimBoolSsLightingTab = new AnimBool(_ssLightingTab.boolValue); + AnimBoolSsLightingTab.valueChanged.RemoveAllListeners(); + AnimBoolSsLightingTab.valueChanged.AddListener(Repaint); + + AnimBoolReflIndirLightingTab = new AnimBool(_reflectionsTab.boolValue); + AnimBoolReflIndirLightingTab.valueChanged.RemoveAllListeners(); + AnimBoolReflIndirLightingTab.valueChanged.AddListener(Repaint); + + AnimBoolWSGITab = new AnimBool(_wsgiTab.boolValue); + AnimBoolWSGITab.valueChanged.RemoveAllListeners(); + AnimBoolWSGITab.valueChanged.AddListener(Repaint); + + AnimBoolLightingTab = new AnimBool(_lightingTab.boolValue); + AnimBoolLightingTab.valueChanged.RemoveAllListeners(); + AnimBoolLightingTab.valueChanged.AddListener(Repaint); + + AnimBoolDebugTab = new AnimBool(_debugTab.boolValue); + AnimBoolDebugTab.valueChanged.RemoveAllListeners(); + AnimBoolDebugTab.valueChanged.AddListener(Repaint); + + AnimBoolEMPTY = new AnimBool(false); + } + + //https://docs.unity3d.com/ScriptReference/IMGUI.Controls.PrimitiveBoundsHandle.DrawHandle.html + private readonly BoxBoundsHandle _boundsHandle = new BoxBoundsHandle(); + + protected virtual void OnSceneGUI() + { + if (VoxelizationRuntimeData.VoxelCamera == null) //when disabled HTrace component it's null + return; + + if (VoxelsService.Instance?.BoundsGizmo == null) // it may not created yet + return; + + Bounds voxelCameraBounds = VoxelsService.Instance.GetVoxelCameraBounds(); + _boundsHandle.center = voxelCameraBounds.center; + _boundsHandle.size = voxelCameraBounds.size; + + _boundsHandle.handleColor = Color.clear; + // draw the handle + _boundsHandle.DrawHandle(); + } + + public override void OnInspectorGUI() + { + serializedObject.Update(); + UpdateStandartStyles(); + // base.OnInspectorGUI(); + //return; + + AnimBoolEMPTY = new AnimBool(false); + Scripts.HTraceWSGI trgt = (Scripts.HTraceWSGI)target; + + Color standartBackgroundColor = GUI.backgroundColor; + Color standartColor = GUI.color; + + WarningsHandle(); + + using (new HEditorUtils.FoldoutScope(AnimBoolGeneralTab, out var shouldDraw, HEditorStyles.GlobalSettings.text)) + { + _globalSettingsTab.boolValue = shouldDraw; + if (shouldDraw) + { + EditorGUILayout.PropertyField(DebugModeWS, HEditorStyles.DebugModeContent); + if ((DebugModeWS)DebugModeWS.enumValueIndex == Scripts.Globals.DebugModeWS.MainBuffers) + { + EditorGUILayout.PropertyField(HBuffer, HEditorStyles.HBuffer); + } + + if ((DebugModeWS)DebugModeWS.enumValueIndex == Scripts.Globals.DebugModeWS.LightClusterHeatmap || (DebugModeWS)DebugModeWS.enumValueIndex == Scripts.Globals.DebugModeWS.LightClusterColor) + EditorGUILayout.PropertyField(VolumetricDebug, HEditorStyles.VolumetricDebug); + + EditorGUILayout.Space(5f); + + EditorGUILayout.PropertyField(RayCountMode, HEditorStyles.RayCountModeContent); + RayLength.intValue = EditorGUILayout.IntSlider(HEditorStyles.RayLengthContent, RayLength.intValue, 0, 100); + EditorGUILayout.PropertyField(Multibounce, HEditorStyles.MultibounceContent); + EditorGUILayout.Space(5f); + EditorGUILayout.LabelField("Pipeline Integration", EditorStyles.boldLabel); + EditorGUILayout.Slider(Intensity, 0.1f, 5.0f, HEditorStyles.Intensity); + EditorGUILayout.PropertyField(AmbientOverride, HEditorStyles.AmbientOverride); + EditorGUILayout.PropertyField(MetallicIndirectFallback, HEditorStyles.MetallicIndirectFallback); + } + } + + + using (new HEditorUtils.FoldoutScope(AnimBoolLightingTab, out var shouldDraw, HEditorStyles.Lighting.text)) + { + _lightingTab.boolValue = shouldDraw; + if (shouldDraw) + { + EditorGUILayout.PropertyField(DirectionalLight, HEditorStyles.DirectionalLightContent); + + if (DirectionalLight.objectReferenceValue == null) + { + EditorGUILayout.HelpBox("Directional Light is not set", MessageType.Error); + } + + + if (Tracing.enumValueIndex == (int)Scripts.Globals.TracingMode.SoftwareTracing) + { + EditorGUILayout.Slider(ExpandShadowmap, 1.0f, 3.0f, HEditorStyles.ExpandShadowmapContent); + } + + if (Tracing.enumValueIndex == (int)Scripts.Globals.TracingMode.HardwareTracing) + { + EditorGUILayout.Slider(ShadowmapRange, 10f, 500f, HEditorStyles.ShadowmapRange); + EditorGUILayout.PropertyField(ShadowmapUpdateMode, HEditorStyles.ShadowmapUpdateMode); + } + + EditorGUILayout.Space(3f); + + { + EditorGUILayout.LabelField("Light Cluster", EditorStyles.boldLabel); + + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(EvaluatePunctualLights, HEditorStyles.EvaluatePunctualLights); + +// #if H_HDRP +// if (EvaluatePunctualLights.boolValue == true && HRenderer.UseDynamicViewportRescale == true) +// { +// //EditorGUILayout.HelpBox("Screen Space Shadows must be active for Hit Lighting Evaluation", MessageType.Warning); +// CoreEditorUtils.DrawFixMeBox(_isDynamicRescaleDisabledMessage, MessageType.Error, HEditorStyles.OpenButtonName , () => +// { +// var hdrpAsset = HRenderer.HdrpAsset; +// if (hdrpAsset != null) +// { +// Selection.activeObject = hdrpAsset; +// +// try // we need it, because we get a random error? +// { +// string path = AssetDatabase.GetAssetPath(hdrpAsset); +// if (!string.IsNullOrEmpty(path)) +// { +// var asset = AssetDatabase.LoadAssetAtPath(path); +// if (asset != null) +// EditorGUIUtility.PingObject(asset); +// } +// } +// catch (Exception e) +// { +// // ignored +// } +// } +// +// // another way to open it: +// //SettingsService.OpenProjectSettings("Project/Quality"); +// //GUIUtility.ExitGUI(); +// }); +// } +// #endif + LightClusterCellLightCount.intValue = HEditorUtils.IntSlider(HEditorStyles.LightClusterCellLightCount, LightClusterCellLightCount.intValue, 2, 16, 2); + LightClusterCellDensity.intValue = HEditorUtils.IntSlider(HEditorStyles.LightClusterCellDensity, LightClusterCellDensity.intValue, 16, 64, 4); + if (Tracing.enumValueIndex == (int)Scripts.Globals.TracingMode.HardwareTracing) + LightClusterRange.intValue = EditorGUILayout.IntSlider(HEditorStyles.LightClusterRange, LightClusterRange.intValue, 10, 500); + EditorGUI.indentLevel--; + } + } + + } + + if (trgt.NeedToReallocForUI == true) + { + GUI.backgroundColor = HEditorStyles.warningBackgroundColor; + //GUI.color = HEditorStyles.warningColor; + } + + using (new HEditorUtils.FoldoutScope(AnimBoolWSGITab, out var shouldDraw, HEditorStyles.VoxelizationContent.text)) + { + _wsgiTab.boolValue = shouldDraw; + + GUI.backgroundColor = standartBackgroundColor; + //GUI.color = standartColor; + if (shouldDraw) + { + EditorGUILayout.PropertyField(VoxelizationMask, HEditorStyles.VoxelizationMaskContent); + EditorGUILayout.PropertyField(VoxelizationUpdateMode, HEditorStyles.VoxelizationUpdateTypeContent); + + EditorGUILayout.PropertyField(AttachTo, HEditorStyles.AttachToContent); + + if (AttachTo.objectReferenceValue != null) + { + if (((Transform)AttachTo.objectReferenceValue).gameObject.GetComponent() != null) + { + EditorGUILayout.Slider(CenterShift, - VoxelBounds.intValue * 0.3f, VoxelBounds.intValue * 0.3f, HEditorStyles.CenterShiftContent); + CenterShift.floatValue = Mathf.Clamp(CenterShift.floatValue, -VoxelBounds.intValue * 0.3f, VoxelBounds.intValue * 0.3f); + } + } + + if (AttachTo.objectReferenceValue == null) + { + EditorGUILayout.HelpBox("Set object to follow voxelization camera", MessageType.Error); + } + LodMax.intValue = EditorGUILayout.IntSlider(HEditorStyles.MaximumLodContent, LodMax.intValue, 0, HConstants.MAX_LOD_LEVEL); + + EditorGUILayout.Space(3f); + + if (trgt.NeedToReallocForUI == true) + { + GUI.backgroundColor = HEditorStyles.warningBackgroundColor; + GUI.color = HEditorStyles.warningColor; + } + + _showVoxelParams.boolValue = EditorGUILayout.BeginFoldoutHeaderGroup(_showVoxelParams.boolValue, "Parameters"); + GUI.backgroundColor = standartBackgroundColor; + GUI.color = standartColor; + + if (_showVoxelParams.boolValue) + { + EditorGUI.indentLevel++; + + EditorGUILayout.Slider(VoxelDensity, 0.0f, 1.0f, HEditorStyles.VoxelDensityContent); + + VoxelBounds.intValue = EditorGUILayout.IntSlider(HEditorStyles.VoxelBoundsContent, VoxelBounds.intValue, 5, HConfig.MAX_VOXEL_BOUNDS); + + EditorGUILayout.BeginHorizontal(); + //EditorGUILayout.PropertyField(OverrideBoundsHeightEnable, HEditorStyles.OverrideBoundsHeightEnableContent); + OverrideBoundsHeightEnable.boolValue = EditorGUILayout.ToggleLeft( + OverrideBoundsHeightEnable.boolValue == false ? HEditorStyles.OverrideBoundsHeightEnableContent2 : GUIContent.none, + OverrideBoundsHeightEnable.boolValue, GUILayout.MaxWidth(OverrideBoundsHeightEnable.boolValue == false ? 160f : 30f)); + if (OverrideBoundsHeightEnable.boolValue == true) + { + OverrideBoundsHeight.intValue = VoxelBounds.intValue < OverrideBoundsHeight.intValue ? VoxelBounds.intValue : OverrideBoundsHeight.intValue; + OverrideBoundsHeight.intValue = OverrideBoundsHeight.intValue < 1 ? 1 : OverrideBoundsHeight.intValue; + OverrideBoundsHeight.intValue = EditorGUILayout.IntSlider(HEditorStyles.OverrideBoundsHeightEnableContent, OverrideBoundsHeight.intValue, 1, VoxelBounds.intValue); + } + else + { + OverrideBoundsHeight.intValue = VoxelBounds.intValue; + } + + EditorGUILayout.EndHorizontal(); + + EditorGUILayout.BeginHorizontal(); + //EditorGUILayout.PropertyField(GroundLevelEnable, HEditorStyles.GroundLevelEnableContent); + GroundLevelEnable.boolValue = EditorGUILayout.ToggleLeft(GroundLevelEnable.boolValue == false ? HEditorStyles.GroundLevelEnableContent2 : GUIContent.none, + GroundLevelEnable.boolValue, GUILayout.MaxWidth(GroundLevelEnable.boolValue == false ? 160f : 30f)); + if (GroundLevelEnable.boolValue == true) + { + EditorGUILayout.PropertyField(GroundLevel, HEditorStyles.GroundLevelEnableContent); + } + + EditorGUILayout.EndHorizontal(); + + if (trgt.NeedToReallocForUI == true) + { + GUI.backgroundColor = HEditorStyles.warningBackgroundColor; + GUI.color = HEditorStyles.warningColor; + } + + EditorGUILayout.BeginHorizontal(); + + if (GUILayout.Button("Apply Parameters", HEditorStyles.standartButton)) + { + VoxelizationRuntimeData.OnReallocTextures?.Invoke(); + } + + GUI.backgroundColor = standartBackgroundColor; + GUI.color = standartColor; + + if (GUILayout.Button(_showStatistic ? "Hide Statistics" : "Show Statistics")) + { + _showStatistic = !_showStatistic; + } + + EditorGUILayout.EndHorizontal(); + + if (_showStatistic) + { + EditorGUILayout.Space(10f); + + Vector3Int voxelResolution = HMath.CalculateVoxelResolution_UI(VoxelBounds.intValue, VoxelDensity.floatValue, OverrideBoundsHeightEnable.boolValue, OverrideBoundsHeight.intValue); + //EditorGUILayout.LabelField($"Voxel Resolution: Width: {(int)voxelResolution.x} Depth: {(int)voxelResolution.y} Height: {(int)voxelResolution.z}"); + + float voxelSize = HMath.CalculateVoxelSizeInCM_UI(VoxelBounds.intValue, VoxelDensity.floatValue); + //EditorGUILayout.LabelField($"Voxel Size: Color {voxelSize:0.0} cm. Position {(voxelSize / 2):0.0} cm."); + + //float texturesSizeInMB = HMath.TexturesSizeInMB_UI(VoxelBounds.intValue, VoxelDensity.floatValue, OverrideBoundsHeightEnable.boolValue, OverrideBoundsHeight.intValue); + float texturesSizeInMB = HMath.TexturesSizeInMB_UI(ExactResolution.vector3IntValue, (VoxelizationUpdateMode)VoxelizationUpdateMode.enumValueIndex); + //EditorGUILayout.LabelField($"GPU Memory Consumption: {texturesSizeInMB:0.0} MB", myStyle); + + GUIStyle myStyle = GUI.skin.GetStyle("HelpBox"); + myStyle.richText = true; + myStyle.fontSize = 12; + + Vector3 voxelsSize = new Vector3(ExactBounds.vector3Value.x / ExactResolution.vector3IntValue.x, ExactBounds.vector3Value.y / ExactResolution.vector3IntValue.y, + ExactBounds.vector3Value.z / ExactResolution.vector3IntValue.z) * 100.0f; + EditorGUILayout.HelpBox( + $"Voxel Resolution: Width: {ExactResolution.vector3IntValue.x} Depth: {ExactResolution.vector3IntValue.y} Height: {ExactResolution.vector3IntValue.z}\n" + + $"Voxel Bounds: {ExactBounds.vector3Value.x} x {ExactBounds.vector3Value.y} x {ExactBounds.vector3Value.z} m\n" + + $"Voxel Size: Color {voxelsSize.x:0.0} cm. Position {(voxelsSize.x / 2):0.0} cm.\n" + + $"GPU Memory Consumption: {texturesSizeInMB:0.00} MB", + MessageType.None); + } + + EditorGUI.indentLevel--; + EditorGUILayout.Space(5f); + } + + //EditorGUILayout.PropertyField(InstancedTerrains, HEditorStyles.InstancedTerrains); + + GUI.backgroundColor = standartBackgroundColor; + //GUI.color = standartColor; + + EditorGUILayout.EndFoldoutHeaderGroup(); + EditorGUILayout.Space(3f); + + if ((VoxelizationUpdateMode)VoxelizationUpdateMode.enumValueIndex == Scripts.Globals.VoxelizationUpdateMode.Partial) + { + + _showUpdateOptions.boolValue = EditorGUILayout.BeginFoldoutHeaderGroup(_showUpdateOptions.boolValue, "Update Options"); + + if (_showUpdateOptions.boolValue) + { + EditorGUI.indentLevel++; + + //todo: after release add + // if (VoxelizationUpdateMode.enumValueIndex == 0 || VoxelizationUpdateMode.enumValueIndex == 1) + // { + // EditorGUILayout.PropertyField(CulledObjectsMask, HEditorStyles.CulledObjectsMaskContent); + // ExpandCullFov.intValue = EditorGUILayout.IntSlider(HEditorStyles.ExpandCullFovContent, ExpandCullFov.intValue, 0, 20); + // EditorGUILayout.Slider(ExpandCullRadius, 0.0f, 3.0f, HEditorStyles.ExpandCullRadiusContent); + // } + + EditorGUILayout.PropertyField(DynamicObjectsMask, HEditorStyles.DynamicObjectsMaskContent); + + EditorGUI.indentLevel--; + EditorGUILayout.Space(5f); + } + + EditorGUILayout.EndFoldoutHeaderGroup(); + } + + } + } + + GUI.backgroundColor = standartBackgroundColor; + //GUI.color = standartColor; + using (new HEditorUtils.FoldoutScope(AnimBoolSsLightingTab, out var shouldDraw, HEditorStyles.ScreenSpaceLightingContent.text)) + { + _ssLightingTab.boolValue = shouldDraw; + if (shouldDraw) + { + EditorGUILayout.PropertyField(DirectionalOcclusion, HEditorStyles.DirectionalOcclusionContent); + // if (DirectionalOcclusion.boolValue == true) + // EditorGUILayout.Slider(OcclusionIntensity, 0.0f, 1.0f, HEditorStyles.OcclusionIntensityContent); + } + } + + + using (new HEditorUtils.FoldoutScope(AnimBoolDebugTab, out var shouldDraw, "Debug Settings"/*, toggle: EnableDebug*/)) + { + _debugTab.boolValue = shouldDraw; + if (shouldDraw) + { + EditorGUILayout.PropertyField(AttachToSceneCamera, new GUIContent("Follow Scene Camera")); + + + if (false) + { + HEditorUtils.HorizontalLine(1f); + EditorGUILayout.LabelField("DEVS FIELDS:", HEditorStyles.VersionStyle); + EditorGUILayout.PropertyField(CameraForTests, new GUIContent("Camera For Tests")); + + EditorGUILayout.PropertyField(EnableCamerasVisualization, new GUIContent("Enable Cameras visualization")); + EditorGUILayout.PropertyField(ShowBowels, new GUIContent("Show Bowels")); + EditorGUILayout.PropertyField(ShowFullDebugLog, new GUIContent("Show Full Debug Log")); + EditorGUILayout.PropertyField(TestCheckbox, new GUIContent("Test Checkbox")); + EditorGUILayout.PropertyField(HTraceLayer, new GUIContent("H Trace Layer")); + EditorGUILayout.PropertyField(RenderTexture, new GUIContent("Render Texture")); + } + + } + } + + HEditorUtils.HorizontalLine(1f); + EditorGUILayout.Space(3); + //EditorGUILayout.LabelField("HTrace WSGI Version: 1.3.1", HEditorStyles.VersionStyle); + HEditorUtils.DrawLinkRow( + ($"Documentation (v. " + HConstants.VERSION + ")", () => Application.OpenURL(HNames.HTRACE_WSGI_DOCUMENTATION_LINK)), + ("Discord", () => Application.OpenURL(HNames.HTRACE_DISCORD_LINK)), + ("Bug report", () => HBugReporterWindow.ShowWindow()) + ); + + serializedObject.ApplyModifiedProperties(); + } + + private const string NO_RENDERER_FEATURE_MESSAGE = "HTrace World Space Global Illumination feature is missing in the active URP renderer."; + private const string RENDERER_FEATURE_OFF_MESSAGE = "HTrace World Space Global Illumination is disabled in the active URP renderer."; + + private void WarningsHandle() + { + var hTraceRendererFeature = HRendererURP.GetRendererFeatureByTypeName(nameof(HTraceWSGIRendererFeature)) as HTraceWSGIRendererFeature; + if (hTraceRendererFeature == null) + { + EditorGUILayout.Space(); + CoreEditorUtils.DrawFixMeBox(NO_RENDERER_FEATURE_MESSAGE, MessageType.Error, HEditorStyles.FixButtonName, () => + { + HRendererURP.AddHTraceRendererFeatureToUniversalRendererData(); + GUIUtility.ExitGUI(); + }); + //EditorGUILayout.HelpBox(NO_RENDERER_FEATURE_MESSAGE, MessageType.Error, wide: true); + return; + } + else if (!hTraceRendererFeature.isActive) + { + EditorGUILayout.Space(); + CoreEditorUtils.DrawFixMeBox(RENDERER_FEATURE_OFF_MESSAGE, MessageType.Warning, HEditorStyles.FixButtonName, () => + { + hTraceRendererFeature.SetActive(true); + GUIUtility.ExitGUI(); + }); + EditorGUILayout.Space(); + } + } + + private void UpdateStandartStyles() + { + HEditorStyles.foldout.fontStyle = FontStyle.Bold; + } + + private void PropertiesRelative() + { + _globalSettingsTab = serializedObject.FindProperty("_globalSettingsTab"); + _ssLightingTab = serializedObject.FindProperty("_screenSpaceLightingTab"); + _wsgiTab = serializedObject.FindProperty("_wsgiTab"); + _reflectionsTab = serializedObject.FindProperty("_reflectionsTab"); + _lightingTab = serializedObject.FindProperty("_lightingTab"); + _debugTab = serializedObject.FindProperty("_debugTab"); + + _showUpdateOptions = serializedObject.FindProperty("_showUpdateOptions"); + _showVoxelParams = serializedObject.FindProperty("_showVoxelParams"); + + GeneralSettings = serializedObject.FindProperty("GeneralSettings"); + VoxelizationSettings = serializedObject.FindProperty("VoxelizationSettings"); + LightingSettings = serializedObject.FindProperty("LightingSettings"); + ScreenSpaceLightingSettings = serializedObject.FindProperty("ScreenSpaceLightingSettings"); + ReflectionIndirectLightingSettings = serializedObject.FindProperty("ReflectionIndirectLightingSettings"); + DebugSettings = serializedObject.FindProperty("DebugSettings"); + + //Debug Tab + EnableDebug = DebugSettings.FindPropertyRelative("_enableDebug"); + AttachToSceneCamera = DebugSettings.FindPropertyRelative("AttachToSceneCamera"); + + //Devs + CameraForTests = DebugSettings.FindPropertyRelative("CameraForTests"); + EnableCamerasVisualization = DebugSettings.FindPropertyRelative("EnableCamerasVisualization"); + ShowBowels = DebugSettings.FindPropertyRelative("ShowBowels"); + ShowFullDebugLog = DebugSettings.FindPropertyRelative("ShowFullDebugLog"); + TestCheckbox = DebugSettings.FindPropertyRelative("TestCheckbox"); + RenderTexture = DebugSettings.FindPropertyRelative("RenderTexture"); + HTraceLayer = DebugSettings.FindPropertyRelative("HTraceLayer"); + + //Global Tab + DebugModeWS = GeneralSettings.FindPropertyRelative("DebugModeWS"); + HBuffer = GeneralSettings.FindPropertyRelative("HBuffer"); + VolumetricDebug = GeneralSettings.FindPropertyRelative("VolumetricDebug"); + Tracing = GeneralSettings.FindPropertyRelative("TracingMode"); + RayCountMode = GeneralSettings.FindPropertyRelative("_rayCountMode"); + RayLength = GeneralSettings.FindPropertyRelative("_rayLength"); + Multibounce = GeneralSettings.FindPropertyRelative("Multibounce"); + Intensity = GeneralSettings.FindPropertyRelative("_intensity"); + AmbientOverride = GeneralSettings.FindPropertyRelative("AmbientOverride"); + MetallicIndirectFallback = GeneralSettings.FindPropertyRelative("MetallicIndirectFallback"); + + // Lighting data + DirectionalLight = LightingSettings.FindPropertyRelative("DirectionalLight"); + ExpandShadowmap = LightingSettings.FindPropertyRelative("_expandShadowmap"); + ShadowmapRange = LightingSettings.FindPropertyRelative("_shadowmapRange"); + ShadowmapUpdateMode = LightingSettings.FindPropertyRelative("ShadowmapUpdateMode"); + EvaluatePunctualLights = LightingSettings.FindPropertyRelative("EvaluatePunctualLights"); + LightClusterCellLightCount = LightingSettings.FindPropertyRelative("_lightClusterCellLightCount"); + LightClusterCellDensity = LightingSettings.FindPropertyRelative("_lightClusterCellDensity"); + LightClusterRange = LightingSettings.FindPropertyRelative("_lightClusterRange"); + + // Voxel Data + VoxelizationMask = VoxelizationSettings.FindPropertyRelative("VoxelizationMask"); + VoxelizationUpdateMode = VoxelizationSettings.FindPropertyRelative("VoxelizationUpdateMode"); + AttachTo = VoxelizationSettings.FindPropertyRelative("AttachTo"); + LodMax = VoxelizationSettings.FindPropertyRelative("_lodMax"); + InstancedTerrains = VoxelizationSettings.FindPropertyRelative("InstancedTerrains"); + + VoxelDensity = VoxelizationSettings.FindPropertyRelative("_voxelDensity"); + VoxelBounds = VoxelizationSettings.FindPropertyRelative("_voxelBounds"); + OverrideBoundsHeightEnable = VoxelizationSettings.FindPropertyRelative("_overrideBoundsHeightEnable"); + OverrideBoundsHeight = VoxelizationSettings.FindPropertyRelative("_overrideBoundsHeight"); + CenterShift = VoxelizationSettings.FindPropertyRelative("CenterShift"); + GroundLevelEnable = VoxelizationSettings.FindPropertyRelative("GroundLevelEnable"); + GroundLevel = VoxelizationSettings.FindPropertyRelative("GroundLevel"); + + CulledObjectsMask = VoxelizationSettings.FindPropertyRelative("CulledObjectsMask"); + ExpandCullFov = VoxelizationSettings.FindPropertyRelative("_expandCullFov"); + ExpandCullRadius = VoxelizationSettings.FindPropertyRelative("_expandCullRadius"); + DynamicObjectsMask = VoxelizationSettings.FindPropertyRelative("DynamicObjectsMask"); + + ExactBounds = VoxelizationSettings.FindPropertyRelative("ExactData").FindPropertyRelative("Bounds"); + ExactResolution = VoxelizationSettings.FindPropertyRelative("ExactData").FindPropertyRelative("Resolution"); + + // Screen Space Lighting Tab + EvaluateHitLighting = ScreenSpaceLightingSettings.FindPropertyRelative("EvaluateHitLighting"); + DirectionalOcclusion = ScreenSpaceLightingSettings.FindPropertyRelative("DirectionalOcclusion"); + OcclusionIntensity = ScreenSpaceLightingSettings.FindPropertyRelative("_occlusionIntensity"); + + // Reflection Indirect Lighting Tab + IndirectEvaluationMethod = ReflectionIndirectLightingSettings.FindPropertyRelative("IndirectEvaluationMethod"); + RayBias = ReflectionIndirectLightingSettings.FindPropertyRelative("_rayBias"); + MaxRayLength = ReflectionIndirectLightingSettings.FindPropertyRelative("_maxRayLength"); + SpatialRadius = ReflectionIndirectLightingSettings.FindPropertyRelative("SpatialRadius"); + JitterRadius = ReflectionIndirectLightingSettings.FindPropertyRelative("_jitterRadius"); + TemporalJitter = ReflectionIndirectLightingSettings.FindPropertyRelative("TemporalJitter"); + OcclusionCheck = ReflectionIndirectLightingSettings.FindPropertyRelative("OcclusionCheck"); + } + } +} +#endif diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/HTraceWSGIEditor.cs.meta b/Assets/External/HTraceWSGI/Scripts/Editor/HTraceWSGIEditor.cs.meta new file mode 100644 index 000000000..66ed9d8ed --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/HTraceWSGIEditor.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7a0a2fecb6d94a04faf8cbe51bdd0c27 +timeCreated: 1674796690 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Editor/HTraceWSGIEditor.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/SceneViewDrawModeTracker.cs b/Assets/External/HTraceWSGI/Scripts/Editor/SceneViewDrawModeTracker.cs new file mode 100644 index 000000000..ccb475ce8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/SceneViewDrawModeTracker.cs @@ -0,0 +1,39 @@ +#if UNITY_EDITOR +using UnityEditor; + +namespace HTraceWSGI.Scripts.Editor +{ + [InitializeOnLoad] + public static class SceneViewDrawModeTracker + { + private const string Shaded = "Shaded"; + private const string Wireframe = "Wireframe"; + private const string ShadedWireframe = "Shaded Wireframe"; + private const string Unlit = "Unlit"; + + private static bool s_isShaded = true; + private static bool s_isWireframe = true; + private static bool s_isShadedWireframe = true; + private static bool s_isUnlit = true; + + public static bool IsShaded => s_isShaded; + public static bool IsWireframe => s_isWireframe; + public static bool IsShadedWireframe => s_isShadedWireframe; + public static bool IsUnlit => s_isUnlit; + + static SceneViewDrawModeTracker() + { + SceneView.duringSceneGui += OnSceneGUI; + + } + + static void OnSceneGUI(SceneView view) + { + s_isShaded = (view.cameraMode.name == Shaded); + s_isWireframe = (view.cameraMode.name == Wireframe); + s_isShadedWireframe = (view.cameraMode.name == ShadedWireframe); + s_isUnlit = (view.cameraMode.name == Unlit); + } + } +} +#endif diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/SceneViewDrawModeTracker.cs.meta b/Assets/External/HTraceWSGI/Scripts/Editor/SceneViewDrawModeTracker.cs.meta new file mode 100644 index 000000000..7743ce4eb --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/SceneViewDrawModeTracker.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a89a0f6c18c94cafb9496ceccbd72c91 +timeCreated: 1758798179 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Editor/SceneViewDrawModeTracker.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu.meta b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu.meta new file mode 100644 index 000000000..fb1cdfd60 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7a1ac13ec6c24d448dc5c41354879601 +timeCreated: 1758279619 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HBugReporterWindow.cs b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HBugReporterWindow.cs new file mode 100644 index 000000000..d32177257 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HBugReporterWindow.cs @@ -0,0 +1,98 @@ +using HTraceWSGI.Scripts.Globals; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace HTraceWSGI.Scripts.Editor.WindowsAndMenu +{ +#if UNITY_EDITOR + public class HBugReporterWindow : EditorWindow + { + private string _reportData = ""; + + private GUIStyle _styleLabel; + private Vector2 _scrollPosition = Vector2.zero; + + [MenuItem("Window/HTrace/Report Bug HTrace WSGI", false, priority: 32)] + public static void ShowWindow() + { + var window = GetWindow(false, "Report Bug", true); + window.minSize = new Vector2(400, 330); + } + + void OnEnable() + { + _reportData = ""; + + var pipeline = HRenderer.CurrentHRenderPipeline.ToString(); + + _reportData += $"{HNames.ASSET_NAME_FULL} Version: {HConstants.VERSION}" + "\n"; + + _reportData += "\n"; + + _reportData += "Unity Version: " + Application.unityVersion + "\n"; + _reportData += "Pipeline: " + pipeline + "\n"; + _reportData += "Platform: " + Application.platform + "\n"; + _reportData += "Graphics API: " + SystemInfo.graphicsDeviceType + "\n"; + + _reportData += "\n"; + + _reportData += "OS: " + SystemInfo.operatingSystem + "\n"; + _reportData += "Graphics: " + SystemInfo.graphicsDeviceName + "\n"; + + _reportData += "\n"; + _reportData += "Additional details:\n"; + } + + void OnGUI() + { + SetGUIStyles(); + + GUILayout.Space(-2); + + GUILayout.BeginHorizontal(); + GUILayout.Space(15); + + GUILayout.BeginVertical(); + + _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, false, false, GUILayout.Width(this.position.width - 28), GUILayout.Height(this.position.height - 80)); + + GUILayout.Label(_reportData, _styleLabel); + + GUILayout.Space(15); + + if (GUILayout.Button("Copy Details To Clipboard", GUILayout.Height(24))) + { + var copyData = _reportData; + + GUIUtility.systemCopyBuffer = copyData; + } + if (GUILayout.Button("Report Bug on Discord", GUILayout.Height(24))) + { + Application.OpenURL(HNames.HTRACE_DISCORD_BUGS_WSGI_LINK); + } + + GUILayout.FlexibleSpace(); + + GUILayout.Space(20); + + GUILayout.EndScrollView(); + + GUILayout.EndVertical(); + + GUILayout.Space(13); + GUILayout.EndHorizontal(); + } + + void SetGUIStyles() + { + _styleLabel = new GUIStyle(EditorStyles.label) + { + richText = true, + }; + } + } + +#endif +} diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HBugReporterWindow.cs.meta b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HBugReporterWindow.cs.meta new file mode 100644 index 000000000..448875a28 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HBugReporterWindow.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 93d4f16c84d1427788db69e1abd0702f +timeCreated: 1758279662 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HBugReporterWindow.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HMenuAndFilesManager.cs b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HMenuAndFilesManager.cs new file mode 100644 index 000000000..e13afacb4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HMenuAndFilesManager.cs @@ -0,0 +1,52 @@ +#if UNITY_EDITOR +using UnityEditor; +using UnityEngine; +using Debug = UnityEngine.Debug; + +namespace HTraceWSGI.Scripts.Editor.WindowsAndMenu +{ + + public class HMenuAndFilesManager : EditorWindow + { + [MenuItem("GameObject/Rendering/HTrace World Space Global Illumination", false, priority: 30)] + static void CreateHTraceGameObject(MenuCommand menuCommand) + { + HTraceWSGI[] hTraces = FindObjectsOfType(typeof(HTraceWSGI)) as HTraceWSGI[]; + if (hTraces != null && hTraces.Length > 0) + { + Debug.Log("Can't create HTrace, because the scene already contains HTrace instance"); + return; + } + + GameObject go = new GameObject("HTraceWSGI"); + GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject); + go.AddComponent(); + + Undo.RegisterCreatedObjectUndo(go, "Create " + go.name); + Selection.activeObject = go; + } + + [MenuItem("Window/HTrace/HTrace WSGI Open documentation", false)] + private static void OpenDocumentation() + { + Application.OpenURL("https://ipgames.gitbook.io/htrace-wsgi"); + } + + // Rect buttonRect; + // private void OnGUI() + // { + // { + // GUILayout.Label("Editor window with Popup example", EditorStyles.boldLabel); + // if (GUILayout.Button("Popup Options", GUILayout.Width(200))) + // { + // PopupWindow.Show(buttonRect, new PopupExample()); + // } + // if (Event.current.type == EventType.Repaint) buttonRect = GUILayoutUtility.GetLastRect(); + // } + // } + + } + +} + +#endif \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HMenuAndFilesManager.cs.meta b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HMenuAndFilesManager.cs.meta new file mode 100644 index 000000000..ded6523bf --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HMenuAndFilesManager.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: d0d3fd7b9bbe640408c0f39f42d4a168 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Editor/WindowsAndMenu/HMenuAndFilesManager.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions.meta b/Assets/External/HTraceWSGI/Scripts/Extensions.meta new file mode 100644 index 000000000..f861cfa91 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 53228bc897a64102983c3530538644da +timeCreated: 1758606614 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem.meta b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem.meta new file mode 100644 index 000000000..262bb03d6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ebf142b4fa9c44ea8c58d0ef62a14298 +timeCreated: 1758613859 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/CameraHistorySystem.cs b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/CameraHistorySystem.cs new file mode 100644 index 000000000..0974c175a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/CameraHistorySystem.cs @@ -0,0 +1,71 @@ +using System; + +namespace HTraceWSGI.Scripts.Extensions.CameraHistorySystem +{ + public class CameraHistorySystem where T : struct, ICameraHistoryData + { + private const int MaxCameraCount = 4; // minimum 2 + + private int _cameraHistoryIndex; + private readonly T[] _cameraHistoryData = new T[MaxCameraCount]; + + + public int UpdateCameraHistoryIndex(int currentCameraHash) + { + _cameraHistoryIndex = GetCameraHistoryDataIndex(currentCameraHash); + return _cameraHistoryIndex; + } + + private int GetCameraHistoryDataIndex(int cameraHash) + { + // Unroll manually for MAX_CAMERA_COUNT = 4 + if (_cameraHistoryData[0].GetHash() == cameraHash) return 0; + if (_cameraHistoryData[1].GetHash() == cameraHash) return 1; + if (_cameraHistoryData[2].GetHash() == cameraHash) return 2; + if (_cameraHistoryData[3].GetHash() == cameraHash) return 3; + return -1; // new camera + } + + public void UpdateCameraHistoryData() + { + bool cameraHasChanged = _cameraHistoryIndex == -1; + + if (cameraHasChanged) + { + const int lastIndex = MaxCameraCount - 1; + + if (_cameraHistoryData[lastIndex] is IDisposable disposable) + disposable.Dispose(); + + // Shift the camera history data back by one + Array.Copy(_cameraHistoryData, 0, _cameraHistoryData, 1, lastIndex); + + _cameraHistoryIndex = 0; + _cameraHistoryData[0] = new T(); //it's critical + } + } + + public ref T GetCameraData() + { + return ref _cameraHistoryData[_cameraHistoryIndex]; + } + + public T[] GetCameraDatas() + { + return _cameraHistoryData; + } + + public void SetCameraData(T data) + { + _cameraHistoryData[_cameraHistoryIndex] = data; + } + + public void Cleanup() + { + for (int index = 0; index < _cameraHistoryData.Length; index++) + { + _cameraHistoryData[index] = default; + } + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/CameraHistorySystem.cs.meta b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/CameraHistorySystem.cs.meta new file mode 100644 index 000000000..822a84fa1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/CameraHistorySystem.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e0b4b2066c454107b6b14b354d45624b +timeCreated: 1758613888 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/CameraHistorySystem.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/ICameraHistoryData.cs b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/ICameraHistoryData.cs new file mode 100644 index 000000000..d90fd9871 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/ICameraHistoryData.cs @@ -0,0 +1,8 @@ +namespace HTraceWSGI.Scripts.Extensions.CameraHistorySystem +{ + public interface ICameraHistoryData + { + int GetHash(); + void SetHash(int hashIn); + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/ICameraHistoryData.cs.meta b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/ICameraHistoryData.cs.meta new file mode 100644 index 000000000..16354c077 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/ICameraHistoryData.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 729e795b6df94beabf07ce1c9c0aa185 +timeCreated: 1758613869 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Extensions/CameraHistorySystem/ICameraHistoryData.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/ExtensionsURP.cs b/Assets/External/HTraceWSGI/Scripts/Extensions/ExtensionsURP.cs new file mode 100644 index 000000000..75dd17dc1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/ExtensionsURP.cs @@ -0,0 +1,33 @@ +//pipelinedefine +#define H_URP + +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Experimental.Rendering; + +using UnityEngine.Rendering.Universal; +#if UNITY_2023_3_OR_NEWER +using UnityEngine.Rendering.RenderGraphModule; +#endif + +namespace HTraceWSGI.Scripts.Extensions +{ + public static class ExtensionsURP + { + +#if UNITY_2023_3_OR_NEWER + public static TextureHandle CreateTexture(string name, RenderGraph rg, ref TextureDesc desc, GraphicsFormat format, DepthBits depthBufferBits = DepthBits.None, + bool enableRandomWrite = true, bool useMipMap = false, bool autoGenerateMips = false) + { + desc.name = name; + desc.format = format; + desc.depthBufferBits = depthBufferBits; + desc.enableRandomWrite = enableRandomWrite; + desc.useMipMap = useMipMap; + desc.autoGenerateMips = autoGenerateMips; + desc.msaaSamples = MSAASamples.None; + return rg.CreateTexture(desc); + } +#endif //UNITY_2023_3_OR_NEWER + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/ExtensionsURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Extensions/ExtensionsURP.cs.meta new file mode 100644 index 000000000..fec091058 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/ExtensionsURP.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ddbba7b4fe214e178df8cfa241b33fa6 +timeCreated: 1759390448 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Extensions/ExtensionsURP.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/HExtensions.cs b/Assets/External/HTraceWSGI/Scripts/Extensions/HExtensions.cs new file mode 100644 index 000000000..7015f2e9a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/HExtensions.cs @@ -0,0 +1,316 @@ +using System; +using System.Reflection; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Wrappers; +using UnityEditor; +using UnityEngine; +using UnityEngine.Experimental.Rendering; //For OLD Unity +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Extensions +{ + public enum DebugType + { + Log, + Warning, + Error, + } + + public static class HExtensions + { + public static string ERROR_OUT_RANGE_VALUE = "Your \"{0}\" value is out of range: {1}"; + + public static void DebugPrint(DebugType type, string msg) + { + msg = "HTrace log: " + msg; + + switch (type) + { + case DebugType.Log: + Debug.Log(msg); + break; + case DebugType.Warning: + Debug.LogWarning(msg); + break; + case DebugType.Error: + Debug.LogError(msg); + break; + } + } + + public static ComputeShader LoadComputeShader(string shaderName, HRenderPipeline pipeline = HRenderPipeline.None) + { + string path = $"HTraceWSGI/"; + switch (pipeline) + { + case HRenderPipeline.None: + path += "_Shared/"; + break; + case HRenderPipeline.BIRP: + path += "BIRP/"; + break; + case HRenderPipeline.URP: + path += "URP/"; + break; + case HRenderPipeline.HDRP: + path += "HDRP/"; + break; + } + path += $"Computes/{shaderName}"; + var computeShader = (ComputeShader)Resources.Load(path); + if (computeShader == null) + { + Debug.LogError($"{path} is missing."); + return null; + } + + return computeShader; + } + + public static RayTracingShader LoadRayTracingShader(string shaderName, HRenderPipeline pipeline = HRenderPipeline.None) + { + string path = $"HTraceWSGI/"; + switch (pipeline) + { + case HRenderPipeline.None: + path += "_Shared/"; + break; + case HRenderPipeline.BIRP: + path += "BIRP/"; + break; + case HRenderPipeline.URP: + path += "URP/"; + break; + case HRenderPipeline.HDRP: + path += "HDRP/"; + break; + } + path += $"Computes/{shaderName}"; + var rtShader = (RayTracingShader)Resources.Load(path); + if (rtShader == null) + { + Debug.LogError($"{path} is missing."); + return null; + } + + return rtShader; + } + + public static bool ContainsOnOfElement(this string str, string[] elements) + { + foreach (var element in elements) + { + if (str.Contains(element)) + return true; + } + return false; + } + + public static T Next(this T src) where T : struct + { + if (!typeof(T).IsEnum) throw new ArgumentException(String.Format("Argument {0} is not an Enum", typeof(T).FullName)); + + T[] array = (T[])Enum.GetValues(src.GetType()); + int nextIndex = Array.IndexOf(array, src) + 1; + return (array.Length == nextIndex) ? array[0] : array[nextIndex]; + } + + public static T Prev(this T src) where T : struct + { + if (!typeof(T).IsEnum) throw new ArgumentException(String.Format("Argument {0} is not an Enum", typeof(T).FullName)); + + T[] array = (T[])Enum.GetValues(src.GetType()); + int prevIndex = Array.IndexOf(array, src) - 1; + return (-1 == prevIndex) ? array[array.Length - 1] : array[prevIndex]; + } + + public static int ParseToProbeSize(this RayCountMode rayCountMode) + { + switch (rayCountMode) + { + case RayCountMode.Performance: + return 8; + case RayCountMode.Quality: + return 6; + case RayCountMode.Cinematic: + return 4; + } + + return 6; + } + + public static int ParseToInt(this SpatialRadius spatialRadius) + { + switch (spatialRadius) + { + case SpatialRadius.None: + return 1; + case SpatialRadius.Medium: + return 9; + case SpatialRadius.Wide: + return 25; + } + + return 1; + } + + //custom Attributes +#if UNITY_EDITOR + + /// + /// Read Only attribute. + /// Attribute is use only to mark ReadOnly properties. + /// + public class ReadOnlyAttribute : PropertyAttribute + { + } + + /// + /// This class contain custom drawer for ReadOnly attribute. + /// + [CustomPropertyDrawer(typeof(ReadOnlyAttribute))] + public class ReadOnlyDrawer : PropertyDrawer + { + /// + /// Unity method for drawing GUI in Editor + /// + /// Position. + /// Property. + /// Label. + public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) + { + // Saving previous GUI enabled value + var previousGUIState = GUI.enabled; + // Disabling edit for property + GUI.enabled = false; + // Drawing Property + EditorGUI.PropertyField(position, property, label); + // Setting old GUI enabled value + GUI.enabled = previousGUIState; + } + } +#endif + + /// + /// Attribute used to make a float or int variable in a script be restricted to a specific range. + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] + public class HRangeAttribute : Attribute + { + public readonly bool isFloat; + + public readonly float minFloat; + public readonly float maxFloat; + public readonly int minInt; + public readonly int maxInt; + + /// + /// Attribute used to make a float or int variable in a script be restricted to a specific range. + /// + /// The minimum allowed value. + /// The maximum allowed value. + public HRangeAttribute(float minFloat, float maxFloat) + { + this.minFloat = minFloat; + this.maxFloat = maxFloat; + isFloat = true; + } + + /// + /// Attribute used to make a float or int variable in a script be restricted to a specific range. + /// + /// The minimum allowed value. + /// The maximum allowed value. + public HRangeAttribute(int minInt, int maxInt) + { + this.minInt = minInt; + this.maxInt = maxInt; + isFloat = false; + } + } + + public struct HRangeAttributeElement + { + public bool isFloat; + public float minFloat; + public float maxFloat; + public int minInt; + public int maxInt; + } + + public static float Clamp(float value, Type type, string nameOfField) + { + HRangeAttribute rangeAttribute = null; + + var filed = type.GetField(nameOfField); + if (filed != null) + { + rangeAttribute = filed.GetCustomAttribute(); + } + var property = type.GetProperty(nameOfField); + if (property != null) + { + rangeAttribute = property.GetCustomAttribute(); + } + + return Mathf.Clamp(value, rangeAttribute.minFloat, rangeAttribute.maxFloat); + } + + public static int Clamp(int value, Type type, string nameOfField) + { + HRangeAttribute rangeAttribute = null; + + var filed = type.GetField(nameOfField); + if (filed != null) + { + rangeAttribute = filed.GetCustomAttribute(); + } + var property = type.GetProperty(nameOfField); + if (property != null) + { + rangeAttribute = property.GetCustomAttribute(); + } + + return Mathf.Clamp(value, rangeAttribute.minInt, rangeAttribute.maxInt); + } + + public static void HRelease(this ComputeBuffer computeBuffer) + { + if (computeBuffer != null) + computeBuffer.Release(); + } + + public static void HRelease(this CommandBuffer commandBuffer) + { + if (commandBuffer != null) + { + commandBuffer.Clear(); + commandBuffer.Release(); + } + } + + public static void HRelease(this GraphicsBuffer graphicsBuffer) + { + if (graphicsBuffer != null) + { + graphicsBuffer.Release(); + } + } + + public static void HRelease(this HDynamicBuffer hDynamicBuffer) + { + if (hDynamicBuffer != null) + { + hDynamicBuffer.Release(); + } + } + + public static void HRelease(this RayTracingAccelerationStructure rayTracingAccelerationStructure) + { + if (rayTracingAccelerationStructure != null) + { + rayTracingAccelerationStructure.Release(); + } + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/HExtensions.cs.meta b/Assets/External/HTraceWSGI/Scripts/Extensions/HExtensions.cs.meta new file mode 100644 index 000000000..efcea0cdb --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/HExtensions.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 763c2824f19525148a2eb762b9b84f41 +timeCreated: 1659691524 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Extensions/HExtensions.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/HTraceProfilingScope.cs b/Assets/External/HTraceWSGI/Scripts/Extensions/HTraceProfilingScope.cs new file mode 100644 index 000000000..f08ec7c08 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/HTraceProfilingScope.cs @@ -0,0 +1,317 @@ +// TProfilingSampler.samples should just be an array. Unfortunately, Enum cannot be converted to int without generating garbage. +// This could be worked around by using Unsafe but it's not available at the moment. +// So in the meantime we use a Dictionary with a perf hit... +//#define USE_UNSAFE + +#if UNITY_2020_1_OR_NEWER +#define UNITY_USE_RECORDER +#endif + +using System; +using System.Collections.Generic; +using Unity.Profiling; +using UnityEngine.Profiling; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Extensions +{ + + class ProfilingSamplerHTrace : ProfilingSamplerHTrace where TEnum : Enum + { +#if USE_UNSAFE + internal static TProfilingSampler[] samples; +#else + internal static Dictionary> samples = new Dictionary>(); +#endif + static ProfilingSamplerHTrace() + { + var names = Enum.GetNames(typeof(TEnum)); +#if USE_UNSAFE + var values = Enum.GetValues(typeof(TEnum)).Cast().ToArray(); + samples = new TProfilingSampler[values.Max() + 1]; +#else + var values = Enum.GetValues(typeof(TEnum)); +#endif + + for (int i = 0; i < names.Length; i++) + { + var sample = new ProfilingSamplerHTrace(names[i]); +#if USE_UNSAFE + samples[values[i]] = sample; +#else + samples.Add((TEnum)values.GetValue(i), sample); +#endif + } + } + + public ProfilingSamplerHTrace(string name) + : base(name, null) + { + } + } + + /// + /// Wrapper around CPU and GPU profiling samplers. + /// Use this along ProfilingScope to profile a piece of code. + /// +#if !UNITY_2021 + [IgnoredByDeepProfiler] +#endif + public class ProfilingSamplerHTrace + { + /// + /// Get the sampler for the corresponding enumeration value. + /// + /// Type of the enumeration. + /// Enumeration value. + /// The profiling sampler for the given enumeration value. + public static ProfilingSamplerHTrace Get(TEnum marker) + where TEnum : Enum + { +#if USE_UNSAFE + return TProfilingSamplerHTrace.samples[Unsafe.As(ref marker)]; +#else + ProfilingSamplerHTrace.samples.TryGetValue(marker, out var sampler); + return sampler; +#endif + } + + /// + /// Constructor. + /// + /// Name of the profiling sampler. + /// Name of the PARENT profiling sampler. + public ProfilingSamplerHTrace(string name, string parentName = null, int priority = 0) + { + // Caution: Name of sampler MUST not match name provide to cmd.BeginSample(), otherwise + // we get a mismatch of marker when enabling the profiler. +#if UNITY_USE_RECORDER + sampler = CustomSampler.Create(name, true); // Event markers, command buffer CPU profiling and GPU profiling +#else + // In this case, we need to use the BeginSample(string) API, since it creates a new sampler by that name under the hood, + // we need rename this sampler to not clash with the implicit one (it won't be used in this case) + sampler = CustomSampler.Create($"Dummy_{name}"); +#endif + inlineSampler = CustomSampler.Create($"Inl_{name}"); // Profiles code "immediately" + this.name = name; + this.parentName = parentName; + this.priority = priority; + +#if UNITY_USE_RECORDER + m_Recorder = sampler.GetRecorder(); + m_Recorder.enabled = false; + m_InlineRecorder = inlineSampler.GetRecorder(); + m_InlineRecorder.enabled = false; +#endif + } + + /// + /// Begin the profiling block. + /// + /// Command buffer used by the profiling block. + public void Begin(CommandBuffer cmd) + { + if (cmd != null) +#if UNITY_USE_RECORDER + if (sampler != null && sampler.isValid) + cmd.BeginSample(sampler); + else + cmd.BeginSample(name); +#else + cmd.BeginSample(name); +#endif + inlineSampler?.Begin(); + } + + /// + /// End the profiling block. + /// + /// Command buffer used by the profiling block. + public void End(CommandBuffer cmd) + { + if (cmd != null) +#if UNITY_USE_RECORDER + if (sampler != null && sampler.isValid) + cmd.EndSample(sampler); + else + cmd.EndSample(name); +#else + m_Cmd.EndSample(name); +#endif + inlineSampler?.End(); + } + + internal bool IsValid() { return (sampler != null && inlineSampler != null); } + + internal CustomSampler sampler { get; private set; } + internal CustomSampler inlineSampler { get; private set; } + /// + /// Name of the Profiling Sampler + /// + public string name { get; private set; } + /// + /// Name of the PARENT Profiling Sampler + /// + public string parentName { get; private set; } + /// + /// priority of Profiling Sampler + /// + public int priority { get; private set; } + +#if UNITY_USE_RECORDER + Recorder m_Recorder; + Recorder m_InlineRecorder; +#endif + + /// + /// Set to true to enable recording of profiling sampler timings. + /// + public bool enableRecording + { + set + { +#if UNITY_USE_RECORDER + m_Recorder.enabled = value; + m_InlineRecorder.enabled = value; +#endif + } + } + +#if UNITY_USE_RECORDER + /// + /// GPU Elapsed time in milliseconds. + /// + public float gpuElapsedTime => m_Recorder.enabled ? m_Recorder.gpuElapsedNanoseconds / 1000000.0f : 0.0f; + /// + /// Number of times the Profiling Sampler has hit on the GPU + /// + public int gpuSampleCount => m_Recorder.enabled ? m_Recorder.gpuSampleBlockCount : 0; + /// + /// CPU Elapsed time in milliseconds (Command Buffer execution). + /// + public float cpuElapsedTime => m_Recorder.enabled ? m_Recorder.elapsedNanoseconds / 1000000.0f : 0.0f; + /// + /// Number of times the Profiling Sampler has hit on the CPU in the command buffer. + /// + public int cpuSampleCount => m_Recorder.enabled ? m_Recorder.sampleBlockCount : 0; + /// + /// CPU Elapsed time in milliseconds (Direct execution). + /// + public float inlineCpuElapsedTime => m_InlineRecorder.enabled ? m_InlineRecorder.elapsedNanoseconds / 1000000.0f : 0.0f; + /// + /// Number of times the Profiling Sampler has hit on the CPU. + /// + public int inlineCpuSampleCount => m_InlineRecorder.enabled ? m_InlineRecorder.sampleBlockCount : 0; +#else + /// + /// GPU Elapsed time in milliseconds. + /// + public float gpuElapsedTime => 0.0f; + /// + /// Number of times the Profiling Sampler has hit on the GPU + /// + public int gpuSampleCount => 0; + /// + /// CPU Elapsed time in milliseconds (Command Buffer execution). + /// + public float cpuElapsedTime => 0.0f; + /// + /// Number of times the Profiling Sampler has hit on the CPU in the command buffer. + /// + public int cpuSampleCount => 0; + /// + /// CPU Elapsed time in milliseconds (Direct execution). + /// + public float inlineCpuElapsedTime => 0.0f; + /// + /// Number of times the Profiling Sampler has hit on the CPU. + /// + public int inlineCpuSampleCount => 0; +#endif + // Keep the constructor private + ProfilingSamplerHTrace() { } + } + +#if DEVELOPMENT_BUILD || UNITY_EDITOR + /// + /// Scoped Profiling markers + /// +#if !UNITY_2021 + [IgnoredByDeepProfiler] +#endif + public struct HTraceProfilingScope : IDisposable + { + CommandBuffer m_Cmd; + bool m_Disposed; + ProfilingSamplerHTrace _mSamplerHTrace; + + /// + /// Profiling Scope constructor + /// + /// Command buffer used to add markers and compute execution timings. + /// Profiling Sampler to be used for this scope. + public HTraceProfilingScope(CommandBuffer cmd, ProfilingSamplerHTrace samplerHTrace) + { + // NOTE: Do not mix with named CommandBuffers. + // Currently there's an issue which results in mismatched markers. + // The named CommandBuffer will close its "profiling scope" on execution. + // That will orphan ProfilingScope markers as the named CommandBuffer marker + // is their "parent". + // Resulting in following pattern: + // exec(cmd.start, scope.start, cmd.end) and exec(cmd.start, scope.end, cmd.end) + m_Cmd = cmd; + m_Disposed = false; + _mSamplerHTrace = samplerHTrace; + _mSamplerHTrace?.Begin(m_Cmd); + } + + /// + /// Dispose pattern implementation + /// + public void Dispose() + { + Dispose(true); + } + + // Protected implementation of Dispose pattern. + void Dispose(bool disposing) + { + if (m_Disposed) + return; + + // As this is a struct, it could have been initialized using an empty constructor so we + // need to make sure `cmd` isn't null to avoid a crash. Switching to a class would fix + // this but will generate garbage on every frame (and this struct is used quite a lot). + if (disposing) + { + _mSamplerHTrace?.End(m_Cmd); + } + + m_Disposed = true; + } + } +#else + /// + /// Scoped Profiling markers + /// + public struct HTraceProfilingScope : IDisposable + { + /// + /// Profiling Scope constructor + /// + /// Command buffer used to add markers and compute execution timings. + /// Profiling Sampler to be used for this scope. + public HTraceProfilingScope(CommandBuffer cmd, ProfilingSamplerHTrace samplerHTrace) + { + } + + /// + /// Dispose pattern implementation + /// + public void Dispose() + { + } + } +#endif + +} diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/HTraceProfilingScope.cs.meta b/Assets/External/HTraceWSGI/Scripts/Extensions/HTraceProfilingScope.cs.meta new file mode 100644 index 000000000..fb168a9e1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/HTraceProfilingScope.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: 78a693d303b74a34dae2a484d673be03 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Extensions/HTraceProfilingScope.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/IHistoryData.cs b/Assets/External/HTraceWSGI/Scripts/Extensions/IHistoryData.cs new file mode 100644 index 000000000..d2b5e08a4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/IHistoryData.cs @@ -0,0 +1,4 @@ +namespace HTraceWSGI.Scripts.Extensions +{ + public interface IHistoryData { } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Extensions/IHistoryData.cs.meta b/Assets/External/HTraceWSGI/Scripts/Extensions/IHistoryData.cs.meta new file mode 100644 index 000000000..f31593d31 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Extensions/IHistoryData.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 576960559f9f44a68d156531819b2a27 +timeCreated: 1758616227 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Extensions/IHistoryData.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Globals.meta b/Assets/External/HTraceWSGI/Scripts/Globals.meta new file mode 100644 index 000000000..925983ae4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fedae62d48842de49809e1bdde7001d6 +timeCreated: 1733380776 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HConstants.cs b/Assets/External/HTraceWSGI/Scripts/Globals/HConstants.cs new file mode 100644 index 000000000..336439158 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HConstants.cs @@ -0,0 +1,30 @@ +//pipelinedefine +#define H_URP + +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Globals +{ + internal static class HConstants + { + internal static string VERSION => + HNames.HTRACE_WSGI_URP_VERSION; +#if NONE + HNames.HTRACE_WSGI_BIRP_VERSION; +#endif + + internal const int HASH_STORAGE_SIZE = 512000 * 2; + internal const int HASH_UPDATE_FRACTION = 10; + internal const int PERSISTENT_HISTORY_SAMPLES = 4; + internal const int OCTAHEDRAL_SIZE = 4; + + //Voxelization + internal static readonly Vector2 ShadowmapResolution = new Vector2(2048, 2048); + internal const int OCTANTS_FRAMES_LENGTH = 5; + internal const int MAX_LOD_LEVEL = 10; + + internal static Vector2 ClampVoxelsResolution = new Vector2(64f, 512f); //min - 64 VoxelResolution, max - 512 VoxelResolution + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HConstants.cs.meta b/Assets/External/HTraceWSGI/Scripts/Globals/HConstants.cs.meta new file mode 100644 index 000000000..66bd04b5a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HConstants.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cde03d68491e9f245ad79a975e67649b +timeCreated: 1718361594 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Globals/HConstants.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HEnums.cs b/Assets/External/HTraceWSGI/Scripts/Globals/HEnums.cs new file mode 100644 index 000000000..cfebb15ac --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HEnums.cs @@ -0,0 +1,79 @@ +//pipelinedefine +#define H_URP + + +using UnityEngine; + +namespace HTraceWSGI.Scripts.Globals +{ + public enum DebugModeWS + { + None = 0, + MainBuffers = 1, + GlobalIllumination = 2, + GeometryNormals = 3, + Shadowmap = 4, + VoxelizedColor = 5, + VoxelizedLighting = 6, + LightClusterColor = 7, + LightClusterHeatmap = 8, + DirectLighting = 9, + } + + public enum HBuffer + { + Multi, + Depth, + Diffuse, + Normal, + MotionMask, + MotionVectors, + } + + public enum VoxelizationUpdateMode + { + Constant = 0, + Partial + } + + public enum ShadowmapUpdateMode + { + Default = 0, + TimeSliced, + } + + public enum IndirectEvaluationMethod + { + None = 0, + Tracing, + Approximation + } + + public enum SpatialRadius + { + None = 0, + Medium, + Wide + } + + public enum RayCountMode + { + Performance = 0, + Quality, + Cinematic + } + + + public enum Multibounce + { + None = 0, + IrradianceCache = 1, + AdaptiveProbeVolumes, + } + + public enum TracingMode + { + SoftwareTracing = 0, + HardwareTracing = 1, + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HEnums.cs.meta b/Assets/External/HTraceWSGI/Scripts/Globals/HEnums.cs.meta new file mode 100644 index 000000000..37960e9b3 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HEnums.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: efd600e3c738a6b4ea2d2bef513949a4 +timeCreated: 1661865051 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HMath.cs b/Assets/External/HTraceWSGI/Scripts/Globals/HMath.cs new file mode 100644 index 000000000..184f301b4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HMath.cs @@ -0,0 +1,253 @@ +using HTraceWSGI.Scripts.Data; +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Data.Public; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Globals +{ + public static class HMath + { + /// + /// Remap from one range to another + /// + /// + /// + /// + /// + /// + /// + public static float Remap(float input, float oldLow, float oldHigh, float newLow, float newHigh) + { + float t = Mathf.InverseLerp(oldLow, oldHigh, input); + return Mathf.Lerp(newLow, newHigh, t); + } + + /// + /// Thickness value pre-calculation for GI + /// + /// + /// + /// + public static Vector2 ThicknessBias(float baseThickness, Camera camera) + { + baseThickness = Remap(baseThickness, 0f, 1f, 0f, 0.5f); + float n = camera.nearClipPlane; + float f = camera.farClipPlane; + float thicknessScale = 1.0f / (1.0f + baseThickness); + float thicknessBias = -n / (f - n) * (baseThickness * thicknessScale); + return new Vector2(thicknessScale, thicknessBias); + } + + public static Vector4 ComputeViewportScaleAndLimit(Vector2Int viewportSize, Vector2Int bufferSize) + { + return new Vector4(ComputeViewportScale(viewportSize.x, bufferSize.x), // Scale(x) + ComputeViewportScale(viewportSize.y, bufferSize.y), // Scale(y) + ComputeViewportLimit(viewportSize.x, bufferSize.x), // Limit(x) + ComputeViewportLimit(viewportSize.y, bufferSize.y)); // Limit(y) + } + + public static float PixelSpreadTangent(float Fov, int Width, int Height) + { + return Mathf.Tan(Fov * Mathf.Deg2Rad * 0.5f) * 2.0f / Mathf.Min(Width, Height); + } + + public static Vector3Int CalculateVoxelResolution(VoxelizationSettings voxelizationSettings) + { + Vector3Int resolutionResult = new Vector3Int(); + float resolution = HMath.Remap(voxelizationSettings.VoxelDensity, 0f, 1f, HConstants.ClampVoxelsResolution.x, HConstants.ClampVoxelsResolution.y); + resolutionResult.x = Mathf.CeilToInt(resolution); + resolutionResult.y = Mathf.CeilToInt(resolution); + float targetHeight = (voxelizationSettings.OverrideBoundsHeightEnable == false ? voxelizationSettings.VoxelBounds : voxelizationSettings.OverrideBoundsHeight); + resolutionResult.z = Mathf.CeilToInt(targetHeight / (voxelizationSettings.VoxelBounds / resolution)); + + resolutionResult.x = HMath.DevisionBy32(resolutionResult.x); + resolutionResult.y = HMath.DevisionBy32(resolutionResult.y); + resolutionResult.z = HMath.DevisionBy32(resolutionResult.z); + + return resolutionResult; + } + + public static Vector3Int CalculateVoxelResolutionByVoxelSize(float voxelSize, Vector3Int realBounds) + { + Vector3Int resolutionResult = new Vector3Int(); + resolutionResult.x = Mathf.CeilToInt(Mathf.Clamp(realBounds.x / voxelSize, HConstants.ClampVoxelsResolution.x, HConstants.ClampVoxelsResolution.y)); + resolutionResult.y = Mathf.CeilToInt(Mathf.Clamp(realBounds.y / voxelSize, HConstants.ClampVoxelsResolution.x, HConstants.ClampVoxelsResolution.y)); + resolutionResult.z = Mathf.CeilToInt(Mathf.Clamp(realBounds.z / voxelSize, HConstants.ClampVoxelsResolution.x, HConstants.ClampVoxelsResolution.y)); + + resolutionResult.x = HMath.DevisionBy32(resolutionResult.x); + resolutionResult.y = HMath.DevisionBy32(resolutionResult.y); + resolutionResult.z = HMath.DevisionBy32(resolutionResult.z); + + return resolutionResult; + } + + public static float CalculateVoxelSizeInCM_UI(int bounds, float density) + { + float resolution = Mathf.CeilToInt(bounds / (bounds / HMath.Remap(density, 0f, 1f, HConstants.ClampVoxelsResolution.x, HConstants.ClampVoxelsResolution.y))); + return bounds / resolution * 100f; //100 -> cm + } + + public static float TexturesSizeInMB_UI(int voxelBounds, float density, bool overrideGroundEnable, int GroundLevel) + { + float resolution = voxelBounds / (voxelBounds / HMath.Remap(density, 0f, 1f, HConstants.ClampVoxelsResolution.x, HConstants.ClampVoxelsResolution.y)); + float voxelSize = voxelBounds / resolution; + float textureResolution = resolution * resolution; + textureResolution *= overrideGroundEnable == true ? (GroundLevel / voxelSize) : resolution; + float colorMemorySize = textureResolution * 32 / (1024 * 1024 * 8); + float positionMemorySize = (textureResolution * 32 / (1024 * 1024 * 8)) + (textureResolution * 8 / (1024 * 1024 * 8)); + + return colorMemorySize + positionMemorySize; + } + + public static float TexturesSizeInMB_UI(Vector3Int voxelsRelosution, VoxelizationUpdateMode voxelizationUpdateMode) + { + float textureResolution = voxelsRelosution.x * voxelsRelosution.y * voxelsRelosution.z; + float textureDataMemorySize = textureResolution * 32 / (1024 * 1024 * 8); //32 bits + float textureOccupancyMemorySize = (textureResolution * 8 / (1024 * 1024 * 8)); //8 bits + textureOccupancyMemorySize *= 1.33f; //mipmaps + float textureIntermediateMemorySize = ((textureResolution / (4^3)) * 8 / (1024 * 1024 * 8)); //8 bits + + if (voxelizationUpdateMode == VoxelizationUpdateMode.Partial) + textureDataMemorySize *= 2f; + + return textureDataMemorySize + textureOccupancyMemorySize + textureIntermediateMemorySize; + } + + public static Vector3Int CalculateVoxelResolution_UI(int voxelBounds, float density, bool overrideGroundEnable, int GroundLevel) + { + Vector3Int resolutionResult = new Vector3Int(); + float resolution = HMath.Remap(density, 0f, 1f, HConstants.ClampVoxelsResolution.x, HConstants.ClampVoxelsResolution.y); + resolutionResult.x = Mathf.CeilToInt(resolution); + resolutionResult.y = Mathf.CeilToInt(resolution); + + float height = (overrideGroundEnable == false ? voxelBounds : GroundLevel); + resolutionResult.z = Mathf.CeilToInt(height / (voxelBounds / resolution)); + + resolutionResult.x = HMath.DevisionBy32(resolutionResult.x); + resolutionResult.y = HMath.DevisionBy32(resolutionResult.y); + resolutionResult.z = HMath.DevisionBy32(resolutionResult.z); + + return resolutionResult; + } + + public static Vector3 Truncate(this Vector3 input, int digits) + { + return new Vector3(input.x.RoundTail(digits), input.y.RoundTail(digits), input.z.RoundTail(digits)); + } + + public static Vector3 Ceil(this Vector3 input, int digits) + { + return new Vector3(input.x.RoundToCeilTail(digits), input.y.RoundToCeilTail(digits), input.z.RoundToCeilTail(digits)); + } + + public static float RoundTail(this float value, int digits) + { + float mult = Mathf.Pow(10.0f, digits); + float result = Mathf.Round(mult * value) / mult; + return result; + } + + public static float RoundToCeilTail(this float value, int digits) + { + float mult = Mathf.Pow(10.0f, digits); + float result = Mathf.Ceil(mult * value) / mult; + return result; + } + + public static int CalculateStepCountSSGI(float giRadius, float giAccuracy) + { + if (giRadius <= 25.0f) + { + //5 -> 16, 10 -> 20, 25 -> 25 + return Mathf.FloorToInt((-0.0233f * giRadius * giRadius + 1.15f * giRadius + 10.833f) * giAccuracy); + } + + //50 -> 35, 100 -> 50, 150 -> 64 + return Mathf.FloorToInt((-0.0002f * giRadius * giRadius + 0.33f * giRadius + 19f) * giAccuracy); + } + + public static Vector2Int CalculateDepthPyramidResolution(Vector2Int screenResolution, int lowestMipLevel) + { + int lowestMipScale = (int)Mathf.Pow(2.0f, lowestMipLevel); + Vector2Int lowestMipResolutiom = new Vector2Int(Mathf.CeilToInt( (float)screenResolution.x / (float)lowestMipScale), + Mathf.CeilToInt( (float)screenResolution.y / (float)lowestMipScale)); + + Vector2Int paddedDepthPyramidResolution = lowestMipResolutiom * lowestMipScale; + return paddedDepthPyramidResolution; + } + public static Matrix4x4 ComputeFrustumCorners(Camera cam) + { + Transform cameraTransform = cam.transform; + + Vector3[] frustumCorners = new Vector3[4]; + cam.CalculateFrustumCorners(new Rect(0, 0, 1 / cam.rect.xMax, 1 / cam.rect.yMax), cam.farClipPlane, cam.stereoActiveEye, frustumCorners); + + Vector3 topLeft = cameraTransform.TransformVector(frustumCorners[0]); + Vector3 bottomLeft = cameraTransform.TransformVector(frustumCorners[1]); + Vector3 bottomRight = cameraTransform.TransformVector(frustumCorners[2]); + + Matrix4x4 frustumVectorsArray = Matrix4x4.identity; + frustumVectorsArray.SetRow(0, bottomLeft); + frustumVectorsArray.SetRow(1, bottomLeft + (bottomRight - bottomLeft) * 2); + frustumVectorsArray.SetRow(2, bottomLeft + (topLeft - bottomLeft) * 2); + + return frustumVectorsArray; + } + + public static Matrix4x4 Compute4FrustumCorners(Camera cam) + { + Transform cameraTransform = cam.transform; + + Vector3[] frustumCorners = new Vector3[4]; + cam.CalculateFrustumCorners(new Rect(0, 0, 1 / cam.rect.xMax, 1 / cam.rect.yMax), cam.farClipPlane, cam.stereoActiveEye, frustumCorners); + + // Transform to world space + Vector3 topLeft = cameraTransform.TransformVector(frustumCorners[0]); + Vector3 bottomLeft = cameraTransform.TransformVector(frustumCorners[1]); + Vector3 bottomRight = cameraTransform.TransformVector(frustumCorners[2]); + Vector3 topRight = cameraTransform.TransformVector(frustumCorners[3]); + + Matrix4x4 frustum = new Matrix4x4(); + frustum.SetRow(0, bottomLeft); + frustum.SetRow(1, topLeft); + frustum.SetRow(2, topRight); + frustum.SetRow(3, bottomRight); + + return frustum; + } + + internal static Vector3 OptimizeForVoxelization(this Vector3 position, VoxelizationExactData exactData) + { + Vector3 newPosition = new Vector3(Mathf.Round(position.x / exactData.VoxelSize) * exactData.VoxelSize, + Mathf.Round(position.y / exactData.VoxelSize) * exactData.VoxelSize, + Mathf.Round(position.z / exactData.VoxelSize) * exactData.VoxelSize); + return newPosition; + } + + private static int DevisionBy32(int value) + { + return value % 32 == 0 ? value : DevisionBy32(value + 1); + } + + private static int DevisionBy(int value, int devisionValue) + { + return value % devisionValue == 0 ? value : DevisionBy(value + 1, devisionValue); + } + + private static float ComputeViewportScale(int viewportSize, int bufferSize) + { + float rcpBufferSize = 1.0f / bufferSize; + + // Scale by (vp_dim / buf_dim). + return viewportSize * rcpBufferSize; + } + + private static float ComputeViewportLimit(int viewportSize, int bufferSize) + { + float rcpBufferSize = 1.0f / bufferSize; + + // Clamp to (vp_dim - 0.5) / buf_dim. + return (viewportSize - 0.5f) * rcpBufferSize; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HMath.cs.meta b/Assets/External/HTraceWSGI/Scripts/Globals/HMath.cs.meta new file mode 100644 index 000000000..76a390df3 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HMath.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a970bfadf7a82e44cb0cbb77714b04d8 +timeCreated: 1661871568 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Globals/HMath.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HNames.cs b/Assets/External/HTraceWSGI/Scripts/Globals/HNames.cs new file mode 100644 index 000000000..ff005db9a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HNames.cs @@ -0,0 +1,35 @@ +namespace HTraceWSGI.Scripts.Globals +{ + public static class HNames + { + public const string ASSET_NAME = "HTraceWSGI"; + public const string ASSET_NAME_FULL = "HTrace World Space Global Illumination"; + public const string HTRACE_WSGI_DOCUMENTATION_LINK = "https://ipgames.gitbook.io/htrace-wsgi/"; + public const string HTRACE_DISCORD_LINK = "https://discord.com/invite/Nep56Efu7A"; + public const string HTRACE_DISCORD_BUGS_WSGI_LINK = "https://discord.gg/Bzb2ymDBZy"; + public const string HTRACE_WSGI_HDRP_VERSION = "1.4.1"; + public const string HTRACE_WSGI_URP_VERSION = "0.9.6"; + public const string HTRACE_WSGI_BIRP_VERSION = "1.0.0"; + + + public const string HTRACE_PRE_PASS_NAME = "HTraceWSGI Pre Pass"; + public const string HTRACE_MV_PASS_NAME = "HTraceWSGI Motion Vectors Pass"; + public const string HTRACE_GBUFFER_PASS_NAME = "HTraceWSGI GBuffer Pass"; + public const string HTRACE_LIGHT_CLUSTER_PASS_NAME = "HTraceWSGI Light Cluster Pass"; + public const string HTRACE_SHADOWMAP_PASS_NAME = "HTraceWSGI Shadowmap Pass"; + public const string HTRACE_VOXELIZATION_PASS_NAME = "HTraceWSGI Voxelization Pass"; + public const string HTRACE_VOXEL_VISUALIZATION_PASS_NAME = "HTraceWSGI Voxel Visualization Pass"; + public const string HTRACE_LIGHT_CLUSTER_VISUALIZATION_PASS_NAME = "HTraceWSGI Light Cluster Visualization Pass"; + public const string HTRACE_SOFTWARE_TRACING_PASS_NAME = "HTraceWSGI Software Tracing Pass"; + public const string HTRACE_HARDWARE_TRACING_PASS_NAME = "HTraceWSGI Hardware Tracing Pass"; + public const string HTRACE_FINAL_PASS_NAME = "HTraceWSGI Final Pass"; + + public const string HTRACE_VOXEL_CAMERA_NAME = "HTraceWSGI Voxelization Camera"; + public const string HTRACE_VOXEL_CULLING_CAMERA_NAME = "HTraceWSGI Voxelization Culling Camera"; + public const string HTRACE_VOXEL_OCTANT_CAMERA_NAME = "HTraceWSGI Voxelization Octant Camera"; + + public const string KEYWORD_SWITCHER = "HTRACEGI_OVERRIDE"; + + public const string HTRACE_VOXELIZATION_SHADER_TAG_ID = "HTraceVoxelization"; + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HNames.cs.meta b/Assets/External/HTraceWSGI/Scripts/Globals/HNames.cs.meta new file mode 100644 index 000000000..fe4aeb1d2 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HNames.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0871456c0ac68ec4f970812465b31414 +timeCreated: 1691582446 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Globals/HNames.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HRenderer.cs b/Assets/External/HTraceWSGI/Scripts/Globals/HRenderer.cs new file mode 100644 index 000000000..e1bb1cb23 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HRenderer.cs @@ -0,0 +1,198 @@ +//pipelinedefine +#define H_URP + +using System.Collections.Generic; +using System.Reflection; +using UnityEngine; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Globals +{ + public enum HRenderPipeline + { + None, + BIRP, + URP, + HDRP + } + + internal static class HRenderer + { + static HRenderPipeline s_CurrentHRenderPipeline = HRenderPipeline.None; + + public static HRenderPipeline CurrentHRenderPipeline + { + get + { + if (s_CurrentHRenderPipeline == HRenderPipeline.None) + { + s_CurrentHRenderPipeline = GetRenderPipeline(); + } + return s_CurrentHRenderPipeline; + } + } + + private static HRenderPipeline GetRenderPipeline() + { + if (GraphicsSettings.currentRenderPipeline) + { + if (GraphicsSettings.currentRenderPipeline.GetType().ToString().Contains("HighDefinition")) + return HRenderPipeline.HDRP; + else + return HRenderPipeline.URP; + } + + return HRenderPipeline.BIRP; + } + + public static bool SupportsInlineRayTracing + { + get + { + #if UNITY_2023_1_OR_NEWER + return SystemInfo.supportsInlineRayTracing; + #else + return false; + #endif + } + } + + public static bool SupportsRayTracing + { + get + { + #if UNITY_2023_1_OR_NEWER // TODO: revert this to 2019 when raytracing issue in 2022 is resolved + if (SystemInfo.supportsRayTracing == false) + return false; + + + return true; + #else + return false; + #endif + } + } + + internal static bool PipelineSupportsScreenSpaceShadows + { + get + { + + return true; + } + } + + internal static bool UseDynamicViewportRescale + { + get + { + + return true; + } + } + + internal static bool PipelineSupportsSSGI + { + get + { + + return true; + } + } + + + public static int TextureXrSlices + { + get + { + if (Application.isPlaying == false) + return 1; + + + return 1; + } + } + + static RenderTexture emptyTexture; + public static RenderTexture EmptyTexture + { + get + { + if (emptyTexture == null) + { + emptyTexture = new RenderTexture(4, 4, 0); + emptyTexture.enableRandomWrite = true; + emptyTexture.dimension = TextureDimension.Tex2D; + emptyTexture.format = RenderTextureFormat.ARGBFloat; + emptyTexture.Create(); + } + + return emptyTexture; + } + } + + static RenderTexture emptyTexture2DArray; + public static RenderTexture EmptyTexture2DArray + { + get + { + if (emptyTexture == null) + { + emptyTexture = new RenderTexture(4, 4, 0); + emptyTexture.enableRandomWrite = true; + emptyTexture.dimension = TextureDimension.Tex2DArray; + emptyTexture.volumeDepth = 1; + emptyTexture.format = RenderTextureFormat.ARGBFloat; + emptyTexture.Create(); + } + + return emptyTexture; + } + } + + static RenderTexture emptyTextureCube; + public static RenderTexture EmptyTextureCube + { + get + { + if (emptyTexture == null) + { + emptyTexture = new RenderTexture(4, 4, 0); + emptyTexture.enableRandomWrite = true; + emptyTexture.dimension = TextureDimension.Cube; + emptyTexture.volumeDepth = 1; + emptyTexture.format = RenderTextureFormat.ARGBFloat; + emptyTexture.Create(); + } + + return emptyTexture; + } + } + + + private static Mesh _fullscreenTriangle; + public static Mesh FullscreenTriangle + { + get + { + if (_fullscreenTriangle != null) + return _fullscreenTriangle; + + _fullscreenTriangle = new Mesh { name = "Fullscreen Triangle" }; + + // Because we have to support older platforms (GLES2/3, DX9 etc) we can't do all of + // this directly in the vertex shader using vertex ids :( + _fullscreenTriangle.SetVertices(new List + { + new Vector3(-1f, -1f, 0f), + new Vector3(-1f, 3f, 0f), + new Vector3( 3f, -1f, 0f) + }); + _fullscreenTriangle.SetIndices(new[] { 0, 1, 2 }, MeshTopology.Triangles, 0, false); + _fullscreenTriangle.UploadMeshData(false); + + return _fullscreenTriangle; + } + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HRenderer.cs.meta b/Assets/External/HTraceWSGI/Scripts/Globals/HRenderer.cs.meta new file mode 100644 index 000000000..57e9ec5e1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HRenderer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c8b5e11218ffd034d96c4e8da14f1bb0 +timeCreated: 1743676524 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Globals/HRenderer.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HRendererURP.cs b/Assets/External/HTraceWSGI/Scripts/Globals/HRendererURP.cs new file mode 100644 index 000000000..791c42bd9 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HRendererURP.cs @@ -0,0 +1,264 @@ +//pipelinedefine +#define H_URP + +using System; +using System.Collections.Generic; +using System.Reflection; +using UnityEngine; +using UnityEngine.Rendering; +using HTraceWSGI.Scripts.Infrastructure.URP; +using UnityEditor; +using UnityEngine.Rendering.Universal; + +namespace HTraceWSGI.Scripts.Globals +{ + public static class HRendererURP + { + public static bool RenderGraphEnabled + { + get + { +#if UNITY_2023_3_OR_NEWER + return GraphicsSettings.GetRenderPipelineSettings().enableRenderCompatibilityMode == false; +#endif + return false; + } + } + + public static UniversalRenderPipelineAsset UrpAsset => + GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset urpAsset ? urpAsset : null; + +#if UNITY_EDITOR + private static FieldInfo s_rendererDataListFieldInfo; + private static FieldInfo s_defaultRendererIndexFieldInfo; + + private static ScriptableRendererData[] GetRendererDataList() + { + var urpAsset = UrpAsset; + if (urpAsset == null) + return null; + + try + { + if (s_rendererDataListFieldInfo == null) + s_rendererDataListFieldInfo = typeof(UniversalRenderPipelineAsset) + .GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic); + + if (s_rendererDataListFieldInfo == null) + return null; + + return (ScriptableRendererData[])s_rendererDataListFieldInfo.GetValue(urpAsset); + } + catch (Exception e) + { + Debug.LogError($"Failed to get renderer data list: {e.Message}"); + return null; + } + } + + private static int GetDefaultRendererIndex() + { + var urpAsset = UrpAsset; + if (urpAsset == null) + return -1; + + try + { + if (s_defaultRendererIndexFieldInfo == null) + s_defaultRendererIndexFieldInfo = typeof(UniversalRenderPipelineAsset) + .GetField("m_DefaultRendererIndex", BindingFlags.Instance | BindingFlags.NonPublic); + + if (s_defaultRendererIndexFieldInfo == null) + return -1; + + return (int)s_defaultRendererIndexFieldInfo.GetValue(urpAsset); + } + catch (Exception e) + { + Debug.LogError($"Failed to get default renderer index: {e.Message}"); + return -1; + } + } + + public static UniversalRendererData UniversalRendererData => GetUniversalRendererData(); + + /// + /// Get UniversalRendererData by index or default + /// + /// Renderer index. If -1 - than default + /// + private static UniversalRendererData GetUniversalRendererData(int rendererIndex = -1) + { + var rendererDataList = GetRendererDataList(); + if (rendererDataList == null || rendererDataList.Length == 0) + return null; + + if (rendererIndex == -1) rendererIndex = GetDefaultRendererIndex(); + + // Index validation + if (rendererIndex < 0 || rendererIndex >= rendererDataList.Length) + { + Debug.LogWarning( + $"Invalid renderer index {rendererIndex}. Available renderers: {rendererDataList.Length}"); + return null; + } + + return rendererDataList[rendererIndex] as UniversalRendererData; + } + + public static bool IsSsaoNativeEnabled() + { + return HasRendererFeatureByTypeName("ScreenSpaceAmbientOcclusion"); + } + + private static bool HasRendererFeatureByTypeName(string typeName, int rendererIndex = -1) + { + return GetRendererFeatureByTypeName(typeName, rendererIndex) != null; + } + + public static ScriptableRendererFeature GetRendererFeatureByTypeName(string typeName, int rendererIndex = -1) + { + var rendererDataList = GetRendererDataList(); + if (rendererDataList == null || rendererDataList.Length == 0) + return null; + + var renderersToSearch = new List(); + + if (rendererIndex >= 0 && rendererIndex < rendererDataList.Length) + renderersToSearch.Add(rendererDataList[rendererIndex]); + else + renderersToSearch.AddRange(rendererDataList); + + foreach (var rendererData in renderersToSearch) + { + if (rendererData?.rendererFeatures == null) continue; + + foreach (var feature in rendererData.rendererFeatures) + { + if (feature == null) continue; + + if (feature.GetType().Name.Contains(typeName, StringComparison.OrdinalIgnoreCase)) return feature; + } + } + + return null; + } + + public static T GetRendererFeature(int rendererIndex = -1) where T : ScriptableRendererFeature + { + var rendererDataList = GetRendererDataList(); + if (rendererDataList == null || rendererDataList.Length == 0) + return null; + + var renderersToSearch = new List(); + + if (rendererIndex >= 0 && rendererIndex < rendererDataList.Length) + renderersToSearch.Add(rendererDataList[rendererIndex]); + else + renderersToSearch.AddRange(rendererDataList); + + foreach (var rendererData in renderersToSearch) + { + if (rendererData?.rendererFeatures == null) continue; + + foreach (var feature in rendererData.rendererFeatures) + if (feature is T typedFeature) + return typedFeature; + } + + return null; + } + + private static bool ContainsRenderFeature(List features, string name) + { + if (features == null) return false; + + for (var i = 0; i < features.Count; i++) + if (features[i]?.name == name) + return true; + return false; + } + + public static void AddHTraceRendererFeatureToUniversalRendererData() + { + var universalRendererData = UniversalRendererData; + if (universalRendererData?.rendererFeatures == null) + { + Debug.LogWarning("Universal Renderer Data not found or has no features list"); + return; + } + + var features = universalRendererData.rendererFeatures; + + CleanupRendererFeatures(features); + + if (!ContainsRenderFeature(features, nameof(HTraceWSGIRendererFeature))) + AddHTraceRendererFeature(universalRendererData, features); + + universalRendererData.SetDirty(); + } + + private static void CleanupRendererFeatures(List features) + { + for (var i = features.Count - 1; i >= 0; i--) + { + var feature = features[i]; + + // Delete null elements + if (feature == null) + { + features.RemoveAt(i); + continue; + } + + if (feature.GetType() == typeof(HTraceWSGIRendererFeature)) features.RemoveAt(i); + } + } + + private static void AddHTraceRendererFeature(UniversalRendererData universalRendererData, List features) + { + try + { + var hTraceFeature = ScriptableObject.CreateInstance(); + AssetDatabase.AddObjectToAsset(hTraceFeature, universalRendererData); + features.Add(hTraceFeature); + + Debug.Log($"{HNames.ASSET_NAME} Renderer Feature added successfully"); + } + catch (Exception e) + { + Debug.LogError($"Failed to add {HNames.ASSET_NAME} Renderer Feature: {e.Message}"); + } + } + + /// + /// Get all renderer features by Type in all RendererDatas + /// + /// Тип renderer feature + /// + public static List GetAllRendererFeatures() where T : ScriptableRendererFeature + { + var result = new List(); + var rendererDataList = GetRendererDataList(); + + if (rendererDataList == null) return result; + + foreach (var rendererData in rendererDataList) + { + if (rendererData?.rendererFeatures == null) continue; + + foreach (var feature in rendererData.rendererFeatures) + if (feature is T typedFeature) + result.Add(typedFeature); + } + + return result; + } + + public static int GetRenderersCount() + { + return GetRendererDataList()?.Length ?? 0; + } +#endif // UNITY_EDITOR + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HRendererURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Globals/HRendererURP.cs.meta new file mode 100644 index 000000000..2c9cca1b2 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HRendererURP.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: aa2571e4010147c199090a71cd2c093e +timeCreated: 1759394122 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HShaderParams.cs b/Assets/External/HTraceWSGI/Scripts/Globals/HShaderParams.cs new file mode 100644 index 000000000..771711597 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HShaderParams.cs @@ -0,0 +1,230 @@ +using UnityEngine; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Globals +{ + public static class HShaderParams + { + // ---------------------------------------------- Globals, "g_" prefix ---------------------------------------------- + public static readonly int g_HTraceGBuffer0 = Shader.PropertyToID("g_HTraceGBuffer0"); + public static readonly int g_HTraceGBuffer1 = Shader.PropertyToID("g_HTraceGBuffer1"); + public static readonly int g_HTraceGBuffer2 = Shader.PropertyToID("g_HTraceGBuffer2"); + public static readonly int g_HTraceGBuffer3 = Shader.PropertyToID("g_HTraceGBuffer3"); + public static readonly int g_HTraceRenderLayerMask = Shader.PropertyToID("g_HTraceRenderLayerMask"); + public static readonly int g_HTraceColor = Shader.PropertyToID("g_HTraceColor"); + public static readonly int g_HTraceDepth = Shader.PropertyToID("g_HTraceDepth"); + public static readonly int g_HTraceDepthPyramidWSGI = Shader.PropertyToID("g_HTraceDepthPyramidWSGI"); + public static readonly int g_HTraceStencilBuffer = Shader.PropertyToID("g_HTraceStencilBuffer"); + public static readonly int g_HTraceMotionVectors = Shader.PropertyToID("g_HTraceMotionVectors"); + public static readonly int g_HTraceMotionMask = Shader.PropertyToID("g_HTraceMotionMask"); + public static readonly int g_HTraceBufferGI = Shader.PropertyToID("_HTraceBufferGI"); + public static readonly int g_HTraceShadowmap = Shader.PropertyToID("g_HTraceShadowmap"); + public static readonly int g_LightClusterDebug = Shader.PropertyToID("g_LightClusterDebug"); + public static readonly int g_CameraDepthTexture = Shader.PropertyToID("_CameraDepthTexture"); + public static readonly int g_CameraNormalsTexture = Shader.PropertyToID("_CameraNormalsTexture"); + + public static readonly int g_VoxelPositionPyramid = Shader.PropertyToID("_VoxelPositionPyramid"); + public static readonly int g_ProbeSize = Shader.PropertyToID("_ProbeSize"); + public static readonly int g_OctahedralSize = Shader.PropertyToID("_OctahedralSize"); + public static readonly int g_HFrameIndex = Shader.PropertyToID("_HFrameIndex"); + public static readonly int g_ReprojectSkippedFrame = Shader.PropertyToID("_ReprojectSkippedFrame"); + public static readonly int g_PersistentHistorySamples = Shader.PropertyToID("_PersistentHistorySamples"); + public static readonly int g_SkyOcclusionCone = Shader.PropertyToID("_SkyOcclusionCone"); + public static readonly int g_DirectionalLightIntensity = Shader.PropertyToID("_DirectionalLightIntensity"); + public static readonly int g_SurfaceDiffuseIntensity = Shader.PropertyToID("_SurfaceDiffuseIntensity"); + public static readonly int g_SkyLightIntensity = Shader.PropertyToID("_SkyLightIntensity"); + public static readonly int g_HashBuffer_Key = Shader.PropertyToID("_HashBuffer_Key"); + public static readonly int g_HashBuffer_Payload = Shader.PropertyToID("_HashBuffer_Payload"); + public static readonly int g_HashBuffer_Counter = Shader.PropertyToID("_HashBuffer_Counter"); + public static readonly int g_HashBuffer_Radiance = Shader.PropertyToID("_HashBuffer_Radiance"); + public static readonly int g_HashBuffer_Position = Shader.PropertyToID("_HashBuffer_Position"); + public static readonly int g_HashStorageSize = Shader.PropertyToID("_HashStorageSize"); + public static readonly int g_HashUpdateFraction = Shader.PropertyToID("_HashUpdateFraction"); + public static readonly int g_TestCheckbox = Shader.PropertyToID("_TestCheckbox"); + + + // ---------------------------------------------- GBuffer ---------------------------------------------- + public static readonly int _GBuffer0 = Shader.PropertyToID("_GBuffer0"); + public static readonly int _GBuffer1 = Shader.PropertyToID("_GBuffer1"); + public static readonly int _GBuffer2 = Shader.PropertyToID("_GBuffer2"); + public static readonly int _GBuffer3 = Shader.PropertyToID("_GBuffer3"); + public static readonly int _CameraRenderingLayersTexture = Shader.PropertyToID("_CameraRenderingLayersTexture"); + public static readonly int _GBufferTexture0 = Shader.PropertyToID("_GBufferTexture0"); + public static readonly int _RenderingLayerMaskTexture = Shader.PropertyToID("_RenderingLayerMaskTexture"); + public static readonly int _CameraGBufferTexture0 = Shader.PropertyToID("_CameraGBufferTexture0"); + + public static readonly int H_SHAr = Shader.PropertyToID("H_SHAr"); + public static readonly int H_SHAg = Shader.PropertyToID("H_SHAg"); + public static readonly int H_SHAb = Shader.PropertyToID("H_SHAb"); + public static readonly int H_SHBr = Shader.PropertyToID("H_SHBr"); + public static readonly int H_SHBg = Shader.PropertyToID("H_SHBg"); + public static readonly int H_SHBb = Shader.PropertyToID("H_SHBb"); + public static readonly int H_SHC = Shader.PropertyToID("H_SHC"); + + public static readonly string _GBUFFER_NORMALS_OCT = "_GBUFFER_NORMALS_OCT"; + public static readonly string _WRITE_RENDERING_LAYERS = "_WRITE_RENDERING_LAYERS"; + + public static readonly ShaderTagId UniversalGBufferTag = new ShaderTagId("UniversalGBuffer"); + + // DepthPyramid + public static readonly int _DepthIntermediate = Shader.PropertyToID("_DepthIntermediate"); + public static readonly int _DepthIntermediate_Output = Shader.PropertyToID("_DepthIntermediate_Output"); + public static readonly int _DepthPyramid_OutputMIP0 = Shader.PropertyToID("_DepthPyramid_OutputMIP0"); + public static readonly int _DepthPyramid_OutputMIP1 = Shader.PropertyToID("_DepthPyramid_OutputMIP1"); + public static readonly int _DepthPyramid_OutputMIP2 = Shader.PropertyToID("_DepthPyramid_OutputMIP2"); + public static readonly int _DepthPyramid_OutputMIP3 = Shader.PropertyToID("_DepthPyramid_OutputMIP3"); + public static readonly int _DepthPyramid_OutputMIP4 = Shader.PropertyToID("_DepthPyramid_OutputMIP4"); + public static readonly int _DepthPyramid_OutputMIP5 = Shader.PropertyToID("_DepthPyramid_OutputMIP5"); + public static readonly int _DepthPyramid_OutputMIP6 = Shader.PropertyToID("_DepthPyramid_OutputMIP6"); + public static readonly int _DepthPyramid_OutputMIP7 = Shader.PropertyToID("_DepthPyramid_OutputMIP7"); + public static readonly int _DepthPyramid_OutputMIP8 = Shader.PropertyToID("_DepthPyramid_OutputMIP8"); + + // ---------------------------------------------- Matrix ---------------------------------------------- + public static readonly int H_MATRIX_VP = Shader.PropertyToID("_H_MATRIX_VP"); + public static readonly int H_MATRIX_I_VP = Shader.PropertyToID("_H_MATRIX_I_VP"); + public static readonly int H_MATRIX_PREV_VP = Shader.PropertyToID("_H_MATRIX_PREV_VP"); + public static readonly int H_MATRIX_PREV_I_VP = Shader.PropertyToID("_H_MATRIX_PREV_I_VP"); + + // ---------------------------------------------- Additional ---------------------------------------------- + public static int HRenderScale = Shader.PropertyToID("_HRenderScale"); + public static int HRenderScalePrevious = Shader.PropertyToID("_HRenderScalePrevious"); + public static int FrameCount = Shader.PropertyToID("_FrameCount"); + public static int ScreenSize = Shader.PropertyToID("_ScreenSize"); + + // ---------------------------------------------- Shared Params Other ---------------------------------------------- + public static readonly int _BentNormalAmbientOcclusion_Output = Shader.PropertyToID("_BentNormalAmbientOcclusion_Output"); + public static readonly int _NormalDepthHalf_Output = Shader.PropertyToID("_NormalDepthHalf_Output"); + public static readonly int _Camera_FOV = Shader.PropertyToID("_Camera_FOV"); + public static readonly int _AmbientOcclusion = Shader.PropertyToID("_AmbientOcclusion"); + public static readonly int _NormalDepthHalf = Shader.PropertyToID("_NormalDepthHalf"); + public static readonly int _BentNormalAO_Output = Shader.PropertyToID("_BentNormalAO_Output"); + public static readonly int _GeometryNormal_Output = Shader.PropertyToID("_GeometryNormal_Output"); + + public static readonly int _PointDistribution_Output = Shader.PropertyToID("_PointDistribution_Output"); + public static readonly int _SpatialOffsetsBuffer_Output = Shader.PropertyToID("_SpatialOffsetsBuffer_Output"); + + public static readonly int g_GeometryNormal = Shader.PropertyToID("g_GeometryNormal"); + public static readonly int _ProbeNormalDepth_Output = Shader.PropertyToID("_ProbeNormalDepth_Output"); + public static readonly int _ProbeDiffuse_Output = Shader.PropertyToID("_ProbeDiffuse_Output"); + public static readonly int _SSAO = Shader.PropertyToID("_SSAO"); + public static readonly int _ProbeSSAO_Output = Shader.PropertyToID("_ProbeSSAO_Output"); + public static readonly int _ProbeNormalDepth = Shader.PropertyToID("_ProbeNormalDepth"); + + public static readonly int _HistoryIndirection = Shader.PropertyToID("_HistoryIndirection"); + public static readonly int _ProbeWorldPosNormal_History = Shader.PropertyToID("_ProbeWorldPosNormal_History"); + public static readonly int _ReprojectionCoords_Output = Shader.PropertyToID("_ReprojectionCoords_Output"); + public static readonly int _ReprojectionWeights_Output = Shader.PropertyToID("_ReprojectionWeights_Output"); + public static readonly int _PersistentReprojectionWeights_Output = Shader.PropertyToID("_PersistentReprojectionWeights_Output"); + public static readonly int _PersistentReprojectionCoord_Output = Shader.PropertyToID("_PersistentReprojectionCoord_Output"); + + public static readonly int _ReprojectionCoords = Shader.PropertyToID("_ReprojectionCoords"); + public static readonly int _RayDirectionsJittered_Output = Shader.PropertyToID("_RayDirectionsJittered_Output"); + public static readonly int _IndirectCoordsSS_Output = Shader.PropertyToID("_IndirectCoordsSS_Output"); + public static readonly int _IndirectCoordsOV_Output = Shader.PropertyToID("_IndirectCoordsOV_Output"); + public static readonly int _IndirectCoordsSF_Output = Shader.PropertyToID("_IndirectCoordsSF_Output"); + public static readonly int _RayCounter_Output = Shader.PropertyToID("_RayCounter_Output"); + public static readonly int _RayCounter = Shader.PropertyToID("_RayCounter"); + public static readonly int _TracingCoords = Shader.PropertyToID("_TracingCoords"); + public static readonly int _IndirectArguments_Output = Shader.PropertyToID("_IndirectArguments_Output"); + public static readonly int _RayCounterIndex = Shader.PropertyToID("_RayCounterIndex"); + + public static readonly int _NormalDepth_History = Shader.PropertyToID("_NormalDepth_History"); + public static readonly int _RayDirection = Shader.PropertyToID("_RayDirection"); + public static readonly int _HitDistance_Output = Shader.PropertyToID("_HitDistance_Output"); + public static readonly int _HitCoord_Output = Shader.PropertyToID("_HitCoord_Output"); + public static readonly int _IndexXR = Shader.PropertyToID("_IndexXR"); + public static readonly int _ColorPyramid_History = Shader.PropertyToID("_ColorPyramid_History"); + public static readonly int _Radiance_History = Shader.PropertyToID("_Radiance_History"); + public static readonly int _HitCoord = Shader.PropertyToID("_HitCoord"); + public static readonly int _HitRadiance_Output = Shader.PropertyToID("_HitRadiance_Output"); + + public static readonly int _HitDistance = Shader.PropertyToID("_HitDistance"); + public static readonly int _TracingRayCounter_Output = Shader.PropertyToID("_TracingRayCounter_Output"); + public static readonly int _TracingCoords_Output = Shader.PropertyToID("_TracingCoords_Output"); + public static readonly int _VoxelPayload_Output = Shader.PropertyToID("_VoxelPayload_Output"); + public static readonly int _PointDistribution = Shader.PropertyToID("_PointDistribution"); + public static readonly int _RayLength = Shader.PropertyToID("_RayLength"); + public static readonly int _VoxelPayload = Shader.PropertyToID("_VoxelPayload"); + public static readonly int _HashUpdateFrameIndex = Shader.PropertyToID("_HashUpdateFrameIndex"); + public static readonly int _RadianceAtlas = Shader.PropertyToID("_RadianceAtlas"); + + public static readonly int _RayDistanceSS = Shader.PropertyToID("_RayDistanceSS"); + public static readonly int _RayDistanceWS = Shader.PropertyToID("_RayDistanceWS"); + public static readonly int _ReprojectionWeights = Shader.PropertyToID("_ReprojectionWeights"); + public static readonly int _PersistentReprojectionCoord = Shader.PropertyToID("_PersistentReprojectionCoord"); + public static readonly int _ProbeAmbientOcclusion_History = Shader.PropertyToID("_ProbeAmbientOcclusion_History"); + public static readonly int _ProbeAmbientOcclusion_Output = Shader.PropertyToID("_ProbeAmbientOcclusion_Output"); + public static readonly int _ProbeNormalDepth_History = Shader.PropertyToID("_ProbeNormalDepth_History"); + public static readonly int _SpatialOffsets_Output = Shader.PropertyToID("_SpatialOffsets_Output"); + public static readonly int _SpatialWeights_Output = Shader.PropertyToID("_SpatialWeights_Output"); + public static readonly int _SpatialOffsetsBuffer = Shader.PropertyToID("_SpatialOffsetsBuffer"); + public static readonly int _SpatialWeightsPacked = Shader.PropertyToID("_SpatialWeightsPacked"); + public static readonly int _SpatialOffsetsPacked = Shader.PropertyToID("_SpatialOffsetsPacked"); + public static readonly int _ProbeAmbientOcclusion = Shader.PropertyToID("_ProbeAmbientOcclusion"); + public static readonly int _ProbeAmbientOcclusion_ArrayOutput = Shader.PropertyToID("_ProbeAmbientOcclusion_ArrayOutput"); + public static readonly int _ProbeAmbientOcclusion_OutputFiltered = Shader.PropertyToID("_ProbeAmbientOcclusion_OutputFiltered"); + + public static readonly int _ShadowGuidanceMask = Shader.PropertyToID("_ShadowGuidanceMask"); + public static readonly int _RayDistance = Shader.PropertyToID("_RayDistance"); + public static readonly int _ProbeDiffuse = Shader.PropertyToID("_ProbeDiffuse"); + public static readonly int _ReservoirAtlas_Output = Shader.PropertyToID("_ReservoirAtlas_Output"); + public static readonly int _ReservoirAtlas_History = Shader.PropertyToID("_ReservoirAtlas_History"); + public static readonly int _ReservoirAtlasRayData_Output = Shader.PropertyToID("_ReservoirAtlasRayData_Output"); + public static readonly int _ReservoirAtlasRadianceData_Output = Shader.PropertyToID("_ReservoirAtlasRadianceData_Output"); + public static readonly int _UseDiffuseWeight = Shader.PropertyToID("_UseDiffuseWeight"); + public static readonly int _PassNumber = Shader.PropertyToID("_PassNumber"); + public static readonly int _ReservoirAtlasRayData = Shader.PropertyToID("_ReservoirAtlasRayData"); + public static readonly int _ReservoirAtlasRadianceData = Shader.PropertyToID("_ReservoirAtlasRadianceData"); + public static readonly int _ShadowGuidanceMask_History = Shader.PropertyToID("_ShadowGuidanceMask_History"); + public static readonly int _ShadowGuidanceMask_Output = Shader.PropertyToID("_ShadowGuidanceMask_Output"); + public static readonly int _ReservoirAtlasRayData_Disocclusion = Shader.PropertyToID("_ReservoirAtlasRayData_Disocclusion"); + public static readonly int _ReservoirAtlas = Shader.PropertyToID("_ReservoirAtlas"); + public static readonly int _ReservoirAtlas_ArrayOutput = Shader.PropertyToID("_ReservoirAtlas_ArrayOutput"); + public static readonly int _ReservoirAtlasRadianceData_Inout = Shader.PropertyToID("_ReservoirAtlasRadianceData_Inout"); + public static readonly int _SampleCount_History = Shader.PropertyToID("_SampleCount_History"); + public static readonly int _SampleCount_Output = Shader.PropertyToID("_SampleCount_Output"); + public static readonly int _SampleCount = Shader.PropertyToID("_SampleCount"); + public static readonly int _ReprojectionCoord = Shader.PropertyToID("_ReprojectionCoord"); + public static readonly int _HistoryArrayIndex = Shader.PropertyToID("_HistoryArrayIndex"); + public static readonly int _ProbeWorldPosNormal_HistoryOutput = Shader.PropertyToID("_ProbeWorldPosNormal_HistoryOutput"); + + public static readonly int _Temp = Shader.PropertyToID("_Temp"); + public static readonly int _PackedSH_A_Output = Shader.PropertyToID("_PackedSH_A_Output"); + public static readonly int _PackedSH_B_Output = Shader.PropertyToID("_PackedSH_B_Output"); + public static readonly int _ProbeSSAO = Shader.PropertyToID("_ProbeSSAO"); + public static readonly int _PackedSH_A = Shader.PropertyToID("_PackedSH_A"); + public static readonly int _PackedSH_B = Shader.PropertyToID("_PackedSH_B"); + public static readonly int _BentNormalsAO = Shader.PropertyToID("_BentNormalsAO"); + public static readonly int _Radiance_Output = Shader.PropertyToID("_Radiance_Output"); + public static readonly int _IndirectLightingIntensity = Shader.PropertyToID("_IndirectLightingIntensity"); + public static readonly int _AO_Intensity = Shader.PropertyToID("_AO_Intensity"); + + public static readonly int _Radiance = Shader.PropertyToID("_Radiance"); + public static readonly int _LuminanceDelta_Output = Shader.PropertyToID("_LuminanceDelta_Output"); + public static readonly int _LuminanceDelta_History = Shader.PropertyToID("_LuminanceDelta_History"); + public static readonly int _Radiance_HistoryOutput = Shader.PropertyToID("_Radiance_HistoryOutput"); + public static readonly int _NormalDepth_HistoryOutput = Shader.PropertyToID("_NormalDepth_HistoryOutput"); + + public static readonly int _ShadowGuidanceMask_Samplecount = Shader.PropertyToID("_ShadowGuidanceMask_Samplecount"); + public static readonly int _ShadowGuidanceMask_SamplecountHistoryOutput = Shader.PropertyToID("_ShadowGuidanceMask_SamplecountHistoryOutput"); + public static readonly int _ShadowGuidanceMask_CheckerboardHistoryOutput = Shader.PropertyToID("_ShadowGuidanceMask_CheckerboardHistoryOutput"); + public static readonly int _ShadowGuidanceMask_Accumulated = Shader.PropertyToID("_ShadowGuidanceMask_Accumulated"); + public static readonly int _ShadowGuidanceMask_HistoryOutput = Shader.PropertyToID("_ShadowGuidanceMask_HistoryOutput"); + + public static readonly int _InputA = Shader.PropertyToID("_InputA"); + public static readonly int _InputB = Shader.PropertyToID("_InputB"); + public static readonly int _Output = Shader.PropertyToID("_Output"); + public static readonly int _DebugCameraFrustum = Shader.PropertyToID("_DebugCameraFrustum"); + public static readonly int _DebugRayDirection = Shader.PropertyToID("_DebugRayDirection"); + public static readonly int _Visualization_Output = Shader.PropertyToID("_Visualization_Output"); + public static readonly int _MultibounceMode = Shader.PropertyToID("_MultibounceMode"); + + public static readonly int _HTraceReflectionsGI_SpatialFilteringRadius = Shader.PropertyToID("_HTraceReflectionsGI_SpatialFilteringRadius"); + public static readonly int _HTraceReflectionsGI_JitterRadius = Shader.PropertyToID("_HTraceReflectionsGI_JitterRadius"); + public static readonly int _HTraceReflectionsGI_TemporalJitter = Shader.PropertyToID("_HTraceReflectionsGI_TemporalJitter"); + public static readonly int _HTraceReflectionsGI_RayBias = Shader.PropertyToID("_HTraceReflectionsGI_RayBias"); + public static readonly int _HTraceReflectionsGI_MaxRayLength = Shader.PropertyToID("_HTraceReflectionsGI_MaxRayLength"); + + public static readonly int _ClearTexture = Shader.PropertyToID("_ClearTexture"); + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Globals/HShaderParams.cs.meta b/Assets/External/HTraceWSGI/Scripts/Globals/HShaderParams.cs.meta new file mode 100644 index 000000000..99f3dbae1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Globals/HShaderParams.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 379e3f7b5ce1d4941901ddba7f27b80d +timeCreated: 1743099338 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Globals/HShaderParams.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/HConfig.cs b/Assets/External/HTraceWSGI/Scripts/HConfig.cs new file mode 100644 index 000000000..cfb3239fd --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/HConfig.cs @@ -0,0 +1,17 @@ +using UnityEngine; + +namespace HTraceWSGI.Scripts +{ + public static class HConfig + { + //todo: can we update it in runtime? + [Range(0f,1f)] + public static float SkyOcclusionCone = 0f; + + /// + /// Voxelization volume side length in Metres + /// + /// IMPORTANT!!! IF YOU CHANGE IT - DISABLE AND ENABLE HTRACE + public const int MAX_VOXEL_BOUNDS = 80; + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/HConfig.cs.meta b/Assets/External/HTraceWSGI/Scripts/HConfig.cs.meta new file mode 100644 index 000000000..5bc6c01e2 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/HConfig.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 12864f70c48f6bf4caba7bffa33431da +timeCreated: 1733380291 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/HConfig.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/HTraceWSGI.cs b/Assets/External/HTraceWSGI/Scripts/HTraceWSGI.cs new file mode 100644 index 000000000..0ce801d8e --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/HTraceWSGI.cs @@ -0,0 +1,261 @@ +//pipelinedefine +#define H_URP + +using System.Collections.Generic; +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Data.Public; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Infrastructure.URP; +using HTraceWSGI.Scripts.Passes.Shared; +using HTraceWSGI.Scripts.Passes.URP; +using HTraceWSGI.Scripts.Services; +using HTraceWSGI.Scripts.Services.DirectionalShadowmap; +using HTraceWSGI.Scripts.Services.VoxelCameras; +using HTraceWSGI.Scripts.Services.LightsCluster; +using LightingSettings = HTraceWSGI.Scripts.Data.Public.LightingSettings; +using UnityEngine; +using UnityEngine.Rendering; + +#if UNITY_EDITOR +using UnityEditor; +using HTraceWSGI.Scripts.PipelinesConfigurator; +#endif + + +namespace HTraceWSGI.Scripts +{ + [ExecuteInEditMode, DefaultExecutionOrder(100)] + [HelpURL(HNames.HTRACE_WSGI_DOCUMENTATION_LINK)] + public class HTraceWSGI : MonoBehaviour + { + private Volume _volumeComponent; +#if UNITY_6000_0_OR_NEWER + private ProbeVolumesOptions _probeVolumesOptionsOverrideComponent; +#endif + + private readonly HashSet _services = new HashSet(); + + public GeneralSettings GeneralSettings = new GeneralSettings(); + public VoxelizationSettings VoxelizationSettings = new VoxelizationSettings(); + public LightingSettings LightingSettings = new LightingSettings(); + public ScreenSpaceLightingSettings ScreenSpaceLightingSettings = new ScreenSpaceLightingSettings(); + public ReflectionIndirectLightingSettings ReflectionIndirectLightingSettings = new ReflectionIndirectLightingSettings(); + + [SerializeField] + private DebugSettings DebugSettings = new DebugSettings(); + + [SerializeField] private bool _globalSettingsTab = true; + [SerializeField] private bool _screenSpaceLightingTab = true; + [SerializeField] private bool _wsgiTab = true; + [SerializeField] private bool _lightingTab = true; + [SerializeField] private bool _reflectionsTab = true; + [SerializeField] private bool _debugTab = true; + + [SerializeField] private bool _showVoxelParams = true; + [SerializeField] private bool _showUpdateOptions = true; + + private Light _prevDirLight; + private TracingMode _prevTracingMode; + + internal bool NeedToReallocForUI + { + get + { + return VoxelsService.Instance.NeedToReallocForUI; + } + } + + /// + /// Reset Irradiance Cache + /// + public void ResetIrradianceCache() + { + SoftwareTracingShared.ClearRadianceCache = true; + } + + /// + /// Forced scene voxelization + /// + public void VoxelizeNow() + { + VoxelizationRuntimeData.FullVoxelization = true; + } + + /// + /// Apply Parameters, use only after changes setting's values in Parameters section. Do not recommend use it every frame. + /// + public void ApplyParameters() + { + VoxelizationRuntimeData.OnReallocTextures?.Invoke(); + } + + private void OnEnable() + { + HSettings.GeneralSettings = GeneralSettings; + HSettings.VoxelizationSettings = VoxelizationSettings; + HSettings.LightingSettings = LightingSettings; + HSettings.ScreenSpaceLightingSettings = ScreenSpaceLightingSettings; + HSettings.ReflectionIndirectLightingSettings = ReflectionIndirectLightingSettings; + HSettings.DebugSettings = DebugSettings; + SoftwareTracingPassURP.RequestHashBufferRecreate(); + + VoxelizationRuntimeData.OnReallocTextures += () => + { + HSettings.VoxelizationSettings.UpdateData(); + SoftwareTracingPassURP.AllocationHashBuffers(forceRecreate: true); + + VoxelizationRuntimeData.FullVoxelization = true; + VoxelizationRuntimeData.TextureSwapCounter = 0; + VoxelizationRuntimeData.TextureOutputCounter = 0; + + VoxelizationRuntimeData.SetParamsForApplyButton(HSettings.VoxelizationSettings.VoxelDensity, HSettings.VoxelizationSettings.VoxelBounds, HSettings.VoxelizationSettings.OverrideBoundsHeight); + }; + //HSettings.GeneralSettings.OnRayCountChanged += (RayCountMode mode) => { SoftwareTracingResources.Allocation();}; + +#if UNITY_EDITOR + HPipelinesConfigurator.AlwaysIncludedShaders(); +#endif + VoxelizationRuntimeData.Initialize(); // must be before RegisterService, because needed to reset OctantIndex + VolumeSetup(); + RegisterServices(); + Register(); + } + + private void OnValidate() + { + Register(); + } + + private void Reset() + { + Register(); + } + + private void LateUpdate() + { + foreach (var service in _services) + { + service.LateUpdate(); + } + + VolumeSetup(); + } + + private void RegisterServices() + { + VoxelsService.Instance.Initialize(0); + _services.Add(VoxelsService.Instance); + DirectionalShadowmapService.Instance.Initialize(0); + _services.Add(DirectionalShadowmapService.Instance); + LightService.Instance.Initialize(); + _services.Add(LightService.Instance); + } + + private void Register() + { + HTraceWSGIRendererFeature.RegisterSettings(this); + } + + private void OnDisable() + { + if (_volumeComponent != null) + _volumeComponent.enabled = false; +#if UNITY_6000_0_OR_NEWER + if (_probeVolumesOptionsOverrideComponent != null) + _probeVolumesOptionsOverrideComponent.active = false; +#endif + + foreach (var service in _services) + { + service.Cleanup(); + } + _services.Clear(); + HTraceWSGIRendererFeature.UnregisterSettings(this); + + VoxelizationRuntimeData.OnReallocTextures = null; + } + + private void VolumeSetup() + { +#if UNITY_6000_0_OR_NEWER + CreateSSGIOverrideComponent(); + SetSSGIOverrideComponentSettings(); + ChangeObjectWithSerialization_ONLYEDITOR(); +#endif + } + +#if UNITY_6000_0_OR_NEWER + private void CreateSSGIOverrideComponent() + { + _volumeComponent = gameObject.GetComponent(); + if (_volumeComponent == null) + { + _volumeComponent = gameObject.AddComponent(); + _volumeComponent.enabled = false; + } + + if (_volumeComponent.sharedProfile == null || _volumeComponent.sharedProfile.name.Contains("HTrace") == false) + { + //We can't crate it in runtime, because after build it will break. + //it will call only in editor, but if someone changes it in runtime, we will override. + _volumeComponent.sharedProfile = Resources.Load($"{HNames.ASSET_NAME}/Volume Profile HTrace WSGI URP"); + } + + _volumeComponent.sharedProfile.TryGet(out _probeVolumesOptionsOverrideComponent); + } + + private void SetSSGIOverrideComponentSettings() + { + _volumeComponent.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.None : HideFlags.HideInInspector | HideFlags.DontSave; + + bool isEnable = HSettings.GeneralSettings != null && HSettings.GeneralSettings.AmbientOverride; + _volumeComponent.enabled = isEnable; +#if UNITY_6000_0_OR_NEWER + _probeVolumesOptionsOverrideComponent.active = isEnable; +#endif + _volumeComponent.weight = 1; + _volumeComponent.priority = 100; +#if UNITY_EDITOR + _volumeComponent.runInEditMode = true; +#endif + if (_probeVolumesOptionsOverrideComponent != null) + { + _probeVolumesOptionsOverrideComponent.normalBias.overrideState = true; + _probeVolumesOptionsOverrideComponent.viewBias.overrideState = true; + _probeVolumesOptionsOverrideComponent.samplingNoise.overrideState = true; + } + } + + private void ChangeObjectWithSerialization_ONLYEDITOR() + { +#if UNITY_EDITOR + if (_probeVolumesOptionsOverrideComponent == null) + return; + + SerializedObject probeVolumesOptionsObject = new SerializedObject(_probeVolumesOptionsOverrideComponent); + + var normalBias = probeVolumesOptionsObject.FindProperty("normalBias"); + var m_OverrideState_normalBias = normalBias.FindPropertyRelative("m_OverrideState"); + var m_Value_normalBias = normalBias.FindPropertyRelative("m_Value"); + m_OverrideState_normalBias.boolValue = true; + m_Value_normalBias.floatValue = 0.0f; + + var viewBias = probeVolumesOptionsObject.FindProperty("viewBias"); + var m_OverrideState_viewBias = viewBias.FindPropertyRelative("m_OverrideState"); + var m_Value_viewBias = viewBias.FindPropertyRelative("m_Value"); + m_OverrideState_viewBias.boolValue = true; + m_Value_viewBias.floatValue = 0.0f; + + var samplingNoise = probeVolumesOptionsObject.FindProperty("samplingNoise"); + var m_OverrideState_samplingNoise = samplingNoise.FindPropertyRelative("m_OverrideState"); + var m_Value_samplingNoise = samplingNoise.FindPropertyRelative("m_Value"); + m_OverrideState_samplingNoise.boolValue = true; + m_Value_samplingNoise.floatValue = 0.0f; + + probeVolumesOptionsObject.ApplyModifiedProperties(); +#endif + } +#endif + } +} + diff --git a/Assets/External/HTraceWSGI/Scripts/HTraceWSGI.cs.meta b/Assets/External/HTraceWSGI/Scripts/HTraceWSGI.cs.meta new file mode 100644 index 000000000..7c160f28a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/HTraceWSGI.cs.meta @@ -0,0 +1,18 @@ +fileFormatVersion: 2 +guid: aea289474a4f4fdcb217aa68772e5da2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 0915864a167b66048872805a749c4360, type: 3} + userData: + assetBundleName: + assetBundleVariant: +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/HTraceWSGI.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Infrastructure.meta b/Assets/External/HTraceWSGI/Scripts/Infrastructure.meta new file mode 100644 index 000000000..0a4581345 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Infrastructure.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9a6a738c447cf424dbe8bba28ee6de0a +timeCreated: 1719669846 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Infrastructure/URP.meta b/Assets/External/HTraceWSGI/Scripts/Infrastructure/URP.meta new file mode 100644 index 000000000..f19b6d98e --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Infrastructure/URP.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cf1af4f23fdebf2478b4a930bdac2dbd +timeCreated: 1747323345 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Infrastructure/URP/HTraceWSGIRendererFeature.cs b/Assets/External/HTraceWSGI/Scripts/Infrastructure/URP/HTraceWSGIRendererFeature.cs new file mode 100644 index 000000000..ce541f15a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Infrastructure/URP/HTraceWSGIRendererFeature.cs @@ -0,0 +1,167 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Passes.URP; +#if UNITY_EDITOR +using HTraceWSGI.Scripts.PipelinesConfigurator; +#endif +using UnityEngine; +using UnityEngine.Rendering.Universal; + +namespace HTraceWSGI.Scripts.Infrastructure.URP +{ + [DisallowMultipleRendererFeature(HNames.ASSET_NAME_FULL)] + [ExecuteAlways] + [HelpURL(HNames.HTRACE_WSGI_DOCUMENTATION_LINK)] + public class HTraceWSGIRendererFeature : ScriptableRendererFeature + { + private static HTraceWSGI _hTraceWSGI; + + private PrePassURP _prePassURP; + private MotionVectorsPassURP _motionVectorsPass; + private GBufferPassURP _gBufferPass; + private LightClusterPassURP _lightClusterPass; + private DirectionalShadowmapPassURP _shadowmapPassUrp; + private VoxelizationPassURP _voxelizationPassUrp; + private SoftwareTracingPassURP _softwareTracingPassUrp; + private FinalPassURP _finalPassURP; + + private bool _initialized = false; + + public static void RegisterSettings(HTraceWSGI hTraceWsgi) + { + if (hTraceWsgi != null) + { + _hTraceWSGI = hTraceWsgi; + } + } + + public static void UnregisterSettings(HTraceWSGI hTraceWsgi) + { + if (_hTraceWSGI == hTraceWsgi) + { + _hTraceWSGI = null; + } + } + + /// + /// Initializes this feature's resources. This is called every time serialization happens. + /// + public override void Create() + { + name = HNames.ASSET_NAME_FULL; + Dispose(); + + // if (HResources.GeneralData == null) //after any serialization it will be null, cause HTrace OnEnable() works after + // return; + + _prePassURP = new PrePassURP(); + _prePassURP.renderPassEvent = RenderPassEvent.AfterRenderingOpaques; + _motionVectorsPass = new MotionVectorsPassURP(); + _motionVectorsPass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques; + _gBufferPass = new GBufferPassURP(); + _gBufferPass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques; + _lightClusterPass = new LightClusterPassURP(); + _lightClusterPass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques; + _shadowmapPassUrp = new DirectionalShadowmapPassURP(); + _shadowmapPassUrp.renderPassEvent = RenderPassEvent.AfterRenderingOpaques; + _voxelizationPassUrp = new VoxelizationPassURP(); + _voxelizationPassUrp.renderPassEvent = RenderPassEvent.AfterRenderingOpaques; + _softwareTracingPassUrp = new SoftwareTracingPassURP(); + _softwareTracingPassUrp.renderPassEvent = RenderPassEvent.AfterRenderingOpaques; + + _finalPassURP = new FinalPassURP(); + _finalPassURP.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing; + +#if UNITY_EDITOR + HPipelinesConfigurator.AlwaysIncludedShaders(); +#endif + + _initialized = true; + } + +#if !UNITY_6000_4_OR_NEWER + /// + /// Called when render targets are allocated and ready to be used. + /// + /// + /// + /// +#if UNITY_6000_3_OR_NEWER + [System.Obsolete] +#endif + public override void SetupRenderPasses(ScriptableRenderer renderer, in RenderingData renderingData) + { + if (_initialized == false) + return; + + if (HRendererURP.RenderGraphEnabled == false) + { + _prePassURP.Initialize(renderer); + _motionVectorsPass.Initialize(renderer); + _gBufferPass.Initialize(renderer); + //_shadowmapPassUrp.Initialize(renderer); + + _finalPassURP.Initialize(renderer); + } + } +#endif + + /// + /// Injects one or multiple ScriptableRenderPass in the renderer. + /// + /// + /// + public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) + { + if (renderingData.cameraData.cameraType == CameraType.Reflection || renderingData.cameraData.cameraType == CameraType.Preview) + return; + + + var isActive = _hTraceWSGI != null && _hTraceWSGI.enabled && _hTraceWSGI.gameObject.activeSelf; + if (!isActive) + return; + +#if !UNITY_2022_1_OR_NEWER + _prePassURP.Initialize(renderer); + _mainPassURP.Initialize(renderer); + _finalPassURP.Initialize(renderer); +#endif + renderer.EnqueuePass(_prePassURP); + renderer.EnqueuePass(_motionVectorsPass); + renderer.EnqueuePass(_gBufferPass); + renderer.EnqueuePass(_lightClusterPass); + renderer.EnqueuePass(_voxelizationPassUrp); + renderer.EnqueuePass(_shadowmapPassUrp); // It must be after voxelization, because voxelization pass changes VoxelCamera TRS + renderer.EnqueuePass(_softwareTracingPassUrp); + renderer.EnqueuePass(_finalPassURP); + } + + protected override void Dispose(bool disposing) + { + _prePassURP?.Dispose(); + _motionVectorsPass?.Dispose(); + _gBufferPass?.Dispose(); + _lightClusterPass?.Dispose(); + _shadowmapPassUrp?.Dispose(); + _voxelizationPassUrp?.Dispose(); + _softwareTracingPassUrp?.Dispose(); + + _finalPassURP?.Dispose(); + + _prePassURP = null; + _motionVectorsPass = null; + _gBufferPass = null; + _lightClusterPass = null; + _shadowmapPassUrp = null; + _voxelizationPassUrp = null; + _softwareTracingPassUrp = null; + + _finalPassURP = null; + + _initialized = false; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Infrastructure/URP/HTraceWSGIRendererFeature.cs.meta b/Assets/External/HTraceWSGI/Scripts/Infrastructure/URP/HTraceWSGIRendererFeature.cs.meta new file mode 100644 index 000000000..916ac2611 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Infrastructure/URP/HTraceWSGIRendererFeature.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 94e17f564a7acaf43aa4f96d678cbd0f +timeCreated: 1747323403 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Infrastructure/URP/HTraceWSGIRendererFeature.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes.meta b/Assets/External/HTraceWSGI/Scripts/Passes.meta new file mode 100644 index 000000000..20d54bd55 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 229bb1d7b7d66584a8847fb7bde062e1 +timeCreated: 1674801896 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared.meta b/Assets/External/HTraceWSGI/Scripts/Passes/Shared.meta new file mode 100644 index 000000000..cad77b786 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 779baa71f288432d940ff3de42f3c637 +timeCreated: 1758606999 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HBlueNoiseShared.cs b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HBlueNoiseShared.cs new file mode 100644 index 000000000..056976209 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HBlueNoiseShared.cs @@ -0,0 +1,63 @@ +using UnityEngine; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Passes.Shared +{ + internal static class HBlueNoiseShared + { + private static readonly int g_OwenScrambledTexture = Shader.PropertyToID("g_OwenScrambledTexture"); + private static readonly int g_ScramblingTileXSPP = Shader.PropertyToID("g_ScramblingTileXSPP"); + private static readonly int g_RankingTileXSPP = Shader.PropertyToID("g_RankingTileXSPP"); + private static readonly int g_ScramblingTexture = Shader.PropertyToID("g_ScramblingTexture"); + + private static Texture2D _owenScrambledTexture; + public static Texture2D OwenScrambledTexture + { + get + { + if (_owenScrambledTexture == null) + _owenScrambledTexture = UnityEngine.Resources.Load("HTraceWSGI/_Shared/BlueNoise/OwenScrambledNoise256"); + return _owenScrambledTexture; + } + } + + private static Texture2D _scramblingTileXSPP; + public static Texture2D ScramblingTileXSPP + { + get + { + if (_scramblingTileXSPP == null) + _scramblingTileXSPP = UnityEngine.Resources.Load("HTraceWSGI/_Shared/BlueNoise/ScramblingTile8SPP"); + return _scramblingTileXSPP; + } + } + private static Texture2D _rankingTileXSPP; + public static Texture2D RankingTileXSPP + { + get + { + if (_rankingTileXSPP == null) + _rankingTileXSPP = UnityEngine.Resources.Load("HTraceWSGI/_Shared/BlueNoise/RankingTile8SPP"); + return _rankingTileXSPP; + } + } + private static Texture2D _scramblingTexture; + public static Texture2D ScramblingTexture + { + get + { + if (_scramblingTexture == null) + _scramblingTexture = UnityEngine.Resources.Load("HTraceWSGI/_Shared/BlueNoise/ScrambleNoise"); + return _scramblingTexture; + } + } + + public static void SetTextures(CommandBuffer cmdList) + { + cmdList.SetGlobalTexture(g_OwenScrambledTexture, OwenScrambledTexture); + cmdList.SetGlobalTexture(g_ScramblingTileXSPP, ScramblingTileXSPP); + cmdList.SetGlobalTexture(g_RankingTileXSPP, RankingTileXSPP); + cmdList.SetGlobalTexture(g_ScramblingTexture, ScramblingTexture); + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HBlueNoiseShared.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HBlueNoiseShared.cs.meta new file mode 100644 index 000000000..874e19a52 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HBlueNoiseShared.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 2f609c822f48ff84faaacf14fba38ebd +timeCreated: 1747395812 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/Shared/HBlueNoiseShared.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HardwareTracingShared.cs b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HardwareTracingShared.cs new file mode 100644 index 000000000..9603cedda --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HardwareTracingShared.cs @@ -0,0 +1,62 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Wrappers; +using UnityEngine; +using UnityEngine.Experimental.Rendering; // For OLD Unity +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Passes.Shared +{ + internal static class HardwareTracingShared + { + // Shader properties + private static readonly int _ShaderPropertysample = Shader.PropertyToID("_ShaderPropertysample"); + + // Samplers + private static readonly ProfilingSamplerHTrace SampleProfilingSampler = new ProfilingSamplerHTrace("Sample Profiling Sampler", parentName: HNames.HTRACE_HARDWARE_TRACING_PASS_NAME, priority: 0); + internal static readonly ProfilingSamplerHTrace s_LightEvaluationProfilingSampler = new ProfilingSamplerHTrace("Light Evaluation", parentName: HNames.HTRACE_HARDWARE_TRACING_PASS_NAME, priority: 11); + + + // Materials + internal static Material VoxelVisualizationMaterial = null; + + internal static ComputeBuffer PrevBuffer = null; + internal static RayTracingShader HRayTracing = null; + + internal static RTWrapper TestBuffer = new RTWrapper(); + internal static RTWrapper RayTracedGBufferPayload = new RTWrapper(); + internal static RTWrapper VoxelVisualizationRayDirections = new RTWrapper(); + + internal struct HistoryData : IHistoryData + { + public Vector3 CameraPosition; + + public void Update(Camera camera) + { + CameraPosition = camera.transform.position; + } + } + + internal static HistoryData History = new HistoryData() + { + CameraPosition = Vector3.zero + }; + + internal static void Execute(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight) + { + // Raytrace + cmd.SetRayTracingShaderPass(HRayTracing, "GBufferDXR"); + cmd.SetRayTracingTextureParam(HRayTracing, "_RayDirection", VoxelVisualizationRayDirections.rt); + //cmd.SetRayTracingTextureParam(HRayTracing, "_Output", TestBuffer.rt); + cmd.SetRayTracingTextureParam(HRayTracing, "_Output", RayTracedGBufferPayload.rt); + cmd.DispatchRays(HRayTracing, "TraceAmbientOcclusion", (uint)Mathf.CeilToInt(cameraWidth), (uint)Mathf.CeilToInt(cameraHeight), (uint)HRenderer.TextureXrSlices); + + cmd.SetGlobalBuffer("_PrevBuffer", PrevBuffer); + + cmd.SetGlobalTexture(HShaderParams.g_HTraceBufferGI, TestBuffer.rt); + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HardwareTracingShared.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HardwareTracingShared.cs.meta new file mode 100644 index 000000000..e7c9f210f --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/HardwareTracingShared.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f42951a9673b27f4cac4e16c1697ddd7 +timeCreated: 1743679344 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/Shared/HardwareTracingShared.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/LightClusterShared.cs b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/LightClusterShared.cs new file mode 100644 index 000000000..99b900a72 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/LightClusterShared.cs @@ -0,0 +1,177 @@ +//pipelinedefine +#define H_URP + +using System.Linq; +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Services.LightsCluster; +using HTraceWSGI.Scripts.Wrappers; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Passes.Shared +{ + internal static class LightClusterShared + { + internal enum LightClusterKernels + { + ClearBuffer = 0, + FillLightCluster = 1, + DebugLightCluster = 2, + FillLightClusterDebugBuffer = 3, + LightDataCompaction = 4, + } + + // Properties + internal static readonly int _LightClusterDebug_Output = Shader.PropertyToID("_LightClusterDebug_Output"); + + internal static readonly int _SceneLightsBuffer = Shader.PropertyToID("_SceneLightsBuffer"); + internal static readonly int _LightDatasCompactedBuffer = Shader.PropertyToID("_LightDatasCompactedBuffer"); + internal static readonly int _LightClusterIndexesBuffer = Shader.PropertyToID("_LightClusterIndexesBuffer"); + internal static readonly int _LightClusterCounterBuffer = Shader.PropertyToID("_LightClusterCounterBuffer"); + internal static readonly int _LightClusterDebugBuffer = Shader.PropertyToID("_LightClusterDebugBuffer"); + + internal static readonly int g_HeatmapDebug = Shader.PropertyToID("g_HeatmapDebug"); + internal static readonly int g_MaxLightsPerCell = Shader.PropertyToID("g_MaxLightsPerCell"); + internal static readonly int g_SceneLightsBufferSize = Shader.PropertyToID("g_SceneLightsBufferSize"); + internal static readonly int g_LightClusterDimensions = Shader.PropertyToID("g_LightClusterDimensions"); + internal static readonly int g_MinLightClusterPosition = Shader.PropertyToID("g_MinLightClusterPosition"); + internal static readonly int g_MaxLightClusterPosition = Shader.PropertyToID("g_MaxLightClusterPosition"); + internal static readonly int g_LightCluterCellSize = Shader.PropertyToID("g_LightCluterCellSize"); + + internal static readonly int _LightClusterDebugColor = Shader.PropertyToID("_LightClusterDebugColor"); + internal static readonly int _LightClusterDebugDepth = Shader.PropertyToID("_LightClusterDebugDepth"); + + // Profiler Samplers + internal static readonly ProfilingSamplerHTrace LightClusterBuildProfilingSampler = new ProfilingSamplerHTrace("Light Cluster Build", parentName: HNames.HTRACE_FINAL_PASS_NAME, priority: 0); + internal static readonly ProfilingSamplerHTrace DebugLightClusterProfilingSampler = new ProfilingSamplerHTrace("Debug Light Cluster", parentName: HNames.HTRACE_FINAL_PASS_NAME, priority: 0); + + // Buffers + internal static ComputeShader HLightCluster = null; + + internal static ComputeBuffer SceneLightsBuffer = null; // Scene lights with HTrace punctual light script + internal static ComputeBuffer LightClusterDebugBuffer = null; // Marked edge cells of light cluster (debug purposes only) + internal static ComputeBuffer LightClusterIndexesBuffer = null; // Indirection buffer used to index into _LightDatas + internal static ComputeBuffer LightClusterCounterBuffer = null; // Light count for each cell in light cluster + internal static ComputeBuffer LightDatasCompactedBuffer = null; // Lights from unity's _LightDatas that match lights in SceneLightsBuffer + + // Materials + internal static Material LightClusterVisualizationMaterial = null; + + // RTHandles + internal static RTWrapper LightClusterDebugColor = new RTWrapper(); + internal static RTWrapper LightClusterDebugDepth = new RTWrapper(); + + internal static int MaxPunctualLightOnScreen = 100; + + internal struct HistoryData : IHistoryData + { + public void Update() + { + } + } + + internal static HistoryData History = new HistoryData(); + + internal static void Execute(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight) + { + using (new HTraceProfilingScope(cmd, LightClusterBuildProfilingSampler)) + { + var filteredLights = LightService.Instance.GetLights(camera).ToList(); + SceneLightsBuffer.SetData(filteredLights); + + Vector3 lightClusterRangeVector3 = new Vector3(HSettings.LightingSettings.LightClusterRange, HSettings.LightingSettings.LightClusterRange, HSettings.LightingSettings.LightClusterRange); + Vector3 lightClusterCellSizeSW = HSettings.VoxelizationSettings.ExactData.Bounds / HSettings.LightingSettings.LightClusterCellDensity; + + Vector3 lightClusterCellSizeHW = lightClusterRangeVector3 * 2 / HSettings.LightingSettings.LightClusterCellDensity; + Vector3 lightClusterCellSize = HSettings.GeneralSettings.TracingMode == Globals.TracingMode.SoftwareTracing ? lightClusterCellSizeSW : lightClusterCellSizeHW; + + Vector3 lighClusterCenter = Vector3.zero; + switch (HSettings.GeneralSettings.TracingMode) + { + case Globals.TracingMode.SoftwareTracing: + lighClusterCenter = new Vector3( + Mathf.Round(VoxelizationRuntimeData.VoxelCamera.transform.position.x / lightClusterCellSize.x) * lightClusterCellSize.x, + Mathf.Round(VoxelizationRuntimeData.VoxelCamera.transform.position.y / lightClusterCellSize.y) * lightClusterCellSize.y, + Mathf.Round(VoxelizationRuntimeData.VoxelCamera.transform.position.z / lightClusterCellSize.z) * lightClusterCellSize.z); + break; + case Globals.TracingMode.HardwareTracing: + lighClusterCenter = new Vector3( + Mathf.Round(camera.transform.position.x / lightClusterCellSize.x) * lightClusterCellSize.x, + Mathf.Round(camera.transform.position.y / lightClusterCellSize.y) * lightClusterCellSize.y, + Mathf.Round(camera.transform.position.z / lightClusterCellSize.z) * lightClusterCellSize.z); + break; + } + + Bounds softwareLightClusterBounds = new Bounds(lighClusterCenter, HSettings.VoxelizationSettings.ExactData.Bounds); + Bounds hardwareLightClusterBounds = new Bounds(lighClusterCenter, lightClusterCellSizeHW * HSettings.LightingSettings.LightClusterCellDensity); + Vector3 lightClusterBoundMin = HSettings.GeneralSettings.TracingMode == Globals.TracingMode.SoftwareTracing ? softwareLightClusterBounds.min : hardwareLightClusterBounds.min; + Vector3 lightClusterBoundMax = HSettings.GeneralSettings.TracingMode == Globals.TracingMode.SoftwareTracing ? softwareLightClusterBounds.max : hardwareLightClusterBounds.max; + + // Set buffers + cmd.SetGlobalBuffer(_LightClusterDebugBuffer, LightClusterDebugBuffer); + cmd.SetGlobalBuffer(_LightDatasCompactedBuffer, LightDatasCompactedBuffer); + cmd.SetGlobalBuffer(_LightClusterIndexesBuffer, LightClusterIndexesBuffer); + cmd.SetGlobalBuffer(_LightClusterCounterBuffer, LightClusterCounterBuffer); + + // Set parameters + cmd.SetGlobalVector(g_LightClusterDimensions, new Vector3(HSettings.LightingSettings.LightClusterCellDensity, HSettings.LightingSettings.LightClusterCellDensity, HSettings.LightingSettings.LightClusterCellDensity)); + cmd.SetGlobalVector(g_MinLightClusterPosition, lightClusterBoundMin); + cmd.SetGlobalVector(g_MaxLightClusterPosition, lightClusterBoundMax); + cmd.SetGlobalVector(g_LightCluterCellSize, lightClusterCellSize); + cmd.SetGlobalInt(g_SceneLightsBufferSize, filteredLights.Count); + cmd.SetGlobalInt(g_HeatmapDebug, HSettings.GeneralSettings.DebugModeWS == DebugModeWS.LightClusterHeatmap ? 1 : 0); + cmd.SetGlobalInt(g_MaxLightsPerCell, HSettings.LightingSettings.LightClusterCellLightCount); + + // Clear Counter buffer + cmd.DispatchCompute(HLightCluster, (int)LightClusterKernels.ClearBuffer, Mathf.CeilToInt(64 * 64 * 64 / 64), 1, 1); + + // Compact Unity's _LightData through our Scene Light Buffer + cmd.SetComputeBufferParam(HLightCluster, (int)LightClusterKernels.LightDataCompaction, _SceneLightsBuffer, SceneLightsBuffer); + cmd.DispatchCompute(HLightCluster, (int)LightClusterKernels.LightDataCompaction, MaxPunctualLightOnScreen / 64, 1, 1); + + // Fill Light Cluster + cmd.DispatchCompute(HLightCluster, (int)LightClusterKernels.FillLightCluster, HSettings.LightingSettings.LightClusterCellDensity / 4, HSettings.LightingSettings.LightClusterCellDensity / 4, HSettings.LightingSettings.LightClusterCellDensity / 4); + } + } + + internal static void DebugLightCluster(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight) + { + using (new HTraceProfilingScope(cmd, DebugLightClusterProfilingSampler)) + { + if (HSettings.LightingSettings.EvaluatePunctualLights && (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.LightClusterColor || HSettings.GeneralSettings.DebugModeWS == DebugModeWS.LightClusterHeatmap)) + { + // Draw 2D debug light cluster view on visible surfaces + cmd.SetComputeTextureParam(HLightCluster, (int)LightClusterKernels.DebugLightCluster, _LightClusterDebug_Output, LightClusterDebugColor.rt); + cmd.DispatchCompute(HLightCluster, (int)LightClusterKernels.DebugLightCluster, Mathf.CeilToInt(cameraWidth / 8.0f), Mathf.CeilToInt(cameraHeight / 8.0f), HRenderer.TextureXrSlices); + + if (HSettings.GeneralSettings.VolumetricDebug) + { + // Find all edge cells relative to each light's radius + cmd.DispatchCompute(HLightCluster, (int)LightClusterKernels.FillLightClusterDebugBuffer, HSettings.LightingSettings.LightClusterCellDensity / 4, HSettings.LightingSettings.LightClusterCellDensity / 4, HSettings.LightingSettings.LightClusterCellDensity / 4); + + LightClusterVisualizationMaterial.SetTexture(_LightClusterDebugColor, LightClusterDebugColor.rt); + LightClusterVisualizationMaterial.SetTexture(_LightClusterDebugDepth, LightClusterDebugDepth.rt); + + // Set our own Color and Depth render targets + CoreUtils.SetRenderTarget(cmd, LightClusterDebugColor.rt, LightClusterDebugDepth.rt, ClearFlag.Depth, Color.clear, 0, CubemapFace.Unknown, -1); + + // Draw cubes first to Color and then to Depth + cmd.DrawProcedural(Matrix4x4.identity, LightClusterVisualizationMaterial, 0, MeshTopology.Triangles, 36, HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity); + cmd.DrawProcedural(Matrix4x4.identity, LightClusterVisualizationMaterial, 1, MeshTopology.Triangles, 36, HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity); + + // Set only Color + CoreUtils.SetRenderTarget(cmd, LightClusterDebugColor.rt, ClearFlag.None); + + // Draw lines testing against the Depth filled by Cubes + cmd.DrawProcedural(Matrix4x4.identity, LightClusterVisualizationMaterial, 2, MeshTopology.Lines, 48, HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity); + } + } + } + + cmd.SetGlobalTexture(HShaderParams.g_LightClusterDebug, LightClusterDebugColor.rt); + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/LightClusterShared.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/LightClusterShared.cs.meta new file mode 100644 index 000000000..98dedfd38 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/LightClusterShared.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 4083002b04bf48140a8bf3ce9eb1ec73 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/Shared/LightClusterShared.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/SoftwareTracingShared.cs b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/SoftwareTracingShared.cs new file mode 100644 index 000000000..d2387c169 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/SoftwareTracingShared.cs @@ -0,0 +1,1020 @@ +//pipelinedefine +#define H_URP + +using System; +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Wrappers; +using UnityEngine; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Passes.Shared +{ + internal static class SoftwareTracingShared + { + #region ---------------------------------- KERNELS ---------------------------------- + + private enum HRenderAOKernel + { + HorizonTracing = 0, + OcclusionInterpolation = 1, + OcclusionAccumulation = 2, + } + + private enum HSpatialPrepassKernel + { + SpatialPrepass = 0, + GeometryNormals = 1, + GBufferDownsample = 2, + PointDistributionFill = 3, + SpatialOffsetsBufferFill = 4, + GeometryNormalsSmoothing = 5, + } + + internal enum HTemporalReprojectionKernel + { + ProbeReprojection = 0, + HistoryIndirectionScroll = 1, + HistoryIndirectionUpdate = 2, + HistoryProbeBuffersUpdate = 3, + CopyHistoryURP = 4, + CopyHistoryBIRP = 5, + } + + private enum HRayGenerationKernel + { + RayGeneration = 0, + RayCompaction = 1, + IndirectArguments = 2, + } + + private enum HTracingScreenSpaceKernel + { + LightEvaluation = 0, + ScreenSpaceTracing = 1, + } + + private enum HTracingWorldSpaceKernel + { + WorldSpaceTracing = 0, + LightEvaluation = 1, + } + + private enum HRadianceCacheKernel + { + CacheDataUpdate = 0, + CachePrimarySpawn = 1, + CacheTracingUpdate = 2, + CacheLightEvaluation = 3, + CacheDataClear = 4, + } + + private enum HProbeAmbientOcclusionKernel + { + ProbeAmbientOcclusion = 0, + ProbeAmbientOcclusionSpatialFilter = 1, + ProbeAmbientOcclusionHistoryUpdate = 2, + } + + private enum HReSTIRKernel + { + ProbeAtlasTemporalReuse = 0, + ProbeAtlasSpatialReuse = 1, + ProbeAtlasSpatialReuseDisocclusion = 2, + ReservoirHistoryUpdate = 3, + } + + private enum HReservoirValidationKernel + { + OcclusionValidation = 0, + OcclusionReprojection = 1, + OcclusionSpatialFilter = 2, + OcclusionTemporalFilter = 3, + } + + private enum HInterpolationKernel + { + GatherSH = 0, + Interpolation = 1, + } + + private enum HTemporalDenoiserKernel + { + TemporalDenoising = 0, + SpatialCleanup = 1, + } + + private enum HCopyKernel + { + CopyProbeAtlases = 0, + CopyProbeBuffers = 1, + CopyFullResBuffers = 2, + } + + private enum HDebugPassthroughKernel + { + DebugPassthrough = 0, + } + + #endregion ---------------------------------- KERNELS ---------------------------------- + + internal static ComputeShader HReservoirValidation = null; + internal static ComputeShader HTracingScreenSpace = null; + internal static ComputeShader HTracingWorldSpace = null; + internal static ComputeShader HRadianceCache = null; + internal static ComputeShader HTemporalReprojection = null; + internal static ComputeShader HReSTIR = null; + internal static ComputeShader HCopy = null; + internal static ComputeShader HSpatialPrepass = null; + internal static ComputeShader HProbeAmbientOcclusion = null; + internal static ComputeShader HProbeAtlasAccumulation = null; + internal static ComputeShader HRayGeneration = null; + internal static ComputeShader HRenderAO = null; + internal static ComputeShader HPrefilterTemporal = null; + internal static ComputeShader HPrefilterSpatial = null; + internal static ComputeShader HDebugPassthrough = null; + internal static ComputeShader HInterpolation = null; + internal static ComputeShader HTemporalDenoiser = null; + + // Indirection dispatch buffers + internal static ComputeBuffer RayCounter; + internal static ComputeBuffer RayCounterWS; + internal static ComputeBuffer IndirectArgumentsSS; + internal static ComputeBuffer IndirectArgumentsWS; + internal static ComputeBuffer IndirectArgumentsOV; + internal static ComputeBuffer IndirectArgumentsSF; + internal static HDynamicBuffer IndirectCoordsSS; + internal static HDynamicBuffer IndirectCoordsWS; + internal static HDynamicBuffer IndirectCoordsOV; + internal static HDynamicBuffer IndirectCoordsSF; + + // Spatial offsets buffers + internal static ComputeBuffer PointDistributionBuffer; + internal static ComputeBuffer SpatialOffsetsBuffer; + + // Hash buffers + internal static ComputeBuffer HashBuffer_Key; + internal static ComputeBuffer HashBuffer_Payload; + internal static ComputeBuffer HashBuffer_Counter; + internal static ComputeBuffer HashBuffer_Radiance; + internal static ComputeBuffer HashBuffer_Position; + + // Materials + internal static Material ColorCompose_BIRP; + + #region RT HADNLES ------------------------------------> + + internal static RTWrapper ColorPreviousFrame = new RTWrapper(); + + // SSAO RT + internal static RTWrapper ProbeSSAO = new RTWrapper(); + internal static RTWrapper NormalDepthHalf = new RTWrapper(); + internal static RTWrapper BentNormalsAO = new RTWrapper(); + internal static RTWrapper BentNormalsAO_Interpolated = new RTWrapper(); + internal static RTWrapper BentNormalsAO_History = new RTWrapper(); + internal static RTWrapper BentNormalsAO_Accumulated = new RTWrapper(); + internal static RTWrapper BentNormalsAO_Samplecount = new RTWrapper(); + internal static RTWrapper BentNormalsAO_SamplecountHistory = new RTWrapper(); + + // TRACING RT + internal static RTWrapper VoxelPayload = new RTWrapper(); + internal static RTWrapper RayDirections = new RTWrapper(); + internal static RTWrapper HitRadiance = new RTWrapper(); + internal static RTWrapper HitDistanceScreenSpace = new RTWrapper(); + internal static RTWrapper HitDistanceWorldSpace = new RTWrapper(); + internal static RTWrapper HitCoordScreenSpace = new RTWrapper(); + + // PROBE AO RT + internal static RTWrapper ProbeAmbientOcclusion = new RTWrapper(); + internal static RTWrapper ProbeAmbientOcclusion_History = new RTWrapper(); + internal static RTWrapper ProbeAmbientOcclusion_Filtered = new RTWrapper(); + + // GBUFFER RT + internal static RTWrapper GeometryNormal = new RTWrapper(); + internal static RTWrapper NormalDepth_History = new RTWrapper(); + internal static RTWrapper ProbeNormalDepth = new RTWrapper(); + internal static RTWrapper ProbeNormalDepth_History = new RTWrapper(); + internal static RTWrapper ProbeWorldPosNormal_History = new RTWrapper(); + internal static RTWrapper ProbeNormalDepth_Intermediate = new RTWrapper(); + internal static RTWrapper ProbeDiffuse = new RTWrapper(); + + // REPROJECTION RT + internal static RTWrapper HistoryIndirection = new RTWrapper(); + internal static RTWrapper ReprojectionCoord = new RTWrapper(); + internal static RTWrapper PersistentReprojectionCoord = new RTWrapper(); + internal static RTWrapper ReprojectionWeights = new RTWrapper(); + internal static RTWrapper PersistentReprojectionWeights = new RTWrapper(); + + // SPATIAL PREPASS RT + internal static RTWrapper SpatialOffsetsPacked = new RTWrapper(); + internal static RTWrapper SpatialWeightsPacked = new RTWrapper(); + + // RESERVOIR RT + internal static RTWrapper ReservoirAtlas = new RTWrapper(); + internal static RTWrapper ReservoirAtlas_History = new RTWrapper(); + internal static RTWrapper ReservoirAtlasRadianceData_A = new RTWrapper(); + internal static RTWrapper ReservoirAtlasRadianceData_B = new RTWrapper(); + internal static RTWrapper ReservoirAtlasRadianceData_C = new RTWrapper(); + internal static RTWrapper ReservoirAtlasRayData_A = new RTWrapper(); + internal static RTWrapper ReservoirAtlasRayData_B = new RTWrapper(); + internal static RTWrapper ReservoirAtlasRayData_C = new RTWrapper(); + + // SHADOW GUIDANCE MASK RT + internal static RTWrapper ShadowGuidanceMask = new RTWrapper(); + internal static RTWrapper ShadowGuidanceMask_Accumulated = new RTWrapper(); + internal static RTWrapper ShadowGuidanceMask_Filtered = new RTWrapper(); + internal static RTWrapper ShadowGuidanceMask_History = new RTWrapper(); + internal static RTWrapper ShadowGuidanceMask_CheckerboardHistory = new RTWrapper(); + internal static RTWrapper ShadowGuidanceMask_Samplecount = new RTWrapper(); + internal static RTWrapper ShadowGuidanceMask_SamplecountHistory = new RTWrapper(); + + // INTERPOLATION RT + internal static RTWrapper PackedSH_A = new RTWrapper(); + internal static RTWrapper PackedSH_B = new RTWrapper(); + internal static RTWrapper Radiance_Interpolated = new RTWrapper(); + + // TEMPORAL DENOISER RT + internal static RTWrapper RadianceAccumulated = new RTWrapper(); + internal static RTWrapper RadianceAccumulated_History = new RTWrapper(); + internal static RTWrapper LuminanceDelta = new RTWrapper(); + internal static RTWrapper LuminanceDelta_History = new RTWrapper(); + + // DEBUG RT + internal static RTWrapper DebugOutput = new RTWrapper(); + + internal static RTWrapper RadianceCacheFiltered = new RTWrapper(); + + #endregion + + internal static readonly ProfilingSamplerHTrace s_RenderAmbientOcclsuionProfilingSampler = new ProfilingSamplerHTrace("Render Ambient Occlsuion", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 2); + internal static readonly ProfilingSamplerHTrace s_ProbeGBufferDownsamplingProfilingSampler = new ProfilingSamplerHTrace("Probe GBuffer Downsampling", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 3); + internal static readonly ProfilingSamplerHTrace s_ProbeTemporalReprojectionProfilingSampler = new ProfilingSamplerHTrace("Probe Temporal Reprojection", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 4); + internal static readonly ProfilingSamplerHTrace s_RayGenerationProfilingSampler = new ProfilingSamplerHTrace("Ray Generation", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 5); + internal static readonly ProfilingSamplerHTrace s_ClearTargetsProfilingSampler = new ProfilingSamplerHTrace("Clear Targets", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 6); + internal static readonly ProfilingSamplerHTrace s_ScreenSpaceLightingProfilingSampler = new ProfilingSamplerHTrace("Screen Space Lighting", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 7); + internal static readonly ProfilingSamplerHTrace s_RayCompactionProfilingSampler = new ProfilingSamplerHTrace("Ray Compaction", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 8); + internal static readonly ProfilingSamplerHTrace s_WorldSpaceLightingProfilingSampler = new ProfilingSamplerHTrace("World Space Lighting", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 9); + internal static readonly ProfilingSamplerHTrace s_WorldSpaceTracingProfilingSampler = new ProfilingSamplerHTrace("World Space Tracing", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 10); + internal static readonly ProfilingSamplerHTrace s_LightEvaluationProfilingSampler = new ProfilingSamplerHTrace("Light Evaluation", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 11); + internal static readonly ProfilingSamplerHTrace s_RadianceCachingProfilingSampler = new ProfilingSamplerHTrace("Radiance Caching", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 12); + internal static readonly ProfilingSamplerHTrace s_CacheTracingUpdateProfilingSampler = new ProfilingSamplerHTrace("Cache Tracing Update", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 13); + internal static readonly ProfilingSamplerHTrace s_CacheLightEvaluationProfilingSampler = new ProfilingSamplerHTrace("Cache Light Evaluation", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 14); + internal static readonly ProfilingSamplerHTrace s_PrimaryCacheSpawnProfilingSampler = new ProfilingSamplerHTrace("Primary Cache Spawn", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 15); + internal static readonly ProfilingSamplerHTrace s_CacheDataUpdateProfilingSampler = new ProfilingSamplerHTrace("Cache Data Update", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 16); + internal static readonly ProfilingSamplerHTrace s_SpatialPrepassProfilingSampler = new ProfilingSamplerHTrace("Spatial Prepass", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 17); + internal static readonly ProfilingSamplerHTrace s_ReSTIRTemporalReuseProfilingSampler = new ProfilingSamplerHTrace("ReSTIR Temporal Reuse", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 18); + internal static readonly ProfilingSamplerHTrace s_ReservoirOcclusionValidationProfilingSampler = new ProfilingSamplerHTrace("Reservoir Occlusion Validation", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 19); + internal static readonly ProfilingSamplerHTrace s_ReSTIRSpatialReuseProfilingSampler = new ProfilingSamplerHTrace("ReSTIR Spatial Reuse", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 20); + internal static readonly ProfilingSamplerHTrace s_PersistentHistoryUpdateProfilingSampler = new ProfilingSamplerHTrace("Persistent History Update", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 20); + internal static readonly ProfilingSamplerHTrace s_InterpolationProfilingSampler = new ProfilingSamplerHTrace("Interpolation", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 0); + internal static readonly ProfilingSamplerHTrace s_TemporalDenoisingProfilingSampler = new ProfilingSamplerHTrace("Temporal Denoising", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 0); + internal static readonly ProfilingSamplerHTrace s_SpatialCleanupProfilingSampler = new ProfilingSamplerHTrace("Spatial Cleanup", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 0); + internal static readonly ProfilingSamplerHTrace s_CopyBuffersProfilingSampler = new ProfilingSamplerHTrace("Copy Buffers", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 0); + internal static readonly ProfilingSamplerHTrace s_DebugPassthroughProfilingSampler = new ProfilingSamplerHTrace("Debug Passthrough", parentName: HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, priority: 0); + + private const string MULTIBOUNCE_CACHE = "MULTIBOUNCE_CACHE"; + private const string MULTIBOUNCE_OFF = "MULTIBOUNCE_OFF"; + private const string MULTIBOUNCE_APV = "MULTIBOUNCE_APV"; + private const string GI_TRACING_IN_REFLECTIONS = "GI_TRACING_IN_REFLECTIONS"; + private const string GI_APPROXIMATION_IN_REFLECTIONS = "GI_APPROXIMATION_IN_REFLECTIONS"; + private const string GI_APPROXIMATION_IN_REFLECTIONS_OCCLUSION_CHECK = "GI_APPROXIMATION_IN_REFLECTIONS_OCCLUSION_CHECK"; + private const string USE_DIRECTIONAL_OCCLUSION = "USE_DIRECTIONAL_OCCLUSION"; + private const string DIFFUSE_BUFFER_UNAVAILABLE = "DIFFUSE_BUFFER_UNAVAILABLE"; + private const string HIT_SCREEN_SPACE_LIGHTING = "HIT_SCREEN_SPACE_LIGHTING"; + private const string EVALUATE_PUNCTUAL_LIGHTS = "EVALUATE_PUNCTUAL_LIGHTS"; + private const string ADDITIONAL_LIGHT_SHADOWS = "_ADDITIONAL_LIGHT_SHADOWS"; + + private static int _hFrameIndex = 0; + private static int _hashUpdateFrameIndex = 0; + private static int _startFrameCounter = 0; + + internal static bool SkipFirstFrame = true; + internal static bool ClearRadianceCache = false; + + internal static bool UseDirectionalOcclusion => HSettings.ScreenSpaceLightingSettings.DirectionalOcclusion && HSettings.ScreenSpaceLightingSettings.OcclusionIntensity > Single.Epsilon; + + private static bool UseUrpAdditionalLightShadows + { + get + { + return HRendererURP.UrpAsset != null && HRendererURP.UrpAsset.supportsAdditionalLightShadows; + } + } + + private static void SetUrpAdditionalLightShadowsKeyword(ComputeShader ComputeShader) + { + if (ComputeShader == null) + return; + + if (HSettings.LightingSettings.EvaluatePunctualLights && UseUrpAdditionalLightShadows) + ComputeShader.EnableKeyword(ADDITIONAL_LIGHT_SHADOWS); + else + ComputeShader.DisableKeyword(ADDITIONAL_LIGHT_SHADOWS); + } + + internal struct HistoryData : IHistoryData + { + public bool DebugModeEnabled; + public bool DirectionalOcclusion; + public RayCountMode RayCountMode; + public TracingMode TracingMode; + + public void Update() + { + DebugModeEnabled = HSettings.GeneralSettings.DebugModeWS != DebugModeWS.None; + DirectionalOcclusion = UseDirectionalOcclusion; + RayCountMode = HSettings.GeneralSettings.RayCountMode; + TracingMode = HSettings.GeneralSettings.TracingMode; + } + } + + internal static HistoryData History = new HistoryData(); + + internal static void Execute(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight, Texture cameraColorBuffer = null, Texture previousColorBuffer = null, Texture diffuseBuffer = null) + { + Texture VoxelData = Shader.GetGlobalTexture(HShaderParams.g_VoxelPositionPyramid); + if (VoxelData == null || VoxelData.width != HSettings.VoxelizationSettings.ExactData.Resolution.x) + return; + + Texture ShadowmapData = Shader.GetGlobalTexture(HShaderParams.g_HTraceShadowmap); + if (ShadowmapData == null || ShadowmapData.width != 2048) + return; + + bool UseAPVMultibounce = HSettings.DebugSettings.TestCheckbox; + + + cmd.SetGlobalInt(HShaderParams.g_TestCheckbox, HSettings.DebugSettings.TestCheckbox ? 1 : 0); + + _hFrameIndex = _hFrameIndex > 15 ? 0 : _hFrameIndex; + _hashUpdateFrameIndex = _hashUpdateFrameIndex > HConstants.HASH_UPDATE_FRACTION ? 0 : _hashUpdateFrameIndex; + + cmd.SetGlobalInt(HShaderParams.g_ProbeSize, HSettings.GeneralSettings.RayCountMode.ParseToProbeSize()); + cmd.SetGlobalInt(HShaderParams.g_OctahedralSize, HConstants.OCTAHEDRAL_SIZE); + cmd.SetGlobalInt(HShaderParams.g_HFrameIndex, _hFrameIndex); + cmd.SetGlobalInt(HShaderParams.g_ReprojectSkippedFrame, Time.frameCount % 8 == 0 ? 1 : 0); + cmd.SetGlobalInt(HShaderParams.g_PersistentHistorySamples, HConstants.PERSISTENT_HISTORY_SAMPLES); + + // Constants set + cmd.SetGlobalFloat(HShaderParams.g_SkyOcclusionCone, HConfig.SkyOcclusionCone); + cmd.SetGlobalFloat(HShaderParams.g_DirectionalLightIntensity, HSettings.LightingSettings.DirectionalLightIntensity); + cmd.SetGlobalFloat(HShaderParams.g_SurfaceDiffuseIntensity, HSettings.LightingSettings.SurfaceDiffuseIntensity); + cmd.SetGlobalFloat(HShaderParams.g_SkyLightIntensity, HSettings.LightingSettings.SkyLightIntensity); + + //cmdList.SetGlobalInt("_TestCheckbox", DebugData.TestCheckbox == true ? 1 : 0); + + if (HSettings.LightingSettings.EvaluatePunctualLights) Shader.EnableKeyword(EVALUATE_PUNCTUAL_LIGHTS); + else Shader.DisableKeyword(EVALUATE_PUNCTUAL_LIGHTS); + + cmd.SetGlobalInt(HShaderParams.g_ReprojectSkippedFrame, 0); + + int screenResX = cameraWidth; + int screenResY = cameraHeight; + + // Calculate Resolution for Compute Shaders + Vector2Int runningRes = new Vector2Int(screenResX, screenResY); + Vector2 probeAtlasRes = runningRes * Vector2.one / HSettings.GeneralSettings.RayCountMode.ParseToProbeSize() * HConstants.OCTAHEDRAL_SIZE; + + //Dispatch resolutions + int fullResX_8 = Mathf.CeilToInt((float)runningRes.x / 8); + int fullResY_8 = Mathf.CeilToInt((float)runningRes.y / 8); + int probeResX_8 = Mathf.CeilToInt(((float)runningRes.x / (float)HSettings.GeneralSettings.RayCountMode.ParseToProbeSize() / 8.0f)); + int probeResY_8 = Mathf.CeilToInt(((float)runningRes.y / (float)HSettings.GeneralSettings.RayCountMode.ParseToProbeSize() / 8.0f)); + int probeAtlasResX_8 = Mathf.CeilToInt((Mathf.CeilToInt((float)runningRes.x / (float)HSettings.GeneralSettings.RayCountMode.ParseToProbeSize()) * (float)HConstants.OCTAHEDRAL_SIZE) / 8); + int probeAtlasResY_8 = Mathf.CeilToInt((Mathf.CeilToInt((float)runningRes.y / (float)HSettings.GeneralSettings.RayCountMode.ParseToProbeSize()) * (float)HConstants.OCTAHEDRAL_SIZE) / 8); + + bool diffuseBufferUnavailable = diffuseBuffer == null; + + cmd.SetGlobalBuffer(HShaderParams.g_HashBuffer_Key, HashBuffer_Key); + cmd.SetGlobalBuffer(HShaderParams.g_HashBuffer_Payload, HashBuffer_Payload); + cmd.SetGlobalBuffer(HShaderParams.g_HashBuffer_Counter, HashBuffer_Counter); + cmd.SetGlobalBuffer(HShaderParams.g_HashBuffer_Radiance, HashBuffer_Radiance); + cmd.SetGlobalBuffer(HShaderParams.g_HashBuffer_Position, HashBuffer_Position); + + cmd.SetGlobalInt(HShaderParams.g_HashStorageSize, HConstants.HASH_STORAGE_SIZE); + cmd.SetGlobalInt(HShaderParams.g_HashUpdateFraction, HConstants.HASH_UPDATE_FRACTION); + + cmd.SetGlobalTexture(HShaderParams.g_HTraceBufferGI, RadianceAccumulated.rt); + + if (camera.cameraType == CameraType.Reflection) + return; + + if (_startFrameCounter < 2) { _startFrameCounter++; return; } + + + // ---------------------------------------- RENDER AMBIENT OCCLUSION ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_RenderAmbientOcclsuionProfilingSampler)) + { + int computeResX_GI = (runningRes.x / 2 + 8 - 1) / 8; + int computeResY_GI = (runningRes.y / 2 + 8 - 1) / 8; + + if (UseDirectionalOcclusion) + { + HInterpolation.EnableKeyword(USE_DIRECTIONAL_OCCLUSION); + HSpatialPrepass.EnableKeyword(USE_DIRECTIONAL_OCCLUSION); + + cmd.SetComputeTextureParam(HRenderAO, (int)HRenderAOKernel.HorizonTracing, HShaderParams._BentNormalAmbientOcclusion_Output, BentNormalsAO.rt); + cmd.SetComputeTextureParam(HRenderAO, (int)HRenderAOKernel.HorizonTracing, HShaderParams._NormalDepthHalf_Output, NormalDepthHalf.rt); + cmd.SetComputeFloatParam(HRenderAO, HShaderParams._Camera_FOV, camera.fieldOfView); + cmd.DispatchCompute(HRenderAO, (int)HRenderAOKernel.HorizonTracing, computeResX_GI, computeResY_GI, HRenderer.TextureXrSlices); + + cmd.SetComputeTextureParam(HRenderAO, (int)HRenderAOKernel.OcclusionInterpolation, HShaderParams._AmbientOcclusion, BentNormalsAO.rt); + cmd.SetComputeTextureParam(HRenderAO, (int)HRenderAOKernel.OcclusionInterpolation, HShaderParams._NormalDepthHalf, NormalDepthHalf.rt); + cmd.SetComputeTextureParam(HRenderAO, (int)HRenderAOKernel.OcclusionInterpolation, HShaderParams._BentNormalAO_Output, BentNormalsAO_Interpolated.rt); + cmd.SetComputeTextureParam(HRenderAO, (int)HRenderAOKernel.OcclusionInterpolation, HShaderParams._GeometryNormal_Output, GeometryNormal.rt); + cmd.DispatchCompute(HRenderAO, (int)HRenderAOKernel.OcclusionInterpolation, fullResX_8, fullResY_8, HRenderer.TextureXrSlices); + } + else + { + HInterpolation.DisableKeyword(USE_DIRECTIONAL_OCCLUSION); + HSpatialPrepass.DisableKeyword(USE_DIRECTIONAL_OCCLUSION); + } + } + + // ---------------------------------------- PROBE GBUFFER DOWNSAMPLING ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_ProbeGBufferDownsamplingProfilingSampler)) + { + // Fill sample offsets for disk filters + cmd.SetComputeBufferParam(HSpatialPrepass, (int)HSpatialPrepassKernel.PointDistributionFill, HShaderParams._PointDistribution_Output, PointDistributionBuffer); + cmd.DispatchCompute(HSpatialPrepass, (int)HSpatialPrepassKernel.PointDistributionFill, 1, 1, 1); + + // Fill 4x4 spatial offset buffer + cmd.SetComputeBufferParam(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialOffsetsBufferFill, HShaderParams._SpatialOffsetsBuffer_Output, SpatialOffsetsBuffer); + cmd.DispatchCompute(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialOffsetsBufferFill, 1, 1, 1); + + // Calculate geometry normals + if (!UseDirectionalOcclusion) + { + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.GeometryNormals, HShaderParams._GeometryNormal_Output, GeometryNormal.rt); + cmd.DispatchCompute(HSpatialPrepass, (int)HSpatialPrepassKernel.GeometryNormals, fullResX_8, fullResY_8, HRenderer.TextureXrSlices); + } + + cmd.SetGlobalTexture(HShaderParams.g_GeometryNormal, GeometryNormal.rt); + + if (diffuseBufferUnavailable) HSpatialPrepass.EnableKeyword(DIFFUSE_BUFFER_UNAVAILABLE); + if (!diffuseBufferUnavailable) HSpatialPrepass.DisableKeyword(DIFFUSE_BUFFER_UNAVAILABLE); + + // Downsample depth, normal, diffuse and ambient occlusion + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.GBufferDownsample, HShaderParams._ProbeNormalDepth_Output, ProbeNormalDepth_Intermediate.rt); + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.GBufferDownsample, HShaderParams._ProbeDiffuse_Output, ProbeDiffuse.rt); + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.GBufferDownsample, HShaderParams._SSAO, BentNormalsAO_Interpolated.rt); + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.GBufferDownsample, HShaderParams._ProbeSSAO_Output, ProbeSSAO.rt); + cmd.DispatchCompute(HSpatialPrepass, (int)HSpatialPrepassKernel.GBufferDownsample, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + + // Smooth geometry normals + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.GeometryNormalsSmoothing, HShaderParams._ProbeNormalDepth, ProbeNormalDepth_Intermediate.rt); + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.GeometryNormalsSmoothing, HShaderParams._ProbeNormalDepth_Output, ProbeNormalDepth.rt); + cmd.DispatchCompute(HSpatialPrepass, (int)HSpatialPrepassKernel.GeometryNormalsSmoothing, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- PROBE TEMPORAL REPROJECTION ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_ProbeTemporalReprojectionProfilingSampler)) + { + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.ProbeReprojection, HShaderParams._HistoryIndirection, HistoryIndirection.rt); + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.ProbeReprojection, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.ProbeReprojection, HShaderParams._ProbeWorldPosNormal_History, ProbeWorldPosNormal_History.rt); + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.ProbeReprojection, HShaderParams._ReprojectionCoords_Output, ReprojectionCoord.rt); + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.ProbeReprojection, HShaderParams._ReprojectionWeights_Output, ReprojectionWeights.rt); + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.ProbeReprojection, HShaderParams._PersistentReprojectionWeights_Output, PersistentReprojectionWeights.rt); + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.ProbeReprojection, HShaderParams._PersistentReprojectionCoord_Output, PersistentReprojectionCoord.rt); + cmd.DispatchCompute(HTemporalReprojection, (int)HTemporalReprojectionKernel.ProbeReprojection, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- RAY GENERATION ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_RayGenerationProfilingSampler)) + { + // Generate ray directions and compute lists of indirectly dispatched threads + cmd.SetComputeTextureParam(HRayGeneration, (int)HRayGenerationKernel.RayGeneration, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HRayGeneration, (int)HRayGenerationKernel.RayGeneration, HShaderParams._ReprojectionCoords, ReprojectionCoord.rt); + cmd.SetComputeTextureParam(HRayGeneration, (int)HRayGenerationKernel.RayGeneration, HShaderParams._RayDirectionsJittered_Output, RayDirections.rt); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.RayGeneration, HShaderParams._IndirectCoordsSS_Output, IndirectCoordsSS.ComputeBuffer); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.RayGeneration, HShaderParams._IndirectCoordsOV_Output, IndirectCoordsOV.ComputeBuffer); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.RayGeneration, HShaderParams._IndirectCoordsSF_Output, IndirectCoordsSF.ComputeBuffer); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.RayGeneration, HShaderParams._RayCounter_Output, RayCounter); + cmd.DispatchCompute(HRayGeneration, (int)HRayGenerationKernel.RayGeneration, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + + // Prepare arguments for screen space indirect dispatch + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._RayCounter, RayCounter); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._TracingCoords, IndirectCoordsSS.ComputeBuffer); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._IndirectArguments_Output, IndirectArgumentsSS); + cmd.SetComputeIntParam(HRayGeneration, HShaderParams._RayCounterIndex, 0); + cmd.DispatchCompute(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, 1, 1, HRenderer.TextureXrSlices); + + // Prepare arguments for occlusion validation indirect dispatch + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._RayCounter, RayCounter); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._TracingCoords, IndirectCoordsOV.ComputeBuffer); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._IndirectArguments_Output, IndirectArgumentsOV); + cmd.SetComputeIntParam(HRayGeneration, HShaderParams._RayCounterIndex, 1); + cmd.DispatchCompute(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, 1, 1, HRenderer.TextureXrSlices); + + // Prepare arguments for spatial filter indirect dispatch + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._RayCounter, RayCounter); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._TracingCoords, IndirectCoordsSF.ComputeBuffer); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._IndirectArguments_Output, IndirectArgumentsSF); + cmd.SetComputeIntParam(HRayGeneration, HShaderParams._RayCounterIndex, 2); + cmd.DispatchCompute(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, 1, 1, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- CLEAR CHECKERBOARD TARGETS ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_ClearTargetsProfilingSampler)) + { + // Clear hit targets + CoreUtils.SetRenderTarget(cmd, HitDistanceScreenSpace.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, HitDistanceWorldSpace.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, HitCoordScreenSpace.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, HitRadiance.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + + // Clear voxel payload targets + CoreUtils.SetRenderTarget(cmd, VoxelPayload.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + } + + // ---------------------------------------- SCREEN SPACE LIGHTING ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_ScreenSpaceLightingProfilingSampler)) + { + if (HSettings.ScreenSpaceLightingSettings.EvaluateHitLighting && !diffuseBufferUnavailable) HTracingScreenSpace.EnableKeyword(HIT_SCREEN_SPACE_LIGHTING); + if (!HSettings.ScreenSpaceLightingSettings.EvaluateHitLighting || diffuseBufferUnavailable) HTracingScreenSpace.DisableKeyword(HIT_SCREEN_SPACE_LIGHTING); + + // Trace screen-space rays + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, HShaderParams._ColorPyramid_History, previousColorBuffer); + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, HShaderParams._NormalDepth_History, NormalDepth_History.rt); + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, HShaderParams._RayDirection, RayDirections.rt); + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, HShaderParams._HitRadiance_Output, HitRadiance.rt); + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, HShaderParams._HitDistance_Output, HitDistanceScreenSpace.rt); + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, HShaderParams._HitCoord_Output, HitCoordScreenSpace.rt); + cmd.SetComputeBufferParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, HShaderParams._RayCounter, RayCounter); + cmd.SetComputeBufferParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, HShaderParams._TracingCoords, IndirectCoordsSS.ComputeBuffer); + cmd.SetComputeIntParam(HTracingScreenSpace, HShaderParams._IndexXR, 0); + cmd.DispatchCompute(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, IndirectArgumentsSS, 0); + if (HRenderer.TextureXrSlices > 1) + { + cmd.SetComputeIntParam(HTracingScreenSpace, HShaderParams._IndexXR, 1); + cmd.DispatchCompute(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.ScreenSpaceTracing, IndirectArgumentsSS, sizeof(uint) * 3); + } + + + // Evaluate screen-space hit it requested + if (HSettings.ScreenSpaceLightingSettings.EvaluateHitLighting && !diffuseBufferUnavailable) + { + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.LightEvaluation, HShaderParams._ColorPyramid_History, previousColorBuffer); + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.LightEvaluation, HShaderParams._Radiance_History, RadianceAccumulated.rt); + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.LightEvaluation, HShaderParams._HitCoord, HitCoordScreenSpace.rt); + cmd.SetComputeTextureParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.LightEvaluation, HShaderParams._HitRadiance_Output, HitRadiance.rt); + cmd.SetComputeBufferParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.LightEvaluation, HShaderParams._RayCounter, RayCounter); + cmd.SetComputeBufferParam(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.LightEvaluation, HShaderParams._TracingCoords, IndirectCoordsSS.ComputeBuffer); + cmd.SetComputeIntParam(HTracingScreenSpace, HShaderParams._IndexXR, 0); + cmd.DispatchCompute(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.LightEvaluation, IndirectArgumentsSS, 0); + if (HRenderer.TextureXrSlices > 1) + { + cmd.SetComputeIntParam(HTracingScreenSpace, HShaderParams._IndexXR, 1); + cmd.DispatchCompute(HTracingScreenSpace, (int)HTracingScreenSpaceKernel.LightEvaluation, IndirectArgumentsSS, sizeof(uint) * 3); + } + } + } + + // ---------------------------------------- RAY COMPACTION ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_RayCompactionProfilingSampler)) + { + // Compact rays + cmd.SetComputeTextureParam(HRayGeneration, (int)HRayGenerationKernel.RayCompaction, HShaderParams._HitDistance, HitDistanceScreenSpace.rt); + cmd.SetComputeTextureParam(HRayGeneration, (int)HRayGenerationKernel.RayCompaction, HShaderParams._HitDistance_Output, HitDistanceWorldSpace.rt); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.RayCompaction, HShaderParams._RayCounter, RayCounter); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.RayCompaction, HShaderParams._TracingCoords, IndirectCoordsSS.ComputeBuffer); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.RayCompaction, HShaderParams._TracingRayCounter_Output, RayCounterWS); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.RayCompaction, HShaderParams._TracingCoords_Output, IndirectCoordsWS.ComputeBuffer); + cmd.SetComputeIntParam(HRayGeneration, HShaderParams._IndexXR, 0); + cmd.DispatchCompute(HRayGeneration, (int)HRayGenerationKernel.RayCompaction, IndirectArgumentsSS, 0); + if (HRenderer.TextureXrSlices > 1) + { + cmd.SetComputeIntParam(HRayGeneration, HShaderParams._IndexXR, 1); + cmd.DispatchCompute(HRayGeneration, (int)HRayGenerationKernel.RayCompaction, IndirectArgumentsSS, sizeof(uint) * 3); + } + + // Prepare indirect arguments for world space lighting + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._RayCounter, RayCounterWS); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._TracingCoords, IndirectCoordsWS.ComputeBuffer); + cmd.SetComputeBufferParam(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, HShaderParams._IndirectArguments_Output, IndirectArgumentsWS); + cmd.SetComputeIntParam(HRayGeneration, HShaderParams._RayCounterIndex, 0); + cmd.DispatchCompute(HRayGeneration, (int)HRayGenerationKernel.IndirectArguments, 1, 1, HRenderer.TextureXrSlices); + } + + + // TDR timeout protection + if (SkipFirstFrame + || History.TracingMode != HSettings.GeneralSettings.TracingMode + || History.RayCountMode != HSettings.GeneralSettings.RayCountMode) + { + SkipFirstFrame = false; + return; + } + + // ---------------------------------------- WORLD SPACE LIGHTING ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_WorldSpaceLightingProfilingSampler)) + { + if (HSettings.GeneralSettings.Multibounce == Multibounce.None) { HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_CACHE); HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_APV); HTracingWorldSpace.EnableKeyword(MULTIBOUNCE_OFF); } + if (HSettings.GeneralSettings.Multibounce == Multibounce.IrradianceCache) { HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_OFF); HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_APV); HTracingWorldSpace.EnableKeyword(MULTIBOUNCE_CACHE); } + if (HSettings.GeneralSettings.Multibounce == Multibounce.AdaptiveProbeVolumes) { HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_CACHE); HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_OFF); HTracingWorldSpace.EnableKeyword(MULTIBOUNCE_APV); } + + if (HSettings.LightingSettings.EvaluatePunctualLights) HTracingWorldSpace.EnableKeyword(EVALUATE_PUNCTUAL_LIGHTS); + else HTracingWorldSpace.DisableKeyword(EVALUATE_PUNCTUAL_LIGHTS); + SetUrpAdditionalLightShadowsKeyword(HTracingWorldSpace); + + // Trace world-space rays + using (new HTraceProfilingScope(cmd, s_WorldSpaceTracingProfilingSampler)) + { + cmd.SetComputeTextureParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, HShaderParams._HitDistance, HitDistanceScreenSpace.rt); + cmd.SetComputeTextureParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, HShaderParams._RayDirection, RayDirections.rt); + cmd.SetComputeTextureParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, HShaderParams._HitDistance_Output, HitDistanceWorldSpace.rt); + cmd.SetComputeTextureParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, HShaderParams._VoxelPayload_Output, VoxelPayload.rt); + cmd.SetComputeTextureParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, HShaderParams._HitRadiance_Output, HitRadiance.rt); + cmd.SetComputeBufferParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, HShaderParams._PointDistribution, PointDistributionBuffer); + cmd.SetComputeBufferParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, HShaderParams._TracingCoords, IndirectCoordsWS.ComputeBuffer); + cmd.SetComputeBufferParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, HShaderParams._RayCounter, RayCounterWS); + cmd.SetComputeFloatParam(HTracingWorldSpace, HShaderParams._RayLength, HSettings.GeneralSettings.RayLength); + cmd.SetComputeIntParam(HTracingWorldSpace, HShaderParams._IndexXR, 0); + cmd.DispatchCompute(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, IndirectArgumentsWS, 0); + if (HRenderer.TextureXrSlices > 1) + { + cmd.SetComputeIntParam(HTracingWorldSpace, HShaderParams._IndexXR, 1); + cmd.DispatchCompute(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.WorldSpaceTracing, IndirectArgumentsWS, sizeof(uint) * 3); + } + } + + // Evaluate world-space lighting + using (new HTraceProfilingScope(cmd, s_LightEvaluationProfilingSampler)) + { + cmd.SetComputeTextureParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.LightEvaluation, HShaderParams._VoxelPayload, VoxelPayload.rt); + cmd.SetComputeTextureParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.LightEvaluation, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.LightEvaluation, HShaderParams._HitRadiance_Output, HitRadiance.rt); + cmd.SetComputeBufferParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.LightEvaluation, HShaderParams._TracingCoords, IndirectCoordsWS.ComputeBuffer); + cmd.SetComputeBufferParam(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.LightEvaluation, HShaderParams._RayCounter, RayCounterWS); + cmd.SetComputeIntParam(HTracingWorldSpace, HShaderParams._IndexXR, 0); + cmd.DispatchCompute(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.LightEvaluation, IndirectArgumentsWS, 0); + if (HRenderer.TextureXrSlices > 1) + { + cmd.SetComputeIntParam(HTracingWorldSpace, HShaderParams._IndexXR, 1); + cmd.DispatchCompute(HTracingWorldSpace, (int)HTracingWorldSpaceKernel.LightEvaluation, IndirectArgumentsWS, sizeof(uint) * 3); + } + } + } + + // ---------------------------------------- RADIANCE CACHING ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_RadianceCachingProfilingSampler)) + { + if (HSettings.GeneralSettings.Multibounce == Multibounce.IrradianceCache) + { + if (HSettings.LightingSettings.EvaluatePunctualLights) HRadianceCache.EnableKeyword(EVALUATE_PUNCTUAL_LIGHTS); + else HRadianceCache.DisableKeyword(EVALUATE_PUNCTUAL_LIGHTS); + SetUrpAdditionalLightShadowsKeyword(HRadianceCache); + + // Clear cache on request + if (ClearRadianceCache) + { + cmd.DispatchCompute(HRadianceCache, (int)HRadianceCacheKernel.CacheDataClear, HConstants.HASH_STORAGE_SIZE / 64, 1, 1); + ClearRadianceCache = false; + } + + HRadianceCache.SetInt(HShaderParams._HashUpdateFrameIndex, _hashUpdateFrameIndex); + + // Cache tracing update + using (new HTraceProfilingScope(cmd, s_CacheTracingUpdateProfilingSampler)) + { + cmd.SetComputeFloatParam(HRadianceCache, HShaderParams._RayLength, HSettings.GeneralSettings.RayLength); + cmd.DispatchCompute(HRadianceCache, (int)HRadianceCacheKernel.CacheTracingUpdate, (HConstants.HASH_STORAGE_SIZE / HConstants.HASH_UPDATE_FRACTION) / 64, 1, 1); + } + + // Cache light evaluation at hit points + using (new HTraceProfilingScope(cmd, s_CacheLightEvaluationProfilingSampler)) + { + cmd.DispatchCompute(HRadianceCache, (int)HRadianceCacheKernel.CacheLightEvaluation, (HConstants.HASH_STORAGE_SIZE / HConstants.HASH_UPDATE_FRACTION) / 64, 1, 1); + } + + // Cache writing at primary surfaces + using (new HTraceProfilingScope(cmd, s_PrimaryCacheSpawnProfilingSampler)) + { + cmd.SetComputeTextureParam(HRadianceCache, (int)HRadianceCacheKernel.CachePrimarySpawn, HShaderParams._ReprojectionCoords, ReprojectionCoord.rt); + cmd.SetComputeTextureParam(HRadianceCache, (int)HRadianceCacheKernel.CachePrimarySpawn, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HRadianceCache, (int)HRadianceCacheKernel.CachePrimarySpawn, HShaderParams._RadianceAtlas, HitRadiance.rt); + cmd.DispatchCompute(HRadianceCache, (int)HRadianceCacheKernel.CachePrimarySpawn, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + } + + // Cache counter update, deallocation of out-of-bounds entries, filtered cache population + using (new HTraceProfilingScope(cmd, s_CacheDataUpdateProfilingSampler)) + { + // Clear filtered cache every frame before writing to it + // CoreUtils.SetRenderTarget(ctx.cmd, RadianceCacheFiltered, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + + cmd.DispatchCompute(HRadianceCache, (int)HRadianceCacheKernel.CacheDataUpdate, HConstants.HASH_STORAGE_SIZE / 64, 1, 1); + } + } + + } + + + // ---------------------------------------- SPATIAL PREPASS ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_SpatialPrepassProfilingSampler)) + { + // Gather probe ambient occlusion from ray hit distance and temporally accumulate + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusion, HShaderParams._RayDistanceSS, HitDistanceScreenSpace.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusion, HShaderParams._RayDistanceWS, HitDistanceWorldSpace.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusion, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusion, HShaderParams._ReprojectionWeights, PersistentReprojectionWeights.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusion, HShaderParams._PersistentReprojectionCoord, PersistentReprojectionCoord.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusion, HShaderParams._ProbeAmbientOcclusion_History, ProbeAmbientOcclusion_History.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusion, HShaderParams._ProbeAmbientOcclusion_Output, ProbeAmbientOcclusion.rt); + cmd.DispatchCompute(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusion, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + + // Prepare offsets and weights for further spatial passes + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialPrepass, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialPrepass, HShaderParams._ProbeAmbientOcclusion, ProbeAmbientOcclusion.rt); + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialPrepass, HShaderParams._ProbeNormalDepth_History, ProbeNormalDepth_History.rt); + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialPrepass, HShaderParams._SpatialOffsets_Output, SpatialOffsetsPacked.rt); + cmd.SetComputeTextureParam(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialPrepass, HShaderParams._SpatialWeights_Output, SpatialWeightsPacked.rt); + cmd.SetComputeBufferParam(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialPrepass, HShaderParams._PointDistribution, PointDistributionBuffer); + cmd.SetComputeBufferParam(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialPrepass, HShaderParams._SpatialOffsetsBuffer, SpatialOffsetsBuffer); + cmd.DispatchCompute(HSpatialPrepass, (int)HSpatialPrepassKernel.SpatialPrepass, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + + // Spatially filter probe ambient occlusion + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusionSpatialFilter, HShaderParams._SpatialWeightsPacked, SpatialWeightsPacked.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusionSpatialFilter, HShaderParams._SpatialOffsetsPacked, SpatialOffsetsPacked.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusionSpatialFilter, HShaderParams._ProbeAmbientOcclusion, ProbeAmbientOcclusion.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusionSpatialFilter, HShaderParams._ProbeAmbientOcclusion_OutputFiltered, ProbeAmbientOcclusion_Filtered.rt); + cmd.DispatchCompute(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusionSpatialFilter, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- ReSTIR TEMPORAL REUSE ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_ReSTIRTemporalReuseProfilingSampler)) + { + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._ShadowGuidanceMask, ShadowGuidanceMask_Filtered.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._RayDirection, RayDirections.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._RayDistance, HitDistanceWorldSpace.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._RadianceAtlas, HitRadiance.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._ProbeDiffuse, ProbeDiffuse.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._ReprojectionWeights, PersistentReprojectionWeights.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._PersistentReprojectionCoord, PersistentReprojectionCoord.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._ReservoirAtlas_Output, ReservoirAtlas.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._ReservoirAtlas_History, ReservoirAtlas_History.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._ReservoirAtlasRayData_Output, ReservoirAtlasRayData_A.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, HShaderParams._ReservoirAtlasRadianceData_Output, ReservoirAtlasRadianceData_A.rt); + cmd.SetComputeIntParam(HReSTIR, HShaderParams._UseDiffuseWeight, HSettings.GeneralSettings.DebugModeWS == DebugModeWS.None ? 1 : 0); + cmd.DispatchCompute(HReSTIR, (int)HReSTIRKernel.ProbeAtlasTemporalReuse, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- RESERVOIR OCCLUSION VALIDATION ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_ReservoirOcclusionValidationProfilingSampler)) + { + // Run one pass of spatial reuse in disocclusion areas to generate shadow guidance mask + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, HShaderParams._ProbeDiffuse, ProbeDiffuse.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, HShaderParams._SpatialWeightsPacked, SpatialWeightsPacked.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, HShaderParams._SpatialOffsetsPacked, SpatialOffsetsPacked.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, HShaderParams._ReservoirAtlasRayData, ReservoirAtlasRayData_A.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, HShaderParams._ReservoirAtlasRadianceData, ReservoirAtlasRadianceData_A.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, HShaderParams._ReservoirAtlasRayData_Output, ReservoirAtlasRayData_C.rt); + cmd.SetComputeBufferParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, HShaderParams._TracingCoords, IndirectCoordsSF.ComputeBuffer); + cmd.SetComputeBufferParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, HShaderParams._RayCounter, RayCounter); + cmd.SetComputeIntParam(HReSTIR, HShaderParams._IndexXR, 0); + cmd.DispatchCompute(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, IndirectArgumentsSF, 0); + if (HRenderer.TextureXrSlices > 1) + { + cmd.SetComputeIntParam(HReSTIR, HShaderParams._IndexXR, 1); + cmd.DispatchCompute(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuseDisocclusion, IndirectArgumentsSF, sizeof(uint) * 3); + } + + // Reproject occlusion checkerboarded history + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionReprojection, HShaderParams._ReprojectionCoords, ReprojectionCoord.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionReprojection, HShaderParams._ProbeAmbientOcclusion, ProbeAmbientOcclusion_Filtered.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionReprojection, HShaderParams._ShadowGuidanceMask_History, ShadowGuidanceMask_CheckerboardHistory.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionReprojection, HShaderParams._ShadowGuidanceMask_Output, ShadowGuidanceMask.rt); + cmd.DispatchCompute(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionReprojection, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + + // Validate reservoir occlusion + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._ReprojectionCoords, ReprojectionCoord.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._ReservoirAtlasRayData, ReservoirAtlasRayData_B.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._ReservoirAtlasRayData_Disocclusion, ReservoirAtlasRayData_C.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._ReservoirAtlas, ReservoirAtlas.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._ReservoirAtlasRadianceData_Inout, ReservoirAtlasRadianceData_B.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._ShadowGuidanceMask_Output, ShadowGuidanceMask.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._ProbeAmbientOcclusion, ProbeAmbientOcclusion_Filtered.rt); + cmd.SetComputeBufferParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._PointDistribution, PointDistributionBuffer); + cmd.SetComputeBufferParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._RayCounter, RayCounter); + cmd.SetComputeBufferParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, HShaderParams._TracingCoords, IndirectCoordsOV.ComputeBuffer); + cmd.SetComputeIntParam(HReservoirValidation, HShaderParams._IndexXR, 0); + cmd.DispatchCompute(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, IndirectArgumentsOV, 0); + if (HRenderer.TextureXrSlices > 1) + { + cmd.SetComputeIntParam(HReservoirValidation, HShaderParams._IndexXR, 1); + cmd.DispatchCompute(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionValidation, IndirectArgumentsOV, sizeof(uint) * 3); + } + + // Temporal accumulation pass + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionTemporalFilter, HShaderParams._ReprojectionWeights, ReprojectionWeights.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionTemporalFilter, HShaderParams._ReprojectionCoords, ReprojectionCoord.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionTemporalFilter, HShaderParams._ShadowGuidanceMask, ShadowGuidanceMask.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionTemporalFilter, HShaderParams._SampleCount_History, ShadowGuidanceMask_SamplecountHistory.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionTemporalFilter, HShaderParams._SampleCount_Output, ShadowGuidanceMask_Samplecount.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionTemporalFilter, HShaderParams._ShadowGuidanceMask_History, ShadowGuidanceMask_History.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionTemporalFilter, HShaderParams._ShadowGuidanceMask_Output, ShadowGuidanceMask_Accumulated.rt); + cmd.DispatchCompute(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionTemporalFilter, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + + // Spatial filtering pass + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionSpatialFilter, HShaderParams._SpatialWeightsPacked, SpatialWeightsPacked.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionSpatialFilter, HShaderParams._SpatialOffsetsPacked, SpatialOffsetsPacked.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionSpatialFilter, HShaderParams._SampleCount, ShadowGuidanceMask_Samplecount.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionSpatialFilter, HShaderParams._ShadowGuidanceMask, ShadowGuidanceMask_Accumulated.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionSpatialFilter, HShaderParams._ShadowGuidanceMask_Output, ShadowGuidanceMask_Filtered.rt); + cmd.SetComputeTextureParam(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionSpatialFilter, HShaderParams._ReservoirAtlasRadianceData_Inout, ReservoirAtlasRadianceData_A.rt); + cmd.DispatchCompute(HReservoirValidation, (int)HReservoirValidationKernel.OcclusionSpatialFilter, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- ReSTIR SPATIAL REUSE ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_ReSTIRSpatialReuseProfilingSampler)) + { + // Prepare spatial kernel + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ProbeDiffuse, ProbeDiffuse.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._SpatialWeightsPacked, SpatialWeightsPacked.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._SpatialOffsetsPacked, SpatialOffsetsPacked.rt); + + // 1st spatial disk pass + cmd.SetComputeIntParam(HReSTIR, HShaderParams._PassNumber, 1); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRayData, ReservoirAtlasRayData_A.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRadianceData, ReservoirAtlasRadianceData_A.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRayData_Output, ReservoirAtlasRayData_B.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRadianceData_Output, ReservoirAtlasRadianceData_B.rt); + cmd.DispatchCompute(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + + // 2nd spatial disk pass + cmd.SetComputeIntParam(HReSTIR, HShaderParams._PassNumber, 2); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRayData, ReservoirAtlasRayData_B.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRadianceData, ReservoirAtlasRadianceData_B.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRayData_Output, ReservoirAtlasRayData_A.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRadianceData_Output, ReservoirAtlasRadianceData_A.rt); + cmd.DispatchCompute(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + + // 3rd spatial disk pass + cmd.SetComputeIntParam(HReSTIR, HShaderParams._PassNumber, 3); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRayData, ReservoirAtlasRayData_A.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRadianceData, ReservoirAtlasRadianceData_A.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRayData_Output, ReservoirAtlasRayData_B.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRadianceData_Output, ReservoirAtlasRadianceData_B.rt); + cmd.DispatchCompute(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + + // 3rd spatial disk pass + cmd.SetComputeIntParam(HReSTIR, HShaderParams._PassNumber, 2); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRayData, ReservoirAtlasRayData_B.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRadianceData, ReservoirAtlasRadianceData_B.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRayData_Output, ReservoirAtlasRayData_A.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, HShaderParams._ReservoirAtlasRadianceData_Output, ReservoirAtlasRadianceData_A.rt); + cmd.DispatchCompute(HReSTIR, (int)HReSTIRKernel.ProbeAtlasSpatialReuse, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- PERSISTENT HISTORY UPDATE ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_PersistentHistoryUpdateProfilingSampler)) + { + // Scroll history indirection array slice by slice + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.HistoryIndirectionScroll, HShaderParams._ReprojectionCoord, ReprojectionCoord.rt); + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.HistoryIndirectionScroll, HShaderParams._HistoryIndirection, HistoryIndirection.rt); + + // Scrolling cycle + for (int i = HConstants.PERSISTENT_HISTORY_SAMPLES - 1; i > 0; i--) + { + cmd.SetComputeIntParam(HTemporalReprojection, HShaderParams._HistoryArrayIndex, i); + cmd.DispatchCompute(HTemporalReprojection, (int)HTemporalReprojectionKernel.HistoryIndirectionScroll, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + } + + // Update history indirection coord buffer + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.HistoryIndirectionUpdate, HShaderParams._HistoryIndirection, HistoryIndirection.rt); + cmd.DispatchCompute(HTemporalReprojection, (int)HTemporalReprojectionKernel.HistoryIndirectionUpdate, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + + // Update probe world position & normal history buffer + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.HistoryProbeBuffersUpdate, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HTemporalReprojection, (int)HTemporalReprojectionKernel.HistoryProbeBuffersUpdate, HShaderParams._ProbeWorldPosNormal_HistoryOutput, ProbeWorldPosNormal_History.rt); + cmd.DispatchCompute(HTemporalReprojection, (int)HTemporalReprojectionKernel.HistoryProbeBuffersUpdate, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + + // Update probe ambient occlusion history buffer + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusionHistoryUpdate, HShaderParams._ProbeAmbientOcclusion, ProbeAmbientOcclusion.rt); + cmd.SetComputeTextureParam(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusionHistoryUpdate, HShaderParams._ProbeAmbientOcclusion_ArrayOutput, ProbeAmbientOcclusion_History.rt); + cmd.DispatchCompute(HProbeAmbientOcclusion, (int)HProbeAmbientOcclusionKernel.ProbeAmbientOcclusionHistoryUpdate, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + + // Update reserovir history buffer + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ReservoirHistoryUpdate, HShaderParams._ReservoirAtlas, ReservoirAtlas.rt); + cmd.SetComputeTextureParam(HReSTIR, (int)HReSTIRKernel.ReservoirHistoryUpdate, HShaderParams._ReservoirAtlas_ArrayOutput, ReservoirAtlas_History.rt); + cmd.DispatchCompute(HReSTIR, (int)HReSTIRKernel.ReservoirHistoryUpdate, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- INTERPOLATION ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_InterpolationProfilingSampler)) + { + // Spherical harmonics gather + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.GatherSH, HShaderParams._ShadowGuidanceMask, ShadowGuidanceMask_Accumulated.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.GatherSH, HShaderParams._ReservoirAtlasRadianceData, ReservoirAtlasRadianceData_A.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.GatherSH, HShaderParams._ReservoirAtlasRayData, ReservoirAtlasRayData_A.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.GatherSH, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.GatherSH, HShaderParams._Temp, ShadowGuidanceMask_Accumulated.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.GatherSH, HShaderParams._PackedSH_A_Output, PackedSH_A.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.GatherSH, HShaderParams._PackedSH_B_Output, PackedSH_B.rt); + cmd.DispatchCompute(HInterpolation, (int)HInterpolationKernel.GatherSH, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + + // Interpolation to the final resolution + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.Interpolation, HShaderParams._ProbeSSAO, ProbeSSAO.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.Interpolation, HShaderParams._PackedSH_A, PackedSH_A.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.Interpolation, HShaderParams._PackedSH_B, PackedSH_B.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.Interpolation, HShaderParams._BentNormalsAO, BentNormalsAO_Interpolated.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.Interpolation, HShaderParams._Radiance_Output, Radiance_Interpolated.rt); + cmd.SetComputeTextureParam(HInterpolation, (int)HInterpolationKernel.Interpolation, HShaderParams._ProbeNormalDepth, ProbeNormalDepth.rt); + cmd.SetComputeFloatParam(HInterpolation, HShaderParams._AO_Intensity, HSettings.ScreenSpaceLightingSettings.OcclusionIntensity); + cmd.DispatchCompute(HInterpolation, (int)HInterpolationKernel.Interpolation, fullResX_8, fullResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- TEMPORAL DENOISER ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_TemporalDenoisingProfilingSampler)) + { + cmd.SetComputeTextureParam(HTemporalDenoiser, (int)HTemporalDenoiserKernel.TemporalDenoising, HShaderParams._NormalDepth_History, NormalDepth_History.rt); + cmd.SetComputeTextureParam(HTemporalDenoiser, (int)HTemporalDenoiserKernel.TemporalDenoising, HShaderParams._Radiance, Radiance_Interpolated.rt); + cmd.SetComputeTextureParam(HTemporalDenoiser, (int)HTemporalDenoiserKernel.TemporalDenoising, HShaderParams._Radiance_History, RadianceAccumulated_History.rt); + cmd.SetComputeTextureParam(HTemporalDenoiser, (int)HTemporalDenoiserKernel.TemporalDenoising, HShaderParams._Radiance_Output, RadianceAccumulated.rt); + cmd.SetComputeTextureParam(HTemporalDenoiser, (int)HTemporalDenoiserKernel.TemporalDenoising, HShaderParams._LuminanceDelta_Output, LuminanceDelta.rt); + cmd.SetComputeTextureParam(HTemporalDenoiser, (int)HTemporalDenoiserKernel.TemporalDenoising, HShaderParams._LuminanceDelta_History, LuminanceDelta_History.rt); + cmd.DispatchCompute(HTemporalDenoiser, (int)HTemporalDenoiserKernel.TemporalDenoising, fullResX_8, fullResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- SPATIAL CLEANUP ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_SpatialCleanupProfilingSampler)) + { + cmd.SetComputeTextureParam(HTemporalDenoiser, (int)HTemporalDenoiserKernel.SpatialCleanup, HShaderParams._Radiance, RadianceAccumulated.rt); + cmd.SetComputeTextureParam(HTemporalDenoiser, (int)HTemporalDenoiserKernel.SpatialCleanup, HShaderParams._Radiance_HistoryOutput, RadianceAccumulated_History.rt); + cmd.SetComputeTextureParam(HTemporalDenoiser, (int)HTemporalDenoiserKernel.SpatialCleanup, HShaderParams._NormalDepth_HistoryOutput, NormalDepth_History.rt); + cmd.DispatchCompute(HTemporalDenoiser, (int)HTemporalDenoiserKernel.SpatialCleanup, fullResX_8, fullResY_8, HRenderer.TextureXrSlices); + } + + + // ---------------------------------------- COPY BUFFERS ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_CopyBuffersProfilingSampler)) + { + cmd.SetComputeTextureParam(HCopy, (int)HCopyKernel.CopyProbeBuffers, HShaderParams._ShadowGuidanceMask_Samplecount, ShadowGuidanceMask_Samplecount.rt); + cmd.SetComputeTextureParam(HCopy, (int)HCopyKernel.CopyProbeBuffers, HShaderParams._ShadowGuidanceMask_SamplecountHistoryOutput, ShadowGuidanceMask_SamplecountHistory.rt); + cmd.DispatchCompute(HCopy, (int)HCopyKernel.CopyProbeBuffers, probeResX_8, probeResY_8, HRenderer.TextureXrSlices); + + cmd.SetComputeTextureParam(HCopy, (int)HCopyKernel.CopyProbeAtlases, HShaderParams._ShadowGuidanceMask, ShadowGuidanceMask.rt); + cmd.SetComputeTextureParam(HCopy, (int)HCopyKernel.CopyProbeAtlases, HShaderParams._ShadowGuidanceMask_CheckerboardHistoryOutput, ShadowGuidanceMask_CheckerboardHistory.rt); + cmd.SetComputeTextureParam(HCopy, (int)HCopyKernel.CopyProbeAtlases, HShaderParams._ShadowGuidanceMask_Accumulated, ShadowGuidanceMask_Accumulated.rt); + cmd.SetComputeTextureParam(HCopy, (int)HCopyKernel.CopyProbeAtlases, HShaderParams._ShadowGuidanceMask_HistoryOutput, ShadowGuidanceMask_History.rt); + cmd.DispatchCompute(HCopy, (int)HCopyKernel.CopyProbeAtlases, probeAtlasResX_8, probeAtlasResY_8, HRenderer.TextureXrSlices); + + cmd.SetComputeTextureParam(HCopy, (int)HCopyKernel.CopyFullResBuffers, HShaderParams.g_GeometryNormal, GeometryNormal.rt); + cmd.SetComputeTextureParam(HCopy, (int)HCopyKernel.CopyFullResBuffers, HShaderParams._NormalDepth_HistoryOutput, NormalDepth_History.rt); + cmd.DispatchCompute(HCopy, (int)HCopyKernel.CopyFullResBuffers, fullResX_8, fullResY_8, HRenderer.TextureXrSlices); + } + + // Final output + cmd.SetGlobalTexture(HShaderParams.g_HTraceBufferGI, RadianceAccumulated.rt); + + + // ---------------------------------------- DEBUG (DON'T SHIP!) ---------------------------------------- // + using (new HTraceProfilingScope(cmd, s_DebugPassthroughProfilingSampler)) + { + if (HSettings.GeneralSettings.DebugModeWS != DebugModeWS.None) + { + cmd.SetComputeTextureParam(HDebugPassthrough, (int)HDebugPassthroughKernel.DebugPassthrough, HShaderParams._InputA, RadianceAccumulated.rt); + //cmd.SetComputeTextureParam(HDebugPassthrough, hDebugPassthrough_Kernel, HShaderParams._InputB, VoxelVisualizationRayDirections.rt); + cmd.SetComputeTextureParam(HDebugPassthrough, (int)HDebugPassthroughKernel.DebugPassthrough, HShaderParams._Output, DebugOutput.rt); + cmd.DispatchCompute(HDebugPassthrough, (int)HDebugPassthroughKernel.DebugPassthrough, fullResX_8, fullResY_8, HRenderer.TextureXrSlices); + } + } + + // Visualize voxels if requested + if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedLighting || HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedColor) + { + { + if (HSettings.GeneralSettings.Multibounce == Multibounce.None) { HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_CACHE); HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_APV); HTracingWorldSpace.EnableKeyword(MULTIBOUNCE_OFF); } + if (HSettings.GeneralSettings.Multibounce == Multibounce.IrradianceCache) { HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_OFF); HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_APV); HTracingWorldSpace.EnableKeyword(MULTIBOUNCE_CACHE); } + if (HSettings.GeneralSettings.Multibounce == Multibounce.AdaptiveProbeVolumes) { HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_CACHE); HTracingWorldSpace.DisableKeyword(MULTIBOUNCE_OFF); HTracingWorldSpace.EnableKeyword(MULTIBOUNCE_APV); } + + //this part in Voxelization.cs + } + } + + if (Time.frameCount % 2 == 0) + _hFrameIndex++; + + _hashUpdateFrameIndex++; + + cmd.SetGlobalTexture(HShaderParams.g_GeometryNormal, GeometryNormal.rt); + + if (HSettings.GeneralSettings.DebugModeWS != DebugModeWS.None) + cmd.SetGlobalTexture(HShaderParams.g_HTraceBufferGI, DebugOutput.rt); + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/SoftwareTracingShared.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/SoftwareTracingShared.cs.meta new file mode 100644 index 000000000..a10514e32 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/SoftwareTracingShared.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6b20fded371c9ff4581b8fe54fde562d +timeCreated: 1743679279 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/Shared/SoftwareTracingShared.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationFunctionsShared.cs b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationFunctionsShared.cs new file mode 100644 index 000000000..09ab9d6a0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationFunctionsShared.cs @@ -0,0 +1,147 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using UnityEngine; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Passes.Shared +{ + public class VoxelizationFunctionsShared + { + //globals + internal static readonly int g_OffsetAxisIndex = Shader.PropertyToID("_OffsetAxisIndex"); + internal static readonly int g_AxisOffset = Shader.PropertyToID("_AxisOffset"); + internal static readonly int g_CullingTrim = Shader.PropertyToID("_CullingTrim"); + internal static readonly int g_OctantOffset = Shader.PropertyToID("_OctantOffset"); + internal static readonly int g_CullingTrimAxis = Shader.PropertyToID("_CullingTrimAxis"); + + // Calculates offset data for voxelization + internal static void CalculateOctantOffsets(CommandBuffer cmd) + { + Vector2 cullingTrim = Vector2.zero; + Vector2 cullingTrimAxis = Vector2.zero; + Vector3 octantOffset = Vector3.zero; + Vector3 axisOffset = Vector3.zero; + + Vector3 voxelResolutionSwizzled = new Vector3(HSettings.VoxelizationSettings.ExactData.Resolution.x, HSettings.VoxelizationSettings.ExactData.Resolution.z, HSettings.VoxelizationSettings.ExactData.Resolution.y); + Vector3 axisOffsetSign = VoxelizationRuntimeData.VoxelOctantCamera.transform.position - VoxelizationRuntimeData.VoxelCamera.transform.position; + int offsetAxisIndex = (int)VoxelizationRuntimeData.OffsetAxisIndex > 2 ? (int)VoxelizationRuntimeData.OffsetAxisIndex - 3 : (int)VoxelizationRuntimeData.OffsetAxisIndex; + int octantIndex = (int)VoxelizationRuntimeData.OctantIndex; + + if (offsetAxisIndex == 0) // X axis + { + axisOffset = axisOffsetSign.x > 0 ? new Vector3(voxelResolutionSwizzled.x / 2, 0, 0) : new Vector3(0, 0, 0); + + int cullingFarPlane = axisOffsetSign.x > 0 + ? Mathf.RoundToInt(VoxelizationRuntimeData.CullingCamera.Camera.farClipPlane * HSettings.VoxelizationSettings.ExactData.VoxelsPerMeter) + : Mathf.FloorToInt(VoxelizationRuntimeData.CullingCamera.Camera.farClipPlane * HSettings.VoxelizationSettings.ExactData.VoxelsPerMeter); + + cullingTrim = axisOffsetSign.x > 0 ? new Vector2((int)voxelResolutionSwizzled.x - cullingFarPlane, (int)voxelResolutionSwizzled.x) : new Vector2(0, cullingFarPlane); + cullingTrimAxis = axisOffsetSign.x > 0 ? new Vector2(1, 0) : new Vector2(0, 1); + + if (octantIndex == 1) octantOffset = new Vector3(0, voxelResolutionSwizzled.y / 2, 0); + if (octantIndex == 2) octantOffset = new Vector3(0, voxelResolutionSwizzled.y / 2, voxelResolutionSwizzled.z / 2); + if (octantIndex == 3) octantOffset = new Vector3(0, 0, 0); + if (octantIndex == 4) octantOffset = new Vector3(0, 0, voxelResolutionSwizzled.z / 2); + } + + if (offsetAxisIndex == 1) // Y axis + { + axisOffset = axisOffsetSign.y > 0 ? new Vector3(0, voxelResolutionSwizzled.y / 2, 0) : new Vector3(0, 0, 0); + + int cullingFarPlane = axisOffsetSign.y > 0 + ? Mathf.RoundToInt(VoxelizationRuntimeData.CullingCamera.Camera.farClipPlane * HSettings.VoxelizationSettings.ExactData.VoxelsPerMeter) + : Mathf.FloorToInt(VoxelizationRuntimeData.CullingCamera.Camera.farClipPlane * HSettings.VoxelizationSettings.ExactData.VoxelsPerMeter); + + cullingTrim = axisOffsetSign.y > 0 ? new Vector2((int)voxelResolutionSwizzled.y - cullingFarPlane, (int)voxelResolutionSwizzled.y) : new Vector2(0, cullingFarPlane); + cullingTrimAxis = axisOffsetSign.y > 0 ? new Vector2(1, 0) : new Vector2(0, 1); + + if (octantIndex == 1) octantOffset = new Vector3(0, 0, 0); + if (octantIndex == 2) octantOffset = new Vector3(0, 0, voxelResolutionSwizzled.z / 2); + if (octantIndex == 3) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, 0); + if (octantIndex == 4) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, voxelResolutionSwizzled.z / 2); + } + + if (offsetAxisIndex == 2) // Z axis + { + axisOffset = axisOffsetSign.z > 0 ? new Vector3(0, 0, voxelResolutionSwizzled.z / 2) : new Vector3(0, 0, 0); + + int cullingFarPlane = axisOffsetSign.z > 0 + ? Mathf.RoundToInt(VoxelizationRuntimeData.CullingCamera.Camera.farClipPlane * HSettings.VoxelizationSettings.ExactData.VoxelsPerMeter) + : Mathf.FloorToInt(VoxelizationRuntimeData.CullingCamera.Camera.farClipPlane * HSettings.VoxelizationSettings.ExactData.VoxelsPerMeter); + + cullingTrim = axisOffsetSign.z > 0 ? new Vector2((int)voxelResolutionSwizzled.z - cullingFarPlane, (int)voxelResolutionSwizzled.z) : new Vector2(0, cullingFarPlane); + cullingTrimAxis = axisOffsetSign.z > 0 ? new Vector2(1, 0) : new Vector2(0, 1); + + if (octantIndex == 1) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, voxelResolutionSwizzled.y / 2, 0); + if (octantIndex == 2) octantOffset = new Vector3(0, voxelResolutionSwizzled.y / 2, 0); + if (octantIndex == 3) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, 0); + if (octantIndex == 4) octantOffset = new Vector3(0, 0, 0); + } + + cmd.SetGlobalInt(g_OffsetAxisIndex, offsetAxisIndex); + cmd.SetGlobalVector(g_AxisOffset, axisOffset); + cmd.SetGlobalVector(g_CullingTrim, cullingTrim); + cmd.SetGlobalVector(g_OctantOffset, octantOffset); + cmd.SetGlobalVector(g_CullingTrimAxis, cullingTrimAxis); + } + + // Calculates offset data for copying compute shader + internal static Vector3 CalculateOctantOffsetsForCopyShader() + { + Vector3 octantOffset = Vector3.zero; + + Vector3 voxelResolutionSwizzled = new Vector3(HSettings.VoxelizationSettings.ExactData.Resolution.x, HSettings.VoxelizationSettings.ExactData.Resolution.z, HSettings.VoxelizationSettings.ExactData.Resolution.y); + Vector3 axisOffsetSign = VoxelizationRuntimeData.VoxelOctantCamera.transform.position - VoxelizationRuntimeData.VoxelCamera.transform.position; + int offsetAxisIndex = (int)VoxelizationRuntimeData.OffsetAxisIndex > 2 ? (int)VoxelizationRuntimeData.OffsetAxisIndex - 3 : (int)VoxelizationRuntimeData.OffsetAxisIndex; + int octantIndex = (int)VoxelizationRuntimeData.OctantIndex; + + if (offsetAxisIndex == 0) // X axis + { + if (axisOffsetSign.x < 0) + { + if (octantIndex == 1) octantOffset = new Vector3(0, 0, 0); + if (octantIndex == 2) octantOffset = new Vector3(0, 0, voxelResolutionSwizzled.z / 2); + if (octantIndex == 3) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, voxelResolutionSwizzled.z / 2); + if (octantIndex == 4) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, 0); + } + else + { + if (octantIndex == 1) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, 0); + if (octantIndex == 2) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, voxelResolutionSwizzled.z / 2); + if (octantIndex == 3) octantOffset = new Vector3(0, 0, 0); + if (octantIndex == 4) octantOffset = new Vector3(0, 0, voxelResolutionSwizzled.z / 2); + } + } + + if (offsetAxisIndex == 1) // Y axis + { + if (octantIndex == 1) octantOffset = new Vector3(0, 0, 0); + if (octantIndex == 2) octantOffset = new Vector3(0, 0, voxelResolutionSwizzled.z / 2); + if (octantIndex == 3) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, 0); + if (octantIndex == 4) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, voxelResolutionSwizzled.z / 2); + } + + if (offsetAxisIndex == 2) // Z axis + { + if (axisOffsetSign.z < 0) + { + if (octantIndex == 1) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, 0); + if (octantIndex == 2) octantOffset = new Vector3(0, 0, 0); + if (octantIndex == 3) octantOffset = new Vector3(0, 0, voxelResolutionSwizzled.z / 2); + if (octantIndex == 4) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, voxelResolutionSwizzled.z / 2); + } + else + { + if (octantIndex == 1) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, voxelResolutionSwizzled.z / 2); + if (octantIndex == 2) octantOffset = new Vector3(0, 0, voxelResolutionSwizzled.z / 2); + if (octantIndex == 3) octantOffset = new Vector3(0, 0, 0); + if (octantIndex == 4) octantOffset = new Vector3(voxelResolutionSwizzled.x / 2, 0, 0); + } + } + + return octantOffset; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationFunctionsShared.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationFunctionsShared.cs.meta new file mode 100644 index 000000000..0e443b8b3 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationFunctionsShared.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f64fc5438121dd745abdfea0f57c14c2 +timeCreated: 1750262428 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/Shared/VoxelizationFunctionsShared.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationShared.cs b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationShared.cs new file mode 100644 index 000000000..15bacafdd --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationShared.cs @@ -0,0 +1,120 @@ +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Wrappers; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Passes.Shared +{ + // HDRP and BIRP + internal static class VoxelizationShared + { + internal enum HVoxelizationKernel + { + GeneratePositionPyramid1 = 0, + GeneratePositionPyramid2 = 1, + ClearPositionPyramid = 2, + CopyData = 3, + } + + internal enum VoxelVisualizationKernel + { + VisualizeVoxels = 0, + } + + #region Shaders Properties ID + + //globals + internal static readonly int g_VoxelCameraPos = Shader.PropertyToID("_VoxelCameraPos"); + internal static readonly int g_VoxelCameraPosActual = Shader.PropertyToID("_VoxelCameraPosActual"); + internal static readonly int g_VoxelResolution = Shader.PropertyToID("_VoxelResolution"); + internal static readonly int g_VoxelBounds = Shader.PropertyToID("_VoxelBounds"); + internal static readonly int g_VoxelPerMeter = Shader.PropertyToID("_VoxelPerMeter"); + internal static readonly int g_VoxelSize = Shader.PropertyToID("_VoxelSize"); + internal static readonly int g_VoxelizationAABB_Min = Shader.PropertyToID("_VoxelizationAABB_Min"); + internal static readonly int g_VoxelizationAABB_Max = Shader.PropertyToID("_VoxelizationAABB_Max"); + internal static readonly int g_VoxelData = Shader.PropertyToID("_VoxelData"); + internal static readonly int g_VoxelPositionPyramid = Shader.PropertyToID("_VoxelPositionPyramid"); + + //locals + internal static readonly int _VoxelPositionPyramid_Mip0 = Shader.PropertyToID("_VoxelPositionPyramid_MIP0"); + internal static readonly int _VoxelPositionPyramid_Mip1 = Shader.PropertyToID("_VoxelPositionPyramid_MIP1"); + internal static readonly int _VoxelPositionPyramid_Mip2 = Shader.PropertyToID("_VoxelPositionPyramid_MIP2"); + internal static readonly int _VoxelPositionIntermediate_Output = Shader.PropertyToID("_VoxelPositionIntermediate_Output"); + internal static readonly int _VoxelPositionIntermediate = Shader.PropertyToID("_VoxelPositionIntermediate"); + internal static readonly int _VoxelPositionPyramid_Mip3 = Shader.PropertyToID("_VoxelPositionPyramid_MIP3"); + internal static readonly int _VoxelPositionPyramid_Mip4 = Shader.PropertyToID("_VoxelPositionPyramid_MIP4"); + internal static readonly int _VoxelPositionPyramid_Mip5 = Shader.PropertyToID("_VoxelPositionPyramid_MIP5"); + + //spatial specific below + + + //locals + internal static readonly int _OctantCopyOffset = Shader.PropertyToID("_OctantCopyOffset"); + internal static readonly int _VoxelOffset = Shader.PropertyToID("_VoxelOffset"); + internal static readonly int _VoxelData_A = Shader.PropertyToID("_VoxelData_A"); + internal static readonly int _VoxelData_B = Shader.PropertyToID("_VoxelData_B"); + + #endregion Shaders Properties ID + + internal static ProfilingSamplerHTrace s_VoxelizationConstantProfilingSampler = new ProfilingSamplerHTrace("Voxelization Constant"); + internal static ProfilingSamplerHTrace s_VoxelizationPartialProfilingSampler = new ProfilingSamplerHTrace("Voxelization Partial"); + internal static ProfilingSamplerHTrace s_RenderVoxelsProfilingSampler = new ProfilingSamplerHTrace("Render Voxels"); + + internal static ProfilingSamplerHTrace s_ClearVoxelTexturesProfilingSampler = new ProfilingSamplerHTrace("Clear Voxel Textures"); + internal static ProfilingSamplerHTrace s_GeneratePositionPyramidProfilingSampler = new ProfilingSamplerHTrace("Generate Position Pyramid"); + internal static ProfilingSamplerHTrace s_VisualizeVoxelsProfilingSampler = new ProfilingSamplerHTrace("Visualize Voxels", parentName: HNames.HTRACE_VOXELIZATION_PASS_NAME, priority: 0); + //Spatial specific below + internal static ProfilingSamplerHTrace s_CopyVoxelsProfilingSampler = new ProfilingSamplerHTrace("Copy Voxels"); + + // Shaders & Materials + internal static Shader VoxelizationShader; + internal static ComputeShader HVoxelization; + internal static ComputeShader VoxelVisualization; + internal static Material VoxelVisualizationMaterialHDRP; + internal static Material RayDirectionsVisualizationBIRP; + + // Buffers & Textures + internal static ComputeBuffer DummyVoxelBuffer; + + internal static RTWrapper DummyVoxelizationTarget = new RTWrapper(); + internal static RTWrapper VoxelPositionPyramid = new RTWrapper(); + internal static RTWrapper VoxelPositionIntermediate = new RTWrapper(); + internal static RTWrapper VoxelData = new RTWrapper(); + //Spatial specific below + internal static RTWrapper DummyVoxelizationStaticTarget = new RTWrapper(); + internal static RTWrapper DummyVoxelizationDynamicTarget = new RTWrapper(); + internal static RTWrapper VoxelData_A = new RTWrapper(); + internal static RTWrapper VoxelData_B = new RTWrapper(); + + // DEBUG RT + internal static RTWrapper VoxelVisualizationRayDirections = new RTWrapper(); + internal static RTWrapper DebugOutput = new RTWrapper(); + + internal static string VISUALIZE_OFF = "VISUALIZE_OFF"; + internal static string VISUALIZE_LIGHTING = "VISUALIZE_LIGHTING"; + internal static string VISUALIZE_COLOR = "VISUALIZE_COLOR"; + internal static string EVALUATE_PUNCTUAL_LIGHTS = "EVALUATE_PUNCTUAL_LIGHTS"; + internal static string ADDITIONAL_LIGHT_SHADOWS = "_ADDITIONAL_LIGHT_SHADOWS"; + internal static string DYNAMIC_VOXELIZATION = "DYNAMIC_VOXELIZATION"; + internal static string PARTIAL_VOXELIZATION = "PARTIAL_VOXELIZATION"; + internal static string CONSTANT_VOXELIZATION = "CONSTANT_VOXELIZATION"; + + internal struct HistoryData : IHistoryData + { + public DebugModeWS DebugMode; + public TracingMode TracingMode; + public VoxelizationUpdateMode VoxelizationUpdateMode; + public Vector3 VoxelCameraPosition; //update it directly + + public void Update() + { + DebugMode = HSettings.GeneralSettings.DebugModeWS; + TracingMode = HSettings.GeneralSettings.TracingMode; + VoxelizationUpdateMode = HSettings.VoxelizationSettings.VoxelizationUpdateMode; + } + } + + internal static HistoryData History = new HistoryData(); + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationShared.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationShared.cs.meta new file mode 100644 index 000000000..272028a1a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/Shared/VoxelizationShared.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 410540eedbaf43a0bd5ff6fd830d335b +timeCreated: 1758703389 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/Shared/VoxelizationShared.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP.meta b/Assets/External/HTraceWSGI/Scripts/Passes/URP.meta new file mode 100644 index 000000000..2331984c9 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 86c637a99232f484ea921b2ab20d5645 +timeCreated: 1747396218 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/DirectionalShadowmapPassURP.cs b/Assets/External/HTraceWSGI/Scripts/Passes/URP/DirectionalShadowmapPassURP.cs new file mode 100644 index 000000000..6e4b3d897 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/DirectionalShadowmapPassURP.cs @@ -0,0 +1,430 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Extensions.CameraHistorySystem; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Services.DirectionalShadowmap; +using HTraceWSGI.Scripts.Wrappers; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +#if UNITY_2023_3_OR_NEWER +using HTraceWSGI.Scripts.Services.VoxelCameras; +using UnityEngine.Rendering.RendererUtils; +using UnityEngine.Rendering.RenderGraphModule; +#endif + +namespace HTraceWSGI.Scripts.Passes.URP +{ + internal class DirectionalShadowmapPassURP : ScriptableRenderPass + { +private enum HShadowmapKernel + { + ShadowmapMerge = 0, + } + + // Shader properties + internal static readonly int g_DirLightMatrix = Shader.PropertyToID("g_DirLightMatrix"); + internal static readonly int g_DirLightPlanes = Shader.PropertyToID("g_DirLightPlanes"); + internal static readonly int g_HTraceShadowmap = Shader.PropertyToID("g_HTraceShadowmap"); + + internal static readonly int _DirectionalShadowmapStatic = Shader.PropertyToID("_DirectionalShadowmapStatic"); + internal static readonly int _Shadowmap = Shader.PropertyToID("_Shadowmap"); + internal static readonly int _Shadowmap_Output = Shader.PropertyToID("_Shadowmap_Output"); + internal static readonly int _OctantShadowOffset = Shader.PropertyToID("_OctantShadowOffset"); + + // Samplers + internal static readonly ProfilingSamplerHTrace s_RenderShadowmapProfilingSampler = new ProfilingSamplerHTrace("Render Shadowmap", parentName: HNames.HTRACE_SHADOWMAP_PASS_NAME, priority: 0); + internal static readonly ProfilingSamplerHTrace s_RenderShadowmapDrawRendererListProfilingSampler = new ProfilingSamplerHTrace("Render Shadowmap DrawRendererList"); + internal static readonly ProfilingSamplerHTrace s_MergeShadowmapStaticProfilingSampler = new ProfilingSamplerHTrace("Merge Shadowmap Static"); + + // Buffers & etc + + // Materials and Shaders + internal static Material ShadowmapMaterial; + //Partial + internal static ComputeShader HShadowmap; + + //Textures + internal static RTWrapper DirectionalDepthTarget = new RTWrapper(); + //Partial + internal static RTWrapper DirectionalDepthTargetCombined = new RTWrapper(); + internal static RTWrapper DirectionalDepthTargetStatic = new RTWrapper(); + internal static RTWrapper DirectionalShadowmapStatic = new RTWrapper(); + + internal struct HistoryData : IHistoryData + { + public VoxelizationUpdateMode VoxelizationUpdateMode; + + public void Update() + { + VoxelizationUpdateMode = HSettings.VoxelizationSettings.VoxelizationUpdateMode; + } + } + + internal static HistoryData History = new HistoryData(); + + #region --------------------------- Non Render Graph --------------------------- + +#if !UNITY_6000_4_OR_NEWER + private ScriptableRenderer _renderer; + + protected internal void Initialize(ScriptableRenderer renderer) + { + _renderer = renderer; + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) + { + //ResourcesRG(renderingData.cameraData.camera, renderingData.cameraData.renderScale, renderingData.cameraData.cameraTargetDescriptor); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) + { + ConfigureInput(ScriptableRenderPassInput.Depth); // | ScriptableRenderPassInput.Normal); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + var cmd = CommandBufferPool.Get(HNames.HTRACE_SHADOWMAP_PASS_NAME); + + Camera camera = renderingData.cameraData.camera; + int width = (int)(camera.scaledPixelWidth * renderingData.cameraData.renderScale); + int height = (int)(camera.scaledPixelHeight * renderingData.cameraData.renderScale); + + DirectionalShadowmapService.Instance.DirectionalCamera.ExecuteUpdate(); + + switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) + { + case VoxelizationUpdateMode.Constant: + using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) + //ExecuteConstant(cmd, camera, width, height, ref renderingData.cullResults); + break; + case VoxelizationUpdateMode.Partial: + using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) + //ExecutePartial(cmd, camera, width, height); + break; + } + + History.Update(); + + context.ExecuteCommandBuffer(cmd); + cmd.Clear(); + CommandBufferPool.Release(cmd); + } +#endif + + #endregion --------------------------- Non Render Graph --------------------------- + + #region --------------------------- Render Graph --------------------------- + +#if UNITY_2023_3_OR_NEWER + private class PassData + { + public RendererListHandle RendererListHandle; + public UniversalCameraData UniversalCameraData; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_SHADOWMAP_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_SHADOWMAP_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + UniversalRenderingData universalRenderingData = frameData.Get(); + UniversalLightData lightData = frameData.Get(); + CullContextData cullContextData = frameData.Get(); + + ConfigureInput(ScriptableRenderPassInput.Depth); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(true); + passData.UniversalCameraData = universalCameraData; + + ResourcesRG(renderGraph, universalCameraData); + + DirectionalShadowmapService.Instance.DirectionalCamera.ExecuteUpdate(); + AddRendererList(renderGraph, universalCameraData, universalRenderingData, lightData, passData, builder, cullContextData); + + builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); + } + } + + private static void ResourcesRG(RenderGraph renderGraph, UniversalCameraData universalCameraData) + { + if (ShadowmapMaterial == null) + { + ShadowmapMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/HTraceWSGI/ShadowmapURP")); + ShadowmapMaterial.enableInstancing = true; + } + if (HShadowmap == null) HShadowmap = HExtensions.LoadComputeShader("Shadowmap"); + + int width = (int)(universalCameraData.camera.scaledPixelWidth * universalCameraData.renderScale); + int height = (int)(universalCameraData.camera.scaledPixelHeight * universalCameraData.renderScale); + + RenderTextureDescriptor desc = universalCameraData.cameraTargetDescriptor; + RenderTextureDescriptor depthDesc = universalCameraData.cameraTargetDescriptor; + + switch (HSettings.GeneralSettings.TracingMode) + { + case Globals.TracingMode.SoftwareTracing: + switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) + { + case VoxelizationUpdateMode.Constant: + desc.width = (int)HConstants.ShadowmapResolution.x; + desc.height = (int)HConstants.ShadowmapResolution.y; + desc.depthBufferBits = 0; // Color and depth cannot be combined in RTHandles + desc.dimension = TextureDimension.Tex2D; + desc.stencilFormat = GraphicsFormat.None; + desc.depthStencilFormat = GraphicsFormat.None; + + DirectionalShadowmapStatic.ReAllocateIfNeeded("_DirectionalShadowmapStatic", ref desc, graphicsFormat: GraphicsFormat.R32_SFloat, enableRandomWrite: false); + + depthDesc.width = (int)HConstants.ShadowmapResolution.x; + depthDesc.height = (int)HConstants.ShadowmapResolution.y; + depthDesc.depthBufferBits = 32; + depthDesc.colorFormat = RenderTextureFormat.Depth; + + DirectionalDepthTarget.ReAllocateIfNeeded(name: "_DirectionalDepthTargetCombined", ref depthDesc, enableRandomWrite: false); + + renderGraph.ImportTexture(DirectionalShadowmapStatic.rt); + renderGraph.ImportTexture(DirectionalDepthTarget.rt); + + DirectionalDepthTargetStatic?.HRelease(); + DirectionalDepthTargetCombined?.HRelease(); + + break; + case VoxelizationUpdateMode.Partial: + desc.width = (int)HConstants.ShadowmapResolution.x; + desc.height = (int)HConstants.ShadowmapResolution.y; + desc.depthBufferBits = 0; // Color and depth cannot be combined in RTHandles + desc.dimension = TextureDimension.Tex2D; + desc.stencilFormat = GraphicsFormat.None; + desc.depthStencilFormat = GraphicsFormat.None; + + DirectionalShadowmapStatic.ReAllocateIfNeeded(name: "_DirectionalShadowmapStatic", ref desc, GraphicsFormat.R32_SFloat); + + depthDesc.width = (int)HConstants.ShadowmapResolution.x / 2; + depthDesc.height = (int)HConstants.ShadowmapResolution.y / 2; + depthDesc.dimension = TextureDimension.Tex2D; + depthDesc.depthBufferBits = 32; + depthDesc.colorFormat = RenderTextureFormat.Depth; + depthDesc.useDynamicScale = false; + + DirectionalDepthTargetStatic.ReAllocateIfNeeded("_DirectionalDepthTargetStatic", ref depthDesc, enableRandomWrite: false); + + depthDesc.width = (int)HConstants.ShadowmapResolution.x; + depthDesc.height = (int)HConstants.ShadowmapResolution.y; + + DirectionalDepthTargetCombined.ReAllocateIfNeeded("_DirectionalDepthTargetCombined", ref depthDesc, enableRandomWrite: false); + + renderGraph.ImportTexture(DirectionalShadowmapStatic.rt); + renderGraph.ImportTexture(DirectionalDepthTargetStatic.rt); + renderGraph.ImportTexture(DirectionalDepthTargetCombined.rt); + + DirectionalDepthTarget?.HRelease(); + break; + } + break; + } + } + + private static void AddRendererList(RenderGraph renderGraph, UniversalCameraData universalCameraData, UniversalRenderingData universalRenderingData, UniversalLightData lightData, PassData passData, + IUnsafeRenderGraphBuilder builder, CullContextData cullContextData) + { + LayerMask voxelizationLayer = HSettings.VoxelizationSettings.VoxelizationMask; + + if (HSettings.VoxelizationSettings.VoxelizationUpdateMode == VoxelizationUpdateMode.Partial) + { + voxelizationLayer = HSettings.VoxelizationSettings.VoxelizationMask & ~HSettings.VoxelizationSettings.DynamicObjectsMask; + if (VoxelizationRuntimeData.OctantIndex == OctantIndex.DynamicObjects) + voxelizationLayer = HSettings.VoxelizationSettings.VoxelizationMask & HSettings.VoxelizationSettings.DynamicObjectsMask; + } + + SortingCriteria sortFlags = universalCameraData.defaultOpaqueSortFlags; + RenderQueueRange renderQueueRange = RenderQueueRange.opaque; + FilteringSettings filterSettings = new FilteringSettings(renderQueueRange, voxelizationLayer); + + ShaderTagId tag = new ShaderTagId("ShadowCaster"); + // Create drawing settings + DrawingSettings drawSettings = RenderingUtils.CreateDrawingSettings(tag, universalRenderingData, universalCameraData, lightData, sortFlags); + //drawSettings.perObjectData = PerObjectData.MotionVectors; + //drawSettings.overrideMaterial = materialToUse; + + var voxelizationCamera = VoxelizationRuntimeData.VoxelCamera.Camera; + var directionalLightCamera = DirectionalShadowmapService.Instance.DirectionalCamera.GetDirectionalCamera; + + var maximumLODLevelBackup = QualitySettings.maximumLODLevel; + var lodBiasBackup = QualitySettings.lodBias; + QualitySettings.SetLODSettings(1, HSettings.VoxelizationSettings.LODMax, false); + + if (directionalLightCamera.TryGetCullingParameters(out ScriptableCullingParameters shadowCullingParams)) + { + shadowCullingParams.cullingOptions = CullingOptions.None; + shadowCullingParams.isOrthographic = true; + + //LayerMask shadowmapLayer = HSettings.VoxelizationSettings.VoxelizationMask; + LODParameters lodParameters = shadowCullingParams.lodParameters; + lodParameters.cameraPosition = voxelizationCamera.transform.position; + lodParameters.isOrthographic = true; + lodParameters.orthoSize = 0; + shadowCullingParams.lodParameters = lodParameters; + shadowCullingParams.cullingMask = (uint)voxelizationLayer.value; + + var directionalLightCullResults = cullContextData.Cull(ref shadowCullingParams); + var rendererListParameters = new RendererListParams(directionalLightCullResults, drawSettings, filterSettings); + passData.RendererListHandle = renderGraph.CreateRendererList(rendererListParameters); + builder.UseRendererList(passData.RendererListHandle); + } + + QualitySettings.SetLODSettings(lodBiasBackup, maximumLODLevelBackup, false); + } + + private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); + + Camera camera = data.UniversalCameraData.camera; + int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); + int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); + + switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) + { + case VoxelizationUpdateMode.Constant: + using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) + ExecuteConstant(cmd, camera, width, height, data); + break; + case VoxelizationUpdateMode.Partial: + using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) + ExecutePartial(cmd, camera, width, height, data); + VoxelizationRuntimeData.UpdateOctantIndex(); + break; + } + } +#endif + + #endregion --------------------------- Render Graph --------------------------- + + #region --------------------------- Shared --------------------------- + + private static void ExecuteConstant(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight, PassData data) + { + var viewMatrixCached = camera.worldToCameraMatrix; + var projectionMatrixCached = camera.projectionMatrix; + + var directionalLightCamera = DirectionalShadowmapService.Instance.DirectionalCamera.GetDirectionalCamera; + + cmd.SetViewProjectionMatrices(directionalLightCamera.worldToCameraMatrix, directionalLightCamera.projectionMatrix); + + var viewMatrix = directionalLightCamera.worldToCameraMatrix; + var projectionMatrix = directionalLightCamera.projectionMatrix; + projectionMatrix = GL.GetGPUProjectionMatrix(projectionMatrix, false); + + cmd.SetGlobalMatrix(g_DirLightMatrix, projectionMatrix * viewMatrix); + cmd.SetGlobalVector(g_DirLightPlanes, new Vector2(directionalLightCamera.nearClipPlane, directionalLightCamera.farClipPlane)); + + // Render shadowmap + cmd.SetRenderTarget(DirectionalShadowmapStatic.rt, DirectionalDepthTarget.rt); //TODO: Why we use DirectionalShadowmapStatic here? + cmd.ClearRenderTarget(true, true, Color.black); + cmd.DrawRendererList(data.RendererListHandle); + + cmd.SetGlobalTexture(g_HTraceShadowmap, DirectionalDepthTarget.rt); + + cmd.SetViewProjectionMatrices(viewMatrixCached, projectionMatrixCached); + + History.Update(); + } + + private static void ExecutePartial(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight, PassData data) + { + var viewMatrixCached = camera.worldToCameraMatrix; + var projectionMatrixCached = camera.projectionMatrix; + + var directionalLightCamera = DirectionalShadowmapService.Instance.DirectionalCamera.GetDirectionalCamera; + + cmd.SetViewProjectionMatrices(directionalLightCamera.worldToCameraMatrix, directionalLightCamera.projectionMatrix); + + var shadowmapRenderTarget = DirectionalDepthTargetStatic; + ClearFlag clearDepthFlag = ClearFlag.Depth; + + var viewMatrix = directionalLightCamera.worldToCameraMatrix; + var projectionMatrix = directionalLightCamera.projectionMatrix; + projectionMatrix = GL.GetGPUProjectionMatrix(projectionMatrix, false); + + if ((int)VoxelizationRuntimeData.OctantIndex == 5) + { + cmd.SetGlobalMatrix(g_DirLightMatrix, projectionMatrix * viewMatrix); + + // Copy merged static depth to the final depth render target where dynamic objects will be added + ShadowmapMaterial.SetTexture(_DirectionalShadowmapStatic, DirectionalShadowmapStatic.rt); + CoreUtils.SetRenderTarget(cmd, DirectionalDepthTargetCombined.rt, ClearFlag.Depth, 0, CubemapFace.Unknown, -1); + + CoreUtils.DrawFullScreen(cmd, ShadowmapMaterial, DirectionalDepthTargetCombined.rt, DirectionalDepthTargetCombined.rt, shaderPassId: 0); + + shadowmapRenderTarget = DirectionalDepthTargetCombined; + clearDepthFlag = ClearFlag.None; + } + + var maximumLODLevelBackup = QualitySettings.maximumLODLevel; + var lodBiasBackup = QualitySettings.lodBias; + QualitySettings.SetLODSettings(1, HSettings.VoxelizationSettings.LODMax, false); + + // Render shadowmap + CoreUtils.SetRenderTarget(cmd, shadowmapRenderTarget.rt, shadowmapRenderTarget.rt, clearDepthFlag); + + cmd.DrawRendererList(data.RendererListHandle); + + // Restore matrices and culling of the main camera + QualitySettings.SetLODSettings(lodBiasBackup, maximumLODLevelBackup, false); + cmd.SetViewProjectionMatrices(viewMatrixCached, projectionMatrixCached); + + // Merge shadowmap octants with static objects into a single texture + using (new HTraceProfilingScope(cmd, s_MergeShadowmapStaticProfilingSampler)) + { + if ((int)VoxelizationRuntimeData.OctantIndex != 5) + { + Vector2 octantShadowOffset = Vector2.zero; + int octantIndex = (int)VoxelizationRuntimeData.OctantIndex; + + if (octantIndex == 1) octantShadowOffset = new Vector2(0, HConstants.ShadowmapResolution.y / 2); + if (octantIndex == 2) octantShadowOffset = new Vector2(HConstants.ShadowmapResolution.x / 2, HConstants.ShadowmapResolution.y / 2); + if (octantIndex == 3) octantShadowOffset = new Vector2(0, 0); + if (octantIndex == 4) octantShadowOffset = new Vector2(HConstants.ShadowmapResolution.x / 2, 0); + + cmd.SetComputeTextureParam(HShadowmap, (int)HShadowmapKernel.ShadowmapMerge, _Shadowmap, DirectionalDepthTargetStatic.rt); + cmd.SetComputeTextureParam(HShadowmap, (int)HShadowmapKernel.ShadowmapMerge, _Shadowmap_Output, DirectionalShadowmapStatic.rt); + cmd.SetComputeVectorParam(HShadowmap, _OctantShadowOffset, octantShadowOffset); + cmd.DispatchCompute(HShadowmap, (int)HShadowmapKernel.ShadowmapMerge, (int)HConstants.ShadowmapResolution.x / 2 / 8, (int)HConstants.ShadowmapResolution.y / 2 / 8, 1); + } + } + + // Pass rendered shadowmap to shaders + cmd.SetGlobalTexture(g_HTraceShadowmap, DirectionalDepthTargetCombined.rt); + + History.Update(); + } + + protected internal void Dispose() + { + DirectionalDepthTargetStatic?.HRelease(); + DirectionalDepthTargetCombined?.HRelease(); + DirectionalShadowmapStatic?.HRelease(); + DirectionalDepthTarget?.HRelease(); + } + + #endregion --------------------------- Shared --------------------------- + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/DirectionalShadowmapPassURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/URP/DirectionalShadowmapPassURP.cs.meta new file mode 100644 index 000000000..afcbbd334 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/DirectionalShadowmapPassURP.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 3fc79123f3ec456caf8000442e3b7d38 +timeCreated: 1759390817 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/URP/DirectionalShadowmapPassURP.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/FinalPassURP.cs b/Assets/External/HTraceWSGI/Scripts/Passes/URP/FinalPassURP.cs new file mode 100644 index 000000000..dee089696 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/FinalPassURP.cs @@ -0,0 +1,420 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Passes.Shared; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +#if UNITY_2023_3_OR_NEWER +using UnityEngine.Rendering.RenderGraphModule; +#endif + +namespace HTraceWSGI.Scripts.Passes.URP +{ + internal class FinalPassURP : ScriptableRenderPass + { + const string _OutputTarget = "_OutputTarget"; + private static string s_motionVectorsKeyword = "MOTION_VECTORS"; + + // Shader properties + private static readonly int AmbientOcclusionParam = Shader.PropertyToID("_AmbientOcclusionParam"); + private static readonly int DebugSwitch = Shader.PropertyToID("_DebugSwitch"); + private static readonly int BuffersSwitch = Shader.PropertyToID("_BuffersSwitch"); + private static readonly int Debug_Output = Shader.PropertyToID("_Debug_Output"); + + internal static ComputeShader VoxelVisualization; + internal static Material VoxelVisualizationMaterial; + internal static ComputeShader HLightCluster; + internal static Material LightClusterVisualizationMaterial; + + // Buffers & etc + internal static ComputeShader HDebug = null; + + // Textures + internal static RTHandle OutputTarget; + + + + private static void SetUrpAdditionalLightShadowKeywords(ComputeShader ComputeShader) + { + if (ComputeShader == null) + return; + + bool UseAdditionalLightShadows = HSettings.LightingSettings.EvaluatePunctualLights && HRendererURP.UrpAsset != null && HRendererURP.UrpAsset.supportsAdditionalLightShadows; + + if (UseAdditionalLightShadows) + ComputeShader.EnableKeyword(VoxelizationShared.ADDITIONAL_LIGHT_SHADOWS); + else + ComputeShader.DisableKeyword(VoxelizationShared.ADDITIONAL_LIGHT_SHADOWS); + } + + + #region --------------------------- Non Render Graph --------------------------- + +#if !UNITY_6000_4_OR_NEWER + private ScriptableRenderer _renderer; + + protected internal void Initialize(ScriptableRenderer renderer) + { + _renderer = renderer; + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) + { + // SetupShared(renderingData.cameraData.camera, renderingData.cameraData.renderScale, renderingData.cameraData.cameraTargetDescriptor); + // + // if (HDebug == null) HDebug = HExtensions.LoadComputeShader("HDebug"); + // + // int width = (int)(camera.scaledPixelWidth * renderScale); + // int height = (int)(camera.scaledPixelHeight * renderScale); + // + // if (desc.width != width || desc.height != height) + // desc = new RenderTextureDescriptor(width, height); + // desc.depthBufferBits = 0; // Color and depth cannot be combined in RTHandles + // desc.stencilFormat = GraphicsFormat.None; + // desc.depthStencilFormat = GraphicsFormat.None; + // desc.msaaSamples = 1; + // desc.bindMS = false; + // desc.enableRandomWrite = true; + // + // ExtensionsURP.ReAllocateIfNeeded(_OutputTarget, ref OutputTarget, ref desc); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) + { + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + + Camera camera = renderingData.cameraData.camera; + + var cmd = CommandBufferPool.Get(HNames.HTRACE_FINAL_PASS_NAME); + + int width = (int)(camera.scaledPixelWidth * renderingData.cameraData.renderScale); + int height = (int)(camera.scaledPixelHeight * renderingData.cameraData.renderScale); + + if (DebugModule(cmd, width, height, OutputTarget)) + return; + + Blitter.BlitCameraTexture(cmd, OutputTarget, _renderer.cameraColorTargetHandle); + + + context.ExecuteCommandBuffer(cmd); + cmd.Clear(); + CommandBufferPool.Release(cmd); + } + +#endif + #endregion --------------------------- Non Render Graph --------------------------- + + #region --------------------------- Render Graph --------------------------- + +#if UNITY_2023_3_OR_NEWER + private class VoxelVisPassData + { + public UniversalCameraData UniversalCameraData; + public TextureHandle VoxelVisualizationRayDirections; + public TextureHandle VoxelVisualizationDebugOutput; + } + private class LightClusterVisPassData + { + public UniversalCameraData UniversalCameraData; + public TextureHandle LightClusterDebugColor; + public TextureHandle LightClusterDebugDepth; + } + private class DebugPassData + { + public TextureHandle ColorTexture; + public TextureHandle DebugColorTexture; + public TextureHandle DebugDepthTexture; + public TextureHandle DebugGBuffer0Texture; + public TextureHandle DebugGBuffer1Texture; + public TextureHandle DebugGBuffer2Texture; + public TextureHandle DebugMotionVectorsTexture; + public TextureHandle DebugMotionMaskTexture; + public UniversalCameraData UniversalCameraData; + public TextureHandle OutputTarget; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedLighting || HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedColor) + { + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_VOXEL_VISUALIZATION_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_VOXEL_VISUALIZATION_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + UniversalRenderingData universalRenderingData = frameData.Get(); + UniversalLightData lightData = frameData.Get(); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(false); + + passData.UniversalCameraData = universalCameraData; + + TextureHandle colorTextureHandle = resourceData.activeColorTexture; + TextureDesc textureDesc = colorTextureHandle.GetDescriptor(renderGraph); + + textureDesc.colorFormat = GraphicsFormat.R16G16B16A16_SFloat; + textureDesc.name = "_VoxelVisualizationRayDirections"; + passData.VoxelVisualizationRayDirections = renderGraph.CreateTexture(textureDesc); + builder.UseTexture(passData.VoxelVisualizationRayDirections, AccessFlags.ReadWrite); + + textureDesc.colorFormat = GraphicsFormat.R32G32B32A32_SFloat; + textureDesc.name = "_VoxelVisualizationDebugOutput"; + textureDesc.enableRandomWrite = true; + passData.VoxelVisualizationDebugOutput = renderGraph.CreateTexture(textureDesc); + builder.UseTexture(passData.VoxelVisualizationDebugOutput, AccessFlags.ReadWrite); + + + if (VoxelVisualization == null) VoxelVisualization = HExtensions.LoadComputeShader("VoxelVisualization"); + if (VoxelVisualizationMaterial == null) VoxelVisualizationMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/HTraceWSGI/VoxelVisualizationURP")); + + builder.SetRenderFunc((VoxelVisPassData data, UnsafeGraphContext context) => + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); + + Camera camera = data.UniversalCameraData.camera; + int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); + int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); + + // Disable visualization keywords by default + VoxelVisualization.EnableKeyword(VoxelizationShared.VISUALIZE_OFF); VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_LIGHTING); VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_COLOR); + + if (HSettings.LightingSettings.EvaluatePunctualLights) VoxelVisualization.EnableKeyword(VoxelizationShared.EVALUATE_PUNCTUAL_LIGHTS); + else VoxelVisualization.DisableKeyword(VoxelizationShared.EVALUATE_PUNCTUAL_LIGHTS); + + SetUrpAdditionalLightShadowKeywords(VoxelVisualization); + + using (new HTraceProfilingScope(cmd, VoxelizationShared.s_VisualizeVoxelsProfilingSampler)) + { + if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedLighting) + {VoxelizationShared.VoxelVisualization.EnableKeyword(VoxelizationShared.VISUALIZE_LIGHTING); VoxelizationShared.VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_COLOR); VoxelizationShared.VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_OFF);} + + if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.VoxelizedColor) + {VoxelizationShared.VoxelVisualization.EnableKeyword(VoxelizationShared.VISUALIZE_COLOR); VoxelizationShared.VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_LIGHTING); VoxelizationShared.VoxelVisualization.DisableKeyword(VoxelizationShared.VISUALIZE_OFF);} + + Vector2Int runningRes = new Vector2Int(width, height); + Vector2 probeAtlasRes = runningRes * Vector2.one / HSettings.GeneralSettings.RayCountMode.ParseToProbeSize() * HConstants.OCTAHEDRAL_SIZE; + + //Dispatch resolutions + int fullResX_8 = Mathf.CeilToInt((float)runningRes.x / 8); + int fullResY_8 = Mathf.CeilToInt((float)runningRes.y / 8); + + // Calculate rays in camera frustum + // var debugCameraFrustum = HMath.ComputeFrustumCorners(camera); + // // Interpolate rays in vf shader + // CoreUtils.SetRenderTarget(cmd, data.VoxelVisualizationRayDirections); + // VoxelVisualizationMaterial.SetMatrix(HShaderParams._DebugCameraFrustum, debugCameraFrustum); + // CoreUtils.DrawFullScreen(cmd, VoxelVisualizationMaterial, VoxelizationShared.VoxelVisualizationRayDirections.rt, shaderPassId: 0); + + // Trace into voxels for debug + cmd.SetComputeTextureParam(VoxelVisualization, (int)VoxelizationShared.VoxelVisualizationKernel.VisualizeVoxels, HShaderParams._DebugRayDirection, data.VoxelVisualizationRayDirections); + cmd.SetComputeTextureParam(VoxelVisualization, (int)VoxelizationShared.VoxelVisualizationKernel.VisualizeVoxels, HShaderParams._Visualization_Output, data.VoxelVisualizationDebugOutput); + cmd.SetComputeIntParam(VoxelVisualization, HShaderParams._MultibounceMode, (int)HSettings.GeneralSettings.Multibounce); + cmd.DispatchCompute(VoxelVisualization, (int)VoxelizationShared.VoxelVisualizationKernel.VisualizeVoxels, fullResX_8, fullResY_8, TextureXR.slices); + + cmd.SetGlobalTexture(HShaderParams.g_HTraceBufferGI, data.VoxelVisualizationDebugOutput); + } + }); + } + } + + if (HSettings.LightingSettings.EvaluatePunctualLights && (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.LightClusterColor || HSettings.GeneralSettings.DebugModeWS == DebugModeWS.LightClusterHeatmap)) + { + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_LIGHT_CLUSTER_VISUALIZATION_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_LIGHT_CLUSTER_VISUALIZATION_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(false); + + passData.UniversalCameraData = universalCameraData; + + TextureHandle colorTextureHandle = resourceData.activeColorTexture; + TextureDesc textureDesc = colorTextureHandle.GetDescriptor(renderGraph); + textureDesc.clearBuffer = false; + + passData.LightClusterDebugColor = ExtensionsURP.CreateTexture("_LightClusterDebugColor", renderGraph, ref textureDesc, GraphicsFormat.R16G16B16A16_SFloat); + builder.UseTexture(passData.LightClusterDebugColor, AccessFlags.ReadWrite); + + // Match the dedicated sampleable debug target used by the shared/HDRP path + // instead of inheriting the camera depth texture descriptor. + passData.LightClusterDebugDepth = ExtensionsURP.CreateTexture("_LightClusterDebugDepth", renderGraph, ref textureDesc, GraphicsFormat.R8_UNorm, + depthBufferBits: DepthBits.Depth32, enableRandomWrite: false); + builder.UseTexture(passData.LightClusterDebugDepth, AccessFlags.ReadWrite); + + if (HLightCluster == null) HLightCluster = HExtensions.LoadComputeShader($"HLightClusterURP", HRenderPipeline.URP);; + if (LightClusterVisualizationMaterial == null) LightClusterVisualizationMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/HTraceWSGI/LightClusterVisualizationURP")); + + builder.SetRenderFunc((LightClusterVisPassData data, UnsafeGraphContext context) => + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(context.cmd); + + Camera camera = data.UniversalCameraData.camera; + int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); + int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); + + if (HSettings.LightingSettings.EvaluatePunctualLights == true) + { + // Draw 2D debug light cluster view on visible surfaces + cmd.SetComputeTextureParam(HLightCluster, (int)LightClusterShared.LightClusterKernels.DebugLightCluster, LightClusterShared._LightClusterDebug_Output, passData.LightClusterDebugColor); + cmd.DispatchCompute(HLightCluster, (int)LightClusterShared.LightClusterKernels.DebugLightCluster, Mathf.CeilToInt(width / 8.0f), Mathf.CeilToInt(height / 8.0f), TextureXR.slices); + } + + if (HSettings.LightingSettings.EvaluatePunctualLights && HSettings.GeneralSettings.VolumetricDebug) + { + // Find all edge cells relative to each light's radius + cmd.DispatchCompute(HLightCluster, (int)LightClusterShared.LightClusterKernels.FillLightClusterDebugBuffer, HSettings.LightingSettings.LightClusterCellDensity / 4, HSettings.LightingSettings.LightClusterCellDensity / 4, HSettings.LightingSettings.LightClusterCellDensity / 4); + + LightClusterVisualizationMaterial.SetTexture(LightClusterShared._LightClusterDebugColor, passData.LightClusterDebugColor); + LightClusterVisualizationMaterial.SetTexture(LightClusterShared._LightClusterDebugDepth, passData.LightClusterDebugDepth); + + // Set our own Color and Depth render targets + CoreUtils.SetRenderTarget(cmd, passData.LightClusterDebugColor, passData.LightClusterDebugDepth, ClearFlag.Depth, Color.clear, + 0, CubemapFace.Unknown, -1); + + // Draw cubes first to Color and then to Depth + cmd.DrawProcedural(Matrix4x4.identity, LightClusterVisualizationMaterial, 0, MeshTopology.Triangles, 36, + HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity); + cmd.DrawProcedural(Matrix4x4.identity, LightClusterVisualizationMaterial, 1, MeshTopology.Triangles, 36, + HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity); + + // Set only Color + CoreUtils.SetRenderTarget(cmd, passData.LightClusterDebugColor, ClearFlag.None); + + // Draw lines testing against the Depth filled by Cubes + cmd.DrawProcedural(Matrix4x4.identity, LightClusterVisualizationMaterial, 2, MeshTopology.Lines, 48, + HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity * HSettings.LightingSettings.LightClusterCellDensity); + } + + cmd.SetGlobalTexture(HShaderParams.g_LightClusterDebug, passData.LightClusterDebugColor); + }); + } + } + + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_FINAL_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_FINAL_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + UniversalRenderingData universalRenderingData = frameData.Get(); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(false); + + TextureHandle colorTexture = universalRenderingData.renderingMode == RenderingMode.Deferred +#if UNITY_6000_1_OR_NEWER + || universalRenderingData.renderingMode == RenderingMode.DeferredPlus +#endif + ? resourceData.activeColorTexture : resourceData.cameraColor; + + passData.ColorTexture = colorTexture; + passData.DebugColorTexture = GBufferPassURP.DebugColorTextureRG; + passData.DebugDepthTexture = GBufferPassURP.DebugDepthTextureRG; + passData.DebugGBuffer0Texture = GBufferPassURP.DebugGBuffer0TextureRG; + passData.DebugGBuffer1Texture = GBufferPassURP.DebugGBuffer1TextureRG; + passData.DebugGBuffer2Texture = GBufferPassURP.DebugGBuffer2TextureRG; + passData.DebugMotionVectorsTexture = MotionVectorsPassURP.DebugMotionVectorsTextureRG; + passData.DebugMotionMaskTexture = MotionVectorsPassURP.DebugMotionMaskTextureRG; + passData.UniversalCameraData = universalCameraData; + + if (passData.DebugColorTexture.IsValid()) builder.UseTexture(passData.DebugColorTexture, AccessFlags.Read); + if (passData.DebugDepthTexture.IsValid()) builder.UseTexture(passData.DebugDepthTexture, AccessFlags.Read); + if (passData.DebugGBuffer0Texture.IsValid()) builder.UseTexture(passData.DebugGBuffer0Texture, AccessFlags.Read); + if (passData.DebugGBuffer1Texture.IsValid()) builder.UseTexture(passData.DebugGBuffer1Texture, AccessFlags.Read); + if (passData.DebugGBuffer2Texture.IsValid()) builder.UseTexture(passData.DebugGBuffer2Texture, AccessFlags.Read); + if (passData.DebugMotionVectorsTexture.IsValid()) builder.UseTexture(passData.DebugMotionVectorsTexture, AccessFlags.Read); + if (passData.DebugMotionMaskTexture.IsValid()) builder.UseTexture(passData.DebugMotionMaskTexture, AccessFlags.Read); + + if (HDebug == null) HDebug = HExtensions.LoadComputeShader("HDebug"); + + TextureHandle colorTextureHandle = resourceData.cameraColor; + TextureDesc desc = colorTextureHandle.GetDescriptor(renderGraph); + desc.colorFormat = GraphicsFormat.R16G16B16A16_SFloat; + desc.clearBuffer = false; + desc.name = _OutputTarget; + desc.enableRandomWrite = true; + passData.OutputTarget = renderGraph.CreateTexture(desc); + builder.UseTexture(passData.OutputTarget, AccessFlags.ReadWrite); + + builder.SetRenderFunc((DebugPassData data, UnsafeGraphContext context) => ExecutePass(data, context)); + } + } + + private static void ExecutePass(DebugPassData data, UnsafeGraphContext rgContext) + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); + + int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); + int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); + + if (data.DebugColorTexture.IsValid()) + cmd.SetGlobalTexture(HShaderParams.g_HTraceColor, data.DebugColorTexture); + if (data.DebugDepthTexture.IsValid()) + cmd.SetGlobalTexture(HShaderParams.g_HTraceDepth, data.DebugDepthTexture); + if (data.DebugGBuffer0Texture.IsValid()) + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, data.DebugGBuffer0Texture); + if (data.DebugGBuffer1Texture.IsValid()) + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, data.DebugGBuffer1Texture); + if (data.DebugGBuffer2Texture.IsValid()) + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, data.DebugGBuffer2Texture); + if (data.DebugMotionVectorsTexture.IsValid()) + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionVectors, data.DebugMotionVectorsTexture); + if (data.DebugMotionMaskTexture.IsValid()) + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionMask, data.DebugMotionMaskTexture); + + if (DebugModule(cmd, width, height, data.OutputTarget)) + return; + + Blitter.BlitCameraTexture(cmd, data.OutputTarget, data.ColorTexture); + } +#endif + #endregion --------------------------- Render Graph --------------------------- + + #region --------------------------- Shared --------------------------- + + + private static bool DebugModule(CommandBuffer cmd, int width, int height, RTHandle outputTarget) + { + if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.None || HSettings.GeneralSettings.DebugModeWS == DebugModeWS.DirectLighting) + return true; + + using (new HTraceProfilingScope(cmd, new ProfilingSamplerHTrace("Debug"))) + { + cmd.SetComputeIntParams(HDebug, DebugSwitch, (int)HSettings.GeneralSettings.DebugModeWS); + cmd.SetComputeIntParams(HDebug, BuffersSwitch, (int)HSettings.GeneralSettings.HBuffer); + + int debug_kernel = 0; + cmd.SetComputeTextureParam(HDebug, debug_kernel, Debug_Output, outputTarget.rt); + cmd.DispatchCompute(HDebug, debug_kernel, Mathf.CeilToInt(width / 8.0f), Mathf.CeilToInt(height / 8.0f), HRenderer.TextureXrSlices); + } + + return false; + } + + protected internal void Dispose() + { + + Object.DestroyImmediate(LightClusterVisualizationMaterial); + //HLightCluster + } + + #endregion --------------------------- Shared --------------------------- + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/FinalPassURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/URP/FinalPassURP.cs.meta new file mode 100644 index 000000000..62a0bf1b1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/FinalPassURP.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1c2c9a36cee20a447a1cc021770c36d0 +timeCreated: 1729952288 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/URP/FinalPassURP.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/GBufferPassURP.cs b/Assets/External/HTraceWSGI/Scripts/Passes/URP/GBufferPassURP.cs new file mode 100644 index 000000000..b0dc978d8 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/GBufferPassURP.cs @@ -0,0 +1,545 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +using UnityEngine.Rendering.RendererUtils; +using UnityEngine.Rendering.Universal; + +#if UNITY_2023_3_OR_NEWER +using UnityEngine.Rendering.RenderGraphModule; +#endif + +namespace HTraceWSGI.Scripts.Passes.URP +{ + internal class GBufferPassURP : ScriptableRenderPass + { + private enum HDepthPyramidKernel + { + GenerateDepthPyramid_1 = 0, + GenerateDepthPyramid_2 = 1, + } + // Texture Names + private const string _Dummy = "_Dummy"; + private const string _DepthPyramid = "_DepthPyramid"; + private const string _DepthIntermediate_Pyramid = "_DepthIntermediate_Pyramid"; + private const string _ForwardGBuffer0 = "_ForwardGBuffer0"; + private const string _ForwardGBuffer1 = "_ForwardGBuffer1"; + private const string _ForwardGBuffer2 = "_ForwardGBuffer2"; + private const string _ForwardGBuffer3 = "_ForwardGBuffer3"; + private const string _ForwardRenderLayerMask = "_ForwardRenderLayerMask"; + private const string _ForwardGBufferDepth = "_ForwardGBufferDepth"; + + // Materials & Computes + internal static ComputeShader HDepthPyramid = null; + + // Samplers + internal static readonly ProfilingSamplerHTrace GBufferProfilingSampler = new("GBuffer", HNames.HTRACE_PRE_PASS_NAME, 0); + private static readonly ProfilingSamplerHTrace DepthPyramidGenerationProfilingSampler = new ProfilingSamplerHTrace("Depth Pyramid Generation", parentName: HNames.HTRACE_PRE_PASS_NAME); + + // Textures + internal static RTHandle Dummy; + internal static RTHandle ForwardGBuffer0; + internal static RTHandle ForwardGBuffer1; + internal static RTHandle ForwardGBuffer2; + internal static RTHandle ForwardGBuffer3; + internal static RTHandle ForwardRenderLayerMask; + internal static RTHandle ForwardGBufferDepth; + internal static RTHandle DepthPyramidRT; + internal static RTHandle DepthIntermediate_Pyramid; + internal static TextureHandle DebugGBuffer0TextureRG; + internal static TextureHandle DebugGBuffer1TextureRG; + internal static TextureHandle DebugGBuffer2TextureRG; + internal static TextureHandle DebugDepthTextureRG; + internal static TextureHandle DebugColorTextureRG; + + // MRT Arrays + internal static RenderTargetIdentifier[] GBufferMRT = null; + + // Misc + internal static RenderStateBlock ForwardGBufferRenderStateBlock = new RenderStateBlock(RenderStateMask.Nothing); + + #region --------------------------- Non Render Graph --------------------------- + +#if !UNITY_6000_4_OR_NEWER + private ScriptableRenderer _renderer; + + protected internal void Initialize(ScriptableRenderer renderer) + { + _renderer = renderer; + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) + { + // SetupShared(renderingData.cameraData.camera, renderingData.cameraData.renderScale, renderingData.cameraData.cameraTargetDescriptor); + // if (HDepthPyramid == null) HDepthPyramid = HExtensions.LoadComputeShader("HDepthPyramid"); + // + // int width = (int)(camera.scaledPixelWidth * renderScale); + // int height = (int)(camera.scaledPixelHeight * renderScale); + // + // if (desc.width != width || desc.height != height) + // desc = new RenderTextureDescriptor(width, height); + // desc.depthBufferBits = 0; // Color and depth cannot be combined in RTHandles + // desc.stencilFormat = GraphicsFormat.None; + // desc.depthStencilFormat = GraphicsFormat.None; + // desc.msaaSamples = 1; + // desc.bindMS = false; + // + // var graphicsFormatRenderingLayerMask = GraphicsFormat.R8G8B8A8_UNorm; + // + // #if UNITY_6000_2_OR_NEWER + // graphicsFormatRenderingLayerMask = GraphicsFormat.R8G8_UInt; + // #endif + // + // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBuffer0, ref ForwardGBuffer0, ref desc, graphicsFormat: GraphicsFormat.R8G8B8A8_SRGB); + // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBuffer1, ref ForwardGBuffer1, ref desc, graphicsFormat: GraphicsFormat.R8G8B8A8_UNorm); + // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBuffer2, ref ForwardGBuffer2, ref desc, graphicsFormat: GraphicsFormat.R8G8B8A8_UNorm); + // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBuffer3, ref ForwardGBuffer3, ref desc, graphicsFormat: GraphicsFormat.B10G11R11_UFloatPack32); + // ExtensionsURP.ReAllocateIfNeeded(_ForwardRenderLayerMask, ref ForwardRenderLayerMask, ref desc, graphicsFormat: graphicsFormatRenderingLayerMask); + // ExtensionsURP.ReAllocateIfNeeded(_DepthPyramid, ref DepthPyramidRT, ref desc, graphicsFormat: GraphicsFormat.R16_SFloat, useMipMap: true); + // desc.width = width / 16; + // desc.height = height / 16; + // ExtensionsURP.ReAllocateIfNeeded(_DepthIntermediate_Pyramid, ref DepthIntermediate_Pyramid, ref desc, graphicsFormat: GraphicsFormat.R16_SFloat, useMipMap: true); + // + // RenderTextureDescriptor depthDesc = desc; + // depthDesc.depthBufferBits = 32; + // depthDesc.depthStencilFormat = GraphicsFormat.None; + // ExtensionsURP.ReAllocateIfNeeded(_ForwardGBufferDepth, ref ForwardGBufferDepth, ref depthDesc, graphicsFormat: GraphicsFormat.R16_SFloat, useMipMap: false, enableRandomWrite: false); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) + { + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + Camera camera = renderingData.cameraData.camera; + + var cmd = CommandBufferPool.Get(HNames.HTRACE_GBUFFER_PASS_NAME); + + int width = (int)(camera.scaledPixelWidth * renderingData.cameraData.renderScale); + int height = (int)(camera.scaledPixelHeight * renderingData.cameraData.renderScale); + + // Set Depth and Color to HTrace passes + cmd.SetGlobalTexture(HShaderParams.g_HTraceColor, _renderer.cameraColorTargetHandle); + cmd.SetGlobalTexture(HShaderParams.g_HTraceDepth, _renderer.cameraDepthTargetHandle); + + var nativeGBuffer0 = Shader.GetGlobalTexture(HShaderParams._GBuffer0); + var nativeGBuffer1 = Shader.GetGlobalTexture(HShaderParams._GBuffer1); + var nativeGBuffer2 = Shader.GetGlobalTexture(HShaderParams._GBuffer2); + var renderLayerMaskTexture = Shader.GetGlobalTexture(HShaderParams._CameraRenderingLayersTexture); + + GBufferGenerationNonRenderGraph(cmd, width, height, nativeGBuffer0, nativeGBuffer1, nativeGBuffer2, renderLayerMaskTexture, _renderer.cameraColorTargetHandle, _renderer.cameraDepthTargetHandle, ref context, ref renderingData); + + using (new HTraceProfilingScope(cmd, DepthPyramidGenerationProfilingSampler)) + { + // Generate 0-4 mip levels + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP0, DepthPyramidRT.rt, 0); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP1, DepthPyramidRT.rt, 1); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP2, DepthPyramidRT.rt, 2); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP3, DepthPyramidRT.rt, 3); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP4, DepthPyramidRT.rt, 4); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthIntermediate_Output, DepthIntermediate_Pyramid.rt); + cmd.DispatchCompute(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, Mathf.CeilToInt(width / 16.0f), Mathf.CeilToInt(height / 16.0f), TextureXR.slices); + + // Generate 5-7 mip levels + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthIntermediate, DepthIntermediate_Pyramid.rt); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP5, DepthPyramidRT.rt, 5); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP6, DepthPyramidRT.rt, 6); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP7, DepthPyramidRT.rt, 7); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP8, DepthPyramidRT.rt, 8); + cmd.DispatchCompute(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, Mathf.CeilToInt(width / 16.0f / 8.0f), Mathf.CeilToInt(height / 16.0f / 8.0f), TextureXR.slices); + + cmd.SetGlobalTexture(HShaderParams.g_HTraceDepthPyramidWSGI, DepthPyramidRT.rt); + } + + context.ExecuteCommandBuffer(cmd); + cmd.Clear(); + CommandBufferPool.Release(cmd); + } + + + private static void GBufferGenerationNonRenderGraph(CommandBuffer cmd, int width, int height, Texture nativeGBuffer0, Texture nativeGBuffer1, + Texture nativeGBuffer2, Texture renderLayerMask, RTHandle cameraColorBuffer, RTHandle cameraDepthBuffer, + ref ScriptableRenderContext context, ref RenderingData renderingData) + { + var camera = renderingData.cameraData.camera; + using (new HTraceProfilingScope(cmd, GBufferProfilingSampler)) + { + // Set sky probe management + SphericalHarmonicsL2 ambientProbe = RenderSettings.ambientProbe; + cmd.SetGlobalVector(HShaderParams.H_SHAr, new Vector4(ambientProbe[0, 3], ambientProbe[0, 1], ambientProbe[0, 2], ambientProbe[0, 0] - ambientProbe[0, 6])); + cmd.SetGlobalVector(HShaderParams.H_SHAg, new Vector4(ambientProbe[1, 3], ambientProbe[1, 1], ambientProbe[1, 2], ambientProbe[1, 0] - ambientProbe[1, 6])); + cmd.SetGlobalVector(HShaderParams.H_SHAb, new Vector4(ambientProbe[2, 3], ambientProbe[2, 1], ambientProbe[2, 2], ambientProbe[2, 0] - ambientProbe[2, 6])); + cmd.SetGlobalVector(HShaderParams.H_SHBr, new Vector4(ambientProbe[0, 4], ambientProbe[0, 5], ambientProbe[0, 6] * 3, ambientProbe[0, 7])); + cmd.SetGlobalVector(HShaderParams.H_SHBg, new Vector4(ambientProbe[1, 4], ambientProbe[1, 5], ambientProbe[1, 6] * 3, ambientProbe[1, 7])); + cmd.SetGlobalVector(HShaderParams.H_SHBb, new Vector4(ambientProbe[2, 4], ambientProbe[2, 5], ambientProbe[2, 6] * 3, ambientProbe[2, 7])); + cmd.SetGlobalVector(HShaderParams.H_SHC, new Vector4(ambientProbe[0, 8], ambientProbe[1, 8], ambientProbe[2, 8], 1)); + + // Check if GBuffer is valid (e.g. Forward / wrong scale / is not set, etc.) + bool RequestForwardGBufferRender = false; + if (nativeGBuffer0 == null || nativeGBuffer1 == null || nativeGBuffer2 == null) + { RequestForwardGBufferRender = true; } + else if ( nativeGBuffer0.width != width || nativeGBuffer0.height != height) // CameraDepthBuffer.rtHandleProperties.currentViewportSize.x + { RequestForwardGBufferRender = true; } + + // Set Render Layer Mask to black dummy in case it's disabled as a feature and we can't render it + if (renderLayerMask == null) + renderLayerMask = HRenderer.EmptyTexture;// Dummy.rt; + + //RequestForwardGBufferRender = true; + + // GBuffer can't be rendered because its resolution doesn't match the resolution of Unity's depth buffer. Happens when switching between Scene and Game windows + if (ForwardGBuffer0.rt.width != cameraDepthBuffer.rt.width || ForwardGBuffer0.rt.height != cameraDepthBuffer.rt.height) + { + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, ForwardGBuffer0.rt); + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, ForwardGBuffer1.rt); + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, ForwardGBuffer2.rt); + cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, ForwardRenderLayerMask.rt); + return; + } + + // Set GBuffer to HTrace passes if valid or render it otherwise + if (RequestForwardGBufferRender == false) + { + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, nativeGBuffer0); + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, nativeGBuffer1); + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, nativeGBuffer2); + cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, renderLayerMask); + } + else + { + + if (HRendererURP.RenderGraphEnabled) + GBufferMRT = new RenderTargetIdentifier[] { ForwardGBuffer0.rt, ForwardGBuffer1.rt, ForwardGBuffer2.rt, ForwardGBuffer3.rt, ForwardGBufferDepth.rt, ForwardRenderLayerMask.rt }; + else + GBufferMRT = new RenderTargetIdentifier[] { ForwardGBuffer0.rt, ForwardGBuffer1.rt, ForwardGBuffer2.rt, ForwardGBuffer3.rt, ForwardRenderLayerMask.rt }; + + // If CameraDepthBuffer.rt doesn't work for any reason - we can replace it with our ForwardGBufferDepth.rt, but GBuffer rendering performance will suffer. + CoreUtils.SetRenderTarget(cmd, GBufferMRT, cameraDepthBuffer.rt); + CoreUtils.SetKeyword(cmd, HShaderParams._GBUFFER_NORMALS_OCT, true); + CoreUtils.SetKeyword(cmd, HShaderParams._WRITE_RENDERING_LAYERS, true); + + // ---------------------------------- Non Render Graph Version + CullingResults cullingResults = renderingData.cullResults; + int layerMask = camera.cullingMask; + + ForwardGBufferRenderStateBlock.depthState = new DepthState(false, CompareFunction.LessEqual); + ForwardGBufferRenderStateBlock.mask |= RenderStateMask.Depth; + + var renderList = new UnityEngine.Rendering.RendererUtils.RendererListDesc(HShaderParams.UniversalGBufferTag, cullingResults, camera) + { + rendererConfiguration = PerObjectData.None, + renderQueueRange = RenderQueueRange.opaque, + sortingCriteria = SortingCriteria.OptimizeStateChanges, + layerMask = layerMask, + stateBlock = ForwardGBufferRenderStateBlock, + }; + +#if UNITY_6000_3_OR_NEWER + CoreUtils.DrawRendererList(cmd, context.CreateRendererList(renderList)); +#else + CoreUtils.DrawRendererList(context, cmd, context.CreateRendererList(renderList)); +#endif + + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, ForwardGBuffer0.rt); + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, ForwardGBuffer1.rt); + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, ForwardGBuffer2.rt); + cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, ForwardRenderLayerMask.rt); + } + } + } +#endif + + #endregion --------------------------- Non Render Graph --------------------------- + + #region --------------------------- Render Graph --------------------------- + +#if UNITY_2023_3_OR_NEWER + private class PassData + { + public TextureHandle[] GBufferTextures; + public TextureHandle ColorTexture; + public TextureHandle DepthTexture; + public TextureHandle NormalsTexture; + public RendererListHandle ForwardGBufferRendererListHandle; + public UniversalCameraData UniversalCameraData; + + public TextureHandle ForwardGBuffer0Texture; + public TextureHandle ForwardGBuffer1Texture; + public TextureHandle ForwardGBuffer2Texture; + public TextureHandle ForwardGBuffer3Texture; + public TextureHandle ForwardRenderLayerMaskTexture; + public TextureHandle DepthPyramidTexture; + public TextureHandle DepthPyramidIntermediateTexture; + public TextureHandle ForwardGBufferDepthTexture; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + DebugGBuffer0TextureRG = default(TextureHandle); + DebugGBuffer1TextureRG = default(TextureHandle); + DebugGBuffer2TextureRG = default(TextureHandle); + DebugDepthTextureRG = default(TextureHandle); + DebugColorTextureRG = default(TextureHandle); + + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_GBUFFER_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_GBUFFER_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + UniversalRenderingData universalRenderingData = frameData.Get(); + UniversalLightData lightData = frameData.Get(); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(false); + + TextureHandle colorTexture = universalRenderingData.renderingMode == RenderingMode.Deferred +#if UNITY_6000_1_OR_NEWER + || universalRenderingData.renderingMode == RenderingMode.DeferredPlus +#endif + ? resourceData.activeColorTexture : resourceData.cameraColor; + TextureHandle depthTexture = universalRenderingData.renderingMode == RenderingMode.Deferred +#if UNITY_6000_1_OR_NEWER + || universalRenderingData.renderingMode == RenderingMode.DeferredPlus +#endif + ? resourceData.activeDepthTexture : resourceData.cameraDepth; + TextureHandle normalsTexture = resourceData.cameraNormalsTexture; + builder.UseTexture(depthTexture, AccessFlags.Read); + builder.UseTexture(normalsTexture, AccessFlags.Read); + + passData.ColorTexture = colorTexture; + passData.DepthTexture = depthTexture; + passData.NormalsTexture = normalsTexture; + passData.UniversalCameraData = universalCameraData; + passData.GBufferTextures = resourceData.gBuffer; + + DebugColorTextureRG = colorTexture; + DebugDepthTextureRG = depthTexture; + DebugGBuffer2TextureRG = normalsTexture; + + if (HDepthPyramid == null) HDepthPyramid = HExtensions.LoadComputeShader("HDepthPyramid"); + + TextureHandle colorTextureHandle = resourceData.cameraColor; + TextureDesc desc = colorTextureHandle.GetDescriptor(renderGraph); + desc.clearBuffer = false; + TextureHandle depthTextureHandle = resourceData.cameraDepthTexture; + TextureDesc descDepth = depthTextureHandle.GetDescriptor(renderGraph); + descDepth.clearBuffer = false; + + var graphicsFormatRenderingLayerMask = GraphicsFormat.R8G8B8A8_UNorm; + + #if UNITY_6000_2_OR_NEWER + graphicsFormatRenderingLayerMask = GraphicsFormat.R8G8_UInt; + #endif + + passData.ForwardGBuffer0Texture = ExtensionsURP.CreateTexture(_ForwardGBuffer0, renderGraph, ref desc, format: GraphicsFormat.R8G8B8A8_SRGB); + builder.UseTexture(passData.ForwardGBuffer0Texture, AccessFlags.Write); + passData.ForwardGBuffer1Texture = ExtensionsURP.CreateTexture(_ForwardGBuffer1, renderGraph, ref desc, format: GraphicsFormat.R8G8B8A8_UNorm); + builder.UseTexture(passData.ForwardGBuffer1Texture, AccessFlags.Write); + passData.ForwardGBuffer2Texture = ExtensionsURP.CreateTexture(_ForwardGBuffer2, renderGraph, ref desc, format: GraphicsFormat.R8G8B8A8_SNorm); + builder.UseTexture(passData.ForwardGBuffer2Texture, AccessFlags.Write); + passData.ForwardGBuffer3Texture = ExtensionsURP.CreateTexture(_ForwardGBuffer3, renderGraph, ref desc, format: GraphicsFormat.B10G11R11_UFloatPack32); + builder.UseTexture(passData.ForwardGBuffer3Texture, AccessFlags.Write); + passData.ForwardRenderLayerMaskTexture = ExtensionsURP.CreateTexture(_ForwardRenderLayerMask, renderGraph, ref desc, format: graphicsFormatRenderingLayerMask); + builder.UseTexture(passData.ForwardRenderLayerMaskTexture, AccessFlags.Write); + passData.DepthPyramidTexture = ExtensionsURP.CreateTexture(_DepthPyramid, renderGraph, ref desc, format: GraphicsFormat.R16_SFloat, useMipMap: true); + builder.UseTexture(passData.DepthPyramidTexture, AccessFlags.Write); + + desc.width /= 16; + desc.height /= 16; + passData.DepthPyramidIntermediateTexture = ExtensionsURP.CreateTexture(_DepthIntermediate_Pyramid, renderGraph, ref desc, format: GraphicsFormat.R16_SFloat, useMipMap: true); + builder.UseTexture(passData.DepthPyramidIntermediateTexture, AccessFlags.Write); + + passData.ForwardGBufferDepthTexture = ExtensionsURP.CreateTexture(_ForwardGBufferDepth, renderGraph, ref descDepth, format: GraphicsFormat.R16_SFloat, useMipMap: false, enableRandomWrite: false); + builder.UseTexture(passData.ForwardGBufferDepthTexture, AccessFlags.Write); + + bool useNativeDeferredGBuffer = universalRenderingData.renderingMode == RenderingMode.Deferred +#if UNITY_6000_1_OR_NEWER + || universalRenderingData.renderingMode == RenderingMode.DeferredPlus +#endif + ; + DebugGBuffer0TextureRG = useNativeDeferredGBuffer ? resourceData.gBuffer[0] : passData.ForwardGBuffer0Texture; + DebugGBuffer1TextureRG = useNativeDeferredGBuffer ? resourceData.gBuffer[1] : passData.ForwardGBuffer1Texture; + + + if (useNativeDeferredGBuffer) + { + builder.UseTexture(resourceData.gBuffer[0], AccessFlags.Read); + builder.UseTexture(resourceData.gBuffer[1], AccessFlags.Read); + builder.UseTexture(resourceData.gBuffer[2], AccessFlags.Read); + builder.UseTexture(resourceData.gBuffer[3], AccessFlags.Read); + if (resourceData.gBuffer.Length >= 6 && resourceData.gBuffer[5].IsValid()) + builder.UseTexture(resourceData.gBuffer[5], AccessFlags.Read); + } + + + CullingResults cullingResults = universalRenderingData.cullResults; + ShaderTagId tags = new ShaderTagId("UniversalGBuffer"); + int layerMask = universalCameraData.camera.cullingMask; + + ForwardGBufferRenderStateBlock.depthState = new DepthState(false, CompareFunction.LessEqual); + ForwardGBufferRenderStateBlock.mask |= RenderStateMask.Depth; + + RendererListDesc rendererListDesc = new RendererListDesc(tags, cullingResults, universalCameraData.camera) + { + rendererConfiguration = PerObjectData.None, + renderQueueRange = RenderQueueRange.opaque, + sortingCriteria = SortingCriteria.OptimizeStateChanges, + layerMask = layerMask, + stateBlock = ForwardGBufferRenderStateBlock, + }; + + passData.ForwardGBufferRendererListHandle = renderGraph.CreateRendererList(rendererListDesc); + builder.UseRendererList(passData.ForwardGBufferRendererListHandle); + + builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); + } + } + + private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); + + int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); + int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); + + // Set Depth and Color to HTrace passes + cmd.SetGlobalTexture(HShaderParams.g_HTraceColor, data.ColorTexture); + cmd.SetGlobalTexture(HShaderParams.g_HTraceDepth, data.DepthTexture); + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, data.NormalsTexture); + + var nativeGBuffer0 = data.GBufferTextures[0]; + var nativeGBuffer1 = data.GBufferTextures[1]; + var nativeGBuffer2 = data.GBufferTextures[2]; + Texture renderLayerMaskTexture = data.GBufferTextures.Length >= 6 ? data.GBufferTextures[5] : null; + GBufferGenerationRenderGraph(cmd, data, width, height, nativeGBuffer0, nativeGBuffer1, nativeGBuffer2, renderLayerMaskTexture, data.ColorTexture,data.DepthTexture, data.ForwardGBufferRendererListHandle); + + using (new HTraceProfilingScope(cmd, DepthPyramidGenerationProfilingSampler)) + { + // Generate 0-4 mip levels + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP0, data.DepthPyramidTexture, 0); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP1, data.DepthPyramidTexture, 1); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP2, data.DepthPyramidTexture, 2); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP3, data.DepthPyramidTexture, 3); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthPyramid_OutputMIP4, data.DepthPyramidTexture, 4); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, HShaderParams._DepthIntermediate_Output, data.DepthPyramidIntermediateTexture); + cmd.DispatchCompute(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_1, Mathf.CeilToInt(width / 16.0f), Mathf.CeilToInt(height / 16.0f), TextureXR.slices); + + // Generate 5-7 mip levels + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthIntermediate, data.DepthPyramidIntermediateTexture); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP5, data.DepthPyramidTexture, 5); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP6, data.DepthPyramidTexture, 6); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP7, data.DepthPyramidTexture, 7); + cmd.SetComputeTextureParam(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, HShaderParams._DepthPyramid_OutputMIP8, data.DepthPyramidTexture, 8); + cmd.DispatchCompute(HDepthPyramid, (int)HDepthPyramidKernel.GenerateDepthPyramid_2, Mathf.CeilToInt(width / 16.0f / 8.0f), Mathf.CeilToInt(height / 16.0f / 8.0f), TextureXR.slices); + + cmd.SetGlobalTexture(HShaderParams.g_HTraceDepthPyramidWSGI, data.DepthPyramidTexture); + } + } + + private static void GBufferGenerationRenderGraph(CommandBuffer cmd, PassData data, int width, int height, Texture nativeGBuffer0, Texture nativeGBuffer1, + Texture nativeGBuffer2, Texture renderLayerMask, RTHandle cameraColorBuffer, RTHandle cameraDepthBuffer, + RendererListHandle forwardGBufferRendererListHandle) + { + using (new HTraceProfilingScope(cmd, GBufferProfilingSampler)) + { + // Sky probe management + SphericalHarmonicsL2 ambientProbe = RenderSettings.ambientProbe; + cmd.SetGlobalVector(HShaderParams.H_SHAr, new Vector4(ambientProbe[0, 3], ambientProbe[0, 1], ambientProbe[0, 2], ambientProbe[0, 0] - ambientProbe[0, 6])); + cmd.SetGlobalVector(HShaderParams.H_SHAg, new Vector4(ambientProbe[1, 3], ambientProbe[1, 1], ambientProbe[1, 2], ambientProbe[1, 0] - ambientProbe[1, 6])); + cmd.SetGlobalVector(HShaderParams.H_SHAb, new Vector4(ambientProbe[2, 3], ambientProbe[2, 1], ambientProbe[2, 2], ambientProbe[2, 0] - ambientProbe[2, 6])); + cmd.SetGlobalVector(HShaderParams.H_SHBr, new Vector4(ambientProbe[0, 4], ambientProbe[0, 5], ambientProbe[0, 6] * 3, ambientProbe[0, 7])); + cmd.SetGlobalVector(HShaderParams.H_SHBg, new Vector4(ambientProbe[1, 4], ambientProbe[1, 5], ambientProbe[1, 6] * 3, ambientProbe[1, 7])); + cmd.SetGlobalVector(HShaderParams.H_SHBb, new Vector4(ambientProbe[2, 4], ambientProbe[2, 5], ambientProbe[2, 6] * 3, ambientProbe[2, 7])); + cmd.SetGlobalVector(HShaderParams.H_SHC, new Vector4(ambientProbe[0, 8], ambientProbe[1, 8], ambientProbe[2, 8], 1)); + + // Check if GBuffer is valid (e.g. Forward / wrong scale / is not set, etc.) + bool requestForwardGBufferRender = false; + if (nativeGBuffer0 == null || nativeGBuffer1 == null || nativeGBuffer2 == null) + { requestForwardGBufferRender = true; } + else if ( nativeGBuffer0.width != width || nativeGBuffer0.height != height) // CameraDepthBuffer.rtHandleProperties.currentViewportSize.x + { requestForwardGBufferRender = true; } + + // Set Render Layer Mask to black dummy in case it's disabled as a feature and we can't render it + if (renderLayerMask == null) + renderLayerMask = HRenderer.EmptyTexture;// Dummy.rt; + + // RequestForwardGBufferRender = true; + + // GBuffer can't be rendered because its resolution doesn't match the resolution of Unity's depth buffer. Happens when switching between Scene and Game windows + // NOT actual in new RG allocation? + // if (data.ForwardGBuffer0Texture.width != cameraDepthBuffer.rt.width || ForwardGBuffer0.rt.height != cameraDepthBuffer.rt.height) + // { + // cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, ForwardGBuffer0.rt); + // cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, ForwardGBuffer1.rt); + // cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer2, ForwardGBuffer2.rt); + // cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, ForwardRenderLayerMask.rt); + // return; + // } + + // Set GBuffer to HTrace passes if valid or render it otherwise + if (requestForwardGBufferRender == false) + { + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, nativeGBuffer0); + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, nativeGBuffer1); + cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, renderLayerMask); + } + else + { + + if (HRendererURP.RenderGraphEnabled) + GBufferMRT = new RenderTargetIdentifier[] { data.ForwardGBuffer0Texture, data.ForwardGBuffer1Texture, data.ForwardGBuffer2Texture, data.ForwardGBuffer3Texture, data.ForwardGBufferDepthTexture, data.ForwardRenderLayerMaskTexture }; + else + GBufferMRT = new RenderTargetIdentifier[] { data.ForwardGBuffer0Texture, data.ForwardGBuffer1Texture, data.ForwardGBuffer2Texture, data.ForwardGBuffer3Texture, data.ForwardRenderLayerMaskTexture }; + + // If CameraDepthBuffer.rt doesn't work for any reason - we can replace it with our ForwardGBufferDepth.rt, but GBuffer rendering performance will suffer. + CoreUtils.SetRenderTarget(cmd, GBufferMRT, cameraDepthBuffer.rt, ClearFlag.Color); + bool gbufferNormalsOctKeywordState = Shader.IsKeywordEnabled(HShaderParams._GBUFFER_NORMALS_OCT); + bool renderLayerKeywordState = Shader.IsKeywordEnabled(HShaderParams._WRITE_RENDERING_LAYERS); + CoreUtils.SetKeyword(cmd, HShaderParams._GBUFFER_NORMALS_OCT, true); + CoreUtils.SetKeyword(cmd, HShaderParams._WRITE_RENDERING_LAYERS, true); + + // ---------------------------------- Render Graph Version + cmd.DrawRendererList(forwardGBufferRendererListHandle); + CoreUtils.SetKeyword(cmd, HShaderParams._GBUFFER_NORMALS_OCT, gbufferNormalsOctKeywordState); + CoreUtils.SetKeyword(cmd, HShaderParams._WRITE_RENDERING_LAYERS, renderLayerKeywordState); + + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer0, data.ForwardGBuffer0Texture); + cmd.SetGlobalTexture(HShaderParams.g_HTraceGBuffer1, data.ForwardGBuffer1Texture); + cmd.SetGlobalTexture(HShaderParams.g_HTraceRenderLayerMask, data.ForwardRenderLayerMaskTexture); + } + } + } +#endif + #endregion --------------------------- Render Graph --------------------------- + + #region --------------------------- Shared --------------------------- + + protected internal void Dispose() + { + Dummy?.Release(); + ForwardGBuffer0?.Release(); + ForwardGBuffer1?.Release(); + ForwardGBuffer2?.Release(); + ForwardGBuffer3?.Release(); + ForwardRenderLayerMask?.Release(); + ForwardGBufferDepth?.Release(); + DepthPyramidRT?.Release(); + } + + #endregion --------------------------- Shared --------------------------- + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/GBufferPassURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/URP/GBufferPassURP.cs.meta new file mode 100644 index 000000000..a419c54fd --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/GBufferPassURP.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e27e4181a1204347ba674e80b4f648e4 +timeCreated: 1759390384 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/URP/GBufferPassURP.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/LightClusterPassURP.cs b/Assets/External/HTraceWSGI/Scripts/Passes/URP/LightClusterPassURP.cs new file mode 100644 index 000000000..b03adb01f --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/LightClusterPassURP.cs @@ -0,0 +1,131 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Passes.Shared; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +#if UNITY_2023_3_OR_NEWER +using HTraceWSGI.Scripts.Services.LightsCluster; +using UnityEngine.Rendering.RenderGraphModule; +#endif + +namespace HTraceWSGI.Scripts.Passes.URP +{ + internal class LightClusterPassURP : ScriptableRenderPass + { + const string _OutputTarget = "_OutputTarget"; + private static string s_motionVectorsKeyword = "MOTION_VECTORS"; + + // Shader properties + private static readonly int AmbientOcclusionParam = Shader.PropertyToID("_AmbientOcclusionParam"); + private static readonly int DebugSwitch = Shader.PropertyToID("_DebugSwitch"); + private static readonly int BuffersSwitch = Shader.PropertyToID("_BuffersSwitch"); + private static readonly int Debug_Output = Shader.PropertyToID("_Debug_Output"); + + internal static ComputeShader VoxelVisualization; + internal static Material VoxelVisualizationMaterial; + + // Buffers & etc + internal static ComputeShader HDebug = null; + + // Textures + internal static RTHandle OutputTarget; + + #region --------------------------- Render Graph --------------------------- + +#if UNITY_2023_3_OR_NEWER + private class PassData + { + public UniversalCameraData UniversalCameraData; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_LIGHT_CLUSTER_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_LIGHT_CLUSTER_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + UniversalRenderingData universalRenderingData = frameData.Get(); + UniversalLightData lightData = frameData.Get(); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(false); + + passData.UniversalCameraData = universalCameraData; + + if (Shared.LightClusterShared.HLightCluster == null) Shared.LightClusterShared.HLightCluster = HExtensions.LoadComputeShader($"HLightClusterURP", HRenderPipeline.URP); + + int width = (int)(universalCameraData.camera.scaledPixelWidth * universalCameraData.renderScale); + int height = (int)(universalCameraData.camera.scaledPixelHeight * universalCameraData.renderScale); + Allocation(width, height, universalCameraData.cameraTargetDescriptor); //resourceData.activeColorTexture.GetDescriptor(renderGraph) + + builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); + } + } + + internal static void Allocation(int width, int height, RenderTextureDescriptor desc, bool onlyRelease = false) + { + void ReleaseTextures() + { + Shared.LightClusterShared.SceneLightsBuffer.HRelease(); + Shared.LightClusterShared.LightDatasCompactedBuffer.HRelease(); + Shared.LightClusterShared.LightClusterDebugBuffer.HRelease(); + Shared.LightClusterShared.LightClusterIndexesBuffer.HRelease(); + Shared.LightClusterShared.LightClusterCounterBuffer.HRelease(); + Shared.LightClusterShared.SceneLightsBuffer = null; + Shared.LightClusterShared.LightDatasCompactedBuffer = null; + Shared.LightClusterShared.LightClusterDebugBuffer = null; + Shared.LightClusterShared.LightClusterIndexesBuffer = null; + Shared.LightClusterShared.LightClusterCounterBuffer = null; + } + + if (onlyRelease) + { + ReleaseTextures(); + return; + } + + Shared.LightClusterShared.MaxPunctualLightOnScreen = 100; + + if (Shared.LightClusterShared.SceneLightsBuffer == null) Shared.LightClusterShared.SceneLightsBuffer = new ComputeBuffer(Shared.LightClusterShared.MaxPunctualLightOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightService.LightInfo))); + if (Shared.LightClusterShared.LightDatasCompactedBuffer == null) Shared.LightClusterShared.LightDatasCompactedBuffer = new ComputeBuffer(Shared.LightClusterShared.MaxPunctualLightOnScreen, sizeof(int)); + if (Shared.LightClusterShared.LightClusterDebugBuffer == null) Shared.LightClusterShared.LightClusterDebugBuffer = new ComputeBuffer(64 * 64 * 64, sizeof(int)); + if (Shared.LightClusterShared.LightClusterIndexesBuffer == null) Shared.LightClusterShared.LightClusterIndexesBuffer = new ComputeBuffer(64 * 64 * 64 * 16, sizeof(int)); + if (Shared.LightClusterShared.LightClusterCounterBuffer == null) Shared.LightClusterShared.LightClusterCounterBuffer = new ComputeBuffer(64 * 64 * 64, sizeof(int)); + } + + private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) + { + if (HSettings.LightingSettings.EvaluatePunctualLights == false) + return; + + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); + + int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); + int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); + + Shared.LightClusterShared.Execute(cmd, data.UniversalCameraData.camera, width, height); + + Shared.LightClusterShared.History.Update(); + + } +#endif + #endregion --------------------------- Render Graph --------------------------- + + #region --------------------------- Shared --------------------------- + + + protected internal void Dispose() + { + Allocation(0,0, new RenderTextureDescriptor(), true); + } + + #endregion --------------------------- Shared --------------------------- + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/LightClusterPassURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/URP/LightClusterPassURP.cs.meta new file mode 100644 index 000000000..5476bba6c --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/LightClusterPassURP.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 7bba43ea732d4fcebc8a0e846b1ff9f3 +timeCreated: 1763042959 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/URP/LightClusterPassURP.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/MotionVectorsPassURP.cs b/Assets/External/HTraceWSGI/Scripts/Passes/URP/MotionVectorsPassURP.cs new file mode 100644 index 000000000..640292699 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/MotionVectorsPassURP.cs @@ -0,0 +1,401 @@ +//pipelinedefine +#define H_URP + +using System; +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; +#if UNITY_2023_3_OR_NEWER +using UnityEngine.Rendering.RenderGraphModule; +#else +using UnityEngine.Experimental.Rendering.RenderGraphModule; +#endif + + +namespace HTraceWSGI.Scripts.Passes.URP +{ + internal class MotionVectorsPassURP : ScriptableRenderPass + { + // Texture Names + const string _ObjectMotionVectorsColorURP = "_ObjectMotionVectorsColorURP"; + const string _ObjectMotionVectorsDepthURP = "_ObjectMotionVectorsDepthURP"; + const string _CustomCameraMotionVectorsURP_0 = "_CustomCameraMotionVectorsURP_0"; + const string _CustomCameraMotionVectorsURP_1 = "_CustomCameraMotionVectorsURP_1"; + + const string MotionVectors = "MotionVectors"; + + // Shader Properties + private static readonly int ObjectMotionVectorsColor = Shader.PropertyToID("_ObjectMotionVectors"); + private static readonly int ObjectMotionVectorsDepth = Shader.PropertyToID("_ObjectMotionVectorsDepth"); + private static readonly int BiasOffset = Shader.PropertyToID("_BiasOffset"); + + // Textures + internal static RTHandle[] CustomCameraMotionVectorsURP = new RTHandle[2]; + internal static RTHandle ObjectMotionVectorsColorURP; + internal static RTHandle ObjectMotionVectorsDepthURP; + + // Materials + private static Material MotionVectorsMaterial_URP; + internal static TextureHandle DebugMotionVectorsTextureRG; + internal static TextureHandle DebugMotionMaskTextureRG; + + + #region --------------------------- Non Render Graph --------------------------- + +#if !UNITY_6000_4_OR_NEWER + private ScriptableRenderer _renderer; + + protected internal void Initialize(ScriptableRenderer renderer) + { + _renderer = renderer; + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) + { + //renderingData.cameraData.cameraTargetDescriptor + + // if (MotionVectorsMaterial_URP == null) MotionVectorsMaterial_URP = new Material(Shader.Find($"Hidden/{HNames.ASSET_NAME}/MotionVectorsURP")); + // + // int width = (int)(renderingData.cameraData.camera.scaledPixelWidth * renderingData.cameraData.renderScale); + // int height = (int)(renderingData.cameraData.camera.scaledPixelHeight * renderingData.cameraData.renderScale); + // + // if (desc.width != width || desc.height != height) + // desc = new RenderTextureDescriptor(width, height); + // + // desc.depthBufferBits = 0; // Color and depth cannot be combined in RTHandles + // desc.stencilFormat = GraphicsFormat.None; + // desc.depthStencilFormat = GraphicsFormat.None; + // desc.msaaSamples = 1; + // desc.bindMS = false; + // desc.enableRandomWrite = true; + // + // RenderTextureDescriptor depthDesc = desc; + // depthDesc.depthBufferBits = 32; + // depthDesc.enableRandomWrite = false; + // depthDesc.colorFormat = RenderTextureFormat.Depth; + // + // ExtensionsURP.ReAllocateIfNeeded(_CustomCameraMotionVectorsURP_0, ref CustomCameraMotionVectorsURP[0], ref desc, graphicsFormat: GraphicsFormat.R16G16_SFloat); + // ExtensionsURP.ReAllocateIfNeeded(_CustomCameraMotionVectorsURP_1, ref CustomCameraMotionVectorsURP[1], ref desc, graphicsFormat: GraphicsFormat.R8_SNorm); + // ExtensionsURP.ReAllocateIfNeeded(_ObjectMotionVectorsColorURP, ref ObjectMotionVectorsColorURP, ref desc, graphicsFormat: GraphicsFormat.R16G16_SFloat); + // ExtensionsURP.ReAllocateIfNeeded(_ObjectMotionVectorsDepthURP, ref ObjectMotionVectorsDepthURP, ref depthDesc, enableRandomWrite: false); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) + { + ConfigureInput(ScriptableRenderPassInput.Motion); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + var cmd = CommandBufferPool.Get(HNames.HTRACE_MV_PASS_NAME); + + Camera camera = renderingData.cameraData.camera; + + + RenderMotionVectorsNonRenderGraph(cmd, camera, ref renderingData, ref context); + + context.ExecuteCommandBuffer(cmd); + cmd.Clear(); + CommandBufferPool.Release(cmd); + } + + private void RenderMotionVectorsNonRenderGraph(CommandBuffer cmd, Camera camera, ref RenderingData renderingData, ref ScriptableRenderContext context) + { + void RenderObjectsMotionVectors(ref RenderingData renderingData, ref ScriptableRenderContext context) + { +#if UNITY_2023_3_OR_NEWER + if (camera.cameraType == CameraType.SceneView) + return; +#endif + + CoreUtils.SetRenderTarget(cmd, ObjectMotionVectorsColorURP.rt, ClearFlag.All, Color.clear); + CoreUtils.SetRenderTarget(cmd, ObjectMotionVectorsDepthURP.rt, ClearFlag.All, Color.clear); +#if UNITY_2023_1_OR_NEWER + // We'll write not only to our own Color, but also to our own Depth target to use it later (in Camera MV) to compose per-object mv + CoreUtils.SetRenderTarget(cmd, ObjectMotionVectorsColorURP.rt, ObjectMotionVectorsDepthURP.rt); +#else + // Prior to 2023 camera motion vectors are rendered directly on objects, so we write to both motion mask and motion vectors via MRT + RenderTargetIdentifier[] motionVectorsMRT = { CustomCameraMotionVectorsURP[0].rt, CustomCameraMotionVectorsURP[1].rt,}; + CoreUtils.SetRenderTarget(cmd, motionVectorsMRT, ObjectMotionVectorsDepthURP.rt); + +#endif // UNITY_2023_1_OR_NEWER + + CullingResults cullingResults = renderingData.cullResults; + + ShaderTagId[] tags +#if UNITY_2023_1_OR_NEWER + = {new ShaderTagId("MotionVectors")}; +#else + = {new ShaderTagId("Meta")}; +#endif // UNITY_2023_1_OR_NEWER + + var renderList = new UnityEngine.Rendering.RendererUtils.RendererListDesc(tags, cullingResults, camera) + { + rendererConfiguration = PerObjectData.MotionVectors, + renderQueueRange = RenderQueueRange.opaque, + sortingCriteria = SortingCriteria.CommonOpaque, + layerMask = camera.cullingMask, + overrideMaterial +#if UNITY_2023_1_OR_NEWER + = null, +#else + = MotionVectorsMaterial_URP, + overrideMaterialPassIndex = 1, + // If somethingis wrong with our custom shader we can always use the standard one (and ShaderPass = 0) instead + // Material ObjectMotionVectorsMaterial = new Material(Shader.Find("Hidden/Universal Render Pipeline/ObjectMotionVectors")); + // overrideMaterialPassIndex = 0, +#endif //UNITY_2023_1_OR_NEWER + + }; + +#if UNITY_6000_3_OR_NEWER + CoreUtils.DrawRendererList(cmd, context.CreateRendererList(renderList)); +#else + CoreUtils.DrawRendererList(context, cmd, context.CreateRendererList(renderList)); +#endif + +#if !UNITY_2023_1_OR_NEWER + // Prior to 2023 camera motion vectors are rendered directly on objects, so we will finish mv calculation here and won't execute camera mv + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionVectors, CustomCameraMotionVectorsURP[0].rt); + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionMask, CustomCameraMotionVectorsURP[1].rt); +#endif // UNITY_2023_1_OR_NEWER + } + + + void RenderCameraMotionVectors() + { +#if UNITY_2023_1_OR_NEWER + + float DepthBiasOffset = 0; +#if UNITY_2023_1_OR_NEWER + DepthBiasOffset = 0.00099f; +#endif // UNITY_2023_1_OR_NEWER +#if UNITY_6000_0_OR_NEWER + DepthBiasOffset = 0; +#endif // UNITY_6000_0_OR_NEWER + + // Target target[0] is set as a Depth Buffer, just because this method requires Depth, but we don't care for it in the fullscreen pass + RenderTargetIdentifier[] motionVectorsMRT = { CustomCameraMotionVectorsURP[0], CustomCameraMotionVectorsURP[1]}; + CoreUtils.SetRenderTarget(cmd, motionVectorsMRT, motionVectorsMRT[0]); + + MotionVectorsMaterial_URP.SetTexture(ObjectMotionVectorsColor, ObjectMotionVectorsColorURP); + MotionVectorsMaterial_URP.SetTexture(ObjectMotionVectorsDepth, ObjectMotionVectorsDepthURP); + MotionVectorsMaterial_URP.SetFloat(BiasOffset, DepthBiasOffset); + + cmd.DrawProcedural(Matrix4x4.identity, MotionVectorsMaterial_URP, 0, MeshTopology.Triangles, 3, 1); + + // This restores color camera color target (.SetRenderTarget can be used for Forward + any Depth Priming, but doesn't work in Deferred) +#pragma warning disable CS0618 + ConfigureTarget(_renderer.cameraColorTargetHandle); +#pragma warning restore CS0618 + + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionVectors, CustomCameraMotionVectorsURP[0]); + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionMask, CustomCameraMotionVectorsURP[1]); +#endif // UNITY_2023_1_OR_NEWER + } + + RenderObjectsMotionVectors(ref renderingData, ref context); + RenderCameraMotionVectors(); + } +#endif + + #endregion --------------------------- Non Render Graph --------------------------- + + #region --------------------------- Render Graph --------------------------- + +#if UNITY_2023_3_OR_NEWER + private class PassData + { + public RendererListHandle RendererListHandle; + public TextureHandle ColorTexture; + public TextureHandle DepthTexture; + public TextureHandle MotionVectorsTexture; + public UniversalCameraData UniversalCameraData; + public TextureHandle[] CustomCameraMotionVectors = new TextureHandle[2]; + public TextureHandle ObjectMotionVectorsColor; + public TextureHandle ObjectMotionVectorsDepth; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + DebugMotionVectorsTextureRG = default(TextureHandle); + DebugMotionMaskTextureRG = default(TextureHandle); + + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_MV_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_MV_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + UniversalRenderingData universalRenderingData = frameData.Get(); + UniversalLightData lightData = frameData.Get(); + + ConfigureInput(ScriptableRenderPassInput.Motion); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(false); + + TextureHandle colorTexture = universalRenderingData.renderingMode == RenderingMode.Deferred +#if UNITY_6000_1_OR_NEWER + || universalRenderingData.renderingMode == RenderingMode.DeferredPlus +#endif + ? resourceData.activeColorTexture : resourceData.cameraColor; + TextureHandle depthTexture = universalRenderingData.renderingMode == RenderingMode.Deferred +#if UNITY_6000_1_OR_NEWER + || universalRenderingData.renderingMode == RenderingMode.DeferredPlus +#endif + ? resourceData.activeDepthTexture : resourceData.cameraDepth; + TextureHandle mvTexture = resourceData.motionVectorColor; + builder.UseTexture(colorTexture, AccessFlags.Read); + builder.UseTexture(depthTexture, AccessFlags.Read); + builder.UseTexture(mvTexture, AccessFlags.Read); + + passData.ColorTexture = colorTexture; + passData.DepthTexture = depthTexture; + passData.MotionVectorsTexture = mvTexture; + passData.UniversalCameraData = universalCameraData; + + AddRendererList(renderGraph, universalCameraData, universalRenderingData, lightData, passData, builder); + + if (MotionVectorsMaterial_URP == null) MotionVectorsMaterial_URP = new Material(Shader.Find($"Hidden/{HNames.ASSET_NAME}/MotionVectorsURP")); + + int width = (int)(universalCameraData.camera.scaledPixelWidth * universalCameraData.renderScale); + int height = (int)(universalCameraData.camera.scaledPixelHeight * universalCameraData.renderScale); + + TextureHandle colorTextureHandle = resourceData.cameraColor; + TextureDesc desc = colorTextureHandle.GetDescriptor(renderGraph); + TextureHandle depthTextureHandle = resourceData.cameraDepthTexture; + TextureDesc descDepth = depthTextureHandle.GetDescriptor(renderGraph); + desc.clearBuffer = false; + descDepth.clearBuffer = false; + + passData.CustomCameraMotionVectors[0] = ExtensionsURP.CreateTexture(_CustomCameraMotionVectorsURP_0, renderGraph, ref desc, format: GraphicsFormat.R16G16_SFloat); + passData.CustomCameraMotionVectors[1] = ExtensionsURP.CreateTexture(_CustomCameraMotionVectorsURP_1, renderGraph, ref desc, format: GraphicsFormat.R8_SNorm); + passData.ObjectMotionVectorsColor = ExtensionsURP.CreateTexture(_ObjectMotionVectorsColorURP, renderGraph, ref desc, format: GraphicsFormat.R16G16_SFloat); + passData.ObjectMotionVectorsDepth = ExtensionsURP.CreateTexture(_ObjectMotionVectorsDepthURP, renderGraph, ref descDepth, GraphicsFormat.None, depthBufferBits: DepthBits.Depth32, enableRandomWrite: false); + builder.UseTexture(passData.CustomCameraMotionVectors[0], AccessFlags.Write); + builder.UseTexture(passData.CustomCameraMotionVectors[1], AccessFlags.Write); + builder.UseTexture(passData.ObjectMotionVectorsColor, AccessFlags.Write); + builder.UseTexture(passData.ObjectMotionVectorsDepth, AccessFlags.Write); + + DebugMotionMaskTextureRG = passData.ObjectMotionVectorsColor; + DebugMotionVectorsTextureRG = universalCameraData.cameraType == CameraType.Game ? mvTexture : passData.CustomCameraMotionVectors[0]; + if (universalCameraData.cameraType != CameraType.Game) + DebugMotionMaskTextureRG = passData.CustomCameraMotionVectors[1]; + + builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); + } + } + + private static void AddRendererList(RenderGraph renderGraph, UniversalCameraData universalCameraData, UniversalRenderingData universalRenderingData, UniversalLightData lightData, PassData passData, IUnsafeRenderGraphBuilder builder) + { + SortingCriteria sortFlags = universalCameraData.defaultOpaqueSortFlags; + RenderQueueRange renderQueueRange = RenderQueueRange.opaque; + FilteringSettings filterSettings = new FilteringSettings(renderQueueRange, ~0); + + // Redraw only objects that have their LightMode tag set to UniversalForward + ShaderTagId shadersToOverride = new ShaderTagId(MotionVectors); + + // Create drawing settings + DrawingSettings drawSettings = RenderingUtils.CreateDrawingSettings(shadersToOverride, universalRenderingData, universalCameraData, lightData, sortFlags); + drawSettings.perObjectData = PerObjectData.MotionVectors; + + // Add the override material to the drawing settings + //drawSettings.overrideMaterial = materialToUse; + + // Create the list of objects to draw + var rendererListParameters = new RendererListParams(universalRenderingData.cullResults, drawSettings, filterSettings); + + // Convert the list to a list handle that the render graph system can use + passData.RendererListHandle = renderGraph.CreateRendererList(rendererListParameters); + + // Set the render target as the color and depth textures of the active camera texture + builder.UseRendererList(passData.RendererListHandle); + } + + private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); + + Camera camera = data.UniversalCameraData.camera; + + RenderMotionVectorsRenderGraph(cmd, data); + } + + private static void RenderMotionVectorsRenderGraph(CommandBuffer cmd, PassData data) + { + void RenderObjectMotionVectors() + { + // Object motion vectors can't be rendered in Scene View anyway + if (data.UniversalCameraData.cameraType == CameraType.SceneView) + { + return; + } + + cmd.SetRenderTarget(data.ObjectMotionVectorsColor, data.DepthTexture); + cmd.ClearRenderTarget(false, true, Color.black); + + cmd.DrawRendererList(data.RendererListHandle); + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionVectors, data.MotionVectorsTexture); + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionMask, data.ObjectMotionVectorsColor); + } + + void RenderCameraMotionVectors() + { + // Render Graph + Game View - no need to render camera mv, as they are already available to us in this combination + if (data.UniversalCameraData.cameraType == CameraType.Game) + { + return; + } + + float DepthBiasOffset = 0; + + // Target target[0] is set as a Depth Buffer, just because this method requires Depth, but we don't care for it in the fullscreen pass + RenderTargetIdentifier[] motionVectorsMRT = { data.CustomCameraMotionVectors[0], data.CustomCameraMotionVectors[1],}; + CoreUtils.SetRenderTarget(cmd, motionVectorsMRT, motionVectorsMRT[0]); + + MotionVectorsMaterial_URP.SetTexture(ObjectMotionVectorsColor, data.ObjectMotionVectorsColor); + MotionVectorsMaterial_URP.SetTexture(ObjectMotionVectorsDepth, data.ObjectMotionVectorsDepth); + MotionVectorsMaterial_URP.SetFloat(BiasOffset, DepthBiasOffset); + + cmd.DrawProcedural(Matrix4x4.identity, MotionVectorsMaterial_URP, 0, MeshTopology.Triangles, 3, 1); + + // This restores color camera color target (.SetRenderTarget can be used for Forward + any Depth Priming, but doesn't work in Deferred) + cmd.SetRenderTarget(data.ColorTexture); + + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionVectors, data.CustomCameraMotionVectors[0]); + cmd.SetGlobalTexture(HShaderParams.g_HTraceMotionMask, data.CustomCameraMotionVectors[1]); + } + + RenderObjectMotionVectors(); + RenderCameraMotionVectors(); + } +#endif + + #endregion --------------------------- Render Graph --------------------------- + + #region --------------------------- Share --------------------------- + + protected internal void Dispose() + { + // Not Render Graph + CustomCameraMotionVectorsURP[0]?.Release(); + CustomCameraMotionVectorsURP[1]?.Release(); + ObjectMotionVectorsColorURP?.Release(); + ObjectMotionVectorsDepthURP?.Release(); + } + + #endregion --------------------------- Share --------------------------- + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/MotionVectorsPassURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/URP/MotionVectorsPassURP.cs.meta new file mode 100644 index 000000000..c24708c95 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/MotionVectorsPassURP.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: e518e120e79148fa9571df79110cb213 +timeCreated: 1759390518 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/URP/MotionVectorsPassURP.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/PrePassURP.cs b/Assets/External/HTraceWSGI/Scripts/Passes/URP/PrePassURP.cs new file mode 100644 index 000000000..b1a1c5cd6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/PrePassURP.cs @@ -0,0 +1,224 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Extensions.CameraHistorySystem; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Passes.Shared; +using UnityEngine; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +#if UNITY_2023_3_OR_NEWER +using UnityEngine.Rendering.RenderGraphModule; +#endif + +namespace HTraceWSGI.Scripts.Passes.URP +{ + internal class PrePassURP : ScriptableRenderPass + { + private static Vector4 s_HRenderScalePrevious = Vector4.one; + + private struct HistoryCameraData : ICameraHistoryData + { + private int hash; + public Matrix4x4 previousViewProjMatrix; + public Matrix4x4 previousInvViewProjMatrix; + + public int GetHash() => hash; + public void SetHash(int hashIn) => this.hash = hashIn; + } + + private static readonly CameraHistorySystem CameraHistorySystem = new CameraHistorySystem(); + private static int s_FrameCount = 0; + + #region --------------------------- Non Render Graph --------------------------- + +#if !UNITY_6000_4_OR_NEWER + private ScriptableRenderer _renderer; + + protected internal void Initialize(ScriptableRenderer renderer) + { + _renderer = renderer; + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) + { + Camera camera = renderingData.cameraData.camera; + + CameraHistorySystem.UpdateCameraHistoryIndex(camera.GetHashCode()); + CameraHistorySystem.UpdateCameraHistoryData(); + CameraHistorySystem.GetCameraData().SetHash(camera.GetHashCode()); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) + { + ConfigureInput(ScriptableRenderPassInput.Depth); // | ScriptableRenderPassInput.Normal); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + var cmd = CommandBufferPool.Get(HNames.HTRACE_PRE_PASS_NAME); + + Camera camera = renderingData.cameraData.camera; + + var cameraDepthTexture = Shader.GetGlobalTexture(HShaderParams.g_CameraDepthTexture); + var cameraNormalsTexture = Shader.GetGlobalTexture(HShaderParams.g_CameraNormalsTexture); + if (cameraDepthTexture == null) + Shader.SetGlobalTexture(HShaderParams.g_CameraDepthTexture, HRenderer.EmptyTexture); + if (cameraNormalsTexture == null) + Shader.SetGlobalTexture(HShaderParams.g_CameraNormalsTexture, HRenderer.EmptyTexture); + + // -------------- HRenderScale ----------------- + // Unity's _RTHandleScale in URP always (1,1,1,1)? We need to overwrite it anyway... + cmd.SetGlobalVector(HShaderParams.HRenderScalePrevious, s_HRenderScalePrevious); + //s_HRenderScalePrevious = new Vector4(RTHandles.rtHandleProperties.rtHandleScale.x, RTHandles.rtHandleProperties.rtHandleScale.y, 1 / RTHandles.rtHandleProperties.rtHandleScale.x, 1 / RTHandles.rtHandleProperties.rtHandleScale.y); //we don't needed it more + cmd.SetGlobalVector(HShaderParams.HRenderScale, s_HRenderScalePrevious); + + // -------------- Matrix ----------------- + + Matrix4x4 projMatrix = GL.GetGPUProjectionMatrix(camera.projectionMatrix, true); //renderingData.cameraData.GetGPUProjectionMatrix(); + Matrix4x4 viewMatrix = renderingData.cameraData.GetViewMatrix(); + Matrix4x4 viewProjMatrix = projMatrix * viewMatrix; + Matrix4x4 invViewProjMatrix = Matrix4x4.Inverse(viewProjMatrix); + { + cmd.SetGlobalMatrix(HShaderParams.H_MATRIX_VP, viewProjMatrix); + cmd.SetGlobalMatrix(HShaderParams.H_MATRIX_I_VP, invViewProjMatrix); + ref var previousViewProjMatrix = ref CameraHistorySystem.GetCameraData().previousViewProjMatrix; + cmd.SetGlobalMatrix(HShaderParams.H_MATRIX_PREV_VP, previousViewProjMatrix); + ref var previousInvViewProjMatrix = ref CameraHistorySystem.GetCameraData().previousInvViewProjMatrix; + cmd.SetGlobalMatrix(HShaderParams.H_MATRIX_PREV_I_VP, previousInvViewProjMatrix); + + previousViewProjMatrix = viewProjMatrix; + previousInvViewProjMatrix = invViewProjMatrix; + CameraHistorySystem.GetCameraData().SetHash(camera.GetHashCode()); + + // HistoryCameraData currentData = CameraHistorySystem.GetCameraData(); + // currentData.previousViewProjMatrix = viewProjMatrix; + // currentData.previousInvViewProjMatrix = invViewProjMatrix; + // CameraHistorySystem.SetCameraData(currentData); + } + + + // -------------- Other ----------------- + cmd.SetGlobalInt(HShaderParams.FrameCount, s_FrameCount); + s_FrameCount++; + // Unity's blue noise is unreliable, so we'll use ours in all pipelines + HBlueNoiseShared.SetTextures(cmd); + + context.ExecuteCommandBuffer(cmd); + cmd.Clear(); + CommandBufferPool.Release(cmd); + } +#endif + + #endregion --------------------------- Non Render Graph --------------------------- + + #region --------------------------- Render Graph --------------------------- + +#if UNITY_2023_3_OR_NEWER + private class PassData + { + public RendererListHandle RendererListHandle; + public UniversalCameraData UniversalCameraData; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_PRE_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_PRE_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + UniversalRenderingData universalRenderingData = frameData.Get(); + UniversalLightData lightData = frameData.Get(); + + ConfigureInput(ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(false); + + passData.UniversalCameraData = universalCameraData; + + Camera camera = universalCameraData.camera; + + CameraHistorySystem.UpdateCameraHistoryIndex(camera.GetHashCode()); + CameraHistorySystem.UpdateCameraHistoryData(); + CameraHistorySystem.GetCameraData().SetHash(camera.GetHashCode()); + + builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); + } + } + + private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); + + Camera camera = data.UniversalCameraData.camera; + + var cameraDepthTexture = Shader.GetGlobalTexture(HShaderParams.g_CameraDepthTexture); + var cameraNormalsTexture = Shader.GetGlobalTexture(HShaderParams.g_CameraNormalsTexture); + if (cameraDepthTexture == null) + Shader.SetGlobalTexture(HShaderParams.g_CameraDepthTexture, HRenderer.EmptyTexture); + if (cameraNormalsTexture == null) + Shader.SetGlobalTexture(HShaderParams.g_CameraNormalsTexture, HRenderer.EmptyTexture); + + + // -------------- HRenderScale ----------------- + // Unity's _RTHandleScale in URP always (1,1,1,1)? We need to overwrite it anyway... + cmd.SetGlobalVector(HShaderParams.HRenderScalePrevious, s_HRenderScalePrevious); + //s_HRenderScalePrevious = new Vector4(RTHandles.rtHandleProperties.rtHandleScale.x, RTHandles.rtHandleProperties.rtHandleScale.y, 1 / RTHandles.rtHandleProperties.rtHandleScale.x, 1 / RTHandles.rtHandleProperties.rtHandleScale.y); //we don't needed it more + cmd.SetGlobalVector(HShaderParams.HRenderScale, s_HRenderScalePrevious); + + // -------------- Matrix ----------------- + + Matrix4x4 projMatrix = GL.GetGPUProjectionMatrix(camera.projectionMatrix, true); //renderingData.cameraData.GetGPUProjectionMatrix(); + Matrix4x4 viewMatrix = data.UniversalCameraData.GetViewMatrix(); + Matrix4x4 viewProjMatrix = projMatrix * viewMatrix; + Matrix4x4 invViewProjMatrix = Matrix4x4.Inverse(viewProjMatrix); + { + cmd.SetGlobalMatrix(HShaderParams.H_MATRIX_VP, viewProjMatrix); + cmd.SetGlobalMatrix(HShaderParams.H_MATRIX_I_VP, invViewProjMatrix); + ref var previousViewProjMatrix = ref CameraHistorySystem.GetCameraData().previousViewProjMatrix; + cmd.SetGlobalMatrix(HShaderParams.H_MATRIX_PREV_VP, previousViewProjMatrix); + ref var previousInvViewProjMatrix = ref CameraHistorySystem.GetCameraData().previousInvViewProjMatrix; + cmd.SetGlobalMatrix(HShaderParams.H_MATRIX_PREV_I_VP, previousInvViewProjMatrix); + + previousViewProjMatrix = viewProjMatrix; + previousInvViewProjMatrix = invViewProjMatrix; + CameraHistorySystem.GetCameraData().SetHash(camera.GetHashCode()); + + // HistoryCameraData currentData = CameraHistorySystem.GetCameraData(); + // currentData.previousViewProjMatrix = viewProjMatrix; + // currentData.previousInvViewProjMatrix = invViewProjMatrix; + // CameraHistorySystem.SetCameraData(currentData); + } + + // -------------- Other ----------------- + cmd.SetGlobalInt(HShaderParams.FrameCount, s_FrameCount); + s_FrameCount++; + // Unity's blue noise is unreliable, so we'll use ours in all pipelines + HBlueNoiseShared.SetTextures(cmd); + + // Dummy buffers for Debug + cmd.SetGlobalTexture(HShaderParams.g_HTraceBufferGI, rgContext.defaultResources.blackTexture); + cmd.SetGlobalTexture(HShaderParams.g_GeometryNormal, rgContext.defaultResources.blackTexture); + cmd.SetGlobalTexture(HShaderParams.g_LightClusterDebug, rgContext.defaultResources.blackTexture); + } +#endif + + #endregion --------------------------- Render Graph --------------------------- + + protected internal void Dispose() + { + s_FrameCount = 0; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/PrePassURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/URP/PrePassURP.cs.meta new file mode 100644 index 000000000..cb0a1b235 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/PrePassURP.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 98756599e78ee554293159f5afc70dfe +timeCreated: 1729952288 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/URP/PrePassURP.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/SoftwareTracingPassURP.cs b/Assets/External/HTraceWSGI/Scripts/Passes/URP/SoftwareTracingPassURP.cs new file mode 100644 index 000000000..5e9859d33 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/SoftwareTracingPassURP.cs @@ -0,0 +1,623 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using HTraceWSGI.Scripts.Passes.Shared; +using HTraceWSGI.Scripts.Wrappers; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +#if UNITY_2023_3_OR_NEWER +using UnityEngine.Rendering.RenderGraphModule; +#endif + +namespace HTraceWSGI.Scripts.Passes.URP +{ + internal class SoftwareTracingPassURP : ScriptableRenderPass + { + private static readonly int _CameraNormalsTexture = Shader.PropertyToID("_CameraNormalsTexture"); + public static readonly int _IndirectLightingIntensity = Shader.PropertyToID("_IndirectLightingIntensity"); + public static readonly int _MetallicIndirectFallback = Shader.PropertyToID("_MetallicIndirectFallback"); + public static readonly int _ColorCopy = Shader.PropertyToID("_ColorCopy"); + public static readonly int _SampleCountWSGI = Shader.PropertyToID("_SampleCountSSGI"); + public static readonly string USE_RECEIVE_LAYER_MASK = "USE_RECEIVE_LAYER_MASK"; + + public static Material ColorCompose; + private static bool _forceHashBufferRecreateOnNextAllocation = true; + + public static ProfilingSamplerHTrace AmbientLightingOverrideSampler = new ProfilingSamplerHTrace("Ambient Lighting Override"); + public static ProfilingSamplerHTrace IndirectLightingInjectionSampler = new ProfilingSamplerHTrace("Indirect Lighting Injection"); + + #region --------------------------- Non Render Graph --------------------------- + +#if !UNITY_6000_4_OR_NEWER + private ScriptableRenderer _renderer; + + protected internal void Initialize(ScriptableRenderer renderer) + { + _renderer = renderer; + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) + { + //SetupShared(renderingData.cameraData.camera, renderingData.cameraData.renderScale, renderingData.cameraData.cameraTargetDescriptor); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) + { + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + + Camera camera = renderingData.cameraData.camera; + + var cmd = CommandBufferPool.Get(HNames.HTRACE_FINAL_PASS_NAME); + + int width = (int)(camera.scaledPixelWidth * renderingData.cameraData.renderScale); + int height = (int)(camera.scaledPixelHeight * renderingData.cameraData.renderScale); + + context.ExecuteCommandBuffer(cmd); + cmd.Clear(); + CommandBufferPool.Release(cmd); + } +#endif + + #endregion --------------------------- Non Render Graph --------------------------- + + #region --------------------------- Render Graph --------------------------- + +#if UNITY_2023_3_OR_NEWER + private class PassData + { + public UniversalCameraData UniversalCameraData; + public TextureHandle ColorTexture; + public TextureHandle ColorCopy; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME, out var passData, new ProfilingSampler(HNames.HTRACE_SOFTWARE_TRACING_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + UniversalRenderingData universalRenderingData = frameData.Get(); + UniversalLightData lightData = frameData.Get(); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(false); + + TextureHandle colorTexture = universalRenderingData.renderingMode == RenderingMode.Deferred +#if UNITY_6000_1_OR_NEWER + || universalRenderingData.renderingMode == RenderingMode.DeferredPlus +#endif + ? resourceData.activeColorTexture : resourceData.cameraColor; + builder.UseTexture(colorTexture, AccessFlags.Write); + + passData.UniversalCameraData = universalCameraData; + passData.ColorTexture = colorTexture; + + if (ColorCompose == null) ColorCompose = new Material(Shader.Find($"Hidden/{HNames.ASSET_NAME}/ColorComposeURP")); + if (SoftwareTracingShared.HReservoirValidation == null) SoftwareTracingShared.HReservoirValidation = HExtensions.LoadComputeShader("HReservoirValidation"); + if (SoftwareTracingShared.HTracingScreenSpace == null) SoftwareTracingShared.HTracingScreenSpace = HExtensions.LoadComputeShader("HTracingScreenSpace"); + if (SoftwareTracingShared.HTracingWorldSpace == null) SoftwareTracingShared.HTracingWorldSpace = HExtensions.LoadComputeShader("HTracingWorldSpace"); + if (SoftwareTracingShared.HRadianceCache == null) SoftwareTracingShared.HRadianceCache = HExtensions.LoadComputeShader("HRadianceCache"); + if (SoftwareTracingShared.HTemporalReprojection == null) SoftwareTracingShared.HTemporalReprojection = HExtensions.LoadComputeShader("HTemporalReprojection"); + if (SoftwareTracingShared.HSpatialPrepass == null) SoftwareTracingShared.HSpatialPrepass = HExtensions.LoadComputeShader("HSpatialPrepass"); + if (SoftwareTracingShared.HProbeAmbientOcclusion == null) SoftwareTracingShared.HProbeAmbientOcclusion = HExtensions.LoadComputeShader("HProbeAmbientOcclusion"); + if (SoftwareTracingShared.HReSTIR == null) SoftwareTracingShared.HReSTIR = HExtensions.LoadComputeShader("HReSTIR"); + if (SoftwareTracingShared.HCopy == null) SoftwareTracingShared.HCopy = HExtensions.LoadComputeShader("HCopy"); + if (SoftwareTracingShared.HRayGeneration == null) SoftwareTracingShared.HRayGeneration = HExtensions.LoadComputeShader("HRayGeneration"); + if (SoftwareTracingShared.HRenderAO == null) SoftwareTracingShared.HRenderAO = HExtensions.LoadComputeShader("HRenderAO"); + if (SoftwareTracingShared.HDebugPassthrough == null) SoftwareTracingShared.HDebugPassthrough = HExtensions.LoadComputeShader("HDebugPassthrough"); + if (SoftwareTracingShared.HInterpolation == null) SoftwareTracingShared.HInterpolation = HExtensions.LoadComputeShader("HInterpolation"); + if (SoftwareTracingShared.HTemporalDenoiser == null) SoftwareTracingShared.HTemporalDenoiser = HExtensions.LoadComputeShader("HTemporalDenoiser"); + + int width = (int)(universalCameraData.camera.scaledPixelWidth * universalCameraData.renderScale); + int height = (int)(universalCameraData.camera.scaledPixelHeight * universalCameraData.renderScale); + Allocation(width, height, universalCameraData.cameraTargetDescriptor); //resourceData.activeColorTexture.GetDescriptor(renderGraph) + + TextureHandle colorTextureHandle = colorTexture; + TextureDesc textureDesc = colorTextureHandle.GetDescriptor(renderGraph); + textureDesc.clearBuffer = false; + textureDesc.colorFormat = GraphicsFormat.R16G16B16A16_SFloat; + textureDesc.name = "_ColorCopy"; + passData.ColorCopy = renderGraph.CreateTexture(textureDesc); + builder.UseTexture(passData.ColorCopy, AccessFlags.ReadWrite); + + //SoftwareTracingShared.SkipFirstFrame = true; + + builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); + } + } + + private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); + + int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); + int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); + + if (Shader.GetGlobalTexture(_CameraNormalsTexture) == null) //TODO: do we need it? + return; + + // ---------------------------------------- AMBIENT LIGHTING OVERRIDE ---------------------------------------- // + using (new HTraceProfilingScope(cmd, AmbientLightingOverrideSampler)) + { + cmd.SetGlobalFloat(_IndirectLightingIntensity, HSettings.GeneralSettings.Intensity); + + if (HSettings.GeneralSettings.AmbientOverride) + { + // Copy Color buffer + CoreUtils.SetRenderTarget(cmd, data.ColorCopy); + cmd.DrawProcedural(Matrix4x4.identity, ColorCompose, 0, MeshTopology.Triangles, 3, 1); + + // Subtract indirect lighting from Color buffer + CoreUtils.SetRenderTarget(cmd, data.ColorTexture); + ColorCompose.SetTexture(_ColorCopy, data.ColorCopy); + cmd.DrawProcedural(Matrix4x4.identity, ColorCompose, 1, MeshTopology.Triangles, 3, 1); + } + + // Early out if we want to preview direct lighting only + if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.DirectLighting) + { + return; + } + } + + SoftwareTracingShared.Execute(cmd, data.UniversalCameraData.camera, width, height, data.ColorTexture, SoftwareTracingShared.ColorPreviousFrame.rt, Shader.GetGlobalTexture("g_HTraceGBuffer0")); + + // ---------------------------------------- INDIRECT LIGHTING INJECTION ---------------------------------------- // + + using (new HTraceProfilingScope(cmd, IndirectLightingInjectionSampler)) + { + // Copy color buffer + indirect lighting (without intensity multiplication) for multibounce + cmd.SetComputeTextureParam(SoftwareTracingShared.HTemporalReprojection, (int)SoftwareTracingShared.HTemporalReprojectionKernel.CopyHistoryURP, HShaderParams._Radiance_Output, SoftwareTracingShared.ColorPreviousFrame.rt); + cmd.DispatchCompute(SoftwareTracingShared.HTemporalReprojection, (int)SoftwareTracingShared.HTemporalReprojectionKernel.CopyHistoryURP, Mathf.CeilToInt(width / 8.0f), Mathf.CeilToInt(height / 8.0f), HRenderer.TextureXrSlices); + + // Inject final indirect lighting (with intensity multiplication) into color buffer via additive blending + CoreUtils.SetRenderTarget(cmd, data.ColorTexture); + ColorCompose.SetInt(_MetallicIndirectFallback, HSettings.GeneralSettings.MetallicIndirectFallback ? 1 : 0); + cmd.DrawProcedural(Matrix4x4.identity, ColorCompose, 2, MeshTopology.Triangles, 3, 1); + } + + SoftwareTracingShared.History.Update(); + } + + internal static void Allocation(int width, int height, RenderTextureDescriptor desc, bool onlyRelease = false) + { + AllocateMainRT(width, height, desc, onlyRelease); + AllocateSSAO_RT(width, height, desc, onlyRelease); + AllocationHashBuffers(onlyRelease, _forceHashBufferRecreateOnNextAllocation); + AllocateDebugRT(width, height, desc, onlyRelease); + AllocateIndirectionBuffers(width, height, onlyRelease); + + _forceHashBufferRecreateOnNextAllocation = onlyRelease; + } + + internal static void RequestHashBufferRecreate() + { + _forceHashBufferRecreateOnNextAllocation = true; + } + + internal static void AllocateMainRT(int width, int height, RenderTextureDescriptor desc, bool onlyRelease = false) + { + void ReleaseTextures() + { + SoftwareTracingShared.ColorPreviousFrame.HRelease(); + + SoftwareTracingShared.VoxelPayload.HRelease(); + SoftwareTracingShared.RayDirections.HRelease(); + SoftwareTracingShared.HitRadiance.HRelease(); + SoftwareTracingShared.HitDistanceScreenSpace.HRelease(); + SoftwareTracingShared.HitDistanceWorldSpace.HRelease(); + SoftwareTracingShared.HitCoordScreenSpace.HRelease(); + + SoftwareTracingShared.ProbeAmbientOcclusion.HRelease(); + SoftwareTracingShared.ProbeAmbientOcclusion_History.HRelease(); + SoftwareTracingShared.ProbeAmbientOcclusion_Filtered.HRelease(); + + SoftwareTracingShared.GeometryNormal.HRelease(); + SoftwareTracingShared.NormalDepth_History.HRelease(); + SoftwareTracingShared.ProbeNormalDepth.HRelease(); + SoftwareTracingShared.ProbeNormalDepth_History.HRelease(); + SoftwareTracingShared.ProbeWorldPosNormal_History.HRelease(); + SoftwareTracingShared.ProbeNormalDepth_Intermediate.HRelease(); + SoftwareTracingShared.ProbeDiffuse.HRelease(); + + SoftwareTracingShared.HistoryIndirection.HRelease(); + SoftwareTracingShared.ReprojectionWeights.HRelease(); + SoftwareTracingShared.PersistentReprojectionWeights.HRelease(); + SoftwareTracingShared.ReprojectionCoord.HRelease(); + SoftwareTracingShared.PersistentReprojectionCoord.HRelease(); + + SoftwareTracingShared.SpatialOffsetsPacked.HRelease(); + SoftwareTracingShared.SpatialWeightsPacked.HRelease(); + + SoftwareTracingShared.ReservoirAtlas.HRelease(); + SoftwareTracingShared.ReservoirAtlas_History.HRelease(); + SoftwareTracingShared.ReservoirAtlasRadianceData_A.HRelease(); + SoftwareTracingShared.ReservoirAtlasRadianceData_B.HRelease(); + SoftwareTracingShared.ReservoirAtlasRadianceData_C.HRelease(); + SoftwareTracingShared.ReservoirAtlasRayData_A.HRelease(); + SoftwareTracingShared.ReservoirAtlasRayData_B.HRelease(); + SoftwareTracingShared.ReservoirAtlasRayData_C.HRelease(); + + SoftwareTracingShared.ShadowGuidanceMask.HRelease(); + SoftwareTracingShared.ShadowGuidanceMask_Accumulated.HRelease(); + SoftwareTracingShared.ShadowGuidanceMask_Filtered.HRelease(); + SoftwareTracingShared.ShadowGuidanceMask_History.HRelease(); + SoftwareTracingShared.ShadowGuidanceMask_CheckerboardHistory.HRelease(); + SoftwareTracingShared.ShadowGuidanceMask_Samplecount.HRelease(); + SoftwareTracingShared.ShadowGuidanceMask_SamplecountHistory.HRelease(); + + SoftwareTracingShared.PackedSH_A.HRelease(); + SoftwareTracingShared.PackedSH_B.HRelease(); + SoftwareTracingShared.Radiance_Interpolated.HRelease(); + + SoftwareTracingShared.RadianceAccumulated.HRelease(); + SoftwareTracingShared.RadianceAccumulated_History.HRelease(); + SoftwareTracingShared.LuminanceDelta.HRelease(); + SoftwareTracingShared.LuminanceDelta_History.HRelease(); + + SoftwareTracingShared.RadianceCacheFiltered.HRelease(); + + SoftwareTracingShared.RayCounter.HRelease(); + SoftwareTracingShared.RayCounterWS.HRelease(); + SoftwareTracingShared.IndirectArgumentsSS.HRelease(); + SoftwareTracingShared.IndirectArgumentsWS.HRelease(); + SoftwareTracingShared.IndirectArgumentsOV.HRelease(); + SoftwareTracingShared.IndirectArgumentsSF.HRelease(); + + SoftwareTracingShared.RayCounter = null; + SoftwareTracingShared.RayCounterWS = null; + SoftwareTracingShared.IndirectArgumentsSS = null; + SoftwareTracingShared.IndirectArgumentsWS = null; + SoftwareTracingShared.IndirectArgumentsOV = null; + SoftwareTracingShared.IndirectArgumentsSF = null; + + SoftwareTracingShared.PointDistributionBuffer.HRelease(); + SoftwareTracingShared.SpatialOffsetsBuffer.HRelease(); + + SoftwareTracingShared.PointDistributionBuffer = null; + SoftwareTracingShared.SpatialOffsetsBuffer = null; + + SoftwareTracingShared.HashBuffer_Key.HRelease(); + SoftwareTracingShared.HashBuffer_Payload.HRelease(); + SoftwareTracingShared.HashBuffer_Counter.HRelease(); + SoftwareTracingShared.HashBuffer_Radiance.HRelease(); + SoftwareTracingShared.HashBuffer_Position.HRelease(); + + SoftwareTracingShared.HashBuffer_Key = null; + SoftwareTracingShared.HashBuffer_Payload = null; + SoftwareTracingShared.HashBuffer_Counter = null; + SoftwareTracingShared.HashBuffer_Radiance = null; + SoftwareTracingShared.HashBuffer_Position = null; + } + + if (onlyRelease) + { + ReleaseTextures(); + return; + } + + Vector2Int fullRes = new Vector2Int(width, height); + float probeSize = (float)HSettings.GeneralSettings.RayCountMode.ParseToProbeSize(); + Vector2Int probeRes = new Vector2Int(Mathf.RoundToInt(width / probeSize), Mathf.RoundToInt(height / probeSize)); + Vector2Int probeAtlasRes = new Vector2Int(Mathf.RoundToInt(width / probeSize * (float)HConstants.OCTAHEDRAL_SIZE), Mathf.RoundToInt(height / probeSize * (float)HConstants.OCTAHEDRAL_SIZE)); + + TextureDimension originalTextureDimension = desc.dimension; + RenderTextureDescriptor fullResDesc = desc; + fullResDesc.enableRandomWrite = true; + fullResDesc.depthStencilFormat = GraphicsFormat.None; + + RenderTextureDescriptor probeDesc = desc; + probeDesc.width = probeRes.x; + probeDesc.height = probeRes.y; + probeDesc.enableRandomWrite = true; + probeDesc.depthStencilFormat = GraphicsFormat.None; + + RenderTextureDescriptor probeAtlasDesc = desc; + probeAtlasDesc.width = probeAtlasRes.x; + probeAtlasDesc.height = probeAtlasRes.y; + probeAtlasDesc.enableRandomWrite = true; + probeAtlasDesc.depthStencilFormat = GraphicsFormat.None; + + // -------------------------------------- BUFFERS -------------------------------------- // + + // Indirection dispatch buffers + if (SoftwareTracingShared.RayCounter == null) SoftwareTracingShared.RayCounter = new ComputeBuffer(10 * HRenderer.TextureXrSlices, sizeof(uint)); + if (SoftwareTracingShared.RayCounterWS == null) SoftwareTracingShared.RayCounterWS = new ComputeBuffer(10 * HRenderer.TextureXrSlices, sizeof(uint)); + if (SoftwareTracingShared.IndirectArgumentsSS == null) SoftwareTracingShared.IndirectArgumentsSS = new ComputeBuffer(3 * HRenderer.TextureXrSlices, sizeof(uint), ComputeBufferType.IndirectArguments); + if (SoftwareTracingShared.IndirectArgumentsWS == null) SoftwareTracingShared.IndirectArgumentsWS = new ComputeBuffer(3 * HRenderer.TextureXrSlices, sizeof(uint), ComputeBufferType.IndirectArguments); + if (SoftwareTracingShared.IndirectArgumentsOV == null) SoftwareTracingShared.IndirectArgumentsOV = new ComputeBuffer(3 * HRenderer.TextureXrSlices, sizeof(uint), ComputeBufferType.IndirectArguments); + if (SoftwareTracingShared.IndirectArgumentsSF == null) SoftwareTracingShared.IndirectArgumentsSF = new ComputeBuffer(3 * HRenderer.TextureXrSlices, sizeof(uint), ComputeBufferType.IndirectArguments); + + // Spatial offsets buffers + if (SoftwareTracingShared.PointDistributionBuffer == null) SoftwareTracingShared.PointDistributionBuffer = new ComputeBuffer(HRenderer.TextureXrSlices * 32 * 4, 2 * sizeof(float)); + if (SoftwareTracingShared.SpatialOffsetsBuffer == null) SoftwareTracingShared.SpatialOffsetsBuffer = new ComputeBuffer(9 * 9, 2 * sizeof(int)); + + // Hash buffers + if (SoftwareTracingShared.HashBuffer_Key == null) SoftwareTracingShared.HashBuffer_Key = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE, 1 * sizeof(uint)); + if (SoftwareTracingShared.HashBuffer_Payload == null) SoftwareTracingShared.HashBuffer_Payload = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE / HConstants.HASH_UPDATE_FRACTION, 2 * sizeof(uint)); + if (SoftwareTracingShared.HashBuffer_Counter == null) SoftwareTracingShared.HashBuffer_Counter = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE, 1 * sizeof(uint)); + if (SoftwareTracingShared.HashBuffer_Radiance == null) SoftwareTracingShared.HashBuffer_Radiance = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE, 4 * sizeof(uint)); + if (SoftwareTracingShared.HashBuffer_Position == null) SoftwareTracingShared.HashBuffer_Position = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE, 4 * sizeof(uint)); + + SoftwareTracingShared.ColorPreviousFrame.ReAllocateIfNeeded(name: "_ColorPreviousFrame", ref fullResDesc, GraphicsFormat.B10G11R11_UFloatPack32); + + // -------------------------------------- TRACING RT -------------------------------------- // + SoftwareTracingShared.VoxelPayload.ReAllocateIfNeeded("_VoxelPayload", ref probeAtlasDesc, GraphicsFormat.R32G32_UInt); + SoftwareTracingShared.RayDirections.ReAllocateIfNeeded("_RayDirections", ref probeAtlasDesc, GraphicsFormat.R8G8B8A8_UNorm); + SoftwareTracingShared.HitDistanceScreenSpace.ReAllocateIfNeeded("_HitDistanceScreenSpace", ref probeAtlasDesc, GraphicsFormat.R16_UInt); + SoftwareTracingShared.HitDistanceWorldSpace.ReAllocateIfNeeded("_HitDistanceWorldSpace", ref probeAtlasDesc, GraphicsFormat.R16_SFloat); + SoftwareTracingShared.HitRadiance.ReAllocateIfNeeded("_HitRadiance", ref probeAtlasDesc, GraphicsFormat.R16G16B16A16_SFloat); + SoftwareTracingShared.HitCoordScreenSpace.ReAllocateIfNeeded("_HitCoordScreenSpace", ref fullResDesc, GraphicsFormat.R16G16_UInt); + + + // -------------------------------------- PROBE AO RT -------------------------------------- // + SoftwareTracingShared.ProbeAmbientOcclusion.ReAllocateIfNeeded("_ProbeAmbientOcclusion", ref probeDesc, GraphicsFormat.R16_UInt); + SoftwareTracingShared.ProbeAmbientOcclusion_History.ReAllocateIfNeeded("_ProbeAmbientOcclusion_History", ref probeDesc, GraphicsFormat.R16_UInt, volumeDepth: HRenderer.TextureXrSlices * HConstants.PERSISTENT_HISTORY_SAMPLES, dimension: TextureDimension.Tex2DArray); + SoftwareTracingShared.ProbeAmbientOcclusion_Filtered.ReAllocateIfNeeded("_ProbeAmbientOcclusion_Filtered", ref probeDesc, GraphicsFormat.R8_UNorm); + + + // -------------------------------------- GBUFFER RT -------------------------------------- // + SoftwareTracingShared.GeometryNormal.ReAllocateIfNeeded("_GeometryNormal", ref fullResDesc, GraphicsFormat.R16G16B16A16_SFloat); + SoftwareTracingShared.NormalDepth_History.ReAllocateIfNeeded("_NormalDepth_History", ref fullResDesc, GraphicsFormat.R32G32_UInt); + SoftwareTracingShared.ProbeNormalDepth.ReAllocateIfNeeded("_ProbeNormalDepth", ref probeDesc, GraphicsFormat.R32G32_UInt); + SoftwareTracingShared.ProbeNormalDepth_History.ReAllocateIfNeeded("_ProbeNormalDepth_History", ref probeDesc, GraphicsFormat.R32G32_UInt); + SoftwareTracingShared.ProbeWorldPosNormal_History.ReAllocateIfNeeded("_ProbeWorldPosNormal_History", ref probeDesc, GraphicsFormat.R32G32B32A32_UInt, volumeDepth: HRenderer.TextureXrSlices * HConstants.PERSISTENT_HISTORY_SAMPLES, dimension: TextureDimension.Tex2DArray); + SoftwareTracingShared.ProbeNormalDepth_Intermediate.ReAllocateIfNeeded("_ProbeNormalDepth_Intermediate", ref probeDesc, GraphicsFormat.R32G32_UInt); + SoftwareTracingShared.ProbeDiffuse.ReAllocateIfNeeded("_ProbeDiffuse", ref probeDesc, GraphicsFormat.R8G8B8A8_UNorm); + + + // -------------------------------------- REPROJECTION RT -------------------------------------- // + SoftwareTracingShared.HistoryIndirection.ReAllocateIfNeeded("_HistoryIndirection", ref probeDesc, GraphicsFormat.R16G16_UInt, volumeDepth: HRenderer.TextureXrSlices * HConstants.PERSISTENT_HISTORY_SAMPLES, dimension: TextureDimension.Tex2DArray); + SoftwareTracingShared.ReprojectionWeights.ReAllocateIfNeeded("_ReprojectionWeights", ref probeDesc, GraphicsFormat.R8G8B8A8_UNorm); + SoftwareTracingShared.PersistentReprojectionWeights.ReAllocateIfNeeded("_PersistentReprojectionWeights", ref probeDesc, GraphicsFormat.R8G8B8A8_UNorm); + SoftwareTracingShared.ReprojectionCoord.ReAllocateIfNeeded("_ReprojectionCoord", ref probeDesc, GraphicsFormat.R16G16_UInt); + SoftwareTracingShared.PersistentReprojectionCoord.ReAllocateIfNeeded("_PersistentReprojectionCoord", ref probeDesc, GraphicsFormat.R16G16_UInt); + + + // -------------------------------------- SPATIAL PREPASS RT -------------------------------------- // + SoftwareTracingShared.SpatialOffsetsPacked.ReAllocateIfNeeded("_SpatialOffsetsPacked", ref probeDesc, GraphicsFormat.R32G32B32A32_UInt, volumeDepth: HRenderer.TextureXrSlices * 4, dimension: TextureDimension.Tex2DArray); + SoftwareTracingShared.SpatialWeightsPacked.ReAllocateIfNeeded("_SpatialWeightsPacked", ref probeDesc, GraphicsFormat.R16G16B16A16_UInt, volumeDepth: HRenderer.TextureXrSlices * 4, dimension: TextureDimension.Tex2DArray); + + + // -------------------------------------- RESERVOIR RT -------------------------------------- // + SoftwareTracingShared.ReservoirAtlas.ReAllocateIfNeeded("_ReservoirAtlas", ref probeAtlasDesc, GraphicsFormat.R32G32B32A32_UInt); + SoftwareTracingShared.ReservoirAtlas_History.ReAllocateIfNeeded("_ReservoirAtlas_History", ref probeAtlasDesc, GraphicsFormat.R32G32B32A32_UInt, volumeDepth: HRenderer.TextureXrSlices * HConstants.PERSISTENT_HISTORY_SAMPLES, dimension: TextureDimension.Tex2DArray); + SoftwareTracingShared.ReservoirAtlasRadianceData_A.ReAllocateIfNeeded("_ReservoirAtlasRadianceData_A" , ref probeAtlasDesc, GraphicsFormat.R32G32_UInt); + SoftwareTracingShared.ReservoirAtlasRadianceData_B.ReAllocateIfNeeded("_ReservoirAtlasRadianceData_B", ref probeAtlasDesc, GraphicsFormat.R32G32_UInt); + SoftwareTracingShared.ReservoirAtlasRadianceData_C.ReAllocateIfNeeded("_ReservoirAtlasRadianceData_C", ref probeAtlasDesc, GraphicsFormat.R32G32_UInt); + + SoftwareTracingShared.ReservoirAtlasRayData_A.ReAllocateIfNeeded("_ReservoirAtlasRayData_A", ref probeAtlasDesc, GraphicsFormat.R32_UInt); + SoftwareTracingShared.ReservoirAtlasRayData_B.ReAllocateIfNeeded("_ReservoirAtlasRayData_B", ref probeAtlasDesc, GraphicsFormat.R32_UInt); + SoftwareTracingShared.ReservoirAtlasRayData_C.ReAllocateIfNeeded("_ReservoirAtlasRayData_C", ref probeAtlasDesc, GraphicsFormat.R32_UInt); + + + // -------------------------------------- SHADOW GUIDANCE MASK RT -------------------------------------- // + SoftwareTracingShared.ShadowGuidanceMask.ReAllocateIfNeeded("_ShadowGuidanceMask", ref probeAtlasDesc, GraphicsFormat.R8_UNorm); + SoftwareTracingShared.ShadowGuidanceMask_Accumulated.ReAllocateIfNeeded("_ShadowGuidanceMask_Accumulated", ref probeAtlasDesc, GraphicsFormat.R8_UNorm); + SoftwareTracingShared.ShadowGuidanceMask_Filtered .ReAllocateIfNeeded("_ShadowGuidanceMask_Filtered", ref probeAtlasDesc, GraphicsFormat.R8_UNorm); + SoftwareTracingShared.ShadowGuidanceMask_History.ReAllocateIfNeeded("_ShadowGuidanceMask_History", ref probeAtlasDesc, GraphicsFormat.R8_UNorm); + SoftwareTracingShared.ShadowGuidanceMask_CheckerboardHistory.ReAllocateIfNeeded("_ShadowGuidanceMask_CheckerboardHistory", ref probeAtlasDesc, GraphicsFormat.R8_UNorm); + SoftwareTracingShared.ShadowGuidanceMask_Samplecount.ReAllocateIfNeeded("_ShadowGuidanceMask_Samplecount", ref probeDesc, GraphicsFormat.R16_SFloat); + SoftwareTracingShared.ShadowGuidanceMask_SamplecountHistory.ReAllocateIfNeeded("_ShadowGuidanceMask_SamplecountHistory", ref probeDesc, GraphicsFormat.R16_SFloat); + + + // -------------------------------------- INTERPOLATION RT -------------------------------------- // + SoftwareTracingShared.PackedSH_A.ReAllocateIfNeeded("_PackedSH_A", ref probeDesc, GraphicsFormat.R32G32B32A32_UInt); + SoftwareTracingShared.PackedSH_B.ReAllocateIfNeeded("_PackedSH_B", ref probeDesc, GraphicsFormat.R32G32B32A32_UInt); + SoftwareTracingShared.Radiance_Interpolated.ReAllocateIfNeeded("_Radiance_Interpolated", ref fullResDesc, GraphicsFormat.R32_UInt); + + + // -------------------------------------- TEMPORAL DENOISER RT -------------------------------------- // + SoftwareTracingShared.RadianceAccumulated.ReAllocateIfNeeded("_RadianceAccumulated", ref fullResDesc, GraphicsFormat.R16G16B16A16_SFloat); + SoftwareTracingShared.RadianceAccumulated_History.ReAllocateIfNeeded("_RadianceAccumulated_History", ref fullResDesc, GraphicsFormat.R16G16B16A16_SFloat); + SoftwareTracingShared.LuminanceDelta.ReAllocateIfNeeded("_RadianceLumaDelta", ref fullResDesc, GraphicsFormat.R16_SFloat); + SoftwareTracingShared.LuminanceDelta_History.ReAllocateIfNeeded("_RadianceLumaDelta_History", ref fullResDesc, GraphicsFormat.R16_SFloat); + + // TODO: figure out if we need this, do not delete and do not allocate for now + // RadianceCacheFiltered.ReAllocateIfNeeded(600, 100, 100, TextureDimension.Tex3D, + // GraphicsFormat.B10G11R11_UFloatPack32, "_RadianceCacheFiltered"); + } + + internal static void AllocateSSAO_RT(int width, int height, RenderTextureDescriptor desc, bool onlyRelease = false) + { + void ReleaseTextures() + { + SoftwareTracingShared.ProbeSSAO.HRelease(); + SoftwareTracingShared.NormalDepthHalf.HRelease(); + SoftwareTracingShared.BentNormalsAO.HRelease(); + SoftwareTracingShared.BentNormalsAO_Interpolated.HRelease(); + SoftwareTracingShared.BentNormalsAO_History.HRelease(); + SoftwareTracingShared.BentNormalsAO_Accumulated.HRelease(); + SoftwareTracingShared.BentNormalsAO_Samplecount.HRelease(); + SoftwareTracingShared.BentNormalsAO_SamplecountHistory.HRelease(); + } + + if (onlyRelease) + { + ReleaseTextures(); + return; + } + + if (SoftwareTracingShared.UseDirectionalOcclusion == false) + return; + + Vector2Int fullRes = new Vector2Int(width, height); + float probeSize = (float)HSettings.GeneralSettings.RayCountMode.ParseToProbeSize(); + Vector2Int probeRes = new Vector2Int(Mathf.RoundToInt(width / probeSize), Mathf.RoundToInt(height / probeSize)); + + RenderTextureDescriptor fullResDesc = desc; + TextureDimension originalTextureDimension = desc.dimension; + fullResDesc.depthStencilFormat = GraphicsFormat.None; + fullResDesc.enableRandomWrite = true; + + RenderTextureDescriptor probeDesc = desc; + probeDesc.width = probeRes.x; + probeDesc.height = probeRes.y; + probeDesc.depthStencilFormat = GraphicsFormat.None; + probeDesc.enableRandomWrite = true; + + // -------------------------------------- SSAO RT -------------------------------------- // + + if (HSettings.ScreenSpaceLightingSettings.DirectionalOcclusion) + { + SoftwareTracingShared.ProbeSSAO.ReAllocateIfNeeded("_ProbeSSAO", ref probeDesc, GraphicsFormat.R8_UNorm); + SoftwareTracingShared.BentNormalsAO.ReAllocateIfNeeded("_BentNormalsAO", ref fullResDesc, GraphicsFormat.R16G16B16A16_SFloat); + SoftwareTracingShared.BentNormalsAO_Interpolated.ReAllocateIfNeeded("_BentNormalsAO_Interpolated", ref fullResDesc, GraphicsFormat.R16G16B16A16_SFloat); + fullResDesc.width = Mathf.RoundToInt(fullResDesc.width / 2.0f); + fullResDesc.height = Mathf.RoundToInt(fullResDesc.height / 2.0f); + SoftwareTracingShared.NormalDepthHalf.ReAllocateIfNeeded("_NormalDepthHalf", ref fullResDesc, GraphicsFormat.R16G16B16A16_SFloat); + fullResDesc.width = width; + fullResDesc.height = height; + + // TODO: porbably we will no need these, leave them for now, but don't allocate. + // BentNormalsAO_History.ReAllocateIfNeeded(FullRes, HRenderer.TextureXrSlices, textureDimension: HConstants.TextureDimension, + // GraphicsFormat.R16G16B16A16_SFloat, "_BentNormalsAO_History"); + // + // BentNormalsAO_Accumulated.ReAllocateIfNeeded(FullRes, HRenderer.TextureXrSlices, textureDimension: HConstants.TextureDimension, + // GraphicsFormat.R16G16B16A16_SFloat, "_BentNormalsAO_Accumulated"); + // + // BentNormalsAO_SamplecountHistory.ReAllocateIfNeeded(FullRes, HRenderer.TextureXrSlices, textureDimension: HConstants.TextureDimension, + // GraphicsFormat.R8_UInt, "_BentNormalsAO_SamplecountHistory"); + // + // BentNormalsAO_Samplecount.ReAllocateIfNeeded(FullRes, HRenderer.TextureXrSlices, textureDimension: HConstants.TextureDimension, + // GraphicsFormat.R8_UInt, "_BentNormalsAO_Samplecount"); + } + else //Warnings suppression + { + fullResDesc.width = fullResDesc.height = 1; + SoftwareTracingShared.ProbeSSAO.ReAllocateIfNeeded("_ProbeSSAO", ref fullResDesc, GraphicsFormat.R8_UNorm); + SoftwareTracingShared.BentNormalsAO.ReAllocateIfNeeded("_BentNormalsAO", ref fullResDesc, GraphicsFormat.R16G16B16A16_SFloat); + SoftwareTracingShared.BentNormalsAO_Interpolated.ReAllocateIfNeeded("_BentNormalsAO_Interpolated", ref fullResDesc, GraphicsFormat.R16G16B16A16_SFloat); + SoftwareTracingShared.NormalDepthHalf.ReAllocateIfNeeded("_NormalDepthHalf", ref fullResDesc, GraphicsFormat.R16G16B16A16_SFloat); + } + } + + internal static void AllocateDebugRT(int width, int height, RenderTextureDescriptor desc, bool onlyRelease = false) + { + void ReleaseTextures() + { + SoftwareTracingShared.DebugOutput.HRelease(); + } + + if (onlyRelease) + { + ReleaseTextures(); + return; + } + + if (HSettings.GeneralSettings.DebugModeWS == DebugModeWS.None) + return; + + Vector2 fullRes = Vector2.one; + + // -------------------------------------- DEBUG RT -------------------------------------- // + if (HSettings.GeneralSettings.DebugModeWS != DebugModeWS.None) + { + desc.depthStencilFormat = GraphicsFormat.None; + desc.enableRandomWrite = true; + SoftwareTracingShared.DebugOutput.ReAllocateIfNeeded("_DebugOutput", ref desc, GraphicsFormat.B10G11R11_UFloatPack32); + } + } + + internal static void AllocateIndirectionBuffers(int width, int height, bool onlyRelease = false) + { + void ReleaseTextures() + { + SoftwareTracingShared.IndirectCoordsSS.HRelease(); + SoftwareTracingShared.IndirectCoordsWS.HRelease(); + SoftwareTracingShared.IndirectCoordsOV.HRelease(); + SoftwareTracingShared.IndirectCoordsSF.HRelease(); + SoftwareTracingShared.IndirectCoordsSS = null; + SoftwareTracingShared.IndirectCoordsWS = null; + SoftwareTracingShared.IndirectCoordsOV = null; + SoftwareTracingShared.IndirectCoordsSF = null; + } + + if (onlyRelease) + { + ReleaseTextures(); + return; + } + + // -------------------------------------- BUFFERS -------------------------------------- // + + if (SoftwareTracingShared.IndirectCoordsSS == null) SoftwareTracingShared.IndirectCoordsSS = new HDynamicBuffer(BufferType.ComputeBuffer, 2 * sizeof(uint), HRenderer.TextureXrSlices, avoidDownscale: true); + if (SoftwareTracingShared.IndirectCoordsWS == null) SoftwareTracingShared.IndirectCoordsWS = new HDynamicBuffer(BufferType.ComputeBuffer, 2 * sizeof(uint), HRenderer.TextureXrSlices, avoidDownscale: true); + if (SoftwareTracingShared.IndirectCoordsOV == null) SoftwareTracingShared.IndirectCoordsOV = new HDynamicBuffer(BufferType.ComputeBuffer, 2 * sizeof(uint), HRenderer.TextureXrSlices, avoidDownscale: true); + if (SoftwareTracingShared.IndirectCoordsSF == null) SoftwareTracingShared.IndirectCoordsSF = new HDynamicBuffer(BufferType.ComputeBuffer, 2 * sizeof(uint), HRenderer.TextureXrSlices, avoidDownscale: true); + + SoftwareTracingShared.IndirectCoordsSS.ReAllocIfNeeded(new Vector2Int(width, height)); + SoftwareTracingShared.IndirectCoordsWS.ReAllocIfNeeded(new Vector2Int(width, height)); + SoftwareTracingShared.IndirectCoordsOV.ReAllocIfNeeded(new Vector2Int(width, height)); + SoftwareTracingShared.IndirectCoordsSF.ReAllocIfNeeded(new Vector2Int(width, height)); + } + + internal static void AllocationHashBuffers(bool onlyRelease = false, bool forceRecreate = false) + { + void ReleaseTextures() + { + SoftwareTracingShared.HashBuffer_Key.HRelease(); + SoftwareTracingShared.HashBuffer_Payload.HRelease(); + SoftwareTracingShared.HashBuffer_Counter.HRelease(); + SoftwareTracingShared.HashBuffer_Radiance.HRelease(); + SoftwareTracingShared.HashBuffer_Position.HRelease(); + SoftwareTracingShared.HashBuffer_Key = null; + SoftwareTracingShared.HashBuffer_Payload = null; + SoftwareTracingShared.HashBuffer_Counter = null; + SoftwareTracingShared.HashBuffer_Radiance = null; + SoftwareTracingShared.HashBuffer_Position = null; + } + + if (onlyRelease) + { + ReleaseTextures(); + return; + } + + if (forceRecreate) + { + ReleaseTextures(); + } + + if (SoftwareTracingShared.HashBuffer_Key == null) SoftwareTracingShared.HashBuffer_Key = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE, 1 * sizeof(uint)); + if (SoftwareTracingShared.HashBuffer_Payload == null) SoftwareTracingShared.HashBuffer_Payload = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE / HConstants.HASH_UPDATE_FRACTION, 2 * sizeof(uint)); + if (SoftwareTracingShared.HashBuffer_Counter == null) SoftwareTracingShared.HashBuffer_Counter = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE, 1 * sizeof(uint)); + if (SoftwareTracingShared.HashBuffer_Position == null) SoftwareTracingShared.HashBuffer_Position = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE, 4 * sizeof(uint)); + if (SoftwareTracingShared.HashBuffer_Radiance == null) + { + SoftwareTracingShared.HashBuffer_Radiance = new ComputeBuffer(HConstants.HASH_STORAGE_SIZE, 4 * sizeof(uint)); + uint[] zeroArray = new uint[HConstants.HASH_STORAGE_SIZE * 4]; + SoftwareTracingShared.HashBuffer_Radiance.SetData(zeroArray); + } + } +#endif + #endregion --------------------------- Render Graph --------------------------- + + #region --------------------------- Shared --------------------------- + + protected internal void Dispose() + { + Allocation(0,0, new RenderTextureDescriptor(), true); + } + + #endregion --------------------------- Shared --------------------------- + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/SoftwareTracingPassURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/URP/SoftwareTracingPassURP.cs.meta new file mode 100644 index 000000000..5a67d4147 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/SoftwareTracingPassURP.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 6f331d5124d6468ebe858b940aeadf3f +timeCreated: 1760107102 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/URP/SoftwareTracingPassURP.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/VoxelizationPassURP.cs b/Assets/External/HTraceWSGI/Scripts/Passes/URP/VoxelizationPassURP.cs new file mode 100644 index 000000000..746e2858b --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/VoxelizationPassURP.cs @@ -0,0 +1,553 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +using UnityEngine.Rendering.Universal; + +#if UNITY_2023_3_OR_NEWER +using HTraceWSGI.Scripts.Passes.Shared; +using HTraceWSGI.Scripts.Services.VoxelCameras; +using UnityEngine.Rendering.RendererUtils; +using UnityEngine.Rendering.RenderGraphModule; +#endif + +namespace HTraceWSGI.Scripts.Passes.URP +{ + internal class VoxelizationPassURP : ScriptableRenderPass + { + #region --------------------------- Non Render Graph --------------------------- + +#if !UNITY_6000_4_OR_NEWER + private ScriptableRenderer _renderer; + + protected internal void Initialize(ScriptableRenderer renderer) + { + _renderer = renderer; + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) + { + + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) + { + ConfigureInput(ScriptableRenderPassInput.Depth); // | ScriptableRenderPassInput.Normal); + } + +#if UNITY_2023_3_OR_NEWER + [System.Obsolete] +#endif + public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) + { + var cmd = CommandBufferPool.Get(HNames.HTRACE_SHADOWMAP_PASS_NAME); + + Camera camera = renderingData.cameraData.camera; + int width = (int)(camera.scaledPixelWidth * renderingData.cameraData.renderScale); + int height = (int)(camera.scaledPixelHeight * renderingData.cameraData.renderScale); + + // switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) + // { + // case VoxelizationUpdateMode.Constant: + // using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) + // //ExecuteConstant(cmd, camera, width, height, ref renderingData.cullResults); + // break; + // case VoxelizationUpdateMode.Partial: + // using (new HTraceProfilingScope(cmd, s_RenderShadowmapProfilingSampler)) + // //ExecutePartial(cmd, camera, width, height); + // break; + // } + + VoxelizationShared.History.Update(); + + context.ExecuteCommandBuffer(cmd); + cmd.Clear(); + CommandBufferPool.Release(cmd); + } +#endif + + #endregion --------------------------- Non Render Graph --------------------------- + + #region --------------------------- Render Graph --------------------------- + +#if UNITY_2023_3_OR_NEWER + private class PassData + { + public RendererListHandle RendererListHandle; + public UniversalCameraData UniversalCameraData; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + using (var builder = renderGraph.AddUnsafePass(HNames.HTRACE_VOXELIZATION_PASS_NAME, out PassData passData, new ProfilingSampler(HNames.HTRACE_VOXELIZATION_PASS_NAME))) + { + UniversalResourceData resourceData = frameData.Get(); + UniversalCameraData universalCameraData = frameData.Get(); + UniversalRenderingData universalRenderingData = frameData.Get(); + UniversalLightData lightData = frameData.Get(); + CullContextData cullContextData = frameData.Get(); + + ConfigureInput(ScriptableRenderPassInput.Depth); + + builder.AllowGlobalStateModification(true); + builder.AllowPassCulling(true); + + passData.UniversalCameraData = universalCameraData; + + if (VoxelizationShared.VoxelizationShader == null) VoxelizationShared.VoxelizationShader = Shader.Find("Hidden/HTraceWSGI/VoxelizationURP"); + if (VoxelizationShared.HVoxelization == null) VoxelizationShared.HVoxelization = HExtensions.LoadComputeShader("Voxelization"); + if (VoxelizationShared.VoxelVisualization == null) VoxelizationShared.VoxelVisualization = HExtensions.LoadComputeShader("VoxelVisualization"); + + if (VoxelizationShared.DummyVoxelBuffer == null) VoxelizationShared.DummyVoxelBuffer = new ComputeBuffer(1, sizeof(int)); + + int voxelResX = HSettings.VoxelizationSettings.ExactData.Resolution.x; + int voxelResY = HSettings.VoxelizationSettings.ExactData.Resolution.z; + int voxelResZ = HSettings.VoxelizationSettings.ExactData.Resolution.y; + + RenderTextureDescriptor desc = new RenderTextureDescriptor(voxelResX, voxelResY); + + VoxelizationShared.VoxelPositionPyramid.ReAllocateIfNeeded(name: "_VoxelPositionPyramid", ref desc, graphicsFormat: GraphicsFormat.R8_UInt,voxelResX, voxelResY, volumeDepth: voxelResZ, dimension: TextureDimension.Tex3D, useMipMap: true); + VoxelizationShared.VoxelPositionIntermediate.ReAllocateIfNeeded(name: "_VoxelPositionIntermediate", ref desc, GraphicsFormat.R8_UInt, voxelResX / 4, voxelResY / 4, volumeDepth: voxelResZ / 4, dimension: TextureDimension.Tex3D); + renderGraph.ImportTexture(VoxelizationShared.VoxelPositionPyramid.rt); + renderGraph.ImportTexture(VoxelizationShared.VoxelPositionIntermediate.rt); + + switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) + { + case VoxelizationUpdateMode.Constant: + VoxelizationShared.VoxelData.ReAllocateIfNeeded(name: "_VoxelData", ref desc, GraphicsFormat.R32_UInt, voxelResX, voxelResY, volumeDepth: voxelResZ, dimension: TextureDimension.Tex3D); + VoxelizationShared.DummyVoxelizationTarget.ReAllocateIfNeeded(name: "_DummyVoxelizationDynamicTarget", ref desc, GraphicsFormat.R8_UNorm, voxelResX * 2, voxelResZ * 2); + + renderGraph.ImportTexture(VoxelizationShared.DummyVoxelizationTarget.rt); + renderGraph.ImportTexture(VoxelizationShared.VoxelData.rt); + + VoxelizationShared.DummyVoxelizationStaticTarget?.HRelease(); + VoxelizationShared.DummyVoxelizationDynamicTarget?.HRelease(); + VoxelizationShared.VoxelData_A?.HRelease(); + VoxelizationShared.VoxelData_B?.HRelease(); + break; + case VoxelizationUpdateMode.Partial: + VoxelizationShared.DummyVoxelizationStaticTarget.ReAllocateIfNeeded(name: "_DummyVoxelizationStaticTarget", ref desc, GraphicsFormat.R8_UNorm,voxelResX, voxelResZ); + VoxelizationShared.DummyVoxelizationDynamicTarget.ReAllocateIfNeeded(name: "_DummyVoxelizationDynamicTarget", ref desc, GraphicsFormat.R8_UNorm, voxelResX * 2, voxelResZ * 2); + VoxelizationShared.VoxelData_A.ReAllocateIfNeeded(name: "_VoxelData_A", ref desc, GraphicsFormat.R32_UInt,voxelResX, voxelResY, volumeDepth: voxelResZ, dimension: TextureDimension.Tex3D); + VoxelizationShared.VoxelData_B.ReAllocateIfNeeded(name: "_VoxelData_B", ref desc, GraphicsFormat.R32_UInt,voxelResX, voxelResY, volumeDepth: voxelResZ, dimension: TextureDimension.Tex3D); + + renderGraph.ImportTexture(VoxelizationShared.DummyVoxelizationStaticTarget.rt); + renderGraph.ImportTexture(VoxelizationShared.DummyVoxelizationDynamicTarget.rt); + renderGraph.ImportTexture(VoxelizationShared.VoxelData_A.rt); + renderGraph.ImportTexture(VoxelizationShared.VoxelData_B.rt); + + VoxelizationShared.DummyVoxelizationTarget?.HRelease(); + VoxelizationShared.VoxelData?.HRelease(); + break; + } + + if (VoxelizationShared.History.VoxelizationUpdateMode != HSettings.VoxelizationSettings.VoxelizationUpdateMode && HSettings.VoxelizationSettings.VoxelizationUpdateMode == VoxelizationUpdateMode.Partial) + VoxelizationRuntimeData.FullVoxelization = true; + + VoxelizationRuntimeData.VoxelCamera.ExecuteUpdate(universalCameraData.camera); + AddRendererList(renderGraph, universalCameraData, universalRenderingData, lightData, passData, builder, cullContextData); + + builder.SetRenderFunc((PassData data, UnsafeGraphContext context) => ExecutePass(data, context)); + } + } + + private static void AddRendererList(RenderGraph renderGraph, UniversalCameraData universalCameraData, UniversalRenderingData universalRenderingData, UniversalLightData lightData, PassData passData, + IUnsafeRenderGraphBuilder builder, CullContextData cullContextData) + { + LayerMask voxelizationLayer = HSettings.VoxelizationSettings.VoxelizationMask; + + if (HSettings.VoxelizationSettings.VoxelizationUpdateMode == VoxelizationUpdateMode.Partial && VoxelizationRuntimeData.OctantIndex == OctantIndex.DynamicObjects) + { + voxelizationLayer = HSettings.VoxelizationSettings.DynamicObjectsMask & HSettings.VoxelizationSettings.VoxelizationMask; + } + + SortingCriteria sortFlags = universalCameraData.defaultOpaqueSortFlags; + RenderQueueRange renderQueueRange = RenderQueueRange.opaque; + FilteringSettings filterSettings = new FilteringSettings(renderQueueRange, voxelizationLayer); + + ShaderTagId tag = new ShaderTagId("ShadowCaster"); //todo: use only one now, i will upgrade it if needed, because it's not easy + // Create drawing settings + DrawingSettings drawSettings = RenderingUtils.CreateDrawingSettings(tag, universalRenderingData, universalCameraData, lightData, sortFlags); + drawSettings.overrideShader = VoxelizationShared.VoxelizationShader; + drawSettings.overrideShaderPassIndex = 0; + + var cullingCamera = VoxelizationRuntimeData.VoxelCamera.Camera; + if (HSettings.VoxelizationSettings.VoxelizationUpdateMode == VoxelizationUpdateMode.Partial) + cullingCamera = VoxelizationRuntimeData.FullVoxelization ? VoxelizationRuntimeData.VoxelCamera.Camera : VoxelizationRuntimeData.CullingCamera.Camera; + + var maximumLODLevelBackup = QualitySettings.maximumLODLevel; + var lodBiasBackup = QualitySettings.lodBias; + QualitySettings.SetLODSettings(1, HSettings.VoxelizationSettings.LODMax, false); + + if (cullingCamera.TryGetCullingParameters(out ScriptableCullingParameters cullingParams)) + { + cullingParams.cullingOptions = CullingOptions.None; + cullingParams.isOrthographic = true; + + LODParameters lodParameters = cullingParams.lodParameters; + lodParameters.cameraPosition = cullingCamera.transform.position; + lodParameters.isOrthographic = true; + lodParameters.orthoSize = 0; + cullingParams.lodParameters = lodParameters; + cullingParams.cullingMask = (uint)voxelizationLayer.value; + + var directionalLightCullResults = cullContextData.Cull(ref cullingParams); + var rendererListParameters = new RendererListParams(directionalLightCullResults, drawSettings, filterSettings); + passData.RendererListHandle = renderGraph.CreateRendererList(rendererListParameters); + builder.UseRendererList(passData.RendererListHandle); + } + + QualitySettings.SetLODSettings(lodBiasBackup, maximumLODLevelBackup, false); + } + + private static void ExecutePass(PassData data, UnsafeGraphContext rgContext) + { + var cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); + + Camera camera = data.UniversalCameraData.camera; + int width = (int)(data.UniversalCameraData.camera.scaledPixelWidth * data.UniversalCameraData.renderScale); + int height = (int)(data.UniversalCameraData.camera.scaledPixelHeight * data.UniversalCameraData.renderScale); + + switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) + { + case VoxelizationUpdateMode.Constant: + using (new HTraceProfilingScope(cmd, VoxelizationShared.s_VoxelizationConstantProfilingSampler)) + VoxelizationConstant(cmd, camera, width, height, data); + break; + case VoxelizationUpdateMode.Partial: + using (new HTraceProfilingScope(cmd, VoxelizationShared.s_VoxelizationPartialProfilingSampler)) + VoxelizationPartial(cmd, camera, width, height, data); + break; + } + + VoxelizationShared.History.Update(); + VoxelizationRuntimeData.FullVoxelization = false; + } + + private static void VoxelizationConstant(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight, PassData data) + { + if (VoxelizationRuntimeData.VoxelCamera == null) + return; + + // Clear 3D textures + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelData.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 1, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 2, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 3, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 4, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 5, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionIntermediate.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + + // Pass voxel camera pos to shaders + cmd.SetGlobalVector(VoxelizationShared.g_VoxelCameraPos, VoxelizationRuntimeData.VoxelCamera.transform.position); + + // Load our voxelization camera // + var voxelizationCamera = VoxelizationRuntimeData.VoxelCamera.Camera; + + // Render voxels + if (true) + { + // Pass main voxelization parameters to shaders + cmd.SetGlobalVector(VoxelizationShared.g_VoxelResolution, (Vector3)HSettings.VoxelizationSettings.ExactData.Resolution); + cmd.SetGlobalVector(VoxelizationShared.g_VoxelBounds, HSettings.VoxelizationSettings.ExactData.Bounds); + cmd.SetGlobalFloat(VoxelizationShared.g_VoxelPerMeter, HSettings.VoxelizationSettings.ExactData.VoxelsPerMeter); + cmd.SetGlobalFloat(VoxelizationShared.g_VoxelSize, HSettings.VoxelizationSettings.ExactData.VoxelSize); + + Vector3 BoundsSwizzled = new Vector3(HSettings.VoxelizationSettings.ExactData.Bounds.x, HSettings.VoxelizationSettings.ExactData.Bounds.z, HSettings.VoxelizationSettings.ExactData.Bounds.y); + Bounds voxelizationAABB = new Bounds(VoxelizationRuntimeData.VoxelCamera.transform.position, BoundsSwizzled); + cmd.SetGlobalVector(VoxelizationShared.g_VoxelizationAABB_Min, voxelizationAABB.min); + cmd.SetGlobalVector(VoxelizationShared.g_VoxelizationAABB_Max, voxelizationAABB.max); + + if (voxelizationCamera.farClipPlane > 0) //always in constant + { + // Cache main camera matrices + var viewMatrixCached = camera.worldToCameraMatrix; + var projectionMatrixCached = camera.projectionMatrix; + + // Set voxelization camera matrices + cmd.SetViewProjectionMatrices(voxelizationCamera.worldToCameraMatrix, voxelizationCamera.projectionMatrix); + + // Set rendering targets + cmd.ClearRandomWriteTargets(); + cmd.SetRandomWriteTarget(1, VoxelizationShared.VoxelData.rt); + cmd.SetRandomWriteTarget(2, VoxelizationShared.DummyVoxelBuffer, false); + + Shader.EnableKeyword(VoxelizationShared.CONSTANT_VOXELIZATION); + Shader.DisableKeyword(VoxelizationShared.PARTIAL_VOXELIZATION); + Shader.DisableKeyword(VoxelizationShared.DYNAMIC_VOXELIZATION); + + var maximumLODLevelBackup = QualitySettings.maximumLODLevel; + var lodBiasBackup = QualitySettings.lodBias; + QualitySettings.SetLODSettings(1, HSettings.VoxelizationSettings.LODMax, false); + + // Render voxels + cmd.SetRenderTarget(VoxelizationShared.DummyVoxelizationTarget.rt, VoxelizationShared.DummyVoxelizationTarget.rt); + cmd.ClearRenderTarget(true, true, Color.black); + cmd.DrawRendererList(data.RendererListHandle); + + QualitySettings.SetLODSettings(lodBiasBackup, maximumLODLevelBackup, false); + + // Reset rendering targets + cmd.ClearRandomWriteTargets(); + + // Restore matrices and culling of the main camera + cmd.SetViewProjectionMatrices(viewMatrixCached, projectionMatrixCached); + } + } + + // Generate mip pyramid for 3D position texture + using (new HTraceProfilingScope(cmd, VoxelizationShared.s_GeneratePositionPyramidProfilingSampler)) + { + // Generate 0-2 mip levels + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared.g_VoxelData, VoxelizationShared.VoxelData.rt); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared._VoxelPositionPyramid_Mip0, VoxelizationShared.VoxelPositionPyramid.rt, 0); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared._VoxelPositionPyramid_Mip1, VoxelizationShared.VoxelPositionPyramid.rt, 1); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared._VoxelPositionPyramid_Mip2, VoxelizationShared.VoxelPositionPyramid.rt, 2); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared._VoxelPositionIntermediate_Output, VoxelizationShared.VoxelPositionIntermediate.rt); + cmd.DispatchCompute(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.x / 8f), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.z / 8f), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.y / 8f)); + + // Generate 3-5 mip levels + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, VoxelizationShared._VoxelPositionIntermediate, VoxelizationShared.VoxelPositionIntermediate.rt); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, VoxelizationShared._VoxelPositionPyramid_Mip3, VoxelizationShared.VoxelPositionPyramid.rt, 3); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, VoxelizationShared._VoxelPositionPyramid_Mip4, VoxelizationShared.VoxelPositionPyramid.rt, 4); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, VoxelizationShared._VoxelPositionPyramid_Mip5, VoxelizationShared.VoxelPositionPyramid.rt, 5); + cmd.DispatchCompute(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.x / 32f), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.z / 32f), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.y / 32f)); + } + + // Pass voxelized textures to shaders in the Main Pass + cmd.SetGlobalTexture(VoxelizationShared.g_VoxelPositionPyramid, VoxelizationShared.VoxelPositionPyramid.rt); + cmd.SetGlobalTexture(VoxelizationShared.g_VoxelData, VoxelizationShared.VoxelData.rt); + } + + + private static void VoxelizationPartial(CommandBuffer cmd, Camera camera, int cameraWidth, int cameraHeight, PassData data) + { +#if UNITY_EDITOR + if (UnityEditor.EditorApplication.isPaused) // This is required to avoid flickering in the Frame Debugger. + return; +#endif + if (VoxelizationRuntimeData.VoxelCamera == null) + return; + + bool isFullVoxelization = VoxelizationRuntimeData.FullVoxelization; + bool isDynamicOctant = (int)VoxelizationRuntimeData.OctantIndex == 5 ? true : false; + bool isFirstOctant = (int)VoxelizationRuntimeData.OctantIndex == 1 ? true : false; + + // Swap counter, flips at the start of every cycle + if (isFirstOctant && !isFullVoxelization) + VoxelizationRuntimeData.TextureSwapCounter++; + + // Output counter, flips at the end of every cycle + if (isDynamicOctant && !isFullVoxelization) + { + VoxelizationRuntimeData.TextureOutputCounter = VoxelizationRuntimeData.TextureSwapCounter; + } + + // Clear 3D textures + if (isDynamicOctant || isFullVoxelization) + { + HSettings.DebugSettings.TestCheckbox = false; + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 1, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 2, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 3, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 4, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionPyramid.rt, ClearFlag.Color, Color.clear, 5, CubemapFace.Unknown, -1); + CoreUtils.SetRenderTarget(cmd, VoxelizationShared.VoxelPositionIntermediate.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + } + if (isFirstOctant || isFullVoxelization) + CoreUtils.SetRenderTarget(cmd, VoxelizationRuntimeData.TextureSwapCounter % 2 == 0 ? VoxelizationShared.VoxelData_B.rt : VoxelizationShared.VoxelData_A.rt, ClearFlag.Color, Color.clear, 0, CubemapFace.Unknown, -1); + + // Pass voxel camera pos to shaders at the end of the cycle + if (isDynamicOctant || isFullVoxelization) + { + cmd.SetGlobalVector(VoxelizationShared.g_VoxelCameraPos, VoxelizationRuntimeData.VoxelCamera.transform.position); + } + + // Pass actual voxel camera pos to voxelization shader for geometry trimming + if (isFirstOctant || isFullVoxelization) + { + cmd.SetGlobalVector(VoxelizationShared.g_VoxelCameraPosActual, VoxelizationRuntimeData.VoxelCamera.transform.position); + } + + // Scroll voxels by copying them + using (new HTraceProfilingScope(cmd, VoxelizationShared.s_CopyVoxelsProfilingSampler)) + { + if (!isDynamicOctant && !isFullVoxelization) + { + Vector3 octantCopyOffset = VoxelizationFunctionsShared.CalculateOctantOffsetsForCopyShader(); + + cmd.SetComputeVectorParam(VoxelizationShared.HVoxelization, VoxelizationShared._OctantCopyOffset, octantCopyOffset); + cmd.SetComputeVectorParam(VoxelizationShared.HVoxelization, VoxelizationShared._VoxelOffset, VoxelizationRuntimeData.VoxelCamera.transform.position - VoxelizationShared.History.VoxelCameraPosition); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.CopyData, VoxelizationShared._VoxelData_A, VoxelizationRuntimeData.TextureSwapCounter % 2 == 0 ? VoxelizationShared.VoxelData_B.rt : VoxelizationShared.VoxelData_A.rt); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.CopyData, VoxelizationShared._VoxelData_B, VoxelizationRuntimeData.TextureSwapCounter % 2 == 0 ? VoxelizationShared.VoxelData_A.rt : VoxelizationShared.VoxelData_B.rt); + cmd.DispatchCompute(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.CopyData, + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.x / 8f / 2), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.z / 4f / 2), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.y / 8f / 2)); + } + } + + // Render voxels + if (true) + { + Vector3 BoundsSwizzled = new Vector3(HSettings.VoxelizationSettings.ExactData.Bounds.x, HSettings.VoxelizationSettings.ExactData.Bounds.z, HSettings.VoxelizationSettings.ExactData.Bounds.y); + Bounds voxelizationAABB = new Bounds(VoxelizationRuntimeData.VoxelCamera.transform.position, BoundsSwizzled); + // Pass main voxelization parameters to shaders + cmd.SetGlobalVector(VoxelizationShared.g_VoxelResolution, (Vector3)HSettings.VoxelizationSettings.ExactData.Resolution); + cmd.SetGlobalVector(VoxelizationShared.g_VoxelBounds, HSettings.VoxelizationSettings.ExactData.Bounds); + cmd.SetGlobalFloat(VoxelizationShared.g_VoxelPerMeter, HSettings.VoxelizationSettings.ExactData.VoxelsPerMeter); + cmd.SetGlobalFloat(VoxelizationShared.g_VoxelSize, HSettings.VoxelizationSettings.ExactData.VoxelSize); + + cmd.SetGlobalVector(VoxelizationShared.g_VoxelizationAABB_Min, voxelizationAABB.min); + cmd.SetGlobalVector(VoxelizationShared.g_VoxelizationAABB_Max, voxelizationAABB.max); + + // Load our culling & voxelization camera + Camera cullingCamera = isFullVoxelization ? VoxelizationRuntimeData.VoxelCamera.Camera : VoxelizationRuntimeData.CullingCamera.Camera; + Camera voxelizationCamera = isFullVoxelization ? VoxelizationRuntimeData.VoxelCamera.Camera : VoxelizationRuntimeData.VoxelOctantCamera.Camera; + + if (cullingCamera.farClipPlane > 0 && data.RendererListHandle.IsValid()) // always correct for Dynamic objects + { + // Cache main camera matrices + var viewMatrixCached = camera.worldToCameraMatrix; + var projectionMatrixCached = camera.projectionMatrix; + + // Set voxelization camera matrices + cmd.SetViewProjectionMatrices(voxelizationCamera.worldToCameraMatrix, voxelizationCamera.projectionMatrix); + + if ((int)VoxelizationRuntimeData.OctantIndex != 5) + VoxelizationFunctionsShared.CalculateOctantOffsets(cmd); + + // Set rendering targets + cmd.ClearRandomWriteTargets(); + cmd.SetRandomWriteTarget(1, VoxelizationRuntimeData.TextureSwapCounter % 2 == 0 ? VoxelizationShared.VoxelData_B.rt : VoxelizationShared.VoxelData_A.rt); + cmd.SetRandomWriteTarget(2, VoxelizationShared.DummyVoxelBuffer, false); + + Shader.EnableKeyword(VoxelizationShared.PARTIAL_VOXELIZATION); + Shader.DisableKeyword(VoxelizationShared.DYNAMIC_VOXELIZATION); + Shader.DisableKeyword(VoxelizationShared.CONSTANT_VOXELIZATION); + + var voxelizationRenderTarget = VoxelizationShared.DummyVoxelizationStaticTarget; + + if (isFullVoxelization) + { + voxelizationRenderTarget = VoxelizationShared.DummyVoxelizationDynamicTarget; + Shader.EnableKeyword(VoxelizationShared.CONSTANT_VOXELIZATION); + Shader.DisableKeyword(VoxelizationShared.PARTIAL_VOXELIZATION); + Shader.DisableKeyword(VoxelizationShared.DYNAMIC_VOXELIZATION); + } + else if ((int)VoxelizationRuntimeData.OctantIndex == 5) + { + voxelizationRenderTarget = VoxelizationShared.DummyVoxelizationDynamicTarget; + Shader.EnableKeyword(VoxelizationShared.DYNAMIC_VOXELIZATION); + Shader.DisableKeyword(VoxelizationShared.PARTIAL_VOXELIZATION); + Shader.DisableKeyword(VoxelizationShared.CONSTANT_VOXELIZATION); + } + + var maximumLODLevelBackup = QualitySettings.maximumLODLevel; + var lodBiasBackup = QualitySettings.lodBias; + QualitySettings.SetLODSettings(1, HSettings.VoxelizationSettings.LODMax, false); + + // Render voxels + cmd.SetRenderTarget(voxelizationRenderTarget.rt, voxelizationRenderTarget.rt); + cmd.ClearRenderTarget(true, true, Color.black); + cmd.DrawRendererList(data.RendererListHandle); + + QualitySettings.SetLODSettings(lodBiasBackup, maximumLODLevelBackup, false); + + // Reset rendering targets + cmd.ClearRandomWriteTargets(); + + // Restore matrices and culling of the main camera + cmd.SetViewProjectionMatrices(viewMatrixCached, projectionMatrixCached); + } + } + + // Generate mip pyramid for 3D position texture + using (new HTraceProfilingScope(cmd, VoxelizationShared.s_GeneratePositionPyramidProfilingSampler)) + { + if (isDynamicOctant || isFullVoxelization) + { + // Generate 0-2 mip levels + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared.g_VoxelData, VoxelizationRuntimeData.TextureSwapCounter % 2 == 0 ? VoxelizationShared.VoxelData_B.rt : VoxelizationShared.VoxelData_A.rt); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared._VoxelPositionPyramid_Mip0, VoxelizationShared.VoxelPositionPyramid.rt, 0); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared._VoxelPositionPyramid_Mip1, VoxelizationShared.VoxelPositionPyramid.rt, 1); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared._VoxelPositionPyramid_Mip2, VoxelizationShared.VoxelPositionPyramid.rt, 2); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, VoxelizationShared._VoxelPositionIntermediate_Output, VoxelizationShared.VoxelPositionIntermediate.rt); + cmd.DispatchCompute(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid1, + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.x / 8f), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.z / 8f), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.y / 8f)); + + // Generate 3-5 mip levels + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, VoxelizationShared._VoxelPositionIntermediate, VoxelizationShared.VoxelPositionIntermediate.rt); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, VoxelizationShared._VoxelPositionPyramid_Mip3, VoxelizationShared.VoxelPositionPyramid.rt, 3); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, VoxelizationShared._VoxelPositionPyramid_Mip4, VoxelizationShared.VoxelPositionPyramid.rt, 4); + cmd.SetComputeTextureParam(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, VoxelizationShared._VoxelPositionPyramid_Mip5, VoxelizationShared.VoxelPositionPyramid.rt, 5); + cmd.DispatchCompute(VoxelizationShared.HVoxelization, (int)VoxelizationShared.HVoxelizationKernel.GeneratePositionPyramid2, + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.x / 32f), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.z / 32f), + Mathf.CeilToInt(HSettings.VoxelizationSettings.ExactData.Resolution.y / 32f)); + } + } + + if (isDynamicOctant || isFullVoxelization) + { + VoxelizationShared.History.VoxelCameraPosition = VoxelizationRuntimeData.VoxelCamera.transform.position; + } + + // Pass voxelized textures to shaders in the Main Pass + cmd.SetGlobalTexture(VoxelizationShared.g_VoxelPositionPyramid, VoxelizationShared.VoxelPositionPyramid.rt); + cmd.SetGlobalTexture(VoxelizationShared.g_VoxelData, VoxelizationRuntimeData.TextureOutputCounter % 2 == 0 ? VoxelizationShared.VoxelData_B.rt : VoxelizationShared.VoxelData_A.rt); + + // Copy to the opposite data buffer to make sure we have full voxelization in both of them + if (isFullVoxelization) + { + cmd.CopyTexture(VoxelizationRuntimeData.TextureSwapCounter % 2 == 0 ? VoxelizationShared.VoxelData_B.rt : VoxelizationShared.VoxelData_A.rt, VoxelizationRuntimeData.TextureSwapCounter % 2 == 0 ? VoxelizationShared.VoxelData_A.rt : VoxelizationShared.VoxelData_B.rt); + } + } +#endif + + #endregion --------------------------- Render Graph --------------------------- + + #region --------------------------- Shared --------------------------- + + + protected internal void Dispose() + { + VoxelizationShared.DummyVoxelBuffer.HRelease(); + VoxelizationShared.DummyVoxelBuffer = null; + + VoxelizationShared.DummyVoxelizationTarget.HRelease(); + VoxelizationShared.VoxelPositionPyramid.HRelease(); + VoxelizationShared.VoxelPositionIntermediate.HRelease(); + VoxelizationShared.VoxelData.HRelease(); + VoxelizationShared.DummyVoxelizationStaticTarget.HRelease(); + VoxelizationShared.DummyVoxelizationDynamicTarget.HRelease(); + VoxelizationShared.VoxelData_A.HRelease(); + VoxelizationShared.VoxelData_B.HRelease(); + + + } + + #endregion --------------------------- Shared --------------------------- + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Passes/URP/VoxelizationPassURP.cs.meta b/Assets/External/HTraceWSGI/Scripts/Passes/URP/VoxelizationPassURP.cs.meta new file mode 100644 index 000000000..f716420be --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Passes/URP/VoxelizationPassURP.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: ff95e75af76548c29e82018fe9e372d5 +timeCreated: 1759850117 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Passes/URP/VoxelizationPassURP.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator.meta b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator.meta new file mode 100644 index 000000000..3ea151682 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 73422c61d7e009d4da0775d7e9da3e34 +timeCreated: 1727776393 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/ConfiguratorUtils.cs b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/ConfiguratorUtils.cs new file mode 100644 index 000000000..d892bddc3 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/ConfiguratorUtils.cs @@ -0,0 +1,29 @@ +//pipelinedefine +#define H_URP + +#if UNITY_EDITOR +using System; +using System.Collections; // UNITY 6 +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using UnityEngine; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.PipelinesConfigurator +{ + public static class ConfiguratorUtils + { + + public static string GetHTraceFolderPath() + { + //string filePath = AssetDatabase.GetAssetPath(MonoScript.FromMonoBehaviour(this)); + string filePath = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName(); + string htraceFolder = Directory.GetParent(Directory.GetParent(Path.GetDirectoryName(filePath)).FullName).FullName; + return htraceFolder; + } + + } +} +#endif diff --git a/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/ConfiguratorUtils.cs.meta b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/ConfiguratorUtils.cs.meta new file mode 100644 index 000000000..9d4c93b8e --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/ConfiguratorUtils.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 28f8a9da21928f5488759e999cb41654 +timeCreated: 1721992132 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/PipelinesConfigurator/ConfiguratorUtils.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/HPipelinesConfigurator.cs b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/HPipelinesConfigurator.cs new file mode 100644 index 000000000..829b40c9e --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/HPipelinesConfigurator.cs @@ -0,0 +1,65 @@ +//pipelinedefine +#define H_URP + +#if UNITY_EDITOR +using System; +using System.Collections; // UNITY 6 +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using HTraceWSGI.Scripts.Globals; +using UnityEditor; +using UnityEngine; +using UnityEngine.Rendering; +using Object = UnityEngine.Object; + +namespace HTraceWSGI.Scripts.PipelinesConfigurator +{ + internal class HPipelinesConfigurator + { + public static void AlwaysIncludedShaders() + { + AddShaderToGraphicsSettings("Hidden/HTraceWSGI/ShadowmapURP"); + AddShaderToGraphicsSettings("Hidden/HTraceWSGI/VoxelizationURP"); + AddShaderToGraphicsSettings("Hidden/HTraceWSGI/VoxelVisualizationURP"); + AddShaderToGraphicsSettings("Hidden/HTraceWSGI/MotionVectorsURP"); + AddShaderToGraphicsSettings("Hidden/HTraceWSGI/ColorComposeURP"); + AddShaderToGraphicsSettings("Hidden/HTraceWSGI/LightClusterVisualizationURP"); + } + + private static void AddShaderToGraphicsSettings(string shaderName) + { + var shader = Shader.Find(shaderName); + if (shader == null) + return; + + var graphicsSettings = AssetDatabase.LoadAssetAtPath("ProjectSettings/GraphicsSettings.asset"); + var serializedObject = new SerializedObject(graphicsSettings); + var arrayProp = serializedObject.FindProperty("m_AlwaysIncludedShaders"); + bool hasShader = false; + for (int i = 0; i < arrayProp.arraySize; ++i) + { + var arrayElem = arrayProp.GetArrayElementAtIndex(i); + if (shader == arrayElem.objectReferenceValue) + { + hasShader = true; + break; + } + } + + if (!hasShader) + { + int arrayIndex = arrayProp.arraySize; + arrayProp.InsertArrayElementAtIndex(arrayIndex); + var arrayElem = arrayProp.GetArrayElementAtIndex(arrayIndex); + arrayElem.objectReferenceValue = shader; + + serializedObject.ApplyModifiedProperties(); + + AssetDatabase.SaveAssets(); + } + } + } +} +#endif diff --git a/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/HPipelinesConfigurator.cs.meta b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/HPipelinesConfigurator.cs.meta new file mode 100644 index 000000000..308431ad1 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/PipelinesConfigurator/HPipelinesConfigurator.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 0e642364de342f34a83da159732e5350 +timeCreated: 1722005153 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/PipelinesConfigurator/HPipelinesConfigurator.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services.meta b/Assets/External/HTraceWSGI/Scripts/Services.meta new file mode 100644 index 000000000..76063117c --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cd1c23dd8bdb3fc4682bd051ab1fe1b7 +timeCreated: 1744132295 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap.meta b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap.meta new file mode 100644 index 000000000..fc6cb568b --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cf6d910a17cb2e94291d60427fbd27d3 +timeCreated: 1744132356 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/DirectionalShadowmapService.cs b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/DirectionalShadowmapService.cs new file mode 100644 index 000000000..e9212d2a0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/DirectionalShadowmapService.cs @@ -0,0 +1,68 @@ +using System; +using HTraceWSGI.Scripts.Data.Private; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace HTraceWSGI.Scripts.Services.DirectionalShadowmap +{ + [ExecuteAlways] + internal class DirectionalShadowmapService : IService + { + public HTraceDirectionalCamera DirectionalCamera; + + private static DirectionalShadowmapService _instance; + + public static DirectionalShadowmapService Instance + { + get + { + if (_instance == null) + _instance = new DirectionalShadowmapService(); + return _instance; + } + } + + public void Initialize(int layer) + { + CreateHTraceCameraDirectional(layer); + } + + private void CreateHTraceCameraDirectional(int layer) + { + if (DirectionalCamera != null) + { + DirectionalCamera.Initialize(this); + return; + } + + GameObject cameraFromDirLightGo = new GameObject("HTraceDirectionalCameraHandler"); + cameraFromDirLightGo.layer = layer; + cameraFromDirLightGo.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + DirectionalCamera = cameraFromDirLightGo.AddComponent(); + + DirectionalCamera.Initialize(this); + } + + + + public bool PingDirLight(HTraceDirectionalCamera camera) + { + return DirectionalCamera != camera; + } + + public void LateUpdate() + { + if (DirectionalCamera != null) + { + DirectionalCamera.gameObject.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + DirectionalCamera.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + } + } + + public void Cleanup() + { + // if (DirectionalCamera != null) + // Object.DestroyImmediate(DirectionalCamera.gameObject); + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/DirectionalShadowmapService.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/DirectionalShadowmapService.cs.meta new file mode 100644 index 000000000..0292b88a0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/DirectionalShadowmapService.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: aa1937b3548dcb74a901652d0f7a2c2f +timeCreated: 1744132401 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/DirectionalShadowmap/DirectionalShadowmapService.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/HTraceDirectionalCamera.cs b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/HTraceDirectionalCamera.cs new file mode 100644 index 000000000..148dcb765 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/HTraceDirectionalCamera.cs @@ -0,0 +1,252 @@ +//pipelinedefine +#define H_URP + +using System.Collections.Generic; +using System.Linq; +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace HTraceWSGI.Scripts.Services.DirectionalShadowmap +{ + [ExecuteInEditMode] + internal class HTraceDirectionalCamera : MonoBehaviour + { + private const float SQRT_OF_3 = 1.732f; + + public int ShadowResolution = 2048; + + private Camera _directionalCamera; + private DirectionalShadowmapService _directionalShadowmapService; + + private Vector3 _rememberPos; + private Quaternion _rememberRot; + private Light _directionalLight; + private bool _needToRenderVoxels; + + public Camera GetDirectionalCamera + { + get { return _directionalCamera; } + } + + public Camera Initialize(DirectionalShadowmapService directionalShadowmapService) + { + _directionalShadowmapService = directionalShadowmapService; + + IEnumerable lights = Object.FindObjectsOfType() + .Where(lightComp => lightComp.type == LightType.Directional) + .ToList(); + + if (HSettings.LightingSettings.DirectionalLight != null) + _directionalLight = HSettings.LightingSettings.DirectionalLight; + + if (_directionalLight == null && lights.Any()) + { + _directionalLight = lights.FirstOrDefault(lightComp => lightComp.gameObject.activeSelf == true); + if (_directionalLight == null) + _directionalLight = lights.First(); + + HSettings.LightingSettings.DirectionalLight = _directionalLight; + } + + gameObject.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + CreateDirectionalCamera(); + + return _directionalCamera; + } + + private void CreateDirectionalCamera() + { + _directionalCamera = gameObject.GetComponentInChildren(); + if (_directionalCamera == null) + { + GameObject cameraGo = new GameObject("Directional Camera"); + cameraGo.transform.parent = this.gameObject.transform; + cameraGo.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + _directionalCamera = cameraGo.AddComponent(); + _directionalCamera.hideFlags = HideFlags.HideAndDontSave; + + } + + _directionalCamera.enabled = false; + _directionalCamera.orthographic = true; + _directionalCamera.allowMSAA = false; + _directionalCamera.cullingMask = ~0; + } + + public void ExecuteUpdate() + { + UpdateCamera(); + SetParams(); + if (HSettings.GeneralSettings.TracingMode == TracingMode.SoftwareTracing && HSettings.VoxelizationSettings.VoxelizationUpdateMode == VoxelizationUpdateMode.Partial) + OctantTransformCamera(); + } + + private void UpdateCamera() + { + if (HSettings.LightingSettings.DirectionalLight == null) + return; + + if (HSettings.DebugSettings != null) + { + _directionalCamera.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + _directionalCamera.gameObject.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + } + + //transform.position = _voxelCamera.transform.position - HResources.VoxelizationData.DirectionalLight.transform.forward * _voxelCamera.orthographicSize * SQRT_OF_3; + //transform.rotation = HResources.VoxelizationData.DirectionalLight.transform.rotation; + + switch (HSettings.GeneralSettings.TracingMode) + { + case TracingMode.SoftwareTracing: + transform.parent = VoxelizationRuntimeData.VoxelCamera.Camera.transform; + break; + case TracingMode.HardwareTracing: + transform.parent = Camera.main.transform; + break; + } + + bool isTranslateNeeded = false; + switch (HSettings.GeneralSettings.TracingMode) + { + case TracingMode.SoftwareTracing: + switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) + { + case VoxelizationUpdateMode.Constant: + isTranslateNeeded = true; + break; + case VoxelizationUpdateMode.Partial: + if (VoxelizationRuntimeData.OctantIndex == OctantIndex.OctantA) + isTranslateNeeded = true; + break; + } + break; + case TracingMode.HardwareTracing: + isTranslateNeeded = true; + break; + } + + if (isTranslateNeeded) + { + switch (HSettings.GeneralSettings.TracingMode) + { + case TracingMode.SoftwareTracing: + var voxelCamera = VoxelizationRuntimeData.VoxelCamera.Camera; + transform.position = voxelCamera.transform.position - HSettings.LightingSettings.DirectionalLight.transform.forward * voxelCamera.orthographicSize * SQRT_OF_3 * HSettings.LightingSettings.ExpandShadowmap; + break; + case TracingMode.HardwareTracing: + if (Camera.main != null) + transform.position = Camera.main.transform.position - HSettings.LightingSettings.DirectionalLight.transform.forward * (HSettings.LightingSettings.ShadowmapRange); + break; + } + + transform.rotation = HSettings.LightingSettings.DirectionalLight.transform.rotation; + _rememberPos = transform.position; + _rememberRot = transform.rotation; + } + else + { + transform.position = _rememberPos; + transform.rotation = _rememberRot; + } + + _directionalCamera.transform.localPosition = Vector3.zero; + + //_fakeDirectionalLight.SetShadowResolution(ShadowResolution); + + //_cameraFakeDirLight.transform.localPosition = Vector3.zero; + //_cameraFakeDirLight.transform.localPosition -= Vector3.forward * _voxelCamera.orthographicSize * SQRT_OF_3; + } + + private void SetParams() + { + float scale = 0f; + if (HSettings.VoxelizationSettings.VoxelizationUpdateMode == VoxelizationUpdateMode.Partial) + scale = VoxelizationRuntimeData.OctantIndex == OctantIndex.DynamicObjects ? 1f : 2f; + else + scale = 1f; + + float value = 0; + if (HSettings.GeneralSettings.TracingMode == TracingMode.SoftwareTracing) + value = VoxelizationRuntimeData.VoxelCamera.Camera.orthographicSize * SQRT_OF_3 * HSettings.LightingSettings.ExpandShadowmap; + else + value = HSettings.LightingSettings.ShadowmapRange; + _directionalCamera.farClipPlane = 1f * 2 * value; + _directionalCamera.nearClipPlane = 0f; + _directionalCamera.orthographicSize = value / scale; + _directionalCamera.aspect = 1; + } + + private void OctantTransformCamera() + { + _directionalCamera.transform.SetPositionAndRotation(_rememberPos, _rememberRot); + + Vector3 finalLocalPos = Vector3.zero; + float sizeOrtho = _directionalCamera.orthographicSize; + switch (VoxelizationRuntimeData.OctantIndex) + { + case OctantIndex.OctantA: + finalLocalPos += sizeOrtho * -_directionalCamera.transform.right; + finalLocalPos += sizeOrtho * _directionalCamera.transform.up; + break; + case OctantIndex.OctantB: + finalLocalPos += sizeOrtho * _directionalCamera.transform.right; + finalLocalPos += sizeOrtho * _directionalCamera.transform.up; + break; + case OctantIndex.OctantC: + finalLocalPos += sizeOrtho * -_directionalCamera.transform.right; + finalLocalPos += sizeOrtho * -_directionalCamera.transform.up; + break; + case OctantIndex.OctantD: + finalLocalPos += sizeOrtho * _directionalCamera.transform.right; + finalLocalPos += sizeOrtho * -_directionalCamera.transform.up; + break; + case OctantIndex.DynamicObjects: + break; + } + + _directionalCamera.transform.position += finalLocalPos; + } + + private void Update() + { + if (_directionalShadowmapService == null || _directionalShadowmapService.PingDirLight(this)) + { + DestroyImmediate(this.gameObject); + } + } + +#if UNITY_EDITOR + + private void OnDrawGizmos() + { + if (HSettings.DebugSettings.EnableCamerasVisualization == false) + return; + + var color = Gizmos.color; + Gizmos.color = new Color(1, 0.92f, 0.016f, 0.2f); + + Vector3 posOffset = _directionalCamera.transform.forward * _directionalCamera.farClipPlane / 2; + Vector3 position = _directionalCamera.transform.position + posOffset; + + Matrix4x4 originalMatrix = Gizmos.matrix; + Matrix4x4 rotationMatrix = transform.localToWorldMatrix; + rotationMatrix = Matrix4x4.TRS(position, _directionalCamera.transform.rotation, _directionalCamera.transform.lossyScale); + Gizmos.matrix = rotationMatrix; + + // Size = height / 2 + // Aspect = width / height + // + // height = 2f * size; + // width = height * aspect; + Vector3 size = new Vector3(2f * _directionalCamera.orthographicSize, 2f * _directionalCamera.orthographicSize * _directionalCamera.aspect, _directionalCamera.farClipPlane); + + Gizmos.DrawCube(Vector3.zero, size); + + Gizmos.matrix = originalMatrix; + Gizmos.color = color; + } +#endif + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/HTraceDirectionalCamera.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/HTraceDirectionalCamera.cs.meta new file mode 100644 index 000000000..3b74ad85e --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/DirectionalShadowmap/HTraceDirectionalCamera.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f503fc00afe19a0438d2e6300b2704e1 +timeCreated: 1692788580 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/DirectionalShadowmap/HTraceDirectionalCamera.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/IService.cs b/Assets/External/HTraceWSGI/Scripts/Services/IService.cs new file mode 100644 index 000000000..c27c0988d --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/IService.cs @@ -0,0 +1,8 @@ +namespace HTraceWSGI.Scripts.Services +{ + public interface IService + { + void LateUpdate(); + void Cleanup(); + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/IService.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/IService.cs.meta new file mode 100644 index 000000000..43315f5c9 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/IService.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1feb42a9ba0e3124aac41e00a2c8bc97 +timeCreated: 1744134831 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/IService.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster.meta b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster.meta new file mode 100644 index 000000000..1fb59137e --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5d42a002c087465e89a4aa06e35a9eda +timeCreated: 1744027382 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/HPunctualLight.cs b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/HPunctualLight.cs new file mode 100644 index 000000000..4bf787565 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/HPunctualLight.cs @@ -0,0 +1,135 @@ +using UnityEngine; + +namespace HTraceWSGI.Scripts.Services.LightsCluster +{ + [ExecuteAlways] + [RequireComponent(typeof(Light))] + [DisallowMultipleComponent] + [DefaultExecutionOrder(101)] //after update services + public class HPunctualLight : MonoBehaviour + { + public bool DisableShadowCulling = false; + + private Light _light; + + private bool _initialized; + private bool _isRegistered; + private bool _lastEnabled; + private LightType _lastType; + + private Vector4 _boundingSphere = new(0, 0, 0, 100); + + public Light Light => _light; + + + private void OnEnable() + { + Initialize(); + _lastEnabled = _light.enabled; + _lastType = _light.type; + + if (IsSupportedType(_light.type) && _lastEnabled) + Register(); + + UpdateShadowSettingsAndBounds(); + } + + private void Awake() + { + Initialize(); + } + + private void Initialize() + { + if (_initialized) return; + + _light = GetComponent(); + _initialized = true; + } + + private void LateUpdate() + { + if (_light == null) + return; + + if (_light.enabled != _lastEnabled || _light.type != _lastType) + { + _lastEnabled = _light.enabled; + _lastType = _light.type; + + if (IsSupportedType(_light.type) && _light.enabled) + Register(); + else + Unregister(); + } + + UpdateShadowSettingsAndBounds(); + } + + private void Register() + { + if (_isRegistered) return; + if (!IsSupportedType(_light.type) || !_light.enabled) return; + + if (LightService.Instance != null) + { + LightService.Instance.AddLight(_light); + _isRegistered = true; + } + } + + private void Unregister() + { + if (!_isRegistered) return; + + if (LightService.Instance != null && _light != null) + { + LightService.Instance.RemoveLight(_light); + } + + _isRegistered = false; + } + + private void UpdateShadowSettingsAndBounds() + { + if (_light == null) + return; + + _light.useViewFrustumForShadowCasterCull = !DisableShadowCulling; + + // Only Point/Spot are supported and use the bounding sphere override + if (!IsSupportedType(_light.type)) + { + _light.useBoundingSphereOverride = false; + return; + } + + // Vector3 pos = _light.transform.position; + // float radius = Mathf.Max(1f, _light.range); + // _light.boundingSphereOverride = new Vector4(pos.x, pos.y, pos.z, radius); + + _light.boundingSphereOverride = _boundingSphere; + _light.useBoundingSphereOverride = true; + } + + private void OnDisable() + { + Unregister(); + } + + private void OnDestroy() + { + Unregister(); + } + + private static bool IsSupportedType(LightType type) + { + bool isSupportedType = type == LightType.Point || type == LightType.Spot; + if (isSupportedType == false) + { + Debug.LogWarning($"H Punctual Light script is assigned to an unsupported light type!"); + } + return isSupportedType; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/HPunctualLight.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/HPunctualLight.cs.meta new file mode 100644 index 000000000..c9e1efa9a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/HPunctualLight.cs.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: f26894728a8de5649a1f514a204cc926 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/LightsCluster/HPunctualLight.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/LightService.cs b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/LightService.cs new file mode 100644 index 000000000..990e877c2 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/LightService.cs @@ -0,0 +1,167 @@ +//pipelinedefine +#define H_URP +using System.Collections.Generic; +using System.Linq; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; + +namespace HTraceWSGI.Scripts.Services.LightsCluster +{ + internal sealed class LightService : IService + { + internal struct LightInfo + { + public Vector3 Position; + } + + private static readonly int _MaxCookieResolution = Shader.PropertyToID("_MaxCookieResolution"); + private static readonly int _LightPointCookies_Output = Shader.PropertyToID("_LightPointCookies_Output"); + private static readonly int _LightSpotCookies_Output = Shader.PropertyToID("_LightSpotCookies_Output"); + + private static LightService _instance; + + public static LightService Instance + { + get + { + if (_instance == null) + _instance = new LightService(); + return _instance; + } + } + + private readonly Dictionary _lights = new Dictionary(10); + private readonly List _lightsToRemove = new List(20); + private readonly List _lightsToUpdate = new List(20); + + public void Initialize() + { + + HPunctualLight[] findObjectsByType = Object.FindObjectsByType(FindObjectsSortMode.None); + foreach (var light in findObjectsByType) + { + if (light.enabled == true) + AddLight(light.Light); + } + } + + public void AddLight(Light light) + { + if (light == null || !light.enabled) + return; + + if (light.type != LightType.Point && light.type != LightType.Spot) + return; + + if (_lights.ContainsKey(light)) + return; + + + var lightInfo = new LightInfo + { + Position = light.transform.position, + }; + + _lights[light] = lightInfo; + } + + public void RemoveLight(Light light) + { + if (object.ReferenceEquals(light, null)) + return; + + RemoveLightData(light); + } + + private void RemoveLightData(Light light) + { + if (_lights.TryGetValue(light, out var info)) + { + _lights.Remove(light); + } + } + + public void LateUpdate() + { + _lightsToRemove.Clear(); + + foreach (var kvp in _lights) + { + var key = kvp.Key; + + if (!key || !key.enabled || (key.type != LightType.Point && key.type != LightType.Spot)) + { + _lightsToRemove.Add(key); + } + } + + for (int i = 0; i < _lightsToRemove.Count; i++) + { + RemoveLightData(_lightsToRemove[i]); + } + + _lightsToUpdate.Clear(); + foreach (var kvp in _lights) + { + _lightsToUpdate.Add(kvp.Key); + } + + for (int i = 0; i < _lightsToUpdate.Count; i++) + { + var key = _lightsToUpdate[i]; + var lightInfo = _lights[key]; + + lightInfo.Position = key.transform.position; + _lights[key] = lightInfo; + } + + //CleanupUnusedCookies(); + + } + + public IEnumerable GetLights(Camera camera) + { + if (camera == null) + yield break; + + var cameraPosition = camera.transform.position; + + foreach (var kvp in _lights) + { + var light = kvp.Key; + var lightInfo = kvp.Value; + + if (!light || !light.enabled) + continue; + { + yield return lightInfo; + } + } + } + +#if NONE + public IEnumerable GetLights(Camera camera) + { + foreach (var kvp in _lights) + { + var light = kvp.Key; + var lightInfo = kvp.Value; + + if (!light || !light.enabled) + continue; + + yield return lightInfo; + } + } +#endif + + + public void Cleanup() + { + _lights.Clear(); + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/LightService.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/LightService.cs.meta new file mode 100644 index 000000000..c64e20a2a --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/LightsCluster/LightService.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: a8ff1db96b5a432c9b5b67310ba132bf +timeCreated: 1744028034 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/LightsCluster/LightService.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService.meta b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService.meta new file mode 100644 index 000000000..f275ee7d4 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8c3eae83ac794d746910a08a42119f96 +timeCreated: 1747413710 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/HTraceMotionVector.cs b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/HTraceMotionVector.cs new file mode 100644 index 000000000..e30342d89 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/HTraceMotionVector.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Services.MotionVectorService +{ + public class HTraceMotionVector : MonoBehaviour + { + private void Start() + { + if (MotionVectorService.Instance != null) + { + List renderers = this.gameObject.GetComponentsInChildren().ToList(); + if (this.gameObject.GetComponent() != null) + renderers.Add(this.gameObject.GetComponent()); + + MotionVectorService.Instance.AddObject(gameObject, renderers); + } + } + + private void OnDestroy() + { + if (MotionVectorService.Instance != null) + { + MotionVectorService.Instance.RemoveObject(gameObject); + } + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/HTraceMotionVector.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/HTraceMotionVector.cs.meta new file mode 100644 index 000000000..0bbe71874 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/HTraceMotionVector.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: c7636971a1bcd1d448e18f993ffc52c2 +timeCreated: 1743087936 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/MotionVectorService/HTraceMotionVector.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/MotionVectorService.cs b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/MotionVectorService.cs new file mode 100644 index 000000000..f39327ebe --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/MotionVectorService.cs @@ -0,0 +1,151 @@ +using System.Collections.Generic; +using HTraceWSGI.Scripts.Data.Private; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Services.MotionVectorService +{ + public class MotionVectorRuntimeData + { + public MotionVectorRuntimeData(List renderers) + { + Renderers = renderers; + MaterialPropertyBlock = new MaterialPropertyBlock(); + PreviousModalMatrices = new Dictionary(renderers.Count); + for (int index = 0; index < renderers.Count; index++) + { + PreviousModalMatrices.Add(renderers[index], Matrix4x4.zero); + } + } + public bool WasMovedThisFrame; + public readonly MaterialPropertyBlock MaterialPropertyBlock; + public Dictionary PreviousModalMatrices; + public readonly List Renderers; + } + + public class MotionVectorService : IService + { + private static readonly int s_ForceNoMotion = Shader.PropertyToID("_ForceNoMotion"); + private static readonly int s_HasLastPositionData = Shader.PropertyToID("_HasLastPositionData"); + private static readonly int s_MotionVectorDepthBias = Shader.PropertyToID("_MotionVectorDepthBias"); + private static readonly int s_PreviousM = Shader.PropertyToID("_PreviousM"); + private static readonly int s_NonJitteredVp = Shader.PropertyToID("_NonJitteredVP"); + private static readonly int s_PreviousVp = Shader.PropertyToID("_PreviousVP"); + + private readonly Dictionary _runtimeDatas = new Dictionary(); + private Camera _camera; + + private static MotionVectorService s_Instance; + + public static MotionVectorService Instance + { + get + { + if (s_Instance == null) + s_Instance = new MotionVectorService(); + return s_Instance; + } + } + + public void Initialize(Camera camera) + { + _camera = camera; + } + + public Dictionary GetObjects => _runtimeDatas; + public void AddObject(GameObject gameObject, Renderer renderer) + { + if (gameObject == null || renderer == null) + return; + + if (_runtimeDatas.ContainsKey(gameObject) == false) + { + _runtimeDatas.Add(gameObject, new MotionVectorRuntimeData(new List(){renderer})); + } + } + + public void AddObject(GameObject gameObject, List renderers) + { + if (gameObject == null || renderers == null || renderers.Count == 0) + return; + + if (_runtimeDatas.ContainsKey(gameObject) == false) + { + _runtimeDatas.Add(gameObject, new MotionVectorRuntimeData(renderers)); + } + } + + public void RemoveObject(GameObject gameObject) + { + if (_runtimeDatas.ContainsKey(gameObject) == true) + { + _runtimeDatas.Remove(gameObject); + } + } + + private Matrix4x4 prevVP = Matrix4x4.zero; + + public void LateUpdate() + { + Matrix4x4 projMatrix = GL.GetGPUProjectionMatrix(_camera.projectionMatrix, true); + Matrix4x4 viewMatrix = _camera.worldToCameraMatrix; + foreach (var gObject in _runtimeDatas) + { + foreach (var renderer in gObject.Value.Renderers) + { + var skinnedMeshRenderer = renderer as SkinnedMeshRenderer; + bool isSkinned = skinnedMeshRenderer != null; + + Matrix4x4 currentMatrix; + if (isSkinned == true) + { + if (skinnedMeshRenderer.rootBone == null) + { + currentMatrix = renderer.localToWorldMatrix; + } + else + { + skinnedMeshRenderer.forceMatrixRecalculationPerRender = true; // magic trick for MV + currentMatrix = skinnedMeshRenderer.rootBone.localToWorldMatrix; + } + } + else // default meshes + { + currentMatrix = renderer.localToWorldMatrix; + } + + Matrix4x4 previousMatrix = gObject.Value.PreviousModalMatrices[renderer]; + bool hasMoved = !MatricesAreEqual(currentMatrix, previousMatrix); + gObject.Value.WasMovedThisFrame = hasMoved; + + gObject.Value.MaterialPropertyBlock.SetFloat(s_ForceNoMotion, renderer.motionVectorGenerationMode == MotionVectorGenerationMode.ForceNoMotion ? 1.0f : 0.0f); + gObject.Value.MaterialPropertyBlock.SetInt(s_HasLastPositionData, isSkinned ? 1 : 0); + //gObject.Value.MaterialPropertyBlock.SetFloat(s_MotionVectorDepthBias, 0); //-0.001f + // gObject.Value.MaterialPropertyBlock.SetMatrix(s_PreviousM, isSkinned == false ? previousMatrix : (skinnedMeshRenderer.rootBone == null ? previousMatrix : previousMatrix)); // because skinnedmesh haven't yet updated rootbone matrices, why? + gObject.Value.MaterialPropertyBlock.SetMatrix(s_PreviousM, previousMatrix); // when we moved to LateUpdate + forceMatrixRecalculationPerRender, we can just it + gObject.Value.MaterialPropertyBlock.SetMatrix(s_NonJitteredVp, projMatrix * viewMatrix); + gObject.Value.MaterialPropertyBlock.SetMatrix(s_PreviousVp, prevVP); + renderer.SetPropertyBlock(gObject.Value.MaterialPropertyBlock); + + gObject.Value.PreviousModalMatrices[renderer] = currentMatrix; + } + } + + prevVP = projMatrix * viewMatrix; + } + + public void Cleanup() + { + + } + + private static bool MatricesAreEqual(Matrix4x4 a, Matrix4x4 b, float tolerance = 0.0001f) + { + for (int i = 0; i < 16; i++) + { + if (Mathf.Abs(a[i] - b[i]) > tolerance) + return false; + } + return true; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/MotionVectorService.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/MotionVectorService.cs.meta new file mode 100644 index 000000000..6038ae5d6 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/MotionVectorService/MotionVectorService.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: b29c98d6521f1744b8ba47d29af426ed +timeCreated: 1742712246 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/MotionVectorService/MotionVectorService.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras.meta b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras.meta new file mode 100644 index 000000000..88be20b94 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a6eac100f636e0d47bfd3cfd2d440e31 +timeCreated: 1719666172 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCamera.cs b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCamera.cs new file mode 100644 index 000000000..e42c8cc8c --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCamera.cs @@ -0,0 +1,218 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace HTraceWSGI.Scripts.Services.VoxelCameras +{ + [ExecuteInEditMode] + internal class VoxelCamera : MonoBehaviour + { + public Camera Camera + { + get { return _camera; } + } + + private Camera _camera; + private VoxelsService _voxelsService; + + private bool _dirtyBounds = false; + private Vector3 _prevVoxelBounds; + private Vector3 _rememberPos; + + public void Initialize(VoxelsService voxelsService) + { + _voxelsService = voxelsService; + CreateCamera(); + ExecuteUpdate(null); + VoxelizationRuntimeData.OnReallocTextures += UpdateCameraFromUI; + + if (HSettings.VoxelizationSettings != null) + _prevVoxelBounds = HSettings.VoxelizationSettings.ExactData.Bounds; + } + + public void ExecuteUpdate(Camera camera) + { + if (HSettings.VoxelizationSettings == null) + return; + + if (_dirtyBounds == true) + { + _dirtyBounds = false; + _prevVoxelBounds = HSettings.VoxelizationSettings.ExactData.Bounds; + } + + _camera.cullingMask = ~0; //voxelizationData.VoxelizationMask; + _camera.orthographic = true; + _camera.farClipPlane = .5f * HSettings.VoxelizationSettings.ExactData.Bounds.z; + _camera.nearClipPlane = -.5f * HSettings.VoxelizationSettings.ExactData.Bounds.z; + _camera.orthographicSize = .5f * _prevVoxelBounds.x; + _camera.aspect = (.5f * _prevVoxelBounds.x) / (.5f * _prevVoxelBounds.x); + + //HData.VoxelizationData.ExactData.PreviousVoxelCameraPosition = new Vector3(_camera.transform.position.x, _camera.transform.position.y, _camera.transform.position.z); + + AttachedCameraTranslate(camera); + } + + private void AttachedCameraTranslate(Camera camera) + { + bool attachToSceneCamera = camera != null && camera.cameraType == CameraType.SceneView && HSettings.DebugSettings.AttachToSceneCamera == true; + + if (HSettings.VoxelizationSettings.AttachTo == null && attachToSceneCamera == false) + { + GroundLevelTranslate(); + _camera.transform.position = _camera.transform.position.OptimizeForVoxelization(HSettings.VoxelizationSettings.ExactData); + return; + } + + Transform attachToTransform = HSettings.VoxelizationSettings.AttachTo; +#if UNITY_EDITOR + if (attachToSceneCamera) + { + attachToTransform = SceneView.lastActiveSceneView.camera.transform; + } +#endif + _camera.transform.parent = attachToTransform; + _camera.transform.rotation = Quaternion.identity; + _camera.transform.eulerAngles += new Vector3(-90f, 0, 180f); + + switch (HSettings.VoxelizationSettings.VoxelizationUpdateMode) + { + case VoxelizationUpdateMode.Constant: + { + _camera.transform.localPosition = Vector3.zero; + + CenterShiftTranslate(attachToTransform); + GroundLevelTranslate(); + _camera.transform.position = _camera.transform.position.OptimizeForVoxelization(HSettings.VoxelizationSettings.ExactData); + break; + } + case VoxelizationUpdateMode.Partial: + { + if (VoxelizationRuntimeData.FullVoxelization) + { + CenterShiftTranslate(attachToTransform); + GroundLevelTranslate(); + _camera.transform.position = _camera.transform.position.OptimizeForVoxelization(HSettings.VoxelizationSettings.ExactData); + _rememberPos = _camera.transform.position; + break; + } + + if (VoxelizationRuntimeData.OctantIndex == OctantIndex.OctantA)//(RuntimeData.FrameCount % HConstants.OCTANTS_FRAMES_LENGTH == 0) // || VoxelizationRuntimeData.FullVoxelization + { + _camera.transform.localPosition = Vector3.zero; + + CenterShiftTranslate(attachToTransform); + GroundLevelTranslate(); + _camera.transform.position = _camera.transform.position.OptimizeForVoxelization(HSettings.VoxelizationSettings.ExactData); + + VoxelizationRuntimeData.OffsetAxisIndex = CalculateOffsetPositionAndTargetAxis(); + + if (VoxelizationRuntimeData.CullingCamera != null && VoxelizationRuntimeData.VoxelOctantCamera != null) //first frame exceprion + { + VoxelizationRuntimeData.VoxelOctantCamera.UpdateCamera(); + VoxelizationRuntimeData.CullingCamera.UpdateCamera(); + } + } + else + { + _camera.transform.position = _rememberPos; + } + break; + } + } + + if (VoxelizationRuntimeData.CullingCamera != null && VoxelizationRuntimeData.VoxelOctantCamera != null) //first frame exception + { + // Debug.Log(VoxelizationRuntimeData.OctantIndex); + VoxelizationRuntimeData.VoxelOctantCamera.ExecuteUpdate(); + VoxelizationRuntimeData.CullingCamera.ExecuteUpdate(); + } + } + + private OffsetAxisIndex CalculateOffsetPositionAndTargetAxis() + { + Vector3 offsetWorldPosition = _rememberPos; + _rememberPos = _camera.transform.position; + + offsetWorldPosition = _rememberPos - offsetWorldPosition; + + VoxelizationRuntimeData.OffsetWorldPosition = new OffsetWorldPosition( + VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisXPos ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisXPos, + VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisYPos ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisYPos, + VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisZPos ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisZPos, + VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisXNeg ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisXNeg, + VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisYNeg ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisYNeg, + VoxelizationRuntimeData.OffsetAxisIndex == OffsetAxisIndex.AxisZNeg ? 0.0f : VoxelizationRuntimeData.OffsetWorldPosition.AxisZNeg + ); + + VoxelizationRuntimeData.OffsetWorldPosition += new OffsetWorldPosition( + offsetWorldPosition.x > Mathf.Epsilon ? offsetWorldPosition.x : 0f, + offsetWorldPosition.y > Mathf.Epsilon ? offsetWorldPosition.y : 0f, + offsetWorldPosition.z > Mathf.Epsilon ? offsetWorldPosition.z : 0f, + offsetWorldPosition.x < Mathf.Epsilon ? -offsetWorldPosition.x : 0f, + offsetWorldPosition.y < Mathf.Epsilon ? -offsetWorldPosition.y : 0f, + offsetWorldPosition.z < Mathf.Epsilon ? -offsetWorldPosition.z : 0f + ); + + return VoxelizationRuntimeData.OffsetWorldPosition.MaxAxisOffset(); + } + + private void CenterShiftTranslate(Transform attachToTransform) + { + if (attachToTransform.GetComponent() && Mathf.Abs(HSettings.VoxelizationSettings.CenterShift) > 0.01f) + { + var forward = attachToTransform.forward; + _camera.transform.position += new Vector3(forward.x, 0f, forward.z) * HSettings.VoxelizationSettings.CenterShift; + } + } + + private void GroundLevelTranslate() + { + float height = HSettings.VoxelizationSettings.ExactData.Bounds.z; + if (HSettings.VoxelizationSettings.GroundLevelEnable == true && (_camera.transform.position.y - height / 2) < HSettings.VoxelizationSettings.GroundLevel) + { + _camera.transform.position = new Vector3(_camera.transform.position.x, HSettings.VoxelizationSettings.GroundLevel + height / 2, + _camera.transform.position.z); + } + } + + private void UpdateCameraFromUI() + { + _dirtyBounds = true; + } + + private void CreateCamera() + { + if (_camera == null) + { + _camera = gameObject.AddComponent(); + _camera.aspect = 1f; + _camera.orthographic = true; + _camera.enabled = false; + _camera.clearFlags = CameraClearFlags.Nothing; + _camera.allowMSAA = false; + _camera.hideFlags = HideFlags.HideInHierarchy; + } + } + + private void Update() + { + if (_voxelsService == null || _voxelsService.PingVoxelsHandler(this)) + { + DestroyImmediate(this.gameObject); + } + } + + private void OnDestroy() + { + VoxelizationRuntimeData.OnReallocTextures -= UpdateCameraFromUI; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCamera.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCamera.cs.meta new file mode 100644 index 000000000..8c873123d --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCamera.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1a551d5e01ed2f94f930278a059f932c +timeCreated: 1687004967 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCamera.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCullingCamera.cs b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCullingCamera.cs new file mode 100644 index 000000000..e40302eda --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCullingCamera.cs @@ -0,0 +1,286 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using UnityEngine; + + +namespace HTraceWSGI.Scripts.Services.VoxelCameras +{ + [ExecuteInEditMode] + internal class VoxelCullingCamera : MonoBehaviour + { + public Camera Camera + { + get { return _camera; } + } + + private Camera _camera; + + public void Initialize() + { + CreateCamera(); + SetParams(); + } + + public void UpdateCamera() + { + transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + } + + public void ExecuteUpdate() + { + CullingTransformCamera(); + } + + // Size = height / 2 + // Aspect = width / height + // + // height = 2f * size; + // width = height * aspect; + + private void CullingTransformCamera() + { + transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + + float scale = VoxelizationRuntimeData.OctantIndex == OctantIndex.DynamicObjects ? 2f : 1f; + bool isDynamicObjects = VoxelizationRuntimeData.OctantIndex == OctantIndex.DynamicObjects; + switch (VoxelizationRuntimeData.OffsetAxisIndex) + { + case OffsetAxisIndex.AxisXPos: + transform.localEulerAngles = new Vector3(0, 90f, 90); + transform.localPosition = new Vector3(-HSettings.VoxelizationSettings.ExactData.Bounds.x / 4f, 0, 0); + + _camera.farClipPlane = isDynamicObjects ? HSettings.VoxelizationSettings.ExactData.Bounds.x : VoxelizationRuntimeData.OffsetWorldPosition.AxisXPos; + _camera.orthographicSize = HSettings.VoxelizationSettings.ExactData.Bounds.z * scale / 4f; + _camera.aspect = HSettings.VoxelizationSettings.ExactData.Bounds.x * scale / 4f / _camera.orthographicSize; + MoveAxisX(1f); + break; + case OffsetAxisIndex.AxisXNeg: + transform.localEulerAngles = new Vector3(0, -90f, 90); + transform.localPosition = new Vector3(HSettings.VoxelizationSettings.ExactData.Bounds.x / 4f, 0, 0); + + _camera.farClipPlane = isDynamicObjects ? HSettings.VoxelizationSettings.ExactData.Bounds.x : VoxelizationRuntimeData.OffsetWorldPosition.AxisXNeg; + _camera.orthographicSize = HSettings.VoxelizationSettings.ExactData.Bounds.z * scale / 4f; + _camera.aspect = HSettings.VoxelizationSettings.ExactData.Bounds.x * scale / 4f / _camera.orthographicSize; + MoveAxisX(-1f); + break; + case OffsetAxisIndex.AxisYPos: + transform.localEulerAngles = new Vector3(-180, 0, 0); + transform.localPosition = new Vector3(0, 0, HSettings.VoxelizationSettings.ExactData.Bounds.z / 4f); + + _camera.farClipPlane = isDynamicObjects ? HSettings.VoxelizationSettings.ExactData.Bounds.z : VoxelizationRuntimeData.OffsetWorldPosition.AxisYPos; + _camera.orthographicSize = HSettings.VoxelizationSettings.ExactData.Bounds.x * scale / 4f; + _camera.aspect = 1f; //always quad + MoveAxisY(1f); + break; + case OffsetAxisIndex.AxisYNeg: + transform.localEulerAngles = new Vector3(0, 0, -180f); + transform.localPosition = new Vector3(0, 0, -HSettings.VoxelizationSettings.ExactData.Bounds.z / 4f); + + _camera.farClipPlane = isDynamicObjects ? HSettings.VoxelizationSettings.ExactData.Bounds.z : VoxelizationRuntimeData.OffsetWorldPosition.AxisYNeg; + _camera.orthographicSize = HSettings.VoxelizationSettings.ExactData.Bounds.x * scale / 4f; + _camera.aspect = 1f; //always quad + MoveAxisY(-1f); + break; + case OffsetAxisIndex.AxisZPos: + transform.localEulerAngles = new Vector3(90f, 0, 0); + transform.localPosition = new Vector3(0, HSettings.VoxelizationSettings.ExactData.Bounds.x / 4f, 0); + + _camera.farClipPlane = isDynamicObjects ? HSettings.VoxelizationSettings.ExactData.Bounds.x : VoxelizationRuntimeData.OffsetWorldPosition.AxisZPos; + _camera.orthographicSize = HSettings.VoxelizationSettings.ExactData.Bounds.z * scale / 4f; + _camera.aspect = HSettings.VoxelizationSettings.ExactData.Bounds.x * scale / 4f / _camera.orthographicSize; + MoveAxisZ(1f); + break; + case OffsetAxisIndex.AxisZNeg: + transform.localEulerAngles = new Vector3(-90f, 0, 0); + transform.localPosition = new Vector3(0, -HSettings.VoxelizationSettings.ExactData.Bounds.x / 4f, 0); + + _camera.farClipPlane = isDynamicObjects ? HSettings.VoxelizationSettings.ExactData.Bounds.x : VoxelizationRuntimeData.OffsetWorldPosition.AxisZNeg; + _camera.orthographicSize = HSettings.VoxelizationSettings.ExactData.Bounds.z * scale / 4f; + _camera.aspect = HSettings.VoxelizationSettings.ExactData.Bounds.x * scale / 4f / _camera.orthographicSize; + MoveAxisZ(-1f); + break; + } + } + + private void MoveAxisX(float sign) + { + Vector3 finalPos = Vector3.zero; + switch (VoxelizationRuntimeData.OctantIndex) + { + case OctantIndex.OctantA: + finalPos.x += -sign * HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += -HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantB: + finalPos.x += -sign * HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantC: + finalPos.x += -sign * HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += -HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += -HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantD: + finalPos.x += -sign * HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += -HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.DynamicObjects: + case OctantIndex.FullVoxelization: + finalPos.x += -sign * HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + break; + } + + transform.localPosition += finalPos; + } + + private void MoveAxisY(float sign) + { + Vector3 finalPos = Vector3.zero; + switch (VoxelizationRuntimeData.OctantIndex) + { + case OctantIndex.OctantA: + finalPos.x += HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += -HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += sign * HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantB: + finalPos.x += HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += sign * HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantC: + finalPos.x += -HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += -HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += sign * HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantD: + finalPos.x += -HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += sign * HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.DynamicObjects: + + finalPos.z += sign * HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + } + + transform.localPosition += finalPos; + } + + private void MoveAxisZ(float sign) + { + Vector3 finalPos = Vector3.zero; + + switch (VoxelizationRuntimeData.OctantIndex) + { + case OctantIndex.OctantA: + finalPos.x += -HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += sign * HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantB: + finalPos.x += HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += sign * HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantC: + finalPos.x += -HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += sign * HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += -HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantD: + finalPos.x += HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += sign * HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += -HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.DynamicObjects: + + finalPos.y += sign * HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + break; + } + + transform.localPosition += finalPos; + } + + private void SetParams() + { + _camera.cullingMask = ~0; //voxelizationData.VoxelizationMask; + _camera.orthographic = true; + _camera.farClipPlane = 1; + _camera.nearClipPlane = 0; + _camera.orthographicSize = 0; + _camera.aspect = 1; + } + + private void CreateCamera() + { + if (_camera == null) + { + _camera = gameObject.AddComponent(); + _camera.aspect = 1f; + _camera.orthographic = true; + _camera.enabled = false; + _camera.hideFlags = HideFlags.HideInHierarchy; + + } + } + +#if UNITY_EDITOR + + private void OnDrawGizmos() + { + if (HSettings.DebugSettings.EnableCamerasVisualization == false) + return; + + var color = Gizmos.color; + + Vector3 position = Vector3.zero; + Vector3 size = Vector3.zero; + + switch (VoxelizationRuntimeData.OffsetAxisIndex) + { + case OffsetAxisIndex.AxisXPos: + position = _camera.transform.position + new Vector3(-VoxelizationRuntimeData.OffsetWorldPosition.AxisXPos / 2f, 0, 0); + size = new Vector3(VoxelizationRuntimeData.OffsetWorldPosition.AxisXPos, 2f * _camera.orthographicSize, 2f * _camera.orthographicSize * _camera.aspect); + Gizmos.color = new Color(1, 0, 0, 0.3f); + break; + case OffsetAxisIndex.AxisXNeg: + position = _camera.transform.position + new Vector3(VoxelizationRuntimeData.OffsetWorldPosition.AxisXNeg / 2f, 0, 0); + size = new Vector3(VoxelizationRuntimeData.OffsetWorldPosition.AxisXNeg, 2f * _camera.orthographicSize, 2f * _camera.orthographicSize * _camera.aspect); + Gizmos.color = new Color(1, 0, 0, 0.3f); + break; + case OffsetAxisIndex.AxisYPos: + position = _camera.transform.position + new Vector3(0f, -VoxelizationRuntimeData.OffsetWorldPosition.AxisYPos / 2f, 0); + size = new Vector3(2f * _camera.orthographicSize, VoxelizationRuntimeData.OffsetWorldPosition.AxisYPos, 2f * _camera.orthographicSize * _camera.aspect); + Gizmos.color = new Color(0, 1, 0, 0.3f); + break; + case OffsetAxisIndex.AxisYNeg: + position = _camera.transform.position + new Vector3(0f, VoxelizationRuntimeData.OffsetWorldPosition.AxisYPos / 2f, 0); + size = new Vector3(2f * _camera.orthographicSize, VoxelizationRuntimeData.OffsetWorldPosition.AxisYPos, 2f * _camera.orthographicSize * _camera.aspect); + Gizmos.color = new Color(0, 1, 0, 0.3f); + break; + case OffsetAxisIndex.AxisZPos: + position = _camera.transform.position + new Vector3(0, 0, -VoxelizationRuntimeData.OffsetWorldPosition.AxisZPos / 2f); + size = new Vector3(2f * _camera.orthographicSize * _camera.aspect, 2f * _camera.orthographicSize, VoxelizationRuntimeData.OffsetWorldPosition.AxisZPos); + Gizmos.color = new Color(0, 0, 1, 0.3f); + break; + case OffsetAxisIndex.AxisZNeg: + position = _camera.transform.position + new Vector3(0, 0, VoxelizationRuntimeData.OffsetWorldPosition.AxisZNeg / 2f); + size = new Vector3(2f * _camera.orthographicSize * _camera.aspect, 2f * _camera.orthographicSize, VoxelizationRuntimeData.OffsetWorldPosition.AxisZNeg); + Gizmos.color = new Color(0, 0, 1, 0.3f); + break; + } + + Gizmos.DrawCube(position, size); + + Gizmos.color = color; + } + +#endif + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCullingCamera.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCullingCamera.cs.meta new file mode 100644 index 000000000..89c847f95 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCullingCamera.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: cb4f140b253301c448936594d2f13338 +timeCreated: 1715450232 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelCullingCamera.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelOctantCamera.cs b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelOctantCamera.cs new file mode 100644 index 000000000..d1b26a569 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelOctantCamera.cs @@ -0,0 +1,220 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Data.Private; +using UnityEngine; + + +namespace HTraceWSGI.Scripts.Services.VoxelCameras +{ + [ExecuteInEditMode] + internal class VoxelOctantCamera : MonoBehaviour + { + public Camera Camera + { + get { return _camera; } + } + + private Camera _camera; + + public void Initialize() + { + VoxelizationRuntimeData.OctantIndex = OctantIndex.OctantA; + CreateCamera(); + } + + public void UpdateCamera() + { + transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + } + + public void ExecuteUpdate() + { + // float scale = VoxelizationRuntimeData.OctantIndex == OctantIndex.DynamicObjects ? 1f : 2f; + // if (_camera.orthographicSize * scale < VoxelizationRuntimeData.OffsetWorldPosition.AxisXPos + // || _camera.orthographicSize * scale < VoxelizationRuntimeData.OffsetWorldPosition.AxisXNeg) + // Debug.Log($"Culling camera size X axis less than OffsetWorldPosition.X"); + // if (_camera.farClipPlane * scale < VoxelizationRuntimeData.OffsetWorldPosition.AxisYPos + // || _camera.farClipPlane * scale < VoxelizationRuntimeData.OffsetWorldPosition.AxisYNeg) + // Debug.Log($"Culling camera size Y axis less than OffsetWorldPosition.Y"); + // if (_camera.orthographicSize * _camera.aspect * scale < VoxelizationRuntimeData.OffsetWorldPosition.AxisZPos + // || _camera.orthographicSize * _camera.aspect * scale < VoxelizationRuntimeData.OffsetWorldPosition.AxisZNeg) + // Debug.Log($"Culling camera size Y axis less than OffsetWorldPosition.Y"); + + SetParams(VoxelizationRuntimeData.OctantIndex); + OctantTransformCamera(); + } + + private void OctantTransformCamera() + { + transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + + switch (VoxelizationRuntimeData.OffsetAxisIndex) + { + case OffsetAxisIndex.AxisXPos: + MoveAxisX(1f); + break; + case OffsetAxisIndex.AxisXNeg: + MoveAxisX(-1f); + break; + case OffsetAxisIndex.AxisYPos: + MoveAxisY(1f); + break; + case OffsetAxisIndex.AxisYNeg: + MoveAxisY(-1f); + break; + case OffsetAxisIndex.AxisZPos: + MoveAxisZ(1f); + break; + case OffsetAxisIndex.AxisZNeg: + MoveAxisZ(-1f); + break; + } + } + + private void MoveAxisX(float offset) + { + Vector3 finalPos = Vector3.zero; + switch (VoxelizationRuntimeData.OctantIndex) + { + case OctantIndex.OctantA: + finalPos.x += -offset * HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += -HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantB: + finalPos.x += -offset * HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantC: + finalPos.x += -offset * HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += -HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += -HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantD: + finalPos.x += -offset * HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += -HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.DynamicObjects: + break; + } + + transform.localPosition += finalPos; + } + + private void MoveAxisY(float offset) + { + Vector3 finalPos = Vector3.zero; + switch (VoxelizationRuntimeData.OctantIndex) + { + case OctantIndex.OctantA: + finalPos.x += HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += -HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += offset * HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantB: + finalPos.x += HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += offset * HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantC: + finalPos.x += -HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += -HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += offset * HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantD: + finalPos.x += -HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += offset * HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.DynamicObjects: + break; + } + + transform.localPosition += finalPos; + } + + private void MoveAxisZ(float offset) + { + Vector3 finalPos = Vector3.zero; + switch (VoxelizationRuntimeData.OctantIndex) + { + case OctantIndex.OctantA: + finalPos.x += -HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += offset * HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantB: + finalPos.x += HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += offset * HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantC: + finalPos.x += -HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += offset * HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += -HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.OctantD: + finalPos.x += HSettings.VoxelizationSettings.ExactData.Bounds.x / 4; + finalPos.y += offset * HSettings.VoxelizationSettings.ExactData.Bounds.y / 4; + finalPos.z += -HSettings.VoxelizationSettings.ExactData.Bounds.z / 4; + break; + case OctantIndex.DynamicObjects: + break; + } + + transform.localPosition += finalPos; + } + +#if UNITY_EDITOR + + private void OnDrawGizmos() + { + if (HSettings.DebugSettings.EnableCamerasVisualization == false) + return; + + var color = Gizmos.color; + Gizmos.color = new Color(1, 1, 1, 0.2f); + + Vector3 position = _camera.transform.position; + + // Size = height / 2 + // Aspect = width / height + // + // height = 2f * size; + // width = height * aspect; + Vector3 size = new Vector3(2f * _camera.orthographicSize, _camera.farClipPlane * 2f, 2f * _camera.orthographicSize * _camera.aspect); + + Gizmos.DrawCube(position, size); + + Gizmos.color = color; + } + +#endif + + private void SetParams(OctantIndex octantIndex) + { + float scale = octantIndex == OctantIndex.DynamicObjects ? 1f : 2f; + _camera.cullingMask = ~0; //voxelizationData.VoxelizationMask; + _camera.orthographic = true; + _camera.farClipPlane = HSettings.VoxelizationSettings.ExactData.Bounds.z / (2 * scale); + _camera.nearClipPlane = -HSettings.VoxelizationSettings.ExactData.Bounds.z / (2 * scale); + _camera.orthographicSize = .5f * HSettings.VoxelizationSettings.ExactData.Bounds.x / scale; + _camera.aspect = 1; + } + + private void CreateCamera() + { + if (_camera == null) + { + _camera = gameObject.AddComponent(); + _camera.aspect = 1f; + _camera.orthographic = true; + _camera.enabled = false; + _camera.hideFlags = HideFlags.HideInHierarchy; + } + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelOctantCamera.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelOctantCamera.cs.meta new file mode 100644 index 000000000..38dd13259 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelOctantCamera.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 811be9a1eb8d0ef42a797e9b2aa81ab4 +timeCreated: 1715956615 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelOctantCamera.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelsService.cs b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelsService.cs new file mode 100644 index 000000000..122610347 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelsService.cs @@ -0,0 +1,193 @@ +using HTraceWSGI.Scripts.Data.Private; +using HTraceWSGI.Scripts.Extensions; +using HTraceWSGI.Scripts.Globals; +using UnityEngine; + +namespace HTraceWSGI.Scripts.Services.VoxelCameras +{ + [ExecuteAlways] + public class VoxelsService : IService + { + private static VoxelsService _instance; + + public static VoxelsService Instance + { + get + { + if (_instance == null) + _instance = new VoxelsService(); + return _instance; + } + } + + private bool _initialized; + + //Debug fields + internal Bounds BoundsGizmo; + + private Transform _prevAttachTo; + private int _prevLodMax; + + internal bool NeedToReallocForUI + { + get { return _needToReallocForUI; } + } + + //UI fields for Apply Params button + private bool _needToReallocForUI = false; + private float _prevDensityUI; + private int _prevVoxelBoundsUI; + private int _prevOverrideBoundsHeightUI; + + internal void Initialize(int layer) + { + CreateVoxelCamera(layer); + CreateVoxelCullingCamera(layer); + CreateVoxelOctantCamera(layer); + + if (HSettings.VoxelizationSettings.AttachTo == null && Camera.main != null) + HSettings.VoxelizationSettings.AttachTo = Camera.main.transform; + _prevAttachTo = HSettings.VoxelizationSettings.AttachTo; + + _initialized = true; + } + + public void LateUpdate() + { + if (!_initialized || HSettings.VoxelizationSettings == null) + return; + + CheckBounds(); + HSettings.VoxelizationSettings.UpdateData(); + CheckPrevValues(); + + if (HSettings.DebugSettings != null) + { + VoxelizationRuntimeData.VoxelCamera.Camera.gameObject.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + VoxelizationRuntimeData.VoxelOctantCamera.Camera.gameObject.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + VoxelizationRuntimeData.CullingCamera.Camera.gameObject.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + } + } + + public void Cleanup() + { + // if (VoxelizationRuntimeData.VoxelCamera != null) + // Object.DestroyImmediate(VoxelizationRuntimeData.VoxelCamera.gameObject); + // if (VoxelizationRuntimeData.CullingCamera != null) + // Object.DestroyImmediate(VoxelizationRuntimeData.CullingCamera.gameObject); + // if (VoxelizationRuntimeData.VoxelOctantCamera != null) + // Object.DestroyImmediate(VoxelizationRuntimeData.VoxelOctantCamera.gameObject); + + _initialized = false; + } + + public Bounds GetVoxelCameraBounds() + { + Vector3 boundCenter = VoxelizationRuntimeData.VoxelCamera.transform.position; + + float height = HSettings.VoxelizationSettings.OverrideBoundsHeightEnable == false ? HSettings.VoxelizationSettings.VoxelBounds : HSettings.VoxelizationSettings.OverrideBoundsHeight; + if (HSettings.VoxelizationSettings.GroundLevelEnable == true && (VoxelizationRuntimeData.VoxelCamera.transform.position.y - height / 2) < HSettings.VoxelizationSettings.GroundLevel) + { + boundCenter = new Vector3(VoxelizationRuntimeData.VoxelCamera.transform.position.x, HSettings.VoxelizationSettings.GroundLevel + height / 2, VoxelizationRuntimeData.VoxelCamera.transform.position.z); + } + + BoundsGizmo.center = boundCenter; + + BoundsGizmo.size = new Vector3( + HSettings.VoxelizationSettings.ExactData.Bounds.x, + HSettings.VoxelizationSettings.ExactData.Bounds.z, + HSettings.VoxelizationSettings.ExactData.Bounds.y); + + return BoundsGizmo; + } + + private void CheckBounds() + { + if (VoxelizationRuntimeData.CheckPrevParams(HSettings.VoxelizationSettings.VoxelDensity, HSettings.VoxelizationSettings.VoxelBounds, HSettings.VoxelizationSettings.OverrideBoundsHeight)) + { + _needToReallocForUI = Time.frameCount > 3; // hack for enter and exit in Play mode + } + else + { + _needToReallocForUI = false; + } + } + + private void CheckPrevValues() + { + if (HSettings.VoxelizationSettings.AttachTo != _prevAttachTo) + { + _prevAttachTo = HSettings.VoxelizationSettings.AttachTo; + //VoxelizationRuntimeData.OnReallocTextures?.Invoke(); // why is it here? enought: + VoxelizationRuntimeData.FullVoxelization = true; + } + if (HSettings.VoxelizationSettings.LODMax != _prevLodMax) + { + _prevLodMax = HSettings.VoxelizationSettings.LODMax; + VoxelizationRuntimeData.FullVoxelization = true; + } + } + + private void CreateVoxelCamera(int layer) + { + if (VoxelizationRuntimeData.VoxelCamera != null) + { + VoxelizationRuntimeData.VoxelCamera.Initialize(this); + return; + } + + GameObject cameraGO = new GameObject(HNames.HTRACE_VOXEL_CAMERA_NAME); + cameraGO.layer = layer; + if (HSettings.DebugSettings != null) + cameraGO.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + // cameraGO.transform.parent = Camera.main.transform; + // cameraGO.transform.localPosition = Vector3.zero; + VoxelizationRuntimeData.VoxelCamera = cameraGO.AddComponent(); + VoxelizationRuntimeData.VoxelCamera.Initialize(this); + } + + private void CreateVoxelCullingCamera(int layer) + { + if (VoxelizationRuntimeData.CullingCamera != null) + { + VoxelizationRuntimeData.CullingCamera.Initialize(); + return; + } + + GameObject cameraGO = new GameObject(HNames.HTRACE_VOXEL_CULLING_CAMERA_NAME); + cameraGO.layer = layer; + cameraGO.transform.parent = VoxelizationRuntimeData.VoxelCamera.gameObject.transform; + cameraGO.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + cameraGO.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + // cameraGO.transform.parent = Camera.main.transform; + // cameraGO.transform.localPosition = Vector3.zero; + VoxelizationRuntimeData.CullingCamera = cameraGO.AddComponent(); + VoxelizationRuntimeData.CullingCamera.Initialize(); + } + + private void CreateVoxelOctantCamera(int layer) + { + if (VoxelizationRuntimeData.VoxelOctantCamera != null) + { + VoxelizationRuntimeData.VoxelOctantCamera.Initialize(); + return; + } + + GameObject cameraGO = new GameObject(HNames.HTRACE_VOXEL_OCTANT_CAMERA_NAME); + cameraGO.layer = layer; + cameraGO.transform.parent = VoxelizationRuntimeData.VoxelCamera.gameObject.transform; + cameraGO.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); + cameraGO.hideFlags = HSettings.DebugSettings.ShowBowels ? HideFlags.DontSave : HideFlags.HideAndDontSave; + // cameraGO.transform.parent = Camera.main.transform; + // cameraGO.transform.localPosition = Vector3.zero; + VoxelizationRuntimeData.VoxelOctantCamera = cameraGO.AddComponent(); + VoxelizationRuntimeData.VoxelOctantCamera.Initialize(); + } + + + internal bool PingVoxelsHandler(VoxelCamera voxelCamera) + { + return VoxelizationRuntimeData.VoxelCamera != voxelCamera; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelsService.cs.meta b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelsService.cs.meta new file mode 100644 index 000000000..4d257aefb --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Services/VoxelCameras/VoxelsService.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b449b68fcb7706443a9ce0be0465e62c +timeCreated: 1681734102 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Wrappers.meta b/Assets/External/HTraceWSGI/Scripts/Wrappers.meta new file mode 100644 index 000000000..343103689 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Wrappers.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8fb352acb8c3b0e43a1cea4c027d2cf9 +timeCreated: 1743099126 \ No newline at end of file diff --git a/Assets/External/HTraceWSGI/Scripts/Wrappers/HDynamicBuffer.cs b/Assets/External/HTraceWSGI/Scripts/Wrappers/HDynamicBuffer.cs new file mode 100644 index 000000000..fead58cc2 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Wrappers/HDynamicBuffer.cs @@ -0,0 +1,92 @@ +using UnityEngine; + +namespace HTraceWSGI.Scripts.Wrappers +{ + public enum BufferType + { + ComputeBuffer, + GraphicsBuffer, + } + + public class HDynamicBuffer + { + private ComputeBuffer _computeBuffer; + private GraphicsBuffer _graphicsBuffer; + + private readonly BufferType _bufferType; + private readonly int _stride; + private int _count; + private int _countScale; + private Vector2Int _resolution; + private readonly ComputeBufferType _computeBufferType; + private readonly GraphicsBuffer.Target _graphicsBufferType; + private readonly bool _avoidDownscale; + + public ComputeBuffer ComputeBuffer => _computeBuffer; + public GraphicsBuffer GraphicsBuffer => _graphicsBuffer; + public int Count => _count; + public Vector2Int Resolution => _resolution; + + public bool IsCreated => _bufferType == BufferType.GraphicsBuffer ? _graphicsBuffer != null : _computeBuffer != null; + + public HDynamicBuffer(BufferType bufferType, int stride, int countScale = 1, + ComputeBufferType computeBufferType = ComputeBufferType.Default, GraphicsBuffer.Target graphicsBufferType = GraphicsBuffer.Target.Structured, + bool avoidDownscale = false) + { + _countScale = Mathf.Max(1, countScale); + _stride = stride; + _bufferType = bufferType; + _computeBufferType = computeBufferType; + _graphicsBufferType = graphicsBufferType; + _avoidDownscale = avoidDownscale; + } + + public void ReAllocIfNeeded(Vector2Int newResolution) + { + if (_resolution == newResolution) + return; + + if (_avoidDownscale == true && _resolution.x * _resolution.y > newResolution.x * newResolution.y) + return; + + Release(); + + _resolution = newResolution; + _count = newResolution.x * newResolution.y * _countScale; + + switch (_bufferType) + { + case BufferType.ComputeBuffer: + _computeBuffer = new ComputeBuffer(_count, _stride, _computeBufferType); + break; + case BufferType.GraphicsBuffer: + _graphicsBuffer = new GraphicsBuffer(_graphicsBufferType, _count, _stride); + break; + } + } + + public void SetBuffer(ComputeShader shader, string name, int kernelIndex) + { + switch (_bufferType) + { + case BufferType.ComputeBuffer: + shader.SetBuffer(kernelIndex, name, _computeBuffer); + break; + case BufferType.GraphicsBuffer: + shader.SetBuffer(kernelIndex, name, _graphicsBuffer); + break; + } + } + + public void Release() + { + _computeBuffer?.Release(); + _computeBuffer = null; + + _graphicsBuffer?.Release(); + _graphicsBuffer = null; + + _resolution = Vector2Int.zero; + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Wrappers/HDynamicBuffer.cs.meta b/Assets/External/HTraceWSGI/Scripts/Wrappers/HDynamicBuffer.cs.meta new file mode 100644 index 000000000..29b08ade2 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Wrappers/HDynamicBuffer.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 22e2cb9949dab074c99abd88b0d98d5e +timeCreated: 1747323970 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Wrappers/HDynamicBuffer.cs + uploadId: 925118 diff --git a/Assets/External/HTraceWSGI/Scripts/Wrappers/RTWrapper.cs b/Assets/External/HTraceWSGI/Scripts/Wrappers/RTWrapper.cs new file mode 100644 index 000000000..7f5a888b0 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Wrappers/RTWrapper.cs @@ -0,0 +1,202 @@ +//pipelinedefine +#define H_URP + +using HTraceWSGI.Scripts.Globals; +using UnityEngine; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; +using UnityEngine.Rendering.RenderGraphModule; +using UnityEngine.Rendering.Universal; + +namespace HTraceWSGI.Scripts.Wrappers +{ + public class RTWrapper + { + public RTHandle rt; +#if NONE + public RenderTexture rt; +#endif + + +#if NONE + public void HTextureAlloc(string name, Vector2 resolutionWidthHeight, GraphicsFormat graphicsFormat, int volumeDepthOrSlices = -1, int depthBufferBits = 0, + TextureDimension textureDimension = TextureDimension.Unknown, + bool useMipMap = false, bool autoGenerateMips = false, bool enableRandomWrite = true, bool useDynamicScale = true) //useDynamicScale default = true for Upscalers switch between Hardware and Software + { + volumeDepthOrSlices = volumeDepthOrSlices == -1 ? HRenderer.TextureXrSlices : volumeDepthOrSlices; + textureDimension = textureDimension == TextureDimension.Unknown ? TextureDimension.Tex2D : textureDimension; + + var dscr = new RenderTextureDescriptor(Mathf.CeilToInt(resolutionWidthHeight.x), Mathf.CeilToInt(resolutionWidthHeight.y)); + dscr.graphicsFormat = graphicsFormat; + dscr.volumeDepth = volumeDepthOrSlices; + dscr.depthBufferBits = depthBufferBits; //only 24 bits contains Stencil buffer + dscr.dimension = textureDimension; + dscr.useMipMap = useMipMap; + dscr.autoGenerateMips = autoGenerateMips; + dscr.enableRandomWrite = enableRandomWrite; + dscr.useDynamicScale = useDynamicScale; + + rt = new RenderTexture(dscr); + rt.name = name; + rt.Create(); + } + + public void HTextureAlloc(string name, Vector2 resolutionWidthHeight, RenderTextureFormat renderTextureFormat, int volumeDepthOrSlices = -1, int depthBufferBits = 0, + TextureDimension textureDimension = TextureDimension.Unknown, + bool useMipMap = false, bool autoGenerateMips = false, bool enableRandomWrite = true, bool useDynamicScale = true) //useDynamicScale default = true for Upscalers switch between Hardware and Software + { + volumeDepthOrSlices = volumeDepthOrSlices == -1 ? HRenderer.TextureXrSlices : volumeDepthOrSlices; + textureDimension = textureDimension == TextureDimension.Unknown ? TextureDimension.Tex2D : textureDimension; + + var dscr = new RenderTextureDescriptor(Mathf.CeilToInt(resolutionWidthHeight.x), Mathf.CeilToInt(resolutionWidthHeight.y)); + dscr.colorFormat = renderTextureFormat; + dscr.volumeDepth = volumeDepthOrSlices; + dscr.depthBufferBits = depthBufferBits; //only 24 bits contains Stencil buffer + dscr.dimension = textureDimension; + dscr.useMipMap = useMipMap; + dscr.autoGenerateMips = autoGenerateMips; + dscr.enableRandomWrite = enableRandomWrite; + dscr.useDynamicScale = useDynamicScale; + + rt = new RenderTexture(dscr); + rt.name = name; + rt.Create(); + } + + public void HTextureAlloc(string name, int width, int height, GraphicsFormat graphicsFormat, int volumeDepthOrSlices = -1, int depthBufferBits = 0, TextureDimension textureDimension = TextureDimension.Tex2D + , bool useMipMap = false, bool autoGenerateMips = false, bool enableRandomWrite = true, bool useDynamicScale = true, int mipCount = 1) + { + volumeDepthOrSlices = volumeDepthOrSlices == -1 ? HRenderer.TextureXrSlices : volumeDepthOrSlices; + textureDimension = textureDimension == TextureDimension.Unknown ? TextureDimension.Tex2D : textureDimension; + + var dscr = new RenderTextureDescriptor(width, height); + dscr.graphicsFormat = graphicsFormat; + dscr.volumeDepth = volumeDepthOrSlices; + dscr.depthBufferBits = depthBufferBits; //only 24 bits contains Stencil buffer + dscr.dimension = textureDimension; + dscr.useMipMap = useMipMap; + dscr.autoGenerateMips = autoGenerateMips; + dscr.enableRandomWrite = enableRandomWrite; + dscr.useDynamicScale = useDynamicScale; + dscr.mipCount = mipCount; + + rt = new RenderTexture(dscr); + rt.name = name; + rt.Create(); + } + + public void HTextureAlloc(string name, int width, int height, RenderTextureFormat renderTextureFormat, int volumeDepthOrSlices = -1, int depthBufferBits = 0, TextureDimension textureDimension = TextureDimension.Tex2D, + bool useMipMap = false, bool autoGenerateMips = false, bool enableRandomWrite = true, bool useDynamicScale = true) + { + volumeDepthOrSlices = volumeDepthOrSlices == -1 ? HRenderer.TextureXrSlices : volumeDepthOrSlices; + textureDimension = textureDimension == TextureDimension.Unknown ? TextureDimension.Tex2D : textureDimension; + + var dscr = new RenderTextureDescriptor(width, height); + dscr.colorFormat = renderTextureFormat; + dscr.volumeDepth = volumeDepthOrSlices; + dscr.depthBufferBits = depthBufferBits; //only 24 bits contains Stencil buffer + dscr.dimension = textureDimension; + dscr.useMipMap = useMipMap; + dscr.autoGenerateMips = autoGenerateMips; + dscr.enableRandomWrite = enableRandomWrite; + dscr.useDynamicScale = useDynamicScale; + + rt = new RenderTexture(dscr); + rt.name = name; + rt.Create(); + } + + + public void HRelease() + { + if (rt != null) + rt.Release(); + } +#endif + + public void HTextureAlloc(string name, Vector2 scaleFactor, GraphicsFormat graphicsFormat, int volumeDepthOrSlices = -1, int depthBufferBits = 0, + TextureDimension textureDimension = TextureDimension.Unknown, + bool useMipMap = false, bool autoGenerateMips = false, bool enableRandomWrite = true, bool useDynamicScale = true) //useDynamicScale default = true for Upscalers switch between Hardware and Software + { + volumeDepthOrSlices = volumeDepthOrSlices == -1 ? TextureXR.slices : volumeDepthOrSlices; + textureDimension = textureDimension == TextureDimension.Unknown ? TextureXR.dimension : textureDimension; + + rt = RTHandles.Alloc(scaleFactor, volumeDepthOrSlices, dimension: textureDimension, colorFormat: graphicsFormat, name: name, + enableRandomWrite: enableRandomWrite, useMipMap: useMipMap, useDynamicScale: useDynamicScale, autoGenerateMips: autoGenerateMips, + depthBufferBits: (DepthBits)depthBufferBits); + } + + public void HTextureAlloc(string name, ScaleFunc scaleFunc, GraphicsFormat graphicsFormat, int volumeDepthOrSlices = -1, int depthBufferBits = 0, + TextureDimension textureDimension = TextureDimension.Unknown, + bool useMipMap = false, bool autoGenerateMips = false, bool enableRandomWrite = true, bool useDynamicScale = true) //useDynamicScale default = true for Upscalers switch between Hardware and Software + { + volumeDepthOrSlices = volumeDepthOrSlices == -1 ? TextureXR.slices : volumeDepthOrSlices; + textureDimension = textureDimension == TextureDimension.Unknown ? TextureXR.dimension : textureDimension; + + rt = RTHandles.Alloc(scaleFunc, volumeDepthOrSlices, dimension: textureDimension, colorFormat: graphicsFormat, name: name, + enableRandomWrite: enableRandomWrite, useMipMap: useMipMap, useDynamicScale: useDynamicScale, autoGenerateMips: autoGenerateMips, + depthBufferBits: (DepthBits)depthBufferBits); + } + + public void HTextureAlloc(string name, int width, int height, GraphicsFormat graphicsFormat, int volumeDepthOrSlices = -1, int depthBufferBits = 0, + TextureDimension textureDimension = TextureDimension.Unknown, + bool useMipMap = false, bool autoGenerateMips = false, bool enableRandomWrite = true, bool useDynamicScale = true) //useDynamicScale default = true for Upscalers switch between Hardware and Software + { + volumeDepthOrSlices = volumeDepthOrSlices == -1 ? TextureXR.slices : volumeDepthOrSlices; + textureDimension = textureDimension == TextureDimension.Unknown ? TextureXR.dimension : textureDimension; + + rt = RTHandles.Alloc(width, height, volumeDepthOrSlices, dimension: textureDimension, colorFormat: graphicsFormat, name: name, + enableRandomWrite: enableRandomWrite, useMipMap: useMipMap, useDynamicScale: useDynamicScale, autoGenerateMips: autoGenerateMips, + depthBufferBits: (DepthBits)depthBufferBits); + } + + public void HRelease() + { + RTHandles.Release(rt); + } + + public void ReAllocateIfNeeded(string name, ref RenderTextureDescriptor inputDescriptor, GraphicsFormat graphicsFormat = GraphicsFormat.None, + int width = -1, int height = -1, int volumeDepth = 1, + TextureDimension dimension = TextureDimension.Tex2D, + bool enableRandomWrite = true, bool useMipMap = false, bool autoGenerateMips = false, + bool useDynamicScale = false) + { + if (dimension != TextureDimension.Tex2D || width > 0 || height > 0) //conditions to create new descriptor + { + RenderTextureDescriptor newDesc = inputDescriptor; + + newDesc.width = width == -1 ? inputDescriptor.width : width; + newDesc.height = height == -1 ? inputDescriptor.height : height; + newDesc.volumeDepth = volumeDepth; + newDesc.dimension = dimension; + newDesc.graphicsFormat = graphicsFormat; + newDesc.autoGenerateMips = autoGenerateMips; + newDesc.useMipMap = useMipMap; + newDesc.enableRandomWrite = enableRandomWrite; + newDesc.msaaSamples = 1; + newDesc.useDynamicScale = false; + +#if UNITY_2023_3_OR_NEWER + RenderingUtils.ReAllocateHandleIfNeeded(ref rt, newDesc, name: name); +#else + RenderingUtils.ReAllocateIfNeeded(ref rt, newDesc, name: name); +#endif + return; + } + + inputDescriptor.volumeDepth = volumeDepth; + inputDescriptor.graphicsFormat = graphicsFormat; + inputDescriptor.autoGenerateMips = autoGenerateMips; + inputDescriptor.useMipMap = useMipMap; + inputDescriptor.enableRandomWrite = enableRandomWrite; + inputDescriptor.msaaSamples = 1; + inputDescriptor.useDynamicScale = false; + +#if UNITY_2023_3_OR_NEWER + RenderingUtils.ReAllocateHandleIfNeeded(ref rt, inputDescriptor, name: name); +#else + RenderingUtils.ReAllocateIfNeeded(ref rt, inputDescriptor, name: name); +#endif + } + } +} diff --git a/Assets/External/HTraceWSGI/Scripts/Wrappers/RTWrapper.cs.meta b/Assets/External/HTraceWSGI/Scripts/Wrappers/RTWrapper.cs.meta new file mode 100644 index 000000000..5c0902b11 --- /dev/null +++ b/Assets/External/HTraceWSGI/Scripts/Wrappers/RTWrapper.cs.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 708d1285af610564885f8fbb28f172d1 +timeCreated: 1729184161 +AssetOrigin: + serializedVersion: 1 + productId: 379716 + packageName: 'HTrace: World Space Global Illumination URP | Beta' + packageVersion: 0.9.6 + assetPath: Assets/HTraceWSGI/Scripts/Wrappers/RTWrapper.cs + uploadId: 925118 diff --git a/Assets/NiloToonURP/Shaders/NiloToonEnvironment.shader b/Assets/NiloToonURP/Shaders/NiloToonEnvironment.shader index 2d7439acb..2a8506f0a 100644 --- a/Assets/NiloToonURP/Shaders/NiloToonEnvironment.shader +++ b/Assets/NiloToonURP/Shaders/NiloToonEnvironment.shader @@ -370,8 +370,13 @@ Shader "Universal Render Pipeline/NiloToon/NiloToon_Environment" ENDHLSL } - // NiloToon removed GBuffer pass - /* + // [HTrace patch] NiloToon removed this GBuffer pass; re-enabled so HTrace WSGI can capture + // per-pixel albedo + normal of NiloToon_Environment surfaces (HTrace builds its Forward GBuffer + // by rendering the "UniversalGBuffer" shader tag - see GBufferPassURP.cs). Without this pass these + // surfaces receive no GI. Project runs Forward+ (m_RenderingMode: 2), so URP itself never uses this + // pass for lighting; only HTrace's explicit renderer list picks it up -> safe, no look change. + // The include below uses NiloToon's own LitInput (same UnityPerMaterial CBUFFER as the ForwardLit + // pass) to preserve SRP Batcher compatibility. Pass { // Lightmode matches the ShaderPassName set in UniversalRenderPipeline.cs. SRPDefaultUnlit and passes with @@ -454,11 +459,11 @@ Shader "Universal Render Pipeline/NiloToon/NiloToon_Environment" // ------------------------------------- // Includes - #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" + // [HTrace patch] use NiloToon's LitInput (matching CBUFFER) instead of URP's LitInput.hlsl + #include "NiloToonEnvironment_HLSL/NiloToonEnvironment_LitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl" ENDHLSL } - */ Pass { diff --git a/Assets/Resources/Settings/Streamingle Render Pipeline Asset.asset b/Assets/Resources/Settings/Streamingle Render Pipeline Asset.asset index bad75c114..70766f6e5 100644 --- a/Assets/Resources/Settings/Streamingle Render Pipeline Asset.asset +++ b/Assets/Resources/Settings/Streamingle Render Pipeline Asset.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:554ea98d007d1de2aa3a9d5db14411b3dc25fcd3c2e7dcf46ff6cfc63db4af03 -size 4686 +oid sha256:c47fe38b3709e7ba88831b80796498838b7cdfcde05ac0fc39bd4f3df6dfc077 +size 4614 diff --git a/Assets/Resources/Settings/Streamingle Render Pipeline Asset_Renderer.asset b/Assets/Resources/Settings/Streamingle Render Pipeline Asset_Renderer.asset index 25c897d79..c27ea09e6 100644 --- a/Assets/Resources/Settings/Streamingle Render Pipeline Asset_Renderer.asset +++ b/Assets/Resources/Settings/Streamingle Render Pipeline Asset_Renderer.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:89133499f15dbefaf704aaf67b759ae1d7153b47e40942704a67d5e687c291ce -size 21040 +oid sha256:b7b49440c37f270b7e2bdaae5c62b27d34498bdd6bfaaf6538f374cbe6437dc0 +size 20905