浏览代码

Merge pull request #488 from EvgeniiG/Unity-2017.3

Introduce an improved method of IBL prefiltering
/Yibing-Project-2
GitHub 7 年前
当前提交
aa0bbbbe
共有 4 个文件被更改,包括 41 次插入15 次删除
  1. 2
      ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl
  2. 24
      ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl
  3. 16
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl
  4. 14
      ScriptableRenderPipeline/HDRenderPipeline/ShaderVariablesFunctions.hlsl

2
ScriptableRenderPipeline/Core/ShaderLibrary/BSDF.hlsl


return sqrt((-NdotV * a2 + NdotV) * NdotV + a2);
}
// Note: V = G / (4 * NdotL * NdotV)
// Ref: http://jcgt.org/published/0003/02/03/paper.pdf
float V_SmithJointGGX(float NdotL, float NdotV, float roughness, float preLambdaV)
{

return sqrt(aT2 * TdotV * TdotV + aB2 * BdotV * BdotV + NdotV * NdotV);
}
// Note: V = G / (4 * NdotL * NdotV)
// Ref: https://cedec.cesa.or.jp/2015/session/ENG/14698.html The Rendering Materials of Far Cry 4
float V_SmithJointGGXAniso(float TdotV, float BdotV, float NdotV, float TdotL, float BdotL, float NdotL, float roughnessT, float roughnessB, float preLambdaV)
{

24
ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl


{
float3x3 localToWorld = GetLocalFrame(N);
#ifndef USE_KARIS_APPROXIMATION
float NdotV = 1; // N == V
float preLambdaV = GetSmithJointGGXPreLambdaV(1, roughness);
#endif
// Bias samples towards the mirror direction to reduce variance.
// This will have a side effect of making the reflection sharper.
// Ref: Stochastic Screen-Space Reflections, p. 67.

// TODO: use a Gaussian-like filter to generate the MIP pyramid.
float3 val = SAMPLE_TEXTURECUBE_LOD(tex, sampl, L, mipLevel).rgb;
// Our goal is to use Monte-Carlo integration with importance sampling to evaluate
// X(V) = Integral{Radiance(L) * CBSDF(L, N, V) dL} / Integral{CBSDF(L, N, V) dL}.
// The goal of this function is to use Monte-Carlo integration to find
// X = Integral{Radiance(L) * CBSDF(L, N, V) dL} / Integral{CBSDF(L, N, V) dL}.
// Note: Integral{CBSDF(L, N, V) dL} is given by the FDG texture.
// We use the approximation of Brian Karis from "Real Shading in Unreal Engine 4":
// Weight ≈ NdotL, which produces nearly identical results in practice.
// Therefore, after the Monte Carlo expansion of the integrals,
// X = Sum(Radiance(L) * Weight) / Sum(Weight) = Sum(Radiance(L) * F * G) / Sum(F * G).
#ifndef USE_KARIS_APPROXIMATION
float F = 1; // The choice of the Fresnel factor does not appear to affect the result
float V = V_SmithJointGGX(NdotL, NdotV, roughness, preLambdaV);
float G = V * /* 4 * */ NdotL * NdotV; // 4 cancels out
lightInt += F * G * val;
cbsdfInt += F * G;
#else
// Use the approximation of Brian Karis from "Real Shading in Unreal Engine 4":
// Weight ≈ NdotL.
#endif
}
}

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


// Ref: Moving Frostbite to PBR (Appendix A)
float3 IntegrateSpecularGGXIBLRef(LightLoopContext lightLoopContext,
float3 V, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData,
uint sampleCount = 4096)
uint sampleCount = 2048)
float3x3 localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS);
float3x3 localToWorld;
if (bsdfData.materialId == MATERIALID_LIT_ANISO)
{
localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS);
}
else
{
// We do not have a tangent frame unless we use anisotropic GGX.
localToWorld = GetLocalFrame(bsdfData.normalWS);
}
float NdotV = max(preLightData.NdotV, MIN_N_DOT_V);
float3 acc = float3(0.0, 0.0, 0.0);

{
ImportanceSampleGGX(u, V, localToWorld, bsdfData.roughness, NdotV, L, VdotH, NdotL, weightOverPdf);
}
if (NdotL > 0.0)
{

14
ScriptableRenderPipeline/HDRenderPipeline/ShaderVariablesFunctions.hlsl


return mul(GetWorldToHClipMatrix(), float4(positionWS, 1.0));
}
float3 GetAbsolutePositionWS(float3 cameraRelativePositionWS)
float3 GetAbsolutePositionWS(float3 positionWS)
float3 pos = cameraRelativePositionWS;
pos += _WorldSpaceCameraPos;
positionWS += _WorldSpaceCameraPos;
return pos;
return positionWS;
float3 GetCameraRelativePositionWS(float3 absolutePositionWS)
float3 GetCameraRelativePositionWS(float3 positionWS)
float3 pos = absolutePositionWS;
pos -= _WorldSpaceCameraPos;
positionWS -= _WorldSpaceCameraPos;
return pos;
return positionWS;
}
// Note: '_WorldSpaceCameraPos' is set by the legacy Unity code.

正在加载...
取消
保存