浏览代码

Aggressively simplify

/main
Evgenii Golubev 8 年前
当前提交
d614abcd
共有 2 个文件被更改,包括 36 次插入52 次删除
  1. 37
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl
  2. 51
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl

37
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl


float3 unL = positionWS - lightData.positionWS;
// Pick the axis along which to dilate the attenuation sphere into an ellipsoid.
// Pick the major axis of the ellipsoid.
float3 axis = lightData.right;
// We define the ellipsoid s.t. r1 = (r + len / 2), r2 = r3 = r.

// EvaluateBSDF_Area - Approximation with Linearly Transformed Cosines
//-----------------------------------------------------------------------------
#define ELLIPSOIDAL_ATTENUATION
// #define ELLIPSOIDAL_ATTENUATION
void EvaluateBSDF_Area(LightLoopContext lightLoopContext,
float3 V, float3 positionWS,

float3 unL = positionWS - lightData.positionWS;
#ifdef ELLIPSOIDAL_ATTENUATION
// We define the ellipsoid s.t. r1 = (r + w / 2), r2 = (r + h / 2), r3 = r.
// TODO: This could be precomputed.
float radius = rsqrt(lightData.invSqrAttenuationRadius);
float invAspectRatio1 = radius / (radius + halfWidth);
float invAspectRatio2 = radius / (radius + halfHeight);
// Compute the light attenuation.
float intensity = GetEllipsoidalDistanceAttenuation(unL, lightData.invSqrAttenuationRadius,
lightData.right, invAspectRatio1,
lightData.up, invAspectRatio2);
#else
// The attenuation volume is a box of size [2 * r + w, 2 * r + h, 2 * r].
// TODO: this could be precomputed.
float radius = rsqrt(lightData.invSqrAttenuationRadius);
float3 invHalfDiag = float3(rcp(radius + halfWidth),
rcp(radius + halfHeight),
rcp(radius));
// Define the dimensions of the attenuation volume.
// TODO: This could be precomputed.
float radius = rsqrt(lightData.invSqrAttenuationRadius);
float3 invHalfDim = rcp(float3(radius + halfWidth,
radius + halfHeight,
radius));
float intensity = GetBoxToSphereMapDistanceAttenuation(unL, invHalfDiag);
#ifdef ELLIPSOIDAL_ATTENUATION
// The attenuation volume is an axis-aligned ellipsoid s.t.
// r1 = (r + w / 2), r2 = (r + h / 2), r3 = r.
float intensity = GetEllipsoidalDistanceAttenuation(unL, invHalfDim);
#else
// The attenuation volume is an axis-aligned box s.t.
// hX = (r + w / 2), hY = (r + h / 2), hZ = r.
float intensity = GetBoxDistanceAttenuation(unL, invHalfDim);
#endif
// Terminate if the shaded point is too far away.

51
Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl


return attenuation;
}
// Applies SmoothDistanceAttenuation() after stretching/shrinking the attenuation sphere
// of the given radius into an ellipsoid. The process is performed along the specified axis, and
// Applies SmoothDistanceAttenuation() after transforming the attenuation ellipsoid into a sphere
// of the given radius. The process is performed along the major axis of the ellipsoid, and
// the magnitude of the transformation is controlled by the aspect ratio (the inverse is given).
// Both the ellipsoid (e.i. 'axis') and 'unL' should be in the same coordinate system.
// 'unL' should be computed from the center of the ellipsoid.

// Project the unnormalized light vector onto the stretching/shrinking axis.
// Project the unnormalized light vector onto the axis.
// We want 'unL' to stretch/shrink along each axis (by the inverse of the aspect ratio).
// It is equivalent to stretching/shrinking the sphere (by the aspect ratio) into an ellipsoid.
// Transform the light vector instead of transforming the ellipsoid.
return SmoothDistanceAttenuation(dot(unL, unL), invSqrAttenuationRadius);
float sqDist = dot(unL, unL);
return SmoothDistanceAttenuation(sqDist, invSqrAttenuationRadius);
// Applies SmoothDistanceAttenuation() after stretching/shrinking the attenuation sphere
// of the given radius into an ellipsoid. The process is performed along the 2 specified axes, and
// the magnitude of the transformation is controlled by the aspect ratios (the inverses are given).
// Both the ellipsoid (e.i. 'axis1', 'axis2') and 'unL' should be in the same coordinate system.
// Applies SmoothDistanceAttenuation() using the axis-aligned ellipsoid of the given dimensions.
// Both the ellipsoid and 'unL' should be in the same coordinate system.
float GetEllipsoidalDistanceAttenuation(float3 unL, float invSqrAttenuationRadius,
float3 axis1, float invAspectRatio1,
float3 axis2, float invAspectRatio2)
float GetEllipsoidalDistanceAttenuation(float3 unL, float3 invHalfDim)
// Project the unnormalized light vector onto the stretching/shrinking axes.
float projL1 = dot(unL, axis1);
float projL2 = dot(unL, axis2);
// Transform the light vector so that we can work with
// with the ellipsoid as if it was a unit sphere.
unL *= invHalfDim;
// We want 'unL' to stretch/shrink along each axis (by the inverse of the aspect ratio).
// It is equivalent to stretching/shrinking the sphere (by the aspect ratio) into an ellipsoid.
float diff1 = projL1 - projL1 * invAspectRatio1;
float diff2 = projL2 - projL2 * invAspectRatio2;
unL -= diff1 * axis1;
unL -= diff2 * axis2;
return SmoothDistanceAttenuation(dot(unL, unL), invSqrAttenuationRadius);
float sqDist = dot(unL, unL);
return SmoothDistanceAttenuation(sqDist, 1.0);
// If the length of the diagonal of the box is 'd', invHalfDiag = rcp(0.5 * d).
// Both the box (e.i. 'invHalfDiag') and 'unL' should be in the same coordinate system.
// If the diagonal of the box is 'd', invHalfDim = rcp(0.5 * d).
// Both the box and 'unL' should be in the same coordinate system.
float GetBoxToSphereMapDistanceAttenuation(float3 unL, float3 invHalfDiag)
float GetBoxDistanceAttenuation(float3 unL, float3 invHalfDim)
// As our algorithm only works with the [-1, 1]^2 cube,
// we rescale the light vector to compensate.
unL *= invHalfDiag;
// Transform the light vector so that we can work with
// with the box as if it was a [-1, 1]^2 cube.
unL *= invHalfDim;
// Compute the light attenuation.
float sqDist = ComputeCubeToSphereMapSqMagnitude(unL);
return SmoothDistanceAttenuation(sqDist, 1.0);
}

正在加载...
取消
保存