浏览代码

Merge pull request #384 from EvgeniiG/volumetrics

Merge volumetrics code (WIP)
/main
GitHub 7 年前
当前提交
34abb246
共有 24 个文件被更改,包括 744 次插入85 次删除
  1. 2
      Assets/ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl
  2. 10
      Assets/ScriptableRenderPipeline/Core/ShaderLibrary/CommonLighting.hlsl
  3. 68
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  4. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDShaderIDs.cs
  5. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  6. 179
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  7. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/HDRenderPipelineResources.asset
  8. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/RenderPipelineResources.cs
  9. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl
  10. 10
      Assets/ScriptableRenderPipeline/Core/ShaderLibrary/Random.hlsl.meta
  11. 49
      Assets/ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl
  12. 10
      Assets/ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl.meta
  13. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics.meta
  14. 13
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs.meta
  15. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs.hlsl.meta
  16. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources.meta
  17. 136
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs
  18. 48
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs.hlsl
  19. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute.meta
  20. 226
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute
  21. 10
      Assets/ScriptableRenderPipeline/Core/ShaderLibrary/Noise.hlsl.meta
  22. 0
      /Assets/ScriptableRenderPipeline/Core/ShaderLibrary/Random.hlsl

2
Assets/ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl


#endif
#include "API/Validate.hlsl"
#include "Noise.hlsl"
#include "Random.hlsl"
// Some shader compiler don't support to do multiple ## for concatenation inside the same macro, it require an indirection.
// This is the purpose of this macro

10
Assets/ScriptableRenderPipeline/Core/ShaderLibrary/CommonLighting.hlsl


#define PUNCTUAL_LIGHT_THRESHOLD 0.01 // 1cm (in Unity 1 is 1m)
float GetDistanceAttenuation(float3 unL, float invSqrAttenuationRadius)
float GetDistanceAttenuation(float sqrDist, float invSqrAttenuationRadius)
float sqrDist = dot(unL, unL);
}
float GetDistanceAttenuation(float3 unL, float invSqrAttenuationRadius)
{
float sqrDist = dot(unL, unL);
return GetDistanceAttenuation(sqrDist, invSqrAttenuationRadius);
}
float GetAngleAttenuation(float3 L, float3 lightDir, float lightAngleScale, float lightAngleOffset)

68
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


Material m_SssHorizontalFilterAndCombinePass;
// <<< Old SSS Model
ComputeShader m_VolumetricLightingCS { get { return m_Asset.renderPipelineResources.volumetricLightingCS; } }
int m_VolumetricLightingKernel;
Material m_CameraMotionVectorsMaterial;
Material m_DebugViewMaterialGBuffer;

cmd.SetGlobalVectorArray(HDShaderIDs._ShapeParams, sssParameters.shapeParams);
cmd.SetGlobalVectorArray(HDShaderIDs._HalfRcpVariancesAndWeights, sssParameters.halfRcpVariancesAndWeights);
cmd.SetGlobalVectorArray(HDShaderIDs._TransmissionTints, sssParameters.transmissionTints);
SetGlobalVolumeProperties(cmd);
}
}

// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.
RenderForward(m_CullResults, camera, renderContext, cmd, false);
// Render fog.
VolumetricLightingPass(hdCamera, cmd);
PushFullScreenDebugTexture(cmd, m_CameraColorBuffer, camera, renderContext, FullScreenDebugMode.NanTracker);
// Planar and real time cubemap doesn't need post process and render in FP16

cmd.SetComputeTextureParam(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, HDShaderIDs._CameraFilteringBuffer, m_CameraFilteringBufferRT);
// Perform the SSS filtering pass which fills 'm_CameraFilteringBufferRT'.
//
cmd.DispatchCompute(m_SubsurfaceScatteringCS, m_SubsurfaceScatteringKernel, ((int)hdCamera.screenSize.x + 15) / 16, ((int)hdCamera.screenSize.y + 15) / 16, 1);
cmd.SetGlobalTexture(HDShaderIDs._IrradianceSource, m_CameraFilteringBufferRT); // Cannot set a RT on a material

{
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, passName, Utilities.kRendererConfigurationBakedLighting);
}
}
}
// Returns 'true' if the global fog is enabled, 'false' otherwise.
public static bool SetGlobalVolumeProperties(CommandBuffer cmd, ComputeShader cs = null)
{
HomogeneousFog[] fogComponents = Object.FindObjectsOfType(typeof(HomogeneousFog)) as HomogeneousFog[];
HomogeneousFog globalFogComponent = null;
foreach (HomogeneousFog fogComponent in fogComponents)
{
if (fogComponent.enabled && fogComponent.volumeParameters.IsVolumeUnbounded())
{
globalFogComponent = fogComponent;
break;
}
}
// TODO: may want to cache these results somewhere.
VolumeProperties globalFogProperties = (globalFogComponent != null) ? globalFogComponent.volumeParameters.GetProperties()
: VolumeProperties.GetNeutralVolumeProperties();
if (cs)
{
cmd.SetComputeVectorParam(cs, HDShaderIDs._GlobalFog_Scattering, globalFogProperties.scattering);
cmd.SetComputeFloatParam( cs, HDShaderIDs._GlobalFog_Extinction, globalFogProperties.extinction);
cmd.SetComputeFloatParam( cs, HDShaderIDs._GlobalFog_Asymmetry, globalFogProperties.asymmetry);
}
else
{
cmd.SetGlobalVector(HDShaderIDs._GlobalFog_Scattering, globalFogProperties.scattering);
cmd.SetGlobalFloat( HDShaderIDs._GlobalFog_Extinction, globalFogProperties.extinction);
cmd.SetGlobalFloat( HDShaderIDs._GlobalFog_Asymmetry, globalFogProperties.asymmetry);
}
return (globalFogComponent != null);
}
void VolumetricLightingPass(HDCamera hdCamera, CommandBuffer cmd)
{
if (!SetGlobalVolumeProperties(cmd, m_VolumetricLightingCS)) { return; }
using (new Utilities.ProfilingSample("VolumetricLighting", cmd))
{
bool enableClustered = m_Asset.tileSettings.enableClustered && m_Asset.tileSettings.enableTileAndCluster;
m_VolumetricLightingKernel = m_VolumetricLightingCS.FindKernel(enableClustered ? "VolumetricLightingClustered"
: "VolumetricLightingAllLights");
hdCamera.SetupComputeShader(m_VolumetricLightingCS, cmd);
cmd.SetComputeTextureParam(m_VolumetricLightingCS, m_VolumetricLightingKernel, HDShaderIDs._CameraColorTexture, m_CameraColorBufferRT);
cmd.SetComputeTextureParam(m_VolumetricLightingCS, m_VolumetricLightingKernel, HDShaderIDs._DepthTexture, GetDepthTexture());
cmd.SetComputeVectorParam( m_VolumetricLightingCS, HDShaderIDs._Time, Shader.GetGlobalVector(HDShaderIDs._Time));
// Pass clustered light data (if present) into the compute shader.
m_LightLoop.PushGlobalParams(hdCamera.camera, cmd, m_VolumetricLightingCS, m_VolumetricLightingKernel, true);
cmd.SetComputeIntParam(m_VolumetricLightingCS, HDShaderIDs._UseTileLightList, 0);
cmd.DispatchCompute(m_VolumetricLightingCS, m_VolumetricLightingKernel, ((int)hdCamera.screenSize.x + 15) / 16, ((int)hdCamera.screenSize.y + 15) / 16, 1);
}
}

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDShaderIDs.cs


internal static readonly int _Cubemap = Shader.PropertyToID("_Cubemap");
internal static readonly int _SkyParam = Shader.PropertyToID("_SkyParam");
internal static readonly int _PixelCoordToViewDirWS = Shader.PropertyToID("_PixelCoordToViewDirWS");
internal static readonly int _GlobalFog_Extinction = Shader.PropertyToID("_GlobalFog_Extinction");
internal static readonly int _GlobalFog_Asymmetry = Shader.PropertyToID("_GlobalFog_Asymmetry");
internal static readonly int _GlobalFog_Scattering = Shader.PropertyToID("_GlobalFog_Scattering");
}
}

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


s_LightVolumeDataBuffer.SetData(m_lightList.lightVolumes);
}
private void BindGlobalParams(CommandBuffer cmd, Camera camera)
private void BindGlobalParams(CommandBuffer cmd, Camera camera, bool forceClustered)
SetGlobalBuffer(HDShaderIDs.g_vLightListGlobal, !usingFptl ? s_PerVoxelLightLists : s_LightList); // opaques list (unless MSAA possibly)
SetGlobalBuffer(HDShaderIDs.g_vLightListGlobal, (forceClustered || !usingFptl) ? s_PerVoxelLightLists : s_LightList); // opaques list (unless MSAA possibly)
SetGlobalTexture(HDShaderIDs._CookieTextures, m_CookieTexArray.GetTexCache());
SetGlobalTexture(HDShaderIDs._CookieCubeTextures, m_CubeCookieTexArray.GetTexCache());

}
}
private void PushGlobalParams(Camera camera, CommandBuffer cmd, ComputeShader computeShader, int kernelIndex)
public void PushGlobalParams(Camera camera, CommandBuffer cmd, ComputeShader computeShader, int kernelIndex, bool forceClustered = false)
{
using (new Utilities.ProfilingSample("Push Global Parameters", cmd))
{

SetGlobalPropertyRedirect(computeShader, kernelIndex, cmd);
BindGlobalParams(cmd, camera);
BindGlobalParams(cmd, camera, forceClustered);
SetGlobalPropertyRedirect(null, 0, null);
}
}

cmd.SetComputeTextureParam(deferredComputeShader, kernel, HDShaderIDs.specularLightingUAV, colorBuffers[0]);
cmd.SetComputeTextureParam(deferredComputeShader, kernel, HDShaderIDs.diffuseLightingUAV, colorBuffers[1]);
HDRenderPipeline.SetGlobalVolumeProperties(cmd, deferredComputeShader);
// always do deferred lighting in blocks of 16x16 (not same as tiled light size)

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


#include "Lit.cs.hlsl"
#include "SubsurfaceScatteringProfile.cs.hlsl"
// Enables attenuation of light source contributions by participating media (fog).
#define VOLUMETRIC_SHADOWING_ENABLED
#ifdef VOLUMETRIC_SHADOWING_ENABLED
// Apparently, not all shaders include "ShaderVariables.hlsl".
#include "../../ShaderVariables.hlsl"
#include "../../../Core/ShaderLibrary/VolumeRendering.hlsl"
#endif
// In case we pack data uint16 buffer we need to change the output render target format to uint16
// TODO: Is there a way to automate these output type based on the format declare in lit.cs ?
#if SHADEROPTIONS_PACK_GBUFFER_IN_U16

float3x3 ltcXformClearCoat; // TODO: make sure the compiler not wasting VGPRs on constants
float ltcClearCoatFresnelTerm;
float3x3 ltcCoatT;
#ifdef VOLUMETRIC_SHADOWING_ENABLED
float globalFogExtinction;
#endif
};
// This is a refract - TODO: do we call original refract or this one, original maybe slightly emore expensive, to check

preLightData.ltcMagnitudeFresnel = bsdfData.fresnel0 * ltcGGXFresnelMagnitudeDiff + (float3)ltcGGXFresnelMagnitude;
}
#ifdef VOLUMETRIC_SHADOWING_ENABLED
preLightData.globalFogExtinction = _GlobalFog_Extinction;
#endif
return preLightData;
}

// EvaluateBSDF_Directional (supports directional and box projector lights)
//-----------------------------------------------------------------------------
float4 EvaluateCookie_Directional(LightLoopContext context, DirectionalLightData lightData,
float3 lighToSample)
{
// Compute the NDC position (in [-1, 1]^2) by projecting 'positionWS' onto the near plane.
// 'lightData.right' and 'lightData.up' are pre-scaled on CPU.
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lighToSample, transpose(lightToWorld));
float2 positionNDC = positionLS.xy;
bool isInBounds;
// Remap the texture coordinates from [-1, 1]^2 to [0, 1]^2.
float2 coord = positionNDC * 0.5 + 0.5;
if (lightData.tileCookie)
{
// Tile the texture if the 'repeat' wrap mode is enabled.
coord = frac(coord);
isInBounds = true;
}
else
{
isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1 - positionLS.z) <= 1;
}
// We let the sampler handle tiling or clamping to border.
// Note: tiling (the repeat mode) is not currently supported.
float4 cookie = SampleCookie2D(context, coord, lightData.cookieIndex);
cookie.a = isInBounds ? cookie.a : 0;
return cookie;
}
void EvaluateBSDF_Directional(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput, PreLightData preLightData,
DirectionalLightData lightData, BSDFData bsdfData,

[branch] if (lightData.cookieIndex >= 0)
{
// Compute the NDC position (in [-1, 1]^2) by projecting 'positionWS' onto the near plane.
// 'lightData.right' and 'lightData.up' are pre-scaled on CPU.
float3 lightToSurface = positionWS - lightData.positionWS;
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lightToSurface, transpose(lightToWorld));
float2 positionNDC = positionLS.xy;
float clipFactor;
// Remap the texture coordinates from [-1, 1]^2 to [0, 1]^2.
float2 coord = positionNDC * 0.5 + 0.5;
if (lightData.tileCookie)
{
// Tile the texture if the 'repeat' wrap mode is enabled.
coord = frac(coord);
clipFactor = 1;
}
else
{
bool isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1 - positionLS.z) <= 1;
clipFactor = isInBounds ? 1 : 0;
}
// We let the sampler handle tiling or clamping to border.
// Note: tiling (the repeat mode) is not currently supported.
float4 cookie = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);
float3 lightToSurface = positionWS - lightData.positionWS;
float4 cookie = EvaluateCookie_Directional(lightLoopContext, lightData, lightToSurface);
cookie.a *= clipFactor;
lightData.color *= cookie.rgb;
lightData.diffuseScale *= cookie.a;
lightData.specularScale *= cookie.a;

// EvaluateBSDF_Punctual (supports spot, point and projector lights)
//-----------------------------------------------------------------------------
float4 EvaluateCookie_Punctual(LightLoopContext context, LightData lightData,
float3 lighToSample)
{
int lightType = lightData.lightType;
// Translate and rotate 'positionWS' into the light space.
// 'lightData.right' and 'lightData.up' are pre-scaled on CPU.
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lighToSample, transpose(lightToWorld));
float4 cookie;
[branch] if (lightType == GPULIGHTTYPE_POINT)
{
cookie = SampleCookieCube(context, positionLS, lightData.cookieIndex);
}
else
{
// Compute the NDC position (in [-1, 1]^2) by projecting 'positionWS' onto the plane at 1m distance.
// Box projector lights require no perspective division.
float perspectiveZ = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? positionLS.z : 1;
float2 positionNDC = positionLS.xy / perspectiveZ;
bool isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1 - positionLS.z) <= 1;
// Remap the texture coordinates from [-1, 1]^2 to [0, 1]^2.
float2 coord = positionNDC * 0.5 + 0.5;
// We let the sampler handle clamping to border.
cookie = SampleCookie2D(context, coord, lightData.cookieIndex);
cookie.a = isInBounds ? cookie.a : 0;
}
return cookie;
}
float GetPunctualShapeAttenuation(LightData lightData, float3 L, float distSq)
{
// Note: lightData.invSqrAttenuationRadius is 0 when applyRangeAttenuation is false
float attenuation = GetDistanceAttenuation(distSq, lightData.invSqrAttenuationRadius);
// Reminder: lights are oriented backward (-Z)
return attenuation * GetAngleAttenuation(L, -lightData.forward, lightData.angleScale, lightData.angleOffset);
}
void EvaluateBSDF_Punctual( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput, PreLightData preLightData, LightData lightData, BSDFData bsdfData,
out float3 diffuseLighting,

// For point light and directional GetAngleAttenuation() return 1
float3 lightToSurface = positionWS - lightData.positionWS;
float3 unL = -lightToSurface;
float3 L = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? normalize(unL) : -lightData.forward;
float NdotL = dot(bsdfData.normalWS, L);
float3 unL = -lightToSurface;
float distSq = dot(unL, unL);
float dist = sqrt(distSq);
float3 L = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? unL * rsqrt(distSq) : -lightData.forward;
float NdotL = dot(bsdfData.normalWS, L);
// Note: lightData.invSqrAttenuationRadius is 0 when applyRangeAttenuation is false
float attenuation = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? GetDistanceAttenuation(unL, lightData.invSqrAttenuationRadius) : 1;
// Reminder: lights are oriented backward (-Z)
attenuation *= GetAngleAttenuation(L, -lightData.forward, lightData.angleScale, lightData.angleOffset);
float attenuation = GetPunctualShapeAttenuation(lightData, L, distSq);
// Premultiply.
lightData.diffuseScale *= attenuation;

{
// TODO: make projector lights cast shadows.
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
float4 L_dist = { normalize( L.xyz ), length( unL ) };
float4 L_dist = { L, dist };
// Projector lights always have a cookie.
[branch] if (lightData.cookieIndex >= 0)
{
// Translate and rotate 'positionWS' into the light space.
// 'lightData.right' and 'lightData.up' are pre-scaled on CPU.
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);
float3 positionLS = mul(lightToSurface, transpose(lightToWorld));
float4 cookie;
[branch] if (lightType == GPULIGHTTYPE_POINT)
{
cookie = SampleCookieCube(lightLoopContext, positionLS, lightData.cookieIndex);
}
else
{
// Compute the NDC position (in [-1, 1]^2) by projecting 'positionWS' onto the plane at 1m distance.
// Box projector lights require no perspective division.
float perspectiveZ = (lightType != GPULIGHTTYPE_PROJECTOR_BOX) ? positionLS.z : 1;
float2 positionNDC = positionLS.xy / perspectiveZ;
bool isInBounds = Max3(abs(positionNDC.x), abs(positionNDC.y), 1 - positionLS.z) <= 1;
float clipFactor = isInBounds ? 1 : 0;
#ifdef VOLUMETRIC_SHADOWING_ENABLED
float volumetricShadow = Transmittance(OpticalDepthHomogeneous(preLightData.globalFogExtinction, dist));
// Remap the texture coordinates from [-1, 1]^2 to [0, 1]^2.
float2 coord = positionNDC * 0.5 + 0.5;
// Premultiply.
lightData.diffuseScale *= volumetricShadow;
lightData.specularScale *= volumetricShadow;
#endif
// We let the sampler handle clamping to border.
cookie = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);
cookie.a *= clipFactor;
}
// Projector lights always have a cookies, so we can perform clipping inside the if().
[branch] if (lightData.cookieIndex >= 0)
{
float4 cookie = EvaluateCookie_Punctual(lightLoopContext, lightData, lightToSurface);
// Premultiply.
lightData.color *= cookie.rgb;

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/HDRenderPipelineResources.asset


type: 3}
subsurfaceScatteringCS: {fileID: 7200000, guid: b06a7993621def248addd55d0fe931b1,
type: 3}
volumetricLightingCS: {fileID: 7200000, guid: 799166e2ee6a4b041bba9e74f6942097,
type: 3}
clearDispatchIndirectShader: {fileID: 7200000, guid: fc1f553acb80a6446a32d33e403d0656,
type: 3}
buildDispatchIndirectShader: {fileID: 7200000, guid: 4eb1b418be7044c40bb5200496c50f14,

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/RenderPipelineResources.cs


instance.deferredShader = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.Shader");
instance.screenSpaceAmbientOcclusionShader = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusion.Shader");
instance.subsurfaceScatteringCS = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute");
instance.volumetricLightingCS = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute");
instance.clearDispatchIndirectShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/cleardispatchindirect.compute");
instance.buildDispatchIndirectShader = UnityEditor.AssetDatabase.LoadAssetAtPath<ComputeShader>("Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/builddispatchindirect.compute");

public Shader deferredShader;
public Shader screenSpaceAmbientOcclusionShader;
public ComputeShader subsurfaceScatteringCS;
public ComputeShader volumetricLightingCS;
// Lighting tile pass resources
public ComputeShader clearDispatchIndirectShader;

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl


float4 _InvProjParam;
float4 _ScreenSize; // (w, h, 1/w, 1/h)
float4 _FrustumPlanes[6]; // (N, -dot(N, P))
// Volumetric lighting. Should be a struct in 'UnityPerFrame'.
// Unfortunately, we cannot modify the layout of 'UnityPerFrame',
// and structures inside constant buffers are not supported by Unity.
float3 _GlobalFog_Scattering;
float _GlobalFog_Extinction;
float _GlobalFog_Asymmetry;
float _GlobalFog_Align16_0;
float _GlobalFog_Align16_1;
float _GlobalFog_Align16_2;
CBUFFER_END
#ifdef USE_LEGACY_UNITY_MATRIX_VARIABLES

10
Assets/ScriptableRenderPipeline/Core/ShaderLibrary/Random.hlsl.meta


fileFormatVersion: 2
guid: 11914c30949383848ab39385375eff34
timeCreated: 1504012042
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

49
Assets/ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl


#ifndef UNITY_VOLUME_RENDERING_INCLUDED
#define UNITY_VOLUME_RENDERING_INCLUDED
float OpticalDepthHomogeneous(float extinction, float intervalLength)
{
return extinction * intervalLength;
}
float Transmittance(float opticalDepth)
{
return exp(-opticalDepth);
}
float3 OpticalDepthHomogeneous(float3 extinction, float intervalLength)
{
return extinction * intervalLength;
}
float3 Transmittance(float3 opticalDepth)
{
return exp(-opticalDepth);
}
float IsotropicPhaseFunction()
{
return INV_FOUR_PI;
}
float HenyeyGreensteinPhasePartConstant(float asymmetry)
{
float g = asymmetry;
return INV_FOUR_PI * (1 - g * g);
}
float HenyeyGreensteinPhasePartVarying(float asymmetry, float LdotD)
{
float g = asymmetry;
return pow(abs(1 + g * g - 2 * g * LdotD), -1.5);
}
float HenyeyGreensteinPhaseFunction(float asymmetry, float LdotD)
{
return HenyeyGreensteinPhasePartConstant(asymmetry) *
HenyeyGreensteinPhasePartVarying(asymmetry, LdotD);
}
#endif // UNITY_VOLUME_RENDERING_INCLUDED

10
Assets/ScriptableRenderPipeline/Core/ShaderLibrary/VolumeRendering.hlsl.meta


fileFormatVersion: 2
guid: 76b6dbce57ad3e647a01b5ad36f737a5
timeCreated: 1503651539
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics.meta


fileFormatVersion: 2
guid: 1fe4fc72895e4bb4f90ff44b47e76051
folderAsset: yes
timeCreated: 1503411233
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

13
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs.meta


fileFormatVersion: 2
guid: 8f608e240d5376341bcef2478d231457
timeCreated: 1503411233
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs.hlsl.meta


fileFormatVersion: 2
guid: af39a96c040c8ec4da47ed13c6455ffe
timeCreated: 1503567986
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources.meta


fileFormatVersion: 2
guid: 333b470add5766f44a744f476efc19a8
folderAsset: yes
timeCreated: 1503591964
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

136
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs


using UnityEngine.Rendering;
using UnityEngine;
using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[GenerateHLSL]
public struct VolumeProperties
{
public Vector3 scattering; // [0, 1], prefer sRGB
public float extinction; // [0, 1], prefer sRGB
public float asymmetry; // Global (scene) property
public float align16_0;
public float align16_1;
public float align16_2;
public static VolumeProperties GetNeutralVolumeProperties()
{
VolumeProperties properties = new VolumeProperties();
properties.scattering = Vector3.zero;
properties.extinction = 0;
properties.asymmetry = 0;
return properties;
}
}
[Serializable]
public class VolumeParameters
{
public Bounds bounds; // Position and dimensions in meters
public Color albedo; // Single scattering albedo [0, 1]
public float meanFreePath; // In meters [1, inf]. Should be chromatic - this is an optimization!
public float anisotropy; // [-1, 1]; 0 = isotropic
public VolumeParameters()
{
bounds = new Bounds(Vector3.zero, Vector3.positiveInfinity);
albedo = new Color(0.5f, 0.5f, 0.5f);
meanFreePath = 10.0f;
anisotropy = 0.0f;
}
public bool IsVolumeUnbounded()
{
return bounds.size.x == float.PositiveInfinity &&
bounds.size.y == float.PositiveInfinity &&
bounds.size.z == float.PositiveInfinity;
}
public Vector3 GetAbsorptionCoefficient()
{
float extinction = GetExtinctionCoefficient();
Vector3 scattering = GetScatteringCoefficient();
return Vector3.Max(new Vector3(extinction, extinction, extinction) - scattering, Vector3.zero);
}
public Vector3 GetScatteringCoefficient()
{
float extinction = GetExtinctionCoefficient();
return new Vector3(albedo.r * extinction, albedo.g * extinction, albedo.b * extinction);
}
public float GetExtinctionCoefficient()
{
return 1.0f / meanFreePath;
}
public void Constrain()
{
bounds.size = Vector3.Max(bounds.size, Vector3.zero);
albedo.r = Mathf.Clamp01(albedo.r);
albedo.g = Mathf.Clamp01(albedo.g);
albedo.b = Mathf.Clamp01(albedo.b);
meanFreePath = Mathf.Max(meanFreePath, 1.0f);
anisotropy = Mathf.Clamp(anisotropy, -1.0f, 1.0f);
}
public VolumeProperties GetProperties()
{
VolumeProperties properties = new VolumeProperties();
properties.scattering = GetScatteringCoefficient();
properties.extinction = GetExtinctionCoefficient();
properties.asymmetry = anisotropy;
return properties;
}
}
[ExecuteInEditMode]
[AddComponentMenu("Rendering/Homogeneous Fog", -1)]
public class HomogeneousFog : MonoBehaviour
{
public VolumeParameters volumeParameters;
private void Awake()
{
if (volumeParameters == null)
{
volumeParameters = new VolumeParameters();
}
}
private void OnEnable()
{
}
private void OnDisable()
{
}
private void Update()
{
}
private void OnValidate()
{
volumeParameters.Constrain();
}
void OnDrawGizmos()
{
if (volumeParameters != null && !volumeParameters.IsVolumeUnbounded())
{
Gizmos.DrawWireCube(volumeParameters.bounds.center, volumeParameters.bounds.size);
}
}
}
} // UnityEngine.Experimental.Rendering.HDPipeline

48
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/HomogeneousFog.cs. Please don't edit by hand.
//
#ifndef HOMOGENEOUSFOG_CS_HLSL
#define HOMOGENEOUSFOG_CS_HLSL
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.VolumeProperties
// PackingRules = Exact
struct VolumeProperties
{
float3 scattering;
float extinction;
float asymmetry;
float align16_0;
float align16_1;
float align16_2;
};
//
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.VolumeProperties
//
float3 GetScattering(VolumeProperties value)
{
return value.scattering;
}
float GetExtinction(VolumeProperties value)
{
return value.extinction;
}
float GetAsymmetry(VolumeProperties value)
{
return value.asymmetry;
}
float GetAlign16_0(VolumeProperties value)
{
return value.align16_0;
}
float GetAlign16_1(VolumeProperties value)
{
return value.align16_1;
}
float GetAlign16_2(VolumeProperties value)
{
return value.align16_2;
}
#endif

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute.meta


fileFormatVersion: 2
guid: 799166e2ee6a4b041bba9e74f6942097
timeCreated: 1503570390
licenseType: Pro
ComputeShaderImporter:
externalObjects: {}
currentAPIMask: 4
userData:
assetBundleName:
assetBundleVariant:

226
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/Resources/VolumetricLighting.compute


//--------------------------------------------------------------------------------------------------
// Definitions
//--------------------------------------------------------------------------------------------------
#pragma kernel VolumetricLightingAllLights VolumetricLighting=VolumetricLightingAllLights LIGHTLOOP_SINGLE_PASS
#pragma kernel VolumetricLightingClustered VolumetricLighting=VolumetricLightingClustered LIGHTLOOP_TILE_PASS USE_CLUSTERED_LIGHTLIST
#pragma enable_d3d11_debug_symbols
#include "../../../ShaderPass/ShaderPass.cs.hlsl"
#define SHADERPASS SHADERPASS_VOLUMETRIC_LIGHTING
#define GROUP_SIZE_1D 16
#define GROUP_SIZE_2D (GROUP_SIZE_1D * GROUP_SIZE_1D)
//--------------------------------------------------------------------------------------------------
// Included headers
//--------------------------------------------------------------------------------------------------
#include "../../../../Core/ShaderLibrary/Common.hlsl"
#include "../../../../Core/ShaderLibrary/SpaceFillingCurves.hlsl"
#include "../../../../Core/ShaderLibrary/VolumeRendering.hlsl"
#include "../HomogeneousFog.cs.hlsl"
#define UNITY_MATERIAL_LIT // Need to be defined before including Material.hlsl
#include "../../../ShaderVariables.hlsl"
#include "../../../Lighting/Lighting.hlsl" // This includes Material.hlsl
//--------------------------------------------------------------------------------------------------
// Inputs & outputs
//--------------------------------------------------------------------------------------------------
TEXTURE2D(_DepthTexture); // Z-buffer
RW_TEXTURE2D(float4, _CameraColorTexture); // Updated texture
//--------------------------------------------------------------------------------------------------
// Implementation
//--------------------------------------------------------------------------------------------------
struct Ray
{
float3 originWS;
float3 directionWS; // Normalized
float maxLength; // In meters
};
// Computes the in-scattered radiance along the ray.
float3 PerformIntegration(PositionInputs posInput, Ray ray, uint numSteps)
{
float3 scattering = _GlobalFog_Scattering;
float extinction = _GlobalFog_Extinction;
float asymmetry = _GlobalFog_Asymmetry;
LightLoopContext context;
// ZERO_INITIALIZE(LightLoopContext, context);
context.shadowContext = InitShadowContext();
uint featureFlags = 0xFFFFFFFF; // TODO
float maxDepthVS = posInput.depthVS;
// Note: we are already using 'unPositionSS' for randomization of LODDitheringTransition().
float zeta = GenerateHashedRandomFloat(posInput.unPositionSS.yx);
float du = rcp(numSteps);
float u0 = 0.25 * du + 0.5 * du * zeta;
float dt = du * ray.maxLength;
float3 radiance = 0;
for (uint s = 0; s < numSteps; s++)
{
float u = u0 + s * du; // [0, 1]
float t = u * ray.maxLength; // [0, ray.maxLength]
float3 positionWS = ray.originWS + t * ray.directionWS;
float3 sampleRadiance = 0;
if (featureFlags & LIGHTFEATUREFLAGS_DIRECTIONAL)
{
for (uint i = 0; i < _DirectionalLightCount; ++i)
{
// Fetch the light.
DirectionalLightData lightData = _DirectionalLightDatas[i];
float3 L = -lightData.forward; // Lights point backwards in Unity
float intensity = 1;
float3 color = lightData.color;
// Note: we apply the scattering coefficient and the constant part of the phase function later.
intensity *= HenyeyGreensteinPhasePartVarying(asymmetry, dot(L, ray.directionWS));
[branch] if (lightData.shadowIndex >= 0)
{
float shadow = GetDirectionalShadowAttenuation(context.shadowContext, positionWS,
0, lightData.shadowIndex, L, posInput.unPositionSS);
intensity *= shadow;
}
[branch] if (lightData.cookieIndex >= 0)
{
float3 lightToSample = positionWS - lightData.positionWS;
float4 cookie = EvaluateCookie_Directional(context, lightData, lightToSample);
color *= cookie.rgb;
intensity *= cookie.a;
}
// Compute the amount of in-scattered radiance.
sampleRadiance += color * intensity;
}
}
if (featureFlags & LIGHTFEATUREFLAGS_PUNCTUAL)
{
uint punctualLightCount;
#ifdef LIGHTLOOP_TILE_PASS
uint punctualLightStart;
posInput.depthVS = u * maxDepthVS;
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, punctualLightStart, punctualLightCount);
#else
punctualLightCount = _PunctualLightCount;
#endif
for (uint i = 0; i < punctualLightCount; ++i)
{
#ifdef LIGHTLOOP_TILE_PASS
uint punctualLightIndex = FetchIndex(punctualLightStart, i);
#else
uint punctualLightIndex = i;
#endif
// Fetch the light.
LightData lightData = _LightDatas[punctualLightIndex];
int lightType = lightData.lightType;
float3 lightToSample = positionWS - lightData.positionWS;
float distSq = dot(lightToSample, lightToSample);
float dist = sqrt(distSq);
float3 L = lightToSample * -rsqrt(distSq);
float intensity = GetPunctualShapeAttenuation(lightData, L, distSq);
float3 color = lightData.color;
// Note: we apply the scattering coefficient and the constant part of the phase function later.
intensity *= HenyeyGreensteinPhasePartVarying(asymmetry, dot(L, ray.directionWS));
intensity *= Transmittance(OpticalDepthHomogeneous(extinction, dist));
[branch] if (lightData.shadowIndex >= 0)
{
// TODO: make projector lights cast shadows.
float3 offset = 0; // GetShadowPosOffset(nDotL, normal);
float shadow = GetPunctualShadowAttenuation(context.shadowContext, positionWS + offset,
0, lightData.shadowIndex, float4(L, dist), posInput.unPositionSS);
intensity *= lerp(1, shadow, lightData.shadowDimmer);
}
// Projector lights always have a cookies, so we can perform clipping inside the if().
[branch] if (lightData.cookieIndex >= 0)
{
float4 cookie = EvaluateCookie_Punctual(context, lightData, lightToSample);
color *= cookie.rgb;
intensity *= cookie.a;
}
// Compute the amount of in-scattered radiance.
sampleRadiance += color * intensity;
}
}
radiance += sampleRadiance * (Transmittance(OpticalDepthHomogeneous(extinction, t)) * dt);
}
float3 phaseConstant = scattering * HenyeyGreensteinPhasePartConstant(asymmetry);
return radiance * phaseConstant;
}
[numthreads(GROUP_SIZE_2D, 1, 1)]
void VolumetricLighting(uint2 groupId : SV_GroupID,
uint groupThreadId : SV_GroupThreadID)
{
// Note: any factor of 64 is a suitable wave size for our algorithm.
uint waveIndex = groupThreadId / 64;
uint laneIndex = groupThreadId % 64;
uint quadIndex = laneIndex / 4;
// Arrange threads in the Morton order to optimally match the memory layout of GCN tiles.
uint mortonCode = groupThreadId;
uint2 localCoord = DecodeMorton2D(mortonCode);
uint2 tileAnchor = groupId * GROUP_SIZE_1D;
uint2 pixelCoord = tileAnchor + localCoord;
uint2 tileCoord = pixelCoord / GetTileSize();
if (pixelCoord.x >= (uint)_ScreenSize.x || pixelCoord.y >= (uint)_ScreenSize.y) { return; }
// Idea: zenith angle based distance limiting to simulate aerial perspective?
#ifdef UNITY_REVERSED_Z
float z = max(LOAD_TEXTURE2D(_DepthTexture, pixelCoord).r, 0 + 0.001);
#else
float z = min(LOAD_TEXTURE2D(_DepthTexture, pixelCoord).r, 1 - 0.001);
#endif
PositionInputs posInput = GetPositionInput(pixelCoord, _ScreenSize.zw, tileCoord);
UpdatePositionInput(z, _InvViewProjMatrix, _ViewProjMatrix, posInput);
Ray cameraRay;
// Note: the camera ray does not start on the the near (camera sensor) plane.
// While this is not correct (strictly speaking), the introduced error is small.
cameraRay.originWS = GetCurrentViewPosition();
cameraRay.directionWS = posInput.positionWS - cameraRay.originWS;
cameraRay.maxLength = sqrt(dot(cameraRay.directionWS, cameraRay.directionWS));
cameraRay.directionWS *= rsqrt(dot(cameraRay.directionWS, cameraRay.directionWS)); // Normalize
float rayT = Transmittance(OpticalDepthHomogeneous(_GlobalFog_Extinction, cameraRay.maxLength));
const int numSamples = 64;
float3 inL = PerformIntegration(posInput, cameraRay, numSamples);
// In-place UAV updates do not work on Intel GPUs.
_CameraColorTexture[pixelCoord] = float4(rayT * _CameraColorTexture[pixelCoord].rgb + inL, _CameraColorTexture[pixelCoord].a);
}

10
Assets/ScriptableRenderPipeline/Core/ShaderLibrary/Noise.hlsl.meta


fileFormatVersion: 2
guid: 5918bc8b07f593546974c1961387db77
timeCreated: 1501167559
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

/Assets/ScriptableRenderPipeline/Core/ShaderLibrary/Noise.hlsl → /Assets/ScriptableRenderPipeline/Core/ShaderLibrary/Random.hlsl

正在加载...
取消
保存