浏览代码

Implement transmission for Disney SSS

/Branch_Batching2
Evgenii Golubev 7 年前
当前提交
a92b6036
共有 6 个文件被更改,包括 34 次插入22 次删除
  1. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  2. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
  3. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs.hlsl
  4. 32
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  5. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  6. 6
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/LitUI.cs


// Load the profile from the GUI field.
int profileID = subsurfaceProfile.settingsIndex;
if (0 <= profileID && profileID < hdPipeline.sssSettings.profiles.Length)
if (0 <= profileID && profileID < hdPipeline.sssSettings.profiles.Length &&
hdPipeline.sssSettings.profiles[profileID] != null &&
hdPipeline.sssSettings.profiles[profileID] == subsurfaceProfile)
{
validProfile = true;
material.SetInt("_SubsurfaceProfile", profileID);

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


public float thickness;
public int subsurfaceProfile;
public bool enableTransmission; // Read from the SSS profile
public bool useThinObjectMode; // Read from the SSS profile
public Vector3 transmittance;
// SpecColor

7
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs.hlsl


#define DEBUGVIEW_LIT_BSDFDATA_THICKNESS (1043)
#define DEBUGVIEW_LIT_BSDFDATA_SUBSURFACE_PROFILE (1044)
#define DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMISSION (1045)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1046)
#define DEBUGVIEW_LIT_BSDFDATA_USE_THIN_OBJECT_MODE (1046)
#define DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE (1047)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit.GBufferMaterial: static fields

float thickness;
int subsurfaceProfile;
bool enableTransmission;
bool useThinObjectMode;
float3 transmittance;
};

break;
case DEBUGVIEW_LIT_BSDFDATA_ENABLE_TRANSMISSION:
result = (bsdfdata.enableTransmission) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_BSDFDATA_USE_THIN_OBJECT_MODE:
result = (bsdfdata.useThinObjectMode) ? float3(1.0, 1.0, 1.0) : float3(0.0, 0.0, 0.0);
break;
case DEBUGVIEW_LIT_BSDFDATA_TRANSMITTANCE:
result = bsdfdata.transmittance;

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


float _ThicknessRemaps[SSS_N_PROFILES][2]; // Remap: 0 = start, 1 = end - start
float4 _ShapeParameters[SSS_N_PROFILES]; // RGB = S = 1 / D; A = filter radius
#define SSS_LOW_THICKNESS 10000 // REMOVE
//-----------------------------------------------------------------------------
// Helper functions/variable specific to this material
//-----------------------------------------------------------------------------

#endif
}
// Evaluates transmittance for a linear combination of two normalized 2D Gaussians.
// Computes results for each color channel separately.
// Ref: Real-Time Realistic Skin Translucency (2010), equation 9 (modified).
float3 ComputeTransmittance(float3 halfRcpVariance1, float lerpWeight1,
float3 halfRcpVariance2, float lerpWeight2,
float3 tintColor, float thickness, float radiusScale)
// Computes the fraction of light passing through the object.
// N.b.: it is not just zero scattering (light traveling in a straight path)!
// Ref: Approximate Reflectance Profiles for Efficient Subsurface Scattering by Pixar (BSSRDF only).
float3 ComputeTransmittance(float3 S, float thickness, float radiusScale)
// thickness *= SSS_DISTANCE_SCALE / radiusScale;
// thickness /= radiusScale;
return float3(0, 0, 0);
float3 expOneThird = exp((-thickness * (1.0 / 3.0)) * S);
return 0.5 * (expOneThird + expOneThird * expOneThird * expOneThird);
}
void FillMaterialIdStandardData(float3 baseColor, float specular, float metallic, float roughness, float3 normalWS, float3 tangentWS, float anisotropy, inout BSDFData bsdfData)

bsdfData.thickness = _ThicknessRemaps[subsurfaceProfile][0] +
_ThicknessRemaps[subsurfaceProfile][1] * thickness;
bsdfData.enableTransmission = false;
uint transmissionMode = BitFieldExtract(_TransmissionFlags, 2, 2 * subsurfaceProfile);
bsdfData.enableTransmission = (_EnableSSS != 0) && (transmissionMode != SSS_TRSM_MODE_NONE);
bsdfData.useThinObjectMode = transmissionMode == SSS_TRSM_MODE_THIN;
bsdfData.transmittance = 0;
bsdfData.transmittance = ComputeTransmittance(_ShapeParameters[subsurfaceProfile].rgb, bsdfData.thickness, bsdfData.subsurfaceRadius);
}
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, subsurfaceProfile);

float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w)));
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1;
shadow = bsdfData.useThinObjectMode ? shadow : 1;
illuminance *= shadow * cookie.a;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible.

illuminance *= attenuation;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1;
shadow = bsdfData.useThinObjectMode ? shadow : 1;
illuminance *= shadow * cookie.a;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible.

illuminance *= clipFactor;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1;
shadow = bsdfData.useThinObjectMode ? shadow : 1;
illuminance *= shadow * cookie.a;
// The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible.

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader


//-------------------------------------------------------------------------------------
// Computes the value of the integrand over a disk: (2 * PI * r) * KernelVal().
// N.b.: the returned value is multiplied by 4.
float3 expOneThird = exp(-r * (S * (1.0 / 3.0)));
return (0.25 * S) * (expOneThird + expOneThird * expOneThird * expOneThird);
float3 expOneThird = exp((-r * (1.0 / 3.0)) * S);
// We can skip the multiplication by 0.25 due to weight renormalization.
return /* 0.25 * */ S * (expOneThird + expOneThird * expOneThird * expOneThird);
}
// Computes F(x)/P(x), s.t. x = sqrt(r^2 + z^2).

6
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


// unsigned integer bit field extract implementation
uint BitFieldExtract(uint data, uint size, uint offset)
{
return (data >> offset) & ((1u << size) - 1u);
return (data >> offset) & ((1 << size) - 1);
bool IsBitSet(uint number, uint bitPos)
bool IsBitSet(uint data, uint bitPos)
return ((number >> bitPos) & 1) != 0;
return BitFieldExtract(data, 1, bitPos) != 0;
}
#ifndef INTRINSIC_CLAMP

正在加载...
取消
保存