浏览代码

Merge branch 'master' into Branch_Batching2

/Branch_Batching2
Arnaud Carre 8 年前
当前提交
23470784
共有 5 个文件被更改,包括 55 次插入56 次删除
  1. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  2. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.shader
  3. 60
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  4. 2
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl
  5. 36
      Assets/ScriptableRenderPipeline/ShaderLibrary/CommonLighting.hlsl

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


Shader.SetGlobalInt( "_TexturingModeFlags", (int)sssParameters.texturingModeFlags);
Shader.SetGlobalInt( "_TransmissionFlags", (int)sssParameters.transmissionFlags);
cmd.SetGlobalFloatArray( "_ThicknessRemaps", sssParameters.thicknessRemaps);
// We use the Disney transmission code with the parameters of Jimenez in order not to add an extra shader variant.
// We are currently supporting two different SSS mode: Jimenez (with 2-Gaussian profile) and Disney
// We have added the ability to switch between each other for subsurface scattering, but for transmittance this is more tricky as we need to add
// shader variant for forward, gbuffer and deferred shader. We want to avoid this.
// So for transmittance we use Disney profile formulation (that we know is more correct) in both case, and in the case of Jimenez we hack the parameters with 2-Gaussian parameters (Ideally we should fit but haven't find good fit) so it approximately match.
// Note: Jimenez SSS is in cm unit whereas Disney is in mm unit making an inconsistency here to compare model side by side
cmd.SetGlobalVectorArray("_ShapeParams", sssParameters.useDisneySSS ? sssParameters.shapeParams : sssParameters.halfRcpWeightedVariances);
cmd.SetGlobalVectorArray("_TransmissionTints", sssParameters.transmissionTints);

7
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Deferred.shader


outputs.specularLighting = float4(specularLighting, 1.0);
outputs.diffuseLighting = diffuseLighting;
#if defined(LIGHTLOOP_TILE_INDIRECT) || defined(LIGHTLOOP_TILE_ALL)
// Force non-0 indirect lighting to avoid SSS artifacts.
outputs.diffuseLighting.r = max(outputs.diffuseLighting.r, 0.000001);
// We SSSSS is enabled with use split lighting.
// SSSSS algorithm need to know which pixels contribute to SSS and which doesn't. We could use the stencil for that but it mean that it will increase the cost of SSSSS
// A simpler solution is to add a slight contribution here that isn't visible (here we chose fp16 min (which is also fp11 and fp10 min).
// The SSSSS algorithm will check if diffuse lighting is black and discard the pixel if it is the case
outputs.diffuseLighting.r = max(outputs.diffuseLighting.r, HFLT_MIN);
#endif
#else
outputs.combinedLighting = float4(diffuseLighting + specularLighting, 1.0);

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


}
// Computes F(x)/P(x), s.t. x = sqrt(r^2 + t^2).
float3 ComputeBilateralWeight(float3 S, float r, float t, float rcpDistScale, float rcpPdf)
float3 ComputeBilateralWeight(float3 S, float r, float t, float rcpPdf)
// Reducing the integration distance is equivalent to stretching the integration axis.
float3 val = KernelValCircle(sqrt(r * r + t * t) * rcpDistScale, S);
float3 val = KernelValCircle(sqrt(r * r + t * t), S);
// Rescaling of the PDF is handled via 'totalWeight'.
// Rescaling of the PDF is handled by 'totalWeight'.
millimPerUnit, scaledPixPerMm, rcpDistScale, totalIrradiance, totalWeight) \
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight) \
{ \
float r = kernel[profileID][i][0]; \
/* The relative sample position is known at compile time. */ \

float2 position = centerPosUnSS + vec * scaledPixPerMm; \
float2 position = centerPosUnSS + vec * pixelsPerMm; \
float3 irradiance = LOAD_TEXTURE2D(_IrradianceSource, position).rgb; \
\
/* TODO: see if making this a [branch] improves performance. */ \

float d = LinearEyeDepth(z, _ZBufferParams); \
float t = millimPerUnit * d - (millimPerUnit * centerDepthVS); \
float p = kernel[profileID][i][1]; \
float3 w = ComputeBilateralWeight(shapeParam, r, t, rcpDistScale, p); \
float3 w = ComputeBilateralWeight(shapeParam, r, t, p); \
\
totalIrradiance += w * irradiance; \
totalWeight += w; \

/* Our blur is energy-preserving, so 'centerWeight' should be set to 0. */ \
/* We do not terminate the loop since we want to gather the contribution */ \
/* of the remaining samples (e.g. in case of hair covering skin). */ \
/* Note: See comment in the output of deferred.shader */ \
millimPerUnit, scaledPixPerMm, rcpDistScale, totalIrradiance, totalWeight) \
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight) \
{ \
float centerRcpPdf = kernel[profileID][0][1]; \
float3 centerWeight = KernelValCircle(0, shapeParam) * centerRcpPdf; \

for (uint i = 1; i < n; i++) \
{ \
SSS_ITER(i, n, kernel, profileID, shapeParam, centerPosUnSS, centerDepthVS, \
millimPerUnit, scaledPixPerMm, rcpDistScale, totalIrradiance, totalWeight) \
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight) \
} \
}

float3 cornerPosVS = ComputeViewSpacePosition(cornerPosSS, centerDepth, _InvProjMatrix);
// Compute the view-space dimensions of the pixel as a quad projected onto geometry.
float2 unitsPerPixel = 2 * (cornerPosVS.xy - centerPosVS.xy);
float2 unitsPerPixel = 2 * abs(cornerPosVS.xy - centerPosVS.xy);
float metersPerUnit = _WorldScales[profileID];
float millimPerUnit = MILLIMETERS_PER_METER * metersPerUnit;
float2 scaledPixPerMm = distScale * rcp(millimPerUnit * unitsPerPixel);
// Rescaling the filter is equivalent to inversely scaling the world.
float metersPerUnit = _WorldScales[profileID] / distScale;
float millimPerUnit = MILLIMETERS_PER_METER * metersPerUnit;
float2 pixelsPerMm = rcp(millimPerUnit * unitsPerPixel);
// Take the first (central) sample.
// TODO: copy its neighborhood into LDS.

float maxDistInPixels = maxDistance * max(scaledPixPerMm.x, scaledPixPerMm.y);
float maxDistInPixels = maxDistance * max(pixelsPerMm.x, pixelsPerMm.y);
[branch]
if (distScale == 0 || maxDistInPixels < 1)
{

#else
SSS_LOOP(SSS_N_SAMPLES_FAR_FIELD, _FilterKernelsFarField,
profileID, shapeParam, centerPosition, centerPosVS.z,
millimPerUnit, scaledPixPerMm, rcp(distScale),
totalIrradiance, totalWeight)
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight)
#endif
}
else

#else
SSS_LOOP(SSS_N_SAMPLES_NEAR_FIELD, _FilterKernelsNearField,
profileID, shapeParam, centerPosition, centerPosVS.z,
millimPerUnit, scaledPixPerMm, rcp(distScale),
totalIrradiance, totalWeight)
millimPerUnit, pixelsPerMm, totalIrradiance, totalWeight)
float metersPerUnit = _WorldScales[profileID] * SSS_BASIC_DISTANCE_SCALE;
float centimPerUnit = CENTIMETERS_PER_METER * metersPerUnit;
float2 scaledPixPerCm = distScale * rcp(centimPerUnit * unitsPerPixel);
float unitScale = centimPerUnit / distScale;
// Rescaling the filter is equivalent to inversely scaling the world.
float metersPerUnit = _WorldScales[profileID] / distScale * SSS_BASIC_DISTANCE_SCALE;
float centimPerUnit = CENTIMETERS_PER_METER * metersPerUnit;
float2 pixelsPerCm = rcp(centimPerUnit * unitsPerPixel);
float scaledStepSize = scaledPixPerCm.x;
float2 unitDirection = float2(1, 0);
float2 unitDirection = float2(1, 0);
float scaledStepSize = scaledPixPerCm.y;
float2 unitDirection = float2(0, 1);
float2 unitDirection = float2(0, 1);
float2 scaledDirection = scaledPixPerCm * unitDirection;
float2 scaledDirection = pixelsPerCm * unitDirection;
#if (RBG_BILATERAL_WEIGHTS != 0)
#if RBG_BILATERAL_WEIGHTS
float3 halfRcpVariance = _HalfRcpWeightedVariances[profileID].rgb;
#else
float halfRcpVariance = _HalfRcpWeightedVariances[profileID].a;

// We perform point sampling. Therefore, we can avoid the cost
// of filtering if we stay within the bounds of the current pixel.
// We use the value of 1 instead of 0.5 as an optimization.
float maxDistInPixels = scaledStepSize * maxDistance;
float maxDistInPixels = maxDistance * max(pixelsPerCm.x, pixelsPerCm.y);
[branch]
if (distScale == 0 || maxDistInPixels < 1)

[flatten]
if (any(sampleIrradiance))
{
#if SSS_BILATERAL
float zDistance = unitScale * sampleDepth - (unitScale * centerPosVS.z);
float zDistance = centimPerUnit * sampleDepth - (centimPerUnit * centerPosVS.z);
#endif
totalIrradiance += sampleWeight * sampleIrradiance;
totalWeight += sampleWeight;

2
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


#define FLT_MIN 1.175494351e-38 // Minimum representable positive floating-point number
#define FLT_MAX 3.402823466e+38 // Maximum representable floating-point number
#define HFLT_MIN 0.00006103515625 // 2^14 it is the same for 10, 11 and 16bit float. ref: https://www.khronos.org/opengl/wiki/Small_Float_Formats
float DegToRad(float deg)
{
return deg * PI / 180.0;

36
Assets/ScriptableRenderPipeline/ShaderLibrary/CommonLighting.hlsl


return N;
}
// Generates an orthonormal basis from a unit vector.
// Generates an orthonormal right-handed basis from a unit vector.
// Ref: http://marc-b-reynolds.github.io/quaternions/2016/07/06/Orthonormal.html
float3 upVector = abs(localZ.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0);
float3 localX = normalize(cross(upVector, localZ));
float3 localY = cross(localZ, localX);
return float3x3(localX, localY, localZ);
}
float x = localZ.x;
float y = localZ.y;
float z = localZ.z;
float sz = z >= 0 ? 1 : -1;
float a = 1 / (sz + z);
float ya = y * a;
float b = x * ya;
float c = x * sz;
// TODO: test
/*
// http://orbit.dtu.dk/files/57573287/onb_frisvad_jgt2012.pdf
void GetLocalFrame(float3 N, out float3 tangentX, out float3 tangentY)
{
if (N.z < -0.999) // Handle the singularity
{
tangentX = float3(0.0, -1.0, 0.0);
tangentY = float3(-1.0, 0.0, 0.0);
return ;
}
float3 localX = float3(c * x * a - 1, sz * b, c);
float3 localY = float3(b, y * ya - sz, y);
float a = 1.0 / (1.0 + N.z);
float b = -N.x * N.y * a;
tangentX = float3(1.0 - N.x * N.x * a , b, -N.x);
tangentY = float3(b, 1.0 - N.y * N.y * a, -N.y);
return float3x3(localX, localY, localZ);
*/
#endif // UNITY_COMMON_LIGHTING_INCLUDED
正在加载...
取消
保存