/// <summary> /// 渲染点光源阴影 /// </summary> /// <param name="index"></param> /// <param name="split"></param> /// <param name="tileSize"></param> void RenderPointShadows(int index, int split, int tileSize) { ShadowOtherLight light = shadowedOtherLights[index]; var shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex); //Normal Bias float texelSize = 2f / tileSize; float filterSize = texelSize * ((float)settings.other.filter + 1f); float bias = light.normalBias * filterSize * 1.4142136f; float tileScale = 1 / split; //解决阴影不连续问题 float fovBias = Mathf.Atan(1f + bias + filterSize) * Mathf.Rad2Deg * 2f - 90f; for (int i = 0; i < 6; i++) { cullingResults.ComputePointShadowMatricesAndCullingPrimitives(light.visibleLightIndex, (CubemapFace)i, fovBias, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData); //解决阴影跑到其他物体上 viewMatrix.m11 = -viewMatrix.m11; viewMatrix.m12 = -viewMatrix.m12; viewMatrix.m13 = -viewMatrix.m13; shadowSettings.splitData = splitData; int tileIndex = index + i; Vector2 offset = SetTileViewport(tileIndex, split, tileSize); SetOtherTileData(tileIndex, offset, tileScale, bias); otherShadowMatrices[tileIndex] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, offset, tileScale); buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); buffer.SetGlobalDepthBias(0f, light.slopeScaleBias); ExecuteBuffer(); context.DrawShadows(ref shadowSettings); buffer.SetGlobalDepthBias(0f, 0f); } }
/// <summary> /// 渲染聚光灯阴影 /// </summary> /// <param name="index"></param> /// <param name="split"></param> /// <param name="tileSize"></param> void RenderSpotShadows(int index, int split, int tileSize) { ShadowOtherLight light = shadowedOtherLights[index]; var shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex); cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(light.visibleLightIndex, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData); shadowSettings.splitData = splitData; //Normal Bias float texelSize = 2f / (tileSize * projectionMatrix.m00); float filterSize = texelSize * ((float)settings.other.filter + 1f); float bias = light.normalBias * filterSize * 1.4142136f; Vector2 offset = SetTileViewport(index, split, tileSize); float tileScale = 1 / split; SetOtherTileData(index, offset, tileScale, bias); otherShadowMatrices[index] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, offset, tileScale); buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); buffer.SetGlobalDepthBias(0f, light.slopeScaleBias); ExecuteBuffer(); context.DrawShadows(ref shadowSettings); buffer.SetGlobalDepthBias(0f, 0f); }
/// <summary> /// 用于其他灯光阴影 /// </summary> /// <param name="light"></param> /// <param name="visibleLightIndex"></param> /// <returns></returns> public Vector4 ReserveOtherShadows(Light light, int visibleLightIndex) { //判断无阴影 或者强度是0 立即返回 if (light.shadows == LightShadows.None || light.shadowStrength <= 0f) { return(new Vector4(0f, 0f, 0f, -1f)); } float maskChannel = -1f; LightBakingOutput lightBaking = light.bakingOutput; if (lightBaking.lightmapBakeType == LightmapBakeType.Mixed && lightBaking.mixedLightingMode == MixedLightingMode.Shadowmask) { useShadowMask = true; maskChannel = lightBaking.occlusionMaskChannel; } //是否是点光源 疑问:为什么点光源 需要6个Tile bool isPoint = light.type == LightType.Point; int newLightCount = shadowedOtherLightCount + (isPoint ? 6 : 1); if (newLightCount >= maxShadowedOtherLightCount || !cullingResults.GetShadowCasterBounds(visibleLightIndex, out Bounds b)) { return(new Vector4(-light.shadowStrength, 0f, 0f, maskChannel)); } shadowedOtherLights[shadowedOtherLightCount] = new ShadowOtherLight { visibleLightIndex = visibleLightIndex, slopeScaleBias = light.shadowBias, normalBias = light.shadowNormalBias, isPoint = isPoint }; Vector4 data = new Vector4(light.shadowStrength, shadowedOtherLightCount++, isPoint ? 1f: 0f, lightBaking.occlusionMaskChannel); shadowedOtherLightCount = newLightCount; //返回Mix灯光 ShadowMask return(data); }