浏览代码

Use correct terminology: rename "asymmetry" -> "anisotropy"

According to d'Eon, asymmetric scattering occurs due to anisotropic phase functions in anisotropic participating media.
/main
Evgenii Golubev 6 年前
当前提交
0be42a4f
共有 10 个文件被更改,包括 60 次插入60 次删除
  1. 28
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/VolumeRendering.hlsl
  2. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/AtmosphericScattering/VolumetricFogEditor.cs
  3. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  4. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/SphericalHarmonics.cs
  5. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/HomogeneousDensityVolume.cs
  6. 32
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.compute
  7. 22
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs
  8. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl
  9. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.cs
  10. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/VolumetricFog.cs

28
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/VolumeRendering.hlsl


return INV_FOUR_PI;
}
real HenyeyGreensteinPhasePartConstant(real asymmetry)
real HenyeyGreensteinPhasePartConstant(real anisotropy)
real g = asymmetry;
real g = anisotropy;
real HenyeyGreensteinPhasePartVarying(real asymmetry, real cosTheta)
real HenyeyGreensteinPhasePartVarying(real anisotropy, real cosTheta)
real g = asymmetry;
real g = anisotropy;
real HenyeyGreensteinPhaseFunction(real asymmetry, real cosTheta)
real HenyeyGreensteinPhaseFunction(real anisotropy, real cosTheta)
return HenyeyGreensteinPhasePartConstant(asymmetry) *
HenyeyGreensteinPhasePartVarying(asymmetry, cosTheta);
return HenyeyGreensteinPhasePartConstant(anisotropy) *
HenyeyGreensteinPhasePartVarying(anisotropy, cosTheta);
real CornetteShanksPhasePartConstant(real asymmetry)
real CornetteShanksPhasePartConstant(real anisotropy)
real g = asymmetry;
real g = anisotropy;
real CornetteShanksPhasePartVarying(real asymmetry, real cosTheta)
real CornetteShanksPhasePartVarying(real anisotropy, real cosTheta)
real g = asymmetry;
real g = anisotropy;
real f = rsqrt(1 + g * g - 2 * g * cosTheta); // x^(-1/2)
real h = (1 + cosTheta * cosTheta);

// A better approximation of the Mie phase function.
// Ref: Henyey–Greenstein and Mie phase functions in Monte Carlo radiative transfer computations
real CornetteShanksPhaseFunction(real asymmetry, real cosTheta)
real CornetteShanksPhaseFunction(real anisotropy, real cosTheta)
return CornetteShanksPhasePartConstant(asymmetry) *
CornetteShanksPhasePartVarying(asymmetry, cosTheta);
return CornetteShanksPhasePartConstant(anisotropy) *
CornetteShanksPhasePartVarying(anisotropy, cosTheta);
}
// Samples the interval of homogeneous participating medium using the closed-form tracking approach

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/AtmosphericScattering/VolumetricFogEditor.cs


{
private SerializedDataParameter m_Albedo;
private SerializedDataParameter m_MeanFreePath;
private SerializedDataParameter m_Asymmetry;
private SerializedDataParameter m_Anisotropy;
public override void OnEnable()
{

m_Albedo = Unpack(o.Find(x => x.albedo));
m_MeanFreePath = Unpack(o.Find(x => x.meanFreePath));
m_Asymmetry = Unpack(o.Find(x => x.asymmetry));
m_Anisotropy = Unpack(o.Find(x => x.anisotropy));
}
public override void OnInspectorGUI()

PropertyField(m_Asymmetry);
PropertyField(m_Anisotropy);
}
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int _AmbientProbeCoeffs = Shader.PropertyToID("_AmbientProbeCoeffs");
public static readonly int _GlobalExtinction = Shader.PropertyToID("_GlobalExtinction");
public static readonly int _GlobalScattering = Shader.PropertyToID("_GlobalScattering");
public static readonly int _GlobalAsymmetry = Shader.PropertyToID("_GlobalAsymmetry");
public static readonly int _GlobalAnisotropy = Shader.PropertyToID("_GlobalAnisotropy");
public static readonly int _CornetteShanksConstant = Shader.PropertyToID("_CornetteShanksConstant");
public static readonly int _VBufferResolution = Shader.PropertyToID("_VBufferResolution");
public static readonly int _VBufferSliceCount = Shader.PropertyToID("_VBufferSliceCount");

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/SphericalHarmonics.cs


{
public float[] coeffs; // Must have the size of 3
public static ZonalHarmonicsL2 GetHenyeyGreensteinPhaseFunction(float asymmetry)
public static ZonalHarmonicsL2 GetHenyeyGreensteinPhaseFunction(float anisotropy)
float g = asymmetry;
float g = anisotropy;
var zh = new ZonalHarmonicsL2();
zh.coeffs = new float[3];

return zh;
}
public static ZonalHarmonicsL2 GetCornetteShanksPhaseFunction(float asymmetry)
public static ZonalHarmonicsL2 GetCornetteShanksPhaseFunction(float anisotropy)
float g = asymmetry;
float g = anisotropy;
var zh = new ZonalHarmonicsL2();
zh.coeffs = new float[3];

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/HomogeneousDensityVolume.cs


{
parameters.albedo = new Color(0.5f, 0.5f, 0.5f);
parameters.meanFreePath = 10.0f;
parameters.asymmetry = 0.0f;
parameters.anisotropy = 0.0f;
}
private void Awake()

32
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.compute


// Computes the light integral (in-scattered radiance) within the voxel.
// Multiplication by the scattering coefficient and the phase function is performed outside.
VoxelLighting EvaluateVoxelLighting(LightLoopContext context, uint featureFlags, PositionInputs posInput, float3 centerWS,
DualRay ray, float t0, float t1, float dt, float rndVal, float extinction, float asymmetry
DualRay ray, float t0, float t1, float dt, float rndVal, float extinction, float anisotropy
#ifdef USE_CLUSTERED_LIGHTLIST
, uint lightClusters[2])
#else

// function) is not possible. We work around this issue by reprojecting
// lighting not affected by the phase function. This basically removes
// the phase function from the temporal integration process. It is a hack.
// The downside is that asymmetry no longer benefits from temporal averaging,
// and any temporal instability of asymmetry causes causes visible jitter.
// The downside is that anisotropy no longer benefits from temporal averaging,
// and any temporal instability of anisotropy causes causes visible jitter.
// asymmetry-related calculations.
// anisotropy-related calculations.
float phase = CornetteShanksPhasePartVarying(asymmetry, cosTheta);
float phase = CornetteShanksPhasePartVarying(anisotropy, cosTheta);
// Note: the 'weight' accounts for transmittance from 't0' to 't'.
float intensity = attenuation * weight;

// function) is not possible. We work around this issue by reprojecting
// lighting not affected by the phase function. This basically removes
// the phase function from the temporal integration process. It is a hack.
// The downside is that asymmetry no longer benefits from temporal averaging,
// and any temporal instability of asymmetry causes causes visible jitter.
// The downside is that anisotropy no longer benefits from temporal averaging,
// and any temporal instability of anisotropy causes causes visible jitter.
// asymmetry-related calculations.
// anisotropy-related calculations.
float phase = CornetteShanksPhasePartVarying(asymmetry, cosTheta);
float phase = CornetteShanksPhasePartVarying(anisotropy, cosTheta);
float intensity = attenuation * rcpPdf;

// function) is not possible. We work around this issue by reprojecting
// lighting not affected by the phase function. This basically removes
// the phase function from the temporal integration process. It is a hack.
// The downside is that asymmetry no longer benefits from temporal averaging,
// and any temporal instability of asymmetry causes causes visible jitter.
// The downside is that anisotropy no longer benefits from temporal averaging,
// and any temporal instability of anisotropy causes causes visible jitter.
// asymmetry-related calculations.
float3 centerL = light.positionWS - centerWS;
// anisotropy-related calculations.
float3 centerL = light.positionWS - centerWS;
float phase = CornetteShanksPhasePartVarying(asymmetry, cosTheta);
float phase = CornetteShanksPhasePartVarying(anisotropy, cosTheta);
// Note: the 'weight' accounts for transmittance from 'tEntr' to 't'.
float intensity = attenuation * weight;

// TODO: piecewise linear.
float3 scattering = LOAD_TEXTURE3D(_VBufferDensity, voxelCoord).rgb;
float extinction = LOAD_TEXTURE3D(_VBufferDensity, voxelCoord).a;
float asymmetry = _GlobalAsymmetry;
float anisotropy = _GlobalAnisotropy;
// Prevent division by 0.
extinction = max(extinction, FLT_MIN);

#endif
VoxelLighting lighting = EvaluateVoxelLighting(context, featureFlags, posInput, centerWS,
ray, t0, t1, dt, rndVal, extinction, asymmetry
ray, t0, t1, dt, rndVal, extinction, anisotropy
#ifdef USE_CLUSTERED_LIGHTLIST
, lightClusters);
#else

22
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs


{
public Color albedo; // Single scattering albedo: [0, 1]. Alpha is ignored
public float meanFreePath; // In meters: [1, 1000000]. Should be chromatic - this is an optimization!
public float asymmetry; // Controls the phase function: [-1, 1]
public float anisotropy; // Controls the phase function: [-1, 1]
public void Constrain()
{

meanFreePath = Mathf.Clamp(meanFreePath, 1.0f, float.MaxValue);
asymmetry = Mathf.Clamp(asymmetry, -1.0f, 1.0f);
anisotropy = Mathf.Clamp(anisotropy, -1.0f, 1.0f);
}
public DensityVolumeData GetData()

return depthParams;
}
void SetPreconvolvedAmbientLightProbe(CommandBuffer cmd, float asymmetry)
void SetPreconvolvedAmbientLightProbe(CommandBuffer cmd, float anisotropy)
ZonalHarmonicsL2 phaseZH = ZonalHarmonicsL2.GetCornetteShanksPhaseFunction(asymmetry);
ZonalHarmonicsL2 phaseZH = ZonalHarmonicsL2.GetCornetteShanksPhaseFunction(anisotropy);
float CornetteShanksPhasePartConstant(float asymmetry)
float CornetteShanksPhasePartConstant(float anisotropy)
float g = asymmetry;
float g = anisotropy;
return (1.0f / (4.0f * Mathf.PI)) * 1.5f * (1.0f - g * g) / (2.0f + g * g);
}

var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
if (visualEnvironment.fogType != FogType.Volumetric) return;
// VisualEnvironment sets global fog parameters: _GlobalAsymmetry, _GlobalScattering, _GlobalExtinction.
// VisualEnvironment sets global fog parameters: _GlobalAnisotropy, _GlobalScattering, _GlobalExtinction.
VBuffer vBuffer = FindVBuffer(camera.GetViewID());
if (vBuffer == null)

return;
}
// Get the interpolated asymmetry value.
// Get the interpolated anisotropy value.
SetPreconvolvedAmbientLightProbe(cmd, fog.asymmetry);
SetPreconvolvedAmbientLightProbe(cmd, fog.anisotropy);
var currFrameParams = vBuffer.GetParameters(frameIndex);
var prevFrameParams = vBuffer.GetParameters(frameIndex - 1);

// Currently, we assume that they are completely uncorrelated, but maybe we should correlate them somehow.
Vector4 offset = new Vector4(xySeq[sampleIndex].x, xySeq[sampleIndex].y, zSeq[sampleIndex], frameIndex);
// Get the interpolated asymmetry value.
// Get the interpolated anisotropy value.
var fog = VolumeManager.instance.stack.GetComponent<VolumetricFog>();
// TODO: set 'm_VolumetricLightingPreset'.

cmd.SetComputeFloatParam( m_VolumetricLightingCS, HDShaderIDs._CornetteShanksConstant, CornetteShanksPhasePartConstant(fog.asymmetry));
cmd.SetComputeFloatParam( m_VolumetricLightingCS, HDShaderIDs._CornetteShanksConstant, CornetteShanksPhasePartConstant(fog.anisotropy));
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferDensity, vBuffer.GetDensityBuffer()); // Read
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingIntegral, vBuffer.GetLightingIntegralBuffer()); // Write
if (enableReprojection)

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl


// Volumetric lighting.
float4 _AmbientProbeCoeffs[7]; // 3 bands of SH, packed, rescaled and convolved with the phase function
float _GlobalAsymmetry;
float _GlobalAnisotropy;
float3 _GlobalScattering;
float _GlobalExtinction;
float4 _VBufferResolution; // { w, h, 1/w, 1/h }

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.cs


cmd.SetGlobalVector(HDShaderIDs._GlobalScattering, data.scattering);
cmd.SetGlobalFloat( HDShaderIDs._GlobalExtinction, data.extinction);
cmd.SetGlobalFloat( HDShaderIDs._GlobalAsymmetry, 0.0f);
cmd.SetGlobalFloat( HDShaderIDs._GlobalAnisotropy, 0.0f);
}
}

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/VolumetricFog.cs


{
public ColorParameter albedo = new ColorParameter(new Color(0.5f, 0.5f, 0.5f));
public MinFloatParameter meanFreePath = new MinFloatParameter(1000000.0f, 1.0f);
public ClampedFloatParameter asymmetry = new ClampedFloatParameter(0.0f, -1.0f, 1.0f);
public ClampedFloatParameter anisotropy = new ClampedFloatParameter(0.0f, -1.0f, 1.0f);
// Override the volume blending function.
public override void Override(VolumeComponent state, float interpFactor)

float otherExtinction = VolumeRenderingUtils.ExtinctionFromMeanFreePath(other.meanFreePath);
Vector3 otherScattering = VolumeRenderingUtils.ScatteringFromExtinctionAndAlbedo(otherExtinction, (Vector3)(Vector4)other.albedo.value);
float blendExtinction = Mathf.Lerp(otherExtinction, thisExtinction, interpFactor);
Vector3 blendScattering = Vector3.Lerp(otherScattering, thisScattering, interpFactor);
float blendAsymmetry = Mathf.Lerp(other.asymmetry, asymmetry, interpFactor);
float blendExtinction = Mathf.Lerp(otherExtinction, thisExtinction, interpFactor);
Vector3 blendScattering = Vector3.Lerp(otherScattering, thisScattering, interpFactor);
float blendAnisotropy = Mathf.Lerp(other.anisotropy, anisotropy, interpFactor);
float blendMeanFreePath = VolumeRenderingUtils.MeanFreePathFromExtinction(blendExtinction);
Color blendAlbedo = (Color)(Vector4)VolumeRenderingUtils.AlbedoFromMeanFreePathAndScattering(blendMeanFreePath, blendScattering);

other.albedo.value = blendAlbedo;
}
if (asymmetry.overrideState)
if (anisotropy.overrideState)
other.asymmetry.value = blendAsymmetry;
other.anisotropy.value = blendAnisotropy;
}
}

param.albedo = albedo;
param.meanFreePath = meanFreePath;
param.asymmetry = asymmetry;
param.anisotropy = anisotropy;
DensityVolumeData data = param.GetData();

cmd.SetGlobalFloat( HDShaderIDs._GlobalExtinction, data.extinction);
cmd.SetGlobalFloat( HDShaderIDs._GlobalAsymmetry, asymmetry);
cmd.SetGlobalFloat( HDShaderIDs._GlobalAnisotropy, anisotropy);
}
}
}
正在加载...
取消
保存