internal static bool ShouldHaveFoliage(this MeshId meshId) { int partsNum = MyMeshes.GetLodMesh(meshId, 0).Info.PartsNum; bool shouldHaveFoliage = false; for (int partIndex = 0; partIndex < partsNum; ++partIndex) { var triple = MyMeshes.GetVoxelPart(meshId, partIndex).Info.MaterialTriple; if (triple.I0 >= 0 && MyVoxelMaterials1.Table[triple.I0].HasFoliage) { shouldHaveFoliage = true; break; } if (triple.I1 >= 0 && MyVoxelMaterials1.Table[triple.I1].HasFoliage) { shouldHaveFoliage = true; break; } if (triple.I2 >= 0 && MyVoxelMaterials1.Table[triple.I2].HasFoliage) { shouldHaveFoliage = true; break; } } return(shouldHaveFoliage); }
internal unsafe static void RenderSpotlights() { var coneMesh = MyMeshes.GetMeshId(X.TEXT("Models/Debug/Cone.mwm")); var buffers = MyMeshes.GetLodMesh(coneMesh, 0).Buffers; RC.SetVB(0, buffers.VB0.Buffer, buffers.VB0.Stride); RC.SetIB(buffers.IB.Buffer, buffers.IB.Format); RC.SetVS(SpotlightProxyVs); RC.SetIL(SpotlightProxyIL); RC.SetRS(MyRender11.m_nocullRasterizerState); var cb = MyCommon.GetObjectCB(sizeof(SpotlightConstants)); RC.SetCB(1, cb); RC.Context.PixelShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MyRender11.m_shadowmapSamplerState); int index = 0; int casterIndex = 0; foreach (var id in VisibleSpotlights) { var mapping = MyMapping.MapDiscard(cb); mapping.stream.Write(MyLightRendering.Spotlights[index]); mapping.Unmap(); RC.Context.PixelShader.SetShaderResource(13, MyTextures.GetView(MyLights.Spotlights[id.Index].ReflectorTexture)); if (id.CastsShadows) { RC.Context.PixelShader.SetShaderResource(14, MyShadows.ShadowmapsPool[casterIndex].ShaderView); casterIndex++; } RC.SetPS(SpotlightPs_Pixel); if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.TestEdgeStencil, 0); } RC.Context.DrawIndexed(MyMeshes.GetLodMesh(coneMesh, 0).Info.IndicesNum, 0, 0); if (MyRender11.MultisamplingEnabled) { RC.SetPS(SpotlightPs_Sample); RC.SetDS(MyDepthStencilState.TestEdgeStencil, 0x80); RC.Context.DrawIndexed(MyMeshes.GetLodMesh(coneMesh, 0).Info.IndicesNum, 0, 0); } index++; } if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.DefaultDepthState); } RC.SetRS(null); }
internal bool IsMergable(MeshId model) { var mesh = MyMeshes.GetLodMesh(model, 0); MeshPartId part1; bool multipleParts = MyMeshes.TryGetMeshPart(model, 0, 1, out part1); return(!multipleParts && mesh.Info.Data.VertexLayout == OneAndOnlySupportedVertexLayout && mesh.Info.IndicesNum > 0 && model.Info.RuntimeGenerated == false && model.Info.Dynamic == false); }
internal bool OnAddedToScene(MyClipmapCellProxy cellProxy) { if (!IsUsed()) { return(false); } bool lodAabbChanged = false; int rootProxy = m_boundingBoxes.GetRoot(); BoundingBoxD lodAabbBefore = BoundingBoxD.CreateInvalid(); if (rootProxy != -1) { lodAabbBefore = m_boundingBoxes.GetAabb(rootProxy); } BoundingBoxD cellAabb = (BoundingBoxD)cellProxy.LocalAabb; m_cellProxyToAabbProxy.Add(cellProxy, m_boundingBoxes.AddProxy(ref cellAabb, null, 0)); if (rootProxy != -1) { BoundingBoxD lodAabbAfter = m_boundingBoxes.GetAabb(rootProxy); lodAabbChanged = lodAabbBefore.Equals(lodAabbAfter); } if (lodAabbChanged) { InvalidateAllMergedMeshesInLod(); } Vector3D translation = cellProxy.Translation; int divideIndex = GetDivideIndex(ref translation); m_trackedActors[divideIndex].Add(cellProxy.Actor); MyMergedLodMeshId mergedLodMeshId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0); LodMeshId lodMeshToMerge = MyMeshes.GetLodMesh(cellProxy.MeshId, 0); bool mergedMesh = mergedLodMeshId.MergeLodMesh(lodMeshToMerge); if (mergedMesh) { InvalidateAllMergedMeshesInLod(); } TryCancelMergeJob(divideIndex, MeshId.NULL); bool startedMerge = TryStartMergeJob(divideIndex, 1000); bool shouldMarkDirty = !mergedMesh && !startedMerge; if (shouldMarkDirty) { m_dirtyProxyIndices.Add(divideIndex); } return(shouldMarkDirty); }
internal override bool RebuildLodProxy(int lodNum, bool skinningEnabled, MySkinningComponent skinning) { Debug.Assert(Mesh.Info.LodsNum == 1); MyRenderLod lod = null; int partCount; LodMeshId lodMesh = new LodMeshId(); VertexLayoutId vertexLayout; if (!Owner.IsVisible) { return(false); } lodMesh = MyMeshes.GetLodMesh(Mesh, 0); vertexLayout = lodMesh.VertexLayout; partCount = lodMesh.Info.PartsNum; MyObjectPoolManager.Init(ref m_lods[lodNum]); lod = m_lods[lodNum]; lod.VertexLayout1 = vertexLayout; AddToRenderables(); Debug.Assert(partCount > 0); lod.VertexShaderFlags = MyShaderUnifiedFlags.USE_VOXEL_DATA | MyShaderUnifiedFlags.DITHERED; //| MyShaderUnifiedFlags.USE_VOXEL_MORPHING; bool initializeProxies = true; bool initializeDepthProxy = true; int numToInitialize = (initializeProxies ? partCount : 0) + (initializeDepthProxy ? 1 : 0); if (numToInitialize > 0) { lod.AllocateProxies(numToInitialize); } AnyDrawOutsideViewDistance = false; int constantBufferSize = GetConstantBufferSize(lod, skinningEnabled); if (initializeProxies) { for (int partIndex = 0; partIndex < partCount; partIndex++) { CreateRenderableProxyForPart(lodNum, constantBufferSize, partIndex, partIndex, false); } } if (initializeDepthProxy) { CreateRenderableProxyForPart(lodNum, constantBufferSize, numToInitialize - 1, 0, true); } return(true); }
internal bool IsMergable(MeshId model) { // check if one and only spoorted vertex format // check if same material as the rest // check if has one part(!) // check if has one lod - for now return (model.Info.LodsNum == 1 && MyMeshes.GetLodMesh(model, 0).Info.PartsNum == 1 && m_meshTable.IsMergable(model)); }
private void AssignLodMeshToProxy(MeshId mesh, MyRenderableProxy proxy) { if (MyMeshes.IsMergedVoxelMesh(mesh)) { proxy.MergedMesh = MyMeshes.GetMergedLodMesh(mesh, 0); } else { proxy.Mesh = MyMeshes.GetLodMesh(mesh, 0); } }
internal bool ShouldHaveFoliage() { var mesh = Owner.GetRenderable().GetModel(); int voxelLod = MyMeshes.GetVoxelInfo(mesh).Lod; bool voxelMeshNotReady = voxelLod > LodLimit; if (voxelMeshNotReady) { return(false); } int partsNum; if (MyMeshes.IsMergedVoxelMesh(mesh)) { partsNum = MyMeshes.GetMergedLodMesh(mesh, 0).Info.PartsNum; } else { partsNum = MyMeshes.GetLodMesh(mesh, 0).Info.PartsNum; } // only stream stones for lod0 if (voxelLod > 0) { bool allStone = true; for (int i = 0; i < partsNum; i++) { var triple = MyMeshes.GetVoxelPart(mesh, i).Info.MaterialTriple; if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage && MyVoxelMaterials1.Table[triple.I0].FoliageType == 0) { allStone = false; break; } if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage && MyVoxelMaterials1.Table[triple.I1].FoliageType == 0) { allStone = false; break; } if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage && MyVoxelMaterials1.Table[triple.I2].FoliageType == 0) { allStone = false; break; } } if (allStone) { return(false); } } return(true); }
internal static void AssignLodMeshToProxy(this MeshId meshId, MyRenderableProxy proxy) { Debug.Assert(proxy != null, "Proxy cannot be null!"); if (MyMeshes.IsMergedVoxelMesh(meshId)) { proxy.MergedMesh = MyMeshes.GetMergedLodMesh(meshId, 0); } else { proxy.Mesh = MyMeshes.GetLodMesh(meshId, 0); } }
internal static MyMeshBuffers GetMeshBuffers(this MeshId meshId) { MyMeshBuffers buffers; if (MyMeshes.IsMergedVoxelMesh(meshId)) { buffers = MyMeshes.GetMergedLodMesh(meshId, 0).Buffers; } else { buffers = MyMeshes.GetLodMesh(meshId, 0).Buffers; } return(buffers); }
internal static int GetIndexCount(this MeshId meshId) { int indexCount = 0; if (MyMeshes.IsMergedVoxelMesh(meshId)) { indexCount = MyMeshes.GetMergedLodMesh(meshId, 0).Info.IndicesNum; } else { indexCount = MyMeshes.GetLodMesh(meshId, 0).Info.IndicesNum; } return(indexCount); }
internal bool OnDeleteCell(MyClipmapCellProxy cellProxy) { if (!IsUsed()) { return(false); } bool unloadedCell = false; Vector3D translation = cellProxy.Translation; int divideIndex; if (TryGetDivideIndex(ref translation, out divideIndex)) { MyMergedLodMeshId mergedLodMeshId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0); LodMeshId lodMeshId = MyMeshes.GetLodMesh(cellProxy.MeshId, 0); bool unmergedMesh = mergedLodMeshId.UnmergeLodMesh(lodMeshId); if (unmergedMesh) { InvalidateAllMergedMeshesInLod(); } TryCancelMergeJob(divideIndex, cellProxy.MeshId); cellProxy.Unload(); unloadedCell = true; TryStartMergeJob(divideIndex, 1000); if (unmergedMesh && unloadedCell) { m_dirtyProxyIndices.Add(divideIndex); } m_trackedActors[divideIndex].Remove(cellProxy.Actor); } int proxyId; if (m_cellProxyToAabbProxy.TryGetValue(cellProxy, out proxyId)) { m_boundingBoxes.RemoveProxy(m_cellProxyToAabbProxy[cellProxy]); m_cellProxyToAabbProxy.Remove(cellProxy); } return(unloadedCell); }
private static void RenderBegin() { var RC = MyImmediateRC.RC; var buffers = MyMeshes.GetLodMesh(m_sphereMesh, 0).Buffers; RC.SetVertexBuffer(0, buffers.VB0); RC.SetIndexBuffer(buffers.IB); RC.VertexShader.Set(m_proxyVs); RC.SetInputLayout(m_proxyIL); RC.SetRasterizerState(null); RC.SetBlendState(MyBlendStateManager.BlendAtmosphere); RC.AllShaderStages.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.AllShaderStages.SetConstantBuffer(1, m_cb); RC.PixelShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MySamplerStateManager.Shadowmap); }
private bool TryCancelMergeJob(int divideIndex, MeshId meshIdToRemove) { bool canceled = false; if (m_mergeJobs[divideIndex].LodMeshesBeingMerged.Count > 0) { // Send the cancel message MyRenderProxy.CancelVoxelMeshMerge(m_parentClipmap.Id, m_mergeJobs[divideIndex].CurrentWorkId); if (meshIdToRemove != MeshId.NULL) { m_mergeJobs[divideIndex].LodMeshesBeingMerged.Remove(MyMeshes.GetLodMesh(meshIdToRemove, 0)); } // Put the canceled meshes back into the correct pending queue var mergedId = MyMeshes.GetMergedLodMesh(m_mergedLodMeshProxies[divideIndex].MeshId, 0); mergedId.Info.PendingLodMeshes.UnionWith(m_mergeJobs[divideIndex].LodMeshesBeingMerged); ResetMerge(divideIndex); canceled = true; } return(canceled); }
internal static int GetIndexCount(this MeshId meshId) { return(MyMeshes.GetLodMesh(meshId, 0).Info.IndicesNum); }
internal override bool RebuildLodProxy(int lodNum, bool skinningEnabled, MySkinningComponent skinning) { Debug.Assert(Mesh.Info.LodsNum == 1); MyRenderLod lod = null; int partCount; LodMeshId lodMesh = new LodMeshId(); MyMergedLodMeshId mergedLodMesh = new MyMergedLodMeshId(); VertexLayoutId vertexLayout; bool isMergedMesh = MyMeshes.IsMergedVoxelMesh(Mesh); if (!isMergedMesh) { if (!Owner.IsVisible) { return(false); } lodMesh = MyMeshes.GetLodMesh(Mesh, 0); vertexLayout = lodMesh.VertexLayout; partCount = lodMesh.Info.PartsNum; } else { mergedLodMesh = MyMeshes.GetMergedLodMesh(Mesh, 0); if (mergedLodMesh.VertexLayout == VertexLayoutId.NULL || mergedLodMesh.Info.MergedLodMeshes.Count == 0) { return(false); } partCount = mergedLodMesh.Info.PartsNum; vertexLayout = mergedLodMesh.VertexLayout; } MyObjectPoolManager.Init(ref m_lods[lodNum]); lod = m_lods[lodNum]; lod.VertexLayout1 = vertexLayout; // Hide proxies when they will already be rendered in a merged mesh if (!MyMeshes.IsLodMeshMerged(lodMesh)) { AddToRenderables(); } Debug.Assert(partCount > 0); lod.VertexShaderFlags = MyShaderUnifiedFlags.USE_VOXEL_DATA | MyShaderUnifiedFlags.USE_VOXEL_MORPHING | MyShaderUnifiedFlags.DITHERED; bool initializeProxies = true; //isMergedMesh || !MyMeshes.IsLodMeshMerged(lodMesh); bool initializeDepthProxy = true; //!isMergedMesh && Num > 0; int numToInitialize = (initializeProxies ? partCount : 0) + (initializeDepthProxy ? 1 : 0); if (numToInitialize > 0) { lod.AllocateProxies(numToInitialize); } AnyDrawOutsideViewDistance = false; int constantBufferSize = GetConstantBufferSize(lod, skinningEnabled); if (initializeProxies) { for (int partIndex = 0; partIndex < partCount; partIndex++) { CreateRenderableProxyForPart(lodNum, constantBufferSize, partIndex, partIndex, false); } } if (initializeDepthProxy) { CreateRenderableProxyForPart(lodNum, constantBufferSize, numToInitialize - 1, 0, true); } return(true); }
internal static MyMeshBuffers GetMeshBuffers(this MeshId meshId) { return(MyMeshes.GetLodMesh(meshId, 0).Buffers); }
internal static void AssignLodMeshToProxy(this MeshId meshId, MyRenderableProxy proxy) { Debug.Assert(proxy != null, "Proxy cannot be null!"); proxy.Mesh = MyMeshes.GetLodMesh(meshId, 0); }
internal static BoundingBox?GetBoundingBox(this MeshId meshId, int lod) { return(MyMeshes.GetLodMesh(meshId, lod).Info.BoundingBox); }
private static void RenderOne(Vector3D cameraPosition, ref Matrix viewProj, PixelShaderId ps, PixelShaderId psPerSample, uint atmosphereId) { if (!Enabled) { return; } var RC = MyImmediateRC.RC; var setup = m_atmospheres[atmosphereId]; var worldMatrix = setup.WorldMatrix; worldMatrix.Translation -= cameraPosition; var worldViewProj = ((Matrix)worldMatrix) * viewProj; var constants = FillAtmosphereConstants(cameraPosition, setup); constants.WorldViewProj = Matrix.Transpose(worldViewProj); var mapping = MyMapping.MapDiscard(m_cb); mapping.WriteAndPosition(ref constants); mapping.Unmap(); var luts = AtmosphereLUT[atmosphereId]; RC.PixelShader.SetSrvs(5, luts.TransmittanceLut); bool inside = worldMatrix.Translation.Length() < setup.AtmosphereRadius * setup.PlanetScaleFactor; if (inside) { RC.SetRasterizerState(MyRasterizerStateManager.InvTriRasterizerState); if (MyRender11.MultisamplingEnabled) { RC.SetDepthStencilState(MyDepthStencilStateManager.TestEdgeStencil, 0); } else { RC.SetDepthStencilState(MyDepthStencilStateManager.IgnoreDepthStencil); } } else { RC.SetRasterizerState(null); if (MyRender11.MultisamplingEnabled) { RC.SetDepthStencilState(MyDepthStencilStateManager.TestDepthAndEdgeStencil, 0); } else { RC.SetDepthStencilState(MyDepthStencilStateManager.DepthTestReadOnly); } } RC.PixelShader.Set(ps); var indicesNum = MyMeshes.GetLodMesh(m_sphereMesh, 0).Info.IndicesNum; RC.DrawIndexed(indicesNum, 0, 0); if (MyRender11.MultisamplingEnabled) { if (inside) { RC.SetDepthStencilState(MyDepthStencilStateManager.TestEdgeStencil, 0x80); } else { RC.SetDepthStencilState(MyDepthStencilStateManager.TestDepthAndEdgeStencil, 0x80); } RC.PixelShader.Set(psPerSample); RC.DrawIndexed(indicesNum, 0, 0); } }
internal unsafe void AddMesh(MeshId model) { Debug.Assert(IsMergable(model)); var key = new MyMeshTableEntry { Model = model, Lod = 0, Part = 0 }; if (!ContainsKey(key)) { var vertexOffset = m_vertices; var indexOffset = m_indices; var mesh = MyMeshes.GetLodMesh(model, 0); Debug.Assert(mesh.Info.Data.IndicesFmt == SharpDX.DXGI.Format.R16_UInt); var meshInfo = mesh.Info; var data = meshInfo.Data; int verticesCapacity = vertexOffset + meshInfo.VerticesNum; int indicesCapacity = CalculateIndicesCapacity(indexOffset, meshInfo.IndicesNum); m_vertices = verticesCapacity; m_indices = indicesCapacity; MyArrayHelpers.Reserve(ref m_vertexStream0, verticesCapacity * Stride0, 1024 * 1024); MyArrayHelpers.Reserve(ref m_vertexStream1, verticesCapacity * Stride1, 1024 * 1024); MyArrayHelpers.Reserve(ref m_indexStream, indicesCapacity * IndexStride, 1024 * 1024); var list = new List <int>(); fixed(byte *src = data.VertexStream0, dst_ = m_vertexStream0) { byte *dst = dst_ + data.Stride0 * vertexOffset; SharpDX.Utilities.CopyMemory(new IntPtr(dst), new IntPtr(src), data.Stride0 * meshInfo.VerticesNum); } fixed(byte *src = data.VertexStream1, dst_ = m_vertexStream1) { byte *dst = dst_ + data.Stride1 * vertexOffset; SharpDX.Utilities.CopyMemory(new IntPtr(dst), new IntPtr(src), data.Stride1 * meshInfo.VerticesNum); } fixed(void *dst = m_indexStream) { uint *stream = (uint *)dst; stream += indexOffset; fixed(void *src = data.Indices) { ushort *indices = (ushort *)src; for (int k = 0; k < meshInfo.IndicesNum; k += m_indexPageSize) { int iEnd = Math.Min(k + m_indexPageSize, meshInfo.IndicesNum); for (int i = k; i < iEnd; i++) { stream[i] = (uint)(indices[i] + vertexOffset); } list.Add(m_pagesUsed++); } if ((meshInfo.IndicesNum % m_indexPageSize) != 0) { var pageIndex = meshInfo.IndicesNum / m_indexPageSize; var pageOffset = meshInfo.IndicesNum % m_indexPageSize; uint lastIndex = stream[pageIndex * m_indexPageSize + pageOffset - 1]; for (int i = pageOffset; i < m_indexPageSize; i++) { stream[pageIndex * m_indexPageSize + i] = lastIndex; } } } } m_table.Add(key, new MyMeshTableSrv_Entry { Pages = list }); m_dirty = true; } }
internal bool IsMergable(MeshId model) { var mesh = MyMeshes.GetLodMesh(model, 0); return(mesh.Info.Data.VertexLayout == OneAndOnlySupportedVertexLayout && mesh.Info.IndicesNum > 0 && model.Info.RuntimeGenerated == false && model.Info.Dynamic == false); }
internal unsafe static void Render() { var RC = MyImmediateRC.RC; if (Atmospheres.Count == 0) { return; } var sphereMesh = MyMeshes.GetMeshId(X.TEXT("Models/Debug/Sphere.mwm")); var buffers = MyMeshes.GetLodMesh(sphereMesh, 0).Buffers; RC.SetVB(0, buffers.VB0.Buffer, buffers.VB0.Stride); RC.SetIB(buffers.IB.Buffer, buffers.IB.Format); RC.SetVS(m_proxyVs); RC.SetIL(m_proxyIL); RC.SetRS(null); RC.SetBS(MyRender11.BlendAdditive); var cb = MyCommon.GetObjectCB(sizeof(AtmosphereConstants)); RC.SetCB(1, cb); RC.Context.PixelShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MyRender11.m_shadowmapSamplerState); // depth, RC.BindGBufferForRead(0, MyGBuffer.Main); RC.BindDepthRT(MyGBuffer.Main.Get(MyGbufferSlot.DepthStencil), DepthStencilAccess.ReadOnly, MyGBuffer.Main.Get(MyGbufferSlot.LBuffer)); var indicesNum = MyMeshes.GetLodMesh(sphereMesh, 0).Info.IndicesNum; // sort by distance int i = Atmospheres.Count; foreach (var atmosphere in Atmospheres.OrderByDescending(x => (x.Value.WorldMatrix.Translation - MyEnvironment.CameraPosition).LengthSquared())) { var worldMatrix = atmosphere.Value.WorldMatrix; worldMatrix.Translation -= MyEnvironment.CameraPosition; var worldViewProj = ((Matrix)worldMatrix) * MyEnvironment.ViewProjectionAt0; AtmosphereConstants constants = new AtmosphereConstants(); constants.WorldViewProj = Matrix.Transpose(worldViewProj); constants.PlanetCentre = (Vector3)worldMatrix.Translation; constants.AtmosphereRadius = atmosphere.Value.AtmosphereRadius; constants.GroundRadius = atmosphere.Value.PlanetRadius; constants.BetaRayleighScattering = atmosphere.Value.BetaRayleighScattering; constants.BetaMieScattering = atmosphere.Value.BetaMieScattering; constants.HeightScaleRayleighMie = atmosphere.Value.HeightScaleRayleighMie; constants.RadiusLimit = constants.AtmosphereRadius + 1; var mapping = MyMapping.MapDiscard(cb); mapping.stream.Write(constants); mapping.Unmap(); var luts = AtmosphereLUT[atmosphere.Key]; RC.Context.PixelShader.SetShaderResources(5, luts.TransmittanceLut.ShaderView, luts.InscatterLut.ShaderView); bool inside = worldMatrix.Translation.Length() < constants.AtmosphereRadius; if (inside) { RC.SetRS(MyRender11.m_invTriRasterizerState); if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.TestAAEdge, 0); } else { RC.SetDS(MyDepthStencilState.IgnoreDepthStencil); } } else { RC.SetRS(null); if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.TestDepthAndAAEdge, 0); } else { RC.SetDS(MyDepthStencilState.DepthTest); } } if (i == 1) { RC.SetBS(MyRender11.BlendOutscatter); RC.SetPS(m_psT); RC.Context.DrawIndexed(indicesNum, 0, 0); RC.SetBS(MyRender11.BlendAdditive); } RC.SetPS(m_ps); RC.Context.DrawIndexed(indicesNum, 0, 0); if (MyRender11.MultisamplingEnabled) { if (inside) { RC.SetDS(MyDepthStencilState.TestAAEdge, 0x80); } else { RC.SetDS(MyDepthStencilState.TestDepthAndAAEdge, 0x80); } if (i == 1) { RC.SetBS(MyRender11.BlendOutscatter); RC.SetPS(m_psTPerSample); RC.Context.DrawIndexed(indicesNum, 0, 0); RC.SetBS(MyRender11.BlendAdditive); } RC.SetPS(m_psPerSample); RC.Context.DrawIndexed(indicesNum, 0, 0); } i--; } RC.Context.PixelShader.SetShaderResources(5, null, null); RC.SetRS(null); RC.SetDS(null); }
internal unsafe void FillStreams() { bool alreadyFilled = m_streams != null && m_streams.Count > 0; if (alreadyFilled) { return; } var mesh = Owner.GetRenderable().GetModel(); int voxelLod = MyMeshes.GetVoxelInfo(mesh).Lod; if (!Owner.IsVisible) { return; } int partsNum; if (MyMeshes.IsMergedVoxelMesh(mesh)) { partsNum = MyMeshes.GetMergedLodMesh(mesh, 0).Info.PartsNum; } else { partsNum = MyMeshes.GetLodMesh(mesh, 0).Info.PartsNum; } m_streams = new Dictionary <int, MyFoliageStream>(); // analyze for (int partIndex = 0; partIndex < partsNum; ++partIndex) { var partInfo = MyMeshes.GetVoxelPart(mesh, partIndex).Info; var triple = partInfo.MaterialTriple; if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage) { PrepareStream(triple.I0, partInfo.IndexCount / 3, voxelLod); } if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage) { PrepareStream(triple.I1, partInfo.IndexCount / 3, voxelLod); } if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage) { PrepareStream(triple.I2, partInfo.IndexCount / 3, voxelLod); } } // prepare foreach (var stream in m_streams.Values) { stream.AllocateStreamOutBuffer(sizeof(Vector3) + sizeof(uint)); } // analyze for (int partIndex = 0; partIndex < partsNum; partIndex++) { var partInfo = MyMeshes.GetVoxelPart(mesh, partIndex).Info; var triple = partInfo.MaterialTriple; if (triple.I0 != -1 && MyVoxelMaterials1.Table[triple.I0].HasFoliage) { FillStreamWithTerrainBatch(triple.I0, 0, partInfo.IndexCount, partInfo.StartIndex, 0); } if (triple.I1 != -1 && MyVoxelMaterials1.Table[triple.I1].HasFoliage) { FillStreamWithTerrainBatch(triple.I1, 1, partInfo.IndexCount, partInfo.StartIndex, 0); } if (triple.I2 != -1 && MyVoxelMaterials1.Table[triple.I2].HasFoliage) { FillStreamWithTerrainBatch(triple.I2, 2, partInfo.IndexCount, partInfo.StartIndex, 0); } } }
internal static void Run() { // set resolved depth/ stencil // render all shit with proper depth-stencil state // bluuuur // 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.Context.VertexShader.SetShaderResources(0, null, null, null, null, null, null); RC.Context.GeometryShader.SetShaderResources(0, null, null, null, null, null, null); RC.Context.PixelShader.SetShaderResources(0, null, null, null, null, null, null); RC.Context.ComputeShader.SetShaderResources(0, null, null, null, null, null, null); if (MyRender11.MultisamplingEnabled) { RC.Context.ClearRenderTargetView(MyRender11.m_rgba8_ms.m_RTV, new SharpDX.Color4(0, 0, 0, 0)); RC.Context.OutputMerger.SetTargets(MyGBuffer.Main.DepthStencil.m_DSV, MyRender11.m_rgba8_ms.m_RTV); } else { RC.Context.ClearRenderTargetView(MyRender11.m_rgba8_1.m_RTV, new SharpDX.Color4(0, 0, 0, 0)); RC.Context.OutputMerger.SetTargets(MyGBuffer.Main.DepthStencil.m_DSV, MyRender11.m_rgba8_1.m_RTV); } OutlineConstantsLayout constants; foreach (var kv in m_outlines) { var r = MyIDTracker <MyActor> .FindByID(kv.Key).GetRenderable(); var renderLod = r.m_lods[r.m_lod]; var submeshes = MyMeshes.GetLodMesh(r.GetModel(), r.m_lod).Info.PartsNum; for (int i = 0; i < submeshes; i++) { var part = MyMeshes.GetMeshPart(r.GetModel(), r.m_lod, i); for (int j = 0; j < kv.Value.Count; ++j) { if (part.Info.Material.Info.Name == kv.Value[j].Material) { constants.Color = kv.Value[j].Color.ToVector4(); constants.WorldToVolume = kv.Value[j].WorldToVolume.HasValue ? kv.Value[j].WorldToVolume.Value : Matrix.Zero; var mapping = MyMapping.MapDiscard(MyCommon.OutlineConstants); mapping.stream.Write(constants); mapping.Unmap(); RC.BindShaders(renderLod.HighlightShaders[i]); MyOutlinePass.Instance.RecordCommands(renderLod.RenderableProxies[i]); } } } } MyOutlinePass.Instance.End(); RC.Context.OutputMerger.SetTargets(null as DepthStencilView, null as RenderTargetView); RC.SetBS(null); if (MyRender11.MultisamplingEnabled) { RC.Context.PixelShader.SetShaderResource(0, MyRender11.m_rgba8_ms.m_SRV); } else { RC.Context.PixelShader.SetShaderResource(0, MyRender11.m_rgba8_1.m_SRV); } RC.Context.OutputMerger.SetTargets(null as DepthStencilView, MyRender11.m_rgba8_2.m_RTV); RC.SetPS(m_blurH); MyScreenPass.DrawFullscreenQuad(); RC.Context.PixelShader.SetShaderResource(0, null); RC.Context.OutputMerger.SetTargets(null as DepthStencilView, MyRender11.m_rgba8_1.m_RTV); RC.Context.PixelShader.SetShaderResource(0, MyRender11.m_rgba8_2.m_SRV); RC.SetPS(m_blurV); MyScreenPass.DrawFullscreenQuad(); RC.Context.OutputMerger.SetTargets(null as DepthStencilView, null as RenderTargetView); RC.Context.PixelShader.SetShaderResource(0, null); }
private void CreateRenderableProxyForPart(MyRenderLod lod, int objectConstantsSize, int proxyIndex, int partIndex, bool shadowsOnly) { var partId = MyMeshes.GetVoxelPart(Mesh, partIndex); var technique = partId.Info.MaterialTriple.IsMultimaterial() ? MyVoxelMesh.MULTI_MATERIAL_TAG : MyVoxelMesh.SINGLE_MATERIAL_TAG; if (shadowsOnly) { technique = MyVoxelMesh.SINGLE_MATERIAL_TAG; } lod.RenderableProxies[proxyIndex].WorldMatrix = Owner.WorldMatrix; //lod.RenderableProxies[p].ObjectData.LocalMatrix = m_owner.WorldMatrix; lod.RenderableProxies[proxyIndex].NonVoxelObjectData = MyObjectDataNonVoxel.Invalid; lod.RenderableProxies[proxyIndex].VoxelCommonObjectData.VoxelOffset = m_voxelOffset; lod.RenderableProxies[proxyIndex].VoxelCommonObjectData.MassiveCenterRadius = Vector4.Zero; // Set in UpdateLodState lod.RenderableProxies[proxyIndex].VoxelCommonObjectData.VoxelScale = m_voxelScale; AssignLodMeshToProxy(Mesh, lod.RenderableProxies[proxyIndex]); lod.RenderableProxies[proxyIndex].DepthShaders = MyMaterialShaders.Get( X.TEXT(MapTechniqueToShaderMaterial(technique)), X.TEXT(MyGeometryRenderer.DEFAULT_DEPTH_PASS), lod.VertexLayout1, lod.VertexShaderFlags | MyShaderUnifiedFlags.DEPTH_ONLY | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED); lod.RenderableProxies[proxyIndex].Shaders = MyMaterialShaders.Get( X.TEXT(MapTechniqueToShaderMaterial(technique)), X.TEXT(MyGeometryRenderer.DEFAULT_OPAQUE_PASS), lod.VertexLayout1, lod.VertexShaderFlags | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED); lod.RenderableProxies[proxyIndex].ForwardShaders = MyMaterialShaders.Get( X.TEXT(MapTechniqueToShaderMaterial(technique)), X.TEXT(MyGeometryRenderer.DEFAULT_FORWARD_PASS), lod.VertexLayout1, lod.VertexShaderFlags | MapTechniqueToShaderMaterialFlags(technique) | MyShaderUnifiedFlags.DITHERED); var partInfo = partId.Info; MyDrawSubmesh drawSubmesh; if (shadowsOnly) { MyMeshBuffers buffers; if (MyMeshes.IsMergedVoxelMesh(Mesh)) { buffers = MyMeshes.GetMergedLodMesh(Mesh, 0).Buffers; } else { buffers = MyMeshes.GetLodMesh(Mesh, 0).Buffers; } drawSubmesh = new MyDrawSubmesh { BaseVertex = 0, StartIndex = 0, IndexCount = buffers.IB.Capacity, BonesMapping = null, MaterialId = MyVoxelMaterials1.GetMaterialProxyId(partId.Info.MaterialTriple), Flags = MyDrawSubmesh.MySubmeshFlags.Depth }; } else { drawSubmesh = new MyDrawSubmesh { BaseVertex = partInfo.BaseVertex, StartIndex = partInfo.StartIndex, IndexCount = partInfo.IndexCount, BonesMapping = null, MaterialId = MyVoxelMaterials1.GetMaterialProxyId(partId.Info.MaterialTriple), Flags = MyDrawSubmesh.MySubmeshFlags.Gbuffer | MyDrawSubmesh.MySubmeshFlags.Forward }; } lod.RenderableProxies[proxyIndex].DrawSubmesh = drawSubmesh; lod.RenderableProxies[proxyIndex].SkinningMatrices = null; lod.RenderableProxies[proxyIndex].ObjectBuffer = MyCommon.GetObjectCB(objectConstantsSize); lod.RenderableProxies[proxyIndex].InstanceCount = m_instanceCount; lod.RenderableProxies[proxyIndex].StartInstance = m_startInstance; lod.RenderableProxies[proxyIndex].Flags = MapTechniqueToRenderableFlags(technique) | m_additionalFlags; lod.RenderableProxies[proxyIndex].Type = MapTechniqueToMaterialType(technique); lod.RenderableProxies[proxyIndex].Parent = this; lod.RenderableProxies[proxyIndex].Lod = 0; lod.RenderableProxies[proxyIndex].Instancing = m_instancing; AnyDrawOutsideViewDistance |= lod.RenderableProxies[proxyIndex].Flags.HasFlags(MyRenderableProxyFlags.DrawOutsideViewDistance); ulong sortingKey = 0; My64BitValueHelper.SetBits(ref sortingKey, 36, 2, (ulong)lod.RenderableProxies[proxyIndex].Type); My64BitValueHelper.SetBits(ref sortingKey, 32, 4, (ulong)drawSubmesh.MaterialId.Index); My64BitValueHelper.SetBits(ref sortingKey, 26, 6, (ulong)MyShaderMaterial.GetID(MapTechniqueToShaderMaterial(technique))); My64BitValueHelper.SetBits(ref sortingKey, 22, 4, (ulong)m_voxelLod); My64BitValueHelper.SetBits(ref sortingKey, 16, 6, (ulong)lod.VertexShaderFlags); //My64BitValueHelper.SetBits(ref sortingKey, 14, 6, (ulong)lod.VertexLayout1.Index); //My64BitValueHelper.SetBits(ref sortingKey, 0, 14, (ulong)m_owner.ID); lod.SortingKeys[proxyIndex] = sortingKey; }
internal static unsafe void Render() { if (m_cloudLayers.Count == 0) { return; } var immediateContext = MyImmediateRC.RC; immediateContext.VertexShader.Set(m_proxyVs); immediateContext.PixelShader.Set(m_cloudPs); immediateContext.SetInputLayout(m_proxyIL); immediateContext.SetRasterizerState(MyRasterizerStateManager.NocullRasterizerState); immediateContext.SetBlendState(MyBlendStateManager.BlendTransparent); immediateContext.SetDepthStencilState(MyDepthStencilStateManager.DepthTestReadOnly); var cb = MyCommon.GetObjectCB(sizeof(CloudsConstants)); immediateContext.AllShaderStages.SetConstantBuffer(1, cb); immediateContext.PixelShader.SetSamplers(0, MySamplerStateManager.CloudSampler); immediateContext.SetRtv(MyGBuffer.Main.DepthStencil, MyDepthStencilAccess.ReadOnly, MyGBuffer.Main.LBuffer); m_cloudLayers.OrderByDescending(x => { MyCloudLayer cloudLayer = x.Value; Vector3D cameraToLayer = cloudLayer.CenterPoint - MyRender11.Environment.Matrices.CameraPosition; Vector3D layerToCameraDirection = -Vector3D.Normalize(cameraToLayer); return((cameraToLayer + layerToCameraDirection * cloudLayer.Altitude).Length()); }); foreach (var cloudLayer in m_cloudLayers) { var modifiableData = m_modifiableCloudLayerData[cloudLayer.Key]; int currentGameplayFrame = MyRender11.GameplayFrameCounter; var increment = cloudLayer.Value.AngularVelocity * (float)(currentGameplayFrame - modifiableData.LastGameplayFrameUpdate) / 10.0f; modifiableData.RadiansAroundAxis += increment; // Constant for backward compatibility if (modifiableData.RadiansAroundAxis >= 2 * Math.PI) { modifiableData.RadiansAroundAxis -= 2 * Math.PI; } modifiableData.LastGameplayFrameUpdate = currentGameplayFrame; double scaledAltitude = cloudLayer.Value.Altitude; Vector3D centerPoint = cloudLayer.Value.CenterPoint; Vector3D cameraPosition = MyRender11.Environment.Matrices.CameraPosition; double cameraDistanceFromCenter = (centerPoint - cameraPosition).Length(); if (cloudLayer.Value.ScalingEnabled) { double threshold = cloudLayer.Value.Altitude * 0.95; if (cameraDistanceFromCenter > threshold) { scaledAltitude = MathHelper.Clamp(scaledAltitude * (1 - MathHelper.Clamp((cameraDistanceFromCenter - threshold) / (threshold * 1.5), 0.0, 1.0)), cloudLayer.Value.MinScaledAltitude, cloudLayer.Value.Altitude); } } MatrixD worldMatrix = MatrixD.CreateScale(scaledAltitude) * MatrixD.CreateFromAxisAngle(cloudLayer.Value.RotationAxis, (float)modifiableData.RadiansAroundAxis); worldMatrix.Translation = cloudLayer.Value.CenterPoint; worldMatrix.Translation -= MyRender11.Environment.Matrices.CameraPosition; float layerAlpha = 1.0f; double currentRelativeAltitude = (cameraDistanceFromCenter - cloudLayer.Value.MinScaledAltitude) / (cloudLayer.Value.MaxPlanetHillRadius - cloudLayer.Value.MinScaledAltitude); if (cloudLayer.Value.FadeOutRelativeAltitudeStart > cloudLayer.Value.FadeOutRelativeAltitudeEnd) { layerAlpha = (float)MathHelper.Clamp(1.0 - (cloudLayer.Value.FadeOutRelativeAltitudeStart - currentRelativeAltitude) / (cloudLayer.Value.FadeOutRelativeAltitudeStart - cloudLayer.Value.FadeOutRelativeAltitudeEnd), 0.0, 1.0); } else if (cloudLayer.Value.FadeOutRelativeAltitudeStart < cloudLayer.Value.FadeOutRelativeAltitudeEnd) { layerAlpha = (float)MathHelper.Clamp(1.0 - (currentRelativeAltitude - cloudLayer.Value.FadeOutRelativeAltitudeStart) / (cloudLayer.Value.FadeOutRelativeAltitudeEnd - cloudLayer.Value.FadeOutRelativeAltitudeStart), 0.0, 1.0); } Vector4 layerColor = new Vector4(1, 1, 1, layerAlpha); var constants = new CloudsConstants(); constants.World = MatrixD.Transpose(worldMatrix); constants.ViewProj = MatrixD.Transpose(MyRender11.Environment.Matrices.ViewProjectionAt0); constants.Color = layerColor; var mapping = MyMapping.MapDiscard(cb); mapping.WriteAndPosition(ref constants); mapping.Unmap(); MeshId sphereMesh = cloudLayer.Value.Mesh; LodMeshId lodMesh = MyMeshes.GetLodMesh(sphereMesh, 0); MyMeshBuffers buffers = lodMesh.Buffers; immediateContext.SetVertexBuffer(0, buffers.VB0.Buffer, buffers.VB0.Stride); immediateContext.SetVertexBuffer(1, buffers.VB1.Buffer, buffers.VB1.Stride); immediateContext.SetIndexBuffer(buffers.IB.Buffer, buffers.IB.Format); immediateContext.PixelShader.SetSrv(0, cloudLayer.Value.TextureInfo.ColorMetalTexture); immediateContext.PixelShader.SetSrv(1, cloudLayer.Value.TextureInfo.AlphaTexture); immediateContext.PixelShader.SetSrv(2, cloudLayer.Value.TextureInfo.NormalGlossTexture); immediateContext.DrawIndexed(lodMesh.Info.IndicesNum, 0, 0); } immediateContext.PixelShader.SetSrv(0, null); immediateContext.PixelShader.SetSrv(1, null); immediateContext.PixelShader.SetSrv(2, null); immediateContext.SetDepthStencilState(null); immediateContext.SetBlendState(null); immediateContext.SetRasterizerState(null); immediateContext.SetRtv(null); }
private static unsafe void RenderSpotlights() { RC.SetRtv(MyGBuffer.Main.DepthStencil, MyDepthStencilAccess.ReadOnly, MyGBuffer.Main.LBuffer); RC.SetViewport(0, 0, MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); RC.SetPrimitiveTopology(PrimitiveTopology.TriangleList); if (MyStereoRender.Enable) { MyStereoRender.PSBindRawCB_FrameConstants(RC); MyStereoRender.SetViewport(RC); } var coneMesh = MyMeshes.GetMeshId(X.TEXT_("Models/Debug/Cone.mwm"), 1.0f); var buffers = MyMeshes.GetLodMesh(coneMesh, 0).Buffers; RC.SetVertexBuffer(0, buffers.VB0); RC.SetIndexBuffer(buffers.IB); RC.VertexShader.Set(m_spotlightProxyVs); RC.SetInputLayout(m_spotlightProxyIl); RC.PixelShader.Set(m_spotlightPsPixel); RC.SetRasterizerState(MyRasterizerStateManager.InvTriRasterizerState); var cb = MyCommon.GetObjectCB(sizeof(SpotlightConstants)); RC.AllShaderStages.SetConstantBuffer(1, cb); RC.PixelShader.SetSampler(13, MySamplerStateManager.Alphamask); RC.PixelShader.SetSampler(14, MySamplerStateManager.Shadowmap); RC.PixelShader.SetSampler(15, MySamplerStateManager.Shadowmap); int index = 0; int casterIndex = 0; foreach (var id in VisibleSpotlights) { SpotlightConstants spotlight = new SpotlightConstants(); var reflectorTexture = MyLights.WriteSpotlightConstants(id, ref spotlight); var mapping = MyMapping.MapDiscard(cb); mapping.WriteAndPosition(ref spotlight); mapping.Unmap(); RC.PixelShader.SetSrv(13, reflectorTexture); if (id.CastsShadowsThisFrame) { RC.PixelShader.SetSrv(14, MyRender11.DynamicShadows.ShadowmapsPool[casterIndex]); casterIndex++; } if (MyRender11.MultisamplingEnabled) { RC.SetDepthStencilState(MyDepthStencilStateManager.TestEdgeStencil, 0); RC.PixelShader.Set(m_spotlightPsPixel); } RC.DrawIndexed(MyMeshes.GetLodMesh(coneMesh, 0).Info.IndicesNum, 0, 0); if (MyRender11.MultisamplingEnabled) { RC.PixelShader.Set(m_spotlightPsSample); RC.SetDepthStencilState(MyDepthStencilStateManager.TestEdgeStencil, 0x80); RC.DrawIndexed(MyMeshes.GetLodMesh(coneMesh, 0).Info.IndicesNum, 0, 0); } index++; if (index >= SPOTLIGHTS_MAX) { break; } } if (MyRender11.MultisamplingEnabled) { RC.SetDepthStencilState(MyDepthStencilStateManager.DefaultDepthState); } RC.SetRasterizerState(null); RC.SetRtv(null); }
internal unsafe static void RenderSpotlights() { RC.BindDepthRT(MyGBuffer.Main.Get(MyGbufferSlot.DepthStencil), DepthStencilAccess.ReadOnly, MyGBuffer.Main.Get(MyGbufferSlot.LBuffer)); RC.DeviceContext.Rasterizer.SetViewport(0, 0, MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); RC.DeviceContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; var coneMesh = MyMeshes.GetMeshId(X.TEXT("Models/Debug/Cone.mwm")); var buffers = MyMeshes.GetLodMesh(coneMesh, 0).Buffers; RC.SetVB(0, buffers.VB0.Buffer, buffers.VB0.Stride); RC.SetIB(buffers.IB.Buffer, buffers.IB.Format); RC.SetVS(SpotlightProxyVs); RC.SetIL(SpotlightProxyIL); RC.SetRS(MyRender11.m_invTriRasterizerState); var cb = MyCommon.GetObjectCB(sizeof(SpotlightConstants)); RC.SetCB(1, cb); RC.DeviceContext.PixelShader.SetSampler(13, MyRender11.m_alphamaskSamplerState); RC.DeviceContext.PixelShader.SetSampler(14, MyRender11.m_shadowmapSamplerState); RC.DeviceContext.PixelShader.SetSampler(15, MyRender11.m_shadowmapSamplerState); int index = 0; int casterIndex = 0; foreach (var id in VisibleSpotlights) { MyLights.WriteSpotlightConstants(id, ref Spotlights[index]); var mapping = MyMapping.MapDiscard(cb); mapping.WriteAndPosition(ref Spotlights[index]); mapping.Unmap(); RC.DeviceContext.PixelShader.SetShaderResource(13, MyTextures.GetView(MyLights.Spotlights[id.Index].ReflectorTexture)); if (id.CastsShadowsThisFrame) { RC.DeviceContext.PixelShader.SetShaderResource(14, MyRender11.DynamicShadows.ShadowmapsPool[casterIndex].ShaderView); casterIndex++; } RC.SetPS(SpotlightPs_Pixel); if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.TestEdgeStencil, 0); } RC.DeviceContext.DrawIndexed(MyMeshes.GetLodMesh(coneMesh, 0).Info.IndicesNum, 0, 0); if (MyRender11.MultisamplingEnabled) { RC.SetPS(SpotlightPs_Sample); RC.SetDS(MyDepthStencilState.TestEdgeStencil, 0x80); RC.DeviceContext.DrawIndexed(MyMeshes.GetLodMesh(coneMesh, 0).Info.IndicesNum, 0, 0); } index++; if (index >= SPOTLIGHTS_MAX) { break; } } if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.DefaultDepthState); } RC.SetRS(null); }
internal unsafe static void Render() { var RC = MyImmediateRC.RC; if (Atmospheres.Count == 0 || !Enabled) { return; } var sphereMesh = MyMeshes.GetMeshId(X.TEXT("Models/Debug/Sphere.mwm")); var buffers = MyMeshes.GetLodMesh(sphereMesh, 0).Buffers; RC.SetVB(0, buffers.VB0.Buffer, buffers.VB0.Stride); RC.SetIB(buffers.IB.Buffer, buffers.IB.Format); RC.SetVS(m_proxyVs); RC.SetIL(m_proxyIL); RC.SetRS(null); RC.SetBS(MyRender11.BlendAtmosphere); var cb = MyCommon.GetObjectCB(sizeof(AtmosphereConstants)); RC.SetCB(1, cb); RC.DeviceContext.PixelShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MyRender11.m_shadowmapSamplerState); // depth, RC.BindGBufferForRead(0, MyGBuffer.Main); RC.BindDepthRT(MyGBuffer.Main.Get(MyGbufferSlot.DepthStencil), DepthStencilAccess.ReadOnly, MyGBuffer.Main.Get(MyGbufferSlot.LBuffer)); var indicesNum = MyMeshes.GetLodMesh(sphereMesh, 0).Info.IndicesNum; // sort by distance int i = Atmospheres.Count; foreach (var atmosphere in Atmospheres.OrderByDescending(x => (x.Value.WorldMatrix.Translation - MyEnvironment.CameraPosition).LengthSquared())) { var worldMatrix = atmosphere.Value.WorldMatrix; worldMatrix.Translation -= MyEnvironment.CameraPosition; var worldViewProj = ((Matrix)worldMatrix) * MyEnvironment.ViewProjectionAt0; double distance = worldMatrix.Translation.Length(); double atmosphereTop = atmosphere.Value.AtmosphereRadius * atmosphere.Value.Settings.AtmosphereTopModifier * atmosphere.Value.PlanetScaleFactor * atmosphere.Value.Settings.RayleighTransitionModifier; float rayleighHeight = atmosphere.Value.Settings.RayleighHeight; float t = 0.0f; if (distance > atmosphereTop) { if (distance > atmosphereTop * 2.0f) { t = 1.0f; } else { t = (float)((distance - atmosphereTop) / atmosphereTop); } } rayleighHeight = MathHelper.Lerp(atmosphere.Value.Settings.RayleighHeight, atmosphere.Value.Settings.RayleighHeightSpace, t); AtmosphereConstants constants = new AtmosphereConstants(); constants.WorldViewProj = Matrix.Transpose(worldViewProj); constants.PlanetCentre = (Vector3)worldMatrix.Translation; constants.AtmosphereRadius = atmosphere.Value.AtmosphereRadius * atmosphere.Value.Settings.AtmosphereTopModifier; // Raise the ground a bit for better sunsets constants.GroundRadius = atmosphere.Value.PlanetRadius * 1.01f * atmosphere.Value.Settings.SeaLevelModifier; constants.BetaRayleighScattering = atmosphere.Value.BetaRayleighScattering / atmosphere.Value.Settings.RayleighScattering; constants.BetaMieScattering = atmosphere.Value.BetaMieScattering / atmosphere.Value.Settings.MieColorScattering; constants.HeightScaleRayleighMie = atmosphere.Value.HeightScaleRayleighMie * new Vector2(rayleighHeight, atmosphere.Value.Settings.MieHeight); constants.MieG = atmosphere.Value.Settings.MieG; constants.PlanetScaleFactor = atmosphere.Value.PlanetScaleFactor; constants.AtmosphereScaleFactor = atmosphere.Value.AtmosphereScaleFactor; constants.Intensity = atmosphere.Value.Settings.Intensity; constants.FogIntensity = atmosphere.Value.Settings.FogIntensity; var mapping = MyMapping.MapDiscard(cb); mapping.WriteAndPosition(ref constants); mapping.Unmap(); var luts = AtmosphereLUT[atmosphere.Key]; RC.DeviceContext.PixelShader.SetShaderResources(5, luts.TransmittanceLut.ShaderView); bool inside = worldMatrix.Translation.Length() < atmosphere.Value.AtmosphereRadius * atmosphere.Value.PlanetScaleFactor; if (inside) { RC.SetRS(MyRender11.m_invTriRasterizerState); if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.TestEdgeStencil, 0); } else { RC.SetDS(MyDepthStencilState.IgnoreDepthStencil); } } else { RC.SetRS(null); if (MyRender11.MultisamplingEnabled) { RC.SetDS(MyDepthStencilState.TestDepthAndEdgeStencil, 0); } else { RC.SetDS(MyDepthStencilState.DepthTest); } } RC.SetPS(m_ps); RC.DeviceContext.DrawIndexed(indicesNum, 0, 0); if (MyRender11.MultisamplingEnabled) { if (inside) { RC.SetDS(MyDepthStencilState.TestEdgeStencil, 0x80); } else { RC.SetDS(MyDepthStencilState.TestDepthAndEdgeStencil, 0x80); } RC.SetPS(m_psPerSample); RC.DeviceContext.DrawIndexed(indicesNum, 0, 0); } i--; } RC.DeviceContext.PixelShader.SetShaderResources(5, null, null); RC.SetRS(null); RC.SetDS(null); }