Evgenii Golubev
8 年前
当前提交
0ca79425
共有 31 个文件被更改,包括 930 次插入 和 178 次删除
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader
-
7Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.asset
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.asset.meta
-
200Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.cs
-
5Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/LightLoop.cs
-
57Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/Resources/Deferred.shader
-
18Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute
-
170Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/TilePass.cs
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
-
8Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
-
27Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
-
14Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.shader
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitProperties.hlsl
-
11Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitTessellation.shader
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/PreIntegratedFGD.shader
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Unlit.shader
-
78Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/CommonSettings.cs
-
34Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/Editor/CommonSettingsEditor.cs
-
12Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/Resources/SkyHDRI.shader
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader
-
2Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/GGXConvolve.shader
-
92Assets/ScriptableRenderLoop/HDRenderPipeline/Utilities.cs
-
2ProjectSettings/GraphicsSettings.asset
-
133Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
-
9Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader.meta
-
195Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs
-
12Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs.meta
|
|||
Shader "Hidden/HDRenderPipeline/CombineSubsurfaceScattering" |
|||
{ |
|||
Properties |
|||
{ |
|||
_FilterRadius("", Float) = 20 |
|||
_BilateralScale("", Float) = 0.1 |
|||
[HideInInspector] _DstBlend("", Float) = 1 // Can be set to 1 for blending with specular |
|||
} |
|||
|
|||
SubShader |
|||
{ |
|||
Pass |
|||
{ |
|||
Stencil |
|||
{ |
|||
Ref 1 // StencilBits.SSS |
|||
Comp Equal |
|||
Pass Keep |
|||
} |
|||
|
|||
ZTest Always |
|||
ZWrite Off |
|||
Blend One [_DstBlend], Zero [_DstBlend] |
|||
|
|||
HLSLPROGRAM |
|||
#pragma target 4.5 |
|||
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev |
|||
|
|||
#pragma vertex Vert |
|||
#pragma fragment Frag |
|||
|
|||
//------------------------------------------------------------------------------------- |
|||
// Include |
|||
//------------------------------------------------------------------------------------- |
|||
|
|||
#include "Common.hlsl" |
|||
#include "Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderVariables.hlsl" |
|||
|
|||
//------------------------------------------------------------------------------------- |
|||
// Inputs & outputs |
|||
//------------------------------------------------------------------------------------- |
|||
|
|||
#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 _FilterRadius; // Uses world-space units |
|||
|
|||
TEXTURE2D(_CameraDepthTexture); |
|||
TEXTURE2D(_IrradianceSource); |
|||
SAMPLER2D(sampler_IrradianceSource); |
|||
|
|||
#define bilinearSampler sampler_IrradianceSource |
|||
|
|||
//------------------------------------------------------------------------------------- |
|||
// Implementation |
|||
//------------------------------------------------------------------------------------- |
|||
|
|||
struct Attributes |
|||
{ |
|||
uint vertexId : SV_VertexID; |
|||
}; |
|||
|
|||
struct Varyings |
|||
{ |
|||
float4 positionCS : SV_Position; |
|||
}; |
|||
|
|||
Varyings Vert(Attributes input) |
|||
{ |
|||
Varyings output; |
|||
|
|||
// Generate a triangle in homogeneous clip space, s.t. |
|||
// v0 = (-1, -1, 1), v1 = (3, -1, 1), v2 = (-1, 3, 1). |
|||
float2 uv = float2((input.vertexId << 1) & 2, input.vertexId & 2); |
|||
output.positionCS = float4(uv * 2 - 1, 1, 1); |
|||
|
|||
return output; |
|||
} |
|||
|
|||
float4 Frag(Varyings input) : SV_Target |
|||
{ |
|||
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw); |
|||
|
|||
float rawDepth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).r; |
|||
float cDepth = LinearEyeDepth(rawDepth, _ZBufferParams); |
|||
float radiusScale = _FilterRadius * _DistToProjWindow / cDepth; |
|||
|
|||
// Compute the filtering direction. |
|||
float2 unitDirection = _FilterHorizontal ? float2(1, 0) : float2(0, 1); |
|||
float2 scaledDirection = radiusScale * unitDirection; |
|||
|
|||
// Premultiply with the inverse of the screen size. |
|||
scaledDirection *= _ScreenSize.zw; |
|||
|
|||
// Take the first (central) sample. |
|||
float3 sWeight = _FilterKernel[0].rgb; |
|||
float2 sPosition = posInput.unPositionSS; |
|||
|
|||
float3 sIrradiance = LOAD_TEXTURE2D(_IrradianceSource, sPosition).rgb; |
|||
float3 cIrradiance = sIrradiance; |
|||
|
|||
// Accumulate filtered irradiance (already weighted by (albedo / Pi)). |
|||
float3 filteredIrradiance = sIrradiance * sWeight; |
|||
|
|||
[unroll] |
|||
for (int i = 1; i < N_SAMPLES; i++) |
|||
{ |
|||
sWeight = _FilterKernel[i].rgb; // TODO: normalize weights |
|||
sPosition = posInput.positionSS + scaledDirection * _FilterKernel[i].a; |
|||
|
|||
sIrradiance = SAMPLE_TEXTURE2D_LOD(_IrradianceSource, bilinearSampler, sPosition, 0).rgb; |
|||
rawDepth = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, bilinearSampler, sPosition, 0).r; |
|||
|
|||
// Apply bilateral filtering. |
|||
float sDepth = LinearEyeDepth(rawDepth, _ZBufferParams); |
|||
float dDepth = abs(sDepth - cDepth); |
|||
float dScale = _BilateralScale * _FilterRadius * _DistToProjWindow; |
|||
float t = saturate(dDepth / dScale); |
|||
|
|||
// TODO: use real-world distances for weighting. |
|||
filteredIrradiance += lerp(sIrradiance, cIrradiance, t) * sWeight; |
|||
} |
|||
|
|||
return float4(filteredIrradiance, 1.0); |
|||
} |
|||
ENDHLSL |
|||
} |
|||
} |
|||
Fallback Off |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 867b36db983aa0548889a66f8d685ff6 |
|||
timeCreated: 1485184880 |
|||
licenseType: Pro |
|||
ShaderImporter: |
|||
defaultTextures: [] |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
|
|||
namespace UnityEngine.Experimental.Rendering |
|||
{ |
|||
[Serializable] |
|||
public class SubsurfaceScatteringProfile |
|||
{ |
|||
public const int numSamples = 7; |
|||
|
|||
Color m_StdDev1; |
|||
Color m_StdDev2; |
|||
float m_LerpWeight; |
|||
Vector4[] m_FilterKernel; |
|||
bool m_KernelNeedsUpdate; |
|||
|
|||
// --- Methods ---
|
|||
|
|||
public Color stdDev1 |
|||
{ |
|||
get { return m_StdDev1; } |
|||
set { if (m_StdDev1 != value) { m_StdDev1 = value; m_KernelNeedsUpdate = true; } } |
|||
} |
|||
|
|||
public Color stdDev2 |
|||
{ |
|||
get { return m_StdDev2; } |
|||
set { if (m_StdDev2 != value) { m_StdDev2 = value; m_KernelNeedsUpdate = true; } } |
|||
} |
|||
|
|||
public float lerpWeight |
|||
{ |
|||
get { return m_LerpWeight; } |
|||
set { if (m_LerpWeight != value) { m_LerpWeight = value; m_KernelNeedsUpdate = true; } } |
|||
} |
|||
|
|||
public Vector4[] filterKernel |
|||
{ |
|||
get { if (m_KernelNeedsUpdate) ComputeKernel(); return m_FilterKernel; } |
|||
} |
|||
|
|||
public static SubsurfaceScatteringProfile Default |
|||
{ |
|||
get |
|||
{ |
|||
SubsurfaceScatteringProfile profile = new SubsurfaceScatteringProfile(); |
|||
profile.m_StdDev1 = new Color(0.3f, 0.3f, 0.3f, 0.0f); |
|||
profile.m_StdDev2 = new Color(1.0f, 1.0f, 1.0f, 0.0f); |
|||
profile.m_LerpWeight = 0.5f; |
|||
profile.ComputeKernel(); |
|||
return profile; |
|||
} |
|||
} |
|||
|
|||
static float Gaussian(float x, float stdDev) |
|||
{ |
|||
float variance = stdDev * stdDev; |
|||
return Mathf.Exp(-x * x / (2 * variance)) / Mathf.Sqrt(2 * Mathf.PI * variance); |
|||
} |
|||
|
|||
static float GaussianCombination(float x, float stdDev1, float stdDev2, float lerpWeight) |
|||
{ |
|||
return Mathf.Lerp(Gaussian(x, stdDev1), Gaussian(x, stdDev2), lerpWeight); |
|||
} |
|||
|
|||
static float RationalApproximation(float t) |
|||
{ |
|||
// Abramowitz and Stegun formula 26.2.23.
|
|||
// The absolute value of the error should be less than 4.5 e-4.
|
|||
float[] c = {2.515517f, 0.802853f, 0.010328f}; |
|||
float[] d = {1.432788f, 0.189269f, 0.001308f}; |
|||
return t - ((c[2] * t + c[1]) * t + c[0]) / (((d[2] * t + d[1]) * t + d[0]) * t + 1.0f); |
|||
} |
|||
|
|||
// Ref: https://www.johndcook.com/blog/csharp_phi_inverse/
|
|||
static float NormalCdfInverse(float p, float stdDev) |
|||
{ |
|||
float x; |
|||
|
|||
if (p < 0.5) |
|||
{ |
|||
// F^-1(p) = - G^-1(p)
|
|||
x = -RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(p))); |
|||
} |
|||
else |
|||
{ |
|||
// F^-1(p) = G^-1(1-p)
|
|||
x = RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(1.0f - p))); |
|||
} |
|||
|
|||
return x * stdDev; |
|||
} |
|||
|
|||
static float GaussianCombinationCdfInverse(float p, float stdDev1, float stdDev2, float lerpWeight) |
|||
{ |
|||
return Mathf.Lerp(NormalCdfInverse(p, stdDev1), NormalCdfInverse(p, stdDev2), lerpWeight); |
|||
} |
|||
|
|||
// Ref: http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
|||
static float VanDerCorputBase2(uint i) |
|||
{ |
|||
i = (i << 16) | (i >> 16); |
|||
i = ((i & 0x00ff00ff) << 8) | ((i & 0xff00ff00) >> 8); |
|||
i = ((i & 0x0f0f0f0f) << 4) | ((i & 0xf0f0f0f0) >> 4); |
|||
i = ((i & 0x33333333) << 2) | ((i & 0xcccccccc) >> 2); |
|||
i = ((i & 0x55555555) << 1) | ((i & 0xaaaaaaaa) >> 1); |
|||
|
|||
return i * (1.0f / 4294967296); |
|||
} |
|||
|
|||
void ComputeKernel() |
|||
{ |
|||
if (m_FilterKernel == null) |
|||
{ |
|||
m_FilterKernel = new Vector4[numSamples]; |
|||
} |
|||
|
|||
// Our goal is to blur the image using a filter which is represented
|
|||
// as a product of a linear combination of two normalized 1D Gaussians
|
|||
// as suggested by Jimenez et al. in "Separable Subsurface Scattering".
|
|||
// A normalized (i.e. energy-preserving) 1D Gaussian with the mean of 0
|
|||
// is defined as follows: G1(x, v) = exp(-x� / (2 * v)) / sqrt(2 * Pi * v),
|
|||
// where 'v' is variance and 'x' is the radial distance from the origin.
|
|||
// Using the weight 'w', our 1D and the resulting 2D filters are given as:
|
|||
// A1(v1, v2, w, x) = G1(x, v1) * (1 - w) + G1(r, v2) * w,
|
|||
// A2(v1, v2, w, x, y) = A1(v1, v2, w, x) * A1(v1, v2, w, y).
|
|||
// The resulting filter function is a non-Gaussian PDF.
|
|||
// It is separable by design, but generally not radially symmmetric.
|
|||
|
|||
// Find the widest Gaussian across 3 color channels.
|
|||
float maxStdDev1 = Mathf.Max(m_StdDev1.r, m_StdDev1.g, m_StdDev1.b); |
|||
float maxStdDev2 = Mathf.Max(m_StdDev2.r, m_StdDev2.g, m_StdDev2.b); |
|||
|
|||
Vector3 weightSum = new Vector3(0, 0, 0); |
|||
|
|||
// Importance sample the linear combination of two Gaussians.
|
|||
for (uint i = 0; i < numSamples; i++) |
|||
{ |
|||
float u = VanDerCorputBase2(i + 1); |
|||
float pos = GaussianCombinationCdfInverse(u, maxStdDev1, maxStdDev2, m_LerpWeight); |
|||
float pdf = GaussianCombination(pos, maxStdDev1, maxStdDev2, m_LerpWeight); |
|||
|
|||
Vector3 val; |
|||
val.x = GaussianCombination(pos, m_StdDev1.r, m_StdDev2.r, m_LerpWeight); |
|||
val.y = GaussianCombination(pos, m_StdDev1.g, m_StdDev2.g, m_LerpWeight); |
|||
val.z = GaussianCombination(pos, m_StdDev1.b, m_StdDev2.b, m_LerpWeight); |
|||
|
|||
m_FilterKernel[i].x = val.x / (pdf * numSamples); |
|||
m_FilterKernel[i].y = val.y / (pdf * numSamples); |
|||
m_FilterKernel[i].z = val.z / (pdf * numSamples); |
|||
m_FilterKernel[i].w = pos; |
|||
|
|||
weightSum.x += m_FilterKernel[i].x; |
|||
weightSum.y += m_FilterKernel[i].y; |
|||
weightSum.z += m_FilterKernel[i].z; |
|||
} |
|||
|
|||
// Renormalize the weights to conserve energy.
|
|||
for (uint i = 0; i < numSamples; i++) |
|||
{ |
|||
m_FilterKernel[i].x *= 1.0f / weightSum.x; |
|||
m_FilterKernel[i].y *= 1.0f / weightSum.y; |
|||
m_FilterKernel[i].z *= 1.0f / weightSum.z; |
|||
} |
|||
|
|||
m_KernelNeedsUpdate = false; |
|||
} |
|||
} |
|||
|
|||
[System.Serializable] |
|||
public class SubsurfaceScatteringParameters |
|||
{ |
|||
public const int numProfiles = 1; |
|||
public SubsurfaceScatteringProfile[] profiles; |
|||
public float bilateralScale; |
|||
|
|||
// --- Methods ---
|
|||
|
|||
public static SubsurfaceScatteringParameters Default |
|||
{ |
|||
get |
|||
{ |
|||
SubsurfaceScatteringParameters parameters = new SubsurfaceScatteringParameters(); |
|||
parameters.profiles = new SubsurfaceScatteringProfile[numProfiles]; |
|||
|
|||
for (int i = 0; i < numProfiles; i++) |
|||
{ |
|||
parameters.profiles[i] = SubsurfaceScatteringProfile.Default; |
|||
} |
|||
|
|||
parameters.bilateralScale = 0.1f; |
|||
return parameters; |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: e9493dbe9d624704d9a80a75d52835b3 |
|||
timeCreated: 1485361779 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue