private void RenderDirectionalShadow(CullingResults cull, int sunlightIndex, Light sunlight) { ResetRenderTarget(SunlightShadowmapId, true, false, 1, Color.black); var shadowSettings = new ShadowDrawingSettings(cull, sunlightIndex); if (!cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(sunlightIndex, 0, 1, new Vector3(1, 0, 0), @params.sunlightParams.shadowResolution, sunlight.shadowNearPlane, out var viewMatrix, out var projectionMatrix, out var splitData)) { ExecuteCurrentBuffer(); return; } shadowSettings.splitData = splitData; _currentBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); if (_reversedZBuffer) { projectionMatrix.m20 = -projectionMatrix.m20; projectionMatrix.m21 = -projectionMatrix.m21; projectionMatrix.m22 = -projectionMatrix.m22; projectionMatrix.m23 = -projectionMatrix.m23; } var scaleOffset = Matrix4x4.identity; scaleOffset.m00 = scaleOffset.m11 = scaleOffset.m22 = scaleOffset.m03 = scaleOffset.m13 = scaleOffset.m23 = 0.5f; var sunlightInverseVP = scaleOffset * (projectionMatrix * viewMatrix); _currentBuffer.SetGlobalMatrix(ShaderManager.SUNLIGHT_INVERSE_VP, sunlightInverseVP); ExecuteCurrentBuffer(); _context.DrawShadows(ref shadowSettings); }
void RenderDirectionalShadows(int index, int split, int tileSize) { ShadowedDirectionalLight light = ShadowedDirectionalLights[index]; //create a shadowdrawsetting based on the light index var shadowDSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex) { useRenderingLayerMaskTest = true }; //make shadow effcted by rendering layer mask //take into count that each light will render max 4 cascades int cascadeCount = shadowSettings.directional.cascadeCount; int tileOffset = index * cascadeCount; Vector3 ratios = shadowSettings.directional.CascadeRatios; //cal the cascade culling factor, make it 0.8-fade to make sure casters in transition not being culled float cullingfactor = Mathf.Max(0f, 0.8f - shadowSettings.directional.cascadeFade); float tileScale = 1f / split; //get the lightviewMatrix, lightprojectionMatrix, clip space box for the dirctional lights for (int i = 0; i < cascadeCount; i++) { cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( light.visibleLightIndex, i, cascadeCount, ratios, tileSize, light.nearPlaneOffset, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData); //make UNITY to cull some shadow caster in large cascade if the smaller cascade is enough splitData.shadowCascadeBlendCullingFactor = cullingfactor; shadowDSettings.splitData = splitData; //assign the cascade culling sphere, all lights uses the same culling spheres and same cascade datas if (index == 0) { SetCascadeData(i, splitData.cullingSphere, tileSize); } int tileIdex = tileOffset + i; //set the render view port and get the offset for modify the dir shadow matrix //set the matrix from wolrd space to shadow Atlas space dirShadowMatrices[tileIdex] = ConvertToAtlasMatrix( projectionMatrix * viewMatrix, SetTileViewport(tileIdex, split, tileSize), tileScale ); //set the ViewProjectionMatrices for the buffer buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); //experimental depth bias //buffer.SetGlobalDepthBias(50000f, 0f); //using slop bias buffer.SetGlobalDepthBias(0f, light.slopScaleBias); ExecuteBuffer(); //draw shadow caster on the buffer context.DrawShadows(ref shadowDSettings); //Debug.Log(shadowDSettings buffer.SetGlobalDepthBias(0f, 0f); } }
void RenderDirectionalShadows(int index, int split, int tileSize) { ShadowDirectionalLight light = ShadowDirectionalLights[index]; var shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex) { useRenderingLayerMaskTest = true }; int cascadeCount = settings.directional.cascadeCount; int tileOffset = index * cascadeCount; Vector3 ratios = settings.directional.CascadeRatios; //裁剪参数 float cullingFactor = Mathf.Max(0f, 0.8f - settings.directional.cascadeFade); float tileScale = 1f / split; //遍历Cascade的数量 for (int i = 0; i < cascadeCount; i++) { //Debug.Log(light.nearPlaneOffset); //Unity cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( light.visibleLightIndex, i, cascadeCount, ratios, tileSize, light.nearPlaneOffset, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData); //??????????? splitData.shadowCascadeBlendCullingFactor = cullingFactor; shadowSettings.splitData = splitData; if (index == 0) { //裁剪球 判断片段在哪一级的Cascade里面 w为半径 Vector4 cullingSphere = splitData.cullingSphere; SetCascadeData(i, splitData.cullingSphere, tileSize); } int tileIndex = tileOffset + i; //设置ViewPort大小 //SetTileViewport(index, split, tileSize); //从世界空间到灯光阴影投影空间 dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, SetTileViewport(tileIndex, split, tileSize), tileScale); buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); //球覆盖 buffer.SetGlobalVectorArray(cascadeCullingSpheresId, cascadeCullingSpheres); //Cascade数据 buffer.SetGlobalVectorArray(cascadeDataId, cascadeData); //转换物体到灯光空间 buffer.SetGlobalMatrixArray(dirShadowMatricesId, dirShadowMatrices); buffer.SetGlobalDepthBias(0f, light.slopeScaleBias); ExecuteBuffer(); context.DrawShadows(ref shadowSettings); buffer.SetGlobalDepthBias(0f, 0f); } }
void RenderDirectionalShadows(int index, int split, int tileSize) { ShadowedDirectionalLight light = ShadowedDirectionalLights[index]; var shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex); int cascadeCount = settings.directional.cascadeCount; int tileOffset = index * cascadeCount; for (int i = 0; i < cascadeCount; i++) { cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( light.visibleLightIndex, i, cascadeCount, cascadeRatio, tileSize, 0f, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData ); shadowSettings.splitData = shadowSplitData; int tileIndex = tileOffset + i; dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix( projMatrix * viewMatrix, SetTileViewport(tileIndex, split, tileSize), split ); buffer.SetViewProjectionMatrices(viewMatrix, projMatrix); ExecuteBuffer(); context.DrawShadows(ref shadowSettings); } }
public void RenderShadows(ScriptableRenderContext renderContext, CommandBuffer cmd, DrawShadowsSettings dss) { cmd.SetRenderTarget(identifier); cmd.SetGlobalVector(HDShaderIDs._ShadowAtlasSize, new Vector4(m_Width, m_Height, 1.0f / m_Width, 1.0f / m_Height)); foreach (var shadowRequest in shadowRequests) { cmd.SetViewport(shadowRequest.atlasViewport); cmd.SetViewProjectionMatrices(shadowRequest.view, shadowRequest.projection); cmd.SetGlobalFloat(HDShaderIDs._ZClip, shadowRequest.zClip ? 1.0f : 0.0f); CoreUtils.DrawFullScreen(cmd, m_ClearMaterial, null, 0); dss.lightIndex = shadowRequest.lightIndex; dss.splitData = shadowRequest.splitData; // TODO: remove this execute when DrawShadows will use a CommandBuffer renderContext.ExecuteCommandBuffer(cmd); cmd.Clear(); renderContext.DrawShadows(ref dss); } cmd.SetGlobalFloat(HDShaderIDs._ZClip, 1.0f); // Re-enable zclip globally }
void RenderShadows(ScriptableRenderContext context) { shadowBuffer.GetTemporaryRT(shadowMapId, 512, 512, 16, FilterMode.Bilinear, RenderTextureFormat.Depth); shadowMap = RenderTexture.GetTemporary(512, 512, 16, RenderTextureFormat.Shadowmap); shadowMap.filterMode = FilterMode.Bilinear; shadowMap.wrapMode = TextureWrapMode.Clamp; CoreUtils.SetRenderTarget(shadowBuffer, shadowMap, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth); shadowBuffer.BeginSample("Render Shadows"); context.ExecuteCommandBuffer(shadowBuffer); shadowBuffer.Clear(); Matrix4x4 viewMatrix, projectMatrix; ShadowSplitData splitData; cullingResults.ComputeSpotShadowMatricesAndCullingPrimitives(0, out viewMatrix, out projectMatrix, out splitData); shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectMatrix); context.ExecuteCommandBuffer(shadowBuffer); // draw shadow var shadowSettings = new ShadowDrawingSettings(cullingResults, 0); context.DrawShadows(ref shadowSettings); shadowBuffer.EndSample("Render Shadows"); context.ExecuteCommandBuffer(shadowBuffer); shadowBuffer.Clear(); }
void RenderSpotShadow(ref ScriptableRenderContext context, ref CullingResults cullingResults, int shadowMapSize, int index, ref VisibleLight visibleLight) { if (shadowData.lights[index] == null) { return; } CoreUtils.SetRenderTarget(buffer, shadowData.shadowMaps, ClearFlag.Depth, 0, CubemapFace.Unknown, index); SubmitBuffer(ref context, buffer); if (shadowData.lights[index].cascades[0] == null) { return; } Rect tileViewport = new Rect(0, 0, shadowMapSize, shadowMapSize); buffer.SetViewport(new Rect(tileViewport)); buffer.SetViewProjectionMatrices(shadowData.lights[index].cascades[0].viewMatrix, shadowData.lights[index].cascades[0].projectionMatrix); ShaderInput.SetShadowBias(buffer, visibleLight.light.shadowBias); SubmitBuffer(ref context, buffer); ShadowDrawingSettings shadowSettings = new ShadowDrawingSettings(cullingResults, index); shadowSettings.splitData = shadowData.lights[index].cascades[0].splitData; context.DrawShadows(ref shadowSettings); }
void RenderDirectionalShadows(int index, int split, int tileSize) { ShadowedDirectionalLight light = shadowedDirectionalLights[index]; var shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex); var cascadeCount = settings.directional.cascadeCount; int tileOffset = index * cascadeCount; Vector3 ratios = settings.directional.CascadeRatios; float cullingFactor = Mathf.Max(0, 0.8f - settings.directional.cascadeFade); for (int i = 0; i < cascadeCount; i++) { cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(light.visibleLightIndex, i, cascadeCount, ratios, tileSize, light.nearPlaneOffset, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData); splitData.shadowCascadeBlendCullingFactor = cullingFactor; shadowSettings.splitData = splitData; if (index == 0) { SetCascadeData(i, splitData.cullingSphere, tileSize); } int tileOffIndex = tileOffset + i; dirShadowMatrices[tileOffIndex] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, SetTileViewport(tileOffIndex, split, tileSize), split); buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); buffer.SetGlobalDepthBias(0f, light.slopeScaleBias); ExecuteBuffer(); context.DrawShadows(ref shadowSettings); buffer.SetGlobalDepthBias(0f, 0f); } }
void RenderDirectionalShadow(ref ScriptableRenderContext context, ref CullingResults cullingResults, int shadowMapSize, int index, ref VisibleLight visibleLight) { if (shadowData.lights[index] == null) { return; } CoreUtils.SetRenderTarget(buffer, shadowData.shadowMaps, ClearFlag.Depth, 0, CubemapFace.Unknown, index); SubmitBuffer(ref context, buffer); for (int j = 0; j < 4; j++) { if (shadowData.lights[index].cascades[j] == null) { continue; } Rect tileViewport = new Rect(shadowData.lights[index].cascades[j].tileOffset.x * shadowData.lights[index].tileSize, shadowData.lights[index].cascades[j].tileOffset.y * shadowData.lights[index].tileSize, shadowData.lights[index].tileSize, shadowData.lights[index].tileSize); buffer.SetViewport(new Rect(tileViewport)); buffer.EnableScissorRect(new Rect(tileViewport.x + 4f, tileViewport.y + 4f, shadowData.lights[index].tileSize - 8f, shadowData.lights[index].tileSize - 8f)); buffer.SetViewProjectionMatrices(shadowData.lights[index].cascades[j].viewMatrix, shadowData.lights[index].cascades[j].projectionMatrix); ShaderInput.SetShadowBias(buffer, visibleLight.light.shadowBias); SubmitBuffer(ref context, buffer); ShadowDrawingSettings shadowSettings = new ShadowDrawingSettings(cullingResults, index); shadowSettings.splitData = shadowData.lights[index].cascades[j].splitData; context.DrawShadows(ref shadowSettings); } buffer.DisableScissorRect(); SubmitBuffer(ref context, buffer); }
private void RenderCascadedShadows(ScriptableRenderContext context) { float tileSize = shadowMapSize / 2; cascadedShadowMap = SetShadowRenderTarget(); shadowBuffer.BeginSample("Render Main Shadows"); context.ExecuteCommandBuffer(shadowBuffer); shadowBuffer.Clear(); Light shadowLight = cull.visibleLights[0].light; shadowBuffer.SetGlobalFloat( shadowBiasID, shadowLight.shadowBias); var shadowSettings = new DrawShadowsSettings(cull, 0); var tileMatrix = Matrix4x4.identity; tileMatrix.m00 = tileMatrix.m11 = 0.5f; for (int i = 0; i < shadowCascades; i++) { Matrix4x4 viewMatrix, projectionMatrix; ShadowSplitData splitData; cull.ComputeDirectionalShadowMatricesAndCullingPrimitives( 0, i, shadowCascades, shadowCascadeSplit, (int)tileSize , shadowLight.shadowNearPlane, out viewMatrix, out projectionMatrix, out splitData); Vector2 tileOffset = ConfigureShadowTile(i, 2, tileSize); shadowBuffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); context.ExecuteCommandBuffer(shadowBuffer); shadowBuffer.Clear(); cascadeCullingSpheres[i] = shadowSettings.splitData.cullingSphere = splitData.cullingSphere; //储存半径平方 用于比较 cascadeCullingSpheres[i].w *= splitData.cullingSphere.w; context.DrawShadows(ref shadowSettings); CalculateWorldToShadowMatrix(ref viewMatrix, ref projectionMatrix , out worldToShadowCascadeMatrices[i]); tileMatrix.m03 = tileOffset.x * 0.5f; tileMatrix.m13 = tileOffset.y * 0.5f; worldToShadowCascadeMatrices[i] = tileMatrix * worldToShadowCascadeMatrices[i]; } shadowBuffer.DisableScissorRect(); shadowBuffer.SetGlobalTexture(cascadedShadowMapID, cascadedShadowMap); shadowBuffer.SetGlobalVectorArray(cascadeCullingSpheresID, cascadeCullingSpheres); shadowBuffer.SetGlobalMatrixArray(worldToShadowCascadeMatricesID, worldToShadowCascadeMatrices); float invShadowMapSize = 1f / shadowMapSize; shadowBuffer.SetGlobalVector(cascadedShadowMapSizedID , new Vector4(invShadowMapSize, invShadowMapSize, shadowMapSize, shadowMapSize)); shadowBuffer.SetGlobalFloat(cascadedShadowStrengthID, shadowLight.shadowStrength); bool hard = shadowLight.shadows == LightShadows.Hard; CoreUtils.SetKeyword(shadowBuffer, cascadedShadowsHardKeyword, hard); CoreUtils.SetKeyword(shadowBuffer, cascadedShadowsSoftKeyword, !hard); shadowBuffer.EndSample("Render Main Shadows"); context.ExecuteCommandBuffer(shadowBuffer); shadowBuffer.Clear(); }
void RenderDirectionalShadows(int index, int split, int tileSize) { var light = ShadowedDirectionalLights[index]; var shadowSettings = new ShadowDrawingSettings(cullingResults, index); cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( light.VisibleLightIndex, 0, 1, Vector3.zero, tileSize, 0f, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData); shadowSettings.splitData = shadowSplitData; // SetTileViewport(index, split, tileSize); DirShadowMatrices[index] = ConvertToAtlasMatrix( projMatrix * viewMatrix, SetTileViewport(index, split, tileSize), split); buffer.SetGlobalMatrixArray(DirShadowMatricesID, DirShadowMatrices); buffer.SetViewProjectionMatrices(viewMatrix, projMatrix); ExecuteBuffer(); context.DrawShadows(ref shadowSettings); }
public void DrawShadow(ScriptableRenderContext context, CommandBuffer cmd) { if (!RenderShadow) { return; } context.DrawShadows(ref m_SadowSetting); }
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); }
private void shadow_pass(ref CullResults cull, ref ScriptableRenderContext context) { int shadowLightIndex = 0; int cascadeIdx = 0; int m_ShadowCasterCascadesCount = 1; Vector3 directionalLightCascades = new Vector3(1.0f, 0.0f, 0.0f); int shadowNearPlaneOffset = 0; Matrix4x4 view; Matrix4x4 proj; foreach (var light in cull.visibleLights) { if (light.lightType == LightType.Directional) { DrawShadowsSettings sss = new DrawShadowsSettings(cull, shadowLightIndex); var success = cull.ComputeDirectionalShadowMatricesAndCullingPrimitives(shadowLightIndex, cascadeIdx, m_ShadowCasterCascadesCount, directionalLightCascades, shadowResolution, shadowNearPlaneOffset, out view, out proj, out sss.splitData); //view 光源的视空间 //proj 光源的裁剪空间 if (success) { cmd.Clear(); cmd.name = "clear shadow map"; cmd.SetRenderTarget(_ScreenSpaceShadowMapId); cmd.ClearRenderTarget(true, true, Color.black); context.ExecuteCommandBuffer(cmd); cmd.Clear(); cmd.name = "create shadow map"; cmd.SetViewport(new Rect(0, 0, shadowResolution, shadowResolution)); cmd.SetViewProjectionMatrices(view, proj); context.ExecuteCommandBuffer(cmd); context.DrawShadows(ref sss); context.ExecuteCommandBuffer(cmd); } cmd.Clear(); if (SystemInfo.usesReversedZBuffer) { //Debug.Log("usesReversedZBuffer "); } cmd.SetGlobalMatrix(_mId, proj * view); context.ExecuteCommandBuffer(cmd); } shadowLightIndex++; } }
static void RenderShadows(RenderShadowsParameters parameters, RTHandle atlasRenderTexture, ShadowDrawingSettings shadowDrawSettings, ScriptableRenderContext renderContext, CommandBuffer cmd) { cmd.SetRenderTarget(atlasRenderTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store); cmd.SetGlobalVector(parameters.atlasSizeShaderID, new Vector4(atlasRenderTexture.rt.width, atlasRenderTexture.rt.height, 1.0f / atlasRenderTexture.rt.width, 1.0f / atlasRenderTexture.rt.height)); // Clear the whole atlas to avoid garbage outside of current request when viewing it. if (parameters.debugClearAtlas) { CoreUtils.DrawFullScreen(cmd, parameters.clearMaterial, null, 0); } var hdrp = RenderPipelineManager.currentPipeline as HDRenderPipeline; foreach (var shadowRequest in parameters.shadowRequests) { if (shadowRequest.shouldUseCachedShadow) { continue; } cmd.SetGlobalDepthBias(1.0f, shadowRequest.slopeBias); cmd.SetViewport(shadowRequest.atlasViewport); cmd.SetGlobalFloat(HDShaderIDs._ZClip, shadowRequest.zClip ? 1.0f : 0.0f); CoreUtils.DrawFullScreen(cmd, parameters.clearMaterial, null, 0); shadowDrawSettings.lightIndex = shadowRequest.lightIndex; shadowDrawSettings.splitData = shadowRequest.splitData; // Setup matrices for shadow rendering: Matrix4x4 viewProjection = shadowRequest.deviceProjectionYFlip * shadowRequest.view; cmd.SetGlobalMatrix(HDShaderIDs._ViewMatrix, shadowRequest.view); cmd.SetGlobalMatrix(HDShaderIDs._InvViewMatrix, shadowRequest.view.inverse); cmd.SetGlobalMatrix(HDShaderIDs._ProjMatrix, shadowRequest.deviceProjectionYFlip); cmd.SetGlobalMatrix(HDShaderIDs._InvProjMatrix, shadowRequest.deviceProjectionYFlip.inverse); cmd.SetGlobalMatrix(HDShaderIDs._ViewProjMatrix, viewProjection); cmd.SetGlobalMatrix(HDShaderIDs._InvViewProjMatrix, viewProjection.inverse); cmd.SetGlobalVectorArray(HDShaderIDs._ShadowClipPlanes, shadowRequest.frustumPlanes); // TODO: remove this execute when DrawShadows will use a CommandBuffer renderContext.ExecuteCommandBuffer(cmd); cmd.Clear(); renderContext.DrawShadows(ref shadowDrawSettings); hdrp?.InvokeShadowMapRender(cmd, shadowRequest.worldTexelSize); } cmd.SetGlobalFloat(HDShaderIDs._ZClip, 1.0f); // Re-enable zclip globally cmd.SetGlobalDepthBias(0.0f, 0.0f); // Reset depth bias. }
void RenderPointShadows(int index, int split, int tileSize) { ShadowedOtherLight light = shadowedOtherLights[index]; var shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex) { useRenderingLayerMaskTest = true }; float texelSize = 2f / tileSize; float filterSize = texelSize * ((float)settings.other.filter + 1f); float bias = light.normalBias * filterSize * 1.4142136f; float tileScale = 1f / 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); } }
private void RenderDirectionalShadows(int index, int split, int tileSize) { ShadowedDirectionalLight light = shadowedDirectionalLights[index]; ShadowDrawingSettings shadowSettings = new ShadowDrawingSettings(cullingResults, light.visibleLightIndex) { useRenderingLayerMaskTest = true }; int cascadeCount = this.shadowSettings.directional.cascadeCount; int tileOffset = index * cascadeCount; Vector3 ratios = this.shadowSettings.directional.CascadeRatios; float cullingFactor = Mathf.Max(0f, 0.8f - this.shadowSettings.directional.cascadeFade); float tileScale = 1f / split; for (int i = 0; i < cascadeCount; ++i) { cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( light.visibleLightIndex, i, cascadeCount, ratios, tileSize, light.nearPlaneOffset, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData); splitData.shadowCascadeBlendCullingFactor = cullingFactor; shadowSettings.splitData = splitData; int tileIndex = tileOffset + i; if (index == 0) { //Vector4 cullingSphere = splitData.cullingSphere; //cullingSphere.w *= cullingSphere.w; //cascadeCullingSpheres[i] = cullingSphere; SetCascadeData(i, splitData.cullingSphere, tileSize); } //SetTileViewport(index, split, tileSize); //dirShadowMatrices[index] = projectionMatrix * viewMatrix; dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, SetTileViewport(tileIndex, split, tileSize), tileScale); buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); buffer.SetGlobalDepthBias(0f, light.slopeScaleBias); ExecuteBuffer(); context.DrawShadows(ref shadowSettings); buffer.SetGlobalDepthBias(0f, 0f); } }
private void RenderDirectionalShadows(int index, int tileSize) { ShadowDirectionalLight light = _shadowDirectionalLights[index]; var shadowDrawSettings = new ShadowDrawingSettings(_cullingResults, light.visibleLightIndex); _cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(light.visibleLightIndex, 0, 1, Vector3.zero, tileSize, 0f, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData); shadowDrawSettings.splitData = splitData; _buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); ExecuteBuffer(); _context.DrawShadows(ref shadowDrawSettings); }
public static void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, ref ShadowSliceData shadowSliceData, ref ShadowDrawingSettings settings, Matrix4x4 proj, Matrix4x4 view) { cmd.SetViewport(new Rect(shadowSliceData.offsetX, shadowSliceData.offsetY, shadowSliceData.resolution, shadowSliceData.resolution)); cmd.SetViewProjectionMatrices(view, proj); context.ExecuteCommandBuffer(cmd); cmd.Clear(); context.DrawShadows(ref settings); cmd.DisableScissorRect(); context.ExecuteCommandBuffer(cmd); cmd.Clear(); }
private void RenderShadowSlice(ref ScriptableRenderContext context, int cascadeIndex, Matrix4x4 proj, Matrix4x4 view, DrawShadowsSettings settings) { var buffer = CommandBufferPool.Get("Prepare Shadowmap Slice"); buffer.SetViewport(new Rect(m_ShadowSlices[cascadeIndex].atlasX, m_ShadowSlices[cascadeIndex].atlasY, m_ShadowSlices[cascadeIndex].shadowResolution, m_ShadowSlices[cascadeIndex].shadowResolution)); buffer.SetViewProjectionMatrices(view, proj); context.ExecuteCommandBuffer(buffer); context.DrawShadows(ref settings); CommandBufferPool.Release(buffer); }
void RenderShadow(ScriptableRenderContext context) { shadowMap = RenderTexture.GetTemporary(this.shadowMapSize, this.shadowMapSize, 16, RenderTextureFormat.Shadowmap); shadowMap.filterMode = FilterMode.Bilinear; shadowMap.wrapMode = TextureWrapMode.Clamp; CoreUtils.SetRenderTarget(shadowBuffer, shadowMap, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, ClearFlag.Depth); shadowBuffer.BeginSample("Render Shadow"); // Set View matrix and projection matrix Matrix4x4 viewMatrix, projMatrix; ShadowSplitData shadowSplitData; this.cull.ComputeSpotShadowMatricesAndCullingPrimitives(0, out viewMatrix, out projMatrix, out shadowSplitData); shadowBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix); shadowBuffer.SetGlobalFloat(shadowBiasID, cull.visibleLights[0].light.shadowBias); context.ExecuteCommandBuffer(shadowBuffer); shadowBuffer.Clear(); // Draw Shadow Casters var shadowSetting = new DrawShadowsSettings(cull, 0); context.DrawShadows(ref shadowSetting); // Set Shadow map and shadow space matrix if (SystemInfo.usesReversedZBuffer) { projMatrix.m20 = -projMatrix.m20; projMatrix.m21 = -projMatrix.m21; projMatrix.m22 = -projMatrix.m22; projMatrix.m23 = -projMatrix.m23; } Matrix4x4 scaleOffset = Matrix4x4.identity; scaleOffset.m00 = scaleOffset.m11 = scaleOffset.m22 = 0.5f; scaleOffset.m03 = scaleOffset.m13 = scaleOffset.m23 = 0.5f; Matrix4x4 worldToShadowMatrix = scaleOffset * projMatrix * viewMatrix; shadowBuffer.SetGlobalMatrix(worldToShadowMatrixID, worldToShadowMatrix); shadowBuffer.SetGlobalTexture(shadowMapID, shadowMap); shadowBuffer.SetGlobalFloat(shadowStrengthID, cull.visibleLights[0].light.shadowStrength); shadowBuffer.EndSample("Render Shadow"); context.ExecuteCommandBuffer(shadowBuffer); shadowBuffer.Clear(); }
private void RenderShadowSlice(ref ScriptableRenderContext context, Vector3 lightDir, int cascadeIndex, Matrix4x4 proj, Matrix4x4 view, DrawShadowsSettings settings) { var buffer = new CommandBuffer() { name = "Prepare Shadowmap Slice" }; buffer.SetViewport(new Rect(m_ShadowSlices[cascadeIndex].atlasX, m_ShadowSlices[cascadeIndex].atlasY, m_ShadowSlices[cascadeIndex].shadowResolution, m_ShadowSlices[cascadeIndex].shadowResolution)); buffer.SetViewProjectionMatrices(view, proj); context.ExecuteCommandBuffer(buffer); buffer.Dispose(); context.DrawShadows(ref settings); }
private void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, int cascadeIndex, Matrix4x4 proj, Matrix4x4 view, DrawShadowsSettings settings) { cmd.SetViewport(new Rect(m_ShadowSlices[cascadeIndex].atlasX, m_ShadowSlices[cascadeIndex].atlasY, m_ShadowSlices[cascadeIndex].shadowResolution, m_ShadowSlices[cascadeIndex].shadowResolution)); cmd.EnableScissorRect(new Rect(m_ShadowSlices[cascadeIndex].atlasX + 4, m_ShadowSlices[cascadeIndex].atlasY + 4, m_ShadowSlices[cascadeIndex].shadowResolution - 8, m_ShadowSlices[cascadeIndex].shadowResolution - 8)); cmd.SetViewProjectionMatrices(view, proj); context.ExecuteCommandBuffer(cmd); cmd.Clear(); context.DrawShadows(ref settings); cmd.DisableScissorRect(); context.ExecuteCommandBuffer(cmd); cmd.Clear(); }
public static void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, ref ShadowSliceData shadowSliceData, ref ShadowDrawingSettings settings, Matrix4x4 proj, Matrix4x4 view, Vector4 shadowBias, VisibleLight shadowLight, int cascadeIndex) { 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); CustomRenderShadowSlice?.Invoke(cmd, GL.GetGPUProjectionMatrix(proj, true) * view, shadowBias, shadowLight, cascadeIndex); cmd.DisableScissorRect(); context.ExecuteCommandBuffer(cmd); cmd.Clear(); }
public void RenderDirectionalShadows(int index, int splitCount, int size) { ShadowedDirectionalLight light = ShadowedDirectionalLights[index]; var shadowSetting = new ShadowDrawingSettings(_results, light.visibleLightIndex); //https://docs.unity3d.com/2019.1/Documentation/ScriptReference/Rendering.CullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives.html //利用光源的方向(-transform.forward)方向可以求出view matrix,nearclip 和 最远的阴影距离等可以求出project matrix等等 _results.ComputeDirectionalShadowMatricesAndCullingPrimitives(light.visibleLightIndex, 0, 1, Vector3.zero, size, 0, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData); shadowSetting.splitData = shadowSplitData; SetTileViewport(index, splitCount, size); _commandBuffer.SetViewProjectionMatrices(viewMatrix, projMatrix); ExecuteCommandBuffer(); _context.DrawShadows(ref shadowSetting); }
public void RenderShadows(ScriptableRenderContext renderContext, CommandBuffer cmd, ShadowDrawingSettings dss) { if (m_ShadowRequests.Count == 0) { return; } cmd.SetRenderTarget(identifier); cmd.SetGlobalVector(m_AtlasSizeShaderID, new Vector4(width, height, 1.0f / width, 1.0f / height)); if (m_LightingDebugSettings.clearShadowAtlas) { CoreUtils.DrawFullScreen(cmd, m_ClearMaterial, null, 0); } foreach (var shadowRequest in m_ShadowRequests) { cmd.SetViewport(shadowRequest.atlasViewport); cmd.SetGlobalFloat(HDShaderIDs._ZClip, shadowRequest.zClip ? 1.0f : 0.0f); if (!m_LightingDebugSettings.clearShadowAtlas) { CoreUtils.DrawFullScreen(cmd, m_ClearMaterial, null, 0); } dss.lightIndex = shadowRequest.lightIndex; dss.splitData = shadowRequest.splitData; // Setup matrices for shadow rendering: Matrix4x4 viewProjection = shadowRequest.deviceProjectionYFlip * shadowRequest.view; cmd.SetGlobalMatrix(HDShaderIDs._ViewMatrix, shadowRequest.view); cmd.SetGlobalMatrix(HDShaderIDs._InvViewMatrix, shadowRequest.view.inverse); cmd.SetGlobalMatrix(HDShaderIDs._ProjMatrix, shadowRequest.deviceProjectionYFlip); cmd.SetGlobalMatrix(HDShaderIDs._InvProjMatrix, shadowRequest.deviceProjectionYFlip.inverse); cmd.SetGlobalMatrix(HDShaderIDs._ViewProjMatrix, viewProjection); cmd.SetGlobalMatrix(HDShaderIDs._InvViewProjMatrix, viewProjection.inverse); cmd.SetGlobalVectorArray(HDShaderIDs._ShadowClipPlanes, shadowRequest.frustumPlanes); // TODO: remove this execute when DrawShadows will use a CommandBuffer renderContext.ExecuteCommandBuffer(cmd); cmd.Clear(); renderContext.DrawShadows(ref dss); } cmd.SetGlobalFloat(HDShaderIDs._ZClip, 1.0f); // Re-enable zclip globally }
private bool RenderShadowMaps(ref ScriptableRenderContext context, ref CullingResults cullingResults, ref Matrix4x4 worldToShadowMatrix) { if (cullingResults.visibleLights.Length == 0) { return(false); } int lightIndex = 0; // Just use first light (index 0) for shadows and assume it's a directional light bool needToRender = cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex, 0, 1, Vector3.forward, 1024, cullingResults.visibleLights[0].light.shadowNearPlane, out Matrix4x4 viewMatrix, out Matrix4x4 projMatrix, out ShadowSplitData shadowSplitData); if (!needToRender) { return(false); } CommandBuffer cb = new CommandBuffer(); cb.name = "Set up shadow data"; cb.SetRenderTarget(m_ShadowMap); cb.ClearRenderTarget(true, true, Color.clear); cb.SetViewProjectionMatrices(viewMatrix, projMatrix); context.ExecuteCommandBuffer(cb); ShadowDrawingSettings shadowDrawSettings = new ShadowDrawingSettings(cullingResults, lightIndex); shadowDrawSettings.splitData = shadowSplitData; context.DrawShadows(ref shadowDrawSettings); if (SystemInfo.usesReversedZBuffer) { projMatrix.m20 = -projMatrix.m20; projMatrix.m21 = -projMatrix.m21; projMatrix.m22 = -projMatrix.m22; projMatrix.m23 = -projMatrix.m23; } var scaleOffset = Matrix4x4.TRS( Vector3.one * 0.5f, Quaternion.identity, Vector3.one * 0.5f ); worldToShadowMatrix = scaleOffset * (projMatrix * viewMatrix); return(true); }
public static void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context, ref ShadowSliceData shadowSliceData, ref ShadowDrawingSettings settings, Matrix4x4 proj, Matrix4x4 view) { cmd.SetGlobalDepthBias(1.0f, 2.5f); // these values match HDRP defaults (see https://github.com/Unity-Technologies/Graphics/blob/9544b8ed2f98c62803d285096c91b44e9d8cbc47/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAtlas.cs#L197 ) cmd.SetViewport(new Rect(shadowSliceData.offsetX, shadowSliceData.offsetY, shadowSliceData.resolution, shadowSliceData.resolution)); cmd.SetViewProjectionMatrices(view, proj); context.ExecuteCommandBuffer(cmd); cmd.Clear(); context.DrawShadows(ref settings); cmd.DisableScissorRect(); context.ExecuteCommandBuffer(cmd); cmd.Clear(); cmd.SetGlobalDepthBias(0.0f, 0.0f); // Restore previous depth bias values }
void RenderDirectionalShadows(int index, int split, int tileSize) { ShadowedDirectionalLight light = ShadowedDirectionalLights[index]; var shadowSettings = new ShadowDrawingSettings(_cullingResults, light.visibleLightIndex); int cascadeCount = _settings.directional.cascadeCount; int tileOffset = index * cascadeCount; Vector3 ratios = _settings.directional.CascadeRatios; float cullingFactor = Mathf.Max(0f, 0.8f - _settings.directional.cascadeFade); for (int i = 0; i < cascadeCount; i++) { // 阴影贴图的原理是,从灯光的角度渲染场景,只存储深度信息,用结果标记出来,光线在击中某物体之前会传播多远 // 但是定向光没有真实位置,我们要做的是找出与灯光方向匹配的视图/投影矩阵,并为我们提供一个裁剪空间立方体 // 该立方体与包含可见光阴影的摄像机可见区域重合 _cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( light.visibleLightIndex, i, cascadeCount, ratios, tileSize, light.nearPlaneOffset, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData); // 避免对每个光源渲染相同的阴影投射器不止一次,如果可以保证从较小的级联中覆盖某些阴影投射器,就可以尝试从较大的级联中剔除掉 // 某些阴影投射器 splitData.shadowCascadeBlendCullingFactor = cullingFactor; shadowSettings.splitData = splitData; if (index == 0) { SetCascadeData(i, splitData.cullingSphere, tileSize); // Vector4 cullingSphere = splitData.cullingSphere; } int tileIndex = tileOffset + i; // SetTileViewport(index, split, tileSize); // dirShadowMatrices[index] = projectionMatrix * viewMatrix; dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix(projectionMatrix * viewMatrix, SetTileViewport(tileIndex, split, tileSize), split); buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); // buffer.SetGlobalDepthBias(500000f, 0f); // buffer.SetGlobalDepthBias(0f, 3f); buffer.SetGlobalDepthBias(0f, light.slopeScaleBias); ExecuteBuffer(); _context.DrawShadows(ref shadowSettings); buffer.SetGlobalDepthBias(0f, 0f); } }
void RenderDirectionalShadows(int index, int split, int tileSize) { ShadowedDirectionalLight light = _shadowedDirectionalLights[index]; var shadowSettings = new ShadowDrawingSettings(_cullingResults, light.visibleLightIndex); int splitCount = _settings.directional.cascadeCount; Vector3 splitRatios = _settings.directional.CascadeRatios; float cullingFactor = Mathf.Max(0f, 0.8f - _settings.directional.cascadeFade); for (int i = 0; i < splitCount; i++) { _cullingResults.ComputeDirectionalShadowMatricesAndCullingPrimitives( light.visibleLightIndex, splitIndex: i, splitCount, splitRatios, shadowResolution: tileSize, light.nearPlaneOffset, out Matrix4x4 viewMatrix, out Matrix4x4 projectionMatrix, out ShadowSplitData splitData ); splitData.shadowCascadeBlendCullingFactor = cullingFactor; _settings.SplitData = splitData; if (index == 0) { SetCascadeData(i, splitData.cullingSphere, tileSize); } int tileIndex = index * splitCount + i; var tileOffset = GetTileViewportOffset(tileIndex, split); SetTileViewport(tileOffset, tileSize); _dirShadowMatrices[tileIndex] = ConvertToAtlasMatrix(worldToLight: projectionMatrix * viewMatrix, tileOffset, split); _buffer.SetViewProjectionMatrices(viewMatrix, projectionMatrix); _buffer.SetGlobalDepthBias(0f, light.slopeScaleBias); ExecuteBuffer(); _context.DrawShadows(ref shadowSettings); _buffer.SetGlobalDepthBias(0f, 0f); } }