浏览代码

Allow for multiple SSS profiles

/main
Evgenii Golubev 8 年前
当前提交
b3db0917
共有 3 个文件被更改,包括 29 次插入17 次删除
  1. 13
      Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.cs
  2. 27
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  3. 6
      Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs

13
Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.cs


float distanceToProjectionWindow = 1.0f / Mathf.Tan(0.5f * Mathf.Deg2Rad * hdCamera.camera.fieldOfView);
m_CombineSubsurfaceScattering.SetFloat("_DistToProjWindow", distanceToProjectionWindow);
m_CombineSubsurfaceScattering.SetFloat("_BilateralScale", 0.05f * sssParameters.bilateralScale);
// TODO: use user-defined values for '_ProfileID' and '_FilterRadius.'
m_CombineSubsurfaceScattering.SetVectorArray("_FilterKernel", sssParameters.profiles[0].filterKernel);
// Upload the kernel data.
Vector4[] kernelData = new Vector4[SubsurfaceScatteringParameters.maxNumProfiles * SubsurfaceScatteringProfile.numSamples];
for (int j = 0, m = sssParameters.profiles.Length; j < m; j++)
{
for (int i = 0, n = SubsurfaceScatteringProfile.numSamples; i < n; i++)
{
kernelData[n * j + i] = sssParameters.profiles[j].filterKernel[i];
}
}
m_CombineSubsurfaceScattering.SetVectorArray("_FilterKernels", kernelData);
MaterialPropertyBlock properties = new MaterialPropertyBlock();

27
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader


// Inputs & outputs
//-------------------------------------------------------------------------------------
#define N_SAMPLES 7
#define N_PROFILES 8
#define N_SAMPLES 7
float _BilateralScale; // Uses world-space units
float _DistToProjWindow; // The height of the projection window is 2 meters
float _FilterHorizontal; // Vertical = 0, horizontal = 1
float4 _FilterKernel[7]; // RGB = weights, A = radial distance
float _BilateralScale; // Uses world-space units
float _DistToProjWindow; // The height of the projection window is 2 meters
float _FilterHorizontal; // Vertical = 0, horizontal = 1
float4 _FilterKernels[N_PROFILES][N_SAMPLES]; // RGB = weights, A = radial distance
TEXTURE2D(_CameraDepthTexture);
TEXTURE2D(_GBufferTexture2);

{
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);
float rawDepth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).r;
float centerDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float radiusScale = LOAD_TEXTURE2D(_GBufferTexture2, posInput.unPositionSS).r;
float filterRadius = radiusScale * _DistToProjWindow / centerDepth;
float rawDepth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).r;
float centerDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float2 gBufferValue = LOAD_TEXTURE2D(_GBufferTexture2, posInput.unPositionSS).ra;
float radiusScale = gBufferValue.x;
float profileID = gBufferValue.y * N_PROFILES;
float filterRadius = radiusScale * _DistToProjWindow / centerDepth;
// Compute the filtering direction.
float x, y;

scaledDirection *= _ScreenSize.zw;
// Take the first (central) sample.
float3 sampleWeight = _FilterKernel[0].rgb;
float3 sampleWeight = _FilterKernels[profileID][0].rgb;
float2 samplePosition = posInput.unPositionSS;
float3 sampleIrradiance = LOAD_TEXTURE2D(_IrradianceSource, samplePosition).rgb;

[unroll]
for (int i = 1; i < N_SAMPLES; i++)
{
sampleWeight = _FilterKernel[i].rgb;
samplePosition = posInput.positionSS + scaledDirection * _FilterKernel[i].a;
sampleWeight = _FilterKernels[profileID][i].rgb;
samplePosition = posInput.positionSS + scaledDirection * _FilterKernels[profileID][i].a;
sampleIrradiance = SAMPLE_TEXTURE2D_LOD(_IrradianceSource, bilinearSampler, samplePosition, 0).rgb;
rawDepth = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, bilinearSampler, samplePosition, 0).r;

6
Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs


public class SubsurfaceScatteringParameters : ScriptableObject
{
const int m_maxNumProfiles = 8;
public const int maxNumProfiles = 8;
[SerializeField]
int m_NumProfiles;
[SerializeField]

void OnValidate()
{
if (m_Profiles.Length > m_maxNumProfiles)
if (m_Profiles.Length > maxNumProfiles)
Array.Resize(ref m_Profiles, m_maxNumProfiles);
Array.Resize(ref m_Profiles, maxNumProfiles);
}
m_NumProfiles = m_Profiles.Length;

正在加载...
取消
保存