浏览代码

Implement pyramid projector lights

/fptl_cleanup
Evgenii Golubev 7 年前
当前提交
6b6c6c54
共有 4 个文件被更改,包括 80 次插入47 次删除
  1. 54
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  2. 34
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  3. 11
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs
  4. 28
      Assets/TestScenes/HDTest/HDRenderLoopTest.unity

54
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


lightVolumeData.lightCategory = (uint)lightCategory;
lightVolumeData.lightVolume = (uint)lightVolumeType;
if (gpuLightType == GPULightType.Spot)
if (gpuLightType == GPULightType.Spot || gpuLightType == GPULightType.ProjectorPyramid)
Vector3 lightDir = lightToWorld.GetColumn(2); // Z axis in world space
Vector3 lightDir = lightToWorld.GetColumn(2);
var vz = lightDir; // Z axis in world space
Vector3 vz = lightDir; // Z axis in world space
// transform to camera space (becomes a left hand coordinate frame in Unity since Determinant(worldToView)<0)
vx = worldToView.MultiplyVector(vx);

const float degToRad = (float)(pi / 180.0);
var sa = light.light.spotAngle;
if (gpuLightType == GPULightType.ProjectorPyramid)
{
Vector3 lightPosToProjWindowCorner = (0.5f * lightData.size.x) * vx + (0.5f * lightData.size.y) * vy + 1.0f * vz;
cs = Vector3.Dot(vz, Vector3.Normalize(lightPosToProjWindowCorner));
si = Mathf.Sqrt(1.0f - cs * cs);
}
const float FltMax = 3.402823466e+38F;
var ta = cs > 0.0f ? (si / cs) : FltMax;
var cota = si > 0.0f ? (cs / si) : FltMax;

fAltDx *= range; fAltDy *= range;
// Handle case of pyramid with this select
var altDist = Mathf.Sqrt(fAltDy * fAltDy + (gpuLightType == GPULightType.Spot ? 1.0f : 2.0f) * fAltDx * fAltDx);
// Handle case of pyramid with this select (currently unused)
var altDist = Mathf.Sqrt(fAltDy * fAltDy + (true ? 1.0f : 2.0f) * fAltDx * fAltDx);
bound.radius = altDist > (0.5f * range) ? altDist : (0.5f * range); // will always pick fAltDist
bound.scaleXY = squeeze ? new Vector2(0.01f, 0.01f) : new Vector2(1.0f, 1.0f);

lightVolumeData.lightPos = worldToView.MultiplyPoint(lightPos);
lightVolumeData.radiusSq = range * range;
lightVolumeData.cotan = cota;
lightVolumeData.featureFlags = LightFeatureFlags.FEATURE_FLAG_LIGHT_PUNCTUAL;
lightVolumeData.featureFlags = (gpuLightType == GPULightType.Spot) ? LightFeatureFlags.FEATURE_FLAG_LIGHT_PUNCTUAL
: LightFeatureFlags.FEATURE_FLAG_LIGHT_PROJECTOR;
}
else if (gpuLightType == GPULightType.Point)
{

break;
default:
continue;
Debug.Assert(false, "TODO: encountered an unknown LightType.");
break;
}
}
else

case LightArchetype.Area:
if (areaLightCount >= k_MaxAreaLightsOnScreen)
continue;
lightCategory = LightCategory.Area;
gpuLightType = (additionalData.lightWidth > 0) ? GPULightType.Rectangle : GPULightType.Line;
if (areaLightCount >= k_MaxAreaLightsOnScreen) { continue; }
lightCategory = LightCategory.Area;
gpuLightType = (additionalData.lightWidth > 0) ? GPULightType.Rectangle : GPULightType.Line;
if (projectorLightCount >= k_MaxProjectorLightsOnScreen)
continue;
if (projectorLightCount >= k_MaxProjectorLightsOnScreen) { continue; }
gpuLightType = GPULightType.ProjectorOrtho; // TODO: pyramid
lightVolumeType = LightVolumeType.Box;
switch (light.lightType)
{
case LightType.Directional:
gpuLightType = GPULightType.ProjectorOrtho;
lightVolumeType = LightVolumeType.Box;
break;
case LightType.Spot:
gpuLightType = GPULightType.ProjectorPyramid;
lightVolumeType = LightVolumeType.Cone;
break;
default:
Debug.Assert(false, "Projectors can only be Spot or Directional lights.");
break;
}
continue;
Debug.Assert(false, "TODO: encountered an unknown LightArchetype.");
break;
}
}

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


{
float3 positionWS = posInput.positionWS;
float3 unL = lightData.positionWS - positionWS;
float3 L = -lightData.forward; // Lights are pointing backward in Unity
// Translate and rotate 'positionWS' into the light space.
float3 positionLS = mul(positionWS - lightData.positionWS,
transpose(float3x3(lightData.right, lightData.up, lightData.forward)));
// Project 'unL' onto the light's axes.
float distX = dot(unL, lightData.right);
float distY = dot(unL, lightData.up);
if (lightData.lightType == GPULIGHTTYPE_PROJECTOR_PYRAMID)
{
// Perform perspective division.
positionLS *= rcp(positionLS.z);
}
else
{
// For orthographic projection, the Z coordinate plays no role.
positionLS.z = 0;
}
// Compute windowing factors using the dimensions of the light's "viewport".
float windowX = (abs(distX) <= 0.5 * lightData.size.x) ? 1 : 0;
float windowY = (abs(distY) <= 0.5 * lightData.size.y) ? 1 : 0;
// Compute the NDC position (in [-1, 1]^2). TODO: precompute the inverse?
float2 positionNDC = positionLS.xy * rcp(0.5 * lightData.size);
float illuminance = saturate(dot(bsdfData.normalWS, L) * (windowX * windowY));
// Perform clipping.
float clipFactor = ((positionLS.z >= 0) && (abs(positionNDC.x) <= 1 && abs(positionNDC.y) <= 1)) ? 1 : 0;
float3 L = -lightData.forward; // Lights are pointing backward in Unity
float illuminance = saturate(dot(bsdfData.normalWS, L) * clipFactor);
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);

[branch] if (lightData.cookieIndex >= 0 && illuminance > 0.0)
{
// Project 'unL' onto the light's axes.
float2 coord = float2(distX, distY);
coord = coord / lightData.size + float2(0.5, 0.5);
float2 coord = positionNDC * 0.5 + 0.5;
cookie = SampleCookie2D(lightLoopContext, coord, lightData.cookieIndex);

11
Assets/ScriptableRenderPipeline/HDRenderPipeline/Shadow/ShadowUtilities.cs


public static bool MapLightType(LightType lt, AdditionalLightData ald, out GPULightType gputype, out GPUShadowType shadowtype)
{
shadowtype = GPUShadowType.Unknown; // Default for all non-punctual lights
gputype = GPULightType.Spot;
case LightArchetype.Projector: gputype = GPULightType.ProjectorOrtho; return true; // TODO: pyramid
default: gputype = GPULightType.Spot; return false; // <- probably not what you want
case LightArchetype.Projector:
switch (lt)
{
case LightType.Directional: gputype = GPULightType.ProjectorOrtho; return true;
case LightType.Spot: gputype = GPULightType.ProjectorPyramid; return true;
default: Debug.Assert(false, "Projectors can only be Spot or Directional lights."); return false;
}
default: return false; // <- probably not what you want
}
}

28
Assets/TestScenes/HDTest/HDRenderLoopTest.unity


m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientSkyColor: {r: 0.2, g: 0.2, b: 0.2, a: 0}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1

m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 2800000, guid: 32c4b9c8ddc1c5d49ac7d10122540447, type: 3}
m_Cookie: {fileID: 2800000, guid: a5f5ba3665c610f469d392e02dadb3bd, type: 3}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0

m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 2800000, guid: 32c4b9c8ddc1c5d49ac7d10122540447, type: 3}
m_Cookie: {fileID: 2800000, guid: a5f5ba3665c610f469d392e02dadb3bd, type: 3}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0

affectSpecular: 1
archetype: 2
isDoubleSided: 0
lightLength: 3
lightLength: 2
lightWidth: 2
--- !u!108 &1879857774
Light:

m_Type: 1
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 5
m_Range: 6
m_SpotAngle: 30
m_Range: 53.4
m_SpotAngle: 64.6
m_CookieSize: 10
m_Shadows:
m_Type: 0

m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 2800000, guid: 32c4b9c8ddc1c5d49ac7d10122540447, type: 3}
m_Cookie: {fileID: 2800000, guid: a5f5ba3665c610f469d392e02dadb3bd, type: 3}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0

m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1879857772}
m_LocalRotation: {x: 0.000000059604645, y: 0, z: -0, w: 1}
m_LocalPosition: {x: -0.3023, y: -0.2512, z: -2.904}
m_LocalScale: {x: 0.05, y: 0.08333334, z: 1}
m_LocalRotation: {x: 0.00034031898, y: -0.0000031154561, z: 0.009154134, w: 0.9999581}
m_LocalPosition: {x: -0.3824, y: -0.0218, z: -2.733}
m_LocalScale: {x: 0, y: 0, z: 1.855337}
m_LocalEulerAnglesHint: {x: 90.00001, y: 0, z: 0}
m_LocalEulerAnglesHint: {x: 0.039, y: 0, z: 1.049}
--- !u!1 &1883914490
GameObject:
m_ObjectHideFlags: 0

m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_Cookie: {fileID: 2800000, guid: 32c4b9c8ddc1c5d49ac7d10122540447, type: 3}
m_Cookie: {fileID: 2800000, guid: a5f5ba3665c610f469d392e02dadb3bd, type: 3}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0

m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_Materials:
- {fileID: 2100000, guid: f03665895dc89b84487310c5216b8458, type: 2}
- {fileID: 2100000, guid: 85906790251341e47ab35a0e55892d43, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0

m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 2026378390}
m_LocalRotation: {x: 0.7071068, y: -0, z: -0, w: 0.7071068}
m_LocalPosition: {x: -125, y: -0, z: 36}
m_LocalPosition: {x: -122.356, y: 0, z: 35.449}
m_LocalScale: {x: 20, y: 12, z: 1}
m_Children:
- {fileID: 858501139}

正在加载...
取消
保存