浏览代码

Merge pull request #228 from Unity-Technologies/shadows

Update Shadows system
/Branch_Batching2
GitHub 8 年前
当前提交
712ff1d3
共有 89 个文件被更改,包括 4561 次插入3507 次删除
  1. 4
      .gitmodules
  2. 518
      Assembly-UnityScript.unityproj
  3. 117
      Assets/ScriptableRenderPipeline/AdditionalLightData.cs
  4. 40
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  5. 16
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  6. 40
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl
  7. 8
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightLoop.cs
  8. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Lighting.hlsl
  9. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TileLightLoopProducer.cs
  10. 248
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute
  11. 427
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  12. 120
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  13. 20
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl
  14. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  15. 18
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  16. 258
      Assets/ScriptableRenderPipeline/fptl/FptlLighting.cs
  17. 161
      Assets/ScriptableRenderPipeline/fptl/LightingTemplate.hlsl
  18. 2
      Assets/TestScenes/HDTest/GraphicTest/Two Sided/Prefabs/Materials.meta
  19. 2
      Assets/TestScenes/HDTest/LayeredLitTest/Mesh/Materials.meta
  20. 2
      Assets/TestScenes/HDTest/WindTest/Materials.meta
  21. 2
      ProjectSettings/ProjectVersion.txt
  22. 123
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl
  23. 35
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl
  24. 941
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs
  25. 49
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl
  26. 115
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl
  27. 746
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl
  28. 67
      Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs
  29. 998
      Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs
  30. 44
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl
  31. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl.meta
  32. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl.meta
  33. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow.meta
  34. 25
      Assets/ScriptableRenderPipeline/ShadowIncludes.inl
  35. 8
      Assets/ScriptableRenderPipeline/ShadowIncludes.inl.meta
  36. 9
      Assets/ScriptableRenderPipeline/common/Shadow.meta
  37. 26
      Assets/ScriptableRenderPipeline/fptl/ShadowContext.hlsl
  38. 9
      Assets/ScriptableRenderPipeline/fptl/ShadowContext.hlsl.meta
  39. 36
      Assets/ScriptableRenderPipeline/fptl/ShadowDispatch.hlsl
  40. 9
      Assets/ScriptableRenderPipeline/fptl/ShadowDispatch.hlsl.meta
  41. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources.meta
  42. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute.meta
  43. 235
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute
  44. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl.meta
  45. 277
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl
  46. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl.meta
  47. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl.meta
  48. 126
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl
  49. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl.meta
  50. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl.meta
  51. 133
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowTexFetch.hlsl
  52. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowTexFetch.hlsl.meta
  53. 12
      Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs.meta
  54. 9
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl.meta
  55. 12
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.meta
  56. 249
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowUtilities.cs
  57. 12
      Assets/ScriptableRenderPipeline/common/Shadow/ShadowUtilities.cs.meta
  58. 12
      Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs.meta
  59. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.hlsl.meta
  60. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs.meta
  61. 187
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithms.hlsl
  62. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithms.hlsl.meta
  63. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithmsCustom.hlsl.meta
  64. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl.meta
  65. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.meta
  66. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowContext.hlsl.meta
  67. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowDispatch.hlsl.meta
  68. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowSampling.hlsl.meta
  69. 81
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowTexFetch.hlsl
  70. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowTexFetch.hlsl.meta
  71. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs.meta
  72. 12
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/VectorArray.cs.meta
  73. 96
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs
  74. 9
      Assets/ScriptableRenderPipeline/RenderPasses.meta
  75. 1001
      Assets/TestScenes/HDTest/GraphicTest/SSS/head.OBJ
  76. 148
      Assets/TestScenes/HDTest/GraphicTest/SSS/head.OBJ.meta
  77. 0
      /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl
  78. 0
      /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl
  79. 0
      /Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs
  80. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl
  81. 0
      /Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl
  82. 0
      /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl
  83. 0
      /Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs
  84. 0
      /Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs
  85. 0
      /Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl

4
.gitmodules


[submodule "Assets/TestScenes/Big"]
path = Assets/TestScenes/Big
url = https://github.com/Unity-Technologies/ScriptableRenderLoopScenes
[submodule "Assets/ScriptableRenderPipeline/PostProcessing"]
path = Assets/ScriptableRenderPipeline/PostProcessing
url = https://github.com/Unity-Technologies/PostProcessing
branch = v2

518
Assembly-UnityScript.unityproj


<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.20506</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<RootNamespace></RootNamespace>
<ProjectGuid>{425682D6-2799-ABE6-93DD-977B724BF07C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<AssemblyName>Assembly-UnityScript</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<BaseDirectory>Assets</BaseDirectory>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>Temp\bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_1_0;UNITY_2017_1;UNITY_2017;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_GENERICS;ENABLE_PVR_GI;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_RUNTIME_NAVMESH_BUILDING;ENABLE_SPRITERENDERER_FLIPPING;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_RAKNET;ENABLE_DIRECTOR;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_TIMELINE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;ENABLE_NATIVE_ARRAY;ENABLE_SPRITE_MASKING;INCLUDE_DYNAMIC_GI;INCLUDE_GI;ENABLE_MONO_BDWGC;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_PLAYMODE_TESTS_RUNNER;ENABLE_VIDEO;ENABLE_RMGUI;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_STYLE_SHEETS;UNITY_STANDALONE_OSX;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_GAMECENTER;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_VR;ENABLE_MODULAR_UNITYENGINE_ASSEMBLIES;ENABLE_CLUSTERINPUT;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_2_0_SUBSET;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_OSX;ENABLE_NATIVE_ARRAY_CHECKS;UNITY_TEAM_LICENSE;UNITY_PRO_LICENSE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>0169</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>Temp\bin\Release\</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>0169</NoWarn>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.XML" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="UnityEngine">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/Managed/UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEditor">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/Managed/UnityEditor.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Scripts\Fps.js" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\CommonLighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderConfig.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Material.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowSampling.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitTessellation.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightingTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\lightlistbuild-clustered.compute" />
<None Include="Assets\ScriptableRenderPipeline\fptl\TiledReflectionTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\lightlistbuild-clustered.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\FinalPass.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\SampleUVMappingNormalInternal.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightDefinitions.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightingUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\UnlitData.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassGBuffer.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\AreaLighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\SortingComputeUtils.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\ScreenSpaceAmbientObscurance.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitProperties.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowDispatch.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\GeometricTools.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\NFAA.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Builtin\BuiltinData.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\DebugDisplay.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassVelocity.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\ShaderPass\UnlitSharePass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\SceneSettings\Resources\DrawGaussianProfile.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\Resources\GGXConvolve.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\TessellationShare.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\common\Resources\BlitCubemap.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_DepthOfField\DepthOfFieldScatter.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassForwardUnlit.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowAlgorithmsCustom.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Shaders\WavingGrass.shader" />
<None Include="Assets\LowEndMobilePipeline\Shaders\LowEndParticlesAdd.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Common.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Builtin\BuiltinData.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Wind.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\SampleUVMappingInternal.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Shaders\DistanceFade.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\Resources\BuildProbabilityTables.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitMetaPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\scrbound.compute" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\SSAA.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\LightingConvexHullUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassForward.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\lightlistbuild.compute" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightBoundsDebug.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\D3D11_1.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_DepthOfField\DepthOfFieldDX11.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\SortingComputeUtils.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\FXAAPreset3.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\TilePassLoop.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPass.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\EntityLighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\ReflectionTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\MaterialUtilities.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\frag_ao.cginc" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowBase.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Resources\PreIntegratedFGD.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\CommonMaterial.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitDataInternal.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\DebugDisplay.cs.hlsl" />
<None Include="Assets\LowEndMobilePipeline\Shaders\LowEndMobilePipelineCore.cginc" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowContext.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Lit.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitDepthPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\FragInputs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\LayeredLit\LayeredLit.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\UnlitProperties.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\scrbound.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\ColorGrading.hlsl" />
<None Include="Assets\LowEndMobilePipeline\Shaders\LowEndParticlesMultiply.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\lightlistbuild-bigtile.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\Resources\DebugViewTiles.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\UnityStandardForwardNew.cginc" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassDistortion.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\Unlit.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\EyeAdaptation.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\Validate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\Textures\LICENSE.txt" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\Metal.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\Unlit.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\shadeopaque.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\PatchStandardShaderToNewNamingConvention.cginc" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitSharePass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\D3D11.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\LutGen.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\SSAOShader.shader" />
<None Include="Assets\BasicRenderPipelineTutorial\BasicRenderPipelineShader.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassDepthOnly.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\TilePass.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\HDRISky\Resources\SkyHDRI.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\Textures\COPYING.txt" />
<None Include="Assets\ScriptableRenderPipeline\fptl\TiledLightingUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\TilePass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowAlgorithms.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitTessellation.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\Internal-DeferredComputeShading.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\Resources\DebugDisplayShadowMap.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\ChromaticAberrationShader.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\Resources\DebugDisplayLatlong.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\QuaternionMath.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\GlobalFog.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\Internal-DeferredShading.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\PSSL.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Tessellation.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\LightUtilities.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\BSDF.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitData.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\Forward.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\cleardispatchindirect.compute" />
<None Include="Assets\ScriptableRenderPipeline\fptl\FinalPass.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Filtering.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\Shadow.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\CameraMotionBlurDX11.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitVelocityPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\SceneSettings\Resources\DrawTransmittanceGraph.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\RegularForwardReflectionTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\RegularForwardLightingUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\Resources\DebugViewMaterialGBuffer.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\CameraMotionBlur.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\CommonShadow.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\DLAA.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderVariables.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\ShaderBase.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\SkyManager.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Fibonacci.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\NormalSurfaceGradient.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Lit.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightingConvexHullUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitDistortionPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\Resources\ComputeGgxIblSampleData.compute" />
<None Include="Assets\ScriptableRenderPipeline\fptl\lightlistbuild.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Resources\CombineSubsurfaceScattering.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\StandardTest.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Packing.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_DepthOfField\SeparableBlur.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\MotionBlurClear.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\EyeAdaptation.hlsl" />
<None Include="Assets\LowEndMobilePipeline\Shaders\LowEndMobilePipeline.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\EyeHistogram.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\ProceduralSky\Resources\SkyProcedural.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Lit.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Hammersley.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Color.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowTexFetch.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\common\CubeToSpherical.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\VignettingShader.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\SHMath.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\FXAA2.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\VaryingMesh.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\SampleUVMapping.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\RegularForwardLightingTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\ClusteredUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\Internal-DeferredReflections.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\Lighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\LayeredLit\LayeredLitTessellation.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\PerPixelDisplacement.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassLightTransport.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\Resources\Deferred.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\ShaderPass\UnlitDistortionPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\ShaderPass\UnlitMetaPass.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Shaders\TerrainSurface.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\LightDefinition.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\TiledLightingTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Sampling.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\ProceduralSky\Resources\AtmosphericScattering.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\FeatureFlags.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\Unlit.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\lightlistbuild-bigtile.compute" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\FXAA3Console.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Debug.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\ImageBasedLighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\README.txt" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\VertMesh.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\FXAAPreset2.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\FixedSizePCF\FixedSizePCF.hlsl" />
<Reference Include="UnityEngine.UI">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.Networking">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.TestRunner">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/TestRunner/UnityEngine.TestRunner.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/TestRunner/nunit.framework.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.Timeline">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/Timeline/RuntimeEditor/UnityEngine.Timeline.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.Analytics">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/UnityAnalytics/UnityEngine.Analytics.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.HoloLens">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/UnityHoloLens/RuntimeEditor/UnityEngine.HoloLens.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.20506</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<RootNamespace></RootNamespace>
<ProjectGuid>{425682D6-2799-ABE6-93DD-977B724BF07C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<AssemblyName>Assembly-UnityScript</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<BaseDirectory>Assets</BaseDirectory>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>Temp\bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;UNITY_5_3_OR_NEWER;UNITY_5_4_OR_NEWER;UNITY_5_5_OR_NEWER;UNITY_5_6_OR_NEWER;UNITY_2017_1_OR_NEWER;UNITY_2017_1_0;UNITY_2017_1;UNITY_2017;ENABLE_AUDIO;ENABLE_CACHING;ENABLE_CLOTH;ENABLE_DUCK_TYPING;ENABLE_GENERICS;ENABLE_PVR_GI;ENABLE_MICROPHONE;ENABLE_MULTIPLE_DISPLAYS;ENABLE_PHYSICS;ENABLE_RUNTIME_NAVMESH_BUILDING;ENABLE_SPRITERENDERER_FLIPPING;ENABLE_SPRITES;ENABLE_TERRAIN;ENABLE_RAKNET;ENABLE_DIRECTOR;ENABLE_UNET;ENABLE_LZMA;ENABLE_UNITYEVENTS;ENABLE_WEBCAM;ENABLE_WWW;ENABLE_CLOUD_SERVICES_COLLAB;ENABLE_CLOUD_SERVICES_COLLAB_SOFTLOCKS;ENABLE_CLOUD_SERVICES_ADS;ENABLE_CLOUD_HUB;ENABLE_CLOUD_PROJECT_ID;ENABLE_CLOUD_SERVICES_USE_WEBREQUEST;ENABLE_CLOUD_SERVICES_UNET;ENABLE_CLOUD_SERVICES_BUILD;ENABLE_CLOUD_LICENSE;ENABLE_WEBSOCKET_CLIENT;ENABLE_DIRECTOR_AUDIO;ENABLE_TIMELINE;ENABLE_EDITOR_METRICS;ENABLE_EDITOR_METRICS_CACHING;ENABLE_NATIVE_ARRAY;ENABLE_SPRITE_MASKING;INCLUDE_DYNAMIC_GI;INCLUDE_GI;ENABLE_MONO_BDWGC;PLATFORM_SUPPORTS_MONO;RENDER_SOFTWARE_CURSOR;INCLUDE_PUBNUB;ENABLE_PLAYMODE_TESTS_RUNNER;ENABLE_VIDEO;ENABLE_RMGUI;ENABLE_CUSTOM_RENDER_TEXTURE;ENABLE_STYLE_SHEETS;UNITY_STANDALONE_OSX;UNITY_STANDALONE;ENABLE_SUBSTANCE;ENABLE_GAMECENTER;ENABLE_RUNTIME_GI;ENABLE_MOVIES;ENABLE_NETWORK;ENABLE_CRUNCH_TEXTURE_COMPRESSION;ENABLE_UNITYWEBREQUEST;ENABLE_CLOUD_SERVICES;ENABLE_CLOUD_SERVICES_ANALYTICS;ENABLE_CLOUD_SERVICES_PURCHASING;ENABLE_CLOUD_SERVICES_CRASH_REPORTING;ENABLE_VR;ENABLE_MODULAR_UNITYENGINE_ASSEMBLIES;ENABLE_CLUSTERINPUT;ENABLE_WEBSOCKET_HOST;ENABLE_MONO;NET_2_0_SUBSET;ENABLE_PROFILER;UNITY_ASSERTIONS;UNITY_EDITOR;UNITY_EDITOR_64;UNITY_EDITOR_OSX;ENABLE_NATIVE_ARRAY_CHECKS;UNITY_TEAM_LICENSE;UNITY_PRO_LICENSE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>0169</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>Temp\bin\Release\</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>0169</NoWarn>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.XML" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="UnityEngine">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/Managed/UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEditor">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/Managed/UnityEditor.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Scripts\Fps.js" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\CommonLighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderConfig.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Material.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowSampling.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitTessellation.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightingTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\lightlistbuild-clustered.compute" />
<None Include="Assets\ScriptableRenderPipeline\fptl\TiledReflectionTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\lightlistbuild-clustered.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\FinalPass.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\SampleUVMappingNormalInternal.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightDefinitions.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightingUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\UnlitData.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassGBuffer.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\AreaLighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\SortingComputeUtils.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\ScreenSpaceAmbientObscurance.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitProperties.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowDispatch.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\GeometricTools.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\NFAA.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Builtin\BuiltinData.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\DebugDisplay.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassVelocity.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\ShaderPass\UnlitSharePass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\SceneSettings\Resources\DrawGaussianProfile.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\Resources\GGXConvolve.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\TessellationShare.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\common\Resources\BlitCubemap.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_DepthOfField\DepthOfFieldScatter.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassForwardUnlit.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowAlgorithmsCustom.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Shaders\WavingGrass.shader" />
<None Include="Assets\LowEndMobilePipeline\Shaders\LowEndParticlesAdd.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Common.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Builtin\BuiltinData.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Wind.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\SampleUVMappingInternal.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Shaders\DistanceFade.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\Resources\BuildProbabilityTables.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitMetaPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\scrbound.compute" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\SSAA.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\LightingConvexHullUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassForward.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\lightlistbuild.compute" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightBoundsDebug.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\D3D11_1.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_DepthOfField\DepthOfFieldDX11.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\SortingComputeUtils.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\FXAAPreset3.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\TilePassLoop.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPass.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\EntityLighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\ReflectionTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\MaterialUtilities.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\frag_ao.cginc" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowBase.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Resources\PreIntegratedFGD.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\CommonMaterial.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitDataInternal.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\DebugDisplay.cs.hlsl" />
<None Include="Assets\LowEndMobilePipeline\Shaders\LowEndMobilePipelineCore.cginc" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowContext.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Lit.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitDepthPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\FragInputs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\LayeredLit\LayeredLit.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\UnlitProperties.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\scrbound.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\ColorGrading.hlsl" />
<None Include="Assets\LowEndMobilePipeline\Shaders\LowEndParticlesMultiply.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\lightlistbuild-bigtile.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\Resources\DebugViewTiles.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\UnityStandardForwardNew.cginc" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassDistortion.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\Unlit.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\EyeAdaptation.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\Validate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\Textures\LICENSE.txt" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\Metal.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\Unlit.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\shadeopaque.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\PatchStandardShaderToNewNamingConvention.cginc" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitSharePass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\D3D11.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\LutGen.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\SSAOShader.shader" />
<None Include="Assets\BasicRenderPipelineTutorial\BasicRenderPipelineShader.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassDepthOnly.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\TilePass.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\HDRISky\Resources\SkyHDRI.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\Textures\COPYING.txt" />
<None Include="Assets\ScriptableRenderPipeline\fptl\TiledLightingUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\TilePass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowAlgorithms.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitTessellation.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\Internal-DeferredComputeShading.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\Resources\DebugDisplayShadowMap.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\ChromaticAberrationShader.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\Resources\DebugDisplayLatlong.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\QuaternionMath.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\GlobalFog.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\Internal-DeferredShading.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\API\PSSL.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Tessellation.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\LightUtilities.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\BSDF.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\LitData.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\Forward.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\Resources\cleardispatchindirect.compute" />
<None Include="Assets\ScriptableRenderPipeline\fptl\FinalPass.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Filtering.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\Shadow.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\CameraMotionBlurDX11.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitVelocityPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\SceneSettings\Resources\DrawTransmittanceGraph.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\RegularForwardReflectionTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\RegularForwardLightingUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Debug\Resources\DebugViewMaterialGBuffer.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\CameraMotionBlur.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\CommonShadow.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\DLAA.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderVariables.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\ShaderBase.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\SkyManager.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Fibonacci.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\NormalSurfaceGradient.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Lit.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\LightingConvexHullUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\ShaderPass\LitDistortionPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\Resources\ComputeGgxIblSampleData.compute" />
<None Include="Assets\ScriptableRenderPipeline\fptl\lightlistbuild.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Resources\CombineSubsurfaceScattering.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\StandardTest.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Packing.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_DepthOfField\SeparableBlur.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\MotionBlurClear.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\EyeAdaptation.hlsl" />
<None Include="Assets\LowEndMobilePipeline\Shaders\LowEndMobilePipeline.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\PostProcess\Resources\EyeHistogram.compute" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\ProceduralSky\Resources\SkyProcedural.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Lit\Lit.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Hammersley.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Color.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\ShadowTexFetch.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\common\CubeToSpherical.shader" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\VignettingShader.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\SHMath.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\FXAA2.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\VaryingMesh.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\SampleUVMapping.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\RegularForwardLightingTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\ClusteredUtils.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\Internal-DeferredReflections.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\Lighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\LayeredLit\LayeredLitTessellation.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\PerPixelDisplacement.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\ShaderPassLightTransport.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\Resources\Deferred.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\ShaderPass\UnlitDistortionPass.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\ShaderPass\UnlitMetaPass.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Shaders\TerrainSurface.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\LightDefinition.cs.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\fptl\TiledLightingTemplate.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Sampling.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\ProceduralSky\Resources\AtmosphericScattering.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Lighting\TilePass\FeatureFlags.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Material\Unlit\Unlit.shader" />
<None Include="Assets\ScriptableRenderPipeline\fptl\lightlistbuild-bigtile.compute" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\FXAA3Console.shader" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\Debug.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\ShaderLibrary\ImageBasedLighting.hlsl" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Sky\README.txt" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\ShaderPass\VertMesh.hlsl" />
<None Include="Assets\TestScenes\Big\BenchRenderVikingVillageStatic\Standard Assets\Image Effects (Pro Only)\_Sources\Shaders\_Antialiasing\FXAAPreset2.shader" />
<None Include="Assets\ScriptableRenderPipeline\HDRenderPipeline\Shadow\FixedSizePCF\FixedSizePCF.hlsl" />
<Reference Include="UnityEngine.UI">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/GUISystem/UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.Networking">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/Networking/UnityEngine.Networking.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.TestRunner">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/TestRunner/UnityEngine.TestRunner.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/TestRunner/nunit.framework.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.Timeline">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/Timeline/RuntimeEditor/UnityEngine.Timeline.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.Analytics">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/UnityAnalytics/UnityEngine.Analytics.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.HoloLens">
<HintPath>/Applications/Unity_Installs/Unity branches/ScriptablePipeline/SRP_27april17.app/Contents/UnityExtensions/Unity/UnityHoloLens/RuntimeEditor/UnityEngine.HoloLens.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

117
Assets/ScriptableRenderPipeline/AdditionalLightData.cs


namespace UnityEngine.Experimental.Rendering
namespace UnityEngine.Experimental.Rendering
{
public enum LightArchetype { Punctual, Area, Projector };

[Range(0.0f, 20.0f)]
public float lightWidth = 0.0f; // Area & projector lights
// shadow related parameters
[System.Serializable]
public struct ShadowData
{
public int format;
public int[] data;
};
[HideInInspector, SerializeField] private int shadowAlgorithm;
[HideInInspector, SerializeField] private int shadowVariant;
[HideInInspector, SerializeField] private int shadowPrecision;
[HideInInspector, SerializeField] private ShadowData shadowData;
[HideInInspector, SerializeField] private ShadowData[] shadowDatas = new ShadowData[0];
public void GetShadowAlgorithm( out int algorithm, out int variant, out int precision ) { algorithm = shadowAlgorithm; variant = shadowVariant; precision = shadowPrecision; }
public void SetShadowAlgorithm( int algorithm, int variant, int precision, int format, int[] data )
{
shadowAlgorithm = algorithm;
shadowVariant = variant;
shadowPrecision = precision;
shadowData.format = format;
shadowData.data = data;
int idx = FindShadowData( format );
if( idx < 0 )
{
idx = shadowDatas.Length;
ShadowData[] tmp = new ShadowData[idx+1];
for( int i = 0; i < idx; ++i )
tmp[i] = shadowDatas[i];
shadowDatas = tmp;
}
shadowDatas[idx].format = format;
shadowDatas[idx].data = data != null ? data : new int[0];
}
// Load a specific shadow data. Returns null if requested data is not present.
public int[] GetShadowData( int shadowDataFormat )
{
if( shadowData.format == shadowDataFormat )
return shadowData.data;
int idx = FindShadowData( shadowDataFormat );
return idx >= 0 ? shadowDatas[idx].data : null;
}
// Returns the currently set shadow data and format. Can return null.
public int[] GetShadowData( out int shadowDataFormat )
{
shadowDataFormat = shadowData.format;
return shadowData.data;
}
#if UNITY_EDITOR
public void CompactShadowData()
{
shadowDatas = new ShadowData[0];
UnityEditor.EditorUtility.SetDirty(this);
}
#endif
private int FindShadowData( int shadowDataFormat )
{
for( int i = 0; i < shadowDatas.Length; ++i )
{
if( shadowDatas[i].format == shadowDataFormat )
return i;
}
return -1;
}
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(AdditionalLightData))]
[UnityEditor.CanEditMultipleObjects]
public class AdditionalLightDataEditor : UnityEditor.Editor
{
static ShadowRegistry m_ShadowRegistry;
#pragma warning disable 414 // CS0414 The private field '...' is assigned but its value is never used
UnityEditor.SerializedProperty m_ShadowAlgorithm;
UnityEditor.SerializedProperty m_ShadowVariant;
UnityEditor.SerializedProperty m_ShadowData;
UnityEditor.SerializedProperty m_ShadowDatas;
#pragma warning restore 414
public static void SetRegistry( ShadowRegistry registry ) { m_ShadowRegistry = registry; }
void OnEnable()
{
m_ShadowAlgorithm = serializedObject.FindProperty( "shadowAlgorithm" );
m_ShadowVariant = serializedObject.FindProperty( "shadowVariant" );
m_ShadowData = serializedObject.FindProperty( "shadowData" );
m_ShadowDatas = serializedObject.FindProperty( "shadowDatas" );
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if( m_ShadowRegistry == null )
return;
AdditionalLightData ald = (AdditionalLightData) target;
if( ald == null )
return;
UnityEditor.EditorGUI.BeginChangeCheck();
m_ShadowRegistry.Draw( ald.gameObject.GetComponent<Light>() );
serializedObject.Update();
if( UnityEditor.EditorGUI.EndChangeCheck() )
{
UnityEditor.EditorUtility.SetDirty( ald );
UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();
UnityEditor.SceneView.RepaintAll();
}
serializedObject.ApplyModifiedProperties();
}
}
#endif
}

40
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


int m_CurrentWidth;
int m_CurrentHeight;
ShadowRenderPass m_ShadowPass;
ShadowOutput m_ShadowsResult = new ShadowOutput();
public int GetCurrentShadowCount() { return m_ShadowsResult.shadowLights == null ? 0 : m_ShadowsResult.shadowLights.Length; }
public int GetCurrentShadowCount() { return m_LightLoop.GetCurrentShadowCount(); }
readonly SkyManager m_SkyManager = new SkyManager();
private readonly BaseLightLoop m_LightLoop;

m_FilterAndCombineSubsurfaceScattering.SetFloat("_DstBlend", (float)BlendMode.One);
InitializeDebugMaterials();
m_ShadowPass = new ShadowRenderPass(owner.shadowSettings);
// Init Gbuffer description
m_gbufferManager.gbufferCount = m_LitRenderLoop.GetMaterialGBufferCount();

}
public void OnSceneLoad()
{
// Recreate the textures which went NULL, and set 'isInit' to 'false'.
{
// Recreate the textures which went NULL, and set 'isInit' to 'false'.
m_LitRenderLoop.Build();
}

// select the most main camera!
Camera camera = cameras.OrderByDescending(x => x.tag == "MainCamera").FirstOrDefault();
if (camera == null)
if (camera == null)
return;
return;
}
// Set camera constant buffer

if (!CullResults.GetCullingParameters(camera, out cullingParams))
if (!CullResults.GetCullingParameters(camera, out cullingParams))
return;
return;
m_ShadowPass.UpdateCullingParameters(ref cullingParams);
m_LightLoop.UpdateCullingParameters( ref cullingParams );
var cullResults = CullResults.Cull(ref cullingParams, renderContext);

}
else
{
using (new Utilities.ProfilingSample("Shadow", renderContext))
{
m_ShadowPass.Render(renderContext, cullResults, out m_ShadowsResult);
}
renderContext.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render
m_LightLoop.PrepareLightsForGPU(m_Owner.shadowSettings, cullResults, camera, ref m_ShadowsResult);
m_LightLoop.PrepareLightsForGPU(m_Owner.shadowSettings, cullResults, camera);
m_LightLoop.RenderShadows(renderContext, cullResults);
renderContext.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render
m_LightLoop.BuildGPULightLists(camera, renderContext, m_CameraDepthStencilBufferRT); // TODO: Use async compute here to run light culling during shadow

{
if (lightingDebug.shadowDebugMode == ShadowMapDebugMode.VisualizeShadowMap)
{
#if SHADOWS_OLD
uint visualizeShadowIndex = Math.Min(lightingDebug.shadowMapIndex, (uint)(GetCurrentShadowCount() - 1));
ShadowLight shadowLight = m_ShadowsResult.shadowLights[visualizeShadowIndex];
for (int slice = 0; slice < shadowLight.shadowSliceCount; ++slice)

NextOverlayCoord(ref x, ref y, overlaySize, camera.pixelWidth);
}
#endif
}
else if (lightingDebug.shadowDebugMode == ShadowMapDebugMode.VisualizeAtlas)
{

}
renderContext.ExecuteCommandBuffer(debugCB);
}
// Function to prepare light structure for GPU lighting
void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput)
{
// build per tile light lists
if (m_LightLoop != null)
m_LightLoop.PrepareLightsForGPU(shadowSettings, cullResults, camera, ref shadowOutput);
}
void InitAndClearBuffer(Camera camera, ScriptableRenderContext renderContext)

16
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


};
// TODO: we may have to add various parameters here for shadow - was suppose to be coupled with a light loop
// A point light is 6x PunctualShadowData
[GenerateHLSL]
public struct ShadowData
{
// World to ShadowMap matrix
// Include scale and bias for shadow atlas if any
public Matrix4x4 worldToShadow;
public float bias;
public float quality;
public float unused;
public float unused2;
public Vector4 invResolution;
};
[GenerateHLSL]
public enum EnvShapeType
{

40
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs.hlsl


int cookieIndex;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.ShadowData
// PackingRules = Exact
struct ShadowData
{
float4x4 worldToShadow;
float bias;
float quality;
float unused;
float unused2;
float4 invResolution;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.EnvLightData
// PackingRules = Exact
struct EnvLightData

int GetCookieIndex(DirectionalLightData value)
{
return value.cookieIndex;
}
//
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.ShadowData
//
float4x4 GetWorldToShadow(ShadowData value)
{
return value.worldToShadow;
}
float GetBias(ShadowData value)
{
return value.bias;
}
float GetQuality(ShadowData value)
{
return value.quality;
}
float GetUnused(ShadowData value)
{
return value.unused;
}
float GetUnused2(ShadowData value)
{
return value.unused2;
}
float4 GetInvResolution(ShadowData value)
{
return value.invResolution;
}
//

8
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightLoop.cs


using UnityEngine;
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline

public virtual void NewFrame() {}
public virtual void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput) {}
public virtual int GetCurrentShadowCount() { return 0; }
public virtual void UpdateCullingParameters( ref CullingParameters cullingParams ) {}
public virtual void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera) {}
// TODO: this should not be part of the interface but for now make something working
public virtual void BuildGPULightLists(Camera camera, ScriptableRenderContext loop, RenderTargetIdentifier cameraDepthBufferRT) {}

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Lighting.hlsl


#include "../Lighting/LightDefinition.cs.hlsl"
#include "../Lighting/LightUtilities.hlsl"
#include "../Shadow/Shadow.hlsl"
#define SHADOW_TILEPASS
#include "../../ShaderLibrary/Shadow/Shadow.hlsl"
#undef SHADOW_TILEPASS
#if defined(LIGHTLOOP_SINGLE_PASS) || defined(LIGHTLOOP_TILE_PASS)
#include "../Lighting/TilePass/TilePass.hlsl"

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TileLightLoopProducer.cs


public enum TileDebug : int { None = 0, Punctual = 1, Area = 2, AreaAndPunctual = 3, Projector = 4, ProjectorAndPunctual = 5, ProjectorAndArea = 6, ProjectorAndAreaAndPunctual = 7,
Environment = 8, EnvironmentAndPunctual = 9, EnvironmentAndArea = 10, EnvironemntAndAreaAndPunctual = 11,
EnvironmentAndProjector = 12, EnvironmentAndProjectorAndPunctual = 13, EnvironmentAndProjectorAndArea = 14, EnvironmentAndProjectorAndAreaAndPunctual = 15,
EnvironmentAndProjector = 12, EnvironmentAndProjectorAndPunctual = 13, EnvironmentAndProjectorAndArea = 14, EnvironmentAndProjectorAndAreaAndPunctual = 15,
FeatureVariants = 16 }; //TODO: we should probably make this checkboxes
public TileDebug tileDebugByCategory;

248
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute


#pragma kernel ShadeOpaque_Direct_Fptl SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl USE_FPTL_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Fptl_DebugDisplay SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl_DebugDisplay USE_FPTL_LIGHTLIST DEBUG_DISPLAY
#pragma kernel ShadeOpaque_Direct_Clustered SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered USE_CLUSTERED_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Clustered_DebugDisplay SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered_DebugDisplay USE_CLUSTERED_LIGHTLIST DEBUG_DISPLAY
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant0 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant1 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant2 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant3 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant4 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant5 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant6 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant7 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant8 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant8 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=8
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant9 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant9 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=9
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant10 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant10 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=10
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant11 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant11 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=11
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant12 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant12 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=12
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant13 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant13 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=13
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant14 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant14 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=14
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant15 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant15 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=15
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant0 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant1 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant2 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant3 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant4 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant5 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant6 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant7 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant8 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant8 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=8
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant9 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant9 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=9
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant10 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant10 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=10
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant11 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant11 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=11
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant12 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant12 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=12
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant13 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant13 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=13
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant14 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant14 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=14
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant15 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant15 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=15
#pragma #pragma enable_d3d11_debug_symbols
// Split lighting is required for the SSS pass.
// Not currently possible since we need to access the stencil buffer from the compute shader.
// #pragma multi_compile _ OUTPUT_SPLIT_LIGHTING
#define LIGHTLOOP_TILE_PASS 1
#define LIGHTLOOP_TILE_DIRECT 1
#define LIGHTLOOP_TILE_INDIRECT 1
#define LIGHTLOOP_TILE_ALL 1
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../Debug/DebugDisplay.hlsl"
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../../../ShaderConfig.cs.hlsl"
#include "../../../ShaderVariables.hlsl"
#include "../../../Lighting/Lighting.hlsl" // This include Material.hlsl
#include "../../../Lighting/TilePass/FeatureFlags.hlsl"
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
#ifdef OUTPUT_SPLIT_LIGHTING
RWTexture2D<float4> specularLightingUAV;
RWTexture2D<float3> diffuseLightingUAV;
#else
RWTexture2D<float4> combinedLightingUAV;
#endif
#if USE_INDIRECT
uint g_TileListOffset;
StructuredBuffer<uint> g_TileList;
// Indirect
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 groupThreadId : SV_GroupThreadID, uint groupId : SV_GroupID)
{
uint tileIndex = g_TileList[g_TileListOffset + groupId];
uint2 tileCoord = uint2(tileIndex & 0xFFFF, tileIndex >> 16);
uint2 pixelCoord = tileCoord * GetTileSize() + groupThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, tileCoord);
uint featureFlags = TileVariantToFeatureFlags(VARIANT);
#else
// Direct
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID)
{
uint2 pixelCoord = dispatchThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, groupId);
uint featureFlags = 0xFFFFFFFF;
#endif
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
BSDFData bsdfData;
float3 bakeDiffuseLighting;
DECODE_FROM_GBUFFER(gbuffer, featureFlags, bsdfData, bakeDiffuseLighting);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
float3 diffuseLighting;
float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
#ifdef OUTPUT_SPLIT_LIGHTING
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = diffuseLighting;
#else
combinedLightingUAV[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
#endif
}
#pragma kernel ShadeOpaque_Direct_Fptl SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl USE_FPTL_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Fptl_DebugDisplay SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Fptl_DebugDisplay USE_FPTL_LIGHTLIST DEBUG_DISPLAY
#pragma kernel ShadeOpaque_Direct_Clustered SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered USE_CLUSTERED_LIGHTLIST
#pragma kernel ShadeOpaque_Direct_Clustered_DebugDisplay SHADE_OPAQUE_ENTRY=ShadeOpaque_Direct_Clustered_DebugDisplay USE_CLUSTERED_LIGHTLIST DEBUG_DISPLAY
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant0 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant1 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant2 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant3 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant4 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant5 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant6 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant7 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant8 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant8 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=8
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant9 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant9 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=9
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant10 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant10 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=10
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant11 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant11 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=11
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant12 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant12 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=12
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant13 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant13 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=13
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant14 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant14 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=14
#pragma kernel ShadeOpaque_Indirect_Fptl_Variant15 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Fptl_Variant15 USE_FPTL_LIGHTLIST USE_INDIRECT VARIANT=15
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant0 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant0 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=0
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant1 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant1 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=1
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant2 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant2 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=2
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant3 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant3 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=3
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant4 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant4 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=4
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant5 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant5 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=5
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant6 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant6 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=6
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant7 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant7 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=7
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant8 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant8 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=8
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant9 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant9 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=9
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant10 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant10 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=10
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant11 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant11 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=11
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant12 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant12 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=12
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant13 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant13 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=13
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant14 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant14 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=14
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant15 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant15 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=15
#pragma #pragma enable_d3d11_debug_symbols
// Split lighting is required for the SSS pass.
// Not currently possible since we need to access the stencil buffer from the compute shader.
// #pragma multi_compile _ OUTPUT_SPLIT_LIGHTING
#define LIGHTLOOP_TILE_PASS 1
#define LIGHTLOOP_TILE_DIRECT 1
#define LIGHTLOOP_TILE_INDIRECT 1
#define LIGHTLOOP_TILE_ALL 1
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../Debug/DebugDisplay.hlsl"
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "../../../ShaderConfig.cs.hlsl"
#include "../../../ShaderVariables.hlsl"
#include "../../../Lighting/Lighting.hlsl" // This include Material.hlsl
#include "../../../Lighting/TilePass/FeatureFlags.hlsl"
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
#ifdef OUTPUT_SPLIT_LIGHTING
RWTexture2D<float4> specularLightingUAV;
RWTexture2D<float3> diffuseLightingUAV;
#else
RWTexture2D<float4> combinedLightingUAV;
#endif
#if USE_INDIRECT
uint g_TileListOffset;
StructuredBuffer<uint> g_TileList;
// Indirect
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 groupThreadId : SV_GroupThreadID, uint groupId : SV_GroupID)
{
uint tileIndex = g_TileList[g_TileListOffset + groupId];
uint2 tileCoord = uint2(tileIndex & 0xFFFF, tileIndex >> 16);
uint2 pixelCoord = tileCoord * GetTileSize() + groupThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, tileCoord);
uint featureFlags = TileVariantToFeatureFlags(VARIANT);
#else
// Direct
[numthreads(16, 16, 1)]
void SHADE_OPAQUE_ENTRY(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID)
{
uint2 pixelCoord = dispatchThreadId;
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, groupId);
uint featureFlags = 0xFFFFFFFF;
#endif
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);
FETCH_GBUFFER(gbuffer, _GBufferTexture, posInput.unPositionSS);
BSDFData bsdfData;
float3 bakeDiffuseLighting;
DECODE_FROM_GBUFFER(gbuffer, featureFlags, bsdfData, bakeDiffuseLighting);
PreLightData preLightData = GetPreLightData(V, posInput, bsdfData);
float3 diffuseLighting;
float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
#ifdef OUTPUT_SPLIT_LIGHTING
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = diffuseLighting;
#else
combinedLightingUAV[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
#endif
}

427
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


//#define SHADOWS_ENABLED
//#define SHADOWS_FIXSHADOWIDX
using UnityEngine.Rendering;
using UnityEngine.Rendering;
#if SHADOWS_ENABLED
using ShadowExp;
class ShadowSetup : IDisposable
{
// shadow related stuff

public ShadowSetup(ShadowSettings shadowSettings, out IShadowManager shadowManager)
{
s_ShadowDataBuffer = new ComputeBuffer(k_MaxShadowDataSlots, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowExp.ShadowData)));
s_ShadowPayloadBuffer = new ComputeBuffer(k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowExp.ShadowData)));
s_ShadowDataBuffer = new ComputeBuffer( k_MaxShadowDataSlots, System.Runtime.InteropServices.Marshal.SizeOf( typeof( ShadowData ) ) );
s_ShadowPayloadBuffer = new ComputeBuffer( k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData, System.Runtime.InteropServices.Marshal.SizeOf( typeof( ShadowPayload ) ) );
ShadowAtlas.AtlasInit atlasInit;
atlasInit.baseInit.width = (uint)shadowSettings.shadowAtlasWidth;
atlasInit.baseInit.height = (uint)shadowSettings.shadowAtlasHeight;

atlasInit.baseInit.clearColor = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
atlasInit.baseInit.samplerState = SamplerState.Default();
atlasInit.baseInit.comparisonSamplerState = ComparisonSamplerState.Default();
atlasInit.baseInit.clearColor = new Vector4( 0.0f, 0.0f, 0.0f, 0.0f );
atlasInit.baseInit.shadowSupport = ShadowmapBase.ShadowSupport.Directional;
atlasInit.baseInit.shadowSupport = ShadowmapBase.ShadowSupport.Directional | ShadowmapBase.ShadowSupport.Point | ShadowmapBase.ShadowSupport.Spot;
var atlasInit2 = atlasInit;
atlasInit2.baseInit.shadowSupport = ShadowmapBase.ShadowSupport.Point | ShadowmapBase.ShadowSupport.Spot;
m_Shadowmaps = new ShadowmapBase[] { new ShadowExp.ShadowAtlas(ref atlasInit), new ShadowExp.ShadowAtlas(ref atlasInit2) };
var varianceInit = atlasInit;
varianceInit.baseInit.shadowmapFormat = ShadowVariance.GetFormat( false, false, true );
var varianceInit2 = varianceInit;
varianceInit2.baseInit.shadowmapFormat = ShadowVariance.GetFormat( true, true, false );
var varianceInit3 = varianceInit;
varianceInit3.baseInit.shadowmapFormat = ShadowVariance.GetFormat( true, false, true );
m_Shadowmaps = new ShadowmapBase[] { new ShadowVariance( ref varianceInit ), new ShadowVariance( ref varianceInit2 ), new ShadowVariance( ref varianceInit3 ), new ShadowAtlas( ref atlasInit ) };
ShadowExp.ShadowData[] sds;
ShadowData[] sds;
sc.GetShadowDatas(out sds, out offset, out count);
Debug.Assert(offset == 0);
s_ShadowDataBuffer.SetData(sds); // unfortunately we can't pass an offset or count to this function

// bind textures
uint offset, count;
RenderTargetIdentifier[] tex;
sc.GetTex2DArrays(out tex, out offset, out count);
cb.SetGlobalTexture("_ShadowmapExp_Dir", tex[0]);
cb.SetGlobalTexture("_ShadowmapExp_PointSpot", tex[1]);
sc.GetTex2DArrays( out tex, out offset, out count );
cb.SetGlobalTexture( "_ShadowmapExp_VSM_0", tex[0] );
cb.SetGlobalTexture( "_ShadowmapExp_VSM_1", tex[1] );
cb.SetGlobalTexture( "_ShadowmapExp_VSM_2", tex[2] );
cb.SetGlobalTexture( "_ShadowmapExp_PCF" , tex[3] );
// TODO: Currently samplers are hard coded in ShadowContext.hlsl, so we can't really set them here
};

scInit.storage.maxTex2DArraySlots = 4;
scInit.storage.maxTexCubeArraySlots = 2;
scInit.storage.maxComparisonSamplerSlots = 2;
scInit.storage.maxSamplerSlots = 2;
scInit.storage.maxTexCubeArraySlots = 0;
scInit.storage.maxComparisonSamplerSlots = 1;
scInit.storage.maxSamplerSlots = 4;
m_ShadowMgr = new ShadowExp.ShadowManager(shadowSettings, ref scInit, m_Shadowmaps);
m_ShadowMgr = new ShadowManager(shadowSettings, ref scInit, m_Shadowmaps);
// set global overrides - these need to match the override specified in ShadowDispatch.hlsl
bool useGlobalOverrides = true;
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Spot , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Directional , ShadowAlgorithm.PCF, ShadowVariant.V4, ShadowPrecision.High, useGlobalOverrides );
shadowManager = m_ShadowMgr;
}

{
(m_Shadowmaps[0] as ShadowAtlas).Dispose();
(m_Shadowmaps[1] as ShadowAtlas).Dispose();
(m_Shadowmaps[2] as ShadowAtlas).Dispose();
(m_Shadowmaps[3] as ShadowAtlas).Dispose();
Utilities.SafeRelease(s_ShadowDataBuffer);
Utilities.SafeRelease(s_ShadowPayloadBuffer);
if (s_ShadowDataBuffer != null)
s_ShadowDataBuffer.Release();
if (s_ShadowPayloadBuffer != null)
s_ShadowPayloadBuffer.Release();
#endif
namespace TilePass
{

Material m_SingleDeferredMaterialSRT = null;
Material m_SingleDeferredMaterialMRT = null;
#if (SHADOWS_ENABLED)
FrameId m_FrameId;
FrameId m_FrameId = new FrameId();
ShadowSetup m_ShadowSetup; // doesn't actually have to reside here, it would be enough to pass the IShadowManager in from the outside
IShadowManager m_ShadowMgr;
List<int> m_ShadowRequests = new List<int>();

m_ShadowMgr = null;
}
}
#endif
int GetNumTileFtplX(Camera camera)

UnityEditor.SceneView.onSceneGUIDelegate += OnSceneGUI;
#endif
#if (SHADOWS_ENABLED)
#endif
DeinitShadowSystem();
#if UNITY_EDITOR
UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
#endif

return new Vector3(light.finalColor.r, light.finalColor.g, light.finalColor.b);
}
// Return number of added shadow
public int GetShadows(VisibleLight light, int lightIndex, ref ShadowOutput shadowOutput, ShadowSettings shadowSettings)
{
for (int sliceIndex = 0; sliceIndex < shadowOutput.GetShadowSliceCountLightIndex(lightIndex); ++sliceIndex)
{
ShadowData shadowData = new ShadowData();
int shadowSliceIndex = shadowOutput.GetShadowSliceIndex(lightIndex, sliceIndex);
shadowData.worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose; // Transpose for hlsl reading ?
shadowData.bias = light.light.shadowBias;
shadowData.invResolution = new Vector4(1.0f / shadowSettings.shadowAtlasWidth, 1.0f / shadowSettings.shadowAtlasHeight, 0.0f, 0.0f);
m_lightList.shadows.Add(shadowData);
}
return shadowOutput.GetShadowSliceCountLightIndex(lightIndex);
}
public bool GetDirectionalLightData(ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int directionalShadowcount)
public bool GetDirectionalLightData(ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex)
{
var directionalLightData = new DirectionalLightData();

directionalLightData.tileCookie = (light.light.cookie.wrapMode == TextureWrapMode.Repeat);
directionalLightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
}
bool hasDirectionalShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasDirectionalNotReachMaxLimit = directionalShadowcount == 0; // Only one cascade shadow allowed
// If we have not found a directional shadow casting light yet, we register the last directional anyway as "sun".
if (directionalShadowcount == 0)
// fix up shadow information
int shadowIdx;
if (m_ShadowIndices.TryGetValue(lightIndex, out shadowIdx))
directionalLightData.shadowIndex = shadowIdx;
if (hasDirectionalShadows && hasDirectionalNotReachMaxLimit) // Note < MaxShadows should be check at shadowOutput creation
{
// Always choose the directional shadow casting light if it exists.
m_CurrentSunLight = light.light;
directionalLightData.shadowIndex = m_lightList.shadows.Count;
directionalShadowcount += GetShadows(light, lightIndex, ref shadowOutput, shadowSettings);
// Fill split information for shaders
for (int s = 0; s < k_MaxCascadeCount; ++s)
{
m_lightList.directionalShadowSplitSphereSqr[s] = shadowOutput.directionalShadowSplitSphereSqr[s];
}
}
m_CurrentSunLight = m_CurrentSunLight == null ? light.light : m_CurrentSunLight;
m_lightList.directionalLights.Add(directionalLightData);

return 1.0f - Mathf.Clamp01((distanceToCamera - distanceFadeNear) / (fadeDistance - distanceFadeNear));
}
public bool GetLightData(ShadowSettings shadowSettings, Camera camera, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex, ref ShadowOutput shadowOutput, ref int shadowCount)
public bool GetLightData(ShadowSettings shadowSettings, Camera camera, GPULightType gpuLightType, VisibleLight light, AdditionalLightData additionalData, int lightIndex)
{
var lightData = new LightData();

lightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
}
}
// Setup shadow data arrays
// In case lightData.shadowDimmer == 0.0 we need to avoid rendering the shadow map... see how it can be done with the culling (and more specifically, how can we do that BEFORE sending for shadows)
bool hasShadows = lightData.shadowDimmer > 0.0f && distanceToCamera < shadowSettings.maxShadowDistance && light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasNotReachMaxLimit = shadowCount + (lightData.lightType == GPULightType.Point ? 6 : 1) <= k_MaxShadowOnScreen;
// TODO: Read the comment about shadow limit/management at the beginning of this loop
if (hasShadows && hasNotReachMaxLimit)
// fix up shadow information
int shadowIdx;
if (m_ShadowIndices.TryGetValue(lightIndex, out shadowIdx))
// When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
lightData.shadowIndex = m_lightList.shadows.Count;
shadowCount += GetShadows(light, lightIndex, ref shadowOutput, shadowSettings);
lightData.shadowIndex = shadowIdx;
if (additionalData.archetype != LightArchetype.Punctual)
{
lightData.size = new Vector2(additionalData.lightLength, additionalData.lightWidth);

m_lightList.bounds.Add(bound);
m_lightList.lightVolumes.Add(lightVolumeData);
}
public override int GetCurrentShadowCount()
{
return m_ShadowRequests.Count;
}
public override void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera, ref ShadowOutput shadowOutput)
public override void UpdateCullingParameters(ref CullingParameters cullingParams)
{
m_ShadowMgr.UpdateCullingParameters( ref cullingParams );
}
public override void PrepareLightsForGPU(ShadowSettings shadowSettings, CullResults cullResults, Camera camera)
#if (SHADOWS_ENABLED)
// 0. deal with shadows
{
m_FrameId.frameCount++;

int lcnt = cullResults.visibleLights.Length;
for (int i = 0; i < lcnt; ++i)
{
if (cullResults.visibleLights[i].light.shadows != LightShadows.None)
m_ShadowRequests.Add(i);
VisibleLight vl = cullResults.visibleLights[i];
AdditionalLightData ald = vl.light.GetComponent<AdditionalLightData>();
if( vl.light.shadows != LightShadows.None && ald != null && ald.shadowDimmer > 0.0f )
m_ShadowRequests.Add( i );
uint originalRequestCount = shadowRequestCount;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, cullResults, camera, cullResults.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);

m_ShadowIndices.Add(shadowRequests[i], shadowDataIndices[i]);
}
}
#endif
float oldSpecularGlobalDimmer = m_PassSettings.specularGlobalDimmer;
// Change some parameters in case of "special" rendering (can be preview, reflection, etc.
if (camera.cameraType == CameraType.Reflection)

GPULightType gpuLightType = GPULightType.Point;
LightVolumeType lightVolumeType = LightVolumeType.Count;
// Note: LightType.Area is offline only, use for baking, no need to test it
if (additionalData.archetype == LightArchetype.Punctual)
{
switch (light.lightType)
// Note: LightType.Area is offline only, use for baking, no need to test it
if (additionalData.archetype == LightArchetype.Punctual)
case LightType.Point:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Point;
lightVolumeType = LightVolumeType.Sphere;
break;
switch (light.lightType)
{
case LightType.Point:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Point;
lightVolumeType = LightVolumeType.Sphere;
break;
case LightType.Spot:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Spot;
lightVolumeType = LightVolumeType.Cone;
break;
case LightType.Spot:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Spot;
lightVolumeType = LightVolumeType.Cone;
break;
case LightType.Directional:
if (directionalLightcount >= k_MaxDirectionalLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Directional;
// No need to add volume, always visible
lightVolumeType = LightVolumeType.Count; // Count is none
break;
case LightType.Directional:
if (directionalLightcount >= k_MaxDirectionalLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Directional;
// No need to add volume, always visible
lightVolumeType = LightVolumeType.Count; // Count is none
break;
default:
Debug.Assert(false, "TODO: encountered an unknown LightType.");
break;
default:
Debug.Assert(false, "TODO: encountered an unknown LightType.");
break;
}
}
else
{
switch (additionalData.archetype)
else
case LightArchetype.Area:
if (areaLightCount >= k_MaxAreaLightsOnScreen) { continue; }
lightCategory = LightCategory.Area;
gpuLightType = (additionalData.lightWidth > 0) ? GPULightType.Rectangle : GPULightType.Line;
lightVolumeType = LightVolumeType.Box;
break;
case LightArchetype.Projector:
if (projectorLightCount >= k_MaxProjectorLightsOnScreen) { continue; }
lightCategory = LightCategory.Projector;
switch (light.lightType)
{
case LightType.Directional:
gpuLightType = GPULightType.ProjectorOrtho;
lightVolumeType = LightVolumeType.Box;
break;
case LightType.Spot:
gpuLightType = GPULightType.ProjectorPyramid;
lightVolumeType = LightVolumeType.Cone;
break;
default:
Debug.Assert(false, "Projectors can only be Spot or Directional lights.");
break;
}
break;
default:
Debug.Assert(false, "TODO: encountered an unknown LightArchetype.");
break;
switch (additionalData.archetype)
{
case LightArchetype.Area:
if (areaLightCount >= k_MaxAreaLightsOnScreen) { continue; }
lightCategory = LightCategory.Area;
gpuLightType = (additionalData.lightWidth > 0) ? GPULightType.Rectangle : GPULightType.Line;
lightVolumeType = LightVolumeType.Box;
break;
case LightArchetype.Projector:
if (projectorLightCount >= k_MaxProjectorLightsOnScreen) { continue; }
lightCategory = LightCategory.Projector;
switch (light.lightType)
{
case LightType.Directional:
gpuLightType = GPULightType.ProjectorOrtho;
lightVolumeType = LightVolumeType.Box;
break;
case LightType.Spot:
gpuLightType = GPULightType.ProjectorPyramid;
lightVolumeType = LightVolumeType.Cone;
break;
default:
Debug.Assert(false, "Projectors can only be Spot or Directional lights.");
break;
}
break;
default:
Debug.Assert(false, "TODO: encountered an unknown LightArchetype.");
break;
}
}
#if (SHADOWS_ENABLED)
uint shadow = m_ShadowIndices.ContainsKey(lightIndex) ? 1u : 0;
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 5 bit (0x1F) lightVolume, 1 bit for shadow casting, 16 bit index
sortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 17 | shadow << 16 | (uint)lightIndex;
#else
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 6 bit (0x3F) lightVolume, 16 bit index
sortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 16 | (uint)lightIndex;
#endif
uint shadow = m_ShadowIndices.ContainsKey(lightIndex) ? 1u : 0;
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 5 bit (0x1F) lightVolume, 1 bit for shadow casting, 16 bit index
sortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 17 | shadow << 16 | (uint)lightIndex;
}
Array.Sort(sortKeys);

// will be use...)
// The lightLoop is in charge, not the shadow pass.
// For now we will still apply the maximum of shadow here but we don't apply the sorting by priority + slot allocation yet
int directionalShadowcount = 0;
int shadowCount = 0;
m_CurrentSunLight = null;
// 2. Go thought all lights, convert them to GPU format.
// Create simultaneously data for culling (LigthVolumeData and rendering)

uint sortKey = sortKeys[sortIndex];
LightCategory lightCategory = (LightCategory)((sortKey >> 27) & 0x1F);
GPULightType gpuLightType = (GPULightType)((sortKey >> 22) & 0x1F);
#if (SHADOWS_ENABLED)
#else
LightVolumeType lightVolumeType = (LightVolumeType)((sortKey >> 16) & 0x3F);
#endif
int lightIndex = (int)(sortKey & 0xFFFF);
var light = cullResults.visibleLights[lightIndex];

if (gpuLightType == GPULightType.Directional)
{
if (GetDirectionalLightData(shadowSettings, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref directionalShadowcount))
if (GetDirectionalLightData(shadowSettings, gpuLightType, light, additionalData, lightIndex))
#if (SHADOWS_ENABLED && SHADOWS_FIXSHADOWIDX)
// fix up shadow information
int shadowIdxDir;
if (m_ShadowIndices.TryGetValue(lightIndex, out shadowIdxDir))
{
var lightData = m_lightList.directionalLights[m_lightList.directionalLights.Count - 1];
lightData.shadowIndex = shadowIdxDir;
m_lightList.directionalLights[m_lightList.directionalLights.Count - 1] = lightData;
}
#endif
if (GetLightData(shadowSettings, camera, gpuLightType, light, additionalData, lightIndex, ref shadowOutput, ref shadowCount))
if(GetLightData(shadowSettings, camera, gpuLightType, light, additionalData, lightIndex))
{
switch (lightCategory)
{

// Then culling side. Must be call in this order as we pass the created Light data to the function
GetLightVolumeDataAndBound(lightCategory, gpuLightType, lightVolumeType, light, m_lightList.lights[m_lightList.lights.Count - 1], worldToView);
}
#if (SHADOWS_ENABLED && SHADOWS_FIXSHADOWIDX)
// fix up shadow information
int shadowIdx;
if (m_ShadowIndices.TryGetValue(lightIndex, out shadowIdx))
{
var lightData = m_lightList.lights[m_lightList.lights.Count - 1];
lightData.shadowIndex = shadowIdx;
m_lightList.lights[m_lightList.lights.Count - 1] = lightData;
}
#endif
}
// Sanity check

private void BindGlobalParams(CommandBuffer cmd, ComputeShader computeShader, int kernelIndex, Camera camera, ScriptableRenderContext loop)
{
#if (SHADOWS_ENABLED)
#endif
SetGlobalBuffer("g_vLightListGlobal", !usingFptl ? s_PerVoxelLightLists : s_LightList); // opaques list (unless MSAA possibly)
SetGlobalTexture("_CookieTextures", m_CookieTexArray.GetTexCache());

{
var cmd = new CommandBuffer { name = "Push Global Parameters" };
#if (SHADOWS_ENABLED)
#endif
SetGlobalPropertyRedirect(computeShader, kernelIndex, cmd);
BindGlobalParams(cmd, computeShader, kernelIndex, camera, loop);
SetGlobalPropertyRedirect(null, 0, null);

public override void RenderShadows(ScriptableRenderContext renderContext, CullResults cullResults)
{
#if (SHADOWS_ENABLED)
#endif
}
private void SetupDebugDisplayMode(bool debugDisplayEnable)

Utilities.SetKeyword(m_SingleDeferredMaterialMRT, "DEBUG_DISPLAY", debugDisplayEnable);
}
public override void RenderLightingDebug(HDCamera hdCamera, ScriptableRenderContext renderContext, RenderTargetIdentifier colorBuffer)
public override void RenderLightingDebug(HDCamera hdCamera, ScriptableRenderContext renderContext, RenderTargetIdentifier colorBuffer)
var cmd = new CommandBuffer();
var cmd = new CommandBuffer();
bool bUseClusteredForDeferred = !usingFptl;
bool bUseClusteredForDeferred = !usingFptl;
int w = hdCamera.camera.pixelWidth;
int h = hdCamera.camera.pixelHeight;
int numTilesX = (w + 15) / 16;
int numTilesY = (h + 15) / 16;
int numTiles = numTilesX * numTilesY;
int w = hdCamera.camera.pixelWidth;
int h = hdCamera.camera.pixelHeight;
int numTilesX = (w + 15) / 16;
int numTilesY = (h + 15) / 16;
int numTiles = numTilesX * numTilesY;
Vector2 mousePixelCoord = Input.mousePosition;
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)

}
#endif
// Debug tiles
PushGlobalParams(hdCamera.camera, renderContext, null, 0);
if (m_PassSettings.tileDebugByCategory == TileLightLoopProducer.TileSettings.TileDebug.FeatureVariants)
{
if (GetFeatureVariantsEnabled())
{
// featureVariants
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewTilesMaterial);
m_DebugViewTilesMaterial.SetInt("_NumTiles", numTiles);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_PassSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetVector("_MousePixelCoord", mousePixelCoord);
m_DebugViewTilesMaterial.SetBuffer("g_TileList", s_TileList);
m_DebugViewTilesMaterial.SetBuffer("g_DispatchIndirectBuffer", s_DispatchIndirectBuffer);
m_DebugViewTilesMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword("SHOW_LIGHT_CATEGORIES");
m_DebugViewTilesMaterial.EnableKeyword("SHOW_FEATURE_VARIANTS");
cmd.SetRenderTarget(colorBuffer);
cmd.DrawProcedural(Matrix4x4.identity, m_DebugViewTilesMaterial, 0, MeshTopology.Triangles, numTiles * 6);
}
}
else if (m_PassSettings.tileDebugByCategory != TileLightLoopProducer.TileSettings.TileDebug.None)
{
// lightCategories
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewTilesMaterial);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_PassSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetVector("_MousePixelCoord", mousePixelCoord);
m_DebugViewTilesMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.EnableKeyword("SHOW_LIGHT_CATEGORIES");
m_DebugViewTilesMaterial.DisableKeyword("SHOW_FEATURE_VARIANTS");
cmd.Blit(null, colorBuffer, m_DebugViewTilesMaterial, 0);
// Debug tiles
PushGlobalParams(hdCamera.camera, renderContext, null, 0);
if (m_PassSettings.tileDebugByCategory == TileLightLoopProducer.TileSettings.TileDebug.FeatureVariants)
{
if (GetFeatureVariantsEnabled())
{
// featureVariants
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewTilesMaterial);
m_DebugViewTilesMaterial.SetInt("_NumTiles", numTiles);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_PassSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetVector("_MousePixelCoord", mousePixelCoord);
m_DebugViewTilesMaterial.SetBuffer("g_TileList", s_TileList);
m_DebugViewTilesMaterial.SetBuffer("g_DispatchIndirectBuffer", s_DispatchIndirectBuffer);
m_DebugViewTilesMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword("SHOW_LIGHT_CATEGORIES");
m_DebugViewTilesMaterial.EnableKeyword("SHOW_FEATURE_VARIANTS");
cmd.SetRenderTarget(colorBuffer);
cmd.DrawProcedural(Matrix4x4.identity, m_DebugViewTilesMaterial, 0, MeshTopology.Triangles, numTiles * 6);
}
SetGlobalPropertyRedirect(null, 0, null);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
else if (m_PassSettings.tileDebugByCategory != TileLightLoopProducer.TileSettings.TileDebug.None)
{
// lightCategories
Utilities.SetupMaterialHDCamera(hdCamera, m_DebugViewTilesMaterial);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)m_PassSettings.tileDebugByCategory);
m_DebugViewTilesMaterial.SetVector("_MousePixelCoord", mousePixelCoord);
m_DebugViewTilesMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.EnableKeyword("SHOW_LIGHT_CATEGORIES");
m_DebugViewTilesMaterial.DisableKeyword("SHOW_FEATURE_VARIANTS");
cmd.Blit(null, colorBuffer, m_DebugViewTilesMaterial, 0);
}
SetGlobalPropertyRedirect(null, 0, null);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
public override void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext,

120
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


{
int sampleShadow;
int sampleReflection;
#ifdef SHADOWS_USE_SHADOWCTXT
#endif
#ifndef SHADOWS_USE_SHADOWCTXT
//-----------------------------------------------------------------------------
// Shadow sampling function
// ----------------------------------------------------------------------------
float GetPunctualShadowAttenuation(LightLoopContext lightLoopContext, uint lightType, float3 positionWS, int index, float3 L, float2 unPositionSS)
{
int faceIndex = 0;
if (lightType == GPULIGHTTYPE_POINT)
{
GetCubeFaceID(L, faceIndex);
}
ShadowData shadowData = _ShadowDatas[index + faceIndex];
// Note: scale and bias of shadow atlas are included in ShadowTransform but could be apply here.
float4 positionTXS = mul(float4(positionWS, 1.0), shadowData.worldToShadow);
positionTXS.xyz /= positionTXS.w;
// positionTXS.z -= shadowData.bias;
positionTXS.z -= 0.001; // Apply a linear bias
#if UNITY_REVERSED_Z
positionTXS.z = 1.0 - positionTXS.z;
#endif
// float3 shadowPosDX = ddx_fine(positionTXS);
// float3 shadowPosDY = ddy_fine(positionTXS);
return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
}
// Gets the cascade weights based on the world position of the fragment and the positions of the split spheres for each cascade.
// Returns an invalid split index if past shadowDistance (ie 4 is invalid for cascade)
int GetSplitSphereIndexForDirshadows(float3 positionWS, float4 dirShadowSplitSpheres[4])
{
float3 fromCenter0 = positionWS.xyz - dirShadowSplitSpheres[0].xyz;
float3 fromCenter1 = positionWS.xyz - dirShadowSplitSpheres[1].xyz;
float3 fromCenter2 = positionWS.xyz - dirShadowSplitSpheres[2].xyz;
float3 fromCenter3 = positionWS.xyz - dirShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
float4 dirShadowSplitSphereSqRadii;
dirShadowSplitSphereSqRadii.x = dirShadowSplitSpheres[0].w;
dirShadowSplitSphereSqRadii.y = dirShadowSplitSpheres[1].w;
dirShadowSplitSphereSqRadii.z = dirShadowSplitSpheres[2].w;
dirShadowSplitSphereSqRadii.w = dirShadowSplitSpheres[3].w;
if (distances2.w > dirShadowSplitSphereSqRadii.w)
return -1;
float4 weights = float4(distances2 < dirShadowSplitSphereSqRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
return int(4.0 - dot(weights, float4(4.0, 3.0, 2.0, 1.0)));
}
float GetDirectionalShadowAttenuation(LightLoopContext lightLoopContext, float3 positionWS, int index, float3 L, float2 unPositionSS)
{
// Note Index is 0 for now, but else we need to provide the correct index in _DirShadowSplitSpheres and _ShadowDatas
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
if (shadowSplitIndex == -1)
return 1.0;
ShadowData shadowData = _ShadowDatas[shadowSplitIndex];
// Note: scale and bias of shadow atlas are included in ShadowTransform but could be apply here.
float4 positionTXS = mul(float4(positionWS, 1.0), shadowData.worldToShadow);
positionTXS.xyz /= positionTXS.w;
// positionTXS.z -= shadowData.bias;
positionTXS.z -= 0.003; // Apply a linear bias
#if UNITY_REVERSED_Z
positionTXS.z = 1.0 - positionTXS.z;
#endif
float4 vShadow3x3PCFTerms0;
float4 vShadow3x3PCFTerms1;
float4 vShadow3x3PCFTerms2;
float4 vShadow3x3PCFTerms3;
float flTexelEpsilonX = shadowData.invResolution.x;
float flTexelEpsilonY = shadowData.invResolution.y;
vShadow3x3PCFTerms0 = float4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
vShadow3x3PCFTerms1 = float4(flTexelEpsilonX, flTexelEpsilonY, -flTexelEpsilonX, -flTexelEpsilonY);
vShadow3x3PCFTerms2 = float4(flTexelEpsilonX, flTexelEpsilonY, 0.0f, 0.0f);
vShadow3x3PCFTerms3 = float4(-flTexelEpsilonX, -flTexelEpsilonY, 0.0f, 0.0f);
// float3 shadowPosDX = ddx_fine(positionTXS);
// float3 shadowPosDY = ddy_fine(positionTXS);
//return SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS);
float4 v20Taps;
v20Taps.x = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.xy, positionTXS.z)).x; // 1 1
v20Taps.y = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.zy, positionTXS.z)).x; // -1 1
v20Taps.z = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.xw, positionTXS.z)).x; // 1 -1
v20Taps.w = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms1.zw, positionTXS.z)).x; // -1 -1
float flSum = dot(v20Taps.xyzw, float4(0.25, 0.25, 0.25, 0.25));
if ((flSum == 0.0) || (flSum == 1.0))
return flSum;
flSum *= vShadow3x3PCFTerms0.x * 4.0;
float4 v33Taps;
v33Taps.x = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms2.xz, positionTXS.z)).x; // 1 0
v33Taps.y = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms3.xz, positionTXS.z)).x; // -1 0
v33Taps.z = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms3.zy, positionTXS.z)).x; // 0 -1
v33Taps.w = SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, float3(positionTXS.xy + vShadow3x3PCFTerms2.zy, positionTXS.z)).x; // 0 1
flSum += dot(v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy);
flSum += SAMPLE_TEXTURE2D_SHADOW(g_tShadowBuffer, samplerg_tShadowBuffer, positionTXS).x * vShadow3x3PCFTerms0.z;
return flSum;
}
#endif
//-----------------------------------------------------------------------------
// Cookie sampling functions

20
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LightLoop
// ----------------------------------------------------------------------------

float3(1.0, 1.0, 0.0)
};
#ifdef SHADOWS_USE_SHADOWCTXT
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#else
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#endif
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, float3(0.0, 1.0, 0.0 ), 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
float4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres(lightLoopContext.shadowContext, 0, dirShadowSplitSpheres);
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows(positionWS, dirShadowSplitSpheres);
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
if (shadowSplitIndex == -1)
diffuseLighting = float3(0.0, 0.0, 0.0);
else

out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);

out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs


m_PreIntegratedFGD = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_PreIntegratedFGD.filterMode = FilterMode.Bilinear;
m_PreIntegratedFGD.wrapMode = TextureWrapMode.Clamp;
m_PreIntegratedFGD.hideFlags = HideFlags.DontSave;
m_PreIntegratedFGD.Create();
m_LtcData = new Texture2DArray(k_LtcLUTResolution, k_LtcLUTResolution, 3, TextureFormat.RGBAHalf, false /*mipmap*/, true /* linear */)

18
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


[branch] if (lightData.shadowIndex >= 0)
{
#ifdef SHADOWS_USE_SHADOWCTXT
shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
#else
shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
#endif
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS);
illuminance *= shadow;
}

[branch] if (lightData.shadowIndex >= 0)
{
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
#ifdef SHADOWS_USE_SHADOWCTXT
shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, lightData.shadowIndex, L, posInput.unPositionSS);
#else
shadow = GetPunctualShadowAttenuation(lightLoopContext, lightData.lightType, positionWS + offset, lightData.shadowIndex, L, posInput.unPositionSS);
#endif
float shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS);
shadow = lerp(1.0, shadow, lightData.shadowDimmer);
illuminance *= shadow;

[branch] if (lightData.shadowIndex >= 0)
{
#ifdef SHADOWS_USE_SHADOWCTXT
shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
#else
shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);
#endif
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS);
illuminance *= shadow;
}

258
Assets/ScriptableRenderPipeline/fptl/FptlLighting.cs


using UnityEngine.Rendering;
using UnityEngine.Rendering;
class ShadowSetup : IDisposable
{
// shadow related stuff
const int k_MaxShadowDataSlots = 64;
const int k_MaxPayloadSlotsPerShadowData = 4;
ShadowmapBase[] m_Shadowmaps;
ShadowManager m_ShadowMgr;
static ComputeBuffer s_ShadowDataBuffer;
static ComputeBuffer s_ShadowPayloadBuffer;
public ShadowSetup(ShadowSettings shadowSettings, out IShadowManager shadowManager)
{
s_ShadowDataBuffer = new ComputeBuffer(k_MaxShadowDataSlots, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
s_ShadowPayloadBuffer = new ComputeBuffer(k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowPayload)));
ShadowAtlas.AtlasInit atlasInit;
atlasInit.baseInit.width = (uint)shadowSettings.shadowAtlasWidth;
atlasInit.baseInit.height = (uint)shadowSettings.shadowAtlasHeight;
atlasInit.baseInit.slices = 1;
atlasInit.baseInit.shadowmapBits = 32;
atlasInit.baseInit.shadowmapFormat = RenderTextureFormat.Shadowmap;
atlasInit.baseInit.samplerState = SamplerState.Default();
atlasInit.baseInit.comparisonSamplerState = ComparisonSamplerState.Default();
atlasInit.baseInit.clearColor = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
atlasInit.baseInit.maxPayloadCount = 0;
atlasInit.baseInit.shadowSupport = ShadowmapBase.ShadowSupport.Directional | ShadowmapBase.ShadowSupport.Point | ShadowmapBase.ShadowSupport.Spot;
atlasInit.shaderKeyword = null;
atlasInit.cascadeCount = shadowSettings.directionalLightCascadeCount;
atlasInit.cascadeRatios = shadowSettings.directionalLightCascades;
m_Shadowmaps = new ShadowmapBase[] { new ShadowAtlas(ref atlasInit) };
ShadowContext.SyncDel syncer = (ShadowContext sc) =>
{
// update buffers
uint offset, count;
ShadowData[] sds;
sc.GetShadowDatas(out sds, out offset, out count);
Debug.Assert(offset == 0);
s_ShadowDataBuffer.SetData(sds); // unfortunately we can't pass an offset or count to this function
ShadowPayload[] payloads;
sc.GetPayloads(out payloads, out offset, out count);
Debug.Assert(offset == 0);
s_ShadowPayloadBuffer.SetData(payloads);
};
// binding code. This needs to be in sync with ShadowContext.hlsl
ShadowContext.BindDel binder = (ShadowContext sc, CommandBuffer cb) =>
{
// bind buffers
cb.SetGlobalBuffer("_ShadowDatasExp", s_ShadowDataBuffer);
cb.SetGlobalBuffer("_ShadowPayloads", s_ShadowPayloadBuffer);
// bind textures
uint offset, count;
RenderTargetIdentifier[] tex;
sc.GetTex2DArrays(out tex, out offset, out count);
cb.SetGlobalTexture("_ShadowmapExp_PCF", tex[0]);
// TODO: Currently samplers are hard coded in ShadowContext.hlsl, so we can't really set them here
};
ShadowContext.CtxtInit scInit;
scInit.storage.maxShadowDataSlots = k_MaxShadowDataSlots;
scInit.storage.maxPayloadSlots = k_MaxShadowDataSlots * k_MaxPayloadSlotsPerShadowData;
scInit.storage.maxTex2DArraySlots = 1;
scInit.storage.maxTexCubeArraySlots = 0;
scInit.storage.maxComparisonSamplerSlots = 1;
scInit.storage.maxSamplerSlots = 0;
scInit.dataSyncer = syncer;
scInit.resourceBinder = binder;
m_ShadowMgr = new ShadowManager(shadowSettings, ref scInit, m_Shadowmaps);
// set global overrides - these need to match the override specified in ShadowDispatch.hlsl
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point , ShadowAlgorithm.PCF, ShadowVariant.V1, ShadowPrecision.High, true );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Spot , ShadowAlgorithm.PCF, ShadowVariant.V1, ShadowPrecision.High, true );
m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Directional , ShadowAlgorithm.PCF, ShadowVariant.V1, ShadowPrecision.High, true );
shadowManager = m_ShadowMgr;
}
public void Dispose()
{
if (m_Shadowmaps != null)
{
(m_Shadowmaps[0] as ShadowAtlas).Dispose();
m_Shadowmaps = null;
}
m_ShadowMgr = null;
if( s_ShadowDataBuffer != null )
s_ShadowDataBuffer.Release();
if( s_ShadowPayloadBuffer != null )
s_ShadowPayloadBuffer.Release();
}
}
public class FptlLightingInstance : RenderPipeline
{
private readonly FptlLighting m_Owner;

[SerializeField]
ShadowSettings m_ShadowSettings = ShadowSettings.Default;
ShadowRenderPass m_ShadowPass;
ShadowSetup m_ShadowSetup;
IShadowManager m_ShadowMgr;
FrameId m_FrameId = new FrameId();
List<int> m_ShadowRequests = new List<int>();
Dictionary<int, int> m_ShadowIndices = new Dictionary<int,int>();
void InitShadowSystem(ShadowSettings shadowSettings)
{
m_ShadowSetup = new ShadowSetup(shadowSettings, out m_ShadowMgr);
}
void DeinitShadowSystem()
{
if (m_ShadowSetup != null)
{
m_ShadowSetup.Dispose();
m_ShadowSetup = null;
m_ShadowMgr = null;
}
}
[SerializeField]
TextureSettings m_TextureSettings = TextureSettings.Default;

const float k_DirectionalLightPullbackDistance = 10000.0f;
[NonSerialized]
private int m_WarnedTooManyLights = 0;
private TextureCache2D m_CookieTexArray;
private TextureCacheCubemap m_CubeCookieTexArray;
private TextureCacheCubemap m_CubeReflTexArray;

}
ClearComputeBuffers();
DeinitShadowSystem();
}
void ClearComputeBuffers()

m_MatWorldToShadow = new Matrix4x4[k_MaxLights * k_MaxShadowmapPerLights];
m_DirShadowSplitSpheres = new Vector4[k_MaxDirectionalSplit];
m_Shadow3X3PCFTerms = new Vector4[4];
m_ShadowPass = new ShadowRenderPass(m_ShadowSettings);
InitShadowSystem(m_ShadowSettings);
m_SkyboxHelper = new SkyboxHelper();
m_SkyboxHelper.CreateMesh();

return camera.projectionMatrix * GetFlipMatrix();
}
static int UpdateDirectionalLights(Camera camera, IList<VisibleLight> visibleLights)
static int UpdateDirectionalLights(Camera camera, IList<VisibleLight> visibleLights, Dictionary<int,int> shadowIndices)
{
var dirLightCount = 0;
var lights = new List<DirectionalLight>();

vy = worldToView.MultiplyVector(vy);
vz = worldToView.MultiplyVector(vz);
l.shadowLightIndex = (light.light.shadows != LightShadows.None) ? (uint)nLight : 0xffffffff;
int shadowIdx;
l.shadowLightIndex = shadowIndices.TryGetValue((int)nLight, out shadowIdx) ? (uint)shadowIdx : 0x80000000;
l.lightAxisX = vx;
l.lightAxisY = vy;
l.lightAxisZ = vz;

return dirLightCount;
}
void UpdateShadowConstants(IList<VisibleLight> visibleLights, ref ShadowOutput shadow)
int GenerateSourceLightBuffers(Camera camera, CullResults inputs)
var nNumLightsIncludingTooMany = 0;
var numLights = 0;
var lightShadowIndex_LightParams = new Vector4[k_MaxLights];
var lightFalloffParams = new Vector4[k_MaxLights];
for (int nLight = 0; nLight < visibleLights.Count; nLight++)
// 0. deal with shadows
nNumLightsIncludingTooMany++;
if (nNumLightsIncludingTooMany > k_MaxLights)
continue;
var light = visibleLights[nLight];
var lightType = light.lightType;
var position = light.light.transform.position;
var lightDir = light.light.transform.forward.normalized;
// Setup shadow data arrays
var hasShadows = shadow.GetShadowSliceCountLightIndex(nLight) != 0;
if (lightType == LightType.Directional)
m_FrameId.frameCount++;
// get the indices for all lights that want to have shadows
m_ShadowRequests.Clear();
m_ShadowRequests.Capacity = inputs.visibleLights.Length;
int lcnt = inputs.visibleLights.Length;
for (int i = 0; i < lcnt; ++i)
lightShadowIndex_LightParams[numLights] = new Vector4(0, 0, 1, 1);
lightFalloffParams[numLights] = new Vector4(0.0f, 0.0f, float.MaxValue, (float)lightType);
if (hasShadows)
{
for (int s = 0; s < k_MaxDirectionalSplit; ++s)
{
m_DirShadowSplitSpheres[s] = shadow.directionalShadowSplitSphereSqr[s];
}
}
VisibleLight vl = inputs.visibleLights[i];
if (vl.light.shadows != LightShadows.None && vl.light.GetComponent<AdditionalLightData>().shadowDimmer > 0.0f)
m_ShadowRequests.Add(i);
else if (lightType == LightType.Point)
{
lightShadowIndex_LightParams[numLights] = new Vector4(0, 0, 1, 1);
lightFalloffParams[numLights] = new Vector4(1.0f, 0.0f, light.range * light.range, (float)lightType);
}
else if (lightType == LightType.Spot)
{
lightShadowIndex_LightParams[numLights] = new Vector4(0, 0, 1, 1);
lightFalloffParams[numLights] = new Vector4(1.0f, 0.0f, light.range * light.range, (float)lightType);
}
// pass this list to a routine that assigns shadows based on some heuristic
uint shadowRequestCount = (uint)m_ShadowRequests.Count;
int[] shadowRequests = m_ShadowRequests.ToArray();
int[] shadowDataIndices;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, inputs, camera, inputs.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);
if (hasShadows)
// update the visibleLights with the shadow information
m_ShadowIndices.Clear();
for (uint i = 0; i < shadowRequestCount; i++)
// Enable shadows
lightShadowIndex_LightParams[numLights].x = 1;
for (int s = 0; s < shadow.GetShadowSliceCountLightIndex(nLight); ++s)
{
var shadowSliceIndex = shadow.GetShadowSliceIndex(nLight, s);
m_MatWorldToShadow[numLights * k_MaxShadowmapPerLights + s] = shadow.shadowSlices[shadowSliceIndex].shadowTransform.transpose;
}
}
numLights++;
}
// Warn if too many lights found
if (nNumLightsIncludingTooMany > k_MaxLights)
{
if (nNumLightsIncludingTooMany > m_WarnedTooManyLights)
{
Debug.LogError("ERROR! Found " + nNumLightsIncludingTooMany + " runtime lights! Valve renderer supports up to " + k_MaxLights +
" active runtime lights at a time!\nDisabling " + (nNumLightsIncludingTooMany - k_MaxLights) + " runtime light" +
((nNumLightsIncludingTooMany - k_MaxLights) > 1 ? "s" : "") + "!\n");
}
m_WarnedTooManyLights = nNumLightsIncludingTooMany;
}
else
{
if (m_WarnedTooManyLights > 0)
{
m_WarnedTooManyLights = 0;
Debug.Log("SUCCESS! Found " + nNumLightsIncludingTooMany + " runtime lights which is within the supported number of lights, " + k_MaxLights + ".\n\n");
m_ShadowIndices.Add(shadowRequests[i], shadowDataIndices[i]);
// PCF 3x3 Shadows
var flTexelEpsilonX = 1.0f / m_ShadowSettings.shadowAtlasWidth;
var flTexelEpsilonY = 1.0f / m_ShadowSettings.shadowAtlasHeight;
m_Shadow3X3PCFTerms[0] = new Vector4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
m_Shadow3X3PCFTerms[1] = new Vector4(flTexelEpsilonX, flTexelEpsilonY, -flTexelEpsilonX, -flTexelEpsilonY);
m_Shadow3X3PCFTerms[2] = new Vector4(flTexelEpsilonX, flTexelEpsilonY, 0.0f, 0.0f);
m_Shadow3X3PCFTerms[3] = new Vector4(-flTexelEpsilonX, -flTexelEpsilonY, 0.0f, 0.0f);
}
int GenerateSourceLightBuffers(Camera camera, CullResults inputs)
{
var probes = inputs.visibleReflectionProbes;
//ReflectionProbe[] probes = Object.FindObjectsOfType<ReflectionProbe>();

light.color.Set(cl.finalColor.r, cl.finalColor.g, cl.finalColor.b);
light.sliceIndex = 0;
light.lightModel = (uint)LightDefinitions.DIRECT_LIGHT;
light.shadowLightIndex = shadowLightIndex;
int shadowIdx;
light.shadowLightIndex = m_ShadowIndices.TryGetValue( (int) shadowLightIndex, out shadowIdx ) ? (uint) shadowIdx : 0x80000000;
shadowLightIndex++;
var bHasCookie = cl.light.cookie != null;

if (!CullResults.GetCullingParameters(camera, out cullingParams))
continue;
m_ShadowPass.UpdateCullingParameters(ref cullingParams);
m_ShadowMgr.UpdateCullingParameters( ref cullingParams );
var cullResults = CullResults.Cull(ref cullingParams, renderContext);
ExecuteRenderLoop(camera, cullResults, renderContext);

// do anything we need to do upon a new frame.
NewFrame();
#pragma warning disable 162 // warning CS0162: Unreachable code detected
if (!k_UseAsyncCompute) RenderShadowMaps(cullResults, loop);
#pragma warning restore 162
// generate g-buffer before shadows to leverage async compute
// forward opaques just write to depth.
loop.SetupCameraProperties(camera);

var numLights = GenerateSourceLightBuffers(camera, cullResults);
BuildPerTileLightLists(camera, loop, numLights, projscr, invProjscr);
// render shadow maps (for mobile shadow map rendering should happen before we render g-buffer).
// on GCN it needs to be after to leverage async compute since we need the depth-buffer for optimal light list building.
if (k_UseAsyncCompute)
{
RenderShadowMaps(cullResults, loop);
loop.SetupCameraProperties(camera);
}
m_ShadowMgr.RenderShadows( m_FrameId, loop, cullResults, cullResults.visibleLights );
m_ShadowMgr.SyncData();
m_ShadowMgr.BindResources( loop );
var numDirLights = UpdateDirectionalLights(camera, cullResults.visibleLights);
var numDirLights = UpdateDirectionalLights(camera, cullResults.visibleLights, m_ShadowIndices);
PushGlobalParams(camera, loop, CameraToWorld(camera), projscr, invProjscr, numDirLights);
// do deferred lighting

void RenderShadowMaps(CullResults cullResults, ScriptableRenderContext loop)
{
ShadowOutput shadows;
m_ShadowPass.Render(loop, cullResults, out shadows);
UpdateShadowConstants(cullResults.visibleLights, ref shadows);
}
void ResizeIfNecessary(int curWidth, int curHeight)

161
Assets/ScriptableRenderPipeline/fptl/LightingTemplate.hlsl


#define CUBEMAPFACE_POSITIVE_Z 4
#define CUBEMAPFACE_NEGATIVE_Z 5
#define SHADOW_FPTL
# if defined(SHADER_API_D3D11)
# include "../ShaderLibrary/API/D3D11.hlsl"
# elif defined(SHADER_API_PSSL)
# include "../ShaderLibrary/API/PSSL.hlsl"
# elif defined(SHADER_API_XBOXONE)
# include "../ShaderLibrary/API/D3D11.hlsl"
# include "../ShaderLibrary/API/D3D11_1.hlsl"
# elif defined(SHADER_API_METAL)
# include "../ShaderLibrary/API/Metal.hlsl"
# else
# error unsupported shader api
# endif
# include "../ShaderLibrary/API/Validate.hlsl"
# include "../ShaderLibrary/Shadow/Shadow.hlsl"
#undef SHADOW_FPTL
CBUFFER_START(ShadowLightData)
float4 g_vShadow3x3PCFTerms0;

StructuredBuffer<DirectionalLight> g_dirLightData;
#define DECLARE_SHADOWMAP( tex ) Texture2D tex; SamplerComparisonState sampler##tex
#ifdef REVERSE_ZBUF
#define SAMPLE_SHADOW( tex, coord ) tex.SampleCmpLevelZero( sampler##tex, (coord).xy, (coord).z )
#else
#define SAMPLE_SHADOW( tex, coord ) tex.SampleCmpLevelZero( sampler##tex, (coord).xy, 1.0-(coord).z )
#endif
DECLARE_SHADOWMAP(g_tShadowBuffer);
float ComputeShadow_PCF_3x3_Gaussian(float3 vPositionWs, float4x4 matWorldToShadow)
{
float4 vPositionTextureSpace = mul(float4(vPositionWs.xyz, 1.0), matWorldToShadow);
vPositionTextureSpace.xyz /= vPositionTextureSpace.w;
float2 shadowMapCenter = vPositionTextureSpace.xy;
if ((shadowMapCenter.x < 0.0f) || (shadowMapCenter.x > 1.0f) || (shadowMapCenter.y < 0.0f) || (shadowMapCenter.y > 1.0f))
return 1.0f;
float objDepth = saturate(257.0 / 256.0 - vPositionTextureSpace.z);
float4 v20Taps;
v20Taps.x = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.xy, objDepth)).x; // 1 1
v20Taps.y = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.zy, objDepth)).x; // -1 1
v20Taps.z = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.xw, objDepth)).x; // 1 -1
v20Taps.w = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms1.zw, objDepth)).x; // -1 -1
float flSum = dot(v20Taps.xyzw, float4(0.25, 0.25, 0.25, 0.25));
if ((flSum == 0.0) || (flSum == 1.0))
return flSum;
flSum *= g_vShadow3x3PCFTerms0.x * 4.0;
float4 v33Taps;
v33Taps.x = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms2.xz, objDepth)).x; // 1 0
v33Taps.y = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms3.xz, objDepth)).x; // -1 0
v33Taps.z = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms3.zy, objDepth)).x; // 0 -1
v33Taps.w = SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy + g_vShadow3x3PCFTerms2.zy, objDepth)).x; // 0 1
flSum += dot(v33Taps.xyzw, g_vShadow3x3PCFTerms0.yyyy);
flSum += SAMPLE_SHADOW(g_tShadowBuffer, float3(shadowMapCenter.xy, objDepth)).x * g_vShadow3x3PCFTerms0.z;
return flSum;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* Gets the cascade weights based on the world position of the fragment and the positions of the split spheres for each cascade.
* Returns an invalid split index if past shadowDistance (ie 4 is invalid for cascade)
*/
float GetSplitSphereIndexForDirshadows(float3 wpos)
{
float3 fromCenter0 = wpos.xyz - g_vDirShadowSplitSpheres[0].xyz;
float3 fromCenter1 = wpos.xyz - g_vDirShadowSplitSpheres[1].xyz;
float3 fromCenter2 = wpos.xyz - g_vDirShadowSplitSpheres[2].xyz;
float3 fromCenter3 = wpos.xyz - g_vDirShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
float4 vDirShadowSplitSphereSqRadii;
vDirShadowSplitSphereSqRadii.x = g_vDirShadowSplitSpheres[0].w;
vDirShadowSplitSphereSqRadii.y = g_vDirShadowSplitSpheres[1].w;
vDirShadowSplitSphereSqRadii.z = g_vDirShadowSplitSpheres[2].w;
vDirShadowSplitSphereSqRadii.w = g_vDirShadowSplitSpheres[3].w;
fixed4 weights = float4(distances2 < vDirShadowSplitSphereSqRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
return 4 - dot(weights, float4(4, 3, 2, 1));
}
float SampleShadow(uint type, float3 vPositionWs, float3 vPositionToLightDirWs, uint lightIndex)
{
float flShadowScalar = 1.0;
int shadowSplitIndex = 0;
if (type == DIRECTIONAL_LIGHT)
{
shadowSplitIndex = GetSplitSphereIndexForDirshadows(vPositionWs);
}
else if (type == SPHERE_LIGHT)
{
float3 absPos = abs(vPositionToLightDirWs);
shadowSplitIndex = (vPositionToLightDirWs.z > 0) ? CUBEMAPFACE_NEGATIVE_Z : CUBEMAPFACE_POSITIVE_Z;
if (absPos.x > absPos.y)
{
if (absPos.x > absPos.z)
{
shadowSplitIndex = (vPositionToLightDirWs.x > 0) ? CUBEMAPFACE_NEGATIVE_X : CUBEMAPFACE_POSITIVE_X;
}
}
else
{
if (absPos.y > absPos.z)
{
shadowSplitIndex = (vPositionToLightDirWs.y > 0) ? CUBEMAPFACE_NEGATIVE_Y : CUBEMAPFACE_POSITIVE_Y;
}
}
}
flShadowScalar = ComputeShadow_PCF_3x3_Gaussian(vPositionWs.xyz, g_matWorldToShadow[lightIndex * MAX_SHADOWMAP_PER_LIGHT + shadowSplitIndex]);
return flShadowScalar;
}
float3 ExecuteLightList(uint start, uint numLights, float3 vP, float3 vPw, float3 Vworld)
{
UnityIndirect ind;

ShadowContext shadowContext = InitShadowContext();
float3 ints = 0;

float atten = 1;
[branch]
if (lightData.shadowLightIndex != 0xffffffff)
{
float shadowScalar = SampleShadow(DIRECTIONAL_LIGHT, vPw, 0, lightData.shadowLightIndex);
atten *= shadowScalar;
}
int shadowIdx = asint(lightData.shadowLightIndex);
[branch]
if (shadowIdx >= 0)
{
float shadow = GetDirectionalShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, 0.0.xxx);
atten *= shadow;
}
UnityLight light;
light.color.xyz = lightData.color.xyz * atten;
light.dir.xyz = mul((float3x3) g_mViewToWorld, -lightData.lightAxisZ).xyz;

}
atten *= angularAtt.w*(fProjVec>0.0); // finally apply this to the dist att.
const bool bHasShadow = (lgtDat.flags&HAS_SHADOW)!=0;
[branch]if(bHasShadow)
{
float shadowScalar = SampleShadow(SPOT_LIGHT, vPw, 0, lgtDat.shadowLightIndex);
atten *= shadowScalar;
}
int shadowIdx = asint(lgtDat.shadowLightIndex);
[branch]
if (shadowIdx >= 0)
{
float shadow = GetPunctualShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, 0.0.xxx);
atten *= shadow;
}
UnityLight light;
light.color.xyz = lgtDat.color.xyz*atten*angularAtt.xyz;

atten *= cookieColor.w;
}
const bool bHasShadow = (lgtDat.flags&HAS_SHADOW)!=0;
[branch]if(bHasShadow)
{
float shadowScalar = SampleShadow(SPHERE_LIGHT, vPw, vLw, lgtDat.shadowLightIndex);
atten *= shadowScalar;
}
int shadowIdx = asint(lgtDat.shadowLightIndex);
[branch]
if (shadowIdx >= 0)
{
float shadow = GetPunctualShadowAttenuation(shadowContext, vPw, 0.0.xxx, shadowIdx, vLw);
atten *= shadow;
}
UnityLight light;
light.color.xyz = lgtDat.color.xyz*atten*cookieColor.xyz;

2
Assets/TestScenes/HDTest/GraphicTest/Two Sided/Prefabs/Materials.meta


fileFormatVersion: 2
fileFormatVersion: 2
guid: ee9aedf6876b41c459d476afd81ab708
folderAsset: yes
timeCreated: 1492083994

2
Assets/TestScenes/HDTest/LayeredLitTest/Mesh/Materials.meta


fileFormatVersion: 2
fileFormatVersion: 2
guid: babcbb0e8a80beb4ca87d6a963225ae6
folderAsset: yes
timeCreated: 1492083990

2
Assets/TestScenes/HDTest/WindTest/Materials.meta


fileFormatVersion: 2
fileFormatVersion: 2
guid: fd0f1959e62dce14aa6e413beba5bdb4
folderAsset: yes
timeCreated: 1492083997

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2017.1.0b3
m_EditorVersion: 2017.2.0a1

123
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl


#ifndef SHADOW_HLSL
#ifndef SHADOW_HLSL
#define SHADOW_HLSL
//
// Shadow master include header.

//
//#define SHADOWS_USE_SHADOWCTXT
#ifdef SHADOWS_USE_SHADOWCTXT
// TODO: Remove this once we've moved over to the new system. Also delete the undef at the bottom again.
#define ShadowData ShadowDataExp
#include "../../common/Shadow/ShadowBase.cs.hlsl" // ShadowData definition, auto generated (don't modify)
#include "ShadowTexFetch.hlsl" // Resource sampling definitions (don't modify)
#include "ShadowBase.cs.hlsl" // ShadowData definition, auto generated (don't modify)
#include "ShadowTexFetch.hlsl" // Resource sampling definitions (don't modify)
// Declares a shadow context struct with members and sampling code based on whether _...Slots > 0
#define SHADOWCONTEXT_DECLARE( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
\
struct ShadowContext \
{ \
StructuredBuffer<ShadowData> shadowDatas; \
StructuredBuffer<int4> payloads; \
SHADOWCONTEXT_DECLARE_TEXTURES( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
}; \
\
SHADOW_DEFINE_SAMPLING_FUNCS( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots )
#define SHADOWCONTEXT_DECLARE( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
\
struct ShadowContext \
{ \
StructuredBuffer<ShadowData> shadowDatas; \
StructuredBuffer<int4> payloads; \
Texture2DArray tex2DArray[_Tex2DArraySlots]; \
TextureCubeArray texCubeArray[_TexCubeArraySlots]; \
SamplerComparisonState compSamplers[_SamplerCompSlots]; \
SamplerState samplers[_SamplerSlots]; \
}; \
\
SHADOW_DEFINE_SAMPLING_FUNCS( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots )
#include "ShadowContext.hlsl"
#define SHADOW_CONTEXT_INCLUDE
#include "../../ShadowIncludes.inl"
#undef SHADOW_CONTEXT_INCLUDE
//#include "ShadowContext.hlsl"
void unpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx, out float slice )
void UnpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx, out float slice )
{
texIdx = (shadowmapId >> 24) & 0xff;
sampIdx = (shadowmapId >> 16) & 0xff;
slice = (float)(shadowmapId & 0xffff);
}
void UnpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx )
texIdx = (shadowmapId >> 24) & 0xff;
sampIdx = (shadowmapId >> 16) & 0xff;
slice = (float)(shadowmapId & 0xffff);
texIdx = (shadowmapId >> 24) & 0xff;
sampIdx = (shadowmapId >> 16) & 0xff;
void unpackShadowmapId( uint shadowmapId, out uint texIdx, out uint sampIdx )
void UnpackShadowmapId( uint shadowmapId, out float slice )
texIdx = (shadowmapId >> 24) & 0xff;
sampIdx = (shadowmapId >> 16) & 0xff;
slice = (float)(shadowmapId & 0xffff);
void unpackShadowmapId( uint shadowmapId, out float slice )
void UnpackShadowType( uint packedShadowType, out uint shadowType, out uint shadowAlgorithm )
slice = (float)(shadowmapId & 0xffff);
shadowType = packedShadowType >> 10;
shadowAlgorithm = packedShadowType & 0x1ff;
void UnpackShadowType( uint packedShadowType, out uint shadowType )
{
shadowType = packedShadowType >> 10;
}
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L );
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L, float2 unPositionSS );
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L );
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS );
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L );
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L, float2 unPositionSS );
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L );
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS );
#include "ShadowSampling.hlsl" // sampling patterns
#include "ShadowAlgorithms.hlsl" // engine default algorithms (don't modify)
#include "ShadowAlgorithmsCustom.hlsl" // project specific custom algorithms (project can modify this)
#include "ShadowSampling.hlsl" // sampling patterns (don't modify)
#include "ShadowAlgorithms.hlsl" // engine default algorithms (don't modify)
#include "ShadowAlgorithmsCustom.hlsl" // project specific custom algorithms (project can modify this)
float GetPunctualShadowAttenuationDefault( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L )
float GetPunctualShadowAttenuationDefault( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
return EvalShadow_PunctualDepth(shadowContext, positionWS, shadowDataIndex, L);
return EvalShadow_PunctualDepth(shadowContext, positionWS, normalWS, shadowDataIndex, L);
float GetPunctualShadowAttenuationDefault( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float GetPunctualShadowAttenuationDefault( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
return GetPunctualShadowAttenuationDefault( shadowContext, positionWS, shadowDataIndex, L );
return GetPunctualShadowAttenuationDefault( shadowContext, positionWS, normalWS, shadowDataIndex, L );
float GetDirectionalShadowAttenuationDefault( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L )
float GetDirectionalShadowAttenuationDefault( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
return EvalShadow_CascadedDepth( shadowContext, positionWS, shadowDataIndex, L );
return EvalShadow_CascadedDepth( shadowContext, positionWS, normalWS, shadowDataIndex, L );
float GetDirectionalShadowAttenuationDefault( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float GetDirectionalShadowAttenuationDefault( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
return GetDirectionalShadowAttenuationDefault( shadowContext, positionWS, shadowDataIndex, L );
return GetDirectionalShadowAttenuationDefault( shadowContext, positionWS, normalWS, shadowDataIndex, L );
#include "ShadowDispatch.hlsl"
#define SHADOW_DISPATCH_INCLUDE
#include "../../ShadowIncludes.inl"
#undef SHADOW_DISPATCH_INCLUDE
//#include "ShadowDispatch.hlsl"
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
return GetPunctualShadowAttenuationDefault( shadowContext, positionWS, shadowDataIndex, L );
return GetPunctualShadowAttenuationDefault( shadowContext, positionWS, normalWS, shadowDataIndex, L );
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
return GetPunctualShadowAttenuationDefault( shadowContext, positionWS, shadowDataIndex, L, unPositionSS );
return GetPunctualShadowAttenuationDefault( shadowContext, positionWS, normalWS, shadowDataIndex, L, unPositionSS );
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L )
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
return GetDirectionalShadowAttenuationDefault( shadowContext, positionWS, shadowDataIndex, L );
return GetDirectionalShadowAttenuationDefault( shadowContext, positionWS, normalWS, shadowDataIndex, L );
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
return GetDirectionalShadowAttenuationDefault( shadowContext, positionWS, shadowDataIndex, L, unPositionSS );
return GetDirectionalShadowAttenuationDefault( shadowContext, positionWS, normalWS, shadowDataIndex, L, unPositionSS );
#undef ShadowData // TODO: Remove this once we've moved over to the new system. Also delete the define at the top again.
#endif // SHADOWS_USE_SHADOWCTXT
#endif // SHADOW_HLSL

35
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl


// This file is empty on purpose. Projects can put their custom shadow algorithms in here so they get automatically included by Shadow.hlsl.
float EvalShadow_CascadedMomentum( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L )
float EvalShadow_CascadedMoment( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
return 1.0;
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, shadowDataIndex, dirShadowSplitSpheres );
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres );
if (shadowSplitIndex < 0)
return 1.0;
ShadowData sd = shadowContext.shadowDatas[shadowDataIndex + 1 + shadowSplitIndex];
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
switch( shadowAlgorithm )
{
case (GPUSHADOWALGORITHM_CUSTOM + 1): return 1.0;
default: return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
float EvalShadow_CascadedMomentum( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float EvalShadow_CascadedMoment( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
return 1.0;
}
return EvalShadow_CascadedMoment( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}

941
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs


using UnityEngine.Rendering;
using UnityEngine.Rendering;
using System.Collections.Generic;
namespace UnityEngine.Experimental.Rendering.HDPipeline
namespace UnityEngine.Experimental.Rendering
[Serializable]
public class ShadowSettings
{
public bool enabled;
public int shadowAtlasWidth;
public int shadowAtlasHeight;
public float maxShadowDistance;
public int directionalLightCascadeCount;
public Vector3 directionalLightCascades;
public float directionalLightNearPlaneOffset;
static ShadowSettings defaultShadowSettings = null;
public static ShadowSettings Default
{
get
{
if (defaultShadowSettings == null)
{
defaultShadowSettings = new ShadowSettings();
defaultShadowSettings.enabled = true;
defaultShadowSettings.shadowAtlasHeight = defaultShadowSettings.shadowAtlasWidth = 4096;
defaultShadowSettings.directionalLightCascadeCount = 1;
defaultShadowSettings.directionalLightCascades = new Vector3(0.05F, 0.2F, 0.3F);
defaultShadowSettings.directionalLightCascadeCount = 4;
defaultShadowSettings.directionalLightNearPlaneOffset = 5;
defaultShadowSettings.maxShadowDistance = 1000.0F;
}
return defaultShadowSettings;
}
}
}
[GenerateHLSL]
public enum GPUShadowType
{

};
[GenerateHLSL]
public enum GPUShadowSampling
public enum ShadowAlgorithm // 6 bits
PCF_1tap,
PCF_9Taps_Adaptive,
VSM_1tap,
MSM_1tap
PCF,
VSM,
EVSM,
MSM,
Custom = 32
namespace ShadowExp // temporary namespace until everything can be merged into the HDPipeline
public enum ShadowVariant // 3 bits
// This is the struct passed into shaders
[GenerateHLSL]
public struct ShadowData
{
// shadow texture related params (need to be set by ShadowmapBase and derivatives)
public Matrix4x4 worldToShadow;// to light space matrix
public Vector4 scaleOffset;// scale and offset of shadowmap in atlas
public Vector2 texelSizeRcp;// reciprocal of the shadowmap's texel size in x and y
public uint id; // packed texture id, sampler id and slice idx
public GPUShadowType shadowType; // determines the shadow algorithm, i.e. which map to sample and how to interpret the data
public uint payloadOffset;// if this shadow type requires additional data it can be fetched from a global Buffer<uint> at payloadOffset.
V0,
V1,
V2,
V3,
V4,
V5,
V6,
V7
}
// light related params (need to be set via ShadowMgr and derivatives)
public GPULightType lightType; // the light type
public float bias; // bias setting
public float quality; // some quality parameters
public enum ShadowPrecision // 1 bits
{
High,
Low
}
public void PackShadowmapId(uint texIdx, uint sampIdx, uint slice)
{
Debug.Assert(texIdx <= 0xff);
Debug.Assert(sampIdx <= 0xff);
Debug.Assert(slice <= 0xffff);
id = texIdx << 24 | sampIdx << 16 | slice;
}
};
[GenerateHLSL]
public enum GPUShadowAlgorithm // 9 bits
{
PCF_1tap = ShadowAlgorithm.PCF << 3 | ShadowVariant.V0,
PCF_9tap = ShadowAlgorithm.PCF << 3 | ShadowVariant.V1,
PCF_tent_3x3 = ShadowAlgorithm.PCF << 3 | ShadowVariant.V2,
PCF_tent_5x5 = ShadowAlgorithm.PCF << 3 | ShadowVariant.V3,
PCF_tent_7x7 = ShadowAlgorithm.PCF << 3 | ShadowVariant.V4,
VSM = ShadowAlgorithm.VSM << 3,
EVSM_2 = ShadowAlgorithm.EVSM << 3 | ShadowVariant.V0,
EVSM_4 = ShadowAlgorithm.EVSM << 3 | ShadowVariant.V1,
MSM_Ham = ShadowAlgorithm.MSM << 3 | ShadowVariant.V0,
MSM_Haus = ShadowAlgorithm.MSM << 3 | ShadowVariant.V1,
Custom = ShadowAlgorithm.Custom << 3
}
public struct FrameId
// Central location for storing various shadow constants and bitmasks. These can be used to pack enums into ints, for example.
// These are all guaranteed to be positive, but C# doesn't like uints, so they're all ints.
public static class ShadowConstants
{
public struct Counts
public int frameCount;
public float deltaT;
public const int k_ShadowAlgorithm = 64;
public const int k_ShadowVariant = 8;
public const int k_ShadowPrecision = 2;
public const int k_GPUShadowType = 3;
}
public struct Bits
{
public const int k_ShadowAlgorithm = 6;
public const int k_ShadowVariant = 3;
public const int k_ShadowPrecision = 1;
public const int k_GPUShadowAlgorithm = k_ShadowAlgorithm + k_ShadowVariant + k_ShadowPrecision;
public const int k_GPUShadowType = 4;
// -------------- Begin temporary structs that need to be replaced at some point ---------------
public struct SamplerState
public struct Masks
// TODO: this should either contain the description for a sampler, or be replaced by a struct that does
public static bool operator==(SamplerState lhs, SamplerState rhs) { return false; }
public static bool operator!=(SamplerState lhs, SamplerState rhs) { return true; }
public override bool Equals(object obj) { return (obj is SamplerState) && (SamplerState)obj == this; }
public override int GetHashCode() { /* TODO: implement this at some point */ throw new NotImplementedException(); }
public const int k_ShadowAlgorithm = (1 << Bits.k_ShadowAlgorithm ) - 1;
public const int k_ShadowVariant = (1 << Bits.k_ShadowVariant ) - 1;
public const int k_ShadowPrecision = (1 << Bits.k_ShadowPrecision ) - 1;
public const int k_GPUShadowAlgorithm = (1 << Bits.k_GPUShadowAlgorithm ) - 1;
public const int k_GPUShadowType = (1 << Bits.k_GPUShadowType ) - 1;
}
public struct ComparisonSamplerState
// Shadow Registry for exposing shadow features to the UI
public class ShadowRegistry
{
public delegate void VariantDelegate( Light l, ShadowAlgorithm dataAlgorithm, ShadowVariant dataVariant, ShadowPrecision dataPrecision, ref int[] dataContainer );
struct Dels
{
public VariantDelegate low;
public VariantDelegate high;
}
struct Entry
// TODO: this should either contain the description for a comparison sampler, or be replaced by a struct that does
public static bool operator==(ComparisonSamplerState lhs, ComparisonSamplerState rhs) { return false; }
public static bool operator!=(ComparisonSamplerState lhs, ComparisonSamplerState rhs) { return true; }
public override bool Equals(object obj) { return (obj is ComparisonSamplerState) && (ComparisonSamplerState)obj == this; }
public override int GetHashCode() { /* TODO: implement this at some point */ throw new NotImplementedException(); }
public string algorithmDesc;
public int variantsAvailable;
public string[] variantDescs;
public Dels[] variantDels;
// -------------- End temporary structs that need to be replaced at some point ---------------
public struct ShadowPayload
struct Override
public int p0;
public int p1;
public int p2;
public int p3;
public bool enabled;
public ShadowAlgorithm algorithm;
public ShadowVariant variant;
public ShadowPrecision precision;
}
public void Set(float v0, float v1, float v2, float v3)
{
p0 = ShadowUtils.Asint(v0);
p1 = ShadowUtils.Asint(v1);
p2 = ShadowUtils.Asint(v2);
p3 = ShadowUtils.Asint(v3);
}
Override[] m_GlobalOverrides = new Override[(int)GPUShadowType.MAX];
Dictionary<ShadowAlgorithm, Entry>[] m_Entries = new Dictionary<ShadowAlgorithm, Entry>[ShadowConstants.Counts.k_GPUShadowType]
{ new Dictionary<ShadowAlgorithm, Entry>(),
new Dictionary<ShadowAlgorithm, Entry>(),
new Dictionary<ShadowAlgorithm, Entry>() };
public void Set(Vector4 v) { Set(v.x, v.y, v.z, v.w); }
public void ClearRegistry()
{
foreach( var d in m_Entries )
d.Clear();
// Class holding resource information that needs to be synchronized with shaders.
public class ShadowContextStorage
public void Register( GPUShadowType type, ShadowPrecision precision, ShadowAlgorithm algorithm, string algorithmDescriptor, ShadowVariant[] variants, string[] variantDescriptors, VariantDelegate[] variantDelegates )
{
if( Validate( algorithmDescriptor, variants, variantDescriptors, variantDelegates ) )
Register( m_Entries[(int)type], precision, algorithm, algorithmDescriptor, variants, variantDescriptors, variantDelegates );
}
private bool Validate( string algorithmDescriptor, ShadowVariant[] variants, string[] variantDescriptors, VariantDelegate[] variantDelegates )
public struct Init
if( string.IsNullOrEmpty( algorithmDescriptor ) )
{
Debug.LogError( "Tried to register a shadow algorithm but the algorithm descriptor is empty." );
return false;
}
if( variantDescriptors == null || variantDescriptors.Length == 0 )
public uint maxShadowDataSlots;
public uint maxPayloadSlots;
public uint maxTex2DArraySlots;
public uint maxTexCubeArraySlots;
public uint maxComparisonSamplerSlots;
public uint maxSamplerSlots;
Debug.LogError( "Tried to register a shadow algorithm (" + algorithmDescriptor + ") but the variant descriptors are empty. At least one variant descriptor is required for registration." );
return false;
protected ShadowContextStorage(ref Init initializer)
if( variantDescriptors.Length > ShadowConstants.Counts.k_ShadowVariant )
m_ShadowDatas.Reserve(initializer.maxShadowDataSlots);
m_Payloads.Reserve(initializer.maxPayloadSlots);
m_Tex2DArray.Reserve(initializer.maxTex2DArraySlots);
m_TexCubeArray.Reserve(initializer.maxTexCubeArraySlots);
m_CompSamplers.Reserve(initializer.maxComparisonSamplerSlots);
m_Samplers.Reserve(initializer.maxSamplerSlots);
Debug.LogError( "Tried to register a shadow algorithm (" + algorithmDescriptor + ") with more than the valid amount of variants. Variant count: " + variantDescriptors.Length + ", valid count: " + ShadowConstants.Counts.k_ShadowVariant + "." );
return false;
// query functions to be used by the shadowmap
public uint RequestTex2DArraySlot() { return m_Tex2DArray.Add(new RenderTargetIdentifier()); }
public uint RequestTexCubeArraySlot() { return m_TexCubeArray.Add(new RenderTargetIdentifier()); }
public uint RequestSamplerSlot(SamplerState ss)
if( variantDescriptors.Length != variants.Length )
uint idx;
if (m_Samplers.FindFirst(out idx, ref ss))
return idx;
idx = m_Samplers.Count();
m_Samplers.Add(ss);
return idx;
Debug.LogError( "Tried to register a shadow algorithm (" + algorithmDescriptor + ") but the length of variant descriptors (" + variantDescriptors.Length + ") does not match the length of variants (" + variants.Length + ")." );
return false;
public uint RequestSamplerSlot(ComparisonSamplerState css)
if( variantDelegates.Length != variants.Length )
uint idx;
if (m_CompSamplers.FindFirst(out idx, ref css))
return idx;
idx = m_CompSamplers.Count();
m_CompSamplers.Add(css);
return idx;
Debug.LogError( "Tried to register a shadow algorithm (" + algorithmDescriptor + ") but the length of variant delegates (" + variantDelegates.Length + ") does not match the length of variants (" + variants.Length + ")." );
return false;
// setters called each frame on the shadowmap
public void SetTex2DArraySlot(uint slot, RenderTargetIdentifier val) { m_Tex2DArray[slot] = val; }
public void SetTexCubeArraySlot(uint slot, RenderTargetIdentifier val) { m_TexCubeArray[slot] = val; }
protected VectorArray<ShadowData> m_ShadowDatas = new VectorArray<ShadowData>(0, false);
protected VectorArray<ShadowPayload> m_Payloads = new VectorArray<ShadowPayload>(0, false);
protected VectorArray<RenderTargetIdentifier> m_Tex2DArray = new VectorArray<RenderTargetIdentifier>(0, true);
protected VectorArray<RenderTargetIdentifier> m_TexCubeArray = new VectorArray<RenderTargetIdentifier>(0, true);
protected VectorArray<ComparisonSamplerState> m_CompSamplers = new VectorArray<ComparisonSamplerState>(0, true);
protected VectorArray<SamplerState> m_Samplers = new VectorArray<SamplerState>(0, true);
return true;
// Class providing hooks to do the actual synchronization
public class ShadowContext : ShadowContextStorage
private void Register( Dictionary<ShadowAlgorithm, Entry> dict, ShadowPrecision precision, ShadowAlgorithm algorithm, string algorithmDescriptor, ShadowVariant[] variants, string[] variantDescriptors, VariantDelegate[] variantDelegates )
public delegate void SyncDel(ShadowContext sc);
public delegate void BindDel(ShadowContext sc, CommandBuffer cb);
public struct CtxtInit
if( !dict.ContainsKey( algorithm ) )
public Init storage;
public SyncDel dataSyncer;
public BindDel resourceBinder;
Entry e;
e.algorithmDesc = algorithmDescriptor;
e.variantsAvailable = variants.Length;
e.variantDescs = new string[ShadowConstants.Counts.k_ShadowVariant];
e.variantDels = new Dels[ShadowConstants.Counts.k_ShadowVariant];
for( uint i = 0, cnt = (uint) variants.Length; i < cnt; ++i )
{
e.variantDescs[(uint) variants[i]] = variantDescriptors[i];
if( precision == ShadowPrecision.Low )
e.variantDels[(uint) variants[i]].low = variantDelegates[i];
else
e.variantDels[(uint) variants[i]].high = variantDelegates[i];
}
dict.Add( algorithm, e );
public ShadowContext(ref CtxtInit initializer) : base(ref initializer.storage)
else
Debug.Assert(initializer.dataSyncer != null && initializer.resourceBinder != null);
m_DataSyncerDel = initializer.dataSyncer;
m_ResourceBinderDel = initializer.resourceBinder;
var entry = dict[algorithm];
for( uint i = 0, cnt = (uint) variants.Length; i < cnt; ++i )
{
if( string.IsNullOrEmpty( entry.variantDescs[(uint) variants[i]] ) )
{
entry.variantsAvailable++;
entry.variantDescs[(uint) variants[i]] = variantDescriptors[i];
entry.variantDels[(uint) variants[i]].low = precision == ShadowPrecision.Low ? variantDelegates[i] : null;
entry.variantDels[(uint) variants[i]].high = precision == ShadowPrecision.High ? variantDelegates[i] : null;
}
else if( precision == ShadowPrecision.Low && entry.variantDels[(uint)variants[i]].low == null )
{
entry.variantDels[(uint)variants[i]].low = variantDelegates[i];
}
else if( precision == ShadowPrecision.High && entry.variantDels[(uint)variants[i]].high == null )
{
entry.variantDels[(uint)variants[i]].high = variantDelegates[i];
}
else
Debug.Log( "Tried to register variant " + variants[i] + " for algorithm " + algorithm + " with precision " + precision + ", but this variant is already registered. Skipping registration." );
}
}
public void ClearData() { m_ShadowDatas.Reset(); m_Payloads.Reset(); }
// delegate that takes care of syncing data to the GPU
public void SyncData() { m_DataSyncerDel(this); }
// delegate that takes care of binding textures, buffers and samplers to shaders just before rendering
public void BindResources(CommandBuffer cb) { m_ResourceBinderDel(this, cb); }
public void Draw( Light l )
{
AdditionalLightData ald = l.GetComponent<AdditionalLightData>();
Debug.Assert(ald != null, "Light has no valid AdditionalLightData component attached.");
GPUShadowType shadowType;
ShadowUtils.MapLightType( ald.archetype, l.type, out shadowType );
// check if this has supported shadows
if( (int) shadowType >= ShadowConstants.Counts.k_GPUShadowType )
return;
int shadowAlgorithm;
int shadowVariant;
int shadowPrecision;
bool globalOverride = m_GlobalOverrides[(int)shadowType].enabled;
// the following functions are to be used by the bind and sync delegates
public void GetShadowDatas(out ShadowData[] shadowDatas, out uint offset, out uint count) { shadowDatas = m_ShadowDatas.AsArray(out offset, out count); }
public void GetPayloads(out ShadowPayload[] payloads, out uint offset, out uint count) { payloads = m_Payloads.AsArray(out offset, out count); }
public void GetTex2DArrays(out RenderTargetIdentifier[] tex2DArrays, out uint offset, out uint count) { tex2DArrays = m_Tex2DArray.AsArray(out offset, out count); }
public void GetTexCubeArrays(out RenderTargetIdentifier[] texCubeArrays, out uint offset, out uint count) { texCubeArrays = m_TexCubeArray.AsArray(out offset, out count); }
public void GetComparisonSamplerArrays(out ComparisonSamplerState[] compSamplers, out uint offset, out uint count) { compSamplers = m_CompSamplers.AsArray(out offset, out count); }
public void GetSamplerArrays(out SamplerState[] samplerArrays, out uint offset, out uint count) { samplerArrays = m_Samplers.AsArray(out offset, out count); }
if( globalOverride )
{
shadowAlgorithm = (int) m_GlobalOverrides[(int)shadowType].algorithm;
shadowVariant = (int) m_GlobalOverrides[(int)shadowType].variant;
shadowPrecision = (int) m_GlobalOverrides[(int)shadowType].precision;
}
else
ald.GetShadowAlgorithm( out shadowAlgorithm, out shadowVariant, out shadowPrecision );
private SyncDel m_DataSyncerDel;
private BindDel m_ResourceBinderDel;
DrawWidgets( l, shadowType, (ShadowAlgorithm) shadowAlgorithm, (ShadowVariant) shadowVariant, (ShadowPrecision) shadowPrecision, globalOverride );
// Abstract base class for handling shadow maps.
// Specific implementations managing atlases and the likes should inherit from this
abstract public class ShadowmapBase
void DrawWidgets( Light l, GPUShadowType shadowType, ShadowAlgorithm shadowAlgorithm, ShadowVariant shadowVariant, ShadowPrecision shadowPrecision, bool globalOverride )
[Flags]
public enum ShadowSupport
#if UNITY_EDITOR
var dict = m_Entries[(int)shadowType];
int[] algoOptions = new int[dict.Count];
GUIContent[] algoDescs = new GUIContent[dict.Count];
int idx = 0;
foreach( var entry in dict )
Point = 1 << GPUShadowType.Point,
Spot = 1 << GPUShadowType.Spot,
Directional = 1 << GPUShadowType.Directional
algoOptions[idx] = (int) entry.Key;
algoDescs[idx] = new GUIContent( entry.Value.algorithmDesc );
idx++;
public struct ShadowRequest
using (new UnityEditor.EditorGUI.DisabledGroupScope(globalOverride))
private const byte k_IndexBits = 24;
private const byte k_FaceBits = 32 - k_IndexBits;
private const uint k_MaxIndex = (1 << k_IndexBits) - 1;
private const byte k_MaxFace = (1 << k_FaceBits) - 1;
public const int k_MaxFaceCount = k_FaceBits;
UnityEditor.EditorGUI.BeginChangeCheck();
shadowAlgorithm = (ShadowAlgorithm) UnityEditor.EditorGUILayout.IntPopup( new GUIContent( "Shadow Algorithm" ), (int) shadowAlgorithm, algoDescs, algoOptions );
if( UnityEditor.EditorGUI.EndChangeCheck() )
shadowVariant = 0;
}
UnityEditor.EditorGUI.indentLevel++;
Entry e = dict[shadowAlgorithm];
int varsAvailable = e.variantsAvailable;
int[] varOptions = new int[varsAvailable];
GUIContent[] varDescs = new GUIContent[varsAvailable];
// combined face mask and visible light index
private uint m_MaskIndex;
// instance Id for this light
public int instanceId { get; set; }
// shadow type of this light
public GPUShadowType shadowType { get; set; }
// index into the visible lights array
public uint index
idx = 0;
for( int writeIdx = 0; writeIdx < varsAvailable; idx++ )
{
if( e.variantDels[idx].low != null || e.variantDels[idx].high != null )
get { return m_MaskIndex & k_MaxIndex; }
set { m_MaskIndex = value & k_MaxIndex; }
varOptions[writeIdx] = idx;
varDescs[writeIdx] = new GUIContent( e.variantDescs[idx] );
writeIdx++;
// mask of which faces are requested:
// - for spotlights the value is always 1
// - for point lights the bit positions map to the faces as listed in the CubemapFace enum
// - for directional lights the bit positions map to the individual cascades
public uint facemask
}
UnityEditor.EditorGUILayout.BeginHorizontal();
using( new UnityEditor.EditorGUI.DisabledGroupScope( globalOverride ) )
{
shadowVariant = (ShadowVariant) UnityEditor.EditorGUILayout.IntPopup( new GUIContent( "Variant + Precision" ), (int) shadowVariant, varDescs, varOptions );
if( e.variantDels[(int)shadowVariant].low != null && e.variantDels[(int)shadowVariant].high != null )
get { return (m_MaskIndex >> k_IndexBits) & k_MaxFace; }
set { m_MaskIndex = (m_MaskIndex & k_MaxIndex) | (value << k_IndexBits); }
GUIContent[] precDescs = new GUIContent[] { new GUIContent( "High" ), new GUIContent( "Low" ) };
int[] precOptions = new int[] { 0, 1 };
shadowPrecision = (ShadowPrecision)UnityEditor.EditorGUILayout.IntPopup((int)shadowPrecision, precDescs, precOptions, GUILayout.MaxWidth(65));
public uint facecount
else
get
using( new UnityEditor.EditorGUI.DisabledScope() )
uint fc = facemask;
uint count = 0;
while (fc != 0)
{
count += fc & 1;
fc >>= 1;
}
return count;
GUIContent[] precDescs = new GUIContent[] { new GUIContent( e.variantDels[(int)shadowVariant].low == null ? "High" : "Low" ) };
int[] precOptions = new int[] { e.variantDels[(int)shadowVariant].low == null ? 0 : 1 };
UnityEditor.EditorGUILayout.IntPopup(precOptions[0], precDescs, precOptions, GUILayout.MaxWidth(65));
shadowPrecision = (ShadowPrecision) precOptions[0];
AdditionalLightData ald = l.GetComponent<AdditionalLightData>();
GPUShadowAlgorithm packedAlgo = ShadowUtils.Pack( shadowAlgorithm, shadowVariant, shadowPrecision );
int[] shadowData = null;
if( !GUILayout.Button( "Reset", GUILayout.MaxWidth( 80.0f ) ) )
shadowData = ald.GetShadowData( (int) packedAlgo );
UnityEditor.EditorGUILayout.EndHorizontal();
if( shadowPrecision == ShadowPrecision.Low )
e.variantDels[(int) shadowVariant].low( l, shadowAlgorithm, shadowVariant, shadowPrecision, ref shadowData );
else
e.variantDels[(int) shadowVariant].high( l, shadowAlgorithm, shadowVariant, shadowPrecision, ref shadowData );
ald.SetShadowAlgorithm( (int) shadowAlgorithm, (int) shadowVariant, (int) shadowPrecision, (int) packedAlgo, shadowData );
protected readonly uint m_Width;
protected readonly uint m_Height;
protected readonly uint m_Slices;
protected readonly uint m_ShadowmapBits;
protected readonly RenderTextureFormat m_ShadowmapFormat;
protected readonly SamplerState m_SamplerState;
protected readonly ComparisonSamplerState m_CompSamplerState;
protected readonly Vector4 m_ClearColor;
protected readonly float m_WidthRcp;
protected readonly float m_HeightRcp;
protected readonly uint m_MaxPayloadCount;
protected readonly ShadowSupport m_ShadowSupport;
protected uint m_ShadowId;
protected CullResults m_CullResults;// TODO: Temporary, due to CullResults dependency in ShadowUtils' matrix extraction code. Remove this member once that dependency is gone.
UnityEditor.EditorGUI.indentLevel--;
#endif
}
public void SetGlobalShadowOverride( GPUShadowType shadowType, ShadowAlgorithm shadowAlgorithm, ShadowVariant shadowVariant, ShadowPrecision shadowPrecision, bool enable )
{
m_GlobalOverrides[(int)shadowType].enabled = enable;
m_GlobalOverrides[(int)shadowType].algorithm = shadowAlgorithm;
m_GlobalOverrides[(int)shadowType].variant = shadowVariant;
m_GlobalOverrides[(int)shadowType].precision = shadowPrecision;
}
void SetGlobalOverrideEnabled( GPUShadowType shadowType, bool enabled )
{
m_GlobalOverrides[(int)shadowType].enabled = enabled;
}
}
// This is the struct passed into shaders
[GenerateHLSL]
public struct ShadowData
{
// shadow texture related params (need to be set by ShadowmapBase and derivatives)
public Matrix4x4 worldToShadow; // to light space matrix
public Vector4 scaleOffset; // scale and offset of shadowmap in atlas
public Vector4 texelSizeRcp; // reciprocal of the shadowmap's texel size in x and y. xy is texture relative, zw is viewport relative.
public uint id; // packed texture id, sampler id and slice idx
public uint shadowType; // determines the shadow algorithm, i.e. which map to sample and how to interpret the data
public uint payloadOffset; // if this shadow type requires additional data it can be fetched from a global Buffer<uint> at payloadOffset.
// light related params (need to be set via ShadowMgr and derivatives)
public float bias; // bias setting
public float normalBias; // bias based on the normal
public void PackShadowmapId( uint texIdx, uint sampIdx, uint slice )
{
Debug.Assert( texIdx <= 0xff );
Debug.Assert( sampIdx <= 0xff );
Debug.Assert( slice <= 0xffff );
id = texIdx << 24 | sampIdx << 16 | slice;
}
public void PackShadowType( GPUShadowType type, GPUShadowAlgorithm algorithm )
{
shadowType = (uint)type << ShadowConstants.Bits.k_GPUShadowAlgorithm | (uint) algorithm;
}
};
public struct FrameId
{
public int frameCount;
public float deltaT;
}
// -------------- Begin temporary structs that need to be replaced at some point ---------------
public struct SamplerState
{
#pragma warning disable 414 // CS0414 The private field '...' is assigned but its value is never used
FilterMode filterMode;
TextureWrapMode wrapMode;
uint anisotropy;
#pragma warning restore 414
public static SamplerState Default()
{
SamplerState defaultState;
defaultState.filterMode = FilterMode.Bilinear;
defaultState.wrapMode = TextureWrapMode.Clamp;
defaultState.anisotropy = 1;
return defaultState;
}
// TODO: this should either contain the description for a sampler, or be replaced by a struct that does
public static bool operator ==( SamplerState lhs, SamplerState rhs )
{
return false; // TODO: Remove this once shared samplers are in
//return lhs.filterMode == rhs.filterMode && lhs.wrapMode == rhs.wrapMode && lhs.anisotropy == rhs.anisotropy;
}
public static bool operator !=( SamplerState lhs, SamplerState rhs ) { return !(lhs == rhs); }
public override bool Equals( object obj ) { return (obj is SamplerState) && (SamplerState) obj == this; }
public override int GetHashCode() { /* TODO: implement this at some point */ throw new NotImplementedException(); }
}
public struct ComparisonSamplerState
{
#pragma warning disable 414 // CS0414 The private field '...' is assigned but its value is never used
FilterMode filterMode;
TextureWrapMode wrapMode;
uint anisotropy;
#pragma warning restore 414
public static ComparisonSamplerState Default()
{
ComparisonSamplerState defaultState;
defaultState.filterMode = FilterMode.Bilinear;
defaultState.wrapMode = TextureWrapMode.Clamp;
defaultState.anisotropy = 1;
return defaultState;
}
// TODO: this should either contain the description for a comparison sampler, or be replaced by a struct that does
public static bool operator ==(ComparisonSamplerState lhs, ComparisonSamplerState rhs)
{
return false;
//return lhs.filterMode == rhs.filterMode && lhs.wrapMode == rhs.wrapMode && lhs.anisotropy == rhs.anisotropy;
}
public static bool operator !=(ComparisonSamplerState lhs, ComparisonSamplerState rhs) { return !(lhs == rhs); }
public override bool Equals( object obj ) { return (obj is ComparisonSamplerState) && (ComparisonSamplerState) obj == this; }
public override int GetHashCode() { /* TODO: implement this at some point */ throw new NotImplementedException(); }
}
// -------------- End temporary structs that need to be replaced at some point ---------------
// Helper struct for passing arbitrary data into shaders. Entry size is 4 ints to minimize load instructions
// in shaders. This should really be int p[4] but C# doesn't let us do that.
public struct ShadowPayload
{
public int p0;
public int p1;
public int p2;
public int p3;
public void Set( float v0, float v1, float v2, float v3 )
{
p0 = ShadowUtils.Asint( v0 );
p1 = ShadowUtils.Asint( v1 );
p2 = ShadowUtils.Asint( v2 );
p3 = ShadowUtils.Asint( v3 );
}
public void Set( int v0, int v1, int v2, int v3 )
{
p0 = v0;
p1 = v1;
p2 = v2;
p3 = v3;
}
public struct BaseInit
{
public uint width; // width of the shadowmap
public uint height; // height of the shadowmap
public uint slices; // slices for the shadowmap
public uint shadowmapBits; // bit depth for native shadowmaps, or bitdepth for the temporary shadowmap if the shadowmapFormat is not native
public RenderTextureFormat shadowmapFormat; // texture format of the shadowmap
public SamplerState samplerState; // the desired sampler state for non-native shadowmaps
public ComparisonSamplerState comparisonSamplerState; // the desired sampler state for native shadowmaps doing depth comparisons as well
public Vector4 clearColor; // the clear color used for non-native shadowmaps
public uint maxPayloadCount; // how many ints will be pushed into the payload buffer for each invocation of Reserve
public ShadowSupport shadowSupport; // bitmask of all shadow types that this shadowmap supports
};
public void Set( Vector4 v ) { Set( v.x, v.y, v.z, v.w ); }
}
// Class holding resource information that needs to be synchronized with shaders.
public class ShadowContextStorage
{
public struct Init
{
public uint maxShadowDataSlots;
public uint maxPayloadSlots;
public uint maxTex2DArraySlots;
public uint maxTexCubeArraySlots;
public uint maxComparisonSamplerSlots;
public uint maxSamplerSlots;
}
protected ShadowContextStorage( ref Init initializer )
{
m_ShadowDatas.Reserve( initializer.maxShadowDataSlots );
m_Payloads.Reserve( initializer.maxPayloadSlots );
m_Tex2DArray.Reserve( initializer.maxTex2DArraySlots );
m_TexCubeArray.Reserve( initializer.maxTexCubeArraySlots );
m_CompSamplers.Reserve( initializer.maxComparisonSamplerSlots );
m_Samplers.Reserve( initializer.maxSamplerSlots );
}
// query functions to be used by the shadowmap
public uint RequestTex2DArraySlot() { return m_Tex2DArray.Add( new RenderTargetIdentifier() ); }
public uint RequestTexCubeArraySlot() { return m_TexCubeArray.Add( new RenderTargetIdentifier() ); }
public uint RequestSamplerSlot( SamplerState ss )
{
uint idx;
if( m_Samplers.FindFirst( out idx, ref ss ) )
return idx;
idx = m_Samplers.Count();
m_Samplers.Add( ss );
return idx;
}
public uint RequestSamplerSlot( ComparisonSamplerState css )
{
uint idx;
if( m_CompSamplers.FindFirst( out idx, ref css ) )
return idx;
idx = m_CompSamplers.Count();
m_CompSamplers.Add( css );
return idx;
}
// setters called each frame on the shadowmap
public void SetTex2DArraySlot( uint slot, RenderTargetIdentifier val ) { m_Tex2DArray[slot] = val; }
public void SetTexCubeArraySlot( uint slot, RenderTargetIdentifier val ) { m_TexCubeArray[slot] = val; }
protected ShadowmapBase(ref BaseInit initializer)
{
m_Width = initializer.width;
m_Height = initializer.height;
m_Slices = initializer.slices;
m_ShadowmapBits = initializer.shadowmapBits;
m_ShadowmapFormat = initializer.shadowmapFormat;
m_SamplerState = initializer.samplerState;
m_CompSamplerState = initializer.comparisonSamplerState;
m_ClearColor = initializer.clearColor;
m_WidthRcp = 1.0f / initializer.width;
m_HeightRcp = 1.0f / initializer.height;
m_MaxPayloadCount = initializer.maxPayloadCount;
m_ShadowSupport = initializer.shadowSupport;
m_ShadowId = 0;
protected VectorArray<ShadowData> m_ShadowDatas = new VectorArray<ShadowData>( 0, false );
protected VectorArray<ShadowPayload> m_Payloads = new VectorArray<ShadowPayload>( 0, false );
protected VectorArray<RenderTargetIdentifier> m_Tex2DArray = new VectorArray<RenderTargetIdentifier>( 0, true );
protected VectorArray<RenderTargetIdentifier> m_TexCubeArray = new VectorArray<RenderTargetIdentifier>( 0, true );
protected VectorArray<ComparisonSamplerState> m_CompSamplers = new VectorArray<ComparisonSamplerState>( 0, true );
protected VectorArray<SamplerState> m_Samplers = new VectorArray<SamplerState>( 0, true );
}
if (IsNativeDepth() && m_Slices > 1)
// Class providing hooks to do the actual synchronization
public class ShadowContext : ShadowContextStorage
{
public delegate void SyncDel( ShadowContext sc );
public delegate void BindDel( ShadowContext sc, CommandBuffer cb );
public struct CtxtInit
{
public Init storage;
public SyncDel dataSyncer;
public BindDel resourceBinder;
}
public ShadowContext( ref CtxtInit initializer ) : base( ref initializer.storage )
{
Debug.Assert( initializer.dataSyncer != null && initializer.resourceBinder != null );
m_DataSyncerDel = initializer.dataSyncer;
m_ResourceBinderDel = initializer.resourceBinder;
}
public void ClearData() { m_ShadowDatas.Reset(); m_Payloads.Reset(); }
// delegate that takes care of syncing data to the GPU
public void SyncData() { m_DataSyncerDel( this ); }
// delegate that takes care of binding textures, buffers and samplers to shaders just before rendering
public void BindResources( CommandBuffer cb ) { m_ResourceBinderDel( this, cb ); }
// the following functions are to be used by the bind and sync delegates
public void GetShadowDatas( out ShadowData[] shadowDatas, out uint offset, out uint count ) { shadowDatas = m_ShadowDatas.AsArray( out offset, out count ); }
public void GetPayloads( out ShadowPayload[] payloads, out uint offset, out uint count ) { payloads = m_Payloads.AsArray( out offset, out count ); }
public void GetTex2DArrays( out RenderTargetIdentifier[] tex2DArrays, out uint offset, out uint count ) { tex2DArrays = m_Tex2DArray.AsArray( out offset, out count ); }
public void GetTexCubeArrays( out RenderTargetIdentifier[] texCubeArrays, out uint offset, out uint count ) { texCubeArrays = m_TexCubeArray.AsArray( out offset, out count ); }
public void GetComparisonSamplerArrays( out ComparisonSamplerState[] compSamplers, out uint offset, out uint count ) { compSamplers = m_CompSamplers.AsArray( out offset, out count ); }
public void GetSamplerArrays( out SamplerState[] samplerArrays, out uint offset, out uint count ) { samplerArrays = m_Samplers.AsArray( out offset, out count ); }
private SyncDel m_DataSyncerDel;
private BindDel m_ResourceBinderDel;
}
// Abstract base class for handling shadow maps.
// Specific implementations managing atlases and the likes should inherit from this
abstract public class ShadowmapBase
{
[Flags]
public enum ShadowSupport
{
Point = 1 << GPUShadowType.Point,
Spot = 1 << GPUShadowType.Spot,
Directional = 1 << GPUShadowType.Directional
}
public struct ShadowRequest
{
private const byte k_IndexBits = 24;
private const byte k_FaceBits = 32 - k_IndexBits;
private const uint k_MaxIndex = (1 << k_IndexBits) - 1;
private const byte k_MaxFace = (1 << k_FaceBits) - 1;
public const int k_MaxFaceCount = k_FaceBits;
// combined face mask and visible light index
private uint m_MaskIndex;
private int m_ShadowTypeAndAlgorithm;
// instance Id for this light
public int instanceId { get; set; }
// shadow type of this light
public GPUShadowType shadowType
{
get { return (GPUShadowType) (m_ShadowTypeAndAlgorithm >> ShadowConstants.Bits.k_GPUShadowAlgorithm); }
set { m_ShadowTypeAndAlgorithm = ((int)value << ShadowConstants.Bits.k_GPUShadowAlgorithm) | (m_ShadowTypeAndAlgorithm & ShadowConstants.Masks.k_GPUShadowAlgorithm); }
}
public GPUShadowAlgorithm shadowAlgorithm
{
get { return (GPUShadowAlgorithm) (m_ShadowTypeAndAlgorithm & ShadowConstants.Masks.k_GPUShadowAlgorithm); }
set { m_ShadowTypeAndAlgorithm = (m_ShadowTypeAndAlgorithm & ~(ShadowConstants.Masks.k_GPUShadowAlgorithm)) | (int)value; }
}
// index into the visible lights array
public uint index
{
get { return m_MaskIndex & k_MaxIndex; }
set { m_MaskIndex = value & k_MaxIndex; }
}
// mask of which faces are requested:
// - for spotlights the value is always 1
// - for point lights the bit positions map to the faces as listed in the CubemapFace enum
// - for directional lights the bit positions map to the individual cascades
public uint facemask
{
get { return (m_MaskIndex >> k_IndexBits) & k_MaxFace; }
set { m_MaskIndex = (m_MaskIndex & k_MaxIndex) | (value << k_IndexBits); }
}
public uint facecount
{
get
// TODO: Right now when using any of the SetRendertarget functions we ultimately end up in RenderTextureD3D11.cpp
// SetRenderTargetD3D11Internal. This function sets the correct slice only for RTVs, whereas depth textures only
// support one DSV. So there's currently no way to have individual DSVs per slice to render into (ignoring going through a geometry shader and selecting the slice there).
Debug.LogError("Unity does not allow direct rendering into specific depth slices, yet. Defaulting back to one array slice.");
m_Slices = 1;
uint fc = facemask;
uint count = 0;
while (fc != 0)
{
count += fc & 1;
fc >>= 1;
}
return count;
}
protected bool IsNativeDepth()
protected readonly uint m_Width;
protected readonly uint m_Height;
protected readonly uint m_Slices;
protected readonly uint m_ShadowmapBits;
protected readonly RenderTextureFormat m_ShadowmapFormat;
protected readonly SamplerState m_SamplerState;
protected readonly ComparisonSamplerState m_CompSamplerState;
protected readonly Vector4 m_ClearColor;
protected readonly float m_WidthRcp;
protected readonly float m_HeightRcp;
protected readonly uint m_MaxPayloadCount;
protected readonly ShadowSupport m_ShadowSupport;
protected CullResults m_CullResults; // TODO: Temporary, due to CullResults dependency in ShadowUtils' matrix extraction code. Remove this member once that dependency is gone.
public struct BaseInit
{
public uint width; // width of the shadowmap
public uint height; // height of the shadowmap
public uint slices; // slices for the shadowmap
public uint shadowmapBits; // bit depth for native shadowmaps, or bitdepth for the temporary shadowmap if the shadowmapFormat is not native
public RenderTextureFormat shadowmapFormat; // texture format of the shadowmap
public SamplerState samplerState; // the desired sampler state for non-native shadowmaps
public ComparisonSamplerState comparisonSamplerState; // the desired sampler state for native shadowmaps doing depth comparisons as well
public Vector4 clearColor; // the clear color used for non-native shadowmaps
public uint maxPayloadCount; // how many ints will be pushed into the payload buffer for each invocation of Reserve
public ShadowSupport shadowSupport; // bitmask of all shadow types that this shadowmap supports
};
protected ShadowmapBase( ref BaseInit initializer )
{
m_Width = initializer.width;
m_Height = initializer.height;
m_Slices = initializer.slices;
m_ShadowmapBits = initializer.shadowmapBits;
m_ShadowmapFormat = initializer.shadowmapFormat;
m_SamplerState = initializer.samplerState;
m_CompSamplerState = initializer.comparisonSamplerState;
m_ClearColor = initializer.clearColor;
m_WidthRcp = 1.0f / initializer.width;
m_HeightRcp = 1.0f / initializer.height;
m_MaxPayloadCount = initializer.maxPayloadCount;
m_ShadowSupport = initializer.shadowSupport;
if( IsNativeDepth() && m_Slices > 1 )
return m_ShadowmapFormat == RenderTextureFormat.Shadowmap || m_ShadowmapFormat == RenderTextureFormat.Depth;
// TODO: Right now when using any of the SetRendertarget functions we ultimately end up in RenderTextureD3D11.cpp
// SetRenderTargetD3D11Internal. This function sets the correct slice only for RTVs, whereas depth textures only
// support one DSV. So there's currently no way to have individual DSVs per slice to render into (ignoring going through a geometry shader and selecting the slice there).
Debug.LogError( "Unity does not allow direct rendering into specific depth slices, yet. Defaulting back to one array slice." );
m_Slices = 1;
public ShadowSupport QueryShadowSupport() { return m_ShadowSupport; }
public uint GetMaxPayload() { return m_MaxPayloadCount; }
public void AssignId(uint shadowId) { m_ShadowId = shadowId; }
public void Assign(CullResults cullResults) { m_CullResults = cullResults; } // TODO: Remove when m_CullResults is removed again
abstract public bool Reserve(FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, VisibleLight[] lights);
abstract public bool Reserve(FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, VisibleLight[] lights);
abstract public bool ReserveFinalize(FrameId frameId, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads);
abstract public void Update(FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights);
abstract public void ReserveSlots(ShadowContextStorage sc);
abstract public void Fill(ShadowContextStorage cs);
interface IShadowManager
protected bool IsNativeDepth()
// Warning: The shadowRequests array and shadowRequestsCount are modified by this function.
// When called the array contains the indices of lights requesting shadows,
// upon returning the array contains up to shadowRequestsCount valid shadow caster indices,
// whereas [shadowRequestsCount;originalRequestsCount) will hold all indices for lights that wanted to cast a shadow but got rejected.
// shadowDataIndices contains the offset into the shadowDatas array only for each shadow casting light, e.g. lights[shadowRequests[i]].shadowDataOffset = shadowDataIndices[i];
// shadowDatas contains shadowmap related basic parameters that can be passed to the shader.
// shadowPayloads contains implementation specific data that is accessed from the shader by indexing into an Buffer<int> using ShadowData.ShadowmapData.payloadOffset.
// This is the equivalent of a void pointer in the shader and there needs to be loader code that knows how to interpret the data.
// If there are no valid shadow casters all output arrays will be null, otherwise they will contain valid data that can be passed to shaders.
void ProcessShadowRequests(FrameId frameId, CullResults cullResults, Camera camera, VisibleLight[] lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices);
// Renders all shadows for lights the were deemed shadow casters after the last call to ProcessShadowRequests
void RenderShadows(FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights);
// Synchronize data with GPU buffers
void SyncData();
// Binds resources to shader stages just before rendering the lighting pass
void BindResources(ScriptableRenderContext renderContext);
return m_ShadowmapFormat == RenderTextureFormat.Shadowmap || m_ShadowmapFormat == RenderTextureFormat.Depth;
abstract public class ShadowManagerBase : IShadowManager
public void Register( ShadowRegistry registry )
public abstract void ProcessShadowRequests(FrameId frameId, CullResults cullResults, Camera camera, VisibleLight[] lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices);
public abstract void RenderShadows(FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights);
public abstract void SyncData();
public abstract void BindResources(ScriptableRenderContext renderContext);
// sort the shadow requests in descending priority - may only modify shadowRequests
protected abstract void PrioritizeShadowCasters(Camera camera, VisibleLight[] lights, uint shadowRequestsCount, int[] shadowRequests);
// prune the shadow requests - may modify shadowRequests and shadowsCountshadowRequestsCount
protected abstract void PruneShadowCasters(Camera camera, VisibleLight[] lights, ref VectorArray<int> shadowRequests, ref VectorArray<ShadowmapBase.ShadowRequest> requestsGranted, out uint totalRequestCount);
// allocate the shadow requests in the shadow map, only is called if shadowsCount > 0 - may modify shadowRequests and shadowsCount
protected abstract void AllocateShadows(FrameId frameId, VisibleLight[] lights, uint totalGranted, ref VectorArray<ShadowmapBase.ShadowRequest> grantedRequests, ref VectorArray<int> shadowIndices, ref VectorArray<ShadowData> shadowmapDatas, ref VectorArray<ShadowPayload> shadowmapPayload);
int bit = 1;
for( GPUShadowType i = GPUShadowType.Point; i < GPUShadowType.MAX; ++i, bit <<= 1 )
{
if( ((int)m_ShadowSupport & bit) != 0 )
Register( i, registry );
}
} // end of namespace ShadowExp
public ShadowSupport QueryShadowSupport() { return m_ShadowSupport; }
public uint GetMaxPayload() { return m_MaxPayloadCount; }
public void Assign( CullResults cullResults ) { m_CullResults = cullResults; } // TODO: Remove when m_CullResults is removed again
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, VisibleLight[] lights );
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, VisibleLight[] lights );
abstract public bool ReserveFinalize( FrameId frameId, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads );
abstract public void Update( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights );
abstract public void ReserveSlots( ShadowContextStorage sc );
abstract public void Fill( ShadowContextStorage cs );
abstract protected void Register( GPUShadowType type, ShadowRegistry registry );
}
interface IShadowManager
{
// Warning: The shadowRequests array and shadowRequestsCount are modified by this function.
// When called the array contains the indices of lights requesting shadows,
// upon returning the array contains up to shadowRequestsCount valid shadow caster indices,
// whereas [shadowRequestsCount;originalRequestsCount) will hold all indices for lights that wanted to cast a shadow but got rejected.
// shadowDataIndices contains the offset into the shadowDatas array only for each shadow casting light, e.g. lights[shadowRequests[i]].shadowDataOffset = shadowDataIndices[i];
// shadowDatas contains shadowmap related basic parameters that can be passed to the shader.
// shadowPayloads contains implementation specific data that is accessed from the shader by indexing into an Buffer<int> using ShadowData.ShadowmapData.payloadOffset.
// This is the equivalent of a void pointer in the shader and there needs to be loader code that knows how to interpret the data.
// If there are no valid shadow casters all output arrays will be null, otherwise they will contain valid data that can be passed to shaders.
void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, VisibleLight[] lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
// Renders all shadows for lights the were deemed shadow casters after the last call to ProcessShadowRequests
void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights );
// Synchronize data with GPU buffers
void SyncData();
// Binds resources to shader stages just before rendering the lighting pass
void BindResources( ScriptableRenderContext renderContext );
// Fixes up some parameters within the cullResults
void UpdateCullingParameters( ref CullingParameters cullingParams );
}
abstract public class ShadowManagerBase : ShadowRegistry, IShadowManager
{
public abstract void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, VisibleLight[] lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
public abstract void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CullResults cullResults, VisibleLight[] lights );
public abstract void SyncData();
public abstract void BindResources( ScriptableRenderContext renderContext );
public abstract void UpdateCullingParameters( ref CullingParameters cullingParams );
// sort the shadow requests in descending priority - may only modify shadowRequests
protected abstract void PrioritizeShadowCasters( Camera camera, VisibleLight[] lights, uint shadowRequestsCount, int[] shadowRequests );
// prune the shadow requests - may modify shadowRequests and shadowsCountshadowRequestsCount
protected abstract void PruneShadowCasters( Camera camera, VisibleLight[] lights, ref VectorArray<int> shadowRequests, ref VectorArray<ShadowmapBase.ShadowRequest> requestsGranted, out uint totalRequestCount );
// allocate the shadow requests in the shadow map, only is called if shadowsCount > 0 - may modify shadowRequests and shadowsCount
protected abstract void AllocateShadows( FrameId frameId, VisibleLight[] lights, uint totalGranted, ref VectorArray<ShadowmapBase.ShadowRequest> grantedRequests, ref VectorArray<int> shadowIndices, ref VectorArray<ShadowData> shadowmapDatas, ref VectorArray<ShadowPayload> shadowmapPayload );
}
} // end of namespace UnityEngine.Experimental.ScriptableRenderLoop

49
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl


// This can be custom for each project and needs to be in sync with the ShadowMgr
#define SHADOWCONTEXT_MAX_TEX2DARRAY 2
#define SHADOWCONTEXT_MAX_TEXCUBEARRAY 1
#define SHADOWCONTEXT_MAX_SAMPLER 1
#define SHADOWCONTEXT_MAX_COMPSAMPLER 2
#define SHADOWCONTEXT_MAX_TEX2DARRAY 4
#define SHADOWCONTEXT_MAX_TEXCUBEARRAY 0
#define SHADOWCONTEXT_MAX_SAMPLER 3
#define SHADOWCONTEXT_MAX_COMPSAMPLER 1
StructuredBuffer<ShadowData> _ShadowDatasExp;
StructuredBuffer<int4> _ShadowPayloads;
TEXTURE2D_ARRAY(_ShadowmapExp_Dir);
SAMPLER2D_SHADOW(sampler_ShadowmapExp_Dir);
TEXTURE2D_ARRAY(_ShadowmapExp_PointSpot);
SAMPLER2D_SHADOW(sampler_ShadowmapExp_PointSpot);
TEXTURE2D_ARRAY(_ShadowmapExp_VSM_0);
SAMPLER2D(sampler_ShadowmapExp_VSM_0);
TEXTURE2D_ARRAY(_ShadowmapExp_VSM_1);
SAMPLER2D(sampler_ShadowmapExp_VSM_1);
TEXTURE2D_ARRAY(_ShadowmapExp_VSM_2);
SAMPLER2D(sampler_ShadowmapExp_VSM_2);
TEXTURE2D_ARRAY(_ShadowmapExp_PCF);
SAMPLER2D_SHADOW(sampler_ShadowmapExp_PCF);
StructuredBuffer<ShadowData> _ShadowDatasExp;
StructuredBuffer<int4> _ShadowPayloads;
ShadowContext sc;
sc.shadowDatas = _ShadowDatasExp;
sc.payloads = _ShadowPayloads;
sc.tex2DArray[0] = _ShadowmapExp_Dir;
sc.tex2DArray[1] = _ShadowmapExp_PointSpot;
sc.compSamplers[0] = sampler_ShadowmapExp_Dir;
sc.compSamplers[1] = sampler_ShadowmapExp_PointSpot;
return sc;
ShadowContext sc;
sc.shadowDatas = _ShadowDatasExp;
sc.payloads = _ShadowPayloads;
sc.tex2DArray[0] = _ShadowmapExp_VSM_0;
sc.tex2DArray[1] = _ShadowmapExp_VSM_1;
sc.tex2DArray[2] = _ShadowmapExp_VSM_2;
sc.tex2DArray[3] = _ShadowmapExp_PCF;
sc.samplers[0] = sampler_ShadowmapExp_VSM_0;
sc.samplers[1] = sampler_ShadowmapExp_VSM_1;
sc.samplers[2] = sampler_ShadowmapExp_VSM_2;
sc.compSamplers[0] = sampler_ShadowmapExp_PCF;
return sc;

115
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl


// This file is empty by default.
// Project specific file to override the default shadow sampling routines.
// We need to define which dispatchers we're overriding, otherwise the compiler will pick default implementations which will lead to compile errors.
// We need to define which dispatchers we're overriding, otherwise the compiler will pick default implementations which will lead to compilation errors.
// This is an example of how to override the default dynamic resource dispatcher
// by hardcoding the resources used and calling the shadow sampling routines that take an explicit texture and sampler.
// It is the responsibility of the author to make sure that ShadowContext.hlsl binds the correct texture to the right slot,
// and that on the C# side the shadowContext bindDelegate binds the correct resource to the correct texture id.
#define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL // enables hardcoded resources and algorithm for directional lights
#define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL // enables hardcoded resources and algorithm for punctual lights
//#define SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS // enables separate resources and algorithms for spot and point lights
// directional
#define SHADOW_DISPATCH_DIR_TEX 3
#define SHADOW_DISPATCH_DIR_SMP 0
#define SHADOW_DISPATCH_DIR_ALG GPUSHADOWALGORITHM_PCF_TENT_7X7
// point
#define SHADOW_DISPATCH_POINT_TEX 3
#define SHADOW_DISPATCH_POINT_SMP 0
#define SHADOW_DISPATCH_POINT_ALG GPUSHADOWALGORITHM_PCF_1TAP
// spot
#define SHADOW_DISPATCH_SPOT_TEX 3
#define SHADOW_DISPATCH_SPOT_SMP 0
#define SHADOW_DISPATCH_SPOT_ALG GPUSHADOWALGORITHM_PCF_9TAP
//punctual
#define SHADOW_DISPATCH_PUNC_TEX 3
#define SHADOW_DISPATCH_PUNC_SMP 0
#define SHADOW_DISPATCH_PUNC_ALG GPUSHADOWALGORITHM_PCF_TENT_7X7
//#define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L )
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
Texture2DArray tex = shadowContext.tex2DArray[0];
SamplerComparisonState compSamp = shadowContext.compSamplers[0];
Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_DIR_TEX];
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_DIR_SMP];
uint algo = SHADOW_DISPATCH_DIR_ALG;
return EvalShadow_CascadedDepth( shadowContext, tex, compSamp, positionWS, shadowDataIndex, L );
//return EvalShadow_CascadedMomentum( shadowContext, positionWS, shadowDataIndex, L );
return EvalShadow_CascadedDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
Texture2DArray tex = shadowContext.tex2DArray[0];
SamplerComparisonState compSamp = shadowContext.compSamplers[0];
return EvalShadow_CascadedDepth( shadowContext, tex, compSamp, positionWS, shadowDataIndex, L );
//return EvalShadow_CascadedMomentum( shadowContext, positionWS, shadowDataIndex, L );
return GetDirectionalShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
// This is an example of how to override the default dynamic resource dispatcher
// by hardcoding the resources used and calling the shadow sampling routines that take an explicit texture and sampler.
// It is the responsibility of the author to make sure that ShadowContext.hlsl binds the correct texture to the right slot,
// and that on the C# side the shadowContext bindDelegate binds the correct resource to the correct texture id.
//#define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
// example of overriding punctual lights
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
Texture2DArray tex = shadowContext.tex2DArray[1];
SamplerComparisonState compSamp = shadowContext.compSamplers[1];
#ifdef SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS
// example for choosing different algos for point and spot lights
ShadowData sd = shadowContext.shadowDatas[shadowDataIndex];
uint shadowType;
UnpackShadowType( sd.shadowType, shadowType );
return EvalShadow_PunctualDepth( shadowContext, tex, compSamp, positionWS, shadowDataIndex, L );
[branch]
if( shadowType == GPUSHADOWTYPE_POINT )
{
Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_POINT_TEX];
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_POINT_SMP];
uint algo = SHADOW_DISPATCH_POINT_ALG;
return EvalShadow_PointDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
}
else
{
Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_SPOT_TEX];
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_SPOT_SMP];
uint algo = SHADOW_DISPATCH_SPOT_ALG;
return EvalShadow_SpotDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
}
#else
// example for choosing the same algo
Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_PUNC_TEX];
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_PUNC_SMP];
uint algo = SHADOW_DISPATCH_PUNC_ALG;
return EvalShadow_PunctualDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
#endif
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, int shadowDataIndex, float3 L, float2 unPositionSS )
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
Texture2DArray tex = shadowContext.tex2DArray[1];
SamplerComparisonState compSamp = shadowContext.compSamplers[1];
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}
#endif
return EvalShadow_PunctualDepth( shadowContext, tex, compSamp, positionWS, shadowDataIndex, L );
}
// cleanup the defines
#undef SHADOW_DISPATCH_DIR_TEX
#undef SHADOW_DISPATCH_DIR_SMP
#undef SHADOW_DISPATCH_DIR_ALG
#undef SHADOW_DISPATCH_POINT_TEX
#undef SHADOW_DISPATCH_POINT_SMP
#undef SHADOW_DISPATCH_POINT_ALG
#undef SHADOW_DISPATCH_SPOT_TEX
#undef SHADOW_DISPATCH_SPOT_SMP
#undef SHADOW_DISPATCH_SPOT_ALG
#undef SHADOW_DISPATCH_PUNC_TEX
#undef SHADOW_DISPATCH_PUNC_SMP
#undef SHADOW_DISPATCH_PUNC_ALG
#ifdef SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS
#undef SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS
#endif

746
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl


// Various shadow sampling logic.
// Again two versions, one for dynamic resource indexing, one for static resource access.
// ------------------------------------------------------------------
// PCF Filtering helpers
// ------------------------------------------------------------------
// Assuming a isoceles right angled triangle of height "triangleHeight" (as drawn below).
// This function return the area of the triangle above the first texel.
// 1 tap PCF sampling
// |\ <-- 45 degree slop isosceles right angled triangle
// | \
// ---- <-- length of this side is "triangleHeight"
// _ _ _ _ <-- texels
float SampleShadow_GetTriangleTexelArea(float triangleHeight)
{
return triangleHeight - 0.5;
}
// Assuming a isoceles triangle of 1.5 texels height and 3 texels wide lying on 4 texels.
// This function return the area of the triangle above each of those texels.
// | <-- offset from -0.5 to 0.5, 0 meaning triangle is exactly in the center
// / \ <-- 45 degree slop isosceles triangle (ie tent projected in 2D)
// / \
// _ _ _ _ <-- texels
// X Y Z W <-- result indices (in computedArea.xyzw and computedAreaUncut.xyzw)
void SampleShadow_GetTexelAreas_Tent_3x3(float offset, out float4 computedArea, out float4 computedAreaUncut)
{
// Compute the exterior areas
float offset01SquaredHalved = (offset + 0.5) * (offset + 0.5) * 0.5;
computedAreaUncut.x = computedArea.x = offset01SquaredHalved - offset;
computedAreaUncut.w = computedArea.w = offset01SquaredHalved;
// Compute the middle areas
// For Y : We find the area in Y of as if the left section of the isoceles triangle would
// intersect the axis between Y and Z (ie where offset = 0).
computedAreaUncut.y = SampleShadow_GetTriangleTexelArea(1.5 - offset);
// This area is superior to the one we are looking for if (offset < 0) thus we need to
// subtract the area of the triangle defined by (0,1.5-offset), (0,1.5+offset), (-offset,1.5).
float clampedOffsetLeft = min(offset,0);
float areaOfSmallLeftTriangle = clampedOffsetLeft * clampedOffsetLeft;
computedArea.y = computedAreaUncut.y - areaOfSmallLeftTriangle;
// We do the same for the Z but with the right part of the isoceles triangle
computedAreaUncut.z = SampleShadow_GetTriangleTexelArea(1.5 + offset);
float clampedOffsetRight = max(offset,0);
float areaOfSmallRightTriangle = clampedOffsetRight * clampedOffsetRight;
computedArea.z = computedAreaUncut.z - areaOfSmallRightTriangle;
}
// Assuming a isoceles triangle of 1.5 texels height and 3 texels wide lying on 4 texels.
// This function return the weight of each texels area relative to the full triangle area.
void SampleShadow_GetTexelWeights_Tent_3x3(float offset, out float4 computedWeight)
{
float4 dummy;
SampleShadow_GetTexelAreas_Tent_3x3(offset, computedWeight, dummy);
computedWeight *= 0.44444;//0.44 == 1/(the triangle area)
}
// Assuming a isoceles triangle of 2.5 texel height and 5 texels wide lying on 6 texels.
// This function return the weight of each texels area relative to the full triangle area.
// / \
// _ _ _ _ _ _ <-- texels
// 0 1 2 3 4 5 <-- computed area indices (in texelsWeights[])
void SampleShadow_GetTexelWeights_Tent_5x5(float offset, out float3 texelsWeightsA, out float3 texelsWeightsB)
{
// See _UnityInternalGetAreaPerTexel_3TexelTriangleFilter for details.
float4 computedArea_From3texelTriangle;
float4 computedAreaUncut_From3texelTriangle;
SampleShadow_GetTexelAreas_Tent_3x3(offset, computedArea_From3texelTriangle, computedAreaUncut_From3texelTriangle);
// Triangle slope is 45 degree thus we can almost reuse the result of the 3 texel wide computation.
// the 5 texel wide triangle can be seen as the 3 texel wide one but shifted up by one unit/texel.
// 0.16 is 1/(the triangle area)
texelsWeightsA.x = 0.16 * (computedArea_From3texelTriangle.x);
texelsWeightsA.y = 0.16 * (computedAreaUncut_From3texelTriangle.y);
texelsWeightsA.z = 0.16 * (computedArea_From3texelTriangle.y + 1);
texelsWeightsB.x = 0.16 * (computedArea_From3texelTriangle.z + 1);
texelsWeightsB.y = 0.16 * (computedAreaUncut_From3texelTriangle.z);
texelsWeightsB.z = 0.16 * (computedArea_From3texelTriangle.w);
}
// Assuming a isoceles triangle of 3.5 texel height and 7 texels wide lying on 8 texels.
// This function return the weight of each texels area relative to the full triangle area.
// / \
// _ _ _ _ _ _ _ _ <-- texels
// 0 1 2 3 4 5 6 7 <-- computed area indices (in texelsWeights[])
void SampleShadow_GetTexelWeights_Tent_7x7(float offset, out float4 texelsWeightsA, out float4 texelsWeightsB)
{
// See _UnityInternalGetAreaPerTexel_3TexelTriangleFilter for details.
float4 computedArea_From3texelTriangle;
float4 computedAreaUncut_From3texelTriangle;
SampleShadow_GetTexelAreas_Tent_3x3(offset, computedArea_From3texelTriangle, computedAreaUncut_From3texelTriangle);
// Triangle slope is 45 degree thus we can almost reuse the result of the 3 texel wide computation.
// the 7 texel wide triangle can be seen as the 3 texel wide one but shifted up by two unit/texel.
// 0.081632 is 1/(the triangle area)
texelsWeightsA.x = 0.081632 * (computedArea_From3texelTriangle.x);
texelsWeightsA.y = 0.081632 * (computedAreaUncut_From3texelTriangle.y);
texelsWeightsA.z = 0.081632 * (computedAreaUncut_From3texelTriangle.y + 1);
texelsWeightsA.w = 0.081632 * (computedArea_From3texelTriangle.y + 2);
texelsWeightsB.x = 0.081632 * (computedArea_From3texelTriangle.z + 2);
texelsWeightsB.y = 0.081632 * (computedAreaUncut_From3texelTriangle.z + 1);
texelsWeightsB.z = 0.081632 * (computedAreaUncut_From3texelTriangle.z);
texelsWeightsB.w = 0.081632 * (computedArea_From3texelTriangle.w);
}
// 3x3 Tent filter (45 degree sloped triangles in U and V)
void SampleShadow_ComputeSamples_Tent_3x3(float4 shadowMapTexture_TexelSize, float2 coord, out float fetchesWeights[4], out float2 fetchesUV[4])
{
// tent base is 3x3 base thus covering from 9 to 12 texels, thus we need 4 bilinear PCF fetches
float2 tentCenterInTexelSpace = coord.xy * shadowMapTexture_TexelSize.zw;
float2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
float2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
// find the weight of each texel based
float4 texelsWeightsU, texelsWeightsV;
SampleShadow_GetTexelWeights_Tent_3x3(offsetFromTentCenterToCenterOfFetches.x, texelsWeightsU);
SampleShadow_GetTexelWeights_Tent_3x3(offsetFromTentCenterToCenterOfFetches.y, texelsWeightsV);
// each fetch will cover a group of 2x2 texels, the weight of each group is the sum of the weights of the texels
float2 fetchesWeightsU = texelsWeightsU.xz + texelsWeightsU.yw;
float2 fetchesWeightsV = texelsWeightsV.xz + texelsWeightsV.yw;
// move the PCF bilinear fetches to respect texels weights
float2 fetchesOffsetsU = texelsWeightsU.yw / fetchesWeightsU.xy + float2(-1.5,0.5);
float2 fetchesOffsetsV = texelsWeightsV.yw / fetchesWeightsV.xy + float2(-1.5,0.5);
fetchesOffsetsU *= shadowMapTexture_TexelSize.xx;
fetchesOffsetsV *= shadowMapTexture_TexelSize.yy;
float2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTexture_TexelSize.xy;
fetchesUV[0] = bilinearFetchOrigin + float2(fetchesOffsetsU.x, fetchesOffsetsV.x);
fetchesUV[1] = bilinearFetchOrigin + float2(fetchesOffsetsU.y, fetchesOffsetsV.x);
fetchesUV[2] = bilinearFetchOrigin + float2(fetchesOffsetsU.x, fetchesOffsetsV.y);
fetchesUV[3] = bilinearFetchOrigin + float2(fetchesOffsetsU.y, fetchesOffsetsV.y);
fetchesWeights[0] = fetchesWeightsU.x * fetchesWeightsV.x;
fetchesWeights[1] = fetchesWeightsU.y * fetchesWeightsV.x;
fetchesWeights[2] = fetchesWeightsU.x * fetchesWeightsV.y;
fetchesWeights[3] = fetchesWeightsU.y * fetchesWeightsV.y;
}
// 5x5 Tent filter (45 degree sloped triangles in U and V)
void SampleShadow_ComputeSamples_Tent_5x5(float4 shadowMapTexture_TexelSize, float2 coord, out float fetchesWeights[9], out float2 fetchesUV[9])
{
// tent base is 5x5 base thus covering from 25 to 36 texels, thus we need 9 bilinear PCF fetches
float2 tentCenterInTexelSpace = coord.xy * shadowMapTexture_TexelSize.zw;
float2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
float2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
// find the weight of each texel based on the area of a 45 degree slop tent above each of them.
float3 texelsWeightsU_A, texelsWeightsU_B;
float3 texelsWeightsV_A, texelsWeightsV_B;
SampleShadow_GetTexelWeights_Tent_5x5(offsetFromTentCenterToCenterOfFetches.x, texelsWeightsU_A, texelsWeightsU_B);
SampleShadow_GetTexelWeights_Tent_5x5(offsetFromTentCenterToCenterOfFetches.y, texelsWeightsV_A, texelsWeightsV_B);
// each fetch will cover a group of 2x2 texels, the weight of each group is the sum of the weights of the texels
float3 fetchesWeightsU = float3(texelsWeightsU_A.xz, texelsWeightsU_B.y) + float3(texelsWeightsU_A.y, texelsWeightsU_B.xz);
float3 fetchesWeightsV = float3(texelsWeightsV_A.xz, texelsWeightsV_B.y) + float3(texelsWeightsV_A.y, texelsWeightsV_B.xz);
// move the PCF bilinear fetches to respect texels weights
float3 fetchesOffsetsU = float3(texelsWeightsU_A.y, texelsWeightsU_B.xz) / fetchesWeightsU.xyz + float3(-2.5,-0.5,1.5);
float3 fetchesOffsetsV = float3(texelsWeightsV_A.y, texelsWeightsV_B.xz) / fetchesWeightsV.xyz + float3(-2.5,-0.5,1.5);
fetchesOffsetsU *= shadowMapTexture_TexelSize.xxx;
fetchesOffsetsV *= shadowMapTexture_TexelSize.yyy;
float2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTexture_TexelSize.xy;
fetchesUV[0] = bilinearFetchOrigin + float2(fetchesOffsetsU.x, fetchesOffsetsV.x);
fetchesUV[1] = bilinearFetchOrigin + float2(fetchesOffsetsU.y, fetchesOffsetsV.x);
fetchesUV[2] = bilinearFetchOrigin + float2(fetchesOffsetsU.z, fetchesOffsetsV.x);
fetchesUV[3] = bilinearFetchOrigin + float2(fetchesOffsetsU.x, fetchesOffsetsV.y);
fetchesUV[4] = bilinearFetchOrigin + float2(fetchesOffsetsU.y, fetchesOffsetsV.y);
fetchesUV[5] = bilinearFetchOrigin + float2(fetchesOffsetsU.z, fetchesOffsetsV.y);
fetchesUV[6] = bilinearFetchOrigin + float2(fetchesOffsetsU.x, fetchesOffsetsV.z);
fetchesUV[7] = bilinearFetchOrigin + float2(fetchesOffsetsU.y, fetchesOffsetsV.z);
fetchesUV[8] = bilinearFetchOrigin + float2(fetchesOffsetsU.z, fetchesOffsetsV.z);
fetchesWeights[0] = fetchesWeightsU.x * fetchesWeightsV.x;
fetchesWeights[1] = fetchesWeightsU.y * fetchesWeightsV.x;
fetchesWeights[2] = fetchesWeightsU.z * fetchesWeightsV.x;
fetchesWeights[3] = fetchesWeightsU.x * fetchesWeightsV.y;
fetchesWeights[4] = fetchesWeightsU.y * fetchesWeightsV.y;
fetchesWeights[5] = fetchesWeightsU.z * fetchesWeightsV.y;
fetchesWeights[6] = fetchesWeightsU.x * fetchesWeightsV.z;
fetchesWeights[7] = fetchesWeightsU.y * fetchesWeightsV.z;
fetchesWeights[8] = fetchesWeightsU.z * fetchesWeightsV.z;
}
// 7x7 Tent filter (45 degree sloped triangles in U and V)
void SampleShadow_ComputeSamples_Tent_7x7(float4 shadowMapTexture_TexelSize, float2 coord, out float fetchesWeights[16], out float2 fetchesUV[16])
{
// tent base is 7x7 base thus covering from 49 to 64 texels, thus we need 16 bilinear PCF fetches
float2 tentCenterInTexelSpace = coord.xy * shadowMapTexture_TexelSize.zw;
float2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);
float2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;
// find the weight of each texel based on the area of a 45 degree slop tent above each of them.
float4 texelsWeightsU_A, texelsWeightsU_B;
float4 texelsWeightsV_A, texelsWeightsV_B;
SampleShadow_GetTexelWeights_Tent_7x7(offsetFromTentCenterToCenterOfFetches.x, texelsWeightsU_A, texelsWeightsU_B);
SampleShadow_GetTexelWeights_Tent_7x7(offsetFromTentCenterToCenterOfFetches.y, texelsWeightsV_A, texelsWeightsV_B);
// each fetch will cover a group of 2x2 texels, the weight of each group is the sum of the weights of the texels
float4 fetchesWeightsU = float4(texelsWeightsU_A.xz, texelsWeightsU_B.xz) + float4(texelsWeightsU_A.yw, texelsWeightsU_B.yw);
float4 fetchesWeightsV = float4(texelsWeightsV_A.xz, texelsWeightsV_B.xz) + float4(texelsWeightsV_A.yw, texelsWeightsV_B.yw);
// move the PCF bilinear fetches to respect texels weights
float4 fetchesOffsetsU = float4(texelsWeightsU_A.yw, texelsWeightsU_B.yw) / fetchesWeightsU.xyzw + float4(-3.5,-1.5,0.5,2.5);
float4 fetchesOffsetsV = float4(texelsWeightsV_A.yw, texelsWeightsV_B.yw) / fetchesWeightsV.xyzw + float4(-3.5,-1.5,0.5,2.5);
fetchesOffsetsU *= shadowMapTexture_TexelSize.xxxx;
fetchesOffsetsV *= shadowMapTexture_TexelSize.yyyy;
float2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTexture_TexelSize.xy;
fetchesUV[0] = bilinearFetchOrigin + float2(fetchesOffsetsU.x, fetchesOffsetsV.x);
fetchesUV[1] = bilinearFetchOrigin + float2(fetchesOffsetsU.y, fetchesOffsetsV.x);
fetchesUV[2] = bilinearFetchOrigin + float2(fetchesOffsetsU.z, fetchesOffsetsV.x);
fetchesUV[3] = bilinearFetchOrigin + float2(fetchesOffsetsU.w, fetchesOffsetsV.x);
fetchesUV[4] = bilinearFetchOrigin + float2(fetchesOffsetsU.x, fetchesOffsetsV.y);
fetchesUV[5] = bilinearFetchOrigin + float2(fetchesOffsetsU.y, fetchesOffsetsV.y);
fetchesUV[6] = bilinearFetchOrigin + float2(fetchesOffsetsU.z, fetchesOffsetsV.y);
fetchesUV[7] = bilinearFetchOrigin + float2(fetchesOffsetsU.w, fetchesOffsetsV.y);
fetchesUV[8] = bilinearFetchOrigin + float2(fetchesOffsetsU.x, fetchesOffsetsV.z);
fetchesUV[9] = bilinearFetchOrigin + float2(fetchesOffsetsU.y, fetchesOffsetsV.z);
fetchesUV[10] = bilinearFetchOrigin + float2(fetchesOffsetsU.z, fetchesOffsetsV.z);
fetchesUV[11] = bilinearFetchOrigin + float2(fetchesOffsetsU.w, fetchesOffsetsV.z);
fetchesUV[12] = bilinearFetchOrigin + float2(fetchesOffsetsU.x, fetchesOffsetsV.w);
fetchesUV[13] = bilinearFetchOrigin + float2(fetchesOffsetsU.y, fetchesOffsetsV.w);
fetchesUV[14] = bilinearFetchOrigin + float2(fetchesOffsetsU.z, fetchesOffsetsV.w);
fetchesUV[15] = bilinearFetchOrigin + float2(fetchesOffsetsU.w, fetchesOffsetsV.w);
fetchesWeights[0] = fetchesWeightsU.x * fetchesWeightsV.x;
fetchesWeights[1] = fetchesWeightsU.y * fetchesWeightsV.x;
fetchesWeights[2] = fetchesWeightsU.z * fetchesWeightsV.x;
fetchesWeights[3] = fetchesWeightsU.w * fetchesWeightsV.x;
fetchesWeights[4] = fetchesWeightsU.x * fetchesWeightsV.y;
fetchesWeights[5] = fetchesWeightsU.y * fetchesWeightsV.y;
fetchesWeights[6] = fetchesWeightsU.z * fetchesWeightsV.y;
fetchesWeights[7] = fetchesWeightsU.w * fetchesWeightsV.y;
fetchesWeights[8] = fetchesWeightsU.x * fetchesWeightsV.z;
fetchesWeights[9] = fetchesWeightsU.y * fetchesWeightsV.z;
fetchesWeights[10] = fetchesWeightsU.z * fetchesWeightsV.z;
fetchesWeights[11] = fetchesWeightsU.w * fetchesWeightsV.z;
fetchesWeights[12] = fetchesWeightsU.x * fetchesWeightsV.w;
fetchesWeights[13] = fetchesWeightsU.y * fetchesWeightsV.w;
fetchesWeights[14] = fetchesWeightsU.z * fetchesWeightsV.w;
fetchesWeights[15] = fetchesWeightsU.w * fetchesWeightsV.w;
}
// ------------------------------------------------------------------
// PCF Filtering methods
// ------------------------------------------------------------------
float SampleShadow_PCF_1tap( ShadowContext shadowContext, float3 tcs, uint slice, uint texIdx, uint sampIdx )
// 1 tap PCF sampling
//
float SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, float bias, uint slice, uint texIdx, uint sampIdx )
// sample the texture
return SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, tcs, slice ).x;
float depthBias = asfloat( shadowContext.payloads[payloadOffset].x );
payloadOffset++;
// add the depth bias
tcs.z += depthBias;
// sample the texture
return SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, tcs, slice ).x;
float SampleShadow_PCF_1tap( ShadowContext shadowContext, float3 tcs, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
float SampleShadow_PCF_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, float bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
// sample the texture
return SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, tcs, slice );
float depthBias = asfloat( shadowContext.payloads[payloadOffset].x );
payloadOffset++;
// add the depth bias
tcs.z += depthBias;
// sample the texture
return SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, tcs, slice );
// 9 tap adaptive PCF sampling
// 3x3 tent PCF sampling (4 taps)
float SampleShadow_PCF_9tap_Adaptive( ShadowContext shadowContext, float2 texelSizeRcp, float3 tcs, uint slice, uint texIdx, uint sampIdx )
float SampleShadow_PCF_Tent_3x3( ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 coord, uint slice, uint texIdx, uint sampIdx )
// Terms0 are weights for the individual samples, the other terms are offsets in texel space
float4 vShadow3x3PCFTerms0 = float4( 20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f );
float4 vShadow3x3PCFTerms1 = float4( texelSizeRcp.x, texelSizeRcp.y, -texelSizeRcp.x, -texelSizeRcp.y );
float4 vShadow3x3PCFTerms2 = float4( texelSizeRcp.x, texelSizeRcp.y, 0.0f, 0.0f );
float4 vShadow3x3PCFTerms3 = float4(-texelSizeRcp.x, -texelSizeRcp.y, 0.0f, 0.0f );
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float depthBias = params.x;
payloadOffset++;
float4 v20Taps;
v20Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
float flSum = dot( v20Taps.xyzw, float4( 0.25, 0.25, 0.25, 0.25 ) );
// fully in light or shadow? -> bail
if( ( flSum == 0.0 ) || ( flSum == 1.0 ) )
return flSum;
// TODO move this to shadow data to avoid the rcp?
float4 shadowMapTexture_TexelSize = float4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
// add the depth bias
coord.z += depthBias;
float shadow = 0.0;
float fetchesWeights[4];
float2 fetchesUV[4];
SampleShadow_ComputeSamples_Tent_3x3(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
[loop] for (int i = 0; i < 4; i++)
{
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( fetchesUV[i].xy, coord.z ), slice ).x;
}
return shadow;
}
float SampleShadow_PCF_Tent_3x3(ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
{
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float depthBias = params.x;
payloadOffset++;
// we're in a transition area, do 5 more taps
flSum *= vShadow3x3PCFTerms0.x * 4.0;
// TODO move this to shadow data to avoid the rcp?
float4 shadowMapTexture_TexelSize = float4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
float4 v33Taps;
v33Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
flSum += dot( v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy );
// add the depth bias
coord.z += depthBias;
flSum += SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, tcs, slice ).x * vShadow3x3PCFTerms0.z;
float shadow = 0.0;
float fetchesWeights[4];
float2 fetchesUV[4];
return flSum;
SampleShadow_ComputeSamples_Tent_3x3(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
for (int i = 0; i < 4; i++)
{
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[i].xy, coord.z ), slice ).x;
}
return shadow;
float SampleShadow_PCF_9tap_Adaptive(ShadowContext shadowContext, float2 texelSizeRcp, float3 tcs, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
//
// 5x5 tent PCF sampling (9 taps)
//
float SampleShadow_PCF_Tent_5x5( ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 coord, uint slice, uint texIdx, uint sampIdx )
// Terms0 are weights for the individual samples, the other terms are offsets in texel space
float4 vShadow3x3PCFTerms0 = float4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
float4 vShadow3x3PCFTerms1 = float4( texelSizeRcp.x, texelSizeRcp.y, -texelSizeRcp.x, -texelSizeRcp.y);
float4 vShadow3x3PCFTerms2 = float4( texelSizeRcp.x, texelSizeRcp.y, 0.0f, 0.0f);
float4 vShadow3x3PCFTerms3 = float4(-texelSizeRcp.x, -texelSizeRcp.y, 0.0f, 0.0f);
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float depthBias = params.x;
payloadOffset++;
float4 v20Taps;
v20Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
float flSum = dot( v20Taps.xyzw, float4( 0.25, 0.25, 0.25, 0.25 ) );
// fully in light or shadow? -> bail
if( ( flSum == 0.0 ) || ( flSum == 1.0 ) )
return flSum;
// TODO move this to shadow data to avoid the rcp?
float4 shadowMapTexture_TexelSize = float4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
// we're in a transition area, do 5 more taps
flSum *= vShadow3x3PCFTerms0.x * 4.0;
// add the depth bias
coord.z += depthBias;
float4 v33Taps;
v33Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
flSum += dot( v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy );
float shadow = 0.0;
float fetchesWeights[9];
float2 fetchesUV[9];
SampleShadow_ComputeSamples_Tent_5x5(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
[loop] for (int i = 0; i < 9; i++)
{
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( fetchesUV[i].xy, coord.z ), slice ).x;
}
return shadow;
}
float SampleShadow_PCF_Tent_5x5(ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
{
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float depthBias = params.x;
payloadOffset++;
// TODO move this to shadow data to avoid the rcp
float4 shadowMapTexture_TexelSize = float4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
// add the depth bias
coord.z += depthBias;
float shadow = 0.0;
float fetchesWeights[9];
float2 fetchesUV[9];
SampleShadow_ComputeSamples_Tent_5x5(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
for (int i = 0; i < 9; i++)
{
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[i].xy, coord.z ), slice ).x;
}
return shadow;
}
//
// 7x7 tent PCF sampling (16 taps)
//
float SampleShadow_PCF_Tent_7x7( ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 coord, uint slice, uint texIdx, uint sampIdx )
{
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float depthBias = params.x;
payloadOffset++;
// TODO move this to shadow data to avoid the rcp
float4 shadowMapTexture_TexelSize = float4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
// add the depth bias
coord.z += depthBias;
float shadow = 0.0;
float fetchesWeights[16];
float2 fetchesUV[16];
SampleShadow_ComputeSamples_Tent_7x7(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
[loop] for (int i = 0; i < 16; i++)
{
shadow += fetchesWeights[i] * SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( fetchesUV[i].xy, coord.z ), slice ).x;
}
return shadow;
}
float SampleShadow_PCF_Tent_7x7(ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 coord, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
{
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float depthBias = params.x;
payloadOffset++;
// TODO move this to shadow data to avoid the rcp
float4 shadowMapTexture_TexelSize = float4(texelSizeRcp.xy, rcp(texelSizeRcp.xy));
// add the depth bias
coord.z += depthBias;
float shadow = 0.0;
float fetchesWeights[16];
float2 fetchesUV[16];
SampleShadow_ComputeSamples_Tent_7x7(shadowMapTexture_TexelSize, coord.xy, fetchesWeights, fetchesUV);
for (int i = 0; i < 16; i++)
{
shadow += fetchesWeights[i] * SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( fetchesUV[i].xy, coord.z ), slice ).x;
}
return shadow;
}
//
// 9 tap adaptive PCF sampling
//
float SampleShadow_PCF_9tap_Adaptive( ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 tcs, float bias, uint slice, uint texIdx, uint sampIdx )
{
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float depthBias = params.x;
float filterSize = params.y;
payloadOffset++;
texelSizeRcp *= filterSize;
// add the depth bias
tcs.z += depthBias;
// Terms0 are weights for the individual samples, the other terms are offsets in texel space
float4 vShadow3x3PCFTerms0 = float4( 20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f );
float4 vShadow3x3PCFTerms1 = float4( texelSizeRcp.x, texelSizeRcp.y, -texelSizeRcp.x, -texelSizeRcp.y );
float4 vShadow3x3PCFTerms2 = float4( texelSizeRcp.x, texelSizeRcp.y, 0.0f, 0.0f );
float4 vShadow3x3PCFTerms3 = float4(-texelSizeRcp.x, -texelSizeRcp.y, 0.0f, 0.0f );
float4 v20Taps;
v20Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
float flSum = dot( v20Taps.xyzw, float4( 0.25, 0.25, 0.25, 0.25 ) );
// fully in light or shadow? -> bail
if( ( flSum == 0.0 ) || ( flSum == 1.0 ) )
return flSum;
// we're in a transition area, do 5 more taps
flSum *= vShadow3x3PCFTerms0.x * 4.0;
float4 v33Taps;
v33Taps.x = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, float3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
flSum += dot( v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy );
flSum += SampleCompShadow_T2DA( shadowContext, texIdx, sampIdx, tcs, slice ).x * vShadow3x3PCFTerms0.z;
return flSum;
}
float SampleShadow_PCF_9tap_Adaptive(ShadowContext shadowContext, inout uint payloadOffset, float4 texelSizeRcp, float3 tcs, float bias, uint slice, Texture2DArray tex, SamplerComparisonState compSamp )
{
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float depthBias = params.x;
float filterSize = params.y;
payloadOffset++;
texelSizeRcp *= filterSize;
// add the depth bias
tcs.z += depthBias;
// Terms0 are weights for the individual samples, the other terms are offsets in texel space
float4 vShadow3x3PCFTerms0 = float4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
float4 vShadow3x3PCFTerms1 = float4( texelSizeRcp.x, texelSizeRcp.y, -texelSizeRcp.x, -texelSizeRcp.y);
float4 vShadow3x3PCFTerms2 = float4( texelSizeRcp.x, texelSizeRcp.y, 0.0f, 0.0f);
float4 vShadow3x3PCFTerms3 = float4(-texelSizeRcp.x, -texelSizeRcp.y, 0.0f, 0.0f);
float4 v20Taps;
v20Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms1.xy, tcs.z ), slice ).x; // 1 1
v20Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms1.zy, tcs.z ), slice ).x; // -1 1
v20Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms1.xw, tcs.z ), slice ).x; // 1 -1
v20Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms1.zw, tcs.z ), slice ).x; // -1 -1
float flSum = dot( v20Taps.xyzw, float4( 0.25, 0.25, 0.25, 0.25 ) );
// fully in light or shadow? -> bail
if( ( flSum == 0.0 ) || ( flSum == 1.0 ) )
return flSum;
// we're in a transition area, do 5 more taps
flSum *= vShadow3x3PCFTerms0.x * 4.0;
float4 v33Taps;
v33Taps.x = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms2.xz, tcs.z ), slice ).x; // 1 0
v33Taps.y = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms3.xz, tcs.z ), slice ).x; // -1 0
v33Taps.z = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms3.zy, tcs.z ), slice ).x; // 0 -1
v33Taps.w = SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, float3( tcs.xy + vShadow3x3PCFTerms2.zy, tcs.z ), slice ).x; // 0 1
flSum += dot( v33Taps.xyzw, vShadow3x3PCFTerms0.yyyy );
flSum += SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, tcs, slice ).x * vShadow3x3PCFTerms0.z;
return flSum;
}
#include "ShadowMoments.hlsl"
//
// 1 tap VSM sampling
//
float SampleShadow_VSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, uint texIdx, uint sampIdx )
{
float depth = tcs.z;
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float lightLeakBias = params.x;
float varianceBias = params.y;
payloadOffset++;
float2 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice ).xy;
return ShadowMoments_ChebyshevsInequality( moments, depth, varianceBias, lightLeakBias );
}
float SampleShadow_VSM_1tap(ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, Texture2DArray tex, SamplerState samp )
{
float depth = tcs.z;
float2 params = asfloat( shadowContext.payloads[payloadOffset].xy );
float lightLeakBias = params.x;
float varianceBias = params.y;
payloadOffset++;
float2 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 ).xy;
return ShadowMoments_ChebyshevsInequality( moments, depth, varianceBias, lightLeakBias );
}
//
// 1 tap EVSM sampling
//
float SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, uint texIdx, uint sampIdx, bool fourMoments )
{
float depth = tcs.z;
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float lightLeakBias = params.x;
float varianceBias = params.y;
float2 evsmExponents = params.zw;
payloadOffset++;
float2 warpedDepth = ShadowMoments_WarpDepth( depth, evsmExponents );
float4 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice );
// Derivate of warping at depth
float2 depthScale = evsmExponents * warpedDepth;
float2 minVariance = depthScale * depthScale * varianceBias;
[branch]
if( fourMoments )
{
float posContrib = ShadowMoments_ChebyshevsInequality( moments.xz, warpedDepth.x, minVariance.x, lightLeakBias );
float negContrib = ShadowMoments_ChebyshevsInequality( moments.yw, warpedDepth.y, minVariance.y, lightLeakBias );
return min( posContrib, negContrib );
}
else
{
return ShadowMoments_ChebyshevsInequality( moments.xy, warpedDepth.x, minVariance.x, lightLeakBias );
}
}
float SampleShadow_EVSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool fourMoments )
{
float depth = tcs.z;
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float lightLeakBias = params.x;
float varianceBias = params.y;
float2 evsmExponents = params.zw;
payloadOffset++;
float2 warpedDepth = ShadowMoments_WarpDepth( depth, evsmExponents );
flSum += SAMPLE_TEXTURE2D_ARRAY_SHADOW( tex, compSamp, tcs, slice ).x * vShadow3x3PCFTerms0.z;
float4 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 );
return flSum;
// Derivate of warping at depth
float2 depthScale = evsmExponents * warpedDepth;
float2 minVariance = depthScale * depthScale * varianceBias;
[branch]
if( fourMoments )
{
float posContrib = ShadowMoments_ChebyshevsInequality( moments.xz, warpedDepth.x, minVariance.x, lightLeakBias );
float negContrib = ShadowMoments_ChebyshevsInequality( moments.yw, warpedDepth.y, minVariance.y, lightLeakBias );
return min( posContrib, negContrib );
}
else
{
return ShadowMoments_ChebyshevsInequality( moments.xy, warpedDepth.x, minVariance.x, lightLeakBias );
}
}
//
// 1 tap MSM sampling
//
float SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, uint texIdx, uint sampIdx, bool useHamburger )
{
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float lightLeakBias = params.x;
float momentBias = params.y;
float depthBias = params.z;
float bpp16 = params.w;
float depth = tcs.z + depthBias;
payloadOffset++;
float4 moments = SampleShadow_T2DA( shadowContext, texIdx, sampIdx, tcs.xy, slice );
if( bpp16 != 0.0 )
moments = ShadowMoments_Decode16MSM( moments );
float3 z;
float4 b;
ShadowMoments_SolveMSM( moments, depth, momentBias, z, b );
if( useHamburger )
return ShadowMoments_SolveDelta3MSM( z, b.xy, lightLeakBias );
else
return (z[1] < 0.0 || z[2] > 1.0) ? ShadowMoments_SolveDelta4MSM( z, b, lightLeakBias ) : ShadowMoments_SolveDelta3MSM( z, b.xy, lightLeakBias );
}
float SampleShadow_MSM_1tap( ShadowContext shadowContext, inout uint payloadOffset, float3 tcs, uint slice, Texture2DArray tex, SamplerState samp, bool useHamburger )
{
float4 params = asfloat( shadowContext.payloads[payloadOffset] );
float lightLeakBias = params.x;
float momentBias = params.y;
float depthBias = params.z;
float bpp16 = params.w;
float depth = tcs.z + depthBias;
payloadOffset++;
float4 moments = SAMPLE_TEXTURE2D_ARRAY_LOD( tex, samp, tcs.xy, slice, 0.0 );
if( bpp16 != 0.0 )
moments = ShadowMoments_Decode16MSM( moments );
float3 z;
float4 b;
ShadowMoments_SolveMSM( moments, depth, momentBias, z, b );
if( useHamburger )
return ShadowMoments_SolveDelta3MSM( z, b.xy, lightLeakBias );
else
return (z[1] < 0.0 || z[2] > 1.0) ? ShadowMoments_SolveDelta4MSM( z, b, lightLeakBias ) : ShadowMoments_SolveDelta3MSM( z, b.xy, lightLeakBias );
}
//-----------------------------------------------------------------------------------------------------
// helper function to dispatch a specific shadow algorithm
float SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, float3 posTC, float depthBias, uint slice, uint algorithm, uint texIdx, uint sampIdx )
{
[branch]
switch( algorithm )
{
case GPUSHADOWALGORITHM_PCF_1TAP : return SampleShadow_PCF_1tap( shadowContext, payloadOffset, posTC, depthBias, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_9TAP : return SampleShadow_PCF_9tap_Adaptive( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_3X3 : return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_5X5 : return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_PCF_TENT_7X7 : return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_VSM : return SampleShadow_VSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx );
case GPUSHADOWALGORITHM_EVSM_2 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, false );
case GPUSHADOWALGORITHM_EVSM_4 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, true );
case GPUSHADOWALGORITHM_MSM_HAM : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, true );
case GPUSHADOWALGORITHM_MSM_HAUS : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, slice, texIdx, sampIdx, false );
default: return 1.0;
}
}
float SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, float3 posTC, float depthBias, uint slice, uint algorithm, Texture2DArray tex, SamplerComparisonState compSamp )
{
[branch]
switch( algorithm )
{
case GPUSHADOWALGORITHM_PCF_1TAP : return SampleShadow_PCF_1tap( shadowContext, payloadOffset, posTC, depthBias, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_9TAP : return SampleShadow_PCF_9tap_Adaptive( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, depthBias, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_3X3 : return SampleShadow_PCF_Tent_3x3( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_5X5 : return SampleShadow_PCF_Tent_5x5( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, tex, compSamp );
case GPUSHADOWALGORITHM_PCF_TENT_7X7 : return SampleShadow_PCF_Tent_7x7( shadowContext, payloadOffset, shadowData.texelSizeRcp, posTC, slice, tex, compSamp );
default: return 1.0;
}
}
float SampleShadow_SelectAlgorithm( ShadowContext shadowContext, ShadowData shadowData, inout uint payloadOffset, float3 posTC, float depthBias, uint slice, uint algorithm, Texture2DArray tex, SamplerState samp )
{
[branch]
switch( algorithm )
{
case GPUSHADOWALGORITHM_VSM : return SampleShadow_VSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp );
case GPUSHADOWALGORITHM_EVSM_2 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp, false );
case GPUSHADOWALGORITHM_EVSM_4 : return SampleShadow_EVSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp, true );
case GPUSHADOWALGORITHM_MSM_HAM : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp, true );
case GPUSHADOWALGORITHM_MSM_HAUS : return SampleShadow_MSM_1tap( shadowContext, payloadOffset, posTC, slice, tex, samp, false );
default: return 1.0;
}
}

67
Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs


}
// Add obj and reallocate if necessary. Returns the index where the object was added.
public uint Add(T obj)
public uint Add( T obj )
{
Reserve(1);
uint idx = m_count;

return AddUnchecked(ref vec);
}
// Adds the object if it does not exist in the container, yet
public uint AddUnique( T obj )
{
Reserve( 1 );
return AddUniqueUnchecked( obj );
}
public uint AddUnique( T[] objs, uint count )
{
Reserve( count );
return AddUniqueUnchecked( objs, count );
}
public uint AddUnique( ref VectorArray<T> vec )
{
Reserve( vec.Count() );
return AddUniqueUnchecked( ref vec );
}
public uint AddUnchecked(T obj)
public uint AddUnchecked( T obj )
{
uint idx = m_count;
this[idx] = obj;

m_count += cnt;
return idx;
}
// Adds the object if it does not exist in the container, yet
public uint AddUniqueUnchecked( T obj )
{
if( !Contains( obj ) )
return Add( obj );
return k_InvalidIdx;
}
public uint AddUniqueUnchecked( T[] objs, uint count )
{
uint res = k_InvalidIdx;
for( uint i = 0; i < count; ++i )
{
uint tmp = AddUniqueUnchecked( objs[i] );
res = res <= tmp ? res : tmp;
}
return res;
}
public uint AddUniqueUnchecked( ref VectorArray<T> vec )
{
uint res = k_InvalidIdx;
for( uint i = 0, cnt = vec.Count(); i < cnt; ++i )
{
uint tmp = AddUniqueUnchecked( vec[i] );
res = res <= tmp ? res : tmp;
}
return res;
}
// Purge count number of elements from the end of the array.
public void Purge(uint count)

idx = k_InvalidIdx;
return false;
}
// Returns true if the container already contains the element
public bool Contains( T designator )
{
uint idx;
return FindFirst( out idx, ref designator );
}
// Returns true if the container already contains the element
public bool Contains<U>( U designator, Comparator<U> compareDelegate )
{
uint idx;
return FindFirst( out idx, ref designator, compareDelegate );
}
// Returns a vector representing a subrange. Contents are shared, not duplicated.
public VectorArray<T> Subrange(uint offset, uint count)
{

998
Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs
文件差异内容过多而无法显示
查看文件

44
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs. Please don't edit by hand.
// This file was automatically generated from Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs. Please don't edit by hand.
// UnityEngine.Experimental.Rendering.HDPipeline.GPUShadowType: static fields
// UnityEngine.Experimental.Rendering.GPUShadowType: static fields
//
#define GPUSHADOWTYPE_POINT (0)
#define GPUSHADOWTYPE_SPOT (1)

#define GPUSHADOWTYPE_ALL (3)
//
// UnityEngine.Experimental.Rendering.HDPipeline.GPUShadowSampling: static fields
// UnityEngine.Experimental.Rendering.GPUShadowAlgorithm: static fields
#define GPUSHADOWSAMPLING_PCF_1TAP (0)
#define GPUSHADOWSAMPLING_PCF_9TAPS_ADAPTIVE (1)
#define GPUSHADOWSAMPLING_VSM_1TAP (2)
#define GPUSHADOWSAMPLING_MSM_1TAP (3)
#define GPUSHADOWALGORITHM_PCF_1TAP (0)
#define GPUSHADOWALGORITHM_PCF_9TAP (1)
#define GPUSHADOWALGORITHM_PCF_TENT_3X3 (2)
#define GPUSHADOWALGORITHM_PCF_TENT_5X5 (3)
#define GPUSHADOWALGORITHM_PCF_TENT_7X7 (4)
#define GPUSHADOWALGORITHM_VSM (8)
#define GPUSHADOWALGORITHM_EVSM_2 (16)
#define GPUSHADOWALGORITHM_EVSM_4 (17)
#define GPUSHADOWALGORITHM_MSM_HAM (24)
#define GPUSHADOWALGORITHM_MSM_HAUS (25)
#define GPUSHADOWALGORITHM_CUSTOM (256)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.ShadowExp.ShadowData
// Generated from UnityEngine.Experimental.Rendering.ShadowData
float2 texelSizeRcp;
float4 texelSizeRcp;
int shadowType;
uint shadowType;
int lightType;
float quality;
float normalBias;
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.ShadowExp.ShadowData
// Accessors for UnityEngine.Experimental.Rendering.ShadowData
//
float4x4 GetWorldToShadow(ShadowData value)
{

{
return value.scaleOffset;
}
float2 GetTexelSizeRcp(ShadowData value)
float4 GetTexelSizeRcp(ShadowData value)
{
return value.texelSizeRcp;
}

}
int GetShadowType(ShadowData value)
uint GetShadowType(ShadowData value)
{
return value.shadowType;
}

}
int GetLightType(ShadowData value)
{
return value.lightType;
}
float GetQuality(ShadowData value)
float GetNormalBias(ShadowData value)
return value.quality;
return value.normalBias;
}

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl.meta


fileFormatVersion: 2
guid: b0e81431fe3a7604fb9f9dd2a96bd7e0
timeCreated: 1491321445
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl.meta


fileFormatVersion: 2
guid: e7e55b7306a2b2f43886918882a8935a
timeCreated: 1491321445
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow.meta


fileFormatVersion: 2
guid: d52d6e1ad3dca474ebd73d054d17fb2e
folderAsset: yes
timeCreated: 1491314187
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

25
Assets/ScriptableRenderPipeline/ShadowIncludes.inl


// This file is inlined by ShaderLibrary/Shadow/Shadow.hlsl twice.
// Each time either SHADOW_CONTEXT_INCLUDE or SHADOW_DISPATCH_INCLUDE is defined.
// In the case of SHADOW_CONTEXT_INCLUDE a valid path must be given to a file that contains
// the code to initialize a shadow context.
// SHADOW_DISPATCH_INCLUDE is optional.
#ifdef SHADOW_CONTEXT_INCLUDE
# ifdef SHADOW_TILEPASS
# include "HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl"
# elif defined( SHADOW_FPTL )
# include "fptl/ShadowContext.hlsl"
# else
# error "No valid path to the shadow context has been given."
# endif
#endif
#ifdef SHADOW_DISPATCH_INCLUDE
# ifdef SHADOW_TILEPASS
# include "HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl"
# elif defined( SHADOW_FPTL )
# include "fptl/ShadowDispatch.hlsl"
# else
// It's ok not to have a dispatcher include as it only acts as an override
# endif
#endif

8
Assets/ScriptableRenderPipeline/ShadowIncludes.inl.meta


fileFormatVersion: 2
guid: cbc2765f95de56a47a8f39f5f1badd58
timeCreated: 1491314187
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/common/Shadow.meta


fileFormatVersion: 2
guid: d49f97c73daab8a4a8d389c977c2345f
folderAsset: yes
timeCreated: 1491321440
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

26
Assets/ScriptableRenderPipeline/fptl/ShadowContext.hlsl


// This can be custom for each project and needs to be in sync with the ShadowMgr
#define SHADOWCONTEXT_MAX_TEX2DARRAY 1
#define SHADOWCONTEXT_MAX_TEXCUBEARRAY 0
#define SHADOWCONTEXT_MAX_SAMPLER 0
#define SHADOWCONTEXT_MAX_COMPSAMPLER 1
SHADOWCONTEXT_DECLARE( SHADOWCONTEXT_MAX_TEX2DARRAY, SHADOWCONTEXT_MAX_TEXCUBEARRAY, SHADOWCONTEXT_MAX_COMPSAMPLER, SHADOWCONTEXT_MAX_SAMPLER );
TEXTURE2D_ARRAY(_ShadowmapExp_PCF);
SAMPLER2D_SHADOW(sampler_ShadowmapExp_PCF);
StructuredBuffer<ShadowData> _ShadowDatasExp;
StructuredBuffer<int4> _ShadowPayloads;
ShadowContext InitShadowContext()
{
ShadowContext sc;
sc.shadowDatas = _ShadowDatasExp;
sc.payloads = _ShadowPayloads;
sc.tex2DArray[0] = _ShadowmapExp_PCF;
sc.compSamplers[0] = sampler_ShadowmapExp_PCF;
return sc;
}

9
Assets/ScriptableRenderPipeline/fptl/ShadowContext.hlsl.meta


fileFormatVersion: 2
guid: 30016f0dcc663b14483b62ccf2e8a7ce
timeCreated: 1491395507
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

36
Assets/ScriptableRenderPipeline/fptl/ShadowDispatch.hlsl


#define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL // enables hardcoded resources and algorithm for directional lights
#define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL // enables hardcoded resources and algorithm for punctual lights
// example of overriding directional lights
#ifdef SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
{
Texture2DArray tex = shadowContext.tex2DArray[0];
SamplerComparisonState compSamp = shadowContext.compSamplers[0];
uint algo = GPUSHADOWALGORITHM_PCF_9TAP;
return EvalShadow_CascadedDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
}
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
{
return GetDirectionalShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}
#endif
// example of overriding punctual lights
#ifdef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
{
// example for choosing the same algo
Texture2DArray tex = shadowContext.tex2DArray[0];
SamplerComparisonState compSamp = shadowContext.compSamplers[0];
uint algo = GPUSHADOWALGORITHM_PCF_9TAP;
return EvalShadow_PunctualDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
}
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 unPositionSS )
{
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
}
#endif

9
Assets/ScriptableRenderPipeline/fptl/ShadowDispatch.hlsl.meta


fileFormatVersion: 2
guid: 631ee816f7a634d48ae2c70c43a46e98
timeCreated: 1491395507
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources.meta


fileFormatVersion: 2
guid: f2f1273335a3dc54686dd5620bfc6790
folderAsset: yes
timeCreated: 1491321440
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute.meta


fileFormatVersion: 2
guid: fb36979473602464fa32deacb9630c08
timeCreated: 1488205058
licenseType: Pro
ComputeShaderImporter:
currentAPIMask: 4
userData:
assetBundleName:
assetBundleVariant:

235
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Resources/ShadowBlurMoments.compute


#define VSM 0
#define EVSM_2 1
#define EVSM_4 2
#define MSM 3
#define THREADS 16
#define MAX_BLUR_SIZE 17
#pragma kernel main_VSM_3 KERNEL_MAIN=main_VSM_3 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=3
#pragma kernel main_VSM_5 KERNEL_MAIN=main_VSM_5 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=5
#pragma kernel main_VSM_7 KERNEL_MAIN=main_VSM_7 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=7
#pragma kernel main_VSM_9 KERNEL_MAIN=main_VSM_9 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=9
#pragma kernel main_VSM_11 KERNEL_MAIN=main_VSM_11 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=11
#pragma kernel main_VSM_13 KERNEL_MAIN=main_VSM_13 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=13
#pragma kernel main_VSM_15 KERNEL_MAIN=main_VSM_15 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=15
#pragma kernel main_VSM_17 KERNEL_MAIN=main_VSM_17 SHADOW_MOMENT_ALGORITHM=VSM MAX_MSAA=1 BLUR_SIZE=17
#pragma kernel main_EVSM_2_3 KERNEL_MAIN=main_EVSM_2_3 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=1 BLUR_SIZE=3
#pragma kernel main_EVSM_2_5 KERNEL_MAIN=main_EVSM_2_5 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=1 BLUR_SIZE=5
#pragma kernel main_EVSM_2_7 KERNEL_MAIN=main_EVSM_2_7 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=1 BLUR_SIZE=7
#pragma kernel main_EVSM_2_9 KERNEL_MAIN=main_EVSM_2_9 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=1 BLUR_SIZE=9
#pragma kernel main_EVSM_2_11 KERNEL_MAIN=main_EVSM_2_11 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=1 BLUR_SIZE=11
#pragma kernel main_EVSM_2_13 KERNEL_MAIN=main_EVSM_2_13 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=1 BLUR_SIZE=13
#pragma kernel main_EVSM_2_15 KERNEL_MAIN=main_EVSM_2_15 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=1 BLUR_SIZE=15
#pragma kernel main_EVSM_2_17 KERNEL_MAIN=main_EVSM_2_17 SHADOW_MOMENT_ALGORITHM=EVSM_2 MAX_MSAA=1 BLUR_SIZE=17
#pragma kernel main_EVSM_4_3 KERNEL_MAIN=main_EVSM_4_3 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=1 BLUR_SIZE=3
#pragma kernel main_EVSM_4_5 KERNEL_MAIN=main_EVSM_4_5 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=1 BLUR_SIZE=5
#pragma kernel main_EVSM_4_7 KERNEL_MAIN=main_EVSM_4_7 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=1 BLUR_SIZE=7
#pragma kernel main_EVSM_4_9 KERNEL_MAIN=main_EVSM_4_9 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=1 BLUR_SIZE=9
#pragma kernel main_EVSM_4_11 KERNEL_MAIN=main_EVSM_4_11 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=1 BLUR_SIZE=11
#pragma kernel main_EVSM_4_13 KERNEL_MAIN=main_EVSM_4_13 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=1 BLUR_SIZE=13
#pragma kernel main_EVSM_4_15 KERNEL_MAIN=main_EVSM_4_15 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=1 BLUR_SIZE=15
#pragma kernel main_EVSM_4_17 KERNEL_MAIN=main_EVSM_4_17 SHADOW_MOMENT_ALGORITHM=EVSM_4 MAX_MSAA=1 BLUR_SIZE=17
#pragma kernel main_MSM_3 KERNEL_MAIN=main_MSM_3 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=3
#pragma kernel main_MSM_5 KERNEL_MAIN=main_MSM_5 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=5
#pragma kernel main_MSM_7 KERNEL_MAIN=main_MSM_7 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=7
#pragma kernel main_MSM_9 KERNEL_MAIN=main_MSM_9 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=9
#pragma kernel main_MSM_11 KERNEL_MAIN=main_MSM_11 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=11
#pragma kernel main_MSM_13 KERNEL_MAIN=main_MSM_13 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=13
#pragma kernel main_MSM_15 KERNEL_MAIN=main_MSM_15 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=15
#pragma kernel main_MSM_17 KERNEL_MAIN=main_MSM_17 SHADOW_MOMENT_ALGORITHM=MSM MAX_MSAA=1 BLUR_SIZE=17
#include "ShaderLibrary/common.hlsl"
#include "ShaderLibrary/Shadow/ShadowMoments.hlsl"
#define BLUR_BORDER (BLUR_SIZE / 2)
#define LDS_SIZE (THREADS + BLUR_BORDER + BLUR_BORDER)
#if MAX_MSAA == 1
Texture2D<float> depthTex;
#else
Texture2DMS<float> depthTex;
#endif
uniform uint4 srcRect; // .xy = offset, .zw = width/height
uniform uint4 dstRect; // .xy = offset, .z = array slice , .w = Flags: 1 := 16bpp, 2 := 2 channels pp
uniform float4 blurWeightsStorage[3]; // Unity expects float arrays to be tightly packed
static float blurWeights[12] = (float[12])blurWeightsStorage;
static const int kBits_16 = 1; // 16 bits per channel
static const int kChannels_2 = 2; // 2 channels per pixel
#if (SHADOW_MOMENT_ALGORITHM == VSM)
# define SHADOW_MOMENTS 2
float2 DepthToMoments( float depth )
{
return float2( depth, depth * depth );
}
#elif SHADOW_MOMENT_ALGORITHM == EVSM_2
# define SHADOW_MOMENTS 2
uniform float evsmExponent;
float2 DepthToMoments( float depth )
{
float2 moments = ShadowMoments_WarpDepth( depth, evsmExponent.xx );
return float2( moments.x, moments.x * moments.x );
}
#elif SHADOW_MOMENT_ALGORITHM == EVSM_4
# define SHADOW_MOMENTS 4
uniform float2 evsmExponents;
float4 DepthToMoments( float depth )
{
float2 moments = ShadowMoments_WarpDepth( depth, evsmExponents );
return float4( moments.xy, moments.xy * moments.xy );
}
#elif SHADOW_MOMENT_ALGORITHM == MSM
# define SHADOW_MOMENTS 4
float4 DepthToMoments( float depth )
{
[branch]
if( (dstRect.w & kBits_16) != 0 )
return ShadowMoments_Encode16MSM( depth );
else
{
float dsq = depth * depth;
return float4( depth, dsq, depth * dsq, dsq * dsq );
}
}
#else
# error "No valid shadow moment algorithm has been set to the define SHADOW_MOMENT_ALGORITHM."
#endif
#define moment_t MERGE_NAME( float, SHADOW_MOMENTS )
RWTexture2DArray<moment_t> outputTex;
groupshared moment_t moments[LDS_SIZE][LDS_SIZE];
[numthreads( THREADS, THREADS, 1 )]
void KERNEL_MAIN(uint3 dispatchId : SV_DispatchThreadID, uint3 groupThreadId : SV_GroupThreadID)
{
uint i, j; // because the compiler scopes like its 1999.
#if MAX_MSAA > 1
uint width, height, sampleCnt;
depthTex.GetDimensions(width, height, sampleCnt);
sampleCnt = Clamp(0, MAX_MSAA, sampleCnt);
float sampleCntRcp = 1.0 / sampleCnt;
// calculate weights based on sample positions
float sumWeights = 0;
float sampleWeights[MAX_MSAA];
for (i = 0; i < sampleCnt; i++)
{
float2 spos = depthTex.GetSamplePosition( i );
sampleWeights[i] = sampleCntRcp; // TODO: find a better weight filter
sumWeights += sampleWeights[i];
}
sumWeights = 1.0 / sumWeights;
#endif
// load moments into LDS
// each workgroup works on THREADS * THREADS tiles, but the blur filter requires
// us to fetch enough data around the border of the current tile.
// We assume that the blur filter's support does not exceed THREADS, so we fetch
// the data in 4 blocks.
const int blurBorder = BLUR_BORDER;
const int2 ldsSize = int2( LDS_SIZE, LDS_SIZE );
const int2 threadsCnt = int2( THREADS, THREADS );
const int4 validSrc = int4( srcRect.xy, srcRect.xy + srcRect.zw - 1 );
int2 srcIdx = ((int2) dispatchId.xy) - blurBorder.xx + srcRect.xy;
int2 ldsIdx = groupThreadId.xy;
// calculate an average moment over all samples for a given pixel and load the result into LDS
uint iw, ih, is;
[unroll]
for( ih = 0; ih < 2; ih++ )
{
[branch]
if (ldsIdx.y >= ldsSize.y)
continue;
[unroll]
for( iw = 0; iw < 2; iw++ )
{
[branch]
if (ldsIdx.x >= ldsSize.x)
continue;
moment_t avgMoments = 0.0;
#if MAX_MSAA > 1
for( is = 0; is < sampleCnt; is++ )
{
float depth = depthTex.Load( Clamp( srcIdx, validSrc.xy, validSrc.zw ), is ).x;
moment_t moments = DepthToMoments( depth );
avgMoments += sampleWeights[is] * moments;
}
avgMoments *= sumWeights;
#else
avgMoments = DepthToMoments( depthTex.Load( int3( Clamp( srcIdx, validSrc.xy, validSrc.zw ), 0 ) ).x );
#endif
moments[ldsIdx.y][ldsIdx.x] = avgMoments;
ldsIdx.x += threadsCnt.x;
srcIdx.x += threadsCnt.x;
}
ldsIdx.x = groupThreadId.x;
srcIdx.x = (int) dispatchId.x - blurBorder + srcRect.x;
ldsIdx.y += threadsCnt.y;
srcIdx.y += threadsCnt.y;
}
// sync across all threads so LDS contains the moments for each pixel that we need for the blur
GroupMemoryBarrierWithGroupSync();
// first pass blurs horizontally
ldsIdx = groupThreadId.xy + int2( blurBorder, 0 );
moment_t hblurredMoment = 0.0, hblurredMoment2 = 0.0;
int blurOffset;
for( blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
{
hblurredMoment += moments[ldsIdx.y][ldsIdx.x + blurOffset] * blurWeights[abs( blurOffset )];
}
ldsIdx.y += threadsCnt.y;
[branch]
if( ldsIdx.y < ldsSize.y )
{
for( blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
{
hblurredMoment2 += moments[ldsIdx.y][ldsIdx.x + blurOffset] * blurWeights[abs(blurOffset)];
}
}
// make sure all reads/writes are done
GroupMemoryBarrierWithGroupSync();
// replace LDS values with the horizontally blurred values
moments[groupThreadId.y][ldsIdx.x] = hblurredMoment;
[branch]
if( ldsIdx.y < ldsSize.y )
moments[ldsIdx.y][ldsIdx.x] = hblurredMoment2;
GroupMemoryBarrierWithGroupSync();
// second pass blurs vertically
ldsIdx = groupThreadId.xy + blurBorder.xx;
moment_t vblurredMoment = 0.0;
for( blurOffset = -blurBorder; blurOffset <= blurBorder; blurOffset++ )
{
vblurredMoment += moments[ldsIdx.y + blurOffset][ldsIdx.x] * blurWeights[abs( blurOffset )];
}
// and write out the result
if( all( dispatchId.xy < srcRect.zw ) )
{
dispatchId.z = dstRect.z;
dispatchId.xy += dstRect.xy;
outputTex[dispatchId] = vblurredMoment;
}
}

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl.meta


fileFormatVersion: 2
guid: 3d03971a8848ee14bb29a3c4ee9790b8
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

277
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl


// Various shadow algorithms
// There are two variants provided, one takes the texture and sampler explicitly so they can be statically passed in.
// The variant without resource parameters dynamically accesses the texture when sampling.
// Helper function to offset depth based on the surface normal and light direction.
// If the light hits the surface perpendicularly there will be no offset.
float3 EvalShadow_NormalBias( float3 normalWS, float NoL, float2 texelSize, float normalBias )
{
return max( texelSize.x, texelSize.y ) * normalBias * (1.0 - NoL) * normalWS;
}
// function called by spot, point and directional eval routines to calculate shadow coordinates
float3 EvalShadow_GetTexcoords( ShadowData sd, float3 positionWS )
{
float4 posCS = mul( float4( positionWS, 1.0 ), sd.worldToShadow );
posCS.z -= sd.bias * posCS.w;
float3 posNDC = posCS.xyz / posCS.w;
// calc TCs
float3 posTC = posNDC * 0.5 + 0.5;
posTC.xy = posTC.xy * sd.scaleOffset.xy + sd.scaleOffset.zw;
#if UNITY_REVERSED_Z
posTC.z = 1.0 - posTC.z;
#endif
return posTC;
}
int EvalShadow_GetCubeFaceID( float3 dir )
{
// TODO: Use faceID intrinsic on console
float3 adir = abs(dir);
// +Z -Z
int faceIndex = dir.z > 0.0 ? CUBEMAPFACE_NEGATIVE_Z : CUBEMAPFACE_POSITIVE_Z;
// +X -X
if (adir.x > adir.y && adir.x > adir.z)
{
faceIndex = dir.x > 0.0 ? CUBEMAPFACE_NEGATIVE_X : CUBEMAPFACE_POSITIVE_X;
}
// +Y -Y
else if (adir.y > adir.x && adir.y > adir.z)
{
faceIndex = dir.y > 0.0 ? CUBEMAPFACE_NEGATIVE_Y : CUBEMAPFACE_POSITIVE_Y;
}
return faceIndex;
}
//
// Point shadows
//
float EvalShadow_PointDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = EvalShadow_GetCubeFaceID( L ) + 1;
ShadowData sd = shadowContext.shadowDatas[index + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// get the algorithm
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
// sample the texture according to the given algorithm
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_PointDepth_( _samplerType ) \
float EvalShadow_PointDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
int faceIndex = EvalShadow_GetCubeFaceID( L ) + 1; \
ShadowData sd = shadowContext.shadowDatas[index + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_PointDepth_( SamplerComparisonState )
EvalShadow_PointDepth_( SamplerState )
#undef EvalShadow_PointDepth_
//
// Spot shadows
//
float EvalShadow_SpotDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
ShadowData sd = shadowContext.shadowDatas[index];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// get the algorithm
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
// sample the texture according to the given algorithm
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_SpotDepth_( _samplerType ) \
float EvalShadow_SpotDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
ShadowData sd = shadowContext.shadowDatas[index]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_SpotDepth_( SamplerComparisonState )
EvalShadow_SpotDepth_( SamplerState )
#undef EvalShadow_SpotDepth_
//
// Punctual shadows for Point and Spot
//
float EvalShadow_PunctualDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = 0;
// get the algorithm
uint shadowType, shadowAlgorithm;
UnpackShadowType( shadowContext.shadowDatas[index].shadowType, shadowType );
[branch]
if( shadowType == GPUSHADOWTYPE_POINT )
{
faceIndex = EvalShadow_GetCubeFaceID( L ) + 1;
}
ShadowData sd = shadowContext.shadowDatas[index + faceIndex];
uint payloadOffset = GetPayloadOffset( sd );
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture according to the given algorithm
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_PunctualDepth_( _samplerType ) \
float EvalShadow_PunctualDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
int faceIndex = 0; \
/* get the shadow type */ \
uint shadowType; \
UnpackShadowType( shadowContext.shadowDatas[index].shadowType, shadowType ); \
\
[branch] \
if( shadowType == GPUSHADOWTYPE_POINT ) \
{ \
faceIndex = EvalShadow_GetCubeFaceID( L ) + 1; \
} \
\
ShadowData sd = shadowContext.shadowDatas[index + faceIndex]; \
uint payloadOffset = GetPayloadOffset( sd ); \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_PunctualDepth_( SamplerComparisonState )
EvalShadow_PunctualDepth_( SamplerState )
#undef EvalShadow_PunctualDepth_
//
// Directional shadows (cascaded shadow map)
//
int EvalShadow_GetSplitSphereIndexForDirshadows( float3 positionWS, float4 dirShadowSplitSpheres[4] )
{
float3 fromCenter0 = positionWS.xyz - dirShadowSplitSpheres[0].xyz;
float3 fromCenter1 = positionWS.xyz - dirShadowSplitSpheres[1].xyz;
float3 fromCenter2 = positionWS.xyz - dirShadowSplitSpheres[2].xyz;
float3 fromCenter3 = positionWS.xyz - dirShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
float4 dirShadowSplitSphereSqRadii;
dirShadowSplitSphereSqRadii.x = dirShadowSplitSpheres[0].w;
dirShadowSplitSphereSqRadii.y = dirShadowSplitSpheres[1].w;
dirShadowSplitSphereSqRadii.z = dirShadowSplitSpheres[2].w;
dirShadowSplitSphereSqRadii.w = dirShadowSplitSpheres[3].w;
if( distances2.w > dirShadowSplitSphereSqRadii.w )
return -1;
float4 weights = float4( distances2 < dirShadowSplitSphereSqRadii );
weights.yzw = saturate( weights.yzw - weights.xyz );
return int( 4.0 - dot( weights, float4(4.0, 3.0, 2.0, 1.0 ) ) );
}
uint EvalShadow_LoadSplitSpheres( ShadowContext shadowContext, int index, out float4 splitSpheres[4] )
{
uint offset = GetPayloadOffset( shadowContext.shadowDatas[index] );
splitSpheres[0] = asfloat( shadowContext.payloads[offset + 0] );
splitSpheres[1] = asfloat( shadowContext.payloads[offset + 1] );
splitSpheres[2] = asfloat( shadowContext.payloads[offset + 2] );
splitSpheres[3] = asfloat( shadowContext.payloads[offset + 3] );
return offset + 4;
}
float EvalShadow_CascadedDepth( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int index, float3 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
int shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres );
if( shadowSplitIndex < 0 )
return 1.0;
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex];
// normal based bias
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias );
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
uint texIdx, sampIdx;
float slice;
UnpackShadowmapId( sd.id, texIdx, sampIdx, slice );
uint shadowType, shadowAlgorithm;
UnpackShadowType( sd.shadowType, shadowType, shadowAlgorithm );
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, texIdx, sampIdx );
}
#define EvalShadow_CascadedDepth_( _samplerType ) \
float EvalShadow_CascadedDepth( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, float3 positionWS, float3 normalWS, int index, float3 L ) \
{ \
/* load the right shadow data for the current face */ \
float4 dirShadowSplitSpheres[4]; \
uint payloadOffset = EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres ); \
uint shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres ); \
ShadowData sd = shadowContext.shadowDatas[index + 1 + shadowSplitIndex]; \
/* normal based bias */ \
positionWS += EvalShadow_NormalBias( normalWS, saturate( dot( normalWS, L ) ), sd.texelSizeRcp.zw, sd.normalBias ); \
/* get shadowmap texcoords */ \
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS ); \
/* sample the texture */ \
float slice; \
UnpackShadowmapId( sd.id, slice ); \
\
return SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sd.bias, slice, shadowAlgorithm, tex, samp ); \
}
EvalShadow_CascadedDepth_( SamplerComparisonState )
EvalShadow_CascadedDepth_( SamplerState )
#undef EvalShadow_CascadedDepth_

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithms.hlsl.meta


fileFormatVersion: 2
guid: e2ca1e297ddf0b54f9d72244a419844b
timeCreated: 1491321445
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl.meta


fileFormatVersion: 2
guid: aa4f463e1cdf08f42934e66c91cd612e
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

126
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl


// Library header containing various useful functions for doing moment based shadow maps.
// Supported flavors are VSM, EVSM and MSM
// conversion helper for VSM flavors
// Chebychev's inequality (one-tailed version)
// P( x >= t ) <= pmax(t) := sigma^2 / (sigma^2 + (t - u)^2)
// for us t is depth, u is E(x) i.d. the blurred depth
float ShadowMoments_ChebyshevsInequality( float2 moments, float depth, float minVariance, float lightLeakBias )
{
// variance sig^2 = E(x^2) - E(x)^2
float variance = max( moments.y - (moments.x * moments.x), minVariance );
// probabilistic upper bound
float mD = depth - moments.x;
float p = variance / (variance + mD * mD);
#if UNITY_REVERSED_Z
p = saturate( (p - lightLeakBias) / (1.0f - lightLeakBias) );
return max( p, depth >= moments.x );
#else
p = saturate( p / (1.0f - lightLeakBias) );
return max( p, depth <= moments.x );
#endif
}
// helper for EVSM
float2 ShadowMoments_WarpDepth( float depth, float2 exponents )
{
// Rescale depth into [-1;1]
depth = 2.0 * depth - 1.0;
float pos = exp( exponents.x * depth );
float neg = -exp(-exponents.y * depth );
return float2( pos, neg );
}
// helpers for MSM
// Prepare the moments so there's little quantization error when storing the moments at half
// precision. This step becomes unnecessary if the moments are stored in 32bit floats.
float4 ShadowMoments_Encode16MSM( float depth )
{
float dsq = depth * depth;
float4 moments = { depth, dsq, depth * dsq, dsq * dsq };
float4x4 mat = { - 2.07224649 , 13.7948857237, 0.105877704 , 9.7924062118,
32.23703778 , -59.4683975703, -1.9077466311, -33.7652110555,
-68.571074599 , 82.0359750338, 9.3496555107, 47.9456096605,
39.3703274134, -35.364903257 , -6.6543490743, -23.9728048165 };
float4 optimized = mul( moments, mat );
optimized[0] += 0.035955884801;
return optimized;
}
float4 ShadowMoments_Decode16MSM( float4 moments )
{
moments[0] -= 0.035955884801;
float4x4 mat = { 0.2227744146, 0.1549679261, 0.1451988946, 0.163127443,
0.0771972861, 0.1394629426, 0.2120202157, 0.2591432266,
0.7926986636, 0.7963415838, 0.7258694464, 0.6539092497,
0.0319417555, -0.1722823173, -0.2758014811, -0.3376131734 };
return mul( moments, mat );
}
void ShadowMoments_SolveMSM( float4 moments, float depth, float momentBias, out float3 z, out float4 b )
{
// Bias input data to avoid artifacts
z[0] = depth;
b = lerp( moments, 0.5.xxxx, momentBias );
// Compute a Cholesky factorization of the Hankel matrix B storing only non-trivial entries or related products
float L32D22 = mad( -b[0], b[1], b[2] );
float D22 = mad( -b[0], b[0], b[1] );
float sqDepthVar = mad( -b[1], b[1], b[3] );
float D33D22 = dot( float2( sqDepthVar, -L32D22 ), float2( D22, L32D22 ) );
float InvD22 = 1.0 / D22;
float L32 = L32D22 * InvD22;
// Obtain a scaled inverse image of bz = ( 1, z[0], z[0]*z[0] )^T
float3 c = float3( 1.0, z[0], z[0] * z[0] );
// Forward substitution to solve L * c1 = bz;
c[1] -= b.x;
c[2] -= b.y + L32 * c[1];
// Scaling to solve D * c2 = c1
c[1] *= InvD22;
c[2] *= D22 / D33D22;
// Backward substitution to solve L^T * c3 = c2
c[1] -= L32 * c[2];
c[0] -= dot( c.yz, b.xy );
// Solve the quadratic equation c[0] + c[1] * z + c[2] * z^2 to obtain solutions z[1] and z[2]
float p = c[1] / c[2];
float q = c[0] / c[2];
float D = ((p*p) * 0.25) - q;
float r = sqrt( D );
z[1] = -(p * 0.5) - r;
z[2] = -(p * 0.5) + r;
}
float ShadowMoments_SolveDelta3MSM( float3 z, float2 b, float lightLeakBias )
{
// Construct a solution composed of three Dirac-deltas and evaluate its CDF
float4 switchVal = (z[2] < z[0]) ? float4( z[1], z[0], 1.0, 1.0 )
: ((z[1] < z[0]) ? float4( z[0], z[1], 0.0, 1.0 ) : 0.0.xxxx);
float quotient = (switchVal[0] * z[2] - b[0] * (switchVal[0] + z[2]) + b[1]) / ((z[2] - switchVal[1]) * (z[0] - z[1]));
float attenuation = saturate( switchVal[2] + switchVal[3] * quotient );
#if UNITY_REVERSED_Z // probably
return saturate( (attenuation - lightLeakBias) / (1.0f - lightLeakBias) );
#else
return saturate( ((1.0 - attenuation) - lightLeakBias) / (1.0f - lightLeakBias) );
#endif
}
float ShadowMoments_SolveDelta4MSM( float3 z, float4 b, float lightLeakBias)
{
// Use a solution made of four deltas
float zFree = ((b[2] - b[1]) * z[0] + b[2] - b[3]) / ((b[1] - b[0]) * z[0] + b[1] - b[2]);
float w1Factor = (z[0] > zFree) ? 1.0 : 0.0;
float attenuation = saturate( (b[1] - b[0] + (b[2] - b[0] - (zFree + 1.0) * (b[1] - b[0])) * (zFree - w1Factor - z[0]) / (z[0] * (z[0] - zFree))) / (zFree - w1Factor) + 1.0 - b[0] );
#if UNITY_REVERSED_Z // probably
return saturate( (attenuation - lightLeakBias) / (1.0f - lightLeakBias) );
#else
return saturate( ((1.0 - attenuation) - lightLeakBias) / (1.0f - lightLeakBias) );
#endif
}

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowMoments.hlsl.meta


fileFormatVersion: 2
guid: 46258e7f416004a4db9dc7cc2c5a3b62
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl.meta


fileFormatVersion: 2
guid: 870dbce0ad39569448fa01659ed39fd0
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

133
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowTexFetch.hlsl


// This file contains various helper declarations for declaring and sampling members of the ShadowContext struct.
// shadow lookup routines when dynamic array access is possible
#if SHADOW_SUPPORTS_DYNAMIC_INDEXING != 0
// Shader model >= 5.1
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots , _SamplerCompSlots ) float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice ) { return SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[texIdx], ctxt.compSamplers[sampIdx], tcs, slice ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots , _SamplerSlots ) float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 ) { return SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[texIdx], ctxt.samplers[sampIdx], tcs, slice, lod ); }
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx ) { return SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[texIdx], ctxt.compSamplers[sampIdx], tcs, cubeIdx );}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 ) { return SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[texIdx], ctxt.samplers[sampIdx], tcs, cubeIdx, lod ); }
#else // helper macros if dynamic indexing does not work
// Sampler and texture combinations are static. No shadowmap will ever be sampled with two different samplers.
// Once shadowmaps and samplers are fixed consider writing custom dispatchers directly accessing textures and samplers.
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots, _SamplerCompSlots ) \
float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[i], ctxt.compSamplers[j], tcs, slice ); \
break; \
} \
} \
} \
return res; \
}
# define SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ) \
float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[i], ctxt.samplers[j], tcs, slice, lod ); \
break; \
} \
} \
} \
return res; \
}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) \
float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[i], ctxt.compSamplers[j], tcs, cubeIdx ); \
break; \
} \
} \
} \
return res; \
}
# define SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) \
float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 ) \
{ \
float4 res = 1.0.xxxx; \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
res = SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[i], ctxt.samplers[j], tcs, cubeIdx, lod ); \
break; \
} \
} \
} \
return res; \
}
#endif // SHADOW_SUPPORTS_DYNAMIC_INDEXING != 0
// helper macro to suppress code generation if _cnt is 0
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots , _SamplerCompSlots ) float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice );
#define SHADOW_DECLARE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots , _SamplerSlots ) float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 );
#define SHADOW_DECLARE_SAMPLING_FUNC_TCA_COMP( _TexCubeArraySlots, _SamplerCompSlots ) float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx );
#define SHADOW_DECLARE_SAMPLING_FUNC_TCA_SAMP( _TexCubeArraySlots, _SamplerSlots ) float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 );
#define SHADOW_CAT( _left, _right ) _left ## _right
#define SHADOW_CHECK_0( _macro )
#define SHADOW_CHECK_1( _macro ) _macro
#define SHADOW_CHECK_2( _macro ) _macro
#define SHADOW_CHECK_3( _macro ) _macro
#define SHADOW_CHECK_4( _macro ) _macro
#define SHADOW_CHECK_5( _macro ) _macro
#define SHADOW_CHECK_6( _macro ) _macro
#define SHADOW_CHECK_7( _macro ) _macro
#define SHADOW_CHECK_8( _macro ) _macro
#define SHADOW_CHECK_9( _macro ) _macro
#define SHADOW_CHECK( _cnt, _macro ) SHADOW_CAT( SHADOW_CHECK_ , _cnt ) ( _macro )
#define SHADOW_CHECK_ALT_0( _macro, _alt ) _alt
#define SHADOW_CHECK_ALT_1( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_2( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_3( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_4( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_5( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_6( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_7( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_8( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT_9( _macro, _alt ) _macro
#define SHADOW_CHECK_ALT( _cnt, _macro, _alt ) SHADOW_CAT( SHADOW_CHECK_ALT_ , _cnt ) ( _macro, _alt )
// helper macro to declare texture members for the shadow context.
#define SHADOWCONTEXT_DECLARE_TEXTURES( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
SHADOW_CHECK( _Tex2DArraySlots , Texture2DArray tex2DArray[_Tex2DArraySlots]; ) \
SHADOW_CHECK( _TexCubeArraySlots, TextureCubeArray texCubeArray[_TexCubeArraySlots]; ) \
SHADOW_CHECK( _SamplerCompSlots , SamplerComparisonState compSamplers[_Tex2DArraySlots]; ) \
SHADOW_CHECK( _SamplerSlots , SamplerState samplers[_Tex2DArraySlots]; )
// helper macro to declare texture sampling functions for the shadow context.
#define SHADOW_DEFINE_SAMPLING_FUNCS( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
SHADOW_CHECK( _Tex2DArraySlots , SHADOW_CHECK_ALT( _SamplerCompSlots, SHADOW_DEFINE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots, _SamplerCompSlots ), SHADOW_DECLARE_SAMPLING_FUNC_T2DA_COMP( _Tex2DArraySlots, _SamplerCompSlots ) ) ) \
SHADOW_CHECK( _Tex2DArraySlots , SHADOW_CHECK_ALT( _SamplerSlots , SHADOW_DEFINE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ), SHADOW_DECLARE_SAMPLING_FUNC_T2DA_SAMP( _Tex2DArraySlots, _SamplerSlots ) ) ) \
SHADOW_CHECK( _TexCubeArraySlots, SHADOW_CHECK_ALT( _SamplerCompSlots, SHADOW_DEFINE_SAMPLING_FUNC_TCA_COMP(_TexCubeArraySlots, _SamplerCompSlots ), SHADOW_DECLARE_SAMPLING_FUNC_TCA_COMP(_TexCubeArraySlots, _SamplerCompSlots ) ) ) \
SHADOW_CHECK( _TexCubeArraySlots, SHADOW_CHECK_ALT( _SamplerSlots , SHADOW_DEFINE_SAMPLING_FUNC_TCA_SAMP(_TexCubeArraySlots, _SamplerSlots ), SHADOW_DECLARE_SAMPLING_FUNC_TCA_SAMP(_TexCubeArraySlots, _SamplerSlots ) ) )

9
Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowTexFetch.hlsl.meta


fileFormatVersion: 2
guid: a9c17fbca36dfb744b42fb48d3829887
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs.meta


fileFormatVersion: 2
guid: 11e59a3cb6482b245b20ac498cb3afd5
timeCreated: 1491321441
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl.meta


fileFormatVersion: 2
guid: 78929777594e2d84aba05af5bf6463d0
timeCreated: 1491321444
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.meta


fileFormatVersion: 2
guid: 7640004f9f444ad40aba7003ccb31e7f
timeCreated: 1491321441
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

249
Assets/ScriptableRenderPipeline/common/Shadow/ShadowUtilities.cs


namespace UnityEngine.Experimental.Rendering
{
public class ShadowUtilsConstants
{
// Matches ScriptableShadowsUtility.cpp
public enum CubemapEdge
{
kCubeEdgePX_PY = 0,
kCubeEdgePX_NY,
kCubeEdgePX_PZ,
kCubeEdgePX_NZ,
kCubeEdgeNX_PY,
kCubeEdgeNX_NY,
kCubeEdgeNX_PZ,
kCubeEdgeNX_NZ,
kCubeEdgePY_PZ,
kCubeEdgePY_NZ,
kCubeEdgeNY_PZ,
kCubeEdgeNY_NZ,
kCubeEdge_Count
};
public static readonly CubemapEdge[,] kCubemapEdgesPerFace = new CubemapEdge[6,4]
{
{ CubemapEdge.kCubeEdgePX_PY, CubemapEdge.kCubeEdgePX_NY, CubemapEdge.kCubeEdgePX_PZ, CubemapEdge.kCubeEdgePX_NZ }, // PX
{ CubemapEdge.kCubeEdgeNX_PY, CubemapEdge.kCubeEdgeNX_NY, CubemapEdge.kCubeEdgeNX_PZ, CubemapEdge.kCubeEdgeNX_NZ }, // NX
{ CubemapEdge.kCubeEdgePX_PY, CubemapEdge.kCubeEdgeNX_PY, CubemapEdge.kCubeEdgePY_PZ, CubemapEdge.kCubeEdgePY_NZ }, // PY
{ CubemapEdge.kCubeEdgePX_NY, CubemapEdge.kCubeEdgeNX_NY, CubemapEdge.kCubeEdgeNY_PZ, CubemapEdge.kCubeEdgeNY_NZ }, // NY
{ CubemapEdge.kCubeEdgePX_PZ, CubemapEdge.kCubeEdgeNX_PZ, CubemapEdge.kCubeEdgePY_PZ, CubemapEdge.kCubeEdgeNY_PZ }, // PZ
{ CubemapEdge.kCubeEdgePX_NZ, CubemapEdge.kCubeEdgeNX_NZ, CubemapEdge.kCubeEdgePY_NZ, CubemapEdge.kCubeEdgeNY_NZ } // NZ
};
const float oneOverSqr2 = 0.70710678118654752440084436210485f;
public static readonly Vector3[] kCubemapEdgeDirections = new Vector3[(int)CubemapEdge.kCubeEdge_Count]
{
new Vector3( oneOverSqr2, oneOverSqr2, 0 ),
new Vector3( oneOverSqr2, -oneOverSqr2, 0 ),
new Vector3( oneOverSqr2, 0, oneOverSqr2 ),
new Vector3( oneOverSqr2, 0, -oneOverSqr2 ),
new Vector3( -oneOverSqr2, oneOverSqr2, 0 ),
new Vector3( -oneOverSqr2, -oneOverSqr2, 0 ),
new Vector3( -oneOverSqr2, 0, oneOverSqr2 ),
new Vector3( -oneOverSqr2, 0, -oneOverSqr2 ),
new Vector3( 0, oneOverSqr2, oneOverSqr2 ),
new Vector3( 0, oneOverSqr2, -oneOverSqr2 ),
new Vector3( 0, -oneOverSqr2, oneOverSqr2 ),
new Vector3( 0, -oneOverSqr2, -oneOverSqr2 )
};
// Cubemap faces with flipped z coordinate.
// These matrices do NOT match what we have in Skybox.cpp.
// The C++ runtime flips y as well and requires patching up
// the culling state. Using these matrices keeps the winding
// order, but may need some special treatment if rendering
// into an actual cubemap.
public static readonly Matrix4x4[] kCubemapFaces = new Matrix4x4[]
{
new Matrix4x4( // pos X
new Vector4( 0.0f, 0.0f, -1.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( -1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // neg x
new Vector4( 0.0f, 0.0f, 1.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // pos y
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, -1.0f, 0.0f ),
new Vector4( 0.0f, -1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // neg y
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 1.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // pos z
new Vector4( 1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, -1.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) ),
new Matrix4x4( // neg z
new Vector4( -1.0f, 0.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 1.0f, 0.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 1.0f, 0.0f ),
new Vector4( 0.0f, 0.0f, 0.0f, 1.0f ) )
};
}
public class ShadowUtils
{
public static Matrix4x4 ExtractSpotLightMatrix( VisibleLight vl, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData )
{
splitData = new ShadowSplitData();
splitData.cullingSphere.Set( 0.0f, 0.0f, 0.0f, float.NegativeInfinity );
splitData.cullingPlaneCount = 0;
// get lightDir
lightDir = vl.light.transform.forward;
// calculate view
Matrix4x4 scaleMatrix = Matrix4x4.identity;
scaleMatrix.m22 = -1.0f;
view = scaleMatrix * vl.localToWorld.inverse;
// following code is from SharedLightData::GetNearPlaneMinBound
float percentageBound = 0.01f * vl.light.range;
float fixedBound = 0.1f;
float nearmin = fixedBound <= percentageBound ? fixedBound : percentageBound;
// calculate projection
float zfar = vl.range;
float znear = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
float fov = vl.spotAngle;
proj = Matrix4x4.Perspective(fov, 1.0f, znear, zfar);
// and the compound
return proj * view;
}
public static Matrix4x4 ExtractPointLightMatrix( VisibleLight vl, uint faceIdx, float fovBias, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData )
{
Debug.Assert( faceIdx <= (uint) CubemapFace.NegativeZ, "Tried to extract cubemap face " + faceIdx + "." );
splitData = new ShadowSplitData();
splitData.cullingSphere.Set( 0.0f, 0.0f, 0.0f, float.NegativeInfinity );
splitData.cullingPlaneCount = 4;
// get lightDir
lightDir = vl.light.transform.forward;
// calculate the view matrices
Vector3 lpos = vl.light.transform.position;
view = ShadowUtilsConstants.kCubemapFaces[faceIdx];
Vector3 inverted_viewpos = ShadowUtilsConstants.kCubemapFaces[faceIdx].MultiplyPoint( -lpos );
view.SetColumn( 3, new Vector4( inverted_viewpos.x, inverted_viewpos.y, inverted_viewpos.z, 1.0f ) );
for( int i = 0; i < 4; ++i )
{
ShadowUtilsConstants.CubemapEdge cubemapEdge = ShadowUtilsConstants.kCubemapEdgesPerFace[faceIdx,i];
Vector3 cullingPlaneDirection = ShadowUtilsConstants.kCubemapEdgeDirections[(int)cubemapEdge];
splitData.SetCullingPlane( i, new Plane( cullingPlaneDirection, lpos ) );
}
// following code is from SharedLightData::GetNearPlaneMinBound
float percentageBound = 0.01f * vl.light.range;
float fixedBound = 0.1f;
float nearmin = fixedBound <= percentageBound ? fixedBound : percentageBound;
// calculate projection
float farPlane = vl.range;
float nearPlane = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
proj = Matrix4x4.Perspective( 90.0f + fovBias, 1.0f, nearPlane, farPlane );
// and the compound
return proj * view;
}
public static Matrix4x4 ExtractDirectionalLightMatrix( VisibleLight vl, uint cascadeIdx, int cascadeCount, Vector3 splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex )
{
Debug.Assert( width == height, "Currently the cascaded shadow mapping code requires square cascades." );
splitData = new ShadowSplitData();
splitData.cullingSphere.Set(0.0f, 0.0f, 0.0f, float.NegativeInfinity);
splitData.cullingPlaneCount = 0;
// get lightDir
lightDir = vl.light.transform.forward;
// TODO: At some point this logic should be moved to C#, then the parameters cullResults and lightIndex can be removed as well
// For directional lights shadow data is extracted from the cullResults, so that needs to be somehow provided here.
// Check ScriptableShadowsUtility.cpp ComputeDirectionalShadowMatricesAndCullingPrimitives(...) for details.
cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( lightIndex, (int) cascadeIdx, cascadeCount, splitRatio, (int) width, nearPlaneOffset, out view, out proj, out splitData );
// and the compound
return proj * view;
}
public static bool MapLightType( LightType lt, out HDPipeline.GPULightType gputype, out GPUShadowType shadowtype )
{
switch( lt )
{
case LightType.Spot : gputype = HDPipeline.GPULightType.Spot; shadowtype = GPUShadowType.Spot; return true;
case LightType.Directional : gputype = HDPipeline.GPULightType.Directional; shadowtype = GPUShadowType.Directional; return true;
case LightType.Point : gputype = HDPipeline.GPULightType.Point; shadowtype = GPUShadowType.Point; return true;
default:
case LightType.Area : gputype = HDPipeline.GPULightType.Rectangle; shadowtype = GPUShadowType.Unknown; return false; // area lights by themselves can't be mapped to any GPU type
}
}
public static bool MapLightType(LightArchetype la, LightType lt, out GPUShadowType shadowtype)
{
switch (la)
{
case LightArchetype.Punctual:
return MapLightType(lt, out shadowtype);
case LightArchetype.Area:
shadowtype = GPUShadowType.Unknown;
return true;
case LightArchetype.Projector:
shadowtype = GPUShadowType.Unknown;
return true;
default:
shadowtype = GPUShadowType.Unknown;
return false; // <- probably not what you want
}
}
public static bool MapLightType(LightType lt, out GPUShadowType shadowtype)
{
switch (lt)
{
case LightType.Spot:
shadowtype = GPUShadowType.Spot;
return true;
case LightType.Directional:
shadowtype = GPUShadowType.Directional;
return true;
case LightType.Point:
shadowtype = GPUShadowType.Point;
return true;
default:
case LightType.Area:
shadowtype = GPUShadowType.Unknown;
return false; // area lights by themselves can't be mapped to any GPU type
}
}
public static GPUShadowAlgorithm Pack( ShadowAlgorithm algo, ShadowVariant vari, ShadowPrecision prec )
{
int precshift = ShadowConstants.Bits.k_ShadowVariant + ShadowConstants.Bits.k_ShadowAlgorithm;
int algoshift = ShadowConstants.Bits.k_ShadowVariant;
return (GPUShadowAlgorithm) ( (int) prec << precshift | ((int) algo << algoshift) | (int)vari);
}
public static ShadowAlgorithm ExtractAlgorithm( GPUShadowAlgorithm gpuAlgo ) { return (ShadowAlgorithm) ( ShadowConstants.Masks.k_ShadowAlgorithm & ((int)gpuAlgo >> ShadowConstants.Bits.k_ShadowVariant) ); }
public static ShadowVariant ExtractVariant( GPUShadowAlgorithm gpuAlgo ) { return (ShadowVariant ) ( ShadowConstants.Masks.k_ShadowVariant & (int)gpuAlgo ); }
public static ShadowPrecision ExtractPrecision( GPUShadowAlgorithm gpuAlgo ) { return (ShadowPrecision) ( ShadowConstants.Masks.k_ShadowPrecision & ((int)gpuAlgo >> (ShadowConstants.Bits.k_ShadowVariant + ShadowConstants.Bits.k_ShadowAlgorithm)) ); }
public static void Unpack( GPUShadowAlgorithm gpuAlgo, out ShadowAlgorithm algo, out ShadowVariant vari, out ShadowPrecision prec )
{
algo = ExtractAlgorithm( gpuAlgo );
vari = ExtractVariant( gpuAlgo );
prec = ExtractPrecision( gpuAlgo );
}
public static GPUShadowAlgorithm ClearPrecision( GPUShadowAlgorithm gpuAlgo )
{
var algo = ExtractAlgorithm( gpuAlgo );
var vari = ExtractVariant( gpuAlgo );
return Pack( algo, vari, ShadowPrecision.Low );
}
public static float Asfloat( uint val ) { return System.BitConverter.ToSingle( System.BitConverter.GetBytes( val ), 0 ); }
public static float Asfloat( int val ) { return System.BitConverter.ToSingle( System.BitConverter.GetBytes( val ), 0 ); }
public static int Asint( float val ) { return System.BitConverter.ToInt32( System.BitConverter.GetBytes( val ), 0 ); }
public static uint Asuint( float val ) { return System.BitConverter.ToUInt32( System.BitConverter.GetBytes( val ), 0 ); }
}
} // end of namespace UnityEngine.Experimental.ScriptableRenderLoop

12
Assets/ScriptableRenderPipeline/common/Shadow/ShadowUtilities.cs.meta


fileFormatVersion: 2
guid: d53d8bd422ecef740865c3acd7e2c62b
timeCreated: 1491321441
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs.meta


fileFormatVersion: 2
guid: b6860f4fd5236f648b2c48c6799c68a7
timeCreated: 1491321441
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.hlsl.meta


fileFormatVersion: 2
guid: 1c64d27a91e935140a9f402077f52fa0
timeCreated: 1477395059
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs.meta


fileFormatVersion: 2
guid: 6931cfbd757a1864f8822b5399719960
timeCreated: 1485511432
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

187
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithms.hlsl


// Various shadow algorithms
// There are two variants provided, one takes the texture and sampler explicitly so they can be statically passed in.
// The variant without resource parameters dynamically accesses the texture when sampling.
// function called by spot, point and directional eval routines to calculate shadow coordinates
float3 EvalShadow_GetTexcoords( ShadowData sd, float3 positionWS )
{
float4 posCS = mul( float4( positionWS, 1.0 ), sd.worldToShadow );
// apply a bias
posCS.z -= sd.bias;
float3 posNDC = posCS.xyz / posCS.w;
// calc TCs
float3 posTC = posNDC * 0.5 + 0.5;
posTC.xy = posTC.xy * sd.scaleOffset.xy + sd.scaleOffset.zw;
#if UNITY_REVERSED_Z
posTC.z = 1.0 - posTC.z;
#endif
return posTC;
}
//
// Point shadows
//
float EvalShadow_PointDepth( ShadowContext shadowContext, float3 positionWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = 0;
GetCubeFaceID( L, faceIndex );
ShadowData sd = shadowContext.shadowDatas[index + faceIndex];
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
uint texIdx, sampIdx;
float slice;
unpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_PCF_1tap( shadowContext, posTC, slice, texIdx, sampIdx );
}
float EvalShadow_PointDepth( ShadowContext shadowContext, Texture2DArray tex, SamplerComparisonState compSamp, float3 positionWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = 0;
GetCubeFaceID( L, faceIndex );
ShadowData sd = shadowContext.shadowDatas[index + faceIndex];
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
float slice;
unpackShadowmapId( sd.id, slice );
return SampleShadow_PCF_1tap( shadowContext, posTC, slice, tex, compSamp );
}
//
// Spot shadows
//
float EvalShadow_SpotDepth( ShadowContext shadowContext, float3 positionWS, int index, float3 L )
{
// load the right shadow data for the current face
ShadowData sd = shadowContext.shadowDatas[index];
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
uint texIdx, sampIdx;
float slice;
unpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_PCF_1tap( shadowContext, posTC, slice, texIdx, sampIdx );
}
float EvalShadow_SpotDepth( ShadowContext shadowContext, Texture2DArray tex, SamplerComparisonState compSamp, float3 positionWS, int index, float3 L )
{
// load the right shadow data for the current face
ShadowData sd = shadowContext.shadowDatas[index];
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
float slice;
unpackShadowmapId( sd.id, slice );
return SampleShadow_PCF_1tap( shadowContext, posTC, slice, tex, compSamp );
}
//
// Punctual shadows for Point and Spot
//
float EvalShadow_PunctualDepth( ShadowContext shadowContext, float3 positionWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = 0;
[branch]
if( shadowContext.shadowDatas[index].shadowType == GPUSHADOWTYPE_POINT )
GetCubeFaceID( L, faceIndex );
ShadowData sd = shadowContext.shadowDatas[index + faceIndex];
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
uint texIdx, sampIdx;
float slice;
unpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_PCF_1tap( shadowContext, posTC, slice, texIdx, sampIdx );
}
float EvalShadow_PunctualDepth( ShadowContext shadowContext, Texture2DArray tex, SamplerComparisonState compSamp, float3 positionWS, int index, float3 L )
{
// load the right shadow data for the current face
int faceIndex = 0;
[branch]
if( shadowContext.shadowDatas[index].shadowType == GPUSHADOWTYPE_POINT )
GetCubeFaceID( L, faceIndex );
ShadowData sd = shadowContext.shadowDatas[index + faceIndex];
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
float slice;
unpackShadowmapId( sd.id, slice );
return SampleShadow_PCF_1tap( shadowContext, posTC, slice, tex, compSamp );
}
//
// Directional shadows (cascaded shadow map)
//
uint EvalShadow_GetSplitSphereIndexForDirshadows( float3 positionWS, float4 dirShadowSplitSpheres[4] )
{
float3 fromCenter0 = positionWS.xyz - dirShadowSplitSpheres[0].xyz;
float3 fromCenter1 = positionWS.xyz - dirShadowSplitSpheres[1].xyz;
float3 fromCenter2 = positionWS.xyz - dirShadowSplitSpheres[2].xyz;
float3 fromCenter3 = positionWS.xyz - dirShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
float4 dirShadowSplitSphereSqRadii;
dirShadowSplitSphereSqRadii.x = dirShadowSplitSpheres[0].w;
dirShadowSplitSphereSqRadii.y = dirShadowSplitSpheres[1].w;
dirShadowSplitSphereSqRadii.z = dirShadowSplitSpheres[2].w;
dirShadowSplitSphereSqRadii.w = dirShadowSplitSpheres[3].w;
float4 weights = float4( distances2 < dirShadowSplitSphereSqRadii );
weights.yzw = saturate( weights.yzw - weights.xyz );
return uint( 4.0 - dot( weights, float4(4.0, 3.0, 2.0, 1.0 ) ) );
}
void EvalShadow_LoadSplitSpheres( ShadowContext shadowContext, int index, out float4 splitSpheres[4] )
{
uint offset = GetPayloadOffset( shadowContext.shadowDatas[index] );
splitSpheres[0] = asfloat( shadowContext.payloads[offset + 0] );
splitSpheres[1] = asfloat( shadowContext.payloads[offset + 1] );
splitSpheres[2] = asfloat( shadowContext.payloads[offset + 2] );
splitSpheres[3] = asfloat( shadowContext.payloads[offset + 3] );
}
float EvalShadow_CascadedDepth( ShadowContext shadowContext, float3 positionWS, int index, float3 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
uint shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres );
ShadowData sd = shadowContext.shadowDatas[index + shadowSplitIndex];
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
uint texIdx, sampIdx;
float slice;
unpackShadowmapId( sd.id, texIdx, sampIdx, slice );
return SampleShadow_PCF_9tap_Adaptive( shadowContext, sd.texelSizeRcp, posTC, slice, texIdx, sampIdx );
}
float EvalShadow_CascadedDepth( ShadowContext shadowContext, Texture2DArray tex, SamplerComparisonState compSamp, float3 positionWS, int index, float3 L )
{
// load the right shadow data for the current face
float4 dirShadowSplitSpheres[4];
EvalShadow_LoadSplitSpheres( shadowContext, index, dirShadowSplitSpheres );
uint shadowSplitIndex = EvalShadow_GetSplitSphereIndexForDirshadows( positionWS, dirShadowSplitSpheres );
ShadowData sd = shadowContext.shadowDatas[index + shadowSplitIndex];
// get shadowmap texcoords
float3 posTC = EvalShadow_GetTexcoords( sd, positionWS );
// sample the texture
float slice;
unpackShadowmapId(sd.id, slice);
return SampleShadow_PCF_9tap_Adaptive( shadowContext, sd.texelSizeRcp, posTC, slice, tex, compSamp );
}

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithms.hlsl.meta


fileFormatVersion: 2
guid: 9900a5b8191991b4d9e2c37413d85dc3
timeCreated: 1485511902
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithmsCustom.hlsl.meta


fileFormatVersion: 2
guid: 1163a3730c1812748b5cc5a7ecfbaf0c
timeCreated: 1485511901
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl.meta


fileFormatVersion: 2
guid: 68d59da52ffb57240bdf73300a2736bf
timeCreated: 1485788693
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.meta


fileFormatVersion: 2
guid: 0998db889743f994b8ea4257f9ab33fa
timeCreated: 1485511431
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowContext.hlsl.meta


fileFormatVersion: 2
guid: 4091aef5166b0624db069f6dbfd0673a
timeCreated: 1485511901
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowDispatch.hlsl.meta


fileFormatVersion: 2
guid: 1c09a112d6337c7468843f1d64d7795f
timeCreated: 1485511901
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowSampling.hlsl.meta


fileFormatVersion: 2
guid: 32c86a80860fd014ba44f8b7a7914a5c
timeCreated: 1487253249
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

81
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowTexFetch.hlsl


// shadow lookup routines when dynamic array access is possible
#if SHADOW_SUPPORTS_DYNAMIC_INDEXING != 0
// Shader model >= 5.1
# define SHADOW_DEFINE_SAMPLING_FUNCS( _Tex2DArraySlots, _TexCubeArraySlots ) \
float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice ) { return SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[texIdx], ctxt.compSamplers[sampIdx], tcs, slice ); } \
float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 ) { return SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[texIdx], ctxt.samplers[sampIdx], tcs, slice, lod ); } \
float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx ) { return SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[texIdx], ctxt.compSamplers[sampIdx], tcs, cubeIdx );} \
float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 ) { return SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[texIdx], ctxt.samplers[sampIdx], tcs, cubeIdx, lod ); }
#else // helper macros if dynamic indexing does not work
// Sampler and texture combinations are static. No shadowmap will ever be sampled with two different samplers.
// Once shadowmaps and samplers are fixed consider writing custom dispatchers directly accessing textures and samplers.
# define SHADOW_DEFINE_SAMPLING_FUNCS( _Tex2DArraySlots, _TexCubeArraySlots, _SamplerCompSlots, _SamplerSlots ) \
\
float4 SampleCompShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float slice ) \
{ \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
return SAMPLE_TEXTURE2D_ARRAY_SHADOW( ctxt.tex2DArray[i], ctxt.compSamplers[j], tcs, slice ); \
} \
} \
} \
return 1.0; \
} \
\
float4 SampleShadow_T2DA( ShadowContext ctxt, uint texIdx, uint sampIdx, float2 tcs, float slice, float lod = 0.0 ) \
{ \
[unroll] for( uint i = 0; i < _Tex2DArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
return SAMPLE_TEXTURE2D_ARRAY_LOD( ctxt.tex2DArray[i], ctxt.samplers[j], tcs, slice, lod ); \
} \
} \
} \
return 1.0; \
} \
\
float4 SampleCompShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float4 tcs, float cubeIdx ) \
{ \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerCompSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
return SAMPLE_TEXTURECUBE_ARRAY_SHADOW( ctxt.texCubeArray[i], ctxt.compSamplers[j], tcs, cubeIdx ); \
} \
} \
} \
return 1.0; \
} \
\
float4 SampleShadow_TCA( ShadowContext ctxt, uint texIdx, uint sampIdx, float3 tcs, float cubeIdx, float lod = 0.0 ) \
{ \
[unroll] for( uint i = 0; i < _TexCubeArraySlots; i++ ) \
{ \
[unroll] for( uint j = 0; j < _SamplerSlots; j++ ) \
{ \
[branch] if( i == texIdx && j == sampIdx ) \
{ \
return SAMPLE_TEXTURECUBE_ARRAY_LOD( ctxt.texCubeArray[i], ctxt.samplers[j], tcs, cubeIdx, lod ); \
} \
} \
} \
return 1.0; \
}
#endif

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowTexFetch.hlsl.meta


fileFormatVersion: 2
guid: 2ac0d1cc115e6ec42b5c47d2ee13f139
timeCreated: 1485873843
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs.meta


fileFormatVersion: 2
guid: 99dfd76ad655ff441aef9bb0015a1f05
timeCreated: 1485511433
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/VectorArray.cs.meta


fileFormatVersion: 2
guid: f5c1ec8ec44960d4bbf72eafaf47d8fd
timeCreated: 1485511435
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

96
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class ShadowUtils
{
public static Matrix4x4 ExtractSpotLightMatrix(VisibleLight vl, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData)
{
splitData = new ShadowSplitData();
splitData.cullingSphere.Set(0.0f, 0.0f, 0.0f, float.NegativeInfinity);
splitData.cullingPlaneCount = 0;
// get lightDir
lightDir = vl.light.transform.forward;
// calculate view
Matrix4x4 scaleMatrix = Matrix4x4.identity;
scaleMatrix.m22 = -1.0f;
view = scaleMatrix * vl.localToWorld.inverse;
// following code is from SharedLightData::GetNearPlaneMinBound
float percentageBound = 0.01f * vl.light.range;
float fixedBound = 0.1f;
float nearmin = fixedBound <= percentageBound ? fixedBound : percentageBound;
// calculate projection
float zfar = vl.range;
float znear = vl.light.shadowNearPlane >= nearmin ? vl.light.shadowNearPlane : nearmin;
float fov = vl.spotAngle;
proj = Matrix4x4.Perspective(fov, 1.0f, znear, zfar);
// and the compound
return proj * view;
}
public static Matrix4x4 ExtractPointLightMatrix(VisibleLight vl, uint faceIdx, float fovBias, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex)
{
Debug.Assert(faceIdx <= (uint)CubemapFace.NegativeZ, "Tried to extract cubemap face " + faceIdx + ".");
splitData = new ShadowSplitData();
splitData.cullingSphere.Set(0.0f, 0.0f, 0.0f, float.NegativeInfinity);
splitData.cullingPlaneCount = 0;
// get lightDir
lightDir = vl.light.transform.forward;
// TODO: At some point this logic should be moved to C#, then the parameters cullResults and lightIndex can be removed as well
cullResults.ComputePointShadowMatricesAndCullingPrimitives(lightIndex, (CubemapFace)faceIdx, fovBias, out view, out proj, out splitData);
// and the compound
return proj * view;
}
public static Matrix4x4 ExtractDirectionalLightMatrix(VisibleLight vl, uint cascadeIdx, int cascadeCount, Vector3 splitRatio, float nearPlaneOffset, uint width, uint height, out Matrix4x4 view, out Matrix4x4 proj, out Vector4 lightDir, out ShadowSplitData splitData, CullResults cullResults, int lightIndex)
{
Debug.Assert(width == height, "Currently the cascaded shadow mapping code requires square cascades.");
splitData = new ShadowSplitData();
splitData.cullingSphere.Set(0.0f, 0.0f, 0.0f, float.NegativeInfinity);
splitData.cullingPlaneCount = 0;
// get lightDir
lightDir = vl.light.transform.forward;
// TODO: At some point this logic should be moved to C#, then the parameters cullResults and lightIndex can be removed as well
// For directional lights shadow data is extracted from the cullResults, so that needs to be somehow provided here.
// Check ScriptableShadowsUtility.cpp ComputeDirectionalShadowMatricesAndCullingPrimitives(...) for details.
cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex, (int)cascadeIdx, cascadeCount, splitRatio, (int)width, nearPlaneOffset, out view, out proj, out splitData);
// and the compound
return proj * view;
}
public static bool MapLightType(LightType lt, AdditionalLightData ald, out GPULightType gputype, out GPUShadowType shadowtype)
{
shadowtype = GPUShadowType.Unknown; // Default for all non-punctual lights
gputype = GPULightType.Spot;
switch (ald.archetype)
{
case LightArchetype.Punctual: return MapLightType(lt, out gputype, out shadowtype);
case LightArchetype.Area: gputype = (ald.lightWidth > 0) ? GPULightType.Rectangle : GPULightType.Line; return true;
case LightArchetype.Projector:
switch (lt)
{
case LightType.Directional: gputype = GPULightType.ProjectorOrtho; return true;
case LightType.Spot: gputype = GPULightType.ProjectorPyramid; return true;
default: Debug.Assert(false, "Projectors can only be Spot or Directional lights."); return false;
}
default: return false; // <- probably not what you want
}
}
public static bool MapLightType(LightType lt, out GPULightType gputype, out GPUShadowType shadowtype)
{
switch (lt)
{
case LightType.Spot: gputype = GPULightType.Spot; shadowtype = GPUShadowType.Spot; return true;
case LightType.Directional: gputype = GPULightType.Directional; shadowtype = GPUShadowType.Directional; return true;
case LightType.Point: gputype = GPULightType.Point; shadowtype = GPUShadowType.Point; return true;
default:
case LightType.Area: gputype = GPULightType.Rectangle; shadowtype = GPUShadowType.Unknown; return false; // area lights by themselves can't be mapped to any GPU type
}
}
public static float Asfloat(uint val) { return System.BitConverter.ToSingle(System.BitConverter.GetBytes(val), 0); }
public static int Asint(float val) { return System.BitConverter.ToInt32(System.BitConverter.GetBytes(val), 0); }
public static uint Asuint(float val) { return System.BitConverter.ToUInt32(System.BitConverter.GetBytes(val), 0); }
}
} // end of namespace UnityEngine.Experimental.ScriptableRenderLoop

9
Assets/ScriptableRenderPipeline/RenderPasses.meta


fileFormatVersion: 2
guid: 8944ea3d2dfa541578ffc26bbdd626ed
folderAsset: yes
timeCreated: 1467147697
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

1001
Assets/TestScenes/HDTest/GraphicTest/SSS/head.OBJ
文件差异内容过多而无法显示
查看文件

148
Assets/TestScenes/HDTest/GraphicTest/SSS/head.OBJ.meta


fileFormatVersion: 2
guid: 2b46db496f27398459cf881becf5763a
timeCreated: 1493400806
licenseType: Pro
ModelImporter:
serializedVersion: 20
fileIDToRecycleName:
100000: Group12
100002: Group14
100004: Group19
100006: Group2
100008: Group24
100010: Group26
100012: Group28
100014: Group33
100016: Group35
100018: Group39
100020: Group4
100022: Group5
100024: Group7
100026: //RootNode
400000: Group12
400002: Group14
400004: Group19
400006: Group2
400008: Group24
400010: Group26
400012: Group28
400014: Group33
400016: Group35
400018: Group39
400020: Group4
400022: Group5
400024: Group7
400026: //RootNode
2300000: Group12
2300002: Group14
2300004: Group19
2300006: Group2
2300008: Group24
2300010: Group26
2300012: Group28
2300014: Group33
2300016: Group35
2300018: Group39
2300020: Group4
2300022: Group5
2300024: Group7
3300000: Group12
3300002: Group14
3300004: Group19
3300006: Group2
3300008: Group24
3300010: Group26
3300012: Group28
3300014: Group33
3300016: Group35
3300018: Group39
3300020: Group4
3300022: Group5
3300024: Group7
4300000: Group12
4300002: Group14
4300004: Group19
4300006: Group2
4300008: Group24
4300010: Group26
4300012: Group28
4300014: Group33
4300016: Group35
4300018: Group39
4300020: Group4
4300022: Group5
4300024: Group7
materials:
importMaterials: 1
materialName: 0
materialSearch: 1
animations:
legacyGenerateAnimations: 4
bakeSimulation: 0
resampleCurves: 1
optimizeGameObjects: 0
motionNodeName:
rigImportErrors:
rigImportWarnings:
animationImportErrors:
animationImportWarnings:
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
animationCompression: 1
animationRotationError: 0.5
animationPositionError: 0.5
animationScaleError: 0.5
animationWrapMode: 0
extraExposedTransformPaths: []
clipAnimations: []
isReadable: 1
meshes:
lODScreenPercentages: []
globalScale: 1
meshCompression: 0
addColliders: 0
importVisibility: 0
importBlendShapes: 1
importCameras: 1
importLights: 1
swapUVChannels: 0
generateSecondaryUV: 0
useFileUnits: 1
optimizeMeshForGPU: 1
keepQuads: 0
weldVertices: 1
secondaryUVAngleDistortion: 8
secondaryUVAreaDistortion: 15.000001
secondaryUVHardAngle: 88
secondaryUVPackMargin: 4
useFileScale: 1
tangentSpace:
normalSmoothAngle: 60
normalImportMode: 0
tangentImportMode: 3
normalCalculationMode: 4
importAnimation: 1
copyAvatar: 0
humanDescription:
serializedVersion: 2
human: []
skeleton: []
armTwist: 0.5
foreArmTwist: 0.5
upperLegTwist: 0.5
legTwist: 0.5
armStretch: 0.05
legStretch: 0.05
feetSpacing: 0
rootMotionBoneName:
rootMotionBoneRotation: {x: 0, y: 0, z: 0, w: 1}
hasTranslationDoF: 0
hasExtraRoot: 0
skeletonHasParents: 1
lastHumanDescriptionAvatarSource: {instanceID: 0}
animationType: 0
humanoidOversampling: 1
additionalBone: 0
userData:
assetBundleName:
assetBundleVariant:

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.hlsl → /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/Shadow.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowAlgorithmsCustom.hlsl → /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowAlgorithmsCustom.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs → /Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowContext.hlsl → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowContext.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowDispatch.hlsl → /Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/ShadowDispatch.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowSampling.hlsl → /Assets/ScriptableRenderPipeline/ShaderLibrary/Shadow/ShadowSampling.hlsl

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/VectorArray.cs → /Assets/ScriptableRenderPipeline/common/Shadow/VectorArray.cs

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/Shadow.cs → /Assets/ScriptableRenderPipeline/common/Shadow/Shadow.cs

/Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowBase.cs.hlsl → /Assets/ScriptableRenderPipeline/common/Shadow/ShadowBase.cs.hlsl

正在加载...
取消
保存