浏览代码

Merge pull request #537 from EvgeniiG/Unity-2017.3

Apply the albedo during lighting only once
/Yibing-Project-2
GitHub 7 年前
当前提交
e16e3030
共有 6 个文件被更改,包括 72 次插入45 次删除
  1. 2
      ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs
  2. 89
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  3. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl
  4. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute
  5. 8
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader
  6. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs

2
ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineMenuItems.cs


static void MenuCreateSubsurfaceScatteringProfile()
{
var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon");
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<DoCreateNewAssetSubsurfaceScatteringSettings>(), "New SSS Profile.asset", icon, null);
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<DoCreateNewAssetSubsurfaceScatteringSettings>(), "New SSS Settings.asset", icon, null);
}
[MenuItem("Assets/Create/HDRenderPipeline/HDRISky Settings", priority = 750)]

89
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


uint transmissionMode = BitFieldExtract(_TransmissionFlags, 2u, 2u * subsurfaceProfile);
bsdfData.enableTransmission = transmissionMode != SSS_TRSM_MODE_NONE && (_EnableSSSAndTransmission > 0);
bsdfData.useThinObjectMode = transmissionMode == SSS_TRSM_MODE_THIN;
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, subsurfaceProfile);
#if defined(SHADERPASS) && (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT) // In case of GI pass don't modify the diffuseColor
bool enableSssAndTransmission = false;
#elif defined(SHADERPASS) && (SHADERPASS == SHADERPASS_SUBSURFACE_SCATTERING)
bool enableSssAndTransmission = true;
#else
bool enableSssAndTransmission = _EnableSSSAndTransmission != 0;
#endif
if (enableSssAndTransmission) // If we globally disable SSS effect, don't modify diffuseColor
if (bsdfData.enableTransmission)
// We modify the albedo here as this code is used by all lighting (including light maps and GI).
if (performPostScatterTexturing)
{
#if !defined(SHADERPASS) || (SHADERPASS != SHADERPASS_SUBSURFACE_SCATTERING)
bsdfData.diffuseColor = float3(1.0, 1.0, 1.0);
#endif
}
else
{
bsdfData.diffuseColor = sqrt(bsdfData.diffuseColor);
}
}
bsdfData.useThinObjectMode = transmissionMode == SSS_TRSM_MODE_THIN;
if (bsdfData.enableTransmission)
{
if (_UseDisneySSS)
{
bsdfData.transmittance = ComputeTransmittance(_ShapeParams[subsurfaceProfile].rgb,

_TransmissionTints[subsurfaceProfile].rgb,
bsdfData.thickness, bsdfData.subsurfaceRadius);
}
}
}
// Returns the modified albedo (diffuse color) for materials with subsurface scattering.
// Ref: Advanced Techniques for Realistic Real-Time Skin Rendering.
float3 ApplyDiffuseTexturingMode(BSDFData bsdfData)
{
float3 albedo = bsdfData.diffuseColor;
if (bsdfData.materialId == MATERIALID_LIT_SSS)
{
#if defined(SHADERPASS) && (SHADERPASS == SHADERPASS_SUBSURFACE_SCATTERING)
// If the SSS pass is executed, we know we have SSS enabled.
bool enableSssAndTransmission = true;
#else
bool enableSssAndTransmission = _EnableSSSAndTransmission != 0;
#endif
bsdfData.transmittance *= bsdfData.diffuseColor; // Premultiply
if (enableSssAndTransmission)
{
bool performPostScatterTexturing = IsBitSet(_TexturingModeFlags, bsdfData.subsurfaceProfile);
if (performPostScatterTexturing)
{
// Post-scatter texturing mode: the albedo is only applied during the SSS pass.
#if !defined(SHADERPASS) || (SHADERPASS != SHADERPASS_SUBSURFACE_SCATTERING)
albedo = float3(1, 1, 1);
#endif
}
else
{
// Pre- and pos- scatter texturing mode.
albedo = sqrt(albedo);
}
}
return albedo;
}
void FillMaterialIdClearCoatData(float3 coatNormalWS, float coatCoverage, float coatIOR, inout BSDFData bsdfData)

// This function require the 3 structure surfaceData, builtinData, bsdfData because it may require both the engine side data, and data that will not be store inside the gbuffer.
float3 GetBakedDiffuseLigthing(SurfaceData surfaceData, BuiltinData builtinData, BSDFData bsdfData, PreLightData preLightData)
{
bsdfData.diffuseColor = ApplyDiffuseTexturingMode(bsdfData);
// Premultiply bake diffuse lighting information with DisneyDiffuse pre-integration
return builtinData.bakeDiffuseLighting * preLightData.diffuseFGD * surfaceData.ambientOcclusion * bsdfData.diffuseColor + builtinData.emissiveColor;
}

float diffuseTerm = DisneyDiffuse(NdotV, NdotL, LdotV, bsdfData.perceptualRoughness);
#endif
diffuseLighting = bsdfData.diffuseColor * diffuseTerm;
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
diffuseLighting = diffuseTerm;
}
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.

float illuminance = Lambert() * ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
}

float illuminance = Lambert() * ComputeWrappedDiffuseLighting(-NdotL, SSS_WRAP_LIGHT);
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse += EvaluateTransmission(bsdfData, illuminance * lightData.diffuseScale, shadow);
}

{
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformDiffuse);
ltcValue *= lightData.diffuseScale;
lighting.diffuse = bsdfData.diffuseColor * (preLightData.ltcMagnitudeDiffuse * ltcValue);
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
}
[branch] if (bsdfData.enableTransmission)

ltcValue *= lightData.diffuseScale;
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse += EvaluateTransmission(bsdfData, ltcValue, 1);
}

// Polygon irradiance in the transformed configuration.
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformDiffuse));
ltcValue *= lightData.diffuseScale;
lighting.diffuse = bsdfData.diffuseColor * (preLightData.ltcMagnitudeDiffuse * ltcValue);
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse = preLightData.ltcMagnitudeDiffuse * ltcValue;
}
[branch] if (bsdfData.enableTransmission)

ltcValue *= lightData.diffuseScale;
// We use diffuse lighting for accumulation since it is going to be blurred during the SSS pass.
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
lighting.diffuse += EvaluateTransmission(bsdfData, ltcValue, 1);
}

lighting.indirect.specularReflected *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion));
#endif
// TODO: we could call a function like PostBSDF that will apply albedo and divide by PI once for the loop
lighting.direct.diffuse *=
#if GTAO_MULTIBOUNCE_APPROX
GTAOMultiBounce(directAmbientOcclusion, bsdfData.diffuseColor);

diffuseLighting = lighting.direct.diffuse + bakeDiffuseLighting;
float3 modifiedDiffuseColor = ApplyDiffuseTexturingMode(bsdfData);
// Apply the albedo to the direct diffuse lighting (only once). The indirect (baked)
// diffuse lighting has already had the albedo applied in GetBakedDiffuseLigthing().
diffuseLighting = modifiedDiffuseColor * lighting.direct.diffuse + bakeDiffuseLighting;
// If refraction is enable we use the transmittanceMask to lerp between current diffuse lighting and refraction value
// Physically speaking, it should be transmittanceMask should be 1, but for artistic reasons, we let the value vary
#if HAS_REFRACTION

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl


{
float4 val = SampleEnv(lightLoopContext, lightData.envIndex, L, 0);
// diffuse Albedo is apply here as describe in ImportanceSampleLambert function
acc += bsdfData.diffuseColor * LambertNoPI() * weightOverPdf * val.rgb;
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
acc += LambertNoPI() * weightOverPdf * val.rgb;
}
}

// in weightOverPdf of ImportanceSampleLambert call.
float disneyDiffuse = DisneyDiffuse(NdotV, NdotL, LdotV, bsdfData.perceptualRoughness);
// diffuse Albedo is apply here as describe in ImportanceSampleLambert function
acc += bsdfData.diffuseColor * disneyDiffuse * weightOverPdf * val.rgb;
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF().
acc += disneyDiffuse * weightOverPdf * val.rgb;
}
}

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.compute


// divergence of execution across the warp.
float maxDistInPixels = maxDistance * max(pixelsPerMm.x, pixelsPerMm.y);
float3 albedo = ApplyDiffuseTexturingMode(bsdfData);
_CameraFilteringTexture[pixelCoord] = float4(bsdfData.diffuseColor * centerIrradiance, 1);
_CameraFilteringTexture[pixelCoord] = float4(albedo * centerIrradiance, 1);
#endif
return;
}

[branch] if (!useNearFieldKernel)
{
_CameraFilteringTexture[pixelCoord] = float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
_CameraFilteringTexture[pixelCoord] = float4(albedo * totalIrradiance / totalWeight, 1);
return;
}

totalIrradiance, totalWeight);
}
_CameraFilteringTexture[pixelCoord] = float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
_CameraFilteringTexture[pixelCoord] = float4(albedo * totalIrradiance / totalWeight, 1);
}

8
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/SubsurfaceScattering.shader


float halfRcpVariance = _HalfRcpWeightedVariances[profileID].a;
#endif
float3 albedo = ApplyDiffuseTexturingMode(bsdfData);
bsdfData.diffuseColor = float3(1, 1, 1);
albedo = float3(1, 1, 1);
#endif
// Take the first (central) sample.

#if SSS_DEBUG_LOD
return float4(0, 0, 1, 1);
#else
return float4(bsdfData.diffuseColor * sampleIrradiance, 1);
return float4(albedo * sampleIrradiance, 1);
#endif
}

}
}
return float4(bsdfData.diffuseColor * totalIrradiance / totalWeight, 1);
return float4(albedo * totalIrradiance / totalWeight, 1);
}
ENDHLSL
}

2
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringSettings.cs


for (int i = 0; i < profileArraySize; i++)
{
if (profiles[i] == null)
profiles[i] = new SubsurfaceScatteringProfile("Profile " + i + 1);
profiles[i] = new SubsurfaceScatteringProfile("Profile " + (i + 1));
profiles[i].Validate();
}

正在加载...
取消
保存