浏览代码

Merge pull request #234 from EvgeniiG/master

Fix cookies and shadows not properly affecting transmission
/Branch_batcher
GitHub 8 年前
当前提交
32f0460f
共有 2 个文件被更改,包括 24 次插入20 次删除
  1. 19
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  2. 25
      Assets/ScriptableRenderPipeline/ShaderLibrary/AreaLighting.hlsl

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


// SSS parameters
#define SSS_N_PROFILES 8
#define SSS_UNIT_CONVERSION (1.0 / 300.0) // From 1/3 centimeters to meters
#define SSS_LOW_THICKNESS 0.005 // 5 mm
#define SSS_LOW_THICKNESS 0.002 // 2 mm
uint _EnableSSS; // Globally toggles subsurface scattering on/off
uint _TransmissionFlags; // 1 bit/profile; 0 = inf. thick, 1 = supports transmission

bsdfData.diffuseColor = baseColor;
// TODO take from subsurfaceProfile
bsdfData.fresnel0 = 0.04; /* 0.028 ? */
bsdfData.subsurfaceProfile = (SSS_N_PROFILES - 1) * inGBuffer2.a + 0.1; // Need to bias for integers to round trip through the G-buffer
bsdfData.subsurfaceProfile = (SSS_N_PROFILES - 0.9) * inGBuffer2.a; // Need to bias for integers to round trip through the G-buffer
// Make the Std. Dev. of 1 correspond to the effective radius of 1 cm (three-sigma rule).
bsdfData.subsurfaceRadius = SSS_UNIT_CONVERSION * inGBuffer2.r + 0.0001;
bsdfData.thickness = SSS_UNIT_CONVERSION * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] +

float4 cookie = float4(1.0, 1.0, 1.0, 1.0);
float shadow = 1;
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.shadowIndex >= 0)
{
#ifdef SHADOWS_USE_SHADOWCTXT
shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);

illuminance *= shadow;
}
[branch] if (lightData.cookieIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.cookieIndex >= 0)
{
float3 lightToSurface = positionWS - lightData.positionWS;

{
// Reverse the normal.
illuminance = saturate(dot(-bsdfData.normalWS, L));
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1;
illuminance *= shadow * cookie.a;

// illuminance *= SampleIES(lightLoopContext, lightData.IESIndex, sphericalCoord, 0).r;
//}
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.shadowIndex >= 0)
{
float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal);
#ifdef SHADOWS_USE_SHADOWCTXT

illuminance *= shadow;
}
[branch] if (lightData.cookieIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.cookieIndex >= 0)
{
float3x3 lightToWorld = float3x3(lightData.right, lightData.up, lightData.forward);

{
// Reverse the normal.
illuminance = saturate(dot(-bsdfData.normalWS, L)) * attenuation;
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1;
illuminance *= shadow * cookie.a;

float4 cookie = float4(1.0, 1.0, 1.0, 1.0);
float shadow = 1;
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.shadowIndex >= 0)
{
#ifdef SHADOWS_USE_SHADOWCTXT
shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, lightData.shadowIndex, L, posInput.unPositionSS);

illuminance *= shadow;
}
[branch] if (lightData.cookieIndex >= 0 && illuminance > 0.0)
[branch] if (lightData.cookieIndex >= 0)
{
// Compute the texture coordinates in [0, 1]^2.
float2 coord = positionNDC * 0.5 + 0.5;

{
// Reverse the normal.
illuminance = saturate(dot(-bsdfData.normalWS, L) * clipFactor);
// For low thickness, we can reuse the shadowing status for the back of the object.
shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1;
illuminance *= shadow * cookie.a;

25
Assets/ScriptableRenderPipeline/ShaderLibrary/AreaLighting.hlsl


// N.b.: this function accounts for horizon clipping.
float DiffuseSphereLightIrradiance(float sinSqSigma, float cosOmega)
{
float sinSqOmega = saturate(1 - cosOmega * cosOmega);
float irradiance;
float sinSqOmega = saturate(1 - cosOmega * cosOmega);
float cosSqSigma = saturate(1 - sinSqSigma);
float sinSqGamma = saturate(cosSqSigma / sinSqOmega);
float cosSqGamma = saturate(1 - sinSqGamma);

float omega = acos(cosOmega);
float gamma = asin(sinGamma);
[branch]
if (omega < 0 || omega >= HALF_PI + sigma)
{
// Full horizon occlusion (case #4).

float e = sinSqSigma * cosOmega;
float irradiance;
[branch]
if (omega < HALF_PI - sigma)

}
}
#else // Ref: Moving Frostbite to Physically Based Rendering, page 47 (2015).
float irradiance;
float cosSqOmega = cosOmega * cosOmega;
if (cosOmega * cosOmega > sinSqSigma)
[branch]
if (cosSqOmega > sinSqSigma)
float a = 1 / sinSqSigma - 1;
float w = rsqrt(a);
float x = sqrt(a);
float y = -x * cosOmega * rsqrt(sinSqOmega);
float z = sqrt(sinSqOmega * (1 - y * y));
irradiance = INV_PI * ((cosOmega * acos(y) - x * z) * sinSqSigma + atan(z * w));
float cotanOmega = cosOmega * rsqrt(1 - cosSqOmega);
float x = rcp(sinSqSigma) - 1;
float y = -cotanOmega * sqrt(x);
float z = sqrt(1 - cosSqOmega * rcp(sinSqSigma));
irradiance = INV_PI * ((cosOmega * acos(y) - z * sqrt(x)) * sinSqSigma + atan(z * rsqrt(x)));
}
#endif
return max(irradiance, 0);

正在加载...
取消
保存