Felipe Lira
7 年前
当前提交
8f6ad3bd
共有 5 个文件被更改,包括 213 次插入 和 309 次删除
-
16ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipelineCore.cs
-
165ScriptableRenderPipeline/LightweightPipeline/LWRP/Passes/DirectionalShadowsPass.cs
-
151ScriptableRenderPipeline/LightweightPipeline/LWRP/Passes/LocalShadowsPass.cs
-
179ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowUtils.cs
-
11ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightShadowUtils.cs.meta
|
|||
using System; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace UnityEngine.Experimental.Rendering.LightweightPipeline |
|||
{ |
|||
public struct ShadowSliceData |
|||
{ |
|||
public Matrix4x4 shadowTransform; |
|||
public int offsetX; |
|||
public int offsetY; |
|||
public int resolution; |
|||
|
|||
public void Clear() |
|||
{ |
|||
shadowTransform = Matrix4x4.identity; |
|||
offsetX = offsetY = 0; |
|||
resolution = 1024; |
|||
} |
|||
} |
|||
|
|||
public class LightweightShadowUtils |
|||
{ |
|||
public static bool ExtractDirectionalLightMatrix(ref CullResults cullResults, ref ShadowData shadowData, int shadowLightIndex, int cascadeIndex, int shadowResolution, float shadowNearPlane, out Vector4 cascadeSplitDistance, out ShadowSliceData shadowSliceData, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix) |
|||
{ |
|||
ShadowSplitData splitData; |
|||
bool success = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex, |
|||
cascadeIndex, shadowData.directionalLightCascadeCount, shadowData.directionalLightCascades, shadowResolution, shadowNearPlane, out viewMatrix, out projMatrix, |
|||
out splitData); |
|||
|
|||
float cullingSphereRadius = splitData.cullingSphere.w; |
|||
cascadeSplitDistance = splitData.cullingSphere; |
|||
cascadeSplitDistance.w = cullingSphereRadius * cullingSphereRadius; |
|||
|
|||
shadowSliceData.offsetX = (cascadeIndex % 2) * shadowResolution; |
|||
shadowSliceData.offsetY = (cascadeIndex / 2) * shadowResolution; |
|||
shadowSliceData.resolution = shadowResolution; |
|||
shadowSliceData.shadowTransform = GetShadowTransform(projMatrix, viewMatrix); |
|||
|
|||
// If we have shadow cascades baked into the atlas we bake cascade transform
|
|||
// in each shadow matrix to save shader ALU and L/S
|
|||
if (shadowData.directionalLightCascadeCount > 1) |
|||
ApplySliceTransform(ref shadowSliceData, shadowData.directionalShadowAtlasWidth, shadowData.directionalShadowAtlasHeight); |
|||
|
|||
return success; |
|||
} |
|||
|
|||
public static bool ExtractSpotLightMatrix(ref CullResults cullResults, ref ShadowData shadowData, int shadowLightIndex, out Matrix4x4 shadowMatrix, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix) |
|||
{ |
|||
ShadowSplitData splitData; |
|||
bool success = cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowLightIndex, out viewMatrix, out projMatrix, out splitData); |
|||
shadowMatrix = GetShadowTransform(projMatrix, viewMatrix); |
|||
return success; |
|||
} |
|||
|
|||
public static void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, |
|||
ref ShadowSliceData shadowSliceData, |
|||
Matrix4x4 proj, Matrix4x4 view, DrawShadowsSettings settings) |
|||
{ |
|||
cmd.SetViewport(new Rect(shadowSliceData.offsetX, shadowSliceData.offsetY, shadowSliceData.resolution, shadowSliceData.resolution)); |
|||
cmd.EnableScissorRect(new Rect(shadowSliceData.offsetX + 4, shadowSliceData.offsetY + 4, shadowSliceData.resolution - 8, shadowSliceData.resolution - 8)); |
|||
|
|||
cmd.SetViewProjectionMatrices(view, proj); |
|||
context.ExecuteCommandBuffer(cmd); |
|||
cmd.Clear(); |
|||
context.DrawShadows(ref settings); |
|||
cmd.DisableScissorRect(); |
|||
context.ExecuteCommandBuffer(cmd); |
|||
cmd.Clear(); |
|||
} |
|||
|
|||
public static int GetMaxTileResolutionInAtlas(int atlasWidth, int atlasHeight, int tileCount) |
|||
{ |
|||
int resolution = Mathf.Min(atlasWidth, atlasHeight); |
|||
if (tileCount > Mathf.Log(resolution)) |
|||
{ |
|||
Debug.LogError( |
|||
String.Format( |
|||
"Cannot fit {0} tiles into current shadowmap atlas of size ({1}, {2}). ShadowMap Resolution set to zero.", |
|||
tileCount, atlasWidth, atlasHeight)); |
|||
return 0; |
|||
} |
|||
|
|||
int currentTileCount = atlasWidth / resolution * atlasHeight / resolution; |
|||
while (currentTileCount < tileCount) |
|||
{ |
|||
resolution = resolution >> 1; |
|||
currentTileCount = atlasWidth / resolution * atlasHeight / resolution; |
|||
} |
|||
return resolution; |
|||
} |
|||
|
|||
public static void ApplySliceTransform(ref ShadowSliceData shadowSliceData, int atlasWidth, int atlasHeight) |
|||
{ |
|||
Matrix4x4 sliceTransform = Matrix4x4.identity; |
|||
float oneOverAtlasWidth = 1.0f / atlasWidth; |
|||
float oneOverAtlasHeight = 1.0f / atlasHeight; |
|||
sliceTransform.m00 = shadowSliceData.resolution * oneOverAtlasWidth; |
|||
sliceTransform.m11 = shadowSliceData.resolution * oneOverAtlasHeight; |
|||
sliceTransform.m03 = shadowSliceData.offsetX * oneOverAtlasWidth; |
|||
sliceTransform.m13 = shadowSliceData.offsetY * oneOverAtlasHeight; |
|||
|
|||
// Apply shadow slice scale and offset
|
|||
shadowSliceData.shadowTransform = sliceTransform * shadowSliceData.shadowTransform; |
|||
} |
|||
|
|||
public static void SetupShadowCasterConstants(CommandBuffer cmd, ref VisibleLight visibleLight, Matrix4x4 proj, float cascadeResolution) |
|||
{ |
|||
Light light = visibleLight.light; |
|||
float bias = 0.0f; |
|||
float normalBias = 0.0f; |
|||
|
|||
// Use same kernel radius as built-in pipeline so we can achieve same bias results
|
|||
// with the default light bias parameters.
|
|||
const float kernelRadius = 3.65f; |
|||
|
|||
if (visibleLight.lightType == LightType.Directional) |
|||
{ |
|||
// Scale bias by cascade's world space depth range.
|
|||
// Directional shadow lights have orthogonal projection.
|
|||
// proj.m22 = -2 / (far - near) since the projection's depth range is [-1.0, 1.0]
|
|||
// In order to be correct we should multiply bias by 0.5 but this introducing aliasing along cascades more visible.
|
|||
float sign = (SystemInfo.usesReversedZBuffer) ? 1.0f : -1.0f; |
|||
bias = light.shadowBias * proj.m22 * sign; |
|||
|
|||
// Currently only square POT cascades resolutions are used.
|
|||
// We scale normalBias
|
|||
double frustumWidth = 2.0 / (double)proj.m00; |
|||
double frustumHeight = 2.0 / (double)proj.m11; |
|||
float texelSizeX = (float)(frustumWidth / (double)cascadeResolution); |
|||
float texelSizeY = (float)(frustumHeight / (double)cascadeResolution); |
|||
float texelSize = Mathf.Max(texelSizeX, texelSizeY); |
|||
|
|||
// Since we are applying normal bias on caster side we want an inset normal offset
|
|||
// thus we use a negative normal bias.
|
|||
normalBias = -light.shadowNormalBias * texelSize * kernelRadius; |
|||
} |
|||
else if (visibleLight.lightType == LightType.Spot) |
|||
{ |
|||
float sign = (SystemInfo.usesReversedZBuffer) ? -1.0f : 1.0f; |
|||
bias = light.shadowBias * sign; |
|||
normalBias = 0.0f; |
|||
} |
|||
else |
|||
{ |
|||
Debug.LogWarning("Only spot and directional shadow casters are supported in lightweight pipeline"); |
|||
} |
|||
|
|||
Vector3 lightDirection = -visibleLight.localToWorld.GetColumn(2); |
|||
cmd.SetGlobalVector("_ShadowBias", new Vector4(bias, normalBias, 0.0f, 0.0f)); |
|||
cmd.SetGlobalVector("_LightDirection", new Vector4(lightDirection.x, lightDirection.y, lightDirection.z, 0.0f)); |
|||
} |
|||
|
|||
static Matrix4x4 GetShadowTransform(Matrix4x4 proj, Matrix4x4 view) |
|||
{ |
|||
// Currently CullResults ComputeDirectionalShadowMatricesAndCullingPrimitives doesn't
|
|||
// apply z reversal to projection matrix. We need to do it manually here.
|
|||
if (SystemInfo.usesReversedZBuffer) |
|||
{ |
|||
proj.m20 = -proj.m20; |
|||
proj.m21 = -proj.m21; |
|||
proj.m22 = -proj.m22; |
|||
proj.m23 = -proj.m23; |
|||
} |
|||
|
|||
Matrix4x4 worldToShadow = proj * view; |
|||
|
|||
var textureScaleAndBias = Matrix4x4.identity; |
|||
textureScaleAndBias.m00 = 0.5f; |
|||
textureScaleAndBias.m11 = 0.5f; |
|||
textureScaleAndBias.m22 = 0.5f; |
|||
textureScaleAndBias.m03 = 0.5f; |
|||
textureScaleAndBias.m23 = 0.5f; |
|||
textureScaleAndBias.m13 = 0.5f; |
|||
|
|||
// Apply texture scale and offset to save a MAD in shader.
|
|||
return textureScaleAndBias * worldToShadow; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6f6f9cae14ad81c44ba88bd7a667b0b6 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue