void RenderOneSpotShadows(int shadowedLightIdx, int atlasSplitFactor, int atlasTileSize) { ShadowedLight shadowedLight = _shadowedSpotLights[shadowedLightIdx]; _cullResults.ComputeSpotShadowMatricesAndCullingPrimitives(shadowedLight.visibleIndex, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData); _cmdBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix); Rect tileViewPort = Rect.zero; int tileIdx = shadowedLightIdx; tileViewPort.x = tileIdx % atlasSplitFactor * atlasTileSize; tileViewPort.y = tileIdx / atlasSplitFactor * atlasTileSize; tileViewPort.width = tileViewPort.height = atlasTileSize; _cmdBuffer.SetViewport(tileViewPort); _cmdBuffer.SetGlobalDepthBias(0, shadowedLight.light.shadowBias); ExecuteCommandBuffer(); int atlasSize = atlasSplitFactor * atlasTileSize; Vector4 normalizeViewPort = Vector4.zero; float texelSize = 1f / atlasSize; normalizeViewPort.x = tileViewPort.x / atlasSize + texelSize; normalizeViewPort.y = tileViewPort.y / atlasSize + texelSize; normalizeViewPort.z = tileViewPort.width / atlasSize - texelSize; normalizeViewPort.w = tileViewPort.height / atlasSize - texelSize; _spotShadowMatrixs[tileIdx] = ShadowMatrixToAtlasTileMatrix(projMatrix * viewMatrix, tileViewPort, atlasSize); _spotShadowTileViewPorts[tileIdx] = normalizeViewPort; ShadowDrawingSettings shadowDrawSetting = new ShadowDrawingSettings(_cullResults, shadowedLight.visibleIndex); shadowDrawSetting.splitData = shadowSplitData; _srContext.DrawShadows(ref shadowDrawSetting); _cmdBuffer.SetGlobalDepthBias(0, 0); }
void RenderOneDirectionalShadow(int lightIdx, int tileSplitFactor) { ShadowedLight shadowedLight = _shadowedDirLights[lightIdx]; int cascadeSplitFactor = _shadowSetting.directional.cascadeCount > 1 ? 2 : 1; int tileSize = (int)_shadowSetting.directional.atlasSize / tileSplitFactor; int cascadeSize = (int)_shadowSetting.directional.atlasSize / (tileSplitFactor * cascadeSplitFactor); int visibleIndex = shadowedLight.visibleIndex; _shadowMapSizes.x = cascadeSize; _cmdBuffer.SetGlobalDepthBias(0, shadowedLight.light.shadowBias); for (int cascadeIdx = 0; cascadeIdx < _shadowSetting.directional.cascadeCount; cascadeIdx++) { _cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(visibleIndex, cascadeIdx, _shadowSetting.directional.cascadeCount, _shadowSetting.directional.cascadeSplitRatio, cascadeSize, shadowedLight.light.shadowNearPlane, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData); _cmdBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix); Vector2 tileOffset = new Vector2(lightIdx % 2, lightIdx / 2); Vector2 cascadeOffset = new Vector2(cascadeIdx % 2, cascadeIdx / 2); Rect viewPortOffset = new Rect(tileOffset.x * tileSize + cascadeOffset.x * cascadeSize, tileOffset.y * tileSize + cascadeOffset.y * cascadeSize, cascadeSize, cascadeSize); _cmdBuffer.SetViewport(viewPortOffset); ExecuteCommandBuffer(); _dirShadowMatrixs[lightIdx * MAX_NUM_DIRECTIONAL_CASCADES + cascadeIdx] = ShadowMatrixToAtlasTileMatrix(projMatrix * viewMatrix, viewPortOffset, (int)_shadowSetting.directional.atlasSize); if (lightIdx == 0) // all directional light share the same cascade culling spheres { _dirCascadeCullingSpheres[cascadeIdx] = shadowSplitData.cullingSphere; } ShadowDrawingSettings shadowDrawSetting = new ShadowDrawingSettings(_cullResults, visibleIndex) { splitData = shadowSplitData }; _srContext.DrawShadows(ref shadowDrawSetting); } _cmdBuffer.SetGlobalDepthBias(0, 0); }
public Vector4 GetDirectionalShadowData(int visibleLightIndex) { Vector4 shadowData = new Vector4(-1, 0, 0, -1); Light dirLight = _cullResults.visibleLights[visibleLightIndex].light; if (dirLight.type != LightType.Directional) { return(shadowData); } if (dirLight.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed && dirLight.bakingOutput.mixedLightingMode == MixedLightingMode.Shadowmask) { shadowData.y = dirLight.shadowStrength; // when mixed light who' s shadow has baked to shadow mask did't cast shadow at run time, we want to use shadow in shadow mask shadowData.w = dirLight.bakingOutput.occlusionMaskChannel; _mixedLightUseShadowMask = true; } if (_shadowedDirLightCount >= MAX_NUM_DIRECTIONAL_SHADOWS || dirLight.shadows == LightShadows.None || dirLight.shadowStrength <= 0 || !_cullResults.GetShadowCasterBounds(visibleLightIndex, out Bounds bounds)) { return(shadowData); } _shadowedDirLights[_shadowedDirLightCount] = new ShadowedLight() { visibleIndex = visibleLightIndex, light = dirLight }; shadowData.x = _shadowedDirLightCount * MAX_NUM_DIRECTIONAL_CASCADES; shadowData.y = dirLight.shadowStrength; shadowData.z = dirLight.shadowNormalBias * 2f - 1f; _shadowedDirLightCount++; return(shadowData); }
void RenderOnePointShadows(int shadowedLightIdx, int atlasSplitFactor, int atlasTileSize) { ShadowedLight shadowedLight = _shadowedPointLights[shadowedLightIdx];; ShadowDrawingSettings shadowDrawSetting = new ShadowDrawingSettings(_cullResults, shadowedLight.visibleIndex); for (int faceIdx = 0; faceIdx < 6; faceIdx++) { _cullResults.ComputePointShadowMatricesAndCullingPrimitives(shadowedLight.visibleIndex, (CubemapFace)faceIdx, 0, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData); viewMatrix.m11 *= -1; // unity render point light shadow upside down viewMatrix.m12 *= -1; viewMatrix.m13 *= -1; _cmdBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix); Rect tileViewPort = Rect.zero; int tileIdx = shadowedLightIdx * 6 + faceIdx; tileViewPort.x = tileIdx % atlasSplitFactor * atlasTileSize; tileViewPort.y = tileIdx / atlasSplitFactor * atlasTileSize; tileViewPort.width = tileViewPort.height = atlasTileSize; _cmdBuffer.SetViewport(tileViewPort); _cmdBuffer.SetGlobalDepthBias(0, shadowedLight.light.shadowBias); ExecuteCommandBuffer(); int atlasSize = atlasSplitFactor * atlasTileSize; Vector4 normalizeViewPort = Vector4.zero; float texelSize = 1f / atlasSize; _pointShadowMatrixs[tileIdx] = ShadowMatrixToAtlasTileMatrix(projMatrix * viewMatrix, tileViewPort, atlasSize); shadowDrawSetting.splitData = shadowSplitData; _srContext.DrawShadows(ref shadowDrawSetting); _cmdBuffer.SetGlobalDepthBias(0, 0); } }
public Vector4 GetSpotLightShadowData(int visibleLightIndex) { Vector4 shadowData = new Vector4(-1, 0, 0, -1); Light spotLight = _cullResults.visibleLights[visibleLightIndex].light; if (spotLight.type != LightType.Spot) { return(shadowData); } if (spotLight.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed && spotLight.bakingOutput.mixedLightingMode == MixedLightingMode.Shadowmask) { shadowData.y = spotLight.shadowStrength; shadowData.w = spotLight.bakingOutput.occlusionMaskChannel; _mixedLightUseShadowMask = true; } if (_shadowedSpotLightCount >= MAX_NUM_SPOT_SHADOWS || spotLight.shadows == LightShadows.None || spotLight.shadowStrength <= 0 || !_cullResults.GetShadowCasterBounds(visibleLightIndex, out Bounds bounds)) { return(shadowData); } _shadowedSpotLights[_shadowedSpotLightCount] = new ShadowedLight() { visibleIndex = visibleLightIndex, light = spotLight }; shadowData.x = _shadowedSpotLightCount; shadowData.y = spotLight.shadowStrength; shadowData.z = spotLight.shadowNormalBias * 2f - 1f; _shadowedSpotLightCount++; return(shadowData); }