├── LICENSE.meta ├── Runtime.meta ├── Shaders.meta ├── README.md.meta ├── package.json.meta ├── Runtime ├── Script.meta ├── RenderFeature.meta ├── Script │ ├── Post_SSGi.cs.meta │ ├── Post_SSR.cs.meta │ ├── Post_SSGi.cs │ └── Post_SSR.cs ├── Infinity.Render.Runtime.asmdef.meta ├── RenderFeature │ ├── PyramidColorGenerator.meta │ ├── PyramidDepthGenerator.meta │ ├── ScreenSpaceReflection.meta │ ├── PyramidColorGenerator │ │ ├── Resources.meta │ │ ├── Script.meta │ │ ├── Resources │ │ │ ├── Shaders.meta │ │ │ └── Shaders │ │ │ │ ├── GaussianDownsampleShader.compute.meta │ │ │ │ └── GaussianDownsampleShader.compute │ │ └── Script │ │ │ ├── PyramidColorGenerator.cs.meta │ │ │ └── PyramidColorGenerator.cs │ ├── PyramidDepthGenerator │ │ ├── Resources.meta │ │ ├── Script.meta │ │ ├── Resources │ │ │ ├── Shaders.meta │ │ │ └── Shaders │ │ │ │ ├── HierarchicalZ_Shader.compute.meta │ │ │ │ └── HierarchicalZ_Shader.compute │ │ └── Script │ │ │ ├── PyramidDepthGenerator.cs.meta │ │ │ └── PyramidDepthGenerator.cs │ ├── ScreenSpaceGlobalIllumination.meta │ ├── ScreenSpaceReflection │ │ ├── Resources.meta │ │ ├── Script.meta │ │ ├── Resources │ │ │ ├── Shaders.meta │ │ │ └── Shaders │ │ │ │ ├── SSR_TraceShader.compute.meta │ │ │ │ └── SSR_TraceShader.compute │ │ └── Script │ │ │ ├── ScreenSpaceReflection.cs.meta │ │ │ └── ScreenSpaceReflection.cs │ ├── SpatialTemporalVarianceFilter.meta │ ├── ScreenSpaceGlobalIllumination │ │ ├── Script.meta │ │ ├── Resources.meta │ │ ├── Resources │ │ │ ├── Shaders.meta │ │ │ └── Shaders │ │ │ │ ├── SSGi_TraceShader.compute.meta │ │ │ │ └── SSGi_TraceShader.compute │ │ └── Script │ │ │ ├── ScreenSpaceGlobalIllumination.cs.meta │ │ │ └── ScreenSpaceGlobalIllumination.cs │ └── SpatialTemporalVarianceFilter │ │ ├── Script.meta │ │ ├── Resources.meta │ │ ├── Resources │ │ ├── Shaders.meta │ │ └── Shaders │ │ │ └── SVGF_Shader.compute.meta │ │ └── Script │ │ ├── SpatialTemporalVarianceFilter.cs.meta │ │ └── SpatialTemporalVarianceFilter.cs └── Infinity.Render.Runtime.asmdef ├── Shaders ├── BuiltIn.meta ├── Private.meta ├── Private │ ├── BSDF.hlsl.meta │ ├── Common.hlsl.meta │ ├── Random.hlsl.meta │ ├── RayTracing.meta │ ├── Lightmap.hlsl.meta │ ├── Montcalo.hlsl.meta │ ├── PackData.hlsl.meta │ ├── RayTracing │ │ ├── Common.meta │ │ ├── Variance.meta │ │ ├── ScreenSpaceRayTrace.meta │ │ ├── Common │ │ │ ├── RayTracingCommon.hlsl.meta │ │ │ └── RayTracingCommon.hlsl │ │ ├── Variance │ │ │ ├── VarianceEstimator.hlsl.meta │ │ │ └── VarianceEstimator.hlsl │ │ └── ScreenSpaceRayTrace │ │ │ └── SSRTRayCast.hlsl.meta │ ├── ShadingModel.hlsl.meta │ ├── ShaderVariable.hlsl.meta │ ├── ImageBasedLighting.hlsl.meta │ ├── ShaderVariable.hlsl │ ├── Lightmap.hlsl │ ├── PackData.hlsl │ ├── ShadingModel.hlsl │ ├── ImageBasedLighting.hlsl │ ├── Montcalo.hlsl │ ├── BSDF.hlsl │ ├── Common.hlsl │ └── Random.hlsl ├── BuiltIn │ ├── SSRCompositing.shader.meta │ └── SSRCompositing.shader ├── Infinity.Render.Shaders.asmdef.meta └── Infinity.Render.Shaders.asmdef ├── .gitattributes ├── README.md ├── package.json ├── .gitignore └── LICENSE /LICENSE.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0dc9678b427a207c59b4b9b1ed2b0f1589e86e710aa9b423d2fb00e75ba73dd1 3 | size 155 4 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8fd90619f0ac2974fa41e46749716ae05ff9de5f625ba5bbacea70c2b4fcc24f 3 | size 172 4 | -------------------------------------------------------------------------------- /Shaders.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:53b53ed37824f3599f7aff34fc53469428124a24706471bc11b8e2b70cf572af 3 | size 172 4 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:761faa44be965b2a29c128719b5900d4055631427be882ef1bbdac6d64ef7fb1 3 | size 158 4 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f5d7ba5c9b0250d8c1928674eec8308d0081b392ed943c9b51042c7f9939fc30 3 | size 170 4 | -------------------------------------------------------------------------------- /Runtime/Script.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a0c867b1b3772eddbb645ed9574f9ef56aec6cf042b67d4fea350f6195dcb715 3 | size 172 4 | -------------------------------------------------------------------------------- /Shaders/BuiltIn.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fae2d0c717f282d31eb77288151d44f7175b38761ce667605af68ca4356ba7fd 3 | size 172 4 | -------------------------------------------------------------------------------- /Shaders/Private.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7168e401e692fa8f9928c63ee70c9889b60412ee5a9ad36d6c148ae24835c3a3 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:995e0bc91a17e3f8e4335cec5cf0ecc01ed7b3f1a79c76fb3ccaca1cda761311 3 | size 172 4 | -------------------------------------------------------------------------------- /Runtime/Script/Post_SSGi.cs.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:bd7b1ca4350c64e433a269a0fe05d0e87f5ac473c2aee3a24ec9dd2a603bc9dc 3 | size 243 4 | -------------------------------------------------------------------------------- /Runtime/Script/Post_SSR.cs.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:621350a4ca7ba8208578978d369f2cbf69e7b8eb342d786e22658c5769bfc5d2 3 | size 243 4 | -------------------------------------------------------------------------------- /Shaders/Private/BSDF.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:046fe45219de9897224fa787869a00dea98b4da2490ec3c8a7467a8db496680b 3 | size 213 4 | -------------------------------------------------------------------------------- /Shaders/Private/Common.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:32483fb8579011adfed5cf54576370bc49de4f27f17168763d68f12ccba2d118 3 | size 213 4 | -------------------------------------------------------------------------------- /Shaders/Private/Random.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d3db60a5fad43773a236ea34fc0b940541ef1d627d8071b2379ac5ce5e3c0f55 3 | size 213 4 | -------------------------------------------------------------------------------- /Shaders/Private/RayTracing.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:82a2c827c5e4f7e91b1a7c3d7e3048b1dc6f9016ecaa83b567ed4bf1246f87e4 3 | size 180 4 | -------------------------------------------------------------------------------- /Shaders/Private/Lightmap.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f0d9b3cae433613a3bad8013594ad92ce0ea7c0d2bb88c6c1c13be16fd8b7660 3 | size 213 4 | -------------------------------------------------------------------------------- /Shaders/Private/Montcalo.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3f48660265a336b123077f062448ed57f97c903afac2c90fda61588f12acc224 3 | size 213 4 | -------------------------------------------------------------------------------- /Shaders/Private/PackData.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:28e38b9a58c539469f420ddee15f4c9625eaaf693698cf0af61fda48dc52215a 3 | size 213 4 | -------------------------------------------------------------------------------- /Shaders/Private/RayTracing/Common.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:64ca601c84b23d31e1a742925a1c7641b5f090a27192b59be767d264d9b0750b 3 | size 180 4 | -------------------------------------------------------------------------------- /Shaders/Private/ShadingModel.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b03d931c79c34fe9a93c91703a85bb068ee9dba58282a49c0c7afc81a24b010c 3 | size 213 4 | -------------------------------------------------------------------------------- /Runtime/Infinity.Render.Runtime.asmdef.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:eaa26fac39d0659ff8947e2721787c0f1959890d75a8e9ea3a128ea409f47264 3 | size 173 4 | -------------------------------------------------------------------------------- /Shaders/BuiltIn/SSRCompositing.shader.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7cf5945572426beb3ce26df6ea277eb4f81b4d8a8e18e77dfc0773eae7ad5093 3 | size 204 4 | -------------------------------------------------------------------------------- /Shaders/Infinity.Render.Shaders.asmdef.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c34771245e9c1f97563401ded402f6ad4f1ae792839fec5903a9163dfc7da01f 3 | size 173 4 | -------------------------------------------------------------------------------- /Shaders/Private/RayTracing/Variance.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d394b4c400abe75a9673eec71daf9c4af0b0335ff39d1203a9c86bcc249e2469 3 | size 180 4 | -------------------------------------------------------------------------------- /Shaders/Private/ShaderVariable.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:29fa02a05c99eb17fa50ed4472c0b6e6b80838a636097eb8cdab03b03e473c90 3 | size 213 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidColorGenerator.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c5858c475d7d7ecbe3826760e2a1dc778f0ed87a7633d72ea2a5452ea5e5e1dc 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidDepthGenerator.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:85ebcb2f50cb3c1367b4f9099dd5fd9bb252d7d32356f3f155b24077b3b075ac 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceReflection.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f3b6c1d9f81b2cd4520ed22419a49b6a4995aa8f1d570daab859f9004a921c61 3 | size 180 4 | -------------------------------------------------------------------------------- /Shaders/Private/ImageBasedLighting.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8d9749185eed0c22e779300158cf9ef4cade90b8eb4c4269c197878a1d073992 3 | size 213 4 | -------------------------------------------------------------------------------- /Shaders/Private/RayTracing/ScreenSpaceRayTrace.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fe77b08a17fa0ad7305f269f5f44ec0ea951c4990e8e16ae727f577c3a67cd94 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidColorGenerator/Resources.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:22c0ba32268773325439b38ce4fff4b0d847ee8470a2bac4f76c0649dbf96266 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidColorGenerator/Script.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:813d892bd90b2b9917daedc2808c814b1e50fef9461774ee6969378a88a0e7ac 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidDepthGenerator/Resources.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e1a5aee809c27ed37910a2eca2e704d1f6837211a2843efdf6735e3ad28ae652 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidDepthGenerator/Script.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0fa237036ed02c4e257d04c67fd4f0c7b0da16851eea81a1640b915d943da2f0 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceGlobalIllumination.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8d3552cba5d1601f4b2a25d4e6ded8f0093e46029cc902630bd70c5ff71acef7 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceReflection/Resources.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:249036a0d0a8d9dfa1996e272f9d53edc25afdc8f9141660f880ec3248835f78 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceReflection/Script.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fc5044a887059bae653b3011d31b1dca9c600934d45541ad6d7778f555f1ff19 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/SpatialTemporalVarianceFilter.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b43b064268fe18ecbad3f2b5be33fe9d69458c7126f64b9283af1cac2f3abd7d 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceGlobalIllumination/Script.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:053f8a7c17713190b05099ca10f97a240193de25edb379dadd84b5594b84dbe4 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/SpatialTemporalVarianceFilter/Script.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:73b4c311752dbe66942556c58b4adea53aec8eb8ca56dc5af1817f6794c2af93 3 | size 180 4 | -------------------------------------------------------------------------------- /Shaders/Private/RayTracing/Common/RayTracingCommon.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:77e25388c9bbd4f9a845cc22cb25b8b6012df223bb87bf22cb9d23eb2610bd43 3 | size 213 4 | -------------------------------------------------------------------------------- /Shaders/Private/RayTracing/Variance/VarianceEstimator.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:56214c21c57fb05900c8f0e0e7fcdf606931da04b447f95ec1de6189e48330ef 3 | size 213 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidColorGenerator/Resources/Shaders.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ba0ec7234e96168f8cb9b62e32df2e40ab3704aa7a112cad8cffab29242179a9 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidDepthGenerator/Resources/Shaders.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:95b5675b092a6eeb93a50b938bee8ac41b62fc2b948ba76f4103f787b2a80937 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceGlobalIllumination/Resources.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8caa8ef5202adad7906fa89503c503982b23a05ef3b80490e2a7286b0f4ede0d 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceReflection/Resources/Shaders.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:cf8d9dff8ce08c1f6dce776d741ea2139478233a1f3c60f09ddc543f96a00de0 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/SpatialTemporalVarianceFilter/Resources.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c6de8753b933fdb4208871cb2d7228933145de63edbdfd14b4a800fddeebdab8 3 | size 180 4 | -------------------------------------------------------------------------------- /Shaders/Private/RayTracing/ScreenSpaceRayTrace/SSRTRayCast.hlsl.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6a350d80c1d0941c03297ff87a6e2d785e8ff5ad7856c1fc672ed7881a36944b 3 | size 213 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceGlobalIllumination/Resources/Shaders.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0c5b04ad8a0cc96839545778220f3b0b08113e1df2278b8f8e2ca833c7d7036e 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/SpatialTemporalVarianceFilter/Resources/Shaders.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4c64115d688cb86ca19a8071615b87d46f6588275c3edbed68d6bdd5f87d4b15 3 | size 180 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidColorGenerator/Script/PyramidColorGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3abc7e9de4920d13b3c702f60f8fe577fa57fbec159f0d3152f4831f54ae99bb 3 | size 254 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidDepthGenerator/Script/PyramidDepthGenerator.cs.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0de0e6450a28d3fc62f05bb71f08608c73cc5e49f9ff8f885ae2bfe0c032668d 3 | size 254 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceReflection/Script/ScreenSpaceReflection.cs.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b4799284a16a492cb44a6e7bfb867ec5f6ac239065e9d75f05a411277d91ae25 3 | size 254 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceReflection/Resources/Shaders/SSR_TraceShader.compute.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e072226f9a7509acd5ff3a77eba7e8bf0946faec65a999b65ca196b7454a0377 3 | size 194 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidDepthGenerator/Resources/Shaders/HierarchicalZ_Shader.compute.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2c70c29405f5a6993f9fe899801d884debd6e0c98d31a6ba3a8e657167a0b97c 3 | size 189 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceGlobalIllumination/Script/ScreenSpaceGlobalIllumination.cs.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8ea24ef420e9718da4160158b03f0b9dd5a85a21f603f68f2a02220e016b9d0f 3 | size 254 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/SpatialTemporalVarianceFilter/Resources/Shaders/SVGF_Shader.compute.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2bf19b9e0efa91bb8ab39e9e87a3c3fe6a1c4f1e1a14f024ab52b487944eb123 3 | size 194 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/SpatialTemporalVarianceFilter/Script/SpatialTemporalVarianceFilter.cs.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:452365a1620661beee31428a8cab488d3f75a218354a2601c6dcfd75d96fc88a 3 | size 254 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidColorGenerator/Resources/Shaders/GaussianDownsampleShader.compute.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:56e802c1cd2aa100c1f7aeb7070e8682a4a878fb9f8dfeb494a57d2d3893f766 3 | size 214 4 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceGlobalIllumination/Resources/Shaders/SSGi_TraceShader.compute.meta: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1e6240f881489f0936c4b93c459d94414ce8457543cb6aa46bcc801d05bb2dff 3 | size 194 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.tif filter=lfs diff=lfs merge=lfs -text 2 | *.png filter=lfs diff=lfs merge=lfs -text 3 | *.tga filter=lfs diff=lfs merge=lfs -text 4 | *.unity filter=lfs diff=lfs merge=lfs -text 5 | *.asset filter=lfs diff=lfs merge=lfs -text 6 | *.meta filter=lfs diff=lfs merge=lfs -text 7 | *.hdr filter=lfs diff=lfs merge=lfs -text 8 | *.fbx filter=lfs diff=lfs merge=lfs -text 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # InfinityScreenSpaceLighting 2 | ScreenSpaceLighting for Unity BuiltIn in PostProcessStackV2. 3 | 4 | ## Feature 5 | Completed : 6 | * Stochastic Screen Space Reflection. 7 | 8 | 9 | Developerment : 10 | * Screen Space Global Illumination. 11 | * GrandTruth Ambient/Reflection Occlusion. 12 | 13 | 14 | Planned : 15 | * Screen Space Refraction. 16 | * Separable Subsurface Scatter. 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.infinity.render.ssl", 3 | "description": "InfinityRender ScreenSpaceLightingPack", 4 | "version": "1.0.0", 5 | "unity": "2019.4", 6 | "unityRelease": "0f1", 7 | "displayName": "InfinityScreenSpaceStack", 8 | "dependencies": { 9 | "com.unity.postprocessing": "2.3.0" 10 | }, 11 | "keywords": [ 12 | "graphics", 13 | "performance", 14 | "rendering", 15 | "render", 16 | "pipeline" 17 | ], 18 | "type": "library" 19 | } -------------------------------------------------------------------------------- /Shaders/Infinity.Render.Shaders.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Infinity.Render.Shaders", 3 | "references": [], 4 | "includePlatforms": [], 5 | "excludePlatforms": [], 6 | "allowUnsafeCode": true, 7 | "overrideReferences": false, 8 | "precompiledReferences": [], 9 | "autoReferenced": true, 10 | "defineConstraints": [], 11 | "versionDefines": [ 12 | { 13 | "name": "com.infinity.render", 14 | "expression": "0.0.0", 15 | "define": "InfinityRenderShaders" 16 | } 17 | ], 18 | "noEngineReferences": false 19 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Bb]uilds/ 6 | [Ll]ogs/ 7 | Assets/TemporalFolder* 8 | 9 | # Visual Studio cache directory 10 | .vs/ 11 | .vscode/ 12 | 13 | # Autogenerated VS/MD/Consulo solution and project files 14 | ExportedObj/ 15 | .consulo/ 16 | *.csproj 17 | *.unityproj 18 | *.sln 19 | *.suo 20 | *.tmp 21 | *.user 22 | *.userprefs 23 | *.pidb 24 | *.booproj 25 | *.svd 26 | *.pdb 27 | *.opendb 28 | 29 | # Unity3D generated meta files 30 | *.pidb.meta 31 | *.pdb.meta 32 | 33 | # Unity3D Generated File On Crash Reports 34 | sysinfo.txt 35 | 36 | # Builds 37 | *.apk 38 | *.unitypackage 39 | -------------------------------------------------------------------------------- /Runtime/Infinity.Render.Runtime.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Infinity.Render.Runtime", 3 | "references": [ 4 | "Unity.Mathematics", 5 | "Unity.Postprocessing.Runtime" 6 | ], 7 | "includePlatforms": [], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": true, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [ 15 | { 16 | "name": "com.infinity.render", 17 | "expression": "0.0.0", 18 | "define": "InfinityRenderRuntime" 19 | } 20 | ], 21 | "noEngineReferences": false 22 | } -------------------------------------------------------------------------------- /Shaders/Private/RayTracing/Variance/VarianceEstimator.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef _VarianceEstimator_ 2 | #define _VarianceEstimator_ 3 | 4 | struct VarianceEstimator 5 | { 6 | int num; 7 | float oldM; 8 | float oldS; 9 | float newM; 10 | float newS; 11 | }; 12 | 13 | void InitializeVarianceEstimator(out VarianceEstimator variance) 14 | { 15 | variance.num = 0; 16 | variance.oldM = 0; 17 | variance.oldS = 0; 18 | variance.newM = 0; 19 | variance.newS = 0; 20 | } 21 | 22 | void PushValue(inout VarianceEstimator variance, float value) 23 | { 24 | variance.num++; 25 | 26 | if (variance.num == 1) { 27 | variance.oldM = variance.newM = value; 28 | variance.oldS = 0; 29 | } else { 30 | variance.newM = variance.oldM + (value - variance.oldM) / variance.num; 31 | variance.newS = variance.oldS + (value - variance.oldM) * (value - variance.newM); 32 | variance.oldM = variance.newM; 33 | variance.oldS = variance.newS; 34 | } 35 | } 36 | 37 | float GetVariance(in VarianceEstimator variance) 38 | { 39 | return ( variance.num > 1 ? max(0.0001, variance.newS) / max(0.0001, (variance.num - 1) ) : 0 ); 40 | } 41 | 42 | #endif -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidDepthGenerator/Resources/Shaders/HierarchicalZ_Shader.compute: -------------------------------------------------------------------------------- 1 | #pragma kernel HiZ_Generation 2 | 3 | float4 _PrevCurr_Inverse_Size; 4 | Texture2D _PrevMipDepth; SamplerState sampler_PrevMipDepth; 5 | RWTexture2D _HierarchicalDepth; 6 | 7 | [numthreads(8, 8, 1)] 8 | void HiZ_Generation (uint3 id : SV_DispatchThreadID) 9 | { 10 | float2 uv = (id.xy + 0.5) * _PrevCurr_Inverse_Size.xy; 11 | float FinalMinZ = _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv, 0); 12 | 13 | /*FinalMinZ = max( FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2( 1, 0) * _PrevCurr_Inverse_Size.zw, 0) ); 14 | FinalMinZ = max( FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2(-1, 0) * _PrevCurr_Inverse_Size.zw, 0) ); 15 | FinalMinZ = max( FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2( 0, 1) * _PrevCurr_Inverse_Size.zw, 0) ); 16 | FinalMinZ = max( FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2( 0, -1) * _PrevCurr_Inverse_Size.zw, 0) ); 17 | FinalMinZ = max( FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2( 1, 1) * _PrevCurr_Inverse_Size.zw, 0) ); 18 | FinalMinZ = max( FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2(-1, 1) * _PrevCurr_Inverse_Size.zw, 0) ); 19 | FinalMinZ = max( FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2( 1, -1) * _PrevCurr_Inverse_Size.zw, 0) ); 20 | FinalMinZ = max( FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2(-1, -1) * _PrevCurr_Inverse_Size.zw, 0) );*/ 21 | 22 | FinalMinZ = max(FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2(0, -1) * _PrevCurr_Inverse_Size.zw, 0)); 23 | FinalMinZ = max(FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2(-1, 0) * _PrevCurr_Inverse_Size.zw, 0)); 24 | FinalMinZ = max(FinalMinZ, _PrevMipDepth.SampleLevel(sampler_PrevMipDepth, uv + int2(-1, -1) * _PrevCurr_Inverse_Size.zw, 0)); 25 | 26 | _HierarchicalDepth[id.xy] = FinalMinZ; 27 | } 28 | -------------------------------------------------------------------------------- /Shaders/Private/ShaderVariable.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef __ShaderVariable__ 2 | #define __ShaderVariable__ 3 | 4 | #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" 5 | 6 | CBUFFER_START(ViewUnifrom) 7 | int FrameIndex; 8 | int Prev_FrameIndex; 9 | float4 TAAJitter; 10 | float4x4 Matrix_WorldToView; 11 | float4x4 Matrix_ViewToWorld; 12 | float4x4 Matrix_Proj; 13 | float4x4 Matrix_InvProj; 14 | float4x4 Matrix_JitterProj; 15 | float4x4 Matrix_InvJitterProj; 16 | float4x4 Matrix_FlipYProj; 17 | float4x4 Matrix_InvFlipYProj; 18 | float4x4 Matrix_FlipYJitterProj; 19 | float4x4 Matrix_InvFlipYJitterProj; 20 | float4x4 Matrix_ViewProj; 21 | float4x4 Matrix_InvViewProj; 22 | float4x4 Matrix_ViewFlipYProj; 23 | float4x4 Matrix_InvViewFlipYProj; 24 | float4x4 Matrix_ViewJitterProj; 25 | float4x4 Matrix_InvViewJitterProj; 26 | float4x4 Matrix_ViewFlipYJitterProj; 27 | float4x4 Matrix_InvViewFlipYJitterProj; 28 | float4x4 Matrix_PrevViewProj; 29 | float4x4 Matrix_PrevViewFlipYProj; 30 | CBUFFER_END 31 | 32 | CBUFFER_START(UnityPerFrame) 33 | float4x4 unity_MatrixV; 34 | float4x4 unity_MatrixInvV; 35 | float4x4 unity_MatrixVP; 36 | CBUFFER_END 37 | 38 | CBUFFER_START(UnityPerDraw) 39 | float4x4 unity_ObjectToWorld; 40 | float4x4 unity_WorldToObject; 41 | float4 unity_LODFade; 42 | float4 unity_WorldTransformParams; 43 | 44 | float4 unity_LightmapST; 45 | float4 unity_DynamicLightmapST; 46 | 47 | float4 unity_RenderingLayer; 48 | 49 | float4 unity_SHAr; 50 | float4 unity_SHAg; 51 | float4 unity_SHAb; 52 | float4 unity_SHBr; 53 | float4 unity_SHBg; 54 | float4 unity_SHBb; 55 | float4 unity_SHC; 56 | 57 | float4 unity_ProbeVolumeParams; 58 | float4x4 unity_ProbeVolumeWorldToObject; 59 | float4 unity_ProbeVolumeSizeInv; 60 | float4 unity_ProbeVolumeMin; 61 | 62 | float4 unity_ProbesOcclusion; 63 | 64 | float4x4 unity_MatrixPreviousM; 65 | float4x4 unity_MatrixPreviousMI; 66 | float4 unity_MotionVectorsParams; 67 | 68 | float4 unity_LightData; 69 | float4 unity_LightIndices[2]; 70 | 71 | float4 unity_SpecCube0_HDR; 72 | float4 unity_SpecCube1_HDR; 73 | CBUFFER_END 74 | 75 | #define UNITY_MATRIX_M unity_ObjectToWorld 76 | #define UNITY_MATRIX_I_M unity_WorldToObject 77 | #define UNITY_MATRIX_V unity_MatrixV 78 | #define UNITY_MATRIX_I_V unity_MatrixInvV 79 | #define UNITY_MATRIX_P Matrix_Proj 80 | #define UNITY_MATRIX_I_P Matrix_InvProj 81 | #define UNITY_MATRIX_VP Matrix_ViewProj //Matrix_ViewJitterProj 82 | #define UNITY_MATRIX_I_VP _InvCameraViewProj 83 | #define UNITY_MATRIX_MV mul(UNITY_MATRIX_V, UNITY_MATRIX_M) 84 | #define UNITY_MATRIX_T_MV transpose(UNITY_MATRIX_MV) 85 | #define UNITY_MATRIX_IT_MV transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)) 86 | #define UNITY_MATRIX_MVP mul(UNITY_MATRIX_VP, UNITY_MATRIX_M) 87 | 88 | #endif -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidDepthGenerator/Script/PyramidDepthGenerator.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Unity.Mathematics; 3 | using UnityEngine.Rendering; 4 | 5 | namespace InfinityTech.Runtime.Rendering.Feature 6 | { 7 | public static class PyramidDepthUniform 8 | { 9 | public static int PrevMipDepth = Shader.PropertyToID("_PrevMipDepth"); 10 | public static int HierarchicalDepth = Shader.PropertyToID("_HierarchicalDepth"); 11 | public static int PrevCurr_InvSize = Shader.PropertyToID("_PrevCurr_Inverse_Size"); 12 | } 13 | 14 | public static class PyramidDepthGenerator 15 | { 16 | private static int MipCount = 9; 17 | 18 | private static ComputeShader PyramidDeptShader { 19 | get { 20 | return Resources.Load("Shaders/HierarchicalZ_Shader"); 21 | } 22 | } 23 | 24 | public static void DepthPyramidInit(ref int[] DepthPyramidMipIDs) 25 | { 26 | if (DepthPyramidMipIDs == null || DepthPyramidMipIDs.Length == 0) { 27 | DepthPyramidMipIDs = new int[MipCount]; 28 | 29 | for (int i = 0; i < MipCount; i++) { 30 | DepthPyramidMipIDs[i] = Shader.PropertyToID("_SSSRDepthMip" + i); 31 | } 32 | } 33 | } 34 | 35 | public static void DepthPyramidUpdate(ref int[] DepthPyramidMipIDs, ref int2 ScreenSize, RenderTargetIdentifier DstRT, CommandBuffer CmdBuffer) { 36 | int2 HiZPyramidSize = ScreenSize; 37 | int2 PrevHiZPyramidSize = ScreenSize; 38 | RenderTargetIdentifier PrevHiZPyramid = DstRT; 39 | 40 | for (int i = 0; i < MipCount; i++) { 41 | HiZPyramidSize.x /= 2; 42 | HiZPyramidSize.y /= 2; 43 | 44 | CmdBuffer.GetTemporaryRT(DepthPyramidMipIDs[i], HiZPyramidSize.x, HiZPyramidSize.y, 0, FilterMode.Point, RenderTextureFormat.RHalf, RenderTextureReadWrite.Default, 1, true); 45 | CmdBuffer.SetComputeTextureParam(PyramidDeptShader, 0, PyramidDepthUniform.PrevMipDepth, PrevHiZPyramid); 46 | CmdBuffer.SetComputeTextureParam(PyramidDeptShader, 0, PyramidDepthUniform.HierarchicalDepth, DepthPyramidMipIDs[i]); 47 | CmdBuffer.SetComputeVectorParam(PyramidDeptShader, PyramidDepthUniform.PrevCurr_InvSize, new float4(1.0f / HiZPyramidSize.x, 1.0f / HiZPyramidSize.y, 1.0f / PrevHiZPyramidSize.x, 1.0f / PrevHiZPyramidSize.y)); 48 | CmdBuffer.DispatchCompute(PyramidDeptShader, 0, Mathf.CeilToInt(HiZPyramidSize.x / 8.0f), Mathf.CeilToInt(HiZPyramidSize.y / 8.0f), 1); 49 | CmdBuffer.CopyTexture(DepthPyramidMipIDs[i], 0, 0, DstRT, 0, i + 1); 50 | 51 | PrevHiZPyramid = DepthPyramidMipIDs[i]; 52 | PrevHiZPyramidSize = HiZPyramidSize; 53 | } for (int i = 0; i < MipCount; i++) { 54 | CmdBuffer.ReleaseTemporaryRT(DepthPyramidMipIDs[i]); 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Shaders/Private/Lightmap.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef _BSDF_ 2 | #define _BSDF_ 3 | 4 | #include "../Private/ShaderVariable.hlsl" 5 | #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" 6 | #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" 7 | 8 | 9 | TEXTURE2D(unity_Lightmap); SAMPLER(samplerunity_Lightmap); 10 | 11 | 12 | half3 SampleSH(half3 normalWS) 13 | { 14 | // LPPV is not supported in Ligthweight Pipeline 15 | real4 SHCoefficients[7]; 16 | SHCoefficients[0] = unity_SHAr; 17 | SHCoefficients[1] = unity_SHAg; 18 | SHCoefficients[2] = unity_SHAb; 19 | SHCoefficients[3] = unity_SHBr; 20 | SHCoefficients[4] = unity_SHBg; 21 | SHCoefficients[5] = unity_SHBb; 22 | SHCoefficients[6] = unity_SHC; 23 | 24 | return max(half3(0, 0, 0), SampleSH9(SHCoefficients, normalWS)); 25 | } 26 | 27 | // SH Vertex Evaluation. Depending on target SH sampling might be 28 | // done completely per vertex or mixed with L2 term per vertex and L0, L1 29 | // per pixel. See SampleSHPixel 30 | half3 SampleSHVertex(half3 normalWS) 31 | { 32 | #if defined(EVALUATE_SH_VERTEX) 33 | return max(half3(0, 0, 0), SampleSH(normalWS)); 34 | #elif defined(EVALUATE_SH_MIXED) 35 | // no max since this is only L2 contribution 36 | return SHEvalLinearL2(normalWS, unity_SHBr, unity_SHBg, unity_SHBb, unity_SHC); 37 | #endif 38 | 39 | // Fully per-pixel. Nothing to compute. 40 | return half3(0.0, 0.0, 0.0); 41 | } 42 | 43 | half3 SampleSHPixel(half3 L2Term, half3 normalWS) 44 | { 45 | #if defined(EVALUATE_SH_VERTEX) 46 | return L2Term; 47 | #elif defined(EVALUATE_SH_MIXED) 48 | half3 L0L1Term = SHEvalLinearL0L1(normalWS, unity_SHAr, unity_SHAg, unity_SHAb); 49 | return max(half3(0, 0, 0), L2Term + L0L1Term); 50 | #endif 51 | 52 | // Default: Evaluate SH fully per-pixel 53 | return SampleSH(normalWS); 54 | } 55 | 56 | half3 SampleLightmap(float2 lightmapUV, half3 normalWS) 57 | { 58 | #ifdef UNITY_LIGHTMAP_FULL_HDR 59 | bool encodedLightmap = false; 60 | #else 61 | bool encodedLightmap = true; 62 | #endif 63 | 64 | half4 decodeInstructions = half4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0h, 0.0h); 65 | 66 | // The shader library sample lightmap functions transform the lightmap uv coords to apply bias and scale. 67 | // However, universal pipeline already transformed those coords in vertex. We pass half4(1, 1, 0, 0) and 68 | // the compiler will optimize the transform away. 69 | half4 transformCoords = half4(1, 1, 0, 0); 70 | 71 | #ifdef DIRLIGHTMAP_COMBINED 72 | return SampleDirectionalLightmap(TEXTURE2D_ARGS(unity_Lightmap, samplerunity_Lightmap), 73 | TEXTURE2D_ARGS(unity_LightmapInd, samplerunity_Lightmap), 74 | lightmapUV, transformCoords, normalWS, encodedLightmap, decodeInstructions); 75 | #elif defined(LIGHTMAP_ON) 76 | return SampleSingleLightmap(TEXTURE2D_ARGS(unity_Lightmap, samplerunity_Lightmap), lightmapUV, transformCoords, encodedLightmap, decodeInstructions); 77 | #else 78 | return half3(0.0, 0.0, 0.0); 79 | #endif 80 | } 81 | 82 | #endif -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidColorGenerator/Script/PyramidColorGenerator.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Unity.Mathematics; 3 | using UnityEngine.Rendering; 4 | 5 | namespace InfinityTech.Runtime.Rendering.Feature 6 | { 7 | public static class PyramidColorUniform 8 | { 9 | public static int PrevLevelColor = Shader.PropertyToID("_Source"); 10 | public static int CurrLevelColor = Shader.PropertyToID("_Result"); 11 | public static int PrevCurr_Size = Shader.PropertyToID("_Size"); 12 | public static int ColorPyramidNumLOD = Shader.PropertyToID("ColorPyramidNumLOD"); 13 | } 14 | 15 | public static class PyramidColorGenerator 16 | { 17 | private static ComputeShader PyramidColorShader { 18 | get { 19 | return Resources.Load("Shaders/GaussianDownsampleShader"); 20 | } 21 | } 22 | 23 | public static void ColorPyramidInit(ref int[] ColorPyramidMipIDs) 24 | { 25 | if (ColorPyramidMipIDs == null || ColorPyramidMipIDs.Length == 0) { 26 | ColorPyramidMipIDs = new int[12]; 27 | 28 | for (int i = 0; i < 12; i++) { 29 | ColorPyramidMipIDs[i] = Shader.PropertyToID("_SSSRGaussianMip" + i); 30 | } 31 | } 32 | } 33 | 34 | public static void ColorPyramidUpdate(ref int[] ColorPyramidMipIDs, ref int2 ScreenSize, RenderTargetIdentifier DstRT , CommandBuffer CmdBuffer) 35 | { 36 | int ColorPyramidCount = Mathf.FloorToInt(Mathf.Log(ScreenSize.x, 2) - 3); 37 | ColorPyramidCount = Mathf.Min(ColorPyramidCount, 12); 38 | CmdBuffer.SetGlobalFloat(PyramidColorUniform.ColorPyramidNumLOD, (float)ColorPyramidCount); 39 | RenderTargetIdentifier PrevColorPyramid = DstRT; 40 | int2 ColorPyramidSize = ScreenSize; 41 | for (int i = 0; i < ColorPyramidCount; i++) { 42 | ColorPyramidSize.x >>= 1; 43 | ColorPyramidSize.y >>= 1; 44 | 45 | CmdBuffer.GetTemporaryRT(ColorPyramidMipIDs[i], ColorPyramidSize.x, ColorPyramidSize.y, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default, 1, true); 46 | CmdBuffer.SetComputeTextureParam(PyramidColorShader, 0, PyramidColorUniform.PrevLevelColor, PrevColorPyramid); 47 | CmdBuffer.SetComputeTextureParam(PyramidColorShader, 0, PyramidColorUniform.CurrLevelColor, ColorPyramidMipIDs[i]); 48 | CmdBuffer.SetComputeVectorParam(PyramidColorShader, PyramidColorUniform.PrevCurr_Size, new float4(ColorPyramidSize.x, ColorPyramidSize.y, 1f / ColorPyramidSize.x, 1f / ColorPyramidSize.y)); 49 | CmdBuffer.DispatchCompute(PyramidColorShader, 0, Mathf.CeilToInt(ColorPyramidSize.x / 8f), Mathf.CeilToInt(ColorPyramidSize.y / 8f), 1); 50 | CmdBuffer.CopyTexture(ColorPyramidMipIDs[i], 0, 0, DstRT, 0, i + 1); 51 | 52 | PrevColorPyramid = ColorPyramidMipIDs[i]; 53 | } for (int i = 0; i < ColorPyramidCount; i++) { 54 | CmdBuffer.ReleaseTemporaryRT(ColorPyramidMipIDs[i]); 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Shaders/BuiltIn/SSRCompositing.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/SSRCompositing" 2 | { 3 | Properties 4 | { 5 | 6 | } 7 | 8 | CGINCLUDE 9 | #include "UnityCG.cginc" 10 | #include "../Private/Common.hlsl" 11 | #include "../Private/ImageBasedLighting.hlsl" 12 | 13 | float4x4 _Matrix_InvViewProj; 14 | sampler2D _MainTex, _SRV_SSRColor, _SRV_SSRAlpha; 15 | sampler2D _CameraDepthTexture, _CameraMotionVectorsTexture, _CameraGBufferTexture0, _CameraGBufferTexture1, _CameraGBufferTexture2, _CameraReflectionsTexture; 16 | 17 | struct VertexInput 18 | { 19 | float2 uv0 : TEXCOORD0; 20 | float4 vertex : POSITION; 21 | }; 22 | 23 | struct VertexOutput 24 | { 25 | float2 uv0 : TEXCOORD0; 26 | float4 vertex : SV_POSITION; 27 | }; 28 | 29 | VertexOutput VertexFunction_Quad(VertexInput AppInput) 30 | { 31 | VertexOutput VertexOut; 32 | VertexOut.vertex = UnityObjectToClipPos(AppInput.vertex); 33 | VertexOut.uv0 = AppInput.uv0; 34 | return VertexOut; 35 | } 36 | 37 | VertexOutput VertexFunction_Triangle(VertexInput AppInput) 38 | { 39 | VertexOutput VertexOut; 40 | VertexOut.vertex = float4(AppInput.vertex.xy, 0, 1); 41 | VertexOut.uv0 = (AppInput.vertex.xy + 1) * 0.5; 42 | #if UNITY_UV_STARTS_AT_TOP 43 | VertexOut.uv0.y = 1 - VertexOut.uv0.y; 44 | #endif 45 | return VertexOut; 46 | } 47 | 48 | float4 PixelFunction_CompositingSSR(VertexOutput VertexIn) : SV_Target 49 | { 50 | float2 UV = VertexIn.uv0; 51 | 52 | float SceneDepth = tex2D(_CameraDepthTexture, UV); 53 | float4 WorldNormal = tex2D(_CameraGBufferTexture2, UV) * 2 - 1; 54 | float4 SpecularColor = tex2D(_CameraGBufferTexture1, UV); 55 | float Roughness = clamp(1 - SpecularColor.a, 0.02, 1); 56 | 57 | float3 ScreenPos = GetNDCPos(UV, SceneDepth); 58 | float3 WorldPos = GetWorldSpacePos(ScreenPos, _Matrix_InvViewProj); 59 | float3 ViewDir = GetViewDir(WorldPos, _WorldSpaceCameraPos); 60 | 61 | float NoV = saturate(dot(WorldNormal, -ViewDir)); 62 | float4 EnvBRDF = EnvBRDFApprox(SpecularColor.rgb, Roughness, NoV); 63 | 64 | float4 SceneColor = tex2D(_MainTex, UV); 65 | 66 | float4 CubemapColor = tex2D(_CameraReflectionsTexture, UV); 67 | SceneColor.rgb = max(1e-5, SceneColor.rgb - CubemapColor.rgb); 68 | float4 SSRColor = tex2D(_SRV_SSRColor, UV); 69 | float SSRMask = saturate(Square(tex2D(_SRV_SSRAlpha, UV).a) * 2); 70 | float4 ReflectionColor = (CubemapColor * (1 - SSRMask)) + (SSRColor * EnvBRDF * SSRMask); 71 | 72 | return SSRColor; 73 | //return SceneColor + ReflectionColor; 74 | } 75 | ENDCG 76 | 77 | SubShader 78 | { 79 | Cull Off 80 | ZTest Always 81 | ZWrite Off 82 | 83 | Pass 84 | { 85 | Name "SSR_Compositing" 86 | 87 | CGPROGRAM 88 | #pragma target 4.5 89 | #pragma vertex VertexFunction_Triangle 90 | #pragma fragment PixelFunction_CompositingSSR 91 | ENDCG 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceGlobalIllumination/Script/ScreenSpaceGlobalIllumination.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Unity.Mathematics; 3 | using UnityEngine.Rendering; 4 | 5 | namespace InfinityTech.Runtime.Rendering.Feature 6 | { 7 | public struct SSGiParameterDescriptor 8 | { 9 | public bool RayMask; 10 | public int NumRays; 11 | public int NumSteps; 12 | public float Thickness; 13 | public float Intensity; 14 | } 15 | 16 | public struct SSGiInputDescriptor 17 | { 18 | public int FrameIndex; 19 | public float4 TraceResolution; 20 | public float4x4 Matrix_Proj; 21 | public float4x4 Matrix_InvProj; 22 | public float4x4 Matrix_ViewProj; 23 | public float4x4 Matrix_InvViewProj; 24 | public float4x4 Matrix_WorldToView; 25 | public RenderTargetIdentifier SRV_PyramidColor; 26 | public RenderTargetIdentifier SRV_PyramidDepth; 27 | public RenderTargetIdentifier SRV_SceneDepth; 28 | public RenderTargetIdentifier SRV_GBufferNormal; 29 | } 30 | 31 | public static class SSGiShaderID 32 | { 33 | public static int NumRays = Shader.PropertyToID("SSGi_NumRays"); 34 | public static int NumSteps = Shader.PropertyToID("SSGi_NumSteps"); 35 | public static int RayMask = Shader.PropertyToID("SSGi_RayMask"); 36 | public static int FrameIndex = Shader.PropertyToID("SSGi_FrameIndex"); 37 | public static int Thickness = Shader.PropertyToID("SSGi_Thickness"); 38 | public static int Intensity = Shader.PropertyToID("SSGi_Intensity"); 39 | public static int TraceResolution = Shader.PropertyToID("SSGi_TraceResolution"); 40 | public static int UAV_ScreenIrradiance = Shader.PropertyToID("UAV_ScreenIrradiance"); 41 | 42 | public static int Matrix_Proj = Shader.PropertyToID("Matrix_Proj"); 43 | public static int Matrix_InvProj = Shader.PropertyToID("Matrix_InvProj"); 44 | public static int Matrix_ViewProj = Shader.PropertyToID("Matrix_ViewProj"); 45 | public static int Matrix_InvViewProj = Shader.PropertyToID("Matrix_InvViewProj"); 46 | public static int Matrix_WorldToView = Shader.PropertyToID("Matrix_WorldToView"); 47 | 48 | public static int SRV_PyramidColor = Shader.PropertyToID("SRV_PyramidColor"); 49 | public static int SRV_PyramidDepth = Shader.PropertyToID("SRV_PyramidDepth"); 50 | public static int SRV_SceneDepth = Shader.PropertyToID("SRV_SceneDepth"); 51 | public static int SRV_GBufferNormal = Shader.PropertyToID("SRV_GBufferNormal"); 52 | } 53 | 54 | public static class SSGi 55 | { 56 | private static ComputeShader SSGiComputeShader { 57 | get { 58 | return Resources.Load("Shaders/SSGi_TraceShader"); 59 | } 60 | } 61 | 62 | public static void Render(CommandBuffer CmdBuffer, RenderTargetIdentifier UAV_ScreenIrradiance, ref SSGiParameterDescriptor Parameters, ref SSGiInputDescriptor InputData) { 63 | CmdBuffer.SetComputeIntParam(SSGiComputeShader, SSGiShaderID.NumRays, Parameters.NumRays); 64 | CmdBuffer.SetComputeIntParam(SSGiComputeShader, SSGiShaderID.NumSteps, Parameters.NumSteps); 65 | CmdBuffer.SetComputeIntParam(SSGiComputeShader, SSGiShaderID.RayMask, (Parameters.RayMask == true)? 1 : 0); 66 | CmdBuffer.SetComputeIntParam(SSGiComputeShader, SSGiShaderID.FrameIndex, InputData.FrameIndex); 67 | CmdBuffer.SetComputeFloatParam(SSGiComputeShader, SSGiShaderID.Thickness, Parameters.Thickness); 68 | CmdBuffer.SetComputeFloatParam(SSGiComputeShader, SSGiShaderID.Intensity, Parameters.Intensity); 69 | CmdBuffer.SetComputeVectorParam(SSGiComputeShader, SSGiShaderID.TraceResolution, InputData.TraceResolution); 70 | 71 | CmdBuffer.SetComputeMatrixParam(SSGiComputeShader, SSGiShaderID.Matrix_Proj, InputData.Matrix_Proj); 72 | CmdBuffer.SetComputeMatrixParam(SSGiComputeShader, SSGiShaderID.Matrix_InvProj, InputData.Matrix_InvProj); 73 | CmdBuffer.SetComputeMatrixParam(SSGiComputeShader, SSGiShaderID.Matrix_ViewProj, InputData.Matrix_ViewProj); 74 | CmdBuffer.SetComputeMatrixParam(SSGiComputeShader, SSGiShaderID.Matrix_InvViewProj, InputData.Matrix_InvViewProj); 75 | CmdBuffer.SetComputeMatrixParam(SSGiComputeShader, SSGiShaderID.Matrix_WorldToView, InputData.Matrix_WorldToView); 76 | 77 | CmdBuffer.SetComputeTextureParam(SSGiComputeShader, 0, SSGiShaderID.SRV_PyramidColor, InputData.SRV_PyramidColor); 78 | CmdBuffer.SetComputeTextureParam(SSGiComputeShader, 0, SSGiShaderID.SRV_PyramidDepth, InputData.SRV_PyramidDepth); 79 | CmdBuffer.SetComputeTextureParam(SSGiComputeShader, 0, SSGiShaderID.SRV_SceneDepth, InputData.SRV_SceneDepth); 80 | CmdBuffer.SetComputeTextureParam(SSGiComputeShader, 0, SSGiShaderID.SRV_GBufferNormal, InputData.SRV_GBufferNormal); 81 | CmdBuffer.SetComputeTextureParam(SSGiComputeShader, 0, SSGiShaderID.UAV_ScreenIrradiance, UAV_ScreenIrradiance); 82 | 83 | CmdBuffer.DispatchCompute(SSGiComputeShader, 0, Mathf.CeilToInt(InputData.TraceResolution.x / 16), Mathf.CeilToInt(InputData.TraceResolution.y / 16), 1); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /Runtime/RenderFeature/PyramidColorGenerator/Resources/Shaders/GaussianDownsampleShader.compute: -------------------------------------------------------------------------------- 1 | float4 _Size; 2 | Texture2D _Source; 3 | RWTexture2D _Result; 4 | SamplerState sampler_LinearClamp; 5 | 6 | // 16x16 pixels with an 8x8 center that we will be blurring writing out. Each uint is two color 7 | // channels packed together. 8 | // The reason for separating channels is to reduce bank conflicts in the local data memory 9 | // controller. A large stride will cause more threads to collide on the same memory bank. 10 | groupshared uint gs_cacheR[128]; 11 | groupshared uint gs_cacheG[128]; 12 | groupshared uint gs_cacheB[128]; 13 | groupshared uint gs_cacheA[128]; 14 | 15 | float4 BlurPixels(float4 a, float4 b, float4 c, float4 d, float4 e, float4 f, float4 g, float4 h, float4 i) 16 | { 17 | return 0.27343750 * (e ) 18 | + 0.21875000 * (d + f) 19 | + 0.10937500 * (c + g) 20 | + 0.03125000 * (b + h) 21 | + 0.00390625 * (a + i); 22 | } 23 | 24 | void Store2Pixels(uint index, float4 pixel1, float4 pixel2) 25 | { 26 | gs_cacheR[index] = f32tof16(pixel1.r) | f32tof16(pixel2.r) << 16; 27 | gs_cacheG[index] = f32tof16(pixel1.g) | f32tof16(pixel2.g) << 16; 28 | gs_cacheB[index] = f32tof16(pixel1.b) | f32tof16(pixel2.b) << 16; 29 | gs_cacheA[index] = f32tof16(pixel1.a) | f32tof16(pixel2.a) << 16; 30 | } 31 | 32 | void Load2Pixels(uint index, out float4 pixel1, out float4 pixel2) 33 | { 34 | uint rr = gs_cacheR[index]; 35 | uint gg = gs_cacheG[index]; 36 | uint bb = gs_cacheB[index]; 37 | uint aa = gs_cacheA[index]; 38 | pixel1 = float4(f16tof32(rr ), f16tof32(gg ), f16tof32(bb ), f16tof32(aa )); 39 | pixel2 = float4(f16tof32(rr >> 16), f16tof32(gg >> 16), f16tof32(bb >> 16), f16tof32(aa >> 16)); 40 | } 41 | 42 | void Store1Pixel(uint index, float4 pixel) 43 | { 44 | gs_cacheR[index] = asuint(pixel.r); 45 | gs_cacheG[index] = asuint(pixel.g); 46 | gs_cacheB[index] = asuint(pixel.b); 47 | gs_cacheA[index] = asuint(pixel.a); 48 | } 49 | 50 | void Load1Pixel(uint index, out float4 pixel) 51 | { 52 | pixel = asfloat(uint4(gs_cacheR[index], gs_cacheG[index], gs_cacheB[index], gs_cacheA[index])); 53 | } 54 | 55 | // Blur two pixels horizontally. This reduces LDS reads and pixel unpacking. 56 | void BlurHorizontally(uint outIndex, uint leftMostIndex) 57 | { 58 | float4 s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; 59 | Load2Pixels(leftMostIndex + 0, s0, s1); 60 | Load2Pixels(leftMostIndex + 1, s2, s3); 61 | Load2Pixels(leftMostIndex + 2, s4, s5); 62 | Load2Pixels(leftMostIndex + 3, s6, s7); 63 | Load2Pixels(leftMostIndex + 4, s8, s9); 64 | 65 | Store1Pixel(outIndex , BlurPixels(s0, s1, s2, s3, s4, s5, s6, s7, s8)); 66 | Store1Pixel(outIndex + 1, BlurPixels(s1, s2, s3, s4, s5, s6, s7, s8, s9)); 67 | } 68 | 69 | void BlurVertically(uint2 pixelCoord, uint topMostIndex) 70 | { 71 | float4 s0, s1, s2, s3, s4, s5, s6, s7, s8; 72 | Load1Pixel(topMostIndex , s0); 73 | Load1Pixel(topMostIndex + 8, s1); 74 | Load1Pixel(topMostIndex + 16, s2); 75 | Load1Pixel(topMostIndex + 24, s3); 76 | Load1Pixel(topMostIndex + 32, s4); 77 | Load1Pixel(topMostIndex + 40, s5); 78 | Load1Pixel(topMostIndex + 48, s6); 79 | Load1Pixel(topMostIndex + 56, s7); 80 | Load1Pixel(topMostIndex + 64, s8); 81 | 82 | float4 blurred = BlurPixels(s0, s1, s2, s3, s4, s5, s6, s7, s8); 83 | 84 | // Write to the final target 85 | _Result[pixelCoord] = blurred; 86 | } 87 | 88 | #pragma kernel KMain 89 | 90 | #ifdef DISABLE_COMPUTE_SHADERS 91 | 92 | TRIVIAL_COMPUTE_KERNEL(KMain) 93 | 94 | #else 95 | 96 | [numthreads(8, 8, 1)] 97 | void KMain(uint2 groupId : SV_GroupID, uint2 groupThreadId : SV_GroupThreadID, uint2 dispatchThreadId : SV_DispatchThreadID) 98 | { 99 | // Upper-left pixel coordinate of quad that this thread will read 100 | int2 threadUL = (groupThreadId << 1) + (groupId << 3) - 4; 101 | 102 | // Downsample the block 103 | float2 offset = float2(threadUL); 104 | float4 p00 = _Source.SampleLevel(sampler_LinearClamp, (offset + 0.5) * _Size.zw, 0.0); 105 | float4 p10 = _Source.SampleLevel(sampler_LinearClamp, (offset + float2(1.0, 0.0) + 0.5) * _Size.zw, 0.0); 106 | float4 p01 = _Source.SampleLevel(sampler_LinearClamp, (offset + float2(0.0, 1.0) + 0.5) * _Size.zw, 0.0); 107 | float4 p11 = _Source.SampleLevel(sampler_LinearClamp, (offset + float2(1.0, 1.0) + 0.5) * _Size.zw, 0.0); 108 | 109 | // Store the 4 downsampled pixels in LDS 110 | uint destIdx = groupThreadId.x + (groupThreadId.y << 4u); 111 | Store2Pixels(destIdx , p00, p10); 112 | Store2Pixels(destIdx + 8u, p01, p11); 113 | 114 | GroupMemoryBarrierWithGroupSync(); 115 | 116 | // Horizontally blur the pixels in LDS 117 | uint row = groupThreadId.y << 4u; 118 | BlurHorizontally(row + (groupThreadId.x << 1u), row + groupThreadId.x + (groupThreadId.x & 4u)); 119 | 120 | GroupMemoryBarrierWithGroupSync(); 121 | 122 | // Vertically blur the pixels in LDS and write the result to memory 123 | BlurVertically(dispatchThreadId, (groupThreadId.y << 3u) + groupThreadId.x); 124 | } 125 | 126 | #endif // DISABLE_COMPUTE_SHADERS 127 | -------------------------------------------------------------------------------- /Shaders/Private/PackData.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef _PackData_ 2 | #define _PackData_ 3 | 4 | #include "../Private/Common.hlsl" 5 | #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" 6 | #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" 7 | 8 | // PackingData 9 | float3 Pack1212To888(float2 x) 10 | { 11 | // Pack 12:12 to 8:8:8 12 | #if 1 13 | uint2 x1212 = (uint2)( x * 4095.0 ); 14 | uint2 High = x1212 >> 8; 15 | uint2 Low = x1212 & 255; 16 | uint3 x888 = uint3( Low, High.x | (High.y << 4) ); 17 | return x888 / 255.0; 18 | #else 19 | float2 x1212 = floor( x * 4095 ); 20 | float2 High = floor( x1212 / 256 ); // x1212 >> 8 21 | float2 Low = x1212 - High * 256; // x1212 & 255 22 | float3 x888 = float3( Low, High.x + High.y * 16 ); 23 | return saturate( x888 / 255 ); 24 | #endif 25 | } 26 | 27 | float2 Pack888To1212(float3 x) 28 | { 29 | // Pack 8:8:8 to 12:12 30 | #if 1 31 | uint3 x888 = (uint3)( x * 255.0 ); 32 | uint High = x888.z >> 4; 33 | uint Low = x888.z & 15; 34 | uint2 x1212 = x888.xy | uint2( Low << 8, High << 8 ); 35 | return x1212 / 4095.0; 36 | #else 37 | float3 x888 = floor( x * 255 ); 38 | float High = floor( x888.z / 16 ); // x888.z >> 4 39 | float Low = x888.z - High * 16; // x888.z & 15 40 | float2 x1212 = x888.xy + float2( Low, High ) * 256; 41 | return saturate( x1212 / 4095 ); 42 | #endif 43 | } 44 | 45 | // CoordSpace 46 | float2 UnitVectorToOctahedron(float3 N) 47 | { 48 | N.xy /= dot( 1, abs(N) ); 49 | if( N.z <= 0 ) { 50 | N.xy = ( 1 - abs(N.yx) ) * ( N.xy >= 0 ? 1 : -1 ); 51 | } 52 | return N.xy; 53 | } 54 | 55 | float3 OctahedronToUnitVector(float2 Oct) 56 | { 57 | float3 N = float3( Oct, 1 - dot( 1, abs(Oct) ) ); 58 | if( N.z < 0 ) { 59 | N.xy = ( 1 - abs(N.yx) ) * ( N.xy >= 0 ? float2(1, 1) : float2(-1, -1) ); 60 | } 61 | return normalize(N); 62 | } 63 | 64 | float2 UnitVectorToHemiOctahedron(float3 N) 65 | { 66 | N.xy /= dot( 1, abs(N) ); 67 | return float2( N.x + N.y, N.x - N.y ); 68 | } 69 | 70 | float3 HemiOctahedronToUnitVector(float2 Oct) 71 | { 72 | Oct = float2( Oct.x + Oct.y, Oct.x - Oct.y ) * 0.5; 73 | float3 N = float3( Oct, 1 - dot( 1, abs(Oct) ) ); 74 | return normalize(N); 75 | } 76 | 77 | // CompressionNormal 78 | float3 EncodeNormalDir_Octa24(float3 N) 79 | { 80 | return Pack1212To888(saturate(UnitVectorToOctahedron(N) * 0.5 + 0.5)); 81 | } 82 | 83 | float3 DecodeNormalDir_Octa24(float3 N) 84 | { 85 | return OctahedronToUnitVector(Pack888To1212(N) * 2 - 1); 86 | } 87 | 88 | // CompressionReflectance&Specular 89 | uint2 EncodeReflectanceSpecular(float Reflectance, float Specular) 90 | { 91 | uint2 ReflectanceSpecular = 0; 92 | ReflectanceSpecular.x = (uint)(Reflectance * 255) * 4; 93 | 94 | float Specular4Bit = floor(Specular * 15); 95 | ReflectanceSpecular.x += Specular4Bit / 4; 96 | ReflectanceSpecular.y = Specular4Bit % 4; 97 | return ReflectanceSpecular; 98 | } 99 | 100 | void DecodeReflectanceSpecular(uint2 ReflectanceSpecular, out float Reflectance, out float Specular) 101 | { 102 | Reflectance = float(ReflectanceSpecular.x * 0.25) / 255; 103 | uint Specular4Bit = ReflectanceSpecular.x % 4; 104 | Specular4Bit = (Specular4Bit * 4) + ReflectanceSpecular.y; 105 | Specular = Specular4Bit / 15.0f; 106 | } 107 | 108 | // Compression GBuffer 109 | struct ThinGBufferData 110 | { 111 | float Specular; 112 | float Roughness; 113 | float Reflactance; 114 | float3 WorldNormal; 115 | float3 BaseColor; 116 | }; 117 | 118 | void EncodeGBuffer(ThinGBufferData GBufferData, out float4 EncodeData_GBufferA, out uint4 EncodeData_GBufferB) 119 | { 120 | uint2 EncodeNormal = floor(UnitVectorToOctahedron(GBufferData.WorldNormal) * 511 + 512); 121 | 122 | EncodeData_GBufferA = float4(GBufferData.BaseColor, GBufferData.Roughness); 123 | EncodeData_GBufferB = uint4(EncodeNormal, EncodeReflectanceSpecular(GBufferData.Reflactance, GBufferData.Specular)); 124 | } 125 | 126 | void DecodeGBuffer(float4 EncodeData_GBufferA, float4 EncodeData_GBufferB, out ThinGBufferData GBufferData) 127 | { 128 | GBufferData.BaseColor = EncodeData_GBufferA.rgb; 129 | GBufferData.Roughness = EncodeData_GBufferA.a; 130 | 131 | GBufferData.WorldNormal = float3(OctahedronToUnitVector(((EncodeData_GBufferB.xy / 1023) - 0.5) * 2)); 132 | DecodeReflectanceSpecular(EncodeData_GBufferB.zw, GBufferData.Reflactance, GBufferData.Specular); 133 | } 134 | 135 | void EncodeGBuffer_Normal24(ThinGBufferData GBufferData, out float4 EncodeData_GBufferA, out float4 EncodeData_GBufferB) 136 | { 137 | float3 EncodeNormal = EncodeNormalDir_Octa24(GBufferData.WorldNormal); 138 | float EncodeRoughness = GBufferData.Roughness; 139 | float EncodeReflactance = GBufferData.Reflactance; 140 | float3 EncodeAlbedo = GBufferData.BaseColor; 141 | 142 | EncodeData_GBufferA = float4(EncodeAlbedo, EncodeRoughness); 143 | EncodeData_GBufferB = float4(EncodeNormal, EncodeReflactance); 144 | } 145 | 146 | void DecodeGBuffer_Normal24(float4 EncodeData_GBufferA, float4 EncodeData_GBufferB, out ThinGBufferData GBufferData) 147 | { 148 | GBufferData.WorldNormal = DecodeNormalDir_Octa24(EncodeData_GBufferB.xyz); 149 | GBufferData.Roughness = EncodeData_GBufferA.a; 150 | GBufferData.Specular = 0.5; 151 | GBufferData.Reflactance = EncodeData_GBufferB.a; 152 | GBufferData.BaseColor = EncodeData_GBufferB.rgb; 153 | } 154 | 155 | void EncodeGBuffer_RayTrace(ThinGBufferData GBufferData, out int EncodeData_GBufferA, out int EncodeData_GBufferB) 156 | { 157 | int2 EncodeNormal = int2(saturate( UnitVectorToOctahedron(GBufferData.WorldNormal) * 0.5 + 0.5) * 0xFFF); 158 | int EncodeRoughness = int(saturate(GBufferData.Roughness) * 0xFF); 159 | int3 EncodeAlbedo = int3(saturate(GBufferData.BaseColor) * 0xFF); 160 | int EncodeReflactance = int(saturate(GBufferData.Reflactance) * 0xFF); 161 | 162 | EncodeData_GBufferA = (EncodeNormal.x << 20) + (EncodeNormal.y << 8) + EncodeRoughness; 163 | EncodeData_GBufferB = (EncodeAlbedo.x << 24) + (EncodeAlbedo.y << 16) + (EncodeAlbedo.z << 8) + EncodeReflactance; 164 | } 165 | 166 | void DecodeGBuffer_RayTrace(int EncodeData_GBufferA, int EncodeData_GBufferB, out ThinGBufferData GBufferData) 167 | { 168 | GBufferData.WorldNormal = OctahedronToUnitVector( (int2(EncodeData_GBufferA >> 20, EncodeData_GBufferA >> 8) & 0xFFF) / float(0xFFF) * 2 - 1); 169 | GBufferData.Specular = 0.5; 170 | GBufferData.Roughness = ((EncodeData_GBufferA >> 32) & 0xFF) / 255.0f; 171 | GBufferData.BaseColor = (int3(EncodeData_GBufferB >> 24, EncodeData_GBufferB >> 16, EncodeData_GBufferB >> 8) & 0xFF) / 255.0f; 172 | GBufferData.Reflactance = (EncodeData_GBufferB >> 24 & 0xFF) / 255.0f; 173 | } 174 | 175 | #endif -------------------------------------------------------------------------------- /Shaders/Private/RayTracing/Common/RayTracingCommon.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef RT_COMMON_H_ 2 | #define RT_COMMON_H_ 3 | 4 | // Engine includes 5 | #include "UnityRaytracingMeshUtils.cginc" 6 | 7 | RaytracingAccelerationStructure _RaytracingSceneStruct; 8 | 9 | struct AttributeData 10 | { 11 | // Barycentric value of the intersection 12 | float2 barycentrics; 13 | }; 14 | 15 | struct AORayPayload 16 | { 17 | float HitDistance; 18 | }; 19 | 20 | // Macro that interpolate any attribute using barycentric coordinates 21 | #define INTERPOLATE_RAYTRACING_ATTRIBUTE(A0, A1, A2, BARYCENTRIC_COORDINATES) (A0 * BARYCENTRIC_COORDINATES.x + A1 * BARYCENTRIC_COORDINATES.y + A2 * BARYCENTRIC_COORDINATES.z) 22 | 23 | // Structure to fill for intersections 24 | struct IntersectionVertex 25 | { 26 | // Object space position of the vertex 27 | float3 positionOS; 28 | // Object space normal of the vertex 29 | float3 normalOS; 30 | // Object space normal of the vertex 31 | float4 tangentOS; 32 | // UV coordinates 33 | float2 texCoord0; 34 | float2 texCoord1; 35 | float2 texCoord2; 36 | float2 texCoord3; 37 | // Vertex color 38 | float4 color; 39 | //geometry normal; 40 | float3 geomoralOS; 41 | // Value used for LOD sampling 42 | //float triangleArea; 43 | //float texCoord0Area; 44 | //float texCoord1Area; 45 | //float texCoord2Area; 46 | //float texCoord3Area; 47 | }; 48 | 49 | // Fetch the intersetion vertex data for the target vertex 50 | void FetchIntersectionVertex(uint vertexIndex, out IntersectionVertex outVertex) 51 | { 52 | outVertex.positionOS = UnityRayTracingFetchVertexAttribute3(vertexIndex, kVertexAttributePosition); 53 | outVertex.normalOS = UnityRayTracingFetchVertexAttribute3(vertexIndex, kVertexAttributeNormal); 54 | outVertex.tangentOS = UnityRayTracingFetchVertexAttribute4(vertexIndex, kVertexAttributeTangent); 55 | outVertex.texCoord0 = UnityRayTracingFetchVertexAttribute2(vertexIndex, kVertexAttributeTexCoord0); 56 | outVertex.texCoord1 = UnityRayTracingFetchVertexAttribute2(vertexIndex, kVertexAttributeTexCoord1); 57 | outVertex.texCoord2 = UnityRayTracingFetchVertexAttribute2(vertexIndex, kVertexAttributeTexCoord2); 58 | outVertex.texCoord3 = UnityRayTracingFetchVertexAttribute2(vertexIndex, kVertexAttributeTexCoord3); 59 | outVertex.color = UnityRayTracingFetchVertexAttribute4(vertexIndex, kVertexAttributeColor); 60 | } 61 | 62 | void GetCurrentIntersectionVertex(AttributeData attributeData, out IntersectionVertex outVertex) 63 | { 64 | // Fetch the indices of the currentr triangle 65 | uint3 triangleIndices = UnityRayTracingFetchTriangleIndices(PrimitiveIndex()); 66 | 67 | // Fetch the 3 vertices 68 | IntersectionVertex v0, v1, v2; 69 | FetchIntersectionVertex(triangleIndices.x, v0); 70 | FetchIntersectionVertex(triangleIndices.y, v1); 71 | FetchIntersectionVertex(triangleIndices.z, v2); 72 | 73 | // Compute the full barycentric coordinates 74 | float3 barycentricCoordinates = float3(1.0 - attributeData.barycentrics.x - attributeData.barycentrics.y, attributeData.barycentrics.x, attributeData.barycentrics.y); 75 | 76 | // Interpolate all the data 77 | outVertex.positionOS = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.positionOS, v1.positionOS, v2.positionOS, barycentricCoordinates); 78 | outVertex.normalOS = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.normalOS, v1.normalOS, v2.normalOS, barycentricCoordinates); 79 | outVertex.tangentOS = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.tangentOS, v1.tangentOS, v2.tangentOS, barycentricCoordinates); 80 | outVertex.texCoord0 = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.texCoord0, v1.texCoord0, v2.texCoord0, barycentricCoordinates); 81 | outVertex.texCoord1 = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.texCoord1, v1.texCoord1, v2.texCoord1, barycentricCoordinates); 82 | outVertex.texCoord2 = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.texCoord2, v1.texCoord2, v2.texCoord2, barycentricCoordinates); 83 | outVertex.texCoord3 = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.texCoord3, v1.texCoord3, v2.texCoord3, barycentricCoordinates); 84 | outVertex.color = INTERPOLATE_RAYTRACING_ATTRIBUTE(v0.color, v1.color, v2.color, barycentricCoordinates); 85 | outVertex.geomoralOS = cross(v0.positionOS - v1.positionOS, v0.positionOS - v2.positionOS); 86 | //// Compute the lambda value (area computed in object space) 87 | //outVertex.triangleArea = length(cross(v1.positionOS - v0.positionOS, v2.positionOS - v0.positionOS)); 88 | //outVertex.texCoord0Area = abs((v1.texCoord0.x - v0.texCoord0.x) * (v2.texCoord0.y - v0.texCoord0.y) - (v2.texCoord0.x - v0.texCoord0.x) * (v1.texCoord0.y - v0.texCoord0.y)); 89 | //outVertex.texCoord1Area = abs((v1.texCoord1.x - v0.texCoord1.x) * (v2.texCoord1.y - v0.texCoord1.y) - (v2.texCoord1.x - v0.texCoord1.x) * (v1.texCoord1.y - v0.texCoord1.y)); 90 | //outVertex.texCoord2Area = abs((v1.texCoord2.x - v0.texCoord2.x) * (v2.texCoord2.y - v0.texCoord2.y) - (v2.texCoord2.x - v0.texCoord2.x) * (v1.texCoord2.y - v0.texCoord2.y)); 91 | //outVertex.texCoord3Area = abs((v1.texCoord3.x - v0.texCoord3.x) * (v2.texCoord3.y - v0.texCoord3.y) - (v2.texCoord3.x - v0.texCoord3.x) * (v1.texCoord3.y - v0.texCoord3.y)); 92 | } 93 | 94 | struct FragInputs 95 | { 96 | bool isFrontFace; 97 | float2 uv0; 98 | float2 uv1; 99 | float2 uv2; 100 | float2 uv3; 101 | float3 normal; 102 | float3 position; 103 | float4 color; 104 | float3x3 tangentToWorld; 105 | }; 106 | 107 | void BuildFragInputsFromIntersection(IntersectionVertex currentVertex, out FragInputs outFragInputs) 108 | { 109 | outFragInputs.position = mul(ObjectToWorld3x4(), float4(currentVertex.positionOS, 1.0)).xyz; 110 | outFragInputs.uv0 = currentVertex.texCoord0; 111 | outFragInputs.uv1 = currentVertex.texCoord1; 112 | outFragInputs.uv2 = currentVertex.texCoord2; 113 | outFragInputs.uv3 = currentVertex.texCoord3; 114 | outFragInputs.color = currentVertex.color; 115 | 116 | // Let's compute the object space binormal 117 | float sign = currentVertex.tangentOS.w; 118 | float3x3 objectToWorld = (float3x3)ObjectToWorld3x4(); 119 | float3x3 worldToObject = (float3x3)WorldToObject3x4(); 120 | 121 | float3 WorldNormal = normalize( mul(currentVertex.normalOS, worldToObject) ); 122 | float4 TangentNormal = float4(normalize( mul(currentVertex.tangentOS.xyz, worldToObject) ), sign); 123 | float3 binormal = normalize ( cross(WorldNormal, TangentNormal) ) * sign; 124 | 125 | outFragInputs.tangentToWorld = float3x3(TangentNormal.xyz * sign, binormal, WorldNormal); 126 | outFragInputs.normal = normalize( mul(currentVertex.geomoralOS, worldToObject) ); 127 | outFragInputs.isFrontFace = dot( outFragInputs.normal, WorldRayDirection() ) < 0.0; 128 | outFragInputs.normal *= outFragInputs.isFrontFace ? 1 : -1; 129 | } 130 | 131 | #define Calculate_VertexData(fragInput) IntersectionVertex currentvertex;\ 132 | GetCurrentIntersectionVertex(attributeData, currentvertex);\ 133 | FragInputs fragInput;\ 134 | BuildFragInputsFromIntersection(currentvertex, fragInput);\ 135 | 136 | 137 | 138 | #endif -------------------------------------------------------------------------------- /Shaders/Private/ShadingModel.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef __SHADING_MODEL__ 2 | #define __SHADING_MODEL__ 3 | 4 | #include "BSDF.hlsl" 5 | 6 | half3 DefultLit(BSDFContext LightData, half3 Attenuation, half3 MultiScatterEnergy, half3 AlbedoColor, half3 SpecularColor, half Roughness) 7 | { 8 | half3 Diffuse = Diffuse_RenormalizeBurley(LightData.LoH, LightData.NoL, LightData.NoV, AlbedoColor, Roughness); 9 | 10 | half pbr_GGX = D_GGX(LightData.NoH, Roughness); 11 | half pbr_Vis = Vis_SmithJoint_NoPI(LightData.NoL, LightData.NoV, Roughness); 12 | half3 pbr_Fresnel = F_Schlick(SpecularColor, 1, LightData.LoH); 13 | 14 | half3 Specular = (pbr_Vis * pbr_GGX) * pbr_Fresnel; 15 | Specular *= MultiScatterEnergy; 16 | 17 | return max( 0, (Diffuse + Specular) * Attenuation ); 18 | } 19 | 20 | half3 SkinLit(BSDFContext LightData, half3 Attenuation, half3 MultiScatterEnergy, half3 AlbedoColor, half3 SpecularColor, half Roughness) 21 | { 22 | half3 Diffuse = Diffuse_RenormalizeBurley(LightData.LoH, LightData.NoL, LightData.NoV, AlbedoColor, Roughness); 23 | 24 | half pbr_GGX = lerp(D_Beckmann(LightData.NoH, Roughness), D_Beckmann(LightData.NoH, Roughness * 0.5), 0.85); 25 | half pbr_Vis = Vis_SmithJoint_NoPI(LightData.NoL, LightData.NoV, Roughness); 26 | half3 pbr_Fresnel = F_Schlick(SpecularColor, 1, LightData.LoH); 27 | 28 | half3 Specular = (pbr_Vis * pbr_GGX) * pbr_Fresnel; 29 | Specular *= MultiScatterEnergy; 30 | 31 | return max( 0, (Diffuse + Specular) * Attenuation ); 32 | } 33 | 34 | half3 ClearCoatLit(BSDFContext LightData, half3 Attenuation, half3 MultiScatterEnergy, half3 ClearCoat_MultiScatterEnergy, half3 AlbedoColor, half3 SpecularColor, half ClearCoat, half ClearCoat_Roughness, half Roughness) 35 | { 36 | half3 Diffuse = Diffuse_RenormalizeBurley(LightData.LoH, LightData.NoL, LightData.NoV, AlbedoColor, Roughness); 37 | 38 | half F0 = pow5(1 - LightData.VoH); 39 | 40 | half ClearCoat_GGX = D_GGX(LightData.NoH, ClearCoat_Roughness); 41 | half ClearCoat_Vis = Vis_Kelemen(LightData.VoH); 42 | half ClearCoat_Fersnel = (F0 + (1 - F0) * 0.05) * ClearCoat; 43 | half ClearCoat_Specular = ClearCoat_GGX * ClearCoat_Vis * ClearCoat_Fersnel; 44 | ClearCoat_Specular *= ClearCoat_MultiScatterEnergy; 45 | 46 | half pbr_GGX = D_GGX(LightData.NoH, Roughness); 47 | half pbr_Vis = Vis_SmithJoint_NoPI(LightData.NoL, LightData.NoV, Roughness); 48 | half3 pbr_Fresnel = saturate(50 * SpecularColor.g) * F0 + (1 - F0) * SpecularColor; 49 | half3 BaseSpecular = (pbr_Vis * pbr_GGX) * pbr_Fresnel; 50 | BaseSpecular *= MultiScatterEnergy; 51 | 52 | half LayerAttenuation = (1 - ClearCoat_Fersnel); 53 | 54 | return max( 0, (Diffuse + BaseSpecular + ClearCoat_Specular) * Attenuation * LayerAttenuation ); 55 | } 56 | 57 | half3 CottonLit(BSDFContext LightData, half3 Attenuation, half3 AlbedoColor, half3 SpecularColor, half Roughness) 58 | { 59 | half3 Diffuse = Diffuse_Fabric(AlbedoColor, Roughness); 60 | 61 | #if _Ashikhmin_Charlie 62 | half pbr_InvGGX = D_Charlie(LightData.NoH, Roughness); 63 | half pbr_Vis = Vis_Charlie(LightData.NoL + 1e-7, LightData.NoV + 1e-7, Roughness); 64 | #else 65 | half pbr_InvGGX = D_Ashikhmin(LightData.NoH, Roughness); 66 | half pbr_Vis = Vis_Ashikhmin(LightData.NoL, LightData.NoV); 67 | #endif 68 | half3 pbr_Fresnel = F_Schlick(SpecularColor, 1, LightData.LoH); 69 | 70 | half3 Specular = (pbr_Vis * pbr_InvGGX) * pbr_Fresnel; 71 | 72 | return max( 0, (Diffuse + Specular) * Attenuation ); 73 | } 74 | 75 | half3 SilkLit(BSDFContext LightData, AnisoBSDFContext AnisoLightContext, half3 Attenuation, half3 MultiScatterEnergy, half3 AlbedoColor, half3 SpecularColor, half Roughness, half RoughnessT, half RoughnessB) 76 | { 77 | 78 | half3 Diffuse = Diffuse_Fabric(AlbedoColor, Roughness); 79 | 80 | half pbr_AnisoGGX = D_AnisotropyGGX(AnisoLightContext.ToH, AnisoLightContext.BoH, LightData.NoH, RoughnessT, RoughnessB); 81 | half pbr_Vis = Vis_AnisotropyGGX(AnisoLightContext.ToV, AnisoLightContext.BoV, LightData.NoV, AnisoLightContext.ToL, AnisoLightContext.BoL, LightData.NoL, RoughnessT, RoughnessB); 82 | half3 pbr_Fresnel = F_Schlick(SpecularColor, 1, LightData.LoH); 83 | 84 | half3 Specular = (pbr_Vis * pbr_AnisoGGX) * pbr_Fresnel; 85 | Specular *= MultiScatterEnergy; 86 | 87 | return max(0, (Diffuse + Specular) * Attenuation); 88 | } 89 | 90 | float3 HairLit(float3 L, float3 V, half3 N, float3 SpecularColor, float Specular, float Roughness,float Backlit, float Scatter, float Area, float Shadow) { 91 | Scatter = Scatter / 10; 92 | const float VoL = dot(V,L); 93 | const float SinThetaL = dot(N,L); 94 | const float SinThetaV = dot(N,V); 95 | float CosThetaD = cos(0.5 * abs(asinFast( SinThetaV ) - asinFast( SinThetaL))); 96 | 97 | const float3 Lp = L - SinThetaL * N; 98 | const float3 Vp = V - SinThetaV * N; 99 | const float CosPhi = dot(Lp,Vp) * rsqrt(dot(Lp,Lp) * dot(Vp,Vp) + 1e-4); 100 | const float CosHalfPhi = sqrt(saturate(0.5 + 0.5 * CosPhi)); 101 | 102 | float3 S = 0; 103 | float n = 1.55; 104 | float n_prime = 1.19 / CosThetaD + 0.36 * CosThetaD; 105 | float Shift = 0.035; 106 | 107 | float Alpha[3] = { 108 | -Shift * 2, 109 | Shift, 110 | Shift * 4, 111 | }; 112 | 113 | float B[3] = { 114 | Area + Square(Roughness), 115 | Area + Square(Roughness) / 2, 116 | Area + Square(Roughness) * 2, 117 | }; 118 | 119 | // R 120 | if(1) { 121 | const float sa = sin(Alpha[0]); 122 | const float ca = cos(Alpha[0]); 123 | float Shift = 2*sa* (ca * CosHalfPhi * sqrt(1 - SinThetaV * SinThetaV) + sa * SinThetaV); 124 | float Mp = Vis_Hair(B[0] * sqrt(2.0) * CosHalfPhi, SinThetaL + SinThetaV - Shift); 125 | float Np = 0.25 * CosHalfPhi; 126 | float Fp = F_Hair(sqrt(saturate( 0.5 + 0.5 * VoL))); 127 | S += Specular * Mp * Np * Fp * lerp(1, Backlit, saturate(-VoL)); 128 | } 129 | // TRT 130 | if(1) { 131 | float Mp = Vis_Hair(B[2], SinThetaL + SinThetaV - Alpha[2]); 132 | float f = F_Hair(CosThetaD * 0.5); 133 | float Fp = Square(1 - f) * f; 134 | float3 Tp = pow(SpecularColor, 0.8 / CosThetaD); 135 | float Np = exp(17 * CosPhi - 16.78); 136 | S += Mp * Np * Fp * Tp; 137 | } 138 | // TT 139 | if(1) { 140 | float Mp = Vis_Hair(B[1], SinThetaL + SinThetaV - Alpha[1]); 141 | float a = 1 / n_prime; 142 | float h = CosHalfPhi * (1 + a * (0.6 - 0.8 * CosPhi)); 143 | float f = F_Hair(CosThetaD * sqrt(saturate( 1 - h*h))); 144 | float Fp = Square(1 - f); 145 | float3 Tp = pow(SpecularColor, 0.5 * sqrt(1 - Square(h * a)) / CosThetaD); 146 | float Np = exp(-3.65 * CosPhi - 3.98); 147 | S += Mp * Np * Fp * Tp * Backlit; 148 | } 149 | // Scatter 150 | if(1) { 151 | float3 FakeNormal = normalize(V - N * dot(V, N)); 152 | N = FakeNormal; 153 | float Wrap = 1; 154 | float NoL = saturate((dot(N, L) + Wrap) / Square(1 + Wrap)); 155 | float DiffuseScatter = Inv_Pi * NoL * Scatter; 156 | float Luma = Luminance(SpecularColor); 157 | float3 ScatterTint = pow(SpecularColor / Luma, Shadow); 158 | S += sqrt(SpecularColor) * DiffuseScatter * ScatterTint; 159 | } 160 | S = -min(-S, 0); 161 | return S; 162 | } 163 | 164 | #endif -------------------------------------------------------------------------------- /Shaders/Private/ImageBasedLighting.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef _ImageBasedLighting_ 2 | #define _ImageBasedLighting_ 3 | 4 | #include "BSDF.hlsl" 5 | #include "ShadingModel.hlsl" 6 | 7 | //////////////////////////Environment LUT 8 | float IBL_Defualt_DiffuseIntegrated(float Roughness, float NoV) { 9 | float r = 0; 10 | const uint NumSamples = 1024; 11 | 12 | float3 V = float3(sqrt(1 - NoV * NoV), 0, NoV); 13 | 14 | for (uint i = 0; i < NumSamples; i++) { 15 | float2 E = Hammersley(i, NumSamples); 16 | float3 L = CosineSampleHemisphere(E).xyz; 17 | float3 H = normalize(V + L); 18 | 19 | float NoL = saturate(L.b); 20 | float LoH = saturate( dot(L, H) ); 21 | if (NoL > 0) { 22 | r += Diffuse_RenormalizeBurley_NoPi(LoH, NoL, NoV, Roughness); 23 | } 24 | } 25 | return r / NumSamples; 26 | } 27 | 28 | float2 IBL_Defualt_SpecularIntegrated(float Roughness, float NoV) { 29 | float2 r = 0; 30 | const uint NumSamples = 1024; 31 | 32 | float3 N = float3(0, 0, 1); 33 | float3 V = float3(sqrt(1 - NoV * NoV), 0, NoV); 34 | 35 | for (uint i = 0; i < NumSamples; i++) { 36 | float2 E = Hammersley(i, NumSamples); 37 | float3 H = ImportanceSampleGGX(E, Roughness).xyz; 38 | float3 L = 2 * dot(V, H) * H - V; 39 | 40 | float VoH = saturate( dot(V, H) ); 41 | float NoL = saturate(L.z); 42 | float NoH = saturate(H.z); 43 | 44 | if (NoL > 0) { 45 | float G = Vis_Schlick(NoL, NoV, Roughness); 46 | float Gv = G * VoH / (NoH * NoV); 47 | float Fc = pow(1 - VoH, 5); 48 | 49 | r.x += Gv * (1 - Fc); 50 | //r.x += Gv; 51 | r.y += Gv * Fc; 52 | } 53 | } 54 | return r / NumSamples; 55 | } 56 | 57 | float2 IBL_Ashikhmin_SpecularIntegrated(float Roughness, float NoV) 58 | { 59 | Roughness *= Roughness; 60 | float2 r = 0; 61 | const uint NumSamples = 1024; 62 | 63 | float3 N = float3(0, 0, 1); 64 | float3 V = float3(sqrt(1 - NoV * NoV), 0, NoV); 65 | 66 | for (uint i = 0; i < NumSamples; i++) 67 | { 68 | float2 E = Hammersley(i, NumSamples); 69 | float3 L = UniformSampleHemisphere(E).xyz; 70 | float3 H = normalize(V + L); 71 | 72 | float NoH = saturate( dot(N, H) ); 73 | float VoH = saturate( dot(V, H) ); 74 | float NoL = saturate( dot(N, L) ); 75 | 76 | if (NoL > 0) 77 | { 78 | //float Gv = 2 * NoL * D_Ashikhmin_NoPi(NoH, Roughness) * Vis_Ashikhmin(NoL, NoV); 79 | float Gv = 2 * NoL * D_Charlie_NoPi(NoH, Roughness) * Vis_Charlie(NoL, NoV, Roughness); 80 | float Fc = pow(1 - VoH, 5); 81 | 82 | r.x += Gv; 83 | r.y += Gv * Fc; 84 | } 85 | } 86 | return r /= NumSamples; 87 | } 88 | 89 | float2 IBL_Defualt_SpecularIntegrated_Approx(float Roughness, float NoV) { 90 | const float4 c0 = float4(-1.0, -0.0275, -0.572, 0.022); 91 | const float4 c1 = float4( 1.0, 0.0425, 1.040, -0.040); 92 | float4 r = Roughness * c0 + c1; 93 | float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y; 94 | return float2(-1.04, 1.04) * a004 + r.zw; 95 | } 96 | 97 | float IBL_Defualt_SpecularIntegrated_Approx_Nonmetal(float Roughness, float NoV) { 98 | const float2 c0 = { -1, -0.0275 }; 99 | const float2 c1 = { 1, 0.0425 }; 100 | float2 r = Roughness * c0 + c1; 101 | return min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y; 102 | } 103 | 104 | 105 | float2 IBL_Ashikhmin_SpecularIntegrated_Approx(float Roughness, float NoV) { 106 | const float4 c0 = float4(0.24, 0.93, 0.01, 0.20); 107 | const float4 c1 = float4(2, -1.30, 0.40, 0.03); 108 | 109 | float s = 1 - NoV; 110 | float e = s - c0.y; 111 | float g = c0.x * exp2(-(e * e) / (2 * c0.z)) + s * c0.w; 112 | float n = Roughness * c1.x + c1.y; 113 | float r = max(1 - n * n, c1.z) * g; 114 | 115 | return float2(r, r * c1.w); 116 | } 117 | 118 | float2 IBL_Charlie_SpecularIntegrated_Approx(float Roughness, float NoV) { 119 | const float3 c0 = float3(0.95, 1250, 0.0095); 120 | const float4 c1 = float4(0.04, 0.2, 0.3, 0.2); 121 | 122 | float a = 1 - NoV; 123 | float b = 1 - (Roughness); 124 | 125 | float n = pow(c1.x + a, 64); 126 | float e = b - c0.x; 127 | float g = exp2(-(e * e) * c0.y); 128 | float f = b + c1.y; 129 | float a2 = a * a; 130 | float a3 = a2 * a; 131 | float c = n * g + c1.z * (a + c1.w) * Roughness + f * f * a3 * a3 * a2; 132 | float r = min(c, 18); 133 | 134 | return float2(r, r * c0.z); 135 | } 136 | 137 | float3 IBL_Hair_FullIntegrated(float3 V, float3 N, float3 SpecularColor, float Roughness, float Scatter) 138 | { 139 | float3 Lighting = 0; 140 | uint NumSamples = 32; 141 | 142 | [loop] 143 | for( uint i = 0; i < NumSamples; i++ ) 144 | { 145 | float2 E = Hammersley(i, NumSamples, Halton(i)); 146 | float3 L = UniformSampleSphere(E).rgb; 147 | 148 | float PDF = 1 / (4 * Pi); 149 | float InvWeight = PDF * NumSamples; 150 | float Weight = rcp(InvWeight); 151 | 152 | Lighting += HairLit(L, V, N, SpecularColor, 0.5, Roughness, 0, Scatter, 0, 0) * Weight; 153 | } 154 | return Lighting; 155 | } 156 | 157 | float3 IBL_Hair_FullIntegrated(float3 V, float3 N, float3 SpecularColor, float Roughness, float Scatter, uint2 Random) 158 | { 159 | float3 Lighting = 0; 160 | uint NumSamples = 32; 161 | 162 | [loop] 163 | for( uint i = 0; i < NumSamples; i++ ) 164 | { 165 | float2 E = Hammersley16(i, NumSamples, Random); 166 | float3 L = UniformSampleSphere(E).rgb; 167 | 168 | float PDF = 1 / (4 * Pi); 169 | float InvWeight = PDF * NumSamples; 170 | float Weight = rcp(InvWeight); 171 | 172 | Lighting += HairLit(L, V, N, SpecularColor, 0.5, Roughness, 0, Scatter, 0, 0) * Weight; 173 | } 174 | return Lighting; 175 | } 176 | 177 | //////////Enviornment BRDF 178 | float4 PreintegratedDGF_LUT(sampler2D PreintegratedLUT, inout float3 EnergyCompensation, float3 SpecularColor, float Roughness, float NoV) 179 | { 180 | float3 Enviorfilter_GFD = tex2Dlod( PreintegratedLUT, float4(Roughness, NoV, 0, 0) ).rgb; 181 | float3 ReflectionGF = lerp( saturate(50 * SpecularColor.g) * Enviorfilter_GFD.ggg, Enviorfilter_GFD.rrr, SpecularColor ); 182 | EnergyCompensation = 1 + SpecularColor * (1 / Enviorfilter_GFD.r - 1); 183 | return float4(ReflectionGF, Enviorfilter_GFD.b); 184 | } 185 | 186 | float4 EnvBRDFApprox(float3 SpecularColor, float Roughness, float NoV) 187 | { 188 | float2 AB = IBL_Defualt_SpecularIntegrated_Approx(Roughness, NoV); 189 | AB.y *= saturate( 50 * SpecularColor.g ); 190 | return float4(SpecularColor * AB.x + AB.y, 1); 191 | } 192 | 193 | float3 PreintegratedGF_ClothAshikhmin(float3 SpecularColor, float Roughness, float NoV) 194 | { 195 | float2 AB = IBL_Ashikhmin_SpecularIntegrated_Approx(Roughness, NoV); 196 | return SpecularColor * AB.r + AB.g; 197 | } 198 | 199 | float3 PreintegratedGF_ClothCharlie(float3 SpecularColor, float Roughness, float NoV) 200 | { 201 | float2 AB = IBL_Charlie_SpecularIntegrated_Approx(Roughness, NoV); 202 | return SpecularColor * AB.r + AB.g; 203 | } 204 | 205 | #endif 206 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceReflection/Resources/Shaders/SSR_TraceShader.compute: -------------------------------------------------------------------------------- 1 | #include "../../../../../Shaders/Private/BSDF.hlsl" 2 | #include "../../../../../Shaders/Private/RayTracing/ScreenSpaceRayTrace/SSRTRayCast.hlsl" 3 | 4 | float4x4 Matrix_Proj, Matrix_InvProj, Matrix_InvViewProj, Matrix_WorldToView; 5 | Texture2D SRV_PyramidColor, SRV_PyramidDepth, SRV_SceneDepth, SRV_GBufferRoughness, SRV_GBufferNormal; 6 | 7 | 8 | ///TracingPass 9 | int SSR_NumRays, SSR_NumSteps, SSR_FrameIndex; 10 | float SSR_BRDFBias, SSR_Thickness, SSR_Fadeness, SSR_RoughnessDiscard, ColorPyramidNumLOD; 11 | float4 SSR_TraceResolution; 12 | RWTexture2D UAV_ReflectionUWVPDF; 13 | RWTexture2D UAV_ReflectionColorMask; 14 | 15 | /*#pragma kernel Raytracing_ScreenTrace 16 | [numthreads(16, 16, 1)] 17 | void Raytracing_ScreenTrace(uint3 id : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) 18 | { 19 | float2 UV = (id.xy + 0.5) * SSR_TraceResolution.zw; 20 | uint2 PixelPosition = uint2(UV.xy * SSR_TraceResolution.xy); 21 | 22 | float SceneDepth = SRV_SceneDepth.SampleLevel(Global_point_clamp_sampler, UV, 0).r; 23 | if (SceneDepth <= 1e-7) { 24 | UAV_ReflectionUWVPDF[id.xy] = 0; 25 | UAV_ReflectionColorMask[id.xy] = 0; 26 | return; 27 | } 28 | float Roughness = SRV_GBufferRoughness.SampleLevel(Global_point_clamp_sampler, UV, 0).a; 29 | Roughness = clamp(1 - Roughness, 0.02, 1); 30 | if (Roughness > SSR_RoughnessDiscard) { 31 | UAV_ReflectionUWVPDF[id.xy] = 0; 32 | UAV_ReflectionColorMask[id.xy] = 0; 33 | return; 34 | } 35 | float3 WorldNormal = SRV_GBufferNormal.SampleLevel(Global_point_clamp_sampler, UV, 0).xyz * 2 - 1; 36 | float3 ViewNormal = mul( (float3x3)Matrix_WorldToView, WorldNormal ); 37 | float3 ScreenSpacePos = GetScreenSpacePos(UV, SceneDepth); 38 | float3 WorldSpacePos = GetWorldSpacePos(ScreenSpacePos, Matrix_InvViewProj); 39 | float3 ViewSpacePos = GetViewSpacePos(ScreenSpacePos, Matrix_InvProj); 40 | float3 ViewSpaceDir = GetViewDir(WorldSpacePos, ViewSpacePos); 41 | 42 | float NoV = saturate( dot(WorldNormal, -ViewSpaceDir) ); 43 | float ConeTangent = lerp( 0, Roughness * (1 - SSR_BRDFBias), NoV * sqrt(Roughness) ); 44 | ConeTangent *= lerp( saturate(NoV * 2), 1, sqrt(Roughness) ); 45 | float MaxColorMipLevel = ColorPyramidNumLOD - 1; 46 | 47 | uint2 Random = Rand3DPCG16( uint3(PixelPosition, fmod(SSR_FrameIndex, 8)) ).xy; 48 | 49 | float Out_AO = 0; 50 | float4 Out_UVWPDF = 0, Out_ColorMask = 0; 51 | 52 | [loop] 53 | for (int i = 0; i < SSR_NumRays; i++) 54 | { 55 | float2 Hammersley = Hammersley16(i, SSR_NumRays, Random); 56 | Hammersley.y = lerp(Hammersley.y, 0, SSR_BRDFBias); 57 | 58 | float4 H = 0; 59 | if (Roughness > 0.1) { 60 | H = TangentToWorld( ImportanceSampleGGX(Hammersley, Roughness).xyz, float4(ViewNormal, 1) ); 61 | } else { 62 | H = float4(ViewNormal, 1); 63 | } 64 | half3 ReflectionDir = reflect(normalize(ViewSpacePos), H.xyz); 65 | 66 | float3 rayOrigin = float3(UV, ScreenSpacePos.z); 67 | float4 rayDir = mul(Matrix_Proj, float4(ViewSpacePos + ReflectionDir, 1)); 68 | rayDir.xyz = normalize((rayDir.xyz / max(rayDir.w, 1e-4)) - ScreenSpacePos); 69 | rayDir.xy *= 0.5; 70 | 71 | float4 RayHitData = HiZ_Trace(SSR_NumSteps * 8, 0.05, SSR_TraceResolution.zw, rayOrigin, rayDir.xyz, SRV_PyramidDepth);; 72 | 73 | float SamplerMip = clamp(log2(ConeTangent * length(RayHitData.xy - UV) * max(SSR_TraceResolution.x, SSR_TraceResolution.y)), 0, MaxColorMipLevel); 74 | float3 RayHitColor = SRV_PyramidColor.SampleLevel(Global_trilinear_clamp_sampler, RayHitData.xy, SamplerMip).rgb; 75 | RayHitColor /= 1 + Luminance(RayHitColor); 76 | 77 | Out_UVWPDF = float4(RayHitData.xy, 1 - RayHitData.z, H.a); 78 | Out_ColorMask += float4(RayHitColor, RayHitData.a * GetScreenFadeBord(RayHitData.xy, SSR_Fadeness)); 79 | } 80 | 81 | Out_ColorMask /= SSR_NumRays; 82 | Out_ColorMask.rgb *= rcp( 1 - Luminance(Out_ColorMask.rgb) ); 83 | Out_ColorMask.a = saturate( sqrt(Out_ColorMask.a) ); 84 | 85 | UAV_ReflectionUWVPDF[id.xy] = float4( Out_UVWPDF.xyz, max(1e-5, (Out_UVWPDF.w != 0) ? 1 / Out_UVWPDF.w : 0) ); 86 | UAV_ReflectionColorMask[id.xy] = Out_ColorMask * Out_ColorMask.a; 87 | }*/ 88 | 89 | #pragma kernel Raytracing_ScreenTrace 90 | [numthreads(16, 16, 1)] 91 | void Raytracing_ScreenTrace (uint3 id : SV_DispatchThreadID) 92 | { 93 | float2 UV = (id.xy + 0.5) * SSR_TraceResolution.zw; 94 | uint2 PixelPosition = uint2(UV.xy * SSR_TraceResolution.xy); 95 | 96 | float SceneDepth = SRV_SceneDepth.SampleLevel(Global_point_clamp_sampler, UV, 0).r; 97 | if (SceneDepth <= 1e-7) { 98 | UAV_ReflectionUWVPDF[id.xy] = 0; 99 | UAV_ReflectionColorMask[id.xy] = 0; 100 | return; 101 | } 102 | float Roughness = 1 - SRV_GBufferRoughness.SampleLevel(Global_point_clamp_sampler, UV, 0).a; 103 | Roughness = clamp(Roughness, 0.02, 1); 104 | if (Roughness > SSR_RoughnessDiscard) { 105 | UAV_ReflectionUWVPDF[id.xy] = 0; 106 | UAV_ReflectionColorMask[id.xy] = 0; 107 | return; 108 | } 109 | float3 NDCPos = GetNDCPos(UV, SceneDepth); 110 | float3 WorldPos = GetWorldSpacePos(NDCPos, Matrix_InvViewProj); 111 | float3 ViewPos = GetViewSpacePos(NDCPos, Matrix_InvProj); 112 | float3 ViewDir = GetViewDir(WorldPos, ViewPos); 113 | float3 WorldNormal = SRV_GBufferNormal.SampleLevel(Global_point_clamp_sampler, UV, 0).xyz * 2 - 1; 114 | float3 ViewNormal = mul( (float3x3)Matrix_WorldToView, WorldNormal ); 115 | float3x3 TangentMatrix = GetTangentBasis(WorldNormal); 116 | 117 | uint FrameIDMod8 = uint(fmod(SSR_FrameIndex, 64)); 118 | uint2 Random = Rand3DPCG16( uint3(PixelPosition, FrameIDMod8) ).xy; 119 | 120 | float4 Out_UVWPDF = 0; 121 | float4 Out_ColorMask = 0; 122 | 123 | [loop] 124 | for (uint i = 0; i < (uint)SSR_NumRays; i++) { 125 | float2 Hash = Hammersley16(i, (uint)SSR_NumRays, Random); 126 | Hash.y = lerp(Hash.y, 0, SSR_BRDFBias); 127 | float4 LightDir_TS = ImportanceSampleGGX(Hash, Roughness); 128 | float3 LightDir_WS = mul(LightDir_TS.xyz, TangentMatrix); 129 | float3 LightDir_VS = mul((float3x3)(Matrix_WorldToView), LightDir_WS); 130 | LightDir_VS = reflect( normalize(ViewPos), LightDir_VS ); 131 | 132 | float Level; 133 | float3 HitUVz; 134 | 135 | float3 RayStartScreen = NDCPos; 136 | float4 RayEndScreen = mul( Matrix_Proj, float4(LightDir_VS, 0) ) + float4(RayStartScreen, 1); 137 | RayEndScreen.xyz = (RayEndScreen.xyz / max(RayEndScreen.w, 1e-4)); 138 | float3 RayDepthScreen = 0.5 * (RayStartScreen + mul( Matrix_Proj, float4(0, 0, 1, 0) ).xyz); 139 | float3 RayStepScreen = RayEndScreen.xyz - RayStartScreen; 140 | RayStepScreen *= GetStepScreenFactorToClipAtScreenEdge(RayStartScreen.xy, RayStepScreen.xy); 141 | float CompareTolerance = max(abs(RayStepScreen.z), (RayStartScreen.z - RayDepthScreen.z) * 2); 142 | 143 | float StepOffset = InterleavedGradientNoise(PixelPosition + 0.5, FrameIDMod8); 144 | StepOffset -= 0.9; 145 | bool bHit = RayCast_Specular(SSR_NumSteps, 0.15, CompareTolerance, StepOffset, RayStartScreen, RayStepScreen, SRV_PyramidDepth, HitUVz, Level); 146 | 147 | Out_UVWPDF.xyz += float3(HitUVz.xy, HitUVz.z); 148 | Out_UVWPDF.w += LightDir_TS.w; 149 | 150 | [branch] 151 | if(bHit) { 152 | float3 SampleColor = SRV_PyramidColor.SampleLevel(Global_point_clamp_sampler, HitUVz.xy, 0).rgb; 153 | SampleColor.rgb *= rcp( 1 + Luminance(SampleColor.rgb) ); 154 | Out_ColorMask += float4(SampleColor.rgb, GetScreenFadeBord(HitUVz.xy, SSR_Fadeness)); 155 | } 156 | } 157 | 158 | Out_UVWPDF.xyz = normalize(Out_UVWPDF.xyz); 159 | Out_UVWPDF.w /= SSR_NumRays; 160 | 161 | Out_ColorMask /= SSR_NumRays; 162 | Out_ColorMask.a = saturate( Out_ColorMask.a * Out_ColorMask.a ); 163 | Out_ColorMask.rgb *= rcp( 1 - Luminance(Out_ColorMask.rgb) ); 164 | 165 | UAV_ReflectionUWVPDF[id.xy] = float4( Out_UVWPDF.xyz, max(1e-5, (Out_UVWPDF.w != 0) ? 1 / Out_UVWPDF.w : 0) ); 166 | UAV_ReflectionColorMask[id.xy] = Out_ColorMask * Out_ColorMask.a; 167 | } 168 | -------------------------------------------------------------------------------- /Runtime/Script/Post_SSGi.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Unity.Mathematics; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.PostProcessing; 6 | using InfinityTech.Runtime.Rendering.Feature; 7 | using IntParameter = UnityEngine.Rendering.PostProcessing.IntParameter; 8 | using FloatParameter = UnityEngine.Rendering.PostProcessing.FloatParameter; 9 | 10 | [Serializable] 11 | [PostProcess(typeof(SSGIRender), PostProcessEvent.BeforeTransparent, "InfinityRender/ScreenSpaceGlobalIllumination")] 12 | public class ScreenSpaceGlobalIllumination : PostProcessEffectSettings 13 | { 14 | [Header("TraceProperty")] 15 | [Range(1, 16)] 16 | public IntParameter NumRays = new IntParameter(){value = 10}; 17 | 18 | [Range(8, 32)] 19 | public IntParameter NumSteps = new IntParameter(){value = 8}; 20 | 21 | [Range(0.05f, 5.0f)] 22 | public FloatParameter Thickness = new FloatParameter(){value = 0.1f}; 23 | 24 | [Range(1, 5)] 25 | public FloatParameter Intensity = new FloatParameter() { value = 1 }; 26 | 27 | ///////////////////////////////////////////////////////////////////////////////////////////// 28 | [Header("FilterProperty")] 29 | [Range(1, 4)] 30 | public IntParameter NumSpatial = new IntParameter() { value = 1 }; 31 | 32 | [Range(1, 2)] 33 | public FloatParameter SpatialRadius = new FloatParameter() { value = 2 }; 34 | 35 | [Range(0, 8)] 36 | public FloatParameter TemporalScale = new FloatParameter() { value = 1.25f }; 37 | 38 | [Range(0, 0.99f)] 39 | public FloatParameter TemporalWeight = new FloatParameter() { value = 0.99f }; 40 | 41 | [Range(0, 2)] 42 | public IntParameter NumBilateral = new IntParameter() { value = 2 }; 43 | 44 | [Range(0.1f, 1)] 45 | public FloatParameter BilateralColorWeight = new FloatParameter() { value = 1 }; 46 | 47 | [Range(0.1f, 1)] 48 | public FloatParameter BilateralDepthWeight = new FloatParameter() { value = 1 }; 49 | 50 | [Range(0.1f, 1)] 51 | public FloatParameter BilateralNormalWeight = new FloatParameter() { value = 0.1f }; 52 | 53 | 54 | ///////////////////////////////////////////////////////////////////////////////////////////// 55 | public override bool IsEnabledAndSupported(PostProcessRenderContext context) { 56 | return enabled 57 | && context.camera.actualRenderingPath == RenderingPath.DeferredShading 58 | && SystemInfo.supportsMotionVectors 59 | && SystemInfo.supportsComputeShaders 60 | && SystemInfo.copyTextureSupport > CopyTextureSupport.None; 61 | } 62 | 63 | } 64 | 65 | public class SSGIRender : PostProcessEffectRenderer 66 | { 67 | private int[] ColorPyramidMipIDs, DepthPyramidMipIDs; 68 | private SSGiParameterDescriptor SSGiParameter; 69 | private SSGiInputDescriptor SSGiData; 70 | private SVGFParameterDescriptor SVGFParamete; 71 | private SVGFInputDescriptor SVGFInputData; 72 | 73 | private int2 PrevScreenSize; 74 | private RenderTexture RTV_TemporalPrev; 75 | 76 | public override void Init() { 77 | PyramidDepthGenerator.DepthPyramidInit(ref DepthPyramidMipIDs); 78 | SSGiData.FrameIndex = 0; 79 | SVGFInputData.FrameIndex = 0; 80 | } 81 | 82 | public override void Render(PostProcessRenderContext RenderContent) { 83 | RenderContent.command.BeginSample("ScreenSpaceGlobalIllumination"); 84 | 85 | int2 HZBSize = new int2(1024, 1024); 86 | int2 ScreenSize = new int2(RenderContent.camera.pixelWidth, RenderContent.camera.pixelHeight); 87 | Matrix4x4 ProjectionMatrix = GL.GetGPUProjectionMatrix(RenderContent.camera.projectionMatrix, false); 88 | Matrix4x4 WorldToViewMatrix = RenderContent.camera.worldToCameraMatrix; 89 | Matrix4x4 ViewProjectionMatrix = ProjectionMatrix * WorldToViewMatrix; 90 | 91 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 92 | { 93 | SSGiParameter.RayMask = false; 94 | SSGiParameter.NumRays = settings.NumRays; 95 | SSGiParameter.NumSteps = settings.NumSteps; 96 | SSGiParameter.Thickness = settings.Thickness; 97 | SSGiParameter.Intensity = settings.Intensity; 98 | 99 | SSGiData.TraceResolution = new float4(ScreenSize.x, ScreenSize.y, 1.0f / ScreenSize.x, 1.0f / ScreenSize.y); 100 | SSGiData.FrameIndex += 1; 101 | SSGiData.Matrix_Proj = ProjectionMatrix; 102 | SSGiData.Matrix_InvProj = ProjectionMatrix.inverse; 103 | SSGiData.Matrix_ViewProj = ViewProjectionMatrix; 104 | SSGiData.Matrix_InvViewProj = ViewProjectionMatrix.inverse; 105 | SSGiData.Matrix_WorldToView = WorldToViewMatrix; 106 | SSGiData.SRV_PyramidColor = RenderContent.source; 107 | SSGiData.SRV_SceneDepth = BuiltinRenderTextureType.ResolvedDepth; 108 | SSGiData.SRV_GBufferNormal = BuiltinRenderTextureType.GBuffer2; 109 | } 110 | 111 | { 112 | SVGFParamete.NumSpatial = settings.NumSpatial; 113 | SVGFParamete.SpatialRadius = settings.SpatialRadius; 114 | SVGFParamete.TemporalScale = settings.TemporalScale; 115 | SVGFParamete.TemporalWeight = settings.TemporalWeight; 116 | //////////////////////////////////////////////////////////////// 117 | SVGFInputData.FrameIndex += 1; 118 | SVGFInputData.Resolution = new float4(ScreenSize.x, ScreenSize.y, 1.0f / ScreenSize.x, 1.0f / ScreenSize.y); 119 | SVGFInputData.Matrix_InvProj = ProjectionMatrix.inverse; 120 | SVGFInputData.Matrix_ViewProj = ViewProjectionMatrix; 121 | SVGFInputData.Matrix_InvViewProj = ViewProjectionMatrix.inverse; 122 | SVGFInputData.Matrix_WorldToView = WorldToViewMatrix; 123 | SVGFInputData.SRV_GBufferMotion = BuiltinRenderTextureType.MotionVectors; 124 | SVGFInputData.SRV_SceneDepth = BuiltinRenderTextureType.ResolvedDepth; 125 | SVGFInputData.SRV_GBufferNormal = BuiltinRenderTextureType.GBuffer2; 126 | SVGFInputData.SRV_GBufferRoughness = BuiltinRenderTextureType.GBuffer1; 127 | } 128 | 129 | //////Set DepthPyramid Data 130 | RenderContent.command.BeginSample("Depth Pyramid"); 131 | RenderTextureDescriptor PyramidDepthDesc = new RenderTextureDescriptor(HZBSize.x, HZBSize.y, RenderTextureFormat.RHalf, 0) { 132 | useMipMap = true, 133 | autoGenerateMips = false, 134 | }; 135 | RenderContent.command.GetTemporaryRT(SSGiShaderID.SRV_PyramidDepth, PyramidDepthDesc, FilterMode.Point); 136 | SSGiData.SRV_PyramidDepth = new RenderTargetIdentifier(SSGiShaderID.SRV_PyramidDepth); 137 | RenderContent.command.BlitFullscreenTriangle(BuiltinRenderTextureType.ResolvedDepth, SSGiData.SRV_PyramidDepth); 138 | PyramidDepthGenerator.DepthPyramidUpdate(ref DepthPyramidMipIDs, ref HZBSize, SSGiData.SRV_PyramidDepth, RenderContent.command); 139 | RenderContent.command.EndSample("Depth Pyramid"); 140 | 141 | RenderContent.command.BeginSample("Gi Raytrace"); 142 | RenderContent.command.GetTemporaryRT(SSGiShaderID.UAV_ScreenIrradiance, (int)SSGiData.TraceResolution.x, (int)SSGiData.TraceResolution.y, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Default, 1, true); 143 | RenderTargetIdentifier ScreenIrradiance = new RenderTargetIdentifier(SSGiShaderID.UAV_ScreenIrradiance); 144 | SSGi.Render(RenderContent.command, ScreenIrradiance, ref SSGiParameter, ref SSGiData); 145 | RenderContent.command.EndSample("Gi Raytrace"); 146 | 147 | RenderContent.command.BeginSample("Reflection Blit"); 148 | RenderContent.command.BlitFullscreenTriangle(ScreenIrradiance, RenderContent.destination); 149 | RenderContent.command.ReleaseTemporaryRT(SSGiShaderID.SRV_PyramidDepth); 150 | RenderContent.command.ReleaseTemporaryRT(SSGiShaderID.UAV_ScreenIrradiance); 151 | //RenderContent.command.ReleaseTemporaryRT(SVGF_SpatialShaderID.UAV_SpatialColor); 152 | //RenderContent.command.ReleaseTemporaryRT(SVGF_TemporalShaderID.UAV_TemporalColor); 153 | SVGFInputData.Matrix_PrevViewProj = ViewProjectionMatrix; 154 | RenderContent.command.EndSample("Reflection Blit"); 155 | 156 | RenderContent.command.EndSample("ScreenSpaceReflection"); 157 | } 158 | 159 | public override void Release() { 160 | RenderTexture.ReleaseTemporary(RTV_TemporalPrev); 161 | } 162 | } -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceGlobalIllumination/Resources/Shaders/SSGi_TraceShader.compute: -------------------------------------------------------------------------------- 1 | //#include "UnityCG.cginc" 2 | #include "../../../../../Shaders/Private/BSDF.hlsl" 3 | #include "../../../../../Shaders/Private/RayTracing/ScreenSpaceRayTrace/SSRTRayCast.hlsl" 4 | 5 | float4x4 Matrix_Proj, Matrix_InvProj, Matrix_ViewProj, Matrix_InvViewProj, Matrix_WorldToView; 6 | Texture2D SRV_PyramidColor, SRV_PyramidDepth, SRV_SceneDepth, SRV_GBufferNormal; 7 | ////////////////////////Raytracing Pass//////////////////////// 8 | int SSGi_RayMask, SSGi_FrameIndex, SSGi_NumRays, SSGi_NumSteps; 9 | float SSGi_Thickness, SSGi_Intensity; 10 | float4 SSGi_HZBUvFactor, SSGi_TraceResolution; 11 | RWTexture2D UAV_ScreenIrradiance; 12 | 13 | /*#pragma kernel Raytracing_ScreenTrace 14 | [numthreads(16, 16, 1)] 15 | void Raytracing_ScreenTrace (uint3 id : SV_DispatchThreadID) 16 | { 17 | float2 UV = (id.xy + 0.5) * SSGi_TraceResolution.zw; 18 | uint2 PixelPosition = uint2(UV.xy * SSGi_TraceResolution.xy); 19 | 20 | float SceneDepth = SRV_SceneDepth.SampleLevel(Global_point_clamp_sampler, UV, 0).r; 21 | if (SceneDepth <= 1e-7) { 22 | UAV_ScreenIrradiance[id.xy] = 0; 23 | return; 24 | } 25 | float3 ScreenPos = GetScreenSpacePos(UV, SceneDepth); 26 | float3 WorldPos = GetWorldSpacePos(ScreenPos, Matrix_InvViewProj); 27 | float3 ViewPos = GetViewSpacePos(ScreenPos, Matrix_InvProj); 28 | float3 ViewDir = GetViewDir(WorldPos, ViewPos); 29 | float3 WorldNormal = SRV_GBufferNormal.SampleLevel(Global_point_clamp_sampler, UV, 0).xyz * 2 - 1; 30 | 31 | uint FrameIDMod8 = uint(fmod(SSGi_FrameIndex, 8)); 32 | uint2 Random = Rand3DPCG16( uint3(PixelPosition, FrameIDMod8) ).xy; 33 | float3x3 TangentToWorld = GetTangentBasis(WorldNormal); 34 | 35 | float Out_AmbientOcclusion = 0; 36 | float4 Out_IrradianceColor = 0; 37 | 38 | [loop] 39 | for (uint i = 0; i < (uint)SSGi_NumRays; i++) { 40 | float2 Hash = Hammersley16(i, (uint)SSGi_NumRays, Random); 41 | 42 | float3 LightDir_TS; 43 | LightDir_TS.xy = UniformSampleDiskConcentric( Hash ); 44 | LightDir_TS.z = sqrt( 1 - dot( LightDir_TS.xy, LightDir_TS.xy ) ); 45 | float3 LightDir_WS = mul(LightDir_TS, TangentToWorld); 46 | float3 LightDir_VS = mul( (float3x3)(Matrix_WorldToView), LightDir_WS ); 47 | 48 | float3 rayOrigin = float3(UV, ScreenPos.z); 49 | float4 rayDir = mul ( Matrix_Proj, float4(ViewPos + LightDir_VS, 1) ); 50 | rayDir.xyz = normalize( (rayDir.xyz / max(rayDir.w, 1e-4)) - ScreenPos); 51 | rayDir.xy *= 0.5; 52 | 53 | float4 RayHitData = HiZ_Trace(SSGi_NumSteps * 8, SSGi_Thickness, SSGi_TraceResolution.zw, rayOrigin, rayDir.xyz, SRV_PyramidDepth); 54 | 55 | float3 SampleColor = SRV_PyramidColor.SampleLevel(Global_point_clamp_sampler, RayHitData.xy, 0).rgb; 56 | float3 SampleNormal = SRV_GBufferNormal.SampleLevel(Global_point_clamp_sampler, RayHitData.xy, 0).xyz * 2 - 1; 57 | float CosineWeight = 1 - saturate( dot(LightDir_WS, SampleNormal) ); 58 | 59 | float3 ViewSpace_RayHitData = GetViewSpacePos( GetScreenSpacePos(RayHitData.xy, RayHitData.z), Matrix_InvProj ); 60 | float3 ViewSpace_RayOrigin = GetViewSpacePos( GetScreenSpacePos(rayOrigin.xy, rayOrigin.z), Matrix_InvProj ); 61 | Out_AmbientOcclusion += smoothstep( 0, 5, distance(ViewSpace_RayOrigin, ViewSpace_RayHitData) ); 62 | 63 | SampleColor *= CosineWeight; 64 | SampleColor *= rcp( 1 + Luminance(SampleColor) ); 65 | 66 | Out_IrradianceColor.rgb += SampleColor; 67 | Out_IrradianceColor.a += RayHitData.a; 68 | } 69 | Out_AmbientOcclusion /= SSGi_NumRays; 70 | Out_IrradianceColor /= SSGi_NumRays; 71 | Out_IrradianceColor.rgb *= rcp( 1 - Luminance(Out_IrradianceColor.rgb) ); 72 | Out_IrradianceColor.a = saturate( sqrt(Out_IrradianceColor.a) ); 73 | 74 | [branch] 75 | if(SSGi_RayMask == 1) { 76 | UAV_ScreenIrradiance[id.xy] = float4( Out_IrradianceColor.rgb * SSGi_Intensity * Out_IrradianceColor.a, Out_AmbientOcclusion ); 77 | } else { 78 | UAV_ScreenIrradiance[id.xy] = float4( Out_IrradianceColor.rgb * SSGi_Intensity, Out_AmbientOcclusion ); 79 | } 80 | }*/ 81 | 82 | inline float ConeConeIntersection(float ArcLength0, float ArcLength1, float AngleBetweenCones) 83 | { 84 | float AngleDifference = abs(ArcLength0 - ArcLength1); 85 | float AngleBlendAlpha = saturate((AngleBetweenCones - AngleDifference) / (ArcLength0 + ArcLength1 - AngleDifference)); 86 | return smoothstep(0, 1, 1 - AngleBlendAlpha); 87 | } 88 | 89 | inline half ReflectionOcclusion(half3 BentNormal, half3 ReflectionVector, half Roughness, half OcclusionStrength) 90 | { 91 | half BentNormalLength = length(BentNormal); 92 | 93 | half ReflectionConeAngle = max(Roughness, 0.04) * Pi; 94 | half UnoccludedAngle = BentNormalLength * Pi * OcclusionStrength; 95 | half AngleBetween = acos( dot(BentNormal, ReflectionVector) / max(BentNormalLength, 0.001) ); 96 | 97 | half ReflectionOcclusion = ConeConeIntersection(ReflectionConeAngle, UnoccludedAngle, AngleBetween); 98 | return lerp(0, ReflectionOcclusion, saturate((UnoccludedAngle - 0.1) / 0.2)); 99 | } 100 | 101 | #pragma kernel Raytracing_ScreenTrace 102 | [numthreads(16, 16, 1)] 103 | void Raytracing_ScreenTrace (uint3 id : SV_DispatchThreadID) 104 | { 105 | float2 UV = (id.xy + 0.5) * SSGi_TraceResolution.zw; 106 | uint2 PixelPosition = uint2(UV.xy * SSGi_TraceResolution.xy); 107 | 108 | float SceneDepth = SRV_SceneDepth.SampleLevel(Global_point_clamp_sampler, UV, 0).r; 109 | if (SceneDepth <= 1e-7) { 110 | UAV_ScreenIrradiance[id.xy] = 0; 111 | return; 112 | } 113 | float3 NDCPos = GetNDCPos(UV, SceneDepth); 114 | float3 WorldPos = GetWorldSpacePos(NDCPos, Matrix_InvViewProj); 115 | float3 ViewPos = GetViewSpacePos(NDCPos, Matrix_InvProj); 116 | float3 ViewDir = GetViewDir(WorldPos, ViewPos); 117 | float3 WorldNormal = SRV_GBufferNormal.SampleLevel(Global_point_clamp_sampler, UV, 0).xyz * 2 - 1; 118 | float3x3 TangentToWorld = GetTangentBasis(WorldNormal); 119 | 120 | uint FrameIDMod8 = uint(fmod(SSGi_FrameIndex, 32)); 121 | uint2 Random = Rand3DPCG16( uint3(PixelPosition, FrameIDMod8) ).xy; 122 | 123 | float Out_Occlusion = 0; 124 | float4 Out_ColorMask = 0; 125 | 126 | //float3 BentNormal = 0; 127 | 128 | [loop] 129 | for (uint i = 0; i < (uint)SSGi_NumRays; i++) 130 | { 131 | //float2 Hash = Halton(i, Random); 132 | float2 Hash = Hammersley16(i, (uint)SSGi_NumRays, Random); 133 | float3 LightDir_TS = CosineSampleHemisphere(Hash).xyz; 134 | float3 LightDir_WS = mul(LightDir_TS, TangentToWorld); 135 | float3 LightDir_VS = mul((float3x3)(Matrix_WorldToView), LightDir_WS); 136 | //BentNormal += LightDir_WS; 137 | 138 | float Level; 139 | float3 HitUVz; 140 | 141 | float3 RayStartScreen = NDCPos; 142 | float4 RayEndScreen = mul( Matrix_Proj, float4(LightDir_VS, 0) ) + float4(RayStartScreen, 1); 143 | RayEndScreen.xyz = (RayEndScreen.xyz / max(RayEndScreen.w, 1e-4)); 144 | float3 RayDepthScreen = 0.5 * (RayStartScreen + mul( Matrix_Proj, float4(0, 0, 1, 0) ).xyz); 145 | float3 RayStepScreen = RayEndScreen.xyz - RayStartScreen; 146 | RayStepScreen *= GetStepScreenFactorToClipAtScreenEdge(RayStartScreen.xy, RayStepScreen.xy); 147 | float CompareTolerance = max(abs(RayStepScreen.z), (RayStartScreen.z - RayDepthScreen.z) * 2); 148 | 149 | float StepOffset = InterleavedGradientNoise(PixelPosition + 0.5, FrameIDMod8); 150 | StepOffset -= 0.9; 151 | bool bHit = RayCast_Diffuse(SSGi_NumSteps, 1, CompareTolerance, StepOffset, RayStartScreen, RayStepScreen, SRV_PyramidDepth, HitUVz, Level); 152 | 153 | [branch] 154 | if(bHit) 155 | { 156 | float3 SampleNormal = SRV_GBufferNormal.SampleLevel(Global_point_clamp_sampler, HitUVz.xy, 0).xyz * 2 - 1; 157 | float CosineWeight = 1 - saturate( dot(LightDir_WS, SampleNormal) ); 158 | Out_Occlusion += CosineWeight; 159 | 160 | float3 SampleColor = SRV_PyramidColor.SampleLevel(Global_point_clamp_sampler, HitUVz.xy, 0).rgb; 161 | SampleColor.rgb *= rcp( 1 + Luminance(SampleColor.rgb) ); 162 | Out_ColorMask += float4(SampleColor.rgb, GetScreenFadeBord(HitUVz.xy, 0.1)); 163 | 164 | //BentNormal = 0; 165 | } 166 | } 167 | 168 | Out_Occlusion /= SSGi_NumRays; 169 | Out_ColorMask /= SSGi_NumRays; 170 | Out_ColorMask.rgb *= rcp( 1 - Luminance(Out_ColorMask.rgb) ) * (1 - Out_Occlusion) * SSGi_Intensity; 171 | UAV_ScreenIrradiance[id.xy] = Out_ColorMask * Out_ColorMask.a; 172 | 173 | 174 | 175 | //BentNormal = normalize(BentNormal); 176 | //float3 ReflectVector = -reflect(WorldNormal, normalize(WorldPos - _WorldSpaceCameraPos)); 177 | //float ReflecOcclusion = ReflectionOcclusion(BentNormal, ReflectVector, 0.25, 0.5); 178 | 179 | //UAV_ScreenIrradiance[id.xy] = ReflecOcclusion; 180 | //UAV_ScreenIrradiance[id.xy] = float4(BentNormal, 1); 181 | //UAV_ScreenIrradiance[id.xy] = dot(BentNormal, _WorldSpaceLightPos0.xyz); 182 | } 183 | -------------------------------------------------------------------------------- /Runtime/RenderFeature/SpatialTemporalVarianceFilter/Script/SpatialTemporalVarianceFilter.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Unity.Mathematics; 3 | using UnityEngine.Rendering; 4 | 5 | namespace InfinityTech.Runtime.Rendering.Feature 6 | { 7 | public static class SVGF_SpatialShaderID 8 | { 9 | public static int FrameIndex = Shader.PropertyToID("SVGF_FrameIndex"); 10 | public static int SpatialRadius = Shader.PropertyToID("SVGF_SpatialRadius"); 11 | public static int SpatialSize = Shader.PropertyToID("SVGF_SpatialSize"); 12 | public static int Matrix_InvProj = Shader.PropertyToID("Matrix_InvProj"); 13 | public static int Matrix_InvViewProj = Shader.PropertyToID("Matrix_InvViewProj"); 14 | public static int Matrix_WorldToView = Shader.PropertyToID("Matrix_WorldToView"); 15 | public static int SRV_SceneDepth = Shader.PropertyToID("SRV_SceneDepth"); 16 | public static int SRV_GBufferNormal = Shader.PropertyToID("SRV_GBufferNormal"); 17 | public static int SRV_GBufferRoughness = Shader.PropertyToID("SRV_GBufferRoughness"); 18 | public static int SRV_UWVPDF = Shader.PropertyToID("SRV_UWVPDF"); 19 | public static int SRV_ColorMask = Shader.PropertyToID("SRV_ColorMask"); 20 | public static int UAV_SpatialColor = Shader.PropertyToID("UAV_SpatialColor"); 21 | } 22 | 23 | public static class SVGF_TemporalShaderID 24 | { 25 | public static int TemporalScale = Shader.PropertyToID("SVGF_TemporalScale"); 26 | public static int TemporalWeight = Shader.PropertyToID("SVGF_TemporalWeight"); 27 | public static int TemporalSize = Shader.PropertyToID("SVGF_TemporalSize"); 28 | public static int Matrix_PrevViewProj = Shader.PropertyToID("Matrix_PrevViewProj"); 29 | public static int Matrix_ViewProj = Shader.PropertyToID("Matrix_ViewProj"); 30 | public static int Matrix_InvViewProj = Shader.PropertyToID("Matrix_InvViewProj"); 31 | public static int SRV_CurrColor = Shader.PropertyToID("SRV_CurrColor"); 32 | public static int SRV_PrevColor = Shader.PropertyToID("SRV_PrevColor"); 33 | public static int SRV_GBufferMotion = Shader.PropertyToID("SRV_GBufferMotion"); 34 | public static int SRV_RayDepth = Shader.PropertyToID("SRV_RayDepth"); 35 | public static int SRV_GBufferNormal = Shader.PropertyToID("SRV_GBufferNormal"); 36 | public static int UAV_TemporalColor = Shader.PropertyToID("UAV_TemporalColor"); 37 | } 38 | 39 | public static class SVGF_BilateralShaderID 40 | { 41 | public static int BilateralRadius = Shader.PropertyToID("SVGF_BilateralRadius"); 42 | public static int ColorWeight = Shader.PropertyToID("SVGF_ColorWeight"); 43 | public static int NormalWeight = Shader.PropertyToID("SVGF_NormalWeight"); 44 | public static int DepthWeight = Shader.PropertyToID("SVGF_DepthWeight"); 45 | public static int BilateralSize = Shader.PropertyToID("SVGF_BilateralSize"); 46 | public static int SRV_InputColor = Shader.PropertyToID("SRV_InputColor"); 47 | public static int SRV_GBufferNormal = Shader.PropertyToID("SRV_GBufferNormal"); 48 | public static int SRV_SceneDepth = Shader.PropertyToID("SRV_SceneDepth"); 49 | public static int UAV_BilateralColor = Shader.PropertyToID("UAV_BilateralColor"); 50 | } 51 | 52 | public struct SVGFParameterDescriptor 53 | { 54 | public int NumSpatial; 55 | public float SpatialRadius; 56 | public float TemporalScale; 57 | public float TemporalWeight; 58 | public float BilateralRadius; 59 | public float BilateralColorWeight; 60 | public float BilateralDepthWeight; 61 | public float BilateralNormalWeight; 62 | } 63 | 64 | public struct SVGFInputDescriptor { 65 | public int FrameIndex; 66 | public float4 Resolution; 67 | public float4x4 Matrix_PrevViewProj; 68 | public float4x4 Matrix_InvProj; 69 | public float4x4 Matrix_ViewProj; 70 | public float4x4 Matrix_InvViewProj; 71 | public float4x4 Matrix_WorldToView; 72 | public RenderTargetIdentifier SRV_SceneDepth; 73 | public RenderTargetIdentifier SRV_GBufferMotion; 74 | public RenderTargetIdentifier SRV_GBufferNormal; 75 | public RenderTargetIdentifier SRV_GBufferRoughness; 76 | } 77 | 78 | 79 | public static class SVGFilter 80 | { 81 | private static ComputeShader SVGF_Shader { 82 | get { 83 | return Resources.Load("Shaders/SVGF_Shader"); 84 | } 85 | } 86 | 87 | public static void SpatialFilter(CommandBuffer CmdBuffer, RenderTargetIdentifier SRV_UWVPDF, RenderTargetIdentifier SRV_ColorMask, RenderTargetIdentifier UAV_SpatialColor, ref SVGFParameterDescriptor Parameters, ref SVGFInputDescriptor InputData) 88 | { 89 | CmdBuffer.SetComputeIntParam(SVGF_Shader, SVGF_SpatialShaderID.FrameIndex, InputData.FrameIndex); 90 | CmdBuffer.SetComputeFloatParam(SVGF_Shader, SVGF_SpatialShaderID.SpatialRadius, Parameters.SpatialRadius); 91 | CmdBuffer.SetComputeVectorParam(SVGF_Shader, SVGF_SpatialShaderID.SpatialSize, InputData.Resolution); 92 | CmdBuffer.SetComputeMatrixParam(SVGF_Shader, SVGF_SpatialShaderID.Matrix_InvProj, InputData.Matrix_InvProj); 93 | CmdBuffer.SetComputeMatrixParam(SVGF_Shader, SVGF_SpatialShaderID.Matrix_InvViewProj, InputData.Matrix_InvViewProj); 94 | CmdBuffer.SetComputeMatrixParam(SVGF_Shader, SVGF_SpatialShaderID.Matrix_WorldToView, InputData.Matrix_WorldToView); 95 | 96 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 0, SVGF_SpatialShaderID.SRV_SceneDepth, InputData.SRV_SceneDepth); 97 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 0, SVGF_SpatialShaderID.SRV_GBufferNormal, InputData.SRV_GBufferNormal); 98 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 0, SVGF_SpatialShaderID.SRV_GBufferRoughness, InputData.SRV_GBufferRoughness); 99 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 0, SVGF_SpatialShaderID.SRV_UWVPDF, SRV_UWVPDF); 100 | for (uint i = 0; i < (uint)Parameters.NumSpatial; i++) { 101 | uint CurrState = i & 1; 102 | if(CurrState == 0) { 103 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 0, SVGF_SpatialShaderID.SRV_ColorMask, SRV_ColorMask); 104 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 0, SVGF_SpatialShaderID.UAV_SpatialColor, UAV_SpatialColor); 105 | CmdBuffer.DispatchCompute(SVGF_Shader, 0, Mathf.CeilToInt(InputData.Resolution.x / 16), Mathf.CeilToInt(InputData.Resolution.y / 16), 1); 106 | } else { 107 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 0, SVGF_SpatialShaderID.SRV_ColorMask, UAV_SpatialColor); 108 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 0, SVGF_SpatialShaderID.UAV_SpatialColor, SRV_ColorMask); 109 | CmdBuffer.DispatchCompute(SVGF_Shader, 0, Mathf.CeilToInt(InputData.Resolution.x / 16), Mathf.CeilToInt(InputData.Resolution.y / 16), 1); 110 | CmdBuffer.CopyTexture(SRV_ColorMask, UAV_SpatialColor); 111 | } 112 | } 113 | } 114 | 115 | public static void TemporalFilter(CommandBuffer CmdBuffer, RenderTargetIdentifier SRV_RayDepth, RenderTargetIdentifier SRV_CurrColor, RenderTargetIdentifier SRV_PrevColor, RenderTargetIdentifier UAV_TemporalColor, ref SVGFParameterDescriptor Parameters, ref SVGFInputDescriptor InputData) 116 | { 117 | CmdBuffer.SetComputeFloatParam(SVGF_Shader, SVGF_TemporalShaderID.TemporalScale, Parameters.TemporalScale); 118 | CmdBuffer.SetComputeFloatParam(SVGF_Shader, SVGF_TemporalShaderID.TemporalWeight, Parameters.TemporalWeight); 119 | CmdBuffer.SetComputeVectorParam(SVGF_Shader, SVGF_TemporalShaderID.TemporalSize, InputData.Resolution); 120 | CmdBuffer.SetComputeMatrixParam(SVGF_Shader, SVGF_TemporalShaderID.Matrix_PrevViewProj, InputData.Matrix_PrevViewProj); 121 | CmdBuffer.SetComputeMatrixParam(SVGF_Shader, SVGF_TemporalShaderID.Matrix_ViewProj, InputData.Matrix_ViewProj); 122 | CmdBuffer.SetComputeMatrixParam(SVGF_Shader, SVGF_TemporalShaderID.Matrix_InvViewProj, InputData.Matrix_InvViewProj); 123 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 1, SVGF_TemporalShaderID.SRV_GBufferMotion, InputData.SRV_GBufferMotion); 124 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 1, SVGF_TemporalShaderID.SRV_RayDepth, SRV_RayDepth); 125 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 1, SVGF_TemporalShaderID.SRV_CurrColor, SRV_CurrColor); 126 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 1, SVGF_TemporalShaderID.SRV_PrevColor, SRV_PrevColor); 127 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 1, SVGF_TemporalShaderID.UAV_TemporalColor, UAV_TemporalColor); 128 | CmdBuffer.DispatchCompute(SVGF_Shader, 1, Mathf.CeilToInt(InputData.Resolution.x / 16), Mathf.CeilToInt(InputData.Resolution.y / 16), 1); 129 | } 130 | 131 | public static void BilateralFilter(CommandBuffer CmdBuffer, RenderTargetIdentifier SRV_InputColor, RenderTargetIdentifier UAV_BilateralColor, ref SVGFParameterDescriptor Parameters, ref SVGFInputDescriptor InputData) 132 | { 133 | CmdBuffer.SetComputeFloatParam(SVGF_Shader, SVGF_BilateralShaderID.BilateralRadius, Parameters.BilateralRadius); 134 | CmdBuffer.SetComputeFloatParam(SVGF_Shader, SVGF_BilateralShaderID.ColorWeight, Parameters.BilateralColorWeight); 135 | CmdBuffer.SetComputeFloatParam(SVGF_Shader, SVGF_BilateralShaderID.NormalWeight, Parameters.BilateralNormalWeight); 136 | CmdBuffer.SetComputeFloatParam(SVGF_Shader, SVGF_BilateralShaderID.DepthWeight, Parameters.BilateralDepthWeight); 137 | CmdBuffer.SetComputeVectorParam(SVGF_Shader, SVGF_BilateralShaderID.BilateralSize, InputData.Resolution); 138 | 139 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 1, SVGF_BilateralShaderID.SRV_InputColor, SRV_InputColor); 140 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 1, SVGF_BilateralShaderID.SRV_GBufferNormal, InputData.SRV_GBufferNormal); 141 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 1, SVGF_BilateralShaderID.SRV_SceneDepth, InputData.SRV_SceneDepth); 142 | CmdBuffer.SetComputeTextureParam(SVGF_Shader, 1, SVGF_BilateralShaderID.UAV_BilateralColor, UAV_BilateralColor); 143 | CmdBuffer.DispatchCompute(SVGF_Shader, 1, Mathf.CeilToInt(InputData.Resolution.x / 16), Mathf.CeilToInt(InputData.Resolution.y / 16), 1); 144 | //CmdBuffer.CopyTexture(UAV_BilateralColor, InputData.SRV_PrevColor); 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /Runtime/Script/Post_SSR.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Unity.Mathematics; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.PostProcessing; 6 | using InfinityTech.Runtime.Rendering.Feature; 7 | using IntParameter = UnityEngine.Rendering.PostProcessing.IntParameter; 8 | using FloatParameter = UnityEngine.Rendering.PostProcessing.FloatParameter; 9 | 10 | [System.Serializable] 11 | public enum PostRenderSize 12 | { 13 | Full = 1, 14 | Half = 2 15 | } 16 | 17 | [Serializable] 18 | public class SSRRenderMode : ParameterOverride {} 19 | 20 | [Serializable] 21 | [PostProcess(typeof(ScreenSpaceReflectionRender), PostProcessEvent.BeforeTransparent, "InfinityRender/ScreenSpaceReflection")] 22 | public class ScreenSpaceReflection : PostProcessEffectSettings 23 | { 24 | [Header("TraceProperty")] 25 | public SSRRenderMode RenderMode = new SSRRenderMode() {value = PostRenderSize.Full}; 26 | 27 | [Range(1, 12)] 28 | public IntParameter NumRays = new IntParameter(){value = 4}; 29 | 30 | [Range(8, 64)] 31 | public IntParameter NumSteps = new IntParameter(){value = 8}; 32 | 33 | [Range(0, 1)] 34 | public FloatParameter BRDFBias = new FloatParameter() { value = 0.7f }; 35 | 36 | [Range(0.05f, 0.25f)] 37 | public FloatParameter Fadeness = new FloatParameter() { value = 0.1f }; 38 | 39 | [Range(0, 1)] 40 | public FloatParameter RoughnessDiscard = new FloatParameter() { value = 0.5f }; 41 | 42 | ///////////////////////////////////////////////////////////////////////////////////////////// 43 | [Header("FilterProperty")] 44 | public BoolParameter EnableSpatial = new BoolParameter(){value = true}; 45 | [Range(1, 4)] 46 | public IntParameter NumSpatial = new IntParameter(){value = 1}; 47 | 48 | [Range(1, 2)] 49 | public FloatParameter SpatialRadius = new FloatParameter(){value = 2}; 50 | 51 | [Range(0, 8)] 52 | public FloatParameter TemporalScale = new FloatParameter(){value = 1.25f}; 53 | 54 | [Range(0, 0.99f)] 55 | public FloatParameter TemporalWeight = new FloatParameter(){value = 0.99f}; 56 | 57 | [Range(0, 2)] 58 | public IntParameter NumBilateral = new IntParameter() { value = 1 }; 59 | 60 | /*[Range(0.1f, 1)] 61 | public FloatParameter BilateralColorWeight = new FloatParameter() { value = 1 }; 62 | 63 | [Range(0.1f, 1)] 64 | public FloatParameter BilateralDepthWeight = new FloatParameter() { value = 1 }; 65 | 66 | [Range(0.1f, 1)] 67 | public FloatParameter BilateralNormalWeight = new FloatParameter() { value = 0.1f };*/ 68 | 69 | ///////////////////////////////////////////////////////////////////////////////////////////// 70 | public override bool IsEnabledAndSupported(PostProcessRenderContext context) { 71 | return enabled 72 | && context.camera.actualRenderingPath == RenderingPath.DeferredShading 73 | && SystemInfo.supportsMotionVectors 74 | && SystemInfo.supportsComputeShaders 75 | && SystemInfo.copyTextureSupport > CopyTextureSupport.None; 76 | } 77 | 78 | } 79 | 80 | public class ScreenSpaceReflectionRender : PostProcessEffectRenderer 81 | { 82 | private int[] ColorPyramidMipIDs, DepthPyramidMipIDs; 83 | private SSRParameterDescriptor SSRParameter; 84 | private SSRInputDescriptor SSRInputData; 85 | private SVGFParameterDescriptor SVGFParamete; 86 | private SVGFInputDescriptor SVGFInputData; 87 | 88 | private int2 PrevScreenSize; 89 | private RenderTexture RTV_PyramidDepth; 90 | //private Shader CompositingShader; 91 | private Material CompositingMaterial; 92 | 93 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 94 | public override void Init() { 95 | //CompositingShader = Resources.Load("Hidden/SSRCompositing"); 96 | CompositingMaterial = new Material(Shader.Find("Hidden/SSRCompositing")); 97 | PyramidDepthGenerator.DepthPyramidInit(ref DepthPyramidMipIDs); 98 | SSRInputData.FrameIndex = 0; 99 | SVGFInputData.FrameIndex = 0; 100 | } 101 | 102 | public override void Render(PostProcessRenderContext RenderContent) { 103 | RenderContent.command.BeginSample("ScreenSpaceReflection"); 104 | 105 | int2 ScreenSize = new int2(RenderContent.camera.pixelWidth, RenderContent.camera.pixelHeight); 106 | int2 HZBSize = new int2(1024, 1024); 107 | //int2 HZBSize = ScreenSize; 108 | Matrix4x4 WorldToViewMatrix = RenderContent.camera.worldToCameraMatrix; 109 | Matrix4x4 ProjectionMatrix = GL.GetGPUProjectionMatrix(RenderContent.camera.projectionMatrix, false); 110 | Matrix4x4 ViewProjectionMatrix = ProjectionMatrix * WorldToViewMatrix; 111 | 112 | { 113 | SSRParameter.NumRays = settings.NumRays; 114 | SSRParameter.NumSteps = settings.NumSteps; 115 | SSRParameter.BRDFBias = settings.BRDFBias; 116 | SSRParameter.Fadeness = settings.Fadeness; 117 | SSRParameter.RoughnessDiscard = settings.RoughnessDiscard; 118 | //////////////////////////////////////////////////////////////// 119 | SSRInputData.FrameIndex += 1; 120 | SSRInputData.Matrix_Proj = ProjectionMatrix; 121 | SSRInputData.Matrix_InvProj = ProjectionMatrix.inverse; 122 | SSRInputData.Matrix_InvViewProj = ViewProjectionMatrix.inverse; 123 | SSRInputData.Matrix_WorldToView = WorldToViewMatrix; 124 | SSRInputData.SRV_PyramidColor = RenderContent.source; 125 | SSRInputData.SRV_SceneDepth = BuiltinRenderTextureType.ResolvedDepth; 126 | SSRInputData.SRV_GBufferNormal = BuiltinRenderTextureType.GBuffer2; 127 | SSRInputData.SRV_GBufferRoughness = BuiltinRenderTextureType.GBuffer1; 128 | SSRInputData.TraceResolution = new float4(ScreenSize.x / (int)settings.RenderMode.value, ScreenSize.y / (int)settings.RenderMode.value, 1.0f / (ScreenSize.x / (int)settings.RenderMode.value), 1.0f / (ScreenSize.y / (int)settings.RenderMode.value)); 129 | } 130 | 131 | { 132 | SVGFParamete.NumSpatial = settings.NumSpatial; 133 | SVGFParamete.SpatialRadius = settings.SpatialRadius; 134 | SVGFParamete.TemporalScale = settings.TemporalScale; 135 | SVGFParamete.TemporalWeight = settings.TemporalWeight; 136 | //////////////////////////////////////////////////////////////// 137 | SVGFInputData.FrameIndex += 1; 138 | SVGFInputData.Resolution = new float4(ScreenSize.x, ScreenSize.y, 1.0f / ScreenSize.x , 1.0f / ScreenSize.y); 139 | SVGFInputData.Matrix_InvProj = ProjectionMatrix.inverse; 140 | SVGFInputData.Matrix_ViewProj = ViewProjectionMatrix; 141 | SVGFInputData.Matrix_InvViewProj = ViewProjectionMatrix.inverse; 142 | SVGFInputData.Matrix_WorldToView = WorldToViewMatrix; 143 | SVGFInputData.SRV_GBufferMotion = BuiltinRenderTextureType.MotionVectors; 144 | SVGFInputData.SRV_SceneDepth = BuiltinRenderTextureType.ResolvedDepth; 145 | SVGFInputData.SRV_GBufferNormal = BuiltinRenderTextureType.GBuffer2; 146 | SVGFInputData.SRV_GBufferRoughness = BuiltinRenderTextureType.GBuffer1; 147 | } 148 | 149 | //////Depth Pyramid 150 | RenderContent.command.BeginSample("Depth Pyramid"); 151 | RenderTextureDescriptor PyramidDepthDesc = new RenderTextureDescriptor(HZBSize.x, HZBSize.y, RenderTextureFormat.RHalf, 0) { 152 | bindMS = false, 153 | useMipMap = true, 154 | autoGenerateMips = false, 155 | dimension = TextureDimension.Tex2D 156 | }; 157 | RTV_PyramidDepth = RenderTexture.GetTemporary(PyramidDepthDesc); 158 | RTV_PyramidDepth.filterMode = FilterMode.Point; 159 | 160 | SSRInputData.SRV_PyramidDepth = new RenderTargetIdentifier(RTV_PyramidDepth); 161 | RenderContent.command.BlitFullscreenTriangle(BuiltinRenderTextureType.ResolvedDepth, SSRInputData.SRV_PyramidDepth); 162 | PyramidDepthGenerator.DepthPyramidUpdate(ref DepthPyramidMipIDs,ref HZBSize, SSRInputData.SRV_PyramidDepth, RenderContent.command); 163 | RenderContent.command.EndSample("Depth Pyramid"); 164 | 165 | //////Ray Casting 166 | RenderContent.command.BeginSample("Reflection Raytrace"); 167 | RenderContent.command.GetTemporaryRT(SSRShaderID.UAV_ReflectionUVWPDF, (int)SSRInputData.TraceResolution.x, (int)SSRInputData.TraceResolution.y, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default, 1, true); 168 | RenderContent.command.GetTemporaryRT(SSRShaderID.UAV_ReflectionColorMask, (int)SSRInputData.TraceResolution.x, (int)SSRInputData.TraceResolution.y, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default, 1, true); 169 | RenderTargetIdentifier ReflectionUWVPDF = new RenderTargetIdentifier(SSRShaderID.UAV_ReflectionUVWPDF); 170 | RenderTargetIdentifier ReflectionColorMask = new RenderTargetIdentifier(SSRShaderID.UAV_ReflectionColorMask); 171 | SSR.Render(RenderContent.command, ReflectionUWVPDF, ReflectionColorMask, ref SSRParameter, ref SSRInputData); 172 | RenderContent.command.EndSample("Reflection Raytrace"); 173 | 174 | //////Spatial Filter 175 | RenderContent.command.BeginSample("Reflection SpatialFilter"); 176 | RenderContent.command.GetTemporaryRT(SVGF_SpatialShaderID.UAV_SpatialColor, (int)SSRInputData.TraceResolution.x, (int)SSRInputData.TraceResolution.y, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default, 1, true); 177 | RenderTargetIdentifier UAV_SpatialColor; 178 | if(settings.EnableSpatial) { 179 | UAV_SpatialColor = new RenderTargetIdentifier(SVGF_SpatialShaderID.UAV_SpatialColor); 180 | SVGFilter.SpatialFilter(RenderContent.command, ReflectionUWVPDF, ReflectionColorMask, UAV_SpatialColor, ref SVGFParamete, ref SVGFInputData); 181 | } else { 182 | UAV_SpatialColor = ReflectionColorMask; 183 | } 184 | RenderContent.command.EndSample("Reflection SpatialFilter"); 185 | 186 | //////Temporal Filter 187 | RenderContent.command.BeginSample("Reflection TemporalFilter"); 188 | RenderContent.command.GetTemporaryRT(SVGF_TemporalShaderID.SRV_PrevColor, (int)SSRInputData.TraceResolution.x, (int)SSRInputData.TraceResolution.y, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default, 1, false); 189 | RenderContent.command.GetTemporaryRT(SVGF_TemporalShaderID.UAV_TemporalColor, (int)SSRInputData.TraceResolution.x, (int)SSRInputData.TraceResolution.y, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default, 1, true); 190 | RenderTargetIdentifier SRV_PrevColor = new RenderTargetIdentifier(SVGF_TemporalShaderID.SRV_PrevColor); 191 | RenderTargetIdentifier UAV_TemporalColor = new RenderTargetIdentifier(SVGF_TemporalShaderID.UAV_TemporalColor); 192 | SVGFilter.TemporalFilter(RenderContent.command, ReflectionUWVPDF, UAV_SpatialColor, SRV_PrevColor, UAV_TemporalColor, ref SVGFParamete, ref SVGFInputData); 193 | RenderContent.command.CopyTexture(UAV_TemporalColor, SRV_PrevColor); 194 | RenderContent.command.EndSample("Reflection TemporalFilter"); 195 | 196 | RenderContent.command.BeginSample("Reflection Blit"); 197 | //PropertySheet Sheet = RenderContent.propertySheets.Get(CompositingShader); 198 | RenderContent.command.SetGlobalMatrix("_Matrix_InvViewProj", ViewProjectionMatrix.inverse); 199 | RenderContent.command.SetGlobalTexture("_SRV_SSRAlpha", UAV_SpatialColor); 200 | RenderContent.command.SetGlobalTexture("_SRV_SSRColor", UAV_TemporalColor); 201 | BlitFullscreenTriangle(RenderContent.command, RenderContent.source, RenderContent.destination, CompositingMaterial, 0); 202 | RenderContent.command.EndSample("Reflection Blit"); 203 | 204 | { 205 | RenderContent.command.ReleaseTemporaryRT(SSRShaderID.UAV_ReflectionUVWPDF); 206 | RenderContent.command.ReleaseTemporaryRT(SSRShaderID.UAV_ReflectionColorMask); 207 | RenderContent.command.ReleaseTemporaryRT(SVGF_SpatialShaderID.UAV_SpatialColor); 208 | RenderContent.command.ReleaseTemporaryRT(SVGF_TemporalShaderID.SRV_PrevColor); 209 | RenderContent.command.ReleaseTemporaryRT(SVGF_TemporalShaderID.UAV_TemporalColor); 210 | RenderTexture.ReleaseTemporary(RTV_PyramidDepth); 211 | SVGFInputData.Matrix_PrevViewProj = ViewProjectionMatrix; 212 | } 213 | 214 | RenderContent.command.EndSample("ScreenSpaceReflection"); 215 | } 216 | 217 | public override void Release() { 218 | 219 | } 220 | 221 | public static void BlitFullscreenTriangle(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, int pass, bool clear = false) 222 | { 223 | cmd.SetGlobalTexture("_MainTex", source); 224 | cmd.SetRenderTarget(destination); 225 | 226 | if (clear) 227 | cmd.ClearRenderTarget(true, true, Color.clear); 228 | 229 | cmd.DrawMesh(RuntimeUtilities.fullscreenTriangle, Matrix4x4.identity, material, 0, pass); 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /Shaders/Private/Montcalo.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef _Montcalo_ 2 | #define _Montcalo_ 3 | 4 | #include "Common.hlsl" 5 | 6 | Texture2D _Ranking_Tile; 7 | Texture2D _Scrambled_Tile; 8 | Texture2D _ScrambledOwen_Noise; 9 | Texture2D _Scrambled_Noise; 10 | 11 | float ScramblingValueFloat(uint2 pixelCoord) 12 | { 13 | pixelCoord = pixelCoord & 255; 14 | return _Scrambled_Noise[uint2(pixelCoord.x, pixelCoord.y)].x; 15 | } 16 | 17 | float2 ScramblingValueFloat2(uint2 pixelCoord) 18 | { 19 | pixelCoord = pixelCoord & 255; 20 | return _Scrambled_Noise[uint2(pixelCoord.x, pixelCoord.y)].xy; 21 | } 22 | 23 | uint ScramblingValueUInt(uint2 pixelCoord) 24 | { 25 | pixelCoord = pixelCoord & 255; 26 | return clamp((uint)(_Scrambled_Noise[uint2(pixelCoord.x, pixelCoord.y)].x * 256.0f), 0, 255); 27 | } 28 | 29 | uint2 ScramblingValueUInt2(uint2 pixelCoord) 30 | { 31 | pixelCoord = pixelCoord & 255; 32 | return clamp((uint2)(_Scrambled_Noise[uint2(pixelCoord.x, pixelCoord.y)] * 256.0f), uint2(0,0), uint2(255, 255)); 33 | } 34 | 35 | float GetLDSequenceSampleFloat(uint sampleIndex, uint sampleDimension) 36 | { 37 | sampleIndex = sampleIndex & 255; 38 | return _ScrambledOwen_Noise[uint2(sampleDimension, sampleIndex)]; 39 | } 40 | 41 | uint GetLDSequenceSampleUInt(uint sampleIndex, uint sampleDimension) 42 | { 43 | sampleIndex = sampleIndex & 255; 44 | return clamp((uint)(_ScrambledOwen_Noise[uint2(sampleDimension, sampleIndex)] * 256.0f), 0, 255); 45 | } 46 | 47 | float GetBNDSequenceSample(uint2 pixelCoord, int sampleIndex, int sampleDimension) 48 | { 49 | pixelCoord = pixelCoord & 127; 50 | sampleIndex = sampleIndex & 255; 51 | 52 | uint rankingIndex = (pixelCoord.x + pixelCoord.y * 128) * 8 + (sampleDimension & 7); 53 | uint rankedSampleIndex = sampleIndex ^ clamp((uint)(_Ranking_Tile[uint2(rankingIndex & 127, rankingIndex / 128)] * 256.0f), 0, 255); 54 | 55 | uint value = clamp((uint)(_ScrambledOwen_Noise[uint2(sampleDimension, rankedSampleIndex.x)] * 256.0f), 0, 255); 56 | 57 | uint scramblingIndex = (pixelCoord.x + pixelCoord.y * 128) * 8 + (sampleDimension & 7); 58 | value = value ^ clamp((uint)(_Scrambled_Tile[uint2(scramblingIndex & 127, scramblingIndex / 128)] * 256.0f), 0, 255); 59 | 60 | return (0.5f + value) / 256.0f; 61 | } 62 | 63 | uint ReverseBits32(uint bits) 64 | { 65 | bits = (bits << 16) | (bits >> 16); 66 | bits = ((bits & 0x00ff00ff) << 8) | ((bits & 0xff00ff00) >> 8); 67 | bits = ((bits & 0x0f0f0f0f) << 4) | ((bits & 0xf0f0f0f0) >> 4); 68 | bits = ((bits & 0x33333333) << 2) | ((bits & 0xcccccccc) >> 2); 69 | bits = ((bits & 0x55555555) << 1) | ((bits & 0xaaaaaaaa) >> 1); 70 | return bits; 71 | } 72 | 73 | float RadicalInverse_VdC(uint bits) 74 | { 75 | bits = (bits << 16u) | (bits >> 16u); 76 | bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); 77 | bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); 78 | bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); 79 | bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); 80 | return float(bits) * 2.3283064365386963e-10; 81 | } 82 | 83 | float RadicalInverseSpecialized(uint base, uint a) 84 | { 85 | const float invBase = (float) 1 / (float) base; 86 | uint reversedDigits = 0; 87 | float invBaseN = 1; 88 | while (a > 0) { 89 | uint next = a / base; 90 | uint digit = a - next * base; 91 | reversedDigits = reversedDigits * base + digit; 92 | invBaseN *= invBase; 93 | a = next; 94 | } 95 | return reversedDigits * invBaseN; 96 | } 97 | 98 | float RadicalInverseSpecialized2(uint a) 99 | { 100 | return (float) reversebits(a) / (float) 0xffffffffu; 101 | } 102 | 103 | uint2 SobolIndex(uint2 Base, int Index, int Bits = 10) { 104 | uint2 SobolNumbers[10] = { 105 | uint2(0x8680u, 0x4c80u), uint2(0xf240u, 0x9240u), uint2(0x8220u, 0x0e20u), uint2(0x4110u, 0x1610u), uint2(0xa608u, 0x7608u), 106 | uint2(0x8a02u, 0x280au), uint2(0xe204u, 0x9e04u), uint2(0xa400u, 0x4682u), uint2(0xe300u, 0xa74du), uint2(0xb700u, 0x9817u), 107 | }; 108 | 109 | uint2 Result = Base; 110 | [roll] 111 | for (int b = 0; b < 10 && b < Bits; ++b) { 112 | Result ^= (Index & (1 << b)) ? SobolNumbers[b] : 0; 113 | } 114 | return Result; 115 | } 116 | 117 | uint Halton(uint Index, uint base = 3) 118 | { 119 | uint result = 0; 120 | uint f = 1; 121 | uint i = Index; 122 | 123 | [unroll(255)] 124 | while (i > 0) { 125 | result += (f / base) * (i % base); 126 | i = floor(i / base); 127 | } 128 | return result; 129 | } 130 | 131 | float2 Halton(uint Index, uint2 Random) 132 | { 133 | float E1 = float( ( ReverseBits32(Index) >> 16 ) ^ Random.x ) * (1.0 / 65536.0); 134 | float E2 = float( ( ReverseBits32(Index) >> 16 ) ^ Random.y ) * (1.0 / 65536.0); 135 | return float2( E1, E2 ); 136 | } 137 | 138 | float2 Hammersley(uint Index, uint NumSamples) 139 | { 140 | return float2( (float) Index / (float) NumSamples, RadicalInverse_VdC(Index) ); 141 | } 142 | 143 | float2 Hammersley(uint Index, uint NumSamples, uint2 Random) 144 | { 145 | float E1 = frac((float)Index / NumSamples + float(Random.x & 0xffff) / (1 << 16)); 146 | float E2 = float(ReverseBits32(Index) ^ Random.y) * 2.3283064365386963e-10; 147 | return float2(E1, E2); 148 | } 149 | 150 | float2 Hammersley2(uint a) 151 | { 152 | return float2(RadicalInverseSpecialized2(a), RadicalInverseSpecialized(3, a)); 153 | } 154 | 155 | float2 Hammersley16(uint Index, uint NumSamples, uint2 Random) 156 | { 157 | float E1 = frac( (float)Index / NumSamples + float( Random.x ) * (1.0 / 65536.0) ); 158 | float E2 = float( ( ReverseBits32(Index) >> 16 ) ^ Random.y ) * (1.0 / 65536.0); 159 | return float2( E1, E2 ); 160 | } 161 | 162 | float3x3 GetTangentBasis(float3 TangentZ) { 163 | float3 UpVector = abs(TangentZ.z) < 0.999 ? float3(0, 0, 1) : float3(1, 0, 0); 164 | float3 TangentX = normalize(cross( UpVector, TangentZ)); 165 | float3 TangentY = cross(TangentZ, TangentX); 166 | return float3x3(TangentX, TangentY, TangentZ); 167 | } 168 | 169 | float3 TangentToWorld(float3 Vec, float3 TangentZ) 170 | { 171 | return mul(Vec, GetTangentBasis(TangentZ)); 172 | } 173 | 174 | float3 WorldToTangent(float3 Vec, float3 TangentZ) 175 | { 176 | return mul(GetTangentBasis(TangentZ), Vec); 177 | } 178 | 179 | float4 TangentToWorld(float3 Vec, float4 TangentZ) 180 | { 181 | half3 T2W = TangentToWorld(Vec, TangentZ.rgb); 182 | return half4(T2W, TangentZ.a); 183 | } 184 | 185 | float2 RandToCircle(uint2 Rand) { 186 | float2 sf = float2(Rand) * (sqrt(2.) / 0xffff) - sqrt(0.5); 187 | float2 sq = sf*sf; 188 | float root = sqrt(2.*max(sq.x, sq.y) - min(sq.x, sq.y)); 189 | if (sq.x > sq.y) { 190 | sf.x = sf.x > 0 ? root : -root; 191 | } 192 | else { 193 | sf.y = sf.y > 0 ? root : -root; 194 | } 195 | return sf; 196 | } 197 | 198 | /////////////Sampler 199 | float2 UniformSampleDisk( float2 E ) 200 | { 201 | float Theta = 2 * Pi * E.x; 202 | float Radius = sqrt( E.y ); 203 | return Radius * float2( cos( Theta ), sin( Theta ) ); 204 | } 205 | 206 | float2 UniformSampleDiskConcentric( float2 E ) 207 | { 208 | float2 p = 2 * E - 1; 209 | float Radius; 210 | float Phi; 211 | if( abs( p.x ) > abs( p.y ) ) 212 | { 213 | Radius = p.x; 214 | Phi = (Pi / 4) * (p.y / p.x); 215 | } 216 | else 217 | { 218 | Radius = p.y; 219 | Phi = (Pi / 2) - (Pi /4) * (p.x / p.y); 220 | } 221 | return float2( Radius * cos( Phi ), Radius * sin( Phi ) ); 222 | } 223 | 224 | float2 UniformSampleDiskConcentricApprox( float2 E ) 225 | { 226 | float2 sf = E * sqrt(2.0) - sqrt(0.5); // map 0..1 to -sqrt(0.5)..sqrt(0.5) 227 | float2 sq = sf*sf; 228 | float root = sqrt(2.0*max(sq.x, sq.y) - min(sq.x, sq.y)); 229 | if (sq.x > sq.y) 230 | { 231 | sf.x = sf.x > 0 ? root : -root; 232 | } 233 | else 234 | { 235 | sf.y = sf.y > 0 ? root : -root; 236 | } 237 | return sf; 238 | } 239 | 240 | float4 UniformSampleSphere(float2 E) { 241 | float Phi = 2 * Pi * E.x;// 242 | float CosTheta = 1 - 2 * E.y; 243 | float SinTheta = sqrt(1 - CosTheta * CosTheta); 244 | 245 | float3 H; 246 | H.x = SinTheta * cos(Phi); 247 | H.y = SinTheta * sin(Phi); 248 | H.z = CosTheta; 249 | 250 | float PDF = 1 / (4 * Pi); 251 | 252 | return float4(H, PDF); 253 | } 254 | 255 | float4 UniformSampleHemisphere(float2 E) { 256 | float Phi = 2 * Pi * E.x; 257 | float CosTheta = E.y; 258 | float SinTheta = sqrt(1 - CosTheta * CosTheta); 259 | 260 | float3 H; 261 | H.x = SinTheta * cos( Phi ); 262 | H.y = SinTheta * sin( Phi ); 263 | H.z = CosTheta; 264 | 265 | float PDF = 1.0 / (2 * Pi); 266 | return float4(H, PDF); 267 | } 268 | 269 | float4 CosineSampleHemisphere(float2 E) { 270 | float Phi = 2 * Pi * E.x; 271 | float CosTheta = sqrt(E.y); 272 | float SinTheta = sqrt(1 - CosTheta * CosTheta); 273 | 274 | float3 H; 275 | H.x = SinTheta * cos(Phi); 276 | H.y = SinTheta * sin(Phi); 277 | H.z = CosTheta; 278 | 279 | float PDF = CosTheta / Pi; 280 | return float4(H, PDF); 281 | } 282 | 283 | float4 CosineSampleHemisphere(float2 E, float3 N) { 284 | float3 H = UniformSampleSphere( E ).xyz; 285 | H = normalize( N + H ); 286 | 287 | float PDF = H.z * Inv_Pi; 288 | 289 | return float4( H, PDF ); 290 | } 291 | 292 | float4 UniformSampleCone(float2 E, float CosThetaMax) { 293 | float Phi = 2 * Pi * E.x; 294 | float CosTheta = lerp(CosThetaMax, 1, E.y); 295 | float SinTheta = sqrt(1 - CosTheta * CosTheta); 296 | 297 | float3 L; 298 | L.x = SinTheta * cos( Phi ); 299 | L.y = SinTheta * sin( Phi ); 300 | L.z = CosTheta; 301 | 302 | float PDF = 1.0 / (2 * Pi * (1 - CosThetaMax)); 303 | return float4(L, PDF); 304 | } 305 | 306 | float4 ImportanceSampleLambert(float2 E) 307 | { 308 | float3 L = CosineSampleHemisphere(E).rgb; 309 | return float4(L, 1); 310 | } 311 | 312 | float4 ImportanceSampleBlinn(float2 E, float Roughness) { 313 | float m = Roughness * Roughness; 314 | float m2 = m * m; 315 | 316 | float Phi = 2 * Pi * E.x; 317 | float n = 2 / m2 - 2; 318 | float CosTheta = pow(max(E.y, 0.001), 1 / (n + 1)); 319 | float SinTheta = sqrt(1 - CosTheta * CosTheta); 320 | 321 | float3 H; 322 | H.x = SinTheta * cos(Phi); 323 | H.y = SinTheta * sin(Phi); 324 | H.z = CosTheta; 325 | 326 | float D = (n + 2)/ Two_Pi * saturate(pow(CosTheta, n)); 327 | float PDF = D * CosTheta; 328 | return float4(H, PDF); 329 | } 330 | 331 | float4 ImportanceSampleGGX(float2 E, float Roughness) { 332 | float m = Roughness * Roughness; 333 | float m2 = m * m; 334 | 335 | float Phi = 2 * Pi * E.x; 336 | float CosTheta = sqrt( (1 - E.y) / ( 1 + (m2 - 1) * E.y) ); 337 | float SinTheta = sqrt(1 - CosTheta * CosTheta); 338 | 339 | float3 H; 340 | H.x = SinTheta * cos(Phi); 341 | H.y = SinTheta * sin(Phi); 342 | H.z = CosTheta; 343 | 344 | float d = (CosTheta * m2 - CosTheta) * CosTheta + 1; 345 | float D = m2 / (Pi * d * d); 346 | 347 | float PDF = D * CosTheta; 348 | return float4(H, PDF); 349 | } 350 | 351 | float4 ImportanceSampleVisibleGGX( float2 E, float Roughness, float3 V ) 352 | { 353 | float a = Roughness * Roughness; 354 | float a2 = a * a; 355 | 356 | // stretch 357 | float3 Vh = normalize( float3( a * V.xy, V.z ) ); 358 | 359 | // Orthonormal basis 360 | float3 Tangent0 = (Vh.z < 0.9999) ? normalize( cross( float3(0, 0, 1), Vh ) ) : float3(1, 0, 0); 361 | float3 Tangent1 = cross( Vh, Tangent0 ); 362 | 363 | float Radius = sqrt( E.x ); 364 | float Phi = 2 * Pi * E.y; 365 | 366 | float2 p = Radius * float2( cos( Phi ), sin( Phi ) ); 367 | float s = 0.5 + 0.5 * Vh.z; 368 | p.y = (1 - s) * sqrt( 1 - p.x * p.x ) + s * p.y; 369 | 370 | float3 H; 371 | H = p.x * Tangent0; 372 | H += p.y * Tangent1; 373 | H += sqrt( saturate( 1 - dot( p, p ) ) ) * Vh; 374 | 375 | // unstretch 376 | H = normalize( float3( a * H.xy, max(0.0, H.z) ) ); 377 | 378 | float NoV = V.z; 379 | float NoH = H.z; 380 | float VoH = dot(V, H); 381 | 382 | float d = (NoH * a2 - NoH) * NoH + 1; 383 | float D = a2 / (Pi * d * d); 384 | 385 | float G_SmithV = 2 * NoV / (NoV + sqrt(NoV * (NoV - NoV * a2) + a2)); 386 | 387 | float PDF = G_SmithV * VoH * D / NoV; 388 | 389 | return float4(H, PDF); 390 | } 391 | 392 | void SampleAnisoGGXDir(float2 u, float3 V, float3 N, float3 tX, float3 tY, float roughnessT, float roughnessB, out float3 H, out float3 L) { 393 | H = sqrt(u.x / (1 - u.x)) * (roughnessT * cos(Two_Pi * u.y) * tX + roughnessB * sin(Two_Pi * u.y) * tY) + N; 394 | H = normalize(H); 395 | L = 2 * saturate(dot(V, H)) * H - V; 396 | } 397 | 398 | void ImportanceSampleAnisoGGX(float2 u, float3 V, float3 N, float3 tX, float3 tY, float roughnessT, float roughnessB, float NoV, out float3 L, out float VoH, out float NoL, out float weightOverPdf) 399 | { 400 | float3 H; 401 | SampleAnisoGGXDir(u, V, N, tX, tY, roughnessT, roughnessB, H, L); 402 | 403 | float NoH = saturate(dot(N, H)); 404 | VoH = saturate(dot(V, H)); 405 | NoL = saturate(dot(N, L)); 406 | 407 | float ToV = dot(tX, V); 408 | float BoV = dot(tY, V); 409 | float ToL = dot(tX, L); 410 | float BoL = dot(tY, L); 411 | 412 | float aT = roughnessT; 413 | float aT2 = aT * aT; 414 | float aB = roughnessB; 415 | float aB2 = aB * aB; 416 | float lambdaV = NoL * sqrt(aT2 * ToV * ToV + aB2 * BoV * BoV + NoV * NoV); 417 | float lambdaL = NoV * sqrt(aT2 * ToL * ToL + aB2 * BoL * BoL + NoL * NoL); 418 | float Vis = 0.5 / (lambdaV + lambdaL); 419 | 420 | weightOverPdf = 4 * Vis * NoL * VoH / NoH; 421 | } 422 | 423 | float MISWeight(uint Num, float PDF, uint OtherNum, float OtherPDF) { 424 | float Weight = Num * PDF; 425 | float OtherWeight = OtherNum * OtherPDF; 426 | return Weight * Weight / (Weight * Weight + OtherWeight * OtherWeight); 427 | } 428 | 429 | #endif -------------------------------------------------------------------------------- /Runtime/RenderFeature/ScreenSpaceReflection/Script/ScreenSpaceReflection.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using Unity.Mathematics; 3 | using UnityEngine.Rendering; 4 | 5 | namespace InfinityTech.Runtime.Rendering.Feature 6 | { 7 | public struct SSRParameterDescriptor 8 | { 9 | public int NumRays; 10 | public int NumSteps; 11 | public float BRDFBias; 12 | public float Fadeness; 13 | public float RoughnessDiscard; 14 | } 15 | 16 | public struct SSRInputDescriptor 17 | { 18 | public int FrameIndex; 19 | public float4 TraceResolution; 20 | public float4x4 Matrix_Proj; 21 | public float4x4 Matrix_InvProj; 22 | public float4x4 Matrix_InvViewProj; 23 | public float4x4 Matrix_WorldToView; 24 | public RenderTargetIdentifier SRV_PyramidColor; 25 | public RenderTargetIdentifier SRV_PyramidDepth; 26 | public RenderTargetIdentifier SRV_SceneDepth; 27 | public RenderTargetIdentifier SRV_GBufferNormal; 28 | public RenderTargetIdentifier SRV_GBufferRoughness; 29 | } 30 | 31 | public static class SSRShaderID 32 | { 33 | public static int NumRays = Shader.PropertyToID("SSR_NumRays"); 34 | public static int NumSteps = Shader.PropertyToID("SSR_NumSteps"); 35 | public static int FrameIndex = Shader.PropertyToID("SSR_FrameIndex"); 36 | public static int BRDFBias = Shader.PropertyToID("SSR_BRDFBias"); 37 | public static int Fadeness = Shader.PropertyToID("SSR_Fadeness"); 38 | public static int TraceResolution = Shader.PropertyToID("SSR_TraceResolution"); 39 | public static int RoughnessDiscard = Shader.PropertyToID("SSR_RoughnessDiscard"); 40 | 41 | public static int Matrix_Proj = Shader.PropertyToID("Matrix_Proj"); 42 | public static int Matrix_InvProj = Shader.PropertyToID("Matrix_InvProj"); 43 | public static int Matrix_InvViewProj = Shader.PropertyToID("Matrix_InvViewProj"); 44 | public static int Matrix_WorldToView = Shader.PropertyToID("Matrix_WorldToView"); 45 | 46 | /*public static int SRV_Ranking_Tile = Shader.PropertyToID("SRV_Ranking_Tile"); 47 | public static int SRV_Scrambled_Tile = Shader.PropertyToID("SRV_Scrambled_Tile"); 48 | public static int SRV_Scrambled_Owen = Shader.PropertyToID("SRV_Scrambled_Owen"); 49 | public static int SRV_Scrambled_Noise = Shader.PropertyToID("SRV_Scrambled_Noise");*/ 50 | 51 | public static int SRV_PyramidColor = Shader.PropertyToID("SRV_PyramidColor"); 52 | public static int SRV_PyramidDepth = Shader.PropertyToID("SRV_PyramidDepth"); 53 | public static int SRV_SceneDepth = Shader.PropertyToID("SRV_SceneDepth"); 54 | public static int SRV_GBufferNormal = Shader.PropertyToID("SRV_GBufferNormal"); 55 | public static int SRV_GBufferRoughness = Shader.PropertyToID("SRV_GBufferRoughness"); 56 | public static int UAV_ReflectionUVWPDF = Shader.PropertyToID("UAV_ReflectionUWVPDF"); 57 | public static int UAV_ReflectionColorMask = Shader.PropertyToID("UAV_ReflectionColorMask"); 58 | } 59 | 60 | public static class SSR 61 | { 62 | /*private static Texture2D Ranking_Tile { 63 | get { 64 | return Resources.Load("Textures/MonteCarlo/RankingTile8SPP"); 65 | } 66 | } 67 | private static Texture2D Scrambled_Tile { 68 | get { 69 | return Resources.Load("Textures/MonteCarlo/ScramblingTile8SPP"); 70 | } 71 | } 72 | private static Texture2D Scrambled_Owen { 73 | get { 74 | return Resources.Load("Textures/MonteCarlo/ScrambledNoise_Owen"); 75 | } 76 | } 77 | private static Texture2D Scrambled_Noise { 78 | get { 79 | return Resources.Load("Textures/MonteCarlo/ScrambledNoise"); 80 | } 81 | }*/ 82 | 83 | private static ComputeShader SSRTraceShader { 84 | get { 85 | return Resources.Load("Shaders/SSR_TraceShader"); 86 | } 87 | } 88 | 89 | public static void Render(CommandBuffer CmdBuffer, RenderTargetIdentifier UAV_ReflectionUWVPDF, RenderTargetIdentifier UAV_ReflectionColorMask, ref SSRParameterDescriptor Parameters, ref SSRInputDescriptor InputData) { 90 | CmdBuffer.SetComputeIntParam(SSRTraceShader, SSRShaderID.NumRays, Parameters.NumRays); 91 | CmdBuffer.SetComputeIntParam(SSRTraceShader, SSRShaderID.NumSteps, Parameters.NumSteps); 92 | CmdBuffer.SetComputeIntParam(SSRTraceShader, SSRShaderID.FrameIndex, InputData.FrameIndex); 93 | 94 | CmdBuffer.SetComputeFloatParam(SSRTraceShader, SSRShaderID.BRDFBias, Parameters.BRDFBias); 95 | CmdBuffer.SetComputeFloatParam(SSRTraceShader, SSRShaderID.Fadeness, Parameters.Fadeness); 96 | CmdBuffer.SetComputeFloatParam(SSRTraceShader, SSRShaderID.RoughnessDiscard, Parameters.RoughnessDiscard); 97 | 98 | CmdBuffer.SetComputeVectorParam(SSRTraceShader, SSRShaderID.TraceResolution, InputData.TraceResolution); 99 | 100 | CmdBuffer.SetComputeMatrixParam(SSRTraceShader, SSRShaderID.Matrix_Proj, InputData.Matrix_Proj); 101 | CmdBuffer.SetComputeMatrixParam(SSRTraceShader, SSRShaderID.Matrix_InvProj, InputData.Matrix_InvProj); 102 | CmdBuffer.SetComputeMatrixParam(SSRTraceShader, SSRShaderID.Matrix_InvViewProj, InputData.Matrix_InvViewProj); 103 | CmdBuffer.SetComputeMatrixParam(SSRTraceShader, SSRShaderID.Matrix_WorldToView, InputData.Matrix_WorldToView); 104 | 105 | CmdBuffer.SetComputeTextureParam(SSRTraceShader, 0, SSRShaderID.SRV_PyramidColor, InputData.SRV_PyramidColor); 106 | CmdBuffer.SetComputeTextureParam(SSRTraceShader, 0, SSRShaderID.SRV_PyramidDepth, InputData.SRV_PyramidDepth); 107 | CmdBuffer.SetComputeTextureParam(SSRTraceShader, 0, SSRShaderID.SRV_SceneDepth, InputData.SRV_SceneDepth); 108 | CmdBuffer.SetComputeTextureParam(SSRTraceShader, 0, SSRShaderID.SRV_GBufferNormal, InputData.SRV_GBufferNormal); 109 | CmdBuffer.SetComputeTextureParam(SSRTraceShader, 0, SSRShaderID.SRV_GBufferRoughness, InputData.SRV_GBufferRoughness); 110 | CmdBuffer.SetComputeTextureParam(SSRTraceShader, 0, SSRShaderID.UAV_ReflectionUVWPDF, UAV_ReflectionUWVPDF); 111 | CmdBuffer.SetComputeTextureParam(SSRTraceShader, 0, SSRShaderID.UAV_ReflectionColorMask, UAV_ReflectionColorMask); 112 | 113 | CmdBuffer.DispatchCompute(SSRTraceShader, 0, Mathf.CeilToInt(InputData.TraceResolution.x / 16), Mathf.CeilToInt(InputData.TraceResolution.y / 16), 1); 114 | } 115 | } 116 | 117 | /*public static class RTReflection_Trace 118 | { 119 | public static void RayTrace_ReflectionTrace(ref RTReflection_TraceParameter ReflectionTraceParameter, ComputeShader RTRComputeShader, CommandBuffer CmdBuffer) { 120 | CmdBuffer.SetComputeIntParam(RTRComputeShader, RTReflection_TraceUniform.RTR_NumRay, ReflectionTraceParameter.NumRays); 121 | CmdBuffer.SetComputeIntParam(RTRComputeShader, RTReflection_TraceUniform.SRTR_NumSteps, ReflectionTraceParameter.NumSteps); 122 | CmdBuffer.SetComputeFloatParam(RTRComputeShader, RTReflection_TraceUniform.RTR_BRDFBias, ReflectionTraceParameter.BRDFBias); 123 | CmdBuffer.SetComputeFloatParam(RTRComputeShader, RTReflection_TraceUniform.SRTR_MaskFade, ReflectionTraceParameter.Fadeness); 124 | CmdBuffer.SetComputeFloatParam(RTRComputeShader, RTReflection_TraceUniform.SRTR_Thickness, ReflectionTraceParameter.Thickness); 125 | CmdBuffer.SetComputeFloatParam(RTRComputeShader, RTReflection_TraceUniform.RTR_RoughnessDiscard, (float)ReflectionTraceParameter.RoughnessDiscard); 126 | CmdBuffer.SetComputeVectorParam(RTRComputeShader, RTReflection_TraceUniform.RTR_TraceSize, new float4(ReflectionTraceParameter.TraceSize.x, ReflectionTraceParameter.TraceSize.y, 1f / ReflectionTraceParameter.TraceSize.x, 1f / ReflectionTraceParameter.TraceSize.y)); 127 | CmdBuffer.SetComputeTextureParam(RTRComputeShader, 0, RTReflection_TraceUniform.RT_ReflectionUWVPDF, ReflectionTraceParameter.ReflectionUVWPDF); 128 | CmdBuffer.SetComputeTextureParam(RTRComputeShader, 0, RTReflection_TraceUniform.RT_ReflectionColorMask, ReflectionTraceParameter.ReflectionColorMask); 129 | CmdBuffer.DispatchCompute(RTRComputeShader, 0, Mathf.CeilToInt((float)ReflectionTraceParameter.TraceSize.x / 16), Mathf.CeilToInt((float)ReflectionTraceParameter.TraceSize.y / 16), 1); 130 | } 131 | }*/ 132 | 133 | 134 | ////////////Ray Trace Reflection Denoise 135 | public struct RTReflection_SpatialParameter 136 | { 137 | public int Normalize; 138 | public int NumSpatial; 139 | public int SpatialRadius; 140 | public int2 TraceSize; 141 | public RenderTargetIdentifier ReflectionUVWPDF; 142 | public RenderTargetIdentifier ReflectionColorMask; 143 | public RenderTargetIdentifier ReflectionSpatialColor; 144 | } 145 | 146 | public static class RTReflection_SpatialUniform 147 | { 148 | public static int RT_Normalize = Shader.PropertyToID("F_RTR_Normalize"); 149 | public static int RT_NumSpatial = Shader.PropertyToID("F_RTR_NumSpatial"); 150 | public static int RT_SpatialRadius = Shader.PropertyToID("F_RTR_SpatialRadius"); 151 | public static int RT_TraceSize = Shader.PropertyToID("F_RTR_SpatialSize"); 152 | public static int RT_ReflectionUWVPDF = Shader.PropertyToID("RT_ReflectionUWVPDF"); 153 | public static int RT_ReflectionColorMask = Shader.PropertyToID("RT_ReflectionColorMask"); 154 | public static int RT_ReflectionSpatialColor = Shader.PropertyToID("RT_ReflectionSpatialColor"); 155 | } 156 | 157 | public struct RTReflection_TemporalParameter 158 | { 159 | public float TemporalScale; 160 | public float TemporalWeight; 161 | public int2 TraceSize; 162 | public RenderTargetIdentifier ReflectionCurrColor; 163 | public RenderTargetIdentifier ReflectionPrevColor; 164 | public RenderTargetIdentifier ReflectionTemporalColor; 165 | } 166 | 167 | public static class RTReflection_TemporalUniform 168 | { 169 | public static int RT_TemporalScale = Shader.PropertyToID("F_RTR_TemporalScale"); 170 | public static int RT_TemporalWeight = Shader.PropertyToID("F_RTR_TemporalWeight"); 171 | public static int RT_TraceSize = Shader.PropertyToID("F_RTR_TemporalSize"); 172 | public static int RT_ReflectionCurrColor = Shader.PropertyToID("RT_ReflectionCurrColor"); 173 | public static int RT_ReflectionPrevColor = Shader.PropertyToID("RT_ReflectionPrevColor"); 174 | public static int RT_ReflectionTemporalColor = Shader.PropertyToID("RT_ReflectionTemporalColor"); 175 | } 176 | 177 | public static class RTReflection_Denoise 178 | { 179 | public static void RayTrace_ReflectionSpatial(ref RTReflection_SpatialParameter ReflectionSpatialParameter, ComputeShader RTRComputeShader, CommandBuffer CmdBuffer) { 180 | CmdBuffer.SetComputeIntParam(RTRComputeShader, RTReflection_SpatialUniform.RT_Normalize, ReflectionSpatialParameter.Normalize); 181 | CmdBuffer.SetComputeIntParam(RTRComputeShader, RTReflection_SpatialUniform.RT_NumSpatial, ReflectionSpatialParameter.NumSpatial); 182 | CmdBuffer.SetComputeIntParam(RTRComputeShader, RTReflection_SpatialUniform.RT_SpatialRadius, ReflectionSpatialParameter.SpatialRadius); 183 | CmdBuffer.SetComputeVectorParam(RTRComputeShader, RTReflection_SpatialUniform.RT_TraceSize, new float4(ReflectionSpatialParameter.TraceSize.x, ReflectionSpatialParameter.TraceSize.y, 1f / ReflectionSpatialParameter.TraceSize.x, 1f / ReflectionSpatialParameter.TraceSize.y)); 184 | CmdBuffer.SetComputeTextureParam(RTRComputeShader, 0, RTReflection_SpatialUniform.RT_ReflectionUWVPDF, ReflectionSpatialParameter.ReflectionUVWPDF); 185 | CmdBuffer.SetComputeTextureParam(RTRComputeShader, 0, RTReflection_SpatialUniform.RT_ReflectionColorMask, ReflectionSpatialParameter.ReflectionColorMask); 186 | CmdBuffer.SetComputeTextureParam(RTRComputeShader, 0, RTReflection_SpatialUniform.RT_ReflectionSpatialColor, ReflectionSpatialParameter.ReflectionSpatialColor); 187 | CmdBuffer.DispatchCompute(RTRComputeShader, 0, Mathf.CeilToInt((float)ReflectionSpatialParameter.TraceSize.x / 16), Mathf.CeilToInt((float)ReflectionSpatialParameter.TraceSize.y / 16), 1); 188 | } 189 | 190 | public static void RayTrace_ReflectionTemporal(ref RTReflection_TemporalParameter ReflectionTemporalParameter, ComputeShader RTRComputeShader, CommandBuffer CmdBuffer) { 191 | CmdBuffer.SetComputeFloatParam(RTRComputeShader, RTReflection_TemporalUniform.RT_TemporalScale, ReflectionTemporalParameter.TemporalScale); 192 | CmdBuffer.SetComputeFloatParam(RTRComputeShader, RTReflection_TemporalUniform.RT_TemporalWeight, ReflectionTemporalParameter.TemporalWeight); 193 | CmdBuffer.SetComputeVectorParam(RTRComputeShader, RTReflection_TemporalUniform.RT_TraceSize, new float4(ReflectionTemporalParameter.TraceSize.x, ReflectionTemporalParameter.TraceSize.y, 1f / ReflectionTemporalParameter.TraceSize.x, 1f / ReflectionTemporalParameter.TraceSize.y)); 194 | CmdBuffer.SetComputeTextureParam(RTRComputeShader, 1, RTReflection_TemporalUniform.RT_ReflectionCurrColor, ReflectionTemporalParameter.ReflectionCurrColor); 195 | CmdBuffer.SetComputeTextureParam(RTRComputeShader, 1, RTReflection_TemporalUniform.RT_ReflectionPrevColor, ReflectionTemporalParameter.ReflectionPrevColor); 196 | CmdBuffer.SetComputeTextureParam(RTRComputeShader, 1, RTReflection_TemporalUniform.RT_ReflectionTemporalColor, ReflectionTemporalParameter.ReflectionTemporalColor); 197 | CmdBuffer.DispatchCompute(RTRComputeShader, 1, Mathf.CeilToInt((float)ReflectionTemporalParameter.TraceSize.x / 16), Mathf.CeilToInt((float)ReflectionTemporalParameter.TraceSize.y / 16), 1); 198 | CmdBuffer.CopyTexture(RTReflection_TemporalUniform.RT_ReflectionTemporalColor, RTReflection_TemporalUniform.RT_ReflectionPrevColor); 199 | } 200 | } 201 | } -------------------------------------------------------------------------------- /Shaders/Private/BSDF.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef _BSDF_ 2 | #define _BSDF_ 3 | 4 | #include "Common.hlsl" 5 | #include "Montcalo.hlsl" 6 | 7 | 8 | struct BSDFContext 9 | { 10 | float NoL; 11 | float NoV; 12 | float NoH; 13 | float LoH; 14 | float VoL; 15 | float VoH; 16 | }; 17 | 18 | void Init(inout BSDFContext LightData, float3 N, float3 V, float3 L, float3 H) 19 | { 20 | LightData.NoL = max(dot(N, L), 0); 21 | LightData.NoV = max(dot(N, V), 0); 22 | LightData.NoH = max(dot(N, H), 0); 23 | LightData.LoH = max(dot(L, H), 0); 24 | LightData.VoL = max(dot(V, L), 0); 25 | LightData.VoH = max(dot(V, H), 0); 26 | } 27 | 28 | struct AnisoBSDFContext 29 | { 30 | float ToH; 31 | float ToL; 32 | float ToV; 33 | float BoH; 34 | float BoL; 35 | float BoV; 36 | }; 37 | 38 | void Init_Aniso(inout AnisoBSDFContext LightData, float3 Tangent, float3 Bitangent, float3 H, float3 L, float3 V) 39 | { 40 | LightData.ToH = dot(Tangent, H); 41 | LightData.ToL = dot(Tangent, L); 42 | LightData.ToV = dot(Tangent, V); 43 | 44 | LightData.BoH = dot(Bitangent, H); 45 | LightData.BoL = dot(Bitangent, L); 46 | LightData.BoV = dot(Bitangent, V); 47 | } 48 | 49 | 50 | 51 | /////////////////////////////////////////////////////////////////Specular F 52 | float IorToFresnel(float transmittedIor, float incidentIor) 53 | { 54 | return pow2(transmittedIor - incidentIor) / pow2(transmittedIor + incidentIor); 55 | } 56 | 57 | float3 IorToFresnel(float3 transmittedIor, float3 incidentIor) 58 | { 59 | return pow2(transmittedIor - incidentIor) / pow2(transmittedIor + incidentIor); 60 | } 61 | 62 | float FresnelToIOR(float fresnel0) 63 | { 64 | return ( 1 + pow2(fresnel0) ) / ( 1 - pow2(fresnel0) ); 65 | } 66 | 67 | float3 FresnelToIOR(float3 fresnel0) 68 | { 69 | return ( 1 + pow2(fresnel0) ) / ( 1 - pow2(fresnel0) ); 70 | } 71 | 72 | float F_Schlick(float F0, float F90, float HoV) 73 | { 74 | return F0 + (F90 - F0) * pow5(1 - HoV); 75 | } 76 | 77 | float3 F_Schlick(float3 F0, float3 F90, float HoV) 78 | { 79 | float Fc = pow5( 1 - HoV ); 80 | return saturate( 50 * F0.g ) * Fc + (1 - Fc) * F0; 81 | } 82 | 83 | float3 F_Fresnel(float3 F0, float HoV) 84 | { 85 | float3 F0Sqrt = sqrt(clamp(float3(0, 0, 0), float3(0.99, 0.99, 0.99), F0)); 86 | float3 n = (1 + F0Sqrt) / (1 - F0Sqrt); 87 | float3 g = sqrt(n * n + HoV * HoV - 1); 88 | return 0.5 * Square((g - HoV) / (g + HoV)) * (1 + Square(((g + HoV) * HoV - 1) / ((g - HoV) * HoV + 1))); 89 | } 90 | 91 | float F_Hair(float CosTheta) { 92 | const float n = 1.55; 93 | const float F0 = Square((1 - n) / (1 + n)); 94 | return F0 + (1 - F0) * pow5(1 - CosTheta); 95 | } 96 | 97 | 98 | 99 | /////////////////////////////////////////////////////////////////Diffuse 100 | float3 Diffuse_Lambert(float3 DiffuseColor) 101 | { 102 | return DiffuseColor * Inv_Pi; 103 | } 104 | 105 | float3 Diffuse_Fabric(float3 DiffuseColor, float3 Roughness) 106 | { 107 | return Diffuse_Lambert(DiffuseColor) * lerp(1, 0.5, Roughness); 108 | } 109 | 110 | float Diffuse_Burley_NoPi(float LoH, float NoL, float NoV, float Roughness) 111 | { 112 | float F90 = 0.5 + 2 * pow2(LoH) * Roughness; 113 | float ViewScatter = F_Schlick(1, F90, NoL); 114 | float LightScatter = F_Schlick(1, F90, NoV); 115 | return ViewScatter * LightScatter; 116 | } 117 | 118 | float3 Diffuse_Burley(float LoH, float NoL, float NoV, float Roughness, float3 DiffuseColor) 119 | { 120 | return Diffuse_Burley_NoPi(LoH, NoL, NoV, Roughness) * (DiffuseColor * Inv_Pi); 121 | } 122 | 123 | float Diffuse_RenormalizeBurley_NoPi(float LoH, float NoL, float NoV, float Roughness) 124 | { 125 | float EnergyBias = lerp(0, 0.5, Roughness); 126 | float EnergyFactor = lerp(1, 1 / 0.662, Roughness); 127 | 128 | float F90 = EnergyBias + 2 * pow2(LoH) * Roughness; 129 | float LightScatter = F_Schlick( 1, F90, NoL ); 130 | float ViewScatter = F_Schlick( 1, F90, NoV ); 131 | return LightScatter * ViewScatter * EnergyFactor; 132 | } 133 | 134 | float3 Diffuse_RenormalizeBurley(float LoH, float NoL, float NoV, float Roughness, float3 DiffuseColor) 135 | { 136 | return Diffuse_RenormalizeBurley_NoPi(LoH, NoL, NoV, Roughness) * (DiffuseColor * Inv_Pi); 137 | } 138 | 139 | float Diffuse_OrenNayar_NoPi(float VoH, float NoL, float NoV, float Roughness) 140 | { 141 | float Roughness4 = pow4(Roughness); 142 | float VoL = 2 * VoH * VoH - 1; 143 | float Cosri = VoL - NoV * NoL; 144 | float C1 = 1 - 0.5 * Roughness4 / (Roughness4 + 0.33); 145 | float C2 = 0.45 * Roughness4 / (Roughness4 + 0.09) * Cosri * ( Cosri >= 0 ? rcp( max( NoL, NoV ) ) : 1 ); 146 | return (C1 + C2) * (1 + Roughness * 0.5); 147 | } 148 | 149 | float3 Diffuse_OrenNayar(float VoH, float NoL, float NoV, float Roughness, float3 DiffuseColor) 150 | { 151 | return Diffuse_OrenNayar_NoPi(VoH, NoL, NoV, Roughness) * (DiffuseColor * Inv_Pi); 152 | } 153 | 154 | 155 | 156 | /////////////////////////////////////////////////////////////////Specular D 157 | float D_GGX_NoPi(float NoH, float Roughness) 158 | { 159 | float Roughness2 = pow2(Roughness); 160 | float D = (NoH * Roughness - NoH) * NoH + 1; 161 | return Roughness2 / pow2(D); 162 | } 163 | 164 | float D_GGX(float NoH, float Roughness) 165 | { 166 | return Inv_Pi * D_GGX_NoPi(NoH, Roughness); 167 | } 168 | 169 | float D_Beckmann_NoPi(float NoH, float Roughness) 170 | { 171 | float Roughness2 = pow2(Roughness); 172 | float NoH2 = pow2(NoH); 173 | return exp( (NoH2 - 1) / (Roughness2 * NoH2) ) / (Roughness2 * NoH2); 174 | } 175 | 176 | float D_Beckmann(float NoH, float Roughness) 177 | { 178 | return Inv_Pi * D_Beckmann_NoPi(NoH, Roughness); 179 | } 180 | 181 | float D_AnisotropyGGX_NoPi(float ToH, float BoH, float NoH, float RoughnessT, float RoughnessB) { 182 | float D = ToH * ToH / pow2(RoughnessT) + BoH * BoH / pow2(RoughnessB) + pow2(NoH); 183 | return rcp( RoughnessT * RoughnessB * pow2(D) ); 184 | } 185 | 186 | float D_AnisotropyGGX(float ToH, float BoH, float NoH, float RoughnessT, float RoughnessB) { 187 | return Inv_Pi * D_AnisotropyGGX_NoPi(ToH, BoH, NoH, RoughnessT, RoughnessB); 188 | } 189 | 190 | float D_InvBlinn_NoPi(float NoH, float Roughness) 191 | { 192 | float Roughness4 = pow4(Roughness); 193 | float Cos2h = NoH * NoH; 194 | float Sin2h = 1 - Cos2h; 195 | return rcp(5 * Roughness4) * ( 5 * exp(-Cos2h / Roughness4) ); 196 | } 197 | 198 | float D_InvBlinn(float NoH, float Roughness) 199 | { 200 | return Inv_Pi * D_InvBlinn_NoPi(NoH, Roughness); 201 | } 202 | 203 | float D_InvBeckmann_NoPi(float NoH, float Roughness) 204 | { 205 | float Roughness4 = pow4(Roughness); 206 | float Cos2h = NoH * NoH; 207 | float Sin2h = 1 - Cos2h; 208 | float Sin4h = Sin2h * Sin2h; 209 | return rcp( (5 * Roughness4) * Sin4h ) * ( Sin4h + 4 * exp( -Cos2h / (Roughness4 * Sin2h) ) ); 210 | } 211 | 212 | float D_InvBeckmann(float NoH, float Roughness) 213 | { 214 | return Inv_Pi * D_InvBeckmann_NoPi(NoH, Roughness); 215 | } 216 | 217 | float D_Ashikhmin_NoPi(float NoH, float Roughness) { 218 | float a2 = pow4(Roughness); 219 | float d = (NoH - a2 * NoH) * NoH + a2; 220 | return rcp (1 + 4 * a2) * ( 1 + 4 * a2 * a2 / (d * d) ); 221 | } 222 | 223 | float D_Ashikhmin(float NoH, float Roughness) { 224 | return Inv_Pi * D_Ashikhmin_NoPi(NoH, Roughness); 225 | } 226 | 227 | float D_Charlie_NoPi(float NoH, float Roughness) 228 | { 229 | float invR = rcp(Roughness); 230 | float cos2h = pow2(NoH); 231 | float sin2h = 1 - cos2h; 232 | return (2 + invR) * pow(sin2h, invR * 0.5) / 2 ; 233 | } 234 | 235 | float D_Charlie(float NoH, float Roughness) 236 | { 237 | return Inv_Pi * D_Charlie_NoPi(NoH, Roughness); 238 | } 239 | 240 | 241 | 242 | /////////////////////////////////////////////////////////////////Specular V 243 | float Vis_Neumann(float NoL, float NoV) 244 | { 245 | return rcp( 4 * max(NoL, NoV) ); 246 | } 247 | 248 | float Vis_Kelemen(float VoH) 249 | { 250 | return rcp( 4 * VoH * VoH + 1e-5); 251 | } 252 | 253 | float Vis_Schlick(float NoL, float NoV, float Roughness) 254 | { 255 | float k = pow2(Roughness) * 0.5; 256 | float Vis_SchlickV = NoV / (NoV * (1 - k) + k); 257 | float Vis_SchlickL = NoL / (NoL * (1 - k) + k); 258 | return Vis_SchlickV * Vis_SchlickL; 259 | } 260 | 261 | float Vis_Smith(float NoL, float NoV, float Roughness) 262 | { 263 | float a2 = pow4(Roughness); 264 | float Vis_SmithV = NoV + sqrt( NoV * (NoV - NoV * a2) + a2 ); 265 | float Vis_SmithL = NoL + sqrt( NoL * (NoL - NoL * a2) + a2 ); 266 | return rcp(Vis_SmithV * Vis_SmithL); 267 | } 268 | 269 | float Vis_SmithJointApprox_NoPI(float NoL, float NoV, float Roughness) 270 | { 271 | float a = pow2(Roughness); 272 | float LambdaL = NoV * (NoL * (1 - a) + a); 273 | float LambdaV = NoL * (NoV * (1 - a) + a); 274 | return 0.5 / rcp(LambdaV + LambdaL); 275 | } 276 | 277 | float Vis_SmithJointApprox(float NoL, float NoV, float Roughness) 278 | { 279 | return Inv_Pi * Vis_SmithJointApprox_NoPI(NoL, NoV, Roughness); 280 | } 281 | 282 | float Vis_SmithJoint_NoPI(float NoL, float NoV, float Roughness) 283 | { 284 | float a2 = pow4(Roughness); 285 | float LambdaV = NoL * sqrt(NoV * (NoV - NoV * a2) + a2); 286 | float LambdaL = NoV * sqrt(NoL * (NoL - NoL * a2) + a2); 287 | return 0.5 / rcp(LambdaL + LambdaV); 288 | } 289 | 290 | float Vis_SmithJoint(float NoL, float NoV, float Roughness) 291 | { 292 | return Inv_Pi * Vis_SmithJoint_NoPI(NoL, NoV, Roughness); 293 | } 294 | 295 | float Vis_AnisotropyGGX_NoPi(float ToV, float BoV, float NoV, float ToL, float BoL, float NoL, float RoughnessT, float RoughnessB) 296 | { 297 | RoughnessT = pow2(RoughnessT); 298 | RoughnessB = pow2(RoughnessB); 299 | 300 | float LambdaV = NoL * sqrt(RoughnessT * pow2(ToV) + RoughnessB * pow2(BoV) + pow2(NoV)); 301 | float LambdaL = NoV * sqrt(RoughnessT * pow2(ToL) + RoughnessB * pow2(BoL) + pow2(NoL)); 302 | 303 | return 0.5 / rcp(LambdaV + LambdaL); 304 | } 305 | 306 | float Vis_AnisotropyGGX(float ToV, float BoV, float NoV, float ToL, float BoL, float NoL, float RoughnessT, float RoughnessB) 307 | { 308 | return Inv_Pi * Vis_AnisotropyGGX_NoPi(ToV, BoV, NoV, ToL, BoL, NoL, RoughnessT, RoughnessB); 309 | } 310 | 311 | float Vis_Ashikhmin(float NoL, float NoV) 312 | { 313 | return rcp(4 * (NoL + NoV - NoL * NoV)); 314 | } 315 | 316 | float Vis_Charlie(float NoL, float NoV, float Roughness) 317 | { 318 | float lambdaV = NoV < 0.5 ? exp(CharlieL(NoV, Roughness)) : exp(2 * CharlieL(0.5, Roughness) - CharlieL(1 - NoV, Roughness)); 319 | float lambdaL = NoL < 0.5 ? exp(CharlieL(NoL, Roughness)) : exp(2 * CharlieL(0.5, Roughness) - CharlieL(1 - NoL, Roughness)); 320 | 321 | return rcp( (1 + lambdaV + lambdaL) * (4 * NoV * NoL) ); 322 | } 323 | 324 | float Vis_Hair(float B, float Theta) { 325 | return exp(-0.5 * Square(Theta) / (B * B)) / (sqrt(2 * Pi) * B); 326 | } 327 | 328 | 329 | 330 | /////////////////////////////////////////////////////////////////Utillity 331 | float3 EvalSensitivity(float opd, float shift) { 332 | float phase = 2 * Pi * opd * 1e-6; 333 | float3 val = float3(5.4856e-13, 4.4201e-13, 5.2481e-13); 334 | float3 pos = float3(1.6810e+06, 1.7953e+06, 2.2084e+06); 335 | float3 var = float3(4.3278e+09, 9.3046e+09, 6.6121e+09); 336 | float3 xyz = val * sqrt(2 * Pi * var) * cos(pos * phase + shift) * exp(-var * phase * phase); 337 | xyz.x += 9.7470e-14 * sqrt(2 * Pi * 4.5282e+09) * cos(2.2399e+06 * phase + shift) * exp(-4.5282e+09 * phase * phase); 338 | return xyz / 1.0685e-7; 339 | } 340 | 341 | float3 Flim_Iridescence(float eta_1, float cosTheta1, float iridescenceThickness, float3 baseLayerFresnel0, float iorOverBaseLayer = 0) { 342 | float Dinc = 3 * iridescenceThickness; 343 | float eta_2 = lerp(2, 1, iridescenceThickness); 344 | float sinTheta2 = Square(eta_1 / eta_2) * (1 - Square(cosTheta1)); 345 | float cosTheta2 = sqrt(1 - sinTheta2); 346 | 347 | float R0 = IorToFresnel(eta_2, eta_1); 348 | float R12 = F_Schlick(R0, 1, cosTheta1); 349 | float R21 = R12; float T121 = 1 - R12; 350 | 351 | float OPD = Dinc * cosTheta2; 352 | float3 R23 = F_Schlick(baseLayerFresnel0, float3(1, 1, 1), cosTheta2); 353 | float3 R123 = R12 * R23; float3 r123 = sqrt(R123); 354 | float3 Rs = Square(T121) * R23 / (1 - R123); 355 | float3 C0 = R12 + Rs; 356 | float3 I = C0; 357 | float3 Cm = Rs - T121; 358 | 359 | [roll] 360 | for (int m = 1; m <= 2; m++) { 361 | Cm *= r123; 362 | float3 Sm = 2 * EvalSensitivity(m * OPD, m * Pi); 363 | I += Cm * Sm; 364 | } 365 | return I; 366 | } 367 | 368 | void RefractionSphere(float3 V, float3 positionWS, float3 normalWS, float ior, float thickness, out float dist, out float3 position, out float3 rayWS) { 369 | float3 R1 = refract(-V, normalWS, 1 / ior); 370 | float3 C = positionWS - normalWS * thickness * 0.5; 371 | 372 | float NoR1 = dot(normalWS, R1); 373 | float distance = -NoR1 * thickness; 374 | float3 P1 = positionWS + R1 * distance; 375 | float3 N1 = normalize(C - P1); 376 | float3 R2 = refract(R1, N1, ior); 377 | float N1oR2 = dot(N1, R2); 378 | float VoR1 = dot(V, R1); 379 | 380 | dist = distance; 381 | position = P1; 382 | rayWS = R2; 383 | } 384 | 385 | void RefractionPlane(float3 V, float3 positionWS, float3 normalWS, float ior, float thickness, out float dist, out float3 position, out float3 rayWS) { 386 | float3 R = refract(-V, normalWS, 1 / ior); 387 | float distance = thickness / dot(R, -normalWS); 388 | 389 | dist = distance; 390 | position = positionWS + R * dist; 391 | rayWS = -V; 392 | } 393 | 394 | float3 TransmissionBRDF_Wrap(float3 L, float3 N, float3 W) { 395 | return saturate( ( dot(L, N) + W ) / ( (1 + W) * (1 + W) ) ); 396 | } 397 | 398 | float3 TransmissionBRDF_UE4(float3 L, float3 V, float3 N, float3 H, float3 SSS_Color, float3 AO, float3 SSS_Thickness) { 399 | float3 InScatter = pow(saturate(dot(L, -V)), 12) * lerp(3, 0.1, SSS_Thickness); 400 | float3 NormalContribution = saturate(dot(N, H) * SSS_Thickness + 1 - SSS_Thickness); 401 | float3 BackScatter = AO * NormalContribution / (Pi * 2); 402 | return SSS_Color * lerp(BackScatter, 1, InScatter); 403 | } 404 | 405 | float3 TransmissionBRDF_Foliage(float3 SSS_Color, float3 L, float3 V, float3 N) 406 | { 407 | float Wrap = 0.5; 408 | float NoL = saturate((dot(-N, L) + Wrap) / Square(1 + Wrap)); 409 | 410 | float VoL = saturate(dot(V, -L)); 411 | float a = 0.6; 412 | float a2 = a * a; 413 | float d = ( VoL * a2 - VoL ) * VoL + 1; 414 | float GGX = (a2 / Pi) / (d * d); 415 | return NoL * GGX * SSS_Color; 416 | } 417 | 418 | float3 TransmissionBRDF_Frostbite(float3 L, float3 V, float3 N, float3 SSS_Color, float AO, float SSS_AmbientIntensity, float SSS_Distortion, float SSS_Power, float SSS_Scale, float SSS_Thickness) { 419 | float3 newLight = L + N * SSS_Distortion; 420 | float newNoL = pow(saturate(dot(V, -newLight)), SSS_Power) * SSS_Scale; 421 | float3 newAtten = (newNoL + (SSS_Color * SSS_AmbientIntensity)) * SSS_Thickness; 422 | return SSS_Color * newAtten * AO; 423 | } 424 | 425 | #endif -------------------------------------------------------------------------------- /Shaders/Private/Common.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef _BaseCommon_ 2 | #define _BaseCommon_ 3 | 4 | 5 | //#define float half 6 | //#define float2 half2 7 | //#define float3 half3 8 | //#define float4 half4 9 | //#define float3x3 half3x3 10 | //#define float4x4 half4x4 11 | //#define float4x3 half4x3 12 | #define Pi 3.1415926 13 | #define Inv_Pi 0.3183091 14 | #define Two_Pi 6.2831852 15 | #define Inv_Two_Pi 0.15915494 16 | 17 | SamplerState Global_point_clamp_sampler, Global_bilinear_clamp_sampler, Global_trilinear_clamp_sampler, Global_point_repeat_sampler, Global_bilinear_repeat_sampler, Global_trilinear_repeat_sampler; 18 | 19 | float Square(float x) 20 | { 21 | return x * x; 22 | } 23 | 24 | float2 Square(float2 x) 25 | { 26 | return x * x; 27 | } 28 | 29 | float3 Square(float3 x) 30 | { 31 | return x * x; 32 | } 33 | 34 | float4 Square(float4 x) 35 | { 36 | return x * x; 37 | } 38 | 39 | float pow2(float x) 40 | { 41 | return x * x; 42 | } 43 | 44 | float2 pow2(float2 x) 45 | { 46 | return x * x; 47 | } 48 | 49 | float3 pow2(float3 x) 50 | { 51 | return x * x; 52 | } 53 | 54 | float4 pow2(float4 x) 55 | { 56 | return x * x; 57 | } 58 | 59 | float pow3(float x) 60 | { 61 | return x * x * x; 62 | } 63 | 64 | float2 pow3(float2 x) 65 | { 66 | return x * x * x; 67 | } 68 | 69 | float3 pow3(float3 x) 70 | { 71 | return x * x * x; 72 | } 73 | 74 | float4 pow3(float4 x) 75 | { 76 | return x * x * x; 77 | } 78 | 79 | float pow4(float x) 80 | { 81 | float xx = x * x; 82 | return xx * xx; 83 | } 84 | 85 | float2 pow4(float2 x) 86 | { 87 | float2 xx = x * x; 88 | return xx * xx; 89 | } 90 | 91 | float3 pow4(float3 x) 92 | { 93 | float3 xx = x * x; 94 | return xx * xx; 95 | } 96 | 97 | float4 pow4(float4 x) 98 | { 99 | float4 xx = x * x; 100 | return xx * xx; 101 | } 102 | 103 | float pow5(float x) 104 | { 105 | float xx = x * x; 106 | return xx * xx * x; 107 | } 108 | 109 | float2 pow5(float2 x) 110 | { 111 | float2 xx = x * x; 112 | return xx * xx * x; 113 | } 114 | 115 | float3 pow5(float3 x) 116 | { 117 | float3 xx = x * x; 118 | return xx * xx * x; 119 | } 120 | 121 | float4 pow5(float4 x) 122 | { 123 | float4 xx = x * x; 124 | return xx * xx * x; 125 | } 126 | 127 | float pow6(float x) 128 | { 129 | float xx = x * x; 130 | return xx * xx * xx; 131 | } 132 | 133 | float2 pow6(float2 x) 134 | { 135 | float2 xx = x * x; 136 | return xx * xx * xx; 137 | } 138 | 139 | float3 pow6(float3 x) 140 | { 141 | float3 xx = x * x; 142 | return xx * xx * xx; 143 | } 144 | 145 | float4 pow6(float4 x) 146 | { 147 | float4 xx = x * x; 148 | return xx * xx * xx; 149 | } 150 | float min3(float a, float b, float c) 151 | { 152 | return min(min(a, b), c); 153 | } 154 | 155 | float max3(float a, float b, float c) 156 | { 157 | return max(a, max(b, c)); 158 | } 159 | 160 | float4 min3(float4 a, float4 b, float4 c) 161 | { 162 | return float4( 163 | min3(a.x, b.x, c.x), 164 | min3(a.y, b.y, c.y), 165 | min3(a.z, b.z, c.z), 166 | min3(a.w, b.w, c.w)); 167 | } 168 | 169 | float4 max3(float4 a, float4 b, float4 c) 170 | { 171 | return float4( 172 | max3(a.x, b.x, c.x), 173 | max3(a.y, b.y, c.y), 174 | max3(a.z, b.z, c.z), 175 | max3(a.w, b.w, c.w)); 176 | } 177 | 178 | float4 Texture1DSample(Texture1D Tex, SamplerState Sampler, float UV) 179 | { 180 | #if COMPUTESHADER 181 | return Tex.SampleLevel(Sampler, UV, 0); 182 | #else 183 | return Tex.Sample(Sampler, UV); 184 | #endif 185 | } 186 | 187 | float4 Texture2DSample(Texture2D Tex, SamplerState Sampler, float2 UV) 188 | { 189 | #if COMPUTESHADER 190 | return Tex.SampleLevel(Sampler, UV, 0);// 191 | #else 192 | return Tex.Sample(Sampler, UV); 193 | #endif 194 | } 195 | 196 | 197 | float4 Texture3DSample(Texture3D Tex, SamplerState Sampler, float3 UV) 198 | { 199 | #if COMPUTESHADER 200 | return Tex.SampleLevel(Sampler, UV, 0); 201 | #else 202 | return Tex.Sample(Sampler, UV); 203 | #endif 204 | } 205 | 206 | 207 | float4 TextureCubeSample(TextureCube Tex, SamplerState Sampler, float3 UV) 208 | { 209 | #if COMPUTESHADER 210 | return Tex.SampleLevel(Sampler, UV, 0); 211 | #else 212 | return Tex.Sample(Sampler, UV); 213 | #endif 214 | } 215 | 216 | 217 | float4 Texture1DSampleLevel(Texture1D Tex, SamplerState Sampler, float UV, float Mip) 218 | { 219 | return Tex.SampleLevel(Sampler, UV, Mip); 220 | } 221 | 222 | 223 | float4 Texture2DSampleLevel(Texture2D Tex, SamplerState Sampler, float2 UV, float Mip) 224 | { 225 | return Tex.SampleLevel(Sampler, UV, Mip); 226 | } 227 | 228 | 229 | float4 Texture2DSampleBias(Texture2D Tex, SamplerState Sampler, float2 UV, float MipBias) 230 | { 231 | #if COMPUTESHADER 232 | return Tex.SampleLevel(Sampler, UV, 0); 233 | #else 234 | return Tex.SampleBias(Sampler, UV, MipBias); 235 | #endif 236 | } 237 | 238 | 239 | float4 Texture2DSampleGrad(Texture2D Tex, SamplerState Sampler, float2 UV, float2 DDX, float2 DDY) 240 | { 241 | return Tex.SampleGrad(Sampler, UV, DDX, DDY); 242 | } 243 | 244 | 245 | float4 Texture3DSampleLevel(Texture3D Tex, SamplerState Sampler, float3 UV, float Mip) 246 | { 247 | return Tex.SampleLevel(Sampler, UV, Mip); 248 | } 249 | 250 | 251 | float4 Texture3DSampleBias(Texture3D Tex, SamplerState Sampler, float3 UV, float MipBias) 252 | { 253 | #if COMPUTESHADER 254 | return Tex.SampleBias(Sampler, UV, 0); 255 | #else 256 | return Tex.SampleBias(Sampler, UV, MipBias); 257 | #endif 258 | } 259 | 260 | 261 | float4 Texture3DSampleGrad(Texture3D Tex, SamplerState Sampler, float3 UV, float3 DDX, float3 DDY) 262 | { 263 | return Tex.SampleGrad(Sampler, UV, DDX, DDY); 264 | } 265 | 266 | 267 | float4 TextureCubeSampleLevel(TextureCube Tex, SamplerState Sampler, float3 UV, float Mip) 268 | { 269 | return Tex.SampleLevel(Sampler, UV, Mip); 270 | } 271 | 272 | 273 | float TextureCubeSampleDepthLevel(TextureCube TexDepth, SamplerState Sampler, float3 UV, float Mip) 274 | { 275 | return TexDepth.SampleLevel(Sampler, UV, Mip).x; 276 | } 277 | 278 | 279 | float4 TextureCubeSampleBias(TextureCube Tex, SamplerState Sampler, float3 UV, float MipBias) 280 | { 281 | #if COMPUTESHADER 282 | return Tex.SampleLevel(Sampler, UV, 0); 283 | #else 284 | return Tex.SampleBias(Sampler, UV, MipBias); 285 | #endif 286 | } 287 | 288 | 289 | float4 TextureCubeSampleGrad(TextureCube Tex, SamplerState Sampler, float3 UV, float3 DDX, float3 DDY) 290 | { 291 | return Tex.SampleGrad(Sampler, UV, DDX, DDY); 292 | } 293 | 294 | /////////////////BicubicSampler 295 | void Bicubic2DCatmullRom(in float2 UV, in float2 Size, in float2 InvSize, out float2 Sample[3], out float2 Weight[3]) 296 | { 297 | UV *= Size; 298 | 299 | float2 tc = floor(UV - 0.5) + 0.5; 300 | float2 f = UV - tc; 301 | float2 f2 = f * f; 302 | float2 f3 = f2 * f; 303 | 304 | float2 w0 = f2 - 0.5 * (f3 + f); 305 | float2 w1 = 1.5 * f3 - 2.5 * f2 + 1; 306 | float2 w3 = 0.5 * (f3 - f2); 307 | float2 w2 = 1 - w0 - w1 - w3; 308 | 309 | Weight[0] = w0; 310 | Weight[1] = w1 + w2; 311 | Weight[2] = w3; 312 | 313 | Sample[0] = tc - 1; 314 | Sample[1] = tc + w2 / Weight[1]; 315 | Sample[2] = tc + 2; 316 | 317 | Sample[0] *= InvSize; 318 | Sample[1] *= InvSize; 319 | Sample[2] *= InvSize; 320 | } 321 | 322 | #define BICUBIC_CATMULL_ROM_SAMPLES 5 323 | 324 | struct FCatmullRomSamples 325 | { 326 | // Constant number of samples (BICUBIC_CATMULL_ROM_SAMPLES) 327 | uint Count; 328 | 329 | // Constant sign of the UV direction from master UV sampling location. 330 | int2 UVDir[BICUBIC_CATMULL_ROM_SAMPLES]; 331 | 332 | // Bilinear sampling UV coordinates of the samples 333 | float2 UV[BICUBIC_CATMULL_ROM_SAMPLES]; 334 | 335 | // Weights of the samples 336 | float Weight[BICUBIC_CATMULL_ROM_SAMPLES]; 337 | 338 | // Final multiplier (it is faster to multiply 3 RGB values than reweights the 5 weights) 339 | float FinalMultiplier; 340 | }; 341 | 342 | FCatmullRomSamples GetBicubic2DCatmullRomSamples(float2 UV, float2 Size, in float2 InvSize) 343 | { 344 | FCatmullRomSamples Samples; 345 | Samples.Count = BICUBIC_CATMULL_ROM_SAMPLES; 346 | 347 | float2 Weight[3]; 348 | float2 Sample[3]; 349 | Bicubic2DCatmullRom(UV, Size, InvSize, Sample, Weight); 350 | 351 | // Optimized by removing corner samples 352 | Samples.UV[0] = float2(Sample[1].x, Sample[0].y); 353 | Samples.UV[1] = float2(Sample[0].x, Sample[1].y); 354 | Samples.UV[2] = float2(Sample[1].x, Sample[1].y); 355 | Samples.UV[3] = float2(Sample[2].x, Sample[1].y); 356 | Samples.UV[4] = float2(Sample[1].x, Sample[2].y); 357 | 358 | Samples.Weight[0] = Weight[1].x * Weight[0].y; 359 | Samples.Weight[1] = Weight[0].x * Weight[1].y; 360 | Samples.Weight[2] = Weight[1].x * Weight[1].y; 361 | Samples.Weight[3] = Weight[2].x * Weight[1].y; 362 | Samples.Weight[4] = Weight[1].x * Weight[2].y; 363 | 364 | Samples.UVDir[0] = int2(0, -1); 365 | Samples.UVDir[1] = int2(-1, 0); 366 | Samples.UVDir[2] = int2(0, 0); 367 | Samples.UVDir[3] = int2(1, 0); 368 | Samples.UVDir[4] = int2(0, 1); 369 | 370 | // Reweight after removing the corners 371 | float CornerWeights; 372 | CornerWeights = Samples.Weight[0]; 373 | CornerWeights += Samples.Weight[1]; 374 | CornerWeights += Samples.Weight[2]; 375 | CornerWeights += Samples.Weight[3]; 376 | CornerWeights += Samples.Weight[4]; 377 | Samples.FinalMultiplier = 1 / CornerWeights; 378 | 379 | return Samples; 380 | } 381 | 382 | float4 Texture2DSampleBicubic(Texture2D Tex, SamplerState Sampler, float2 UV, float2 Size, in float2 InvSize) 383 | { 384 | FCatmullRomSamples Samples = GetBicubic2DCatmullRomSamples(UV, Size, InvSize); 385 | 386 | float4 OutColor = 0; 387 | for (uint i = 0; i < Samples.Count; i++) 388 | { 389 | OutColor += Tex.SampleLevel(Sampler, Samples.UV[i], 0) * Samples.Weight[i]; 390 | } 391 | OutColor *= Samples.FinalMultiplier; 392 | 393 | return OutColor; 394 | } 395 | 396 | //converts an input 1d to 2d position. Useful for locating z frames that have been laid out in a 2d grid like a flipbook. 397 | float2 Tile1Dto2D(float xsize, float idx) 398 | { 399 | float2 xyidx = 0; 400 | xyidx.y = floor(idx / xsize); 401 | xyidx.x = idx - xsize * xyidx.y; 402 | 403 | return xyidx; 404 | } 405 | 406 | float4 PseudoVolumeTexture(Texture2D Tex, SamplerState TexSampler, float3 inPos, float2 xysize, float numframes, 407 | uint mipmode = 0, float miplevel = 0, float2 InDDX = 0, float2 InDDY = 0) 408 | { 409 | float zframe = ceil(inPos.z * numframes); 410 | float zphase = frac(inPos.z * numframes); 411 | 412 | float2 uv = frac(inPos.xy) / xysize; 413 | 414 | float2 curframe = Tile1Dto2D(xysize.x, zframe) / xysize; 415 | float2 nextframe = Tile1Dto2D(xysize.x, zframe + 1) / xysize; 416 | 417 | float4 sampleA = 0, sampleB = 0; 418 | switch (mipmode) 419 | { 420 | case 0: // Mip level 421 | sampleA = Tex.SampleLevel(TexSampler, uv + curframe, miplevel); 422 | sampleB = Tex.SampleLevel(TexSampler, uv + nextframe, miplevel); 423 | break; 424 | case 1: // Gradients automatic from UV 425 | sampleA = Texture2DSample(Tex, TexSampler, uv + curframe); 426 | sampleB = Texture2DSample(Tex, TexSampler, uv + nextframe); 427 | break; 428 | case 2: // Deriviatives provided 429 | sampleA = Tex.SampleGrad(TexSampler, uv + curframe, InDDX, InDDY); 430 | sampleB = Tex.SampleGrad(TexSampler, uv + nextframe, InDDX, InDDY); 431 | break; 432 | default: 433 | break; 434 | } 435 | 436 | return lerp(sampleA, sampleB, zphase); 437 | } 438 | 439 | float Luma4(float3 Color) 440 | { 441 | return (Color.g * 2) + (Color.r + Color.b); 442 | } 443 | 444 | float CLuminance(float3 rgb) 445 | { 446 | return dot( rgb, float3(0.0396819152, 0.458021790, 0.00609653955) ); 447 | } 448 | 449 | float HdrWeight4(float3 Color, float Exposure) 450 | { 451 | return rcp(Luma4(Color) * Exposure + 4); 452 | } 453 | 454 | float HdrWeightY(float Color, float Exposure) 455 | { 456 | return rcp(Color * Exposure + 4); 457 | } 458 | 459 | /*float3 RGBToYCoCg(float3 RGB) 460 | { 461 | float Y = dot(RGB, float3(1, 2, 1)); 462 | float Co = dot(RGB, float3(2, 0, -2)); 463 | float Cg = dot(RGB, float3(-1, 2, -1)); 464 | 465 | float3 YCoCg = float3(Y, Co, Cg); 466 | return YCoCg; 467 | } 468 | 469 | float3 YCoCgToRGB(float3 YCoCg) 470 | { 471 | float Y = YCoCg.x * 0.25; 472 | float Co = YCoCg.y * 0.25; 473 | float Cg = YCoCg.z * 0.25; 474 | 475 | float R = Y + Co - Cg; 476 | float G = Y + Cg; 477 | float B = Y - Co - Cg; 478 | 479 | return float3(R, G, B); 480 | }*/ 481 | 482 | float3 RGBToYCbCr(float3 RGB) { 483 | float Y = (0.299 * RGB.r) + (0.587 * RGB.g) + (0.114 * RGB.b); 484 | float Cb = (RGB.b - Y) * 0.565; 485 | float Cr = (RGB.r - Y) * 0.713; 486 | 487 | return float3(Y, Cb, Cr); 488 | } 489 | 490 | float3 YCbCrToRGB(float3 YCbCr) { 491 | float R = YCbCr.x + (1.403 * YCbCr.z); 492 | float G = YCbCr.x - (0.344 * YCbCr.y) - (0.714 * YCbCr.z); 493 | float B = YCbCr.x + (1.770 * YCbCr.y); 494 | 495 | return float3(R, G, B); 496 | } 497 | 498 | float acosFast(float inX) 499 | { 500 | float x = abs(inX); 501 | float res = -0.156583f * x + (0.5 * Pi); 502 | res *= sqrt(1 - x); 503 | return (inX >= 0) ? res : Pi - res; 504 | } 505 | 506 | float asinFast(float x) 507 | { 508 | return (0.5 * Pi) - acosFast(x); 509 | } 510 | 511 | float ClampedPow(float X, float Y) 512 | { 513 | return pow(max(abs(X), 0.000001), Y); 514 | } 515 | 516 | float CharlieL(float x, float r) 517 | { 518 | r = saturate(r); 519 | r = 1 - (1 - r) * (1 - r); 520 | 521 | float a = lerp(25.3245, 21.5473, r); 522 | float b = lerp(3.32435, 3.82987, r); 523 | float c = lerp(0.16801, 0.19823, r); 524 | float d = lerp(-1.27393, -1.97760, r); 525 | float e = lerp(-4.85967, -4.32054, r); 526 | 527 | return a / (1 + b * pow(x, c)) + d * x + e; 528 | } 529 | 530 | void ConvertAnisotropyToRoughness(float Roughness, float Anisotropy, out float RoughnessT, out float RoughnessB) { 531 | Roughness *= Roughness; 532 | float AnisoAspect = sqrt(1 - 0.9 * Anisotropy); 533 | RoughnessT = Roughness / AnisoAspect; 534 | RoughnessB = Roughness * AnisoAspect; 535 | } 536 | 537 | float3 ComputeGrainNormal(float3 grainDir, float3 V) { 538 | float3 B = cross(-V, grainDir); 539 | return cross(B, grainDir); 540 | } 541 | 542 | float3 GetAnisotropicModifiedNormal(float3 grainDir, float3 N, float3 V, float Anisotropy) { 543 | float3 grainNormal = ComputeGrainNormal(grainDir, V); 544 | return normalize(lerp(N, grainNormal, Anisotropy)); 545 | } 546 | 547 | float3 GetViewSpaceNormal(float3 normal, float4x4 _WToCMatrix) 548 | { 549 | const float3 viewNormal = mul((float3x3)_WToCMatrix, normal.rgb); 550 | return normalize(viewNormal); 551 | } 552 | 553 | float3 GetNDCPos(float2 uv, float depth) 554 | { 555 | return float3(uv * 2 - 1, depth); 556 | } 557 | 558 | float3 GetWorldSpacePos(float3 NDCPos, float4x4 Matrix_InvViewProj) 559 | { 560 | float4 worldPos = mul( Matrix_InvViewProj, float4(NDCPos, 1) ); 561 | return worldPos.xyz / worldPos.w; 562 | } 563 | 564 | float3 GetViewSpacePos(float3 NDCPos, float4x4 Matrix_InvProj) 565 | { 566 | float4 viewPos = mul(Matrix_InvProj, float4(NDCPos, 1)); 567 | return viewPos.xyz / viewPos.w; 568 | } 569 | 570 | float3 GetViewDir(float3 worldPos, float3 ViewPos) 571 | { 572 | return normalize(worldPos - ViewPos); 573 | } 574 | 575 | float2 GetMotionVector(float SceneDepth, float2 inUV, float4x4 Matrix_InvViewProj, float4x4 Matrix_LastViewProj, float4x4 Matrix_ViewProj) 576 | { 577 | float3 NDCPos = GetNDCPos(inUV, SceneDepth); 578 | float4 worldPos = float4(GetWorldSpacePos(NDCPos, Matrix_InvViewProj), 1); 579 | 580 | float4 LastClipPos = mul(Matrix_LastViewProj, worldPos); 581 | float4 CurClipPos = mul(Matrix_ViewProj, worldPos); 582 | 583 | float2 LastNDC = LastClipPos.xy / LastClipPos.w; 584 | float2 CurNDC = CurClipPos.xy / CurClipPos.w; 585 | 586 | float2 LastUV = LastNDC.xy * 0.5 + 0.5; 587 | float2 CurUV = CurNDC.xy * 0.5 + 0.5; 588 | return CurUV - LastUV; 589 | } 590 | 591 | #endif 592 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /Shaders/Private/Random.hlsl: -------------------------------------------------------------------------------- 1 | #ifndef _Random_ush_ 2 | #define _Random_ush_ 3 | 4 | inline int2 ihash(int2 n) 5 | { 6 | n = (n << 13) ^ n; 7 | return (n*(n*n * 15731 + 789221) + 1376312589) & 2147483647; 8 | } 9 | 10 | inline int3 ihash(int3 n) 11 | { 12 | n = (n << 13) ^ n; 13 | return (n*(n*n * 15731 + 789221) + 1376312589) & 2147483647; 14 | } 15 | 16 | inline float2 frand(int2 n) 17 | { 18 | return ihash(n) / 2147483647.0; 19 | } 20 | 21 | inline float3 frand(int3 n) 22 | { 23 | return ihash(n) / 2147483647.0; 24 | } 25 | 26 | inline float2 cellNoise(float2 p, float4 RandomNumber) 27 | { 28 | int seed = dot(p, float2(641338.4168541, 963955.16871685)); 29 | return sin(float2(frand(int2(seed, seed - 53))) * RandomNumber.xy + RandomNumber.zw); 30 | } 31 | 32 | inline float3 cellNoise(float3 p, float4 RandomNumber) 33 | { 34 | int seed = dot(p, float3(641738.4168541, 9646285.16871685, 3186964.168734)); 35 | return sin(float3(frand(int3(seed, seed - 12, seed - 57))) * RandomNumber.xyz + RandomNumber.w); 36 | } 37 | 38 | float PseudoRandom(float2 xy) 39 | { 40 | float2 pos = frac(xy / 128.0f) * 128.0f + float2(-64.340622f, -72.465622f); 41 | return frac(dot(pos.xyx * pos.xyy, float3(20.390625f, 60.703125f, 2.4281209f))); 42 | } 43 | 44 | float InterleavedGradientNoise( float2 uv, float FrameId ) 45 | { 46 | uv += FrameId * (float2(47, 17) * 0.695f); 47 | const float3 magic = float3( 0.06711056f, 0.00583715f, 52.9829189f ); 48 | return frac(magic.z * frac(dot(uv, magic.xy))); 49 | } 50 | 51 | float RandFast( uint2 PixelPos, float Magic = 3571.0 ) 52 | { 53 | float2 Random2 = ( 1.0 / 4320.0 ) * PixelPos + float2( 0.25, 0.0 ); 54 | float Random = frac( dot( Random2 * Random2, Magic ) ); 55 | Random = frac( Random * Random * (2 * Magic) ); 56 | return Random; 57 | } 58 | 59 | #define BBS_PRIME24 4093 60 | 61 | // Blum-Blum-Shub-inspired pseudo random number generator 62 | // http://www.umbc.edu/~olano/papers/mNoise.pdf 63 | // real BBS uses ((s*s) mod M) with bignums and M as the product of two huge Blum primes 64 | // instead, we use a single prime M just small enough not to overflow 65 | // note that the above paper used 61, which fits in a half, but is unusably bad 66 | // @param Integer valued floating point seed 67 | // @return random number in range [0,1) 68 | // ~8 ALU operations (5 *, 3 frac) 69 | float RandBBSfloat(float seed) 70 | { 71 | float s = frac(seed / BBS_PRIME24); 72 | s = frac(s * s * BBS_PRIME24); 73 | s = frac(s * s * BBS_PRIME24); 74 | return s; 75 | } 76 | 77 | // 3D random number generator inspired by PCGs (permuted congruential generator) 78 | // Using a **simple** Feistel cipher in place of the usual xor shift permutation step 79 | // @param v = 3D integer coordinate 80 | // @return three elements w/ 16 random bits each (0-0xffff). 81 | // ~8 ALU operations for result.x (7 mad, 1 >>) 82 | // ~10 ALU operations for result.xy (8 mad, 2 >>) 83 | // ~12 ALU operations for result.xyz (9 mad, 3 >>) 84 | uint3 Rand3DPCG16(int3 p) 85 | { 86 | // taking a signed int then reinterpreting as unsigned gives good behavior for negatives 87 | uint3 v = uint3(p); 88 | 89 | // Linear congruential step. These LCG constants are from Numerical Recipies 90 | // For additional #'s, PCG would do multiple LCG steps and scramble each on output 91 | // So v here is the RNG state 92 | v = v * 1664525u + 1013904223u; 93 | 94 | // PCG uses xorshift for the final shuffle, but it is expensive (and cheap 95 | // versions of xorshift have visible artifacts). Instead, use simple MAD Feistel steps 96 | // 97 | // Feistel ciphers divide the state into separate parts (usually by bits) 98 | // then apply a series of permutation steps one part at a time. The permutations 99 | // use a reversible operation (usually ^) to part being updated with the result of 100 | // a permutation function on the other parts and the key. 101 | // 102 | // In this case, I'm using v.x, v.y and v.z as the parts, using + instead of ^ for 103 | // the combination function, and just multiplying the other two parts (no key) for 104 | // the permutation function. 105 | // 106 | // That gives a simple mad per round. 107 | v.x += v.y*v.z; 108 | v.y += v.z*v.x; 109 | v.z += v.x*v.y; 110 | v.x += v.y*v.z; 111 | v.y += v.z*v.x; 112 | v.z += v.x*v.y; 113 | 114 | // only top 16 bits are well shuffled 115 | return v >> 16u; 116 | } 117 | 118 | // 3D random number generator inspired by PCGs (permuted congruential generator) 119 | // Using a **simple** Feistel cipher in place of the usual xor shift permutation step 120 | // @param v = 3D integer coordinate 121 | // @return three elements w/ 32 random bits each (0-0xffffffff). 122 | // ~12 ALU operations for result.x (10 mad, 3 >>) 123 | // ~14 ALU operations for result.xy (11 mad, 3 >>) 124 | // ~15 ALU operations for result.xyz (12 mad, 3 >>) 125 | uint3 Rand3DPCG32(int3 p) 126 | { 127 | // taking a signed int then reinterpreting as unsigned gives good behavior for negatives 128 | uint3 v = uint3(p); 129 | 130 | // Linear congruential step. 131 | v = v * 1664525u + 1013904223u; 132 | 133 | // swapping low and high bits makes all 32 bits pretty good 134 | v = v * (1u << 16u) + (v >> 16u); 135 | 136 | // final shuffle 137 | v.x += v.y*v.z; 138 | v.y += v.z*v.x; 139 | v.z += v.x*v.y; 140 | v.x += v.y*v.z; 141 | v.y += v.z*v.x; 142 | v.z += v.x*v.y; 143 | 144 | return v; 145 | } 146 | 147 | 148 | 149 | // 4D random number generator inspired by PCGs (permuted congruential generator) 150 | // Using a **simple** Feistel cipher in place of the usual xor shift permutation step 151 | // @param v = 4D integer coordinate 152 | // @return four elements w/ 32 random bits each (0-0xffffffff). 153 | // ~12 ALU operations for result.x (10 mad, 3 >>) 154 | // ~14 ALU operations for result.xy (11 mad, 3 >>) 155 | // ~15 ALU operations for result.xyz (12 mad, 3 >>) 156 | uint4 Rand4DPCG32(int4 p) 157 | { 158 | // taking a signed int then reinterpreting as unsigned gives good behavior for negatives 159 | uint4 v = uint4(p); 160 | 161 | // Linear congruential step. 162 | v = v * 1664525u + 1013904223u; 163 | 164 | // swapping low and high bits makes all 32 bits pretty good 165 | v = v * (1u << 16u) + (v >> 16u); 166 | 167 | // final shuffle 168 | v.x += v.y*v.w; 169 | v.y += v.z*v.x; 170 | v.z += v.x*v.y; 171 | v.w += v.y*v.z; 172 | v.x += v.y*v.w; 173 | v.y += v.z*v.x; 174 | v.z += v.x*v.y; 175 | v.w += v.y*v.z; 176 | 177 | return v; 178 | } 179 | 180 | 181 | 182 | 183 | /** 184 | * Find good arbitrary axis vectors to represent U and V axes of a plane, 185 | * given just the normal. Ported from UnMath.h 186 | */ 187 | void FindBestAxisVectors(float3 In, out float3 Axis1, out float3 Axis2 ) 188 | { 189 | const float3 N = abs(In); 190 | 191 | // Find best basis vectors. 192 | if( N.z > N.x && N.z > N.y ) 193 | { 194 | Axis1 = float3(1, 0, 0); 195 | } 196 | else 197 | { 198 | Axis1 = float3(0, 0, 1); 199 | } 200 | 201 | Axis1 = normalize(Axis1 - In * dot(Axis1, In)); 202 | Axis2 = cross(Axis1, In); 203 | } 204 | 205 | // References for noise: 206 | // 207 | // Improved Perlin noise 208 | // http://mrl.nyu.edu/~perlin/noise/ 209 | // http://http.developer.nvidia.com/GPUGems/gpugems_ch05.html 210 | // Modified Noise for Evaluation on Graphics Hardware 211 | // http://www.csee.umbc.edu/~olano/papers/mNoise.pdf 212 | // Perlin Noise 213 | // http://mrl.nyu.edu/~perlin/doc/oscar.html 214 | // Fast Gradient Noise 215 | // http://prettyprocs.wordpress.com/2012/10/20/fast-perlin-noise 216 | 217 | 218 | // -------- ALU based method --------- 219 | 220 | /* 221 | * Pseudo random number generator, based on "TEA, a tiny Encrytion Algorithm" 222 | * http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.45.281&rep=rep1&type=pdf 223 | * http://www.umbc.edu/~olano/papers/index.html#GPUTEA 224 | * @param v - old seed (full 32bit range) 225 | * @param IterationCount - >=1, bigger numbers cost more performance but improve quality 226 | * @return new seed 227 | */ 228 | uint2 ScrambleTEA(uint2 v, uint IterationCount = 3) 229 | { 230 | // Start with some random data (numbers can be arbitrary but those have been used by others and seem to work well) 231 | uint k[4] ={ 0xA341316Cu , 0xC8013EA4u , 0xAD90777Du , 0x7E95761Eu }; 232 | 233 | uint y = v[0]; 234 | uint z = v[1]; 235 | uint sum = 0; 236 | 237 | [ROOL] 238 | for(uint i = 0; i < IterationCount; ++i) 239 | { 240 | sum += 0x9e3779b9; 241 | y += ((z << 4u) + k[0]) ^ (z + sum) ^ ((z >> 5u) + k[1]); 242 | z += ((y << 4u) + k[2]) ^ (y + sum) ^ ((y >> 5u) + k[3]); 243 | } 244 | 245 | return uint2(y, z); 246 | } 247 | 248 | // Wraps noise for tiling texture creation 249 | // @param v = unwrapped texture parameter 250 | // @param bTiling = true to tile, false to not tile 251 | // @param RepeatSize = number of units before repeating 252 | // @return either original or wrapped coord 253 | float3 NoiseTileWrap(float3 v, bool bTiling, float RepeatSize) 254 | { 255 | return bTiling ? (frac(v / RepeatSize) * RepeatSize) : v; 256 | } 257 | 258 | // Evaluate polynomial to get smooth transitions for Perlin noise 259 | // only needed by Perlin functions in this file 260 | // scalar(per component): 2 add, 5 mul 261 | float4 PerlinRamp(float4 t) 262 | { 263 | return t * t * t * (t * (t * 6 - 15) + 10); 264 | } 265 | 266 | // Analytical derivative of the PerlinRamp polynomial 267 | // only needed by Perlin functions in this file 268 | // scalar(per component): 2 add, 5 mul 269 | float4 PerlinRampDerivative(float4 t) 270 | { 271 | return t * t * (t * (t * 30 - 60) + 30); 272 | } 273 | 274 | #define MGradientMask int3(0x8000, 0x4000, 0x2000) 275 | #define MGradientScale float3(1. / 0x4000, 1. / 0x2000, 1. / 0x1000) 276 | // Modified noise gradient term 277 | // @param seed - random seed for integer lattice position 278 | // @param offset - [-1,1] offset of evaluation point from lattice point 279 | // @return gradient direction (xyz) and contribution (w) from this lattice point 280 | float4 MGradient(int seed, float3 offset) 281 | { 282 | uint rand = Rand3DPCG16(int3(seed,0,0)).x; 283 | float3 direction = float3(rand.xxx & MGradientMask) * MGradientScale - 1; 284 | return float4(direction, dot(direction, offset)); 285 | } 286 | 287 | // compute Perlin and related noise corner seed values 288 | // @param v = 3D noise argument, use float3(x,y,0) for 2D or float3(x,0,0) for 1D 289 | // @param bTiling = true to return seed values for a repeating noise pattern 290 | // @param RepeatSize = integer units before tiling in each dimension 291 | // @param seed000-seed111 = hash function seeds for the eight corners 292 | // @return fractional part of v 293 | float3 NoiseSeeds(float3 v, bool bTiling, float RepeatSize, 294 | out float seed000, out float seed001, out float seed010, out float seed011, 295 | out float seed100, out float seed101, out float seed110, out float seed111) 296 | { 297 | float3 fv = frac(v); 298 | float3 iv = floor(v); 299 | 300 | const float3 primes = float3(19, 47, 101); 301 | 302 | if (bTiling) 303 | { // can't algebraically combine with primes 304 | seed000 = dot(primes, NoiseTileWrap(iv, true, RepeatSize)); 305 | seed100 = dot(primes, NoiseTileWrap(iv + float3(1, 0, 0), true, RepeatSize)); 306 | seed010 = dot(primes, NoiseTileWrap(iv + float3(0, 1, 0), true, RepeatSize)); 307 | seed110 = dot(primes, NoiseTileWrap(iv + float3(1, 1, 0), true, RepeatSize)); 308 | seed001 = dot(primes, NoiseTileWrap(iv + float3(0, 0, 1), true, RepeatSize)); 309 | seed101 = dot(primes, NoiseTileWrap(iv + float3(1, 0, 1), true, RepeatSize)); 310 | seed011 = dot(primes, NoiseTileWrap(iv + float3(0, 1, 1), true, RepeatSize)); 311 | seed111 = dot(primes, NoiseTileWrap(iv + float3(1, 1, 1), true, RepeatSize)); 312 | } 313 | else 314 | { // get to combine offsets with multiplication by primes in this case 315 | seed000 = dot(iv, primes); 316 | seed100 = seed000 + primes.x; 317 | seed010 = seed000 + primes.y; 318 | seed110 = seed100 + primes.y; 319 | seed001 = seed000 + primes.z; 320 | seed101 = seed100 + primes.z; 321 | seed011 = seed010 + primes.z; 322 | seed111 = seed110 + primes.z; 323 | } 324 | 325 | return fv; 326 | } 327 | 328 | // Perlin-style "Modified Noise" 329 | // http://www.umbc.edu/~olano/papers/index.html#mNoise 330 | // @param v = 3D noise argument, use float3(x,y,0) for 2D or float3(x,0,0) for 1D 331 | // @param bTiling = repeat noise pattern 332 | // @param RepeatSize = integer units before tiling in each dimension 333 | // @return random number in the range -1 .. 1 334 | float GradientNoise3D_ALU(float3 v, bool bTiling, float RepeatSize) 335 | { 336 | float seed000, seed001, seed010, seed011, seed100, seed101, seed110, seed111; 337 | float3 fv = NoiseSeeds(v, bTiling, RepeatSize, seed000, seed001, seed010, seed011, seed100, seed101, seed110, seed111); 338 | 339 | float rand000 = MGradient(int(seed000), fv - float3(0, 0, 0)).w; 340 | float rand100 = MGradient(int(seed100), fv - float3(1, 0, 0)).w; 341 | float rand010 = MGradient(int(seed010), fv - float3(0, 1, 0)).w; 342 | float rand110 = MGradient(int(seed110), fv - float3(1, 1, 0)).w; 343 | float rand001 = MGradient(int(seed001), fv - float3(0, 0, 1)).w; 344 | float rand101 = MGradient(int(seed101), fv - float3(1, 0, 1)).w; 345 | float rand011 = MGradient(int(seed011), fv - float3(0, 1, 1)).w; 346 | float rand111 = MGradient(int(seed111), fv - float3(1, 1, 1)).w; 347 | 348 | float3 Weights = PerlinRamp(float4(fv, 0)).xyz; 349 | 350 | float i = lerp(lerp(rand000, rand100, Weights.x), lerp(rand010, rand110, Weights.x), Weights.y); 351 | float j = lerp(lerp(rand001, rand101, Weights.x), lerp(rand011, rand111, Weights.x), Weights.y); 352 | return lerp(i, j, Weights.z).x; 353 | } 354 | 355 | // Coordinates for corners of a Simplex tetrahedron 356 | // Based on McEwan et al., Efficient computation of noise in GLSL, JGT 2011 357 | // @param v = 3D noise argument 358 | // @return 4 corner locations 359 | float4x3 SimplexCorners(float3 v) 360 | { 361 | // find base corner by skewing to tetrahedral space and back 362 | float3 tet = floor(v + v.x/3 + v.y/3 + v.z/3); 363 | float3 base = tet - tet.x/6 - tet.y/6 - tet.z/6; 364 | float3 f = v - base; 365 | 366 | // Find offsets to other corners (McEwan did this in tetrahedral space, 367 | // but since skew is along x=y=z axis, this works in Euclidean space too.) 368 | float3 g = step(f.yzx, f.xyz), h = 1 - g.zxy; 369 | float3 a1 = min(g, h) - 1. / 6., a2 = max(g, h) - 1. / 3.; 370 | 371 | // four corners 372 | return float4x3(base, base + a1, base + a2, base + 0.5); 373 | } 374 | 375 | // Improved smoothing function for simplex noise 376 | // @param f = fractional distance to four tetrahedral corners 377 | // @return weight for each corner 378 | float4 SimplexSmooth(float4x3 f) 379 | { 380 | const float scale = 1024. / 375.; // scale factor to make noise -1..1 381 | float4 d = float4(dot(f[0], f[0]), dot(f[1], f[1]), dot(f[2], f[2]), dot(f[3], f[3])); 382 | float4 s = saturate(2 * d); 383 | return (1 * scale + s*(-3 * scale + s*(3 * scale - s*scale))); 384 | } 385 | 386 | // Derivative of simplex noise smoothing function 387 | // @param f = fractional distanc eto four tetrahedral corners 388 | // @return derivative of smoothing function for each corner by x, y and z 389 | float3x4 SimplexDSmooth(float4x3 f) 390 | { 391 | const float scale = 1024. / 375.; // scale factor to make noise -1..1 392 | float4 d = float4(dot(f[0], f[0]), dot(f[1], f[1]), dot(f[2], f[2]), dot(f[3], f[3])); 393 | float4 s = saturate(2 * d); 394 | s = -12 * scale + s*(24 * scale - s * 12 * scale); 395 | 396 | return float3x4( 397 | s * float4(f[0][0], f[1][0], f[2][0], f[3][0]), 398 | s * float4(f[0][1], f[1][1], f[2][1], f[3][1]), 399 | s * float4(f[0][2], f[1][2], f[2][2], f[3][2])); 400 | } 401 | 402 | // Simplex noise and its Jacobian derivative 403 | // @param v = 3D noise argument 404 | // @param bTiling = whether to repeat noise pattern 405 | // @param RepeatSize = integer units before tiling in each dimension, must be a multiple of 3 406 | // @return float3x3 Jacobian in J[*].xyz, vector noise in J[*].w 407 | // J[0].w, J[1].w, J[2].w is a Perlin-style simplex noise with vector output, e.g. (Nx, Ny, Nz) 408 | // J[i].x is X derivative of the i'th component of the noise so J[2].x is dNz/dx 409 | // You can use this to compute the noise, gradient, curl, or divergence: 410 | // float3x4 J = JacobianSimplex_ALU(...); 411 | // float3 VNoise = float3(J[0].w, J[1].w, J[2].w); // 3D noise 412 | // float3 Grad = J[0].xyz; // gradient of J[0].w 413 | // float3 Curl = float3(J[1][2]-J[2][1], J[2][0]-J[0][2], J[0][1]-J[1][2]); 414 | // float Div = J[0][0]+J[1][1]+J[2][2]; 415 | // All of these are confirmed to compile out all unneeded terms. 416 | // So Grad of X doesn't compute Y or Z components, and VNoise doesn't do any of the derivative computation. 417 | float3x4 JacobianSimplex_ALU(float3 v, bool bTiling, float RepeatSize) 418 | { 419 | // corners of tetrahedron 420 | float4x3 T = SimplexCorners(v); 421 | uint3 rand; 422 | float4x3 gvec[3], fv; 423 | float3x4 grad; 424 | 425 | // processing of tetrahedral vertices, unrolled 426 | // to compute gradient at each corner 427 | fv[0] = v - T[0]; 428 | rand = Rand3DPCG16(int3(floor(NoiseTileWrap(6 * T[0] + 0.5, bTiling, RepeatSize)))); 429 | gvec[0][0] = float3(rand.xxx & MGradientMask) * MGradientScale - 1; 430 | gvec[1][0] = float3(rand.yyy & MGradientMask) * MGradientScale - 1; 431 | gvec[2][0] = float3(rand.zzz & MGradientMask) * MGradientScale - 1; 432 | grad[0][0] = dot(gvec[0][0], fv[0]); 433 | grad[1][0] = dot(gvec[1][0], fv[0]); 434 | grad[2][0] = dot(gvec[2][0], fv[0]); 435 | 436 | fv[1] = v - T[1]; 437 | rand = Rand3DPCG16(int3(floor(NoiseTileWrap(6 * T[1] + 0.5, bTiling, RepeatSize)))); 438 | gvec[0][1] = float3(rand.xxx & MGradientMask) * MGradientScale - 1; 439 | gvec[1][1] = float3(rand.yyy & MGradientMask) * MGradientScale - 1; 440 | gvec[2][1] = float3(rand.zzz & MGradientMask) * MGradientScale - 1; 441 | grad[0][1] = dot(gvec[0][1], fv[1]); 442 | grad[1][1] = dot(gvec[1][1], fv[1]); 443 | grad[2][1] = dot(gvec[2][1], fv[1]); 444 | 445 | fv[2] = v - T[2]; 446 | rand = Rand3DPCG16(int3(floor(NoiseTileWrap(6 * T[2] + 0.5, bTiling, RepeatSize)))); 447 | gvec[0][2] = float3(rand.xxx & MGradientMask) * MGradientScale - 1; 448 | gvec[1][2] = float3(rand.yyy & MGradientMask) * MGradientScale - 1; 449 | gvec[2][2] = float3(rand.zzz & MGradientMask) * MGradientScale - 1; 450 | grad[0][2] = dot(gvec[0][2], fv[2]); 451 | grad[1][2] = dot(gvec[1][2], fv[2]); 452 | grad[2][2] = dot(gvec[2][2], fv[2]); 453 | 454 | fv[3] = v - T[3]; 455 | rand = Rand3DPCG16(int3(floor(NoiseTileWrap(6 * T[3] + 0.5, bTiling, RepeatSize)))); 456 | gvec[0][3] = float3(rand.xxx & MGradientMask) * MGradientScale - 1; 457 | gvec[1][3] = float3(rand.yyy & MGradientMask) * MGradientScale - 1; 458 | gvec[2][3] = float3(rand.zzz & MGradientMask) * MGradientScale - 1; 459 | grad[0][3] = dot(gvec[0][3], fv[3]); 460 | grad[1][3] = dot(gvec[1][3], fv[3]); 461 | grad[2][3] = dot(gvec[2][3], fv[3]); 462 | 463 | // blend gradients 464 | float4 sv = SimplexSmooth(fv); 465 | float3x4 ds = SimplexDSmooth(fv); 466 | 467 | float3x4 jacobian; 468 | jacobian[0] = float4(mul(sv, gvec[0]) + mul(ds, grad[0]), dot(sv, grad[0])); 469 | jacobian[1] = float4(mul(sv, gvec[1]) + mul(ds, grad[1]), dot(sv, grad[1])); 470 | jacobian[2] = float4(mul(sv, gvec[2]) + mul(ds, grad[2]), dot(sv, grad[2])); 471 | 472 | return jacobian; 473 | } 474 | 475 | // 3D value noise - used to be incorrectly called Perlin noise 476 | // @param v = 3D noise argument, use float3(x,y,0) for 2D or float3(x,0,0) for 1D 477 | // @param bTiling = repeat noise pattern 478 | // @param RepeatSize = integer units before tiling in each dimension 479 | // @return random number in the range -1 .. 1 480 | float ValueNoise3D_ALU(float3 v, bool bTiling, float RepeatSize) 481 | { 482 | float seed000, seed001, seed010, seed011, seed100, seed101, seed110, seed111; 483 | float3 fv = NoiseSeeds(v, bTiling, RepeatSize, seed000, seed001, seed010, seed011, seed100, seed101, seed110, seed111); 484 | 485 | float rand000 = RandBBSfloat(seed000) * 2 - 1; 486 | float rand100 = RandBBSfloat(seed100) * 2 - 1; 487 | float rand010 = RandBBSfloat(seed010) * 2 - 1; 488 | float rand110 = RandBBSfloat(seed110) * 2 - 1; 489 | float rand001 = RandBBSfloat(seed001) * 2 - 1; 490 | float rand101 = RandBBSfloat(seed101) * 2 - 1; 491 | float rand011 = RandBBSfloat(seed011) * 2 - 1; 492 | float rand111 = RandBBSfloat(seed111) * 2 - 1; 493 | 494 | float3 Weights = PerlinRamp(float4(fv, 0)).xyz; 495 | 496 | float i = lerp(lerp(rand000, rand100, Weights.x), lerp(rand010, rand110, Weights.x), Weights.y); 497 | float j = lerp(lerp(rand001, rand101, Weights.x), lerp(rand011, rand111, Weights.x), Weights.y); 498 | return lerp(i, j, Weights.z).x; 499 | } 500 | 501 | 502 | #endif 503 | --------------------------------------------------------------------------------