public MyShadowmapQuery GetShadowmapQueryForSingleShadow(int index, IDsvBindable dsvBindable) { MyProjectionInfo projInfo = new MyProjectionInfo(); projInfo.WorldCameraOffsetPosition = MyRender11.Environment.Matrices.CameraPosition; projInfo.WorldToProjection = MatrixWorldAt0ToShadowSpace; projInfo.LocalToProjection = Matrix.CreateTranslation(MyRender11.Environment.Matrices.CameraPosition) * MatrixWorldAt0ToShadowSpace; MyShadowmapQuery query = new MyShadowmapQuery(); query.DepthBuffer = dsvBindable; query.Viewport = new MyViewport(dsvBindable.Size.X, dsvBindable.Size.Y); query.ProjectionInfo = projInfo; query.ProjectionFactor = (float)Math.Sqrt(dsvBindable.Size.X * dsvBindable.Size.Y / (m_matrixShadowToWorldAt0Space.Left.Length() * m_matrixShadowToWorldAt0Space.Up.Length())); query.QueryType = MyFrustumEnum.ShadowProjection; query.Index = index; return query; }
private unsafe void MarkCascadesInStencil(MyProjectionInfo[] cascadeInfo) { MyGpuProfiler.IC_BeginBlock("MarkCascadesInStencil"); //RC.SetRS(MyRasterizerState.CullCW); RC.SetPrimitiveTopology(PrimitiveTopology.TriangleList); RC.SetVertexBuffer(0, m_cascadesBoundingsVertices); RC.SetIndexBuffer(m_cubeIB); RC.SetInputLayout(m_inputLayout); RC.SetViewport(0, 0, MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); if (!MyStereoRender.Enable) RC.AllShaderStages.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); else MyStereoRender.BindRawCB_FrameConstants(RC); RC.SetRtv(MyGBuffer.Main.DepthStencil, MyDepthStencilAccess.DepthReadOnly); RC.VertexShader.Set(m_markVS); RC.PixelShader.Set(m_markPS); const int vertexCount = 8; Vector3D* frustumVerticesSS = stackalloc Vector3D[vertexCount]; frustumVerticesSS[0] = new Vector3D(-1, -1, 0); frustumVerticesSS[1] = new Vector3D(-1, 1, 0); frustumVerticesSS[2] = new Vector3D(1, 1, 0); frustumVerticesSS[3] = new Vector3D(1, -1, 0); frustumVerticesSS[4] = new Vector3D(-1, -1, 1); frustumVerticesSS[5] = new Vector3D(-1, 1, 1); frustumVerticesSS[6] = new Vector3D(1, 1, 1); frustumVerticesSS[7] = new Vector3D(1, -1, 1); Vector3D* lightVertices = stackalloc Vector3D[vertexCount]; Vector3* tmpFloatVertices = stackalloc Vector3[vertexCount]; var mapping = MyMapping.MapDiscard(m_cascadesBoundingsVertices); for (int cascadeIndex = 0; cascadeIndex < MyShadowCascades.Settings.NewData.CascadesCount; ++cascadeIndex) { var inverseViewProj = MatrixD.Invert(cascadeInfo[cascadeIndex].CurrentLocalToProjection); for (int arrayIndex = 0; arrayIndex < vertexCount; ++arrayIndex) { Vector3D.Transform(ref frustumVerticesSS[arrayIndex], ref inverseViewProj, out lightVertices[arrayIndex]); tmpFloatVertices[arrayIndex] = lightVertices[arrayIndex]; } for (int arrayIndex = 0; arrayIndex < vertexCount; ++arrayIndex) mapping.WriteAndPosition(ref tmpFloatVertices[arrayIndex]); } mapping.Unmap(); if (MyStereoRender.Enable) MyStereoRender.SetViewport(RC); for (int cascadeIndex = 0; cascadeIndex < MyShadowCascades.Settings.NewData.CascadesCount; ++cascadeIndex) { RC.SetDepthStencilState(MyDepthStencilStateManager.MarkIfInsideCascade[cascadeIndex], 0xf - cascadeIndex); // mark ith bit on depth near RC.DrawIndexed(36, 0, 8 * cascadeIndex); } RC.SetRtv(null); RC.SetDepthStencilState(MyDepthStencilStateManager.DefaultDepthState); RC.SetRasterizerState(null); MyGpuProfiler.IC_EndBlock(); }
internal void GatherArray(IUavTexture postprocessTarget, ISrvBindable cascadeArray, MyProjectionInfo[] cascadeInfo, IConstantBuffer cascadeConstantBuffer) { MyShadowsQuality shadowsQuality = MyRender11.RenderSettings.ShadowQuality.GetShadowsQuality(); if (!MyRender11.Settings.EnableShadows || !MyRender11.DebugOverrides.Shadows || shadowsQuality == MyShadowsQuality.DISABLED) { RC.ClearUav(postprocessTarget, new RawInt4()); return; } MarkCascadesInStencil(cascadeInfo); MyGpuProfiler.IC_BeginBlock("Cascades postprocess"); if (shadowsQuality == MyShadowsQuality.LOW) RC.ComputeShader.Set(m_gatherCS_LD); else if (shadowsQuality == MyShadowsQuality.MEDIUM) RC.ComputeShader.Set(m_gatherCS_MD); else if (shadowsQuality == MyShadowsQuality.HIGH) RC.ComputeShader.Set(m_gatherCS_HD); RC.ComputeShader.SetUav(0, postprocessTarget); RC.ComputeShader.SetSrv(0, MyGBuffer.Main.ResolvedDepthStencil.SrvDepth); RC.ComputeShader.SetSrv(1, MyGBuffer.Main.DepthStencil.SrvStencil); RC.ComputeShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MySamplerStateManager.Shadowmap); if (!MyStereoRender.Enable) RC.ComputeShader.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); else MyStereoRender.CSBindRawCB_FrameConstants(RC); //RC.ComputeShader.SetConstantBuffer(4, MyManagers.Shadows.GetCsmConstantBufferOldOne()); RC.ComputeShader.SetConstantBuffer(4, cascadeConstantBuffer); RC.ComputeShader.SetSrv(MyCommon.CASCADES_SM_SLOT, cascadeArray); //RC.ComputeShader.SetSrv(MyCommon.CASCADES_SM_SLOT, MyManagers.Shadow.GetCsmForGbuffer()); Vector2I threadGroups = GetThreadGroupCount(); RC.Dispatch(threadGroups.X, threadGroups.Y, 1); RC.ComputeShader.SetUav(0, null); RC.ComputeShader.SetSrv(0, null); RC.ComputeShader.SetSrv(1, null); if (shadowsQuality == MyShadowsQuality.HIGH && MyShadowCascades.Settings.Data.EnableShadowBlur) { IBorrowedUavTexture helper = MyManagers.RwTexturesPool.BorrowUav("MyShadowCascadesPostProcess.Helper", Format.R8_UNorm); MyBlur.Run(postprocessTarget, helper, postprocessTarget, depthStencilState: MyDepthStencilStateManager.IgnoreDepthStencil, depthDiscardThreshold: 0.2f, clearColor: Color4.White); helper.Release(); } MyGpuProfiler.IC_EndBlock(); }