private static void RecordMeshPartCommands(MeshId model, MyActor actor, MyGroupRootComponent group, MyCullProxy_2 proxy, MyOutlineDesc desc, ref float maxThickness) { MeshSectionId sectionId; bool found = MyMeshes.TryGetMeshSection(model, 0, desc.SectionIndex, out sectionId); if (!found) { return; } OutlineConstantsLayout constants = new OutlineConstantsLayout(); maxThickness = Math.Max(desc.Thickness, maxThickness); constants.Color = desc.Color.ToVector4(); if (desc.PulseTimeInFrames > 0) { constants.Color.W *= (float)Math.Pow((float)Math.Cos(2.0 * Math.PI * (float)MyRender11.Settings.GameplayFrame / (float)desc.PulseTimeInFrames), 2.0); } MyMeshSectionInfo1 section = sectionId.Info; MyMeshSectionPartInfo1[] meshes = section.Meshes; for (int idx = 0; idx < meshes.Length; idx++) { MyMaterialMergeGroup materialGroup; found = group.TryGetMaterialGroup(meshes[idx].Material, out materialGroup); if (!found) { DebugRecordMeshPartCommands(model, desc.SectionIndex, meshes[idx].Material); return; } int actorIndex; found = materialGroup.TryGetActorIndex(actor, out actorIndex); if (!found) { return; } var mapping = MyMapping.MapDiscard(MyCommon.OutlineConstants); mapping.WriteAndPosition(ref constants); mapping.Unmap(); MyOutlinePass.Instance.RecordCommands(ref proxy.Proxies[materialGroup.Index], actorIndex, meshes[idx].PartIndex); } }
static void DrawRenderableComponent(MyActor actor, MyRenderableComponent renderableComponent, List <MyHighlightDesc> highlightDescs) { var renderLod = renderableComponent.Lods[renderableComponent.CurrentLod]; var model = renderableComponent.GetModel(); LodMeshId currentModelId; if (!MyMeshes.TryGetLodMesh(model, renderableComponent.CurrentLod, out currentModelId)) { Debug.Fail("Mesh for outlining not found!"); return; } foreach (MyHighlightDesc descriptor in highlightDescs) { if (!renderableComponent.IsRenderedStandAlone) { MyGroupLeafComponent leafComponent = actor.GetGroupLeaf(); MyGroupRootComponent groupComponent = leafComponent.RootGroup; if (groupComponent != null) { RecordMeshPartCommands(model, actor, groupComponent, groupComponent.m_proxy, descriptor); } continue; } if (!string.IsNullOrEmpty(descriptor.SectionName)) { RecordMeshSectionCommands(model, renderableComponent, renderLod, descriptor); } else { RecordMeshPartCommands(model, currentModelId, renderableComponent, renderLod, descriptor); } } }
static void RecordMeshPartCommands(MeshId model, MyActor actor, MyGroupRootComponent group, MyCullProxy_2 proxy, MyHighlightDesc desc) { MeshSectionId sectionId; bool found = MyMeshes.TryGetMeshSection(model, 0, desc.SectionName, out sectionId); if (!found) { return; } WriteHighlightConstants(ref desc); MyMeshSectionInfo1 section = sectionId.Info; MyMeshSectionPartInfo1[] meshes = section.Meshes; for (int idx = 0; idx < meshes.Length; idx++) { MyMaterialMergeGroup materialGroup; found = group.TryGetMaterialGroup(meshes[idx].Material, out materialGroup); if (!found) { DebugRecordMeshPartCommands(model, desc.SectionName, meshes[idx].Material); return; } int actorIndex; found = materialGroup.TryGetActorIndex(actor, out actorIndex); if (!found) { return; } MyHighlightPass.Instance.RecordCommands(ref proxy.Proxies[materialGroup.Index], actorIndex, meshes[idx].PartIndex); } }
internal static void Run() { ProfilerShort.Begin("MyOutline.Run"); MyGpuProfiler.IC_BeginBlock("MyOutline.Run"); // set resolved depth/ stencil // render all with proper depth-stencil state // blur // blend to main target testing with stencil again MyOutlinePass.Instance.ViewProjection = MyEnvironment.ViewProjectionAt0; MyOutlinePass.Instance.Viewport = new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); MyOutlinePass.Instance.PerFrame(); MyOutlinePass.Instance.Begin(); RC.Clear(); RC.DeviceContext.VertexShader.SetShaderResources(0, null, null, null, null, null, null); RC.DeviceContext.GeometryShader.SetShaderResources(0, null, null, null, null, null, null); RC.DeviceContext.PixelShader.SetShaderResources(0, null, null, null, null, null, null); RC.DeviceContext.ComputeShader.SetShaderResources(0, null, null, null, null, null, null); if (MyRender11.MultisamplingEnabled) { RC.DeviceContext.ClearRenderTargetView(MyRender11.m_rgba8_ms.m_RTV, new SharpDX.Color4(0, 0, 0, 0)); RC.DeviceContext.OutputMerger.SetTargets(MyGBuffer.Main.DepthStencil.m_DSV, MyRender11.m_rgba8_ms.m_RTV); } else { RC.DeviceContext.ClearRenderTargetView(MyRender11.m_rgba8_1.m_RTV, new SharpDX.Color4(0, 0, 0, 0)); RC.DeviceContext.OutputMerger.SetTargets(MyGBuffer.Main.DepthStencil.m_DSV, MyRender11.m_rgba8_1.m_RTV); } float maxThickness = 0f; foreach (var pair in m_outlines) { MyActor actor = MyIDTracker <MyActor> .FindByID(pair.Key); MyRenderableComponent renderableComponent; if (actor == null || (renderableComponent = actor.GetRenderable()) == null) { // If an actor has been removed without removing outlines, just remove the outlines too m_keysToRemove.Add(pair.Key); continue; } var renderLod = renderableComponent.Lods[renderableComponent.CurrentLod]; var model = renderableComponent.GetModel(); LodMeshId currentModelId; if (!MyMeshes.TryGetLodMesh(model, renderableComponent.CurrentLod, out currentModelId)) { Debug.Fail("Mesh for outlining not found!"); continue; } foreach (MyOutlineDesc descriptor in pair.Value) { if (!renderableComponent.IsRenderedStandAlone) { MyGroupLeafComponent leafComponent = actor.GetGroupLeaf(); MyGroupRootComponent groupComponent = leafComponent.RootGroup; if (groupComponent != null) { RecordMeshPartCommands(model, actor, groupComponent, groupComponent.m_proxy, descriptor, ref maxThickness); } continue; } if (descriptor.SectionIndex == -1) { RecordMeshPartCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness); } else { RecordMeshSectionCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness); } } } MyOutlinePass.Instance.End(); RC.SetBS(null); foreach (var outlineKey in m_keysToRemove) { m_outlines.Remove(outlineKey); } m_keysToRemove.SetSize(0); ShaderResourceView initialSourceView = MyRender11.MultisamplingEnabled ? MyRender11.m_rgba8_ms.m_SRV : MyRender11.m_rgba8_1.m_SRV; RenderTargetView renderTargetview = MyRender11.MultisamplingEnabled ? MyRender11.m_rgba8_ms.m_RTV : MyRender11.m_rgba8_1.m_RTV; if (maxThickness > 0) { MyBlur.Run(renderTargetview, MyRender11.m_rgba8_2.m_RTV, MyRender11.m_rgba8_2.m_SRV, initialSourceView, (int)Math.Round(5 * maxThickness), MyBlur.MyBlurDensityFunctionType.Exponential, 0.25f, null, MyFoliageRenderingPass.GrassStencilMask, MyRender11.Settings.BlurCopyOnDepthStencilFail); } MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); }
private static void RecordMeshPartCommands(MeshId model, MyActor actor, MyGroupRootComponent group, MyCullProxy_2 proxy, MyHighlightDesc desc, ref float maxThickness) { MeshSectionId sectionId; bool found = MyMeshes.TryGetMeshSection(model, 0, desc.SectionIndex, out sectionId); if (!found) return; WriteHighlightConstants(ref desc, ref maxThickness); MyMeshSectionInfo1 section = sectionId.Info; MyMeshSectionPartInfo1[] meshes = section.Meshes; for (int idx = 0; idx < meshes.Length; idx++) { MyMaterialMergeGroup materialGroup; found = group.TryGetMaterialGroup(meshes[idx].Material, out materialGroup); if (!found) { DebugRecordMeshPartCommands(model, desc.SectionIndex, meshes[idx].Material); return; } int actorIndex; found = materialGroup.TryGetActorIndex(actor, out actorIndex); if (!found) return; MyHighlightPass.Instance.RecordCommands(ref proxy.Proxies[materialGroup.Index], actorIndex, meshes[idx].PartIndex); } }
private static void RecordMeshPartCommands(MeshId model, MyActor actor, MyGroupRootComponent group, MyCullProxy_2 proxy, MyOutlineDesc desc, ref float maxThickness) { MeshSectionId sectionId; bool found = MyMeshes.TryGetMeshSection(model, 0, desc.SectionIndex, out sectionId); if (!found) return; OutlineConstantsLayout constants = new OutlineConstantsLayout(); maxThickness = Math.Max(desc.Thickness, maxThickness); constants.Color = desc.Color.ToVector4(); if (desc.PulseTimeInFrames > 0) constants.Color.W *= (float)Math.Pow((float)Math.Cos(2.0 * Math.PI * (float)MyRender11.GameplayFrameCounter / (float)desc.PulseTimeInFrames), 2.0); MyMeshSectionInfo1 section = sectionId.Info; MyMeshSectionPartInfo1[] meshes = section.Meshes; for (int idx = 0; idx < meshes.Length; idx++) { MyMaterialMergeGroup materialGroup; found = group.TryGetMaterialGroup(meshes[idx].Material, out materialGroup); if (!found) { DebugRecordMeshPartCommands(model, desc.SectionIndex, meshes[idx].Material); return; } int actorIndex; found = materialGroup.TryGetActorIndex(actor, out actorIndex); if (!found) return; var mapping = MyMapping.MapDiscard(MyCommon.OutlineConstants); mapping.WriteAndPosition(ref constants); mapping.Unmap(); MyOutlinePass.Instance.RecordCommands(ref proxy.Proxies[materialGroup.Index], actorIndex, meshes[idx].PartIndex); } }
internal static IBorrowedRtvTexture Run() { ProfilerShort.Begin("MyOutline.Run"); MyGpuProfiler.IC_BeginBlock("MyOutline.Run"); // set resolved depth/ stencil // render all with proper depth-stencil state // blur // blend to main target testing with stencil again MyOutlinePass.Instance.ViewProjection = MyRender11.Environment.Matrices.ViewProjectionAt0; MyOutlinePass.Instance.Viewport = new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); MyOutlinePass.Instance.PerFrame(); MyOutlinePass.Instance.Begin(); RC.VertexShader.SetSrvs(0, null, null, null, null, null, null); RC.GeometryShader.SetSrvs(0, null, null, null, null, null, null); RC.PixelShader.SetSrvs(0, null, null, null, null, null, null); RC.ComputeShader.SetSrvs(0, null, null, null, null, null, null); int samples = MyRender11.RenderSettings.AntialiasingMode.SamplesCount(); IBorrowedRtvTexture rgba8_1 = MyManagers.RwTexturesPool.BorrowRtv("MyOutline.Rgba8_1", Format.R8G8B8A8_UNorm_SRgb, samples); RC.ClearRtv(rgba8_1, new SharpDX.Color4(0, 0, 0, 0)); RC.SetRtv(MyGBuffer.Main.DepthStencil, MyDepthStencilAccess.ReadWrite, rgba8_1); float maxThickness = 0f; foreach (var pair in m_outlines) { MyActor actor = MyIDTracker <MyActor> .FindByID(pair.Key); MyRenderableComponent renderableComponent; if (actor == null || (renderableComponent = actor.GetRenderable()) == null) { // If an actor has been removed without removing outlines, just remove the outlines too m_keysToRemove.Add(pair.Key); continue; } var renderLod = renderableComponent.Lods[renderableComponent.CurrentLod]; var model = renderableComponent.GetModel(); LodMeshId currentModelId; if (!MyMeshes.TryGetLodMesh(model, renderableComponent.CurrentLod, out currentModelId)) { Debug.Fail("Mesh for outlining not found!"); continue; } foreach (MyOutlineDesc descriptor in pair.Value) { if (!renderableComponent.IsRenderedStandAlone) { MyGroupLeafComponent leafComponent = actor.GetGroupLeaf(); MyGroupRootComponent groupComponent = leafComponent.RootGroup; if (groupComponent != null) { RecordMeshPartCommands(model, actor, groupComponent, groupComponent.m_proxy, descriptor, ref maxThickness); } continue; } if (descriptor.SectionIndex == -1) { RecordMeshPartCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness); } else { RecordMeshSectionCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness); } } } MyOutlinePass.Instance.End(); RC.SetBlendState(null); foreach (var outlineKey in m_keysToRemove) { m_outlines.Remove(outlineKey); } m_keysToRemove.SetSize(0); ISrvBindable initialSourceView = rgba8_1; IRtvBindable renderTargetview = rgba8_1; if (maxThickness > 0) { IBorrowedRtvTexture rgba8_2 = MyManagers.RwTexturesPool.BorrowRtv("MyOutline.Rgba8_2", Format.R8G8B8A8_UNorm_SRgb); MyBlur.Run(renderTargetview, rgba8_2, initialSourceView, (int)Math.Round(maxThickness), MyBlur.MyBlurDensityFunctionType.Exponential, 0.25f, MyDepthStencilStateManager.TestSkipGrassStencil, MyFoliageRenderingPass.GrassStencilMask); rgba8_2.Release(); } MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); return(rgba8_1); }