internal static void RequestResources(ref MyVoxelMaterialDetailSet set) { MyFileTextureManager texManager = MyManagers.FileTextures; foreach (var filepath in set.ColorMetalXZnY_Filepaths) { texManager.GetTexture(filepath, MyFileTextureEnum.COLOR_METAL); } foreach (var filepath in set.ColorMetalY_Filepaths) { texManager.GetTexture(filepath, MyFileTextureEnum.COLOR_METAL); } foreach (var filepath in set.NormalGlossXZnY_Filepaths) { texManager.GetTexture(filepath, MyFileTextureEnum.NORMALMAP_GLOSS); } foreach (var filepath in set.NormalGlossY_Filepaths) { texManager.GetTexture(filepath, MyFileTextureEnum.NORMALMAP_GLOSS); } foreach (var filepath in set.ExtXZnY_Filepaths) { texManager.GetTexture(filepath, MyFileTextureEnum.EXTENSIONS); } foreach (var filepath in set.ExtY_Filepaths) { texManager.GetTexture(filepath, MyFileTextureEnum.EXTENSIONS); } }
internal unsafe static void RebuildMaterialFoliageTable() { var array = stackalloc MaterialFoliageConstantsElem[256]; int N = Table.Length; for (int i = 0; i < N; i++) { uint arraySize = 0; if (Table[i].FoliageColorTextureArray != null) { arraySize = (uint)Table[i].FoliageColorTextureArray.SubtexturesCount; } else { MyFileTextureManager texManager = MyManagers.FileTextures; var arrayTex = texManager.GetTexture(Table[i].FoliageArray_Texture, MyFileTextureEnum.COLOR_METAL, true); arraySize = (uint)((Texture2D)arrayTex.Resource).Description.ArraySize; } array[i] = new MaterialFoliageConstantsElem { Scale = Table[i].FoliageScale, ScaleVar = Table[i].FoliageScaleVariation, TexturesNum = arraySize }; } var mapping = MyMapping.MapDiscard(MyCommon.MaterialFoliageTableConstants); for (int arrayIndex = 0; arrayIndex < N; ++arrayIndex) { mapping.WriteAndPosition(ref array[arrayIndex]); } mapping.Unmap(); }
internal unsafe void RecordCommands(MyRenderableProxy proxy, IVertexBuffer stream, int voxelMatId) { if (stream == null) { return; } var foliageType = MyVoxelMaterials1.Table[voxelMatId].FoliageType; MyMapping mapping = MyMapping.MapDiscard(RC, proxy.ObjectBuffer); mapping.WriteAndPosition(ref proxy.NonVoxelObjectData); mapping.WriteAndPosition(ref proxy.CommonObjectData); mapping.Unmap(); RC.AllShaderStages.SetConstantBuffer(MyCommon.OBJECT_SLOT, proxy.ObjectBuffer); RC.GeometryShader.Set(m_GS[foliageType]); RC.PixelShader.Set(m_PS[foliageType]); if (MyVoxelMaterials1.Table[voxelMatId].FoliageColorTextureArray != null) { RC.AllShaderStages.SetSrv(0, MyVoxelMaterials1.Table[voxelMatId].FoliageColorTextureArray); RC.AllShaderStages.SetSrv(1, MyVoxelMaterials1.Table[voxelMatId].FoliageNormalTextureArray); } else { MyFileTextureManager texManager = MyManagers.FileTextures; RC.AllShaderStages.SetSrv(0, texManager.GetTexture(MyVoxelMaterials1.Table[voxelMatId].FoliageArray_Texture, MyFileTextureEnum.COLOR_METAL, true)); RC.AllShaderStages.SetSrv(1, texManager.GetTexture(MyVoxelMaterials1.Table[voxelMatId].FoliageArray_NormalTexture, MyFileTextureEnum.NORMALMAP_GLOSS, true)); } RC.SetVertexBuffer(0, stream); RC.DrawAuto(); }
static void BindResourcesCommon() { RC.SetRasterizerState(MyRasterizerStateManager.NocullRasterizerState); RC.AllShaderStages.SetRawSrv(30, m_SB.Srv); RC.AllShaderStages.SetConstantBuffer(2, m_cbCustomProjections); if (MyStereoRender.Enable && MyStereoRender.EnableUsingStencilMask) { RC.SetDepthStencilState(MyDepthStencilStateManager.StereoDefaultDepthState); } else { RC.SetDepthStencilState(MyDepthStencilStateManager.DefaultDepthState); } RC.AllShaderStages.SetConstantBuffer(4, MyRender11.DynamicShadows.ShadowCascades.CascadeConstantBuffer); RC.VertexShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MySamplerStateManager.Shadowmap); RC.VertexShader.SetSrv(MyCommon.CASCADES_SM_SLOT, MyRender11.DynamicShadows.ShadowCascades.CascadeShadowmapArray); RC.VertexShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); ISrvBindable skybox = MyRender11.IsIntelBrokenCubemapsWorkaround ? MyGeneratedTextureManager.IntelFallbackCubeTex : (ISrvBindable)MyManagers.EnvironmentProbe.Cubemap; RC.VertexShader.SetSrv(MyCommon.SKYBOX_IBL_SLOT, skybox); MyFileTextureManager texManager = MyManagers.FileTextures; RC.SetVertexBuffer(0, m_VB.Buffer, m_VB.Stride); RC.SetIndexBuffer(m_IB.Buffer, m_IB.Format); RC.SetInputLayout(m_inputLayout); }
internal static MyMaterialProxy_2 CreateProxy(ref MyMeshMaterialInfo info) { ISrvBindable A, B, C, D; if (!info.GeometryTextureRef.IsUsed) { MyFileTextureManager texManager = MyManagers.FileTextures; A = texManager.GetTexture(info.ColorMetal_Texture, MyFileTextureEnum.COLOR_METAL); B = texManager.GetTexture(info.NormalGloss_Texture, MyFileTextureEnum.NORMALMAP_GLOSS); C = texManager.GetTexture(info.Extensions_Texture, MyFileTextureEnum.EXTENSIONS); D = texManager.GetTexture(info.Alphamask_Texture, MyFileTextureEnum.ALPHAMASK); } else { A = info.GeometryTextureRef.ColorMetalTexture; B = info.GeometryTextureRef.NormalGlossTexture; C = info.GeometryTextureRef.ExtensionTexture; D = info.GeometryTextureRef.AlphamaskTexture; } var materialSrvs = new MySrvTable { BindFlag = MyBindFlag.BIND_PS, StartSlot = 0, Srvs = new ISrvBindable[] { A, B, C, D }, Version = info.Id.GetHashCode() }; return (new MyMaterialProxy_2 { MaterialSrvs = materialSrvs }); }
internal static void RequestResources(ref MyMeshMaterialInfo info) { if (!info.GeometryTextureRef.IsUsed) { MyFileTextureManager texManager = MyManagers.FileTextures; texManager.GetTexture(info.ColorMetal_Texture, MyFileTextureEnum.COLOR_METAL, false, info.Facing == MyFacingEnum.Impostor); texManager.GetTexture(info.NormalGloss_Texture, MyFileTextureEnum.NORMALMAP_GLOSS); texManager.GetTexture(info.Extensions_Texture, MyFileTextureEnum.EXTENSIONS); texManager.GetTexture(info.Alphamask_Texture, MyFileTextureEnum.ALPHAMASK); } else { if (info.GeometryTextureRef.ColorMetalTexture != null) { info.GeometryTextureRef.ColorMetalTexture.Update(); } if (info.GeometryTextureRef.NormalGlossTexture != null) { info.GeometryTextureRef.NormalGlossTexture.Update(); } if (info.GeometryTextureRef.ExtensionTexture != null) { info.GeometryTextureRef.ExtensionTexture.Update(); } if (info.GeometryTextureRef.AlphamaskTexture != null) { info.GeometryTextureRef.AlphamaskTexture.Update(); } } }
internal void LoadContent() { MyFileTextureManager texManager = MyManagers.FileTextures; foreach (var entry in m_bitmapInfoByID) { m_bitmapTextureById[entry.Key] = texManager.GetTexture(Path.Combine(m_fontDirectory, entry.Value.strFilename), MyFileTextureEnum.GUI, true); } }
internal static void Draw(bool draw = true) { try { MyGpuProfiler.IC_BeginBlock("Draw"); GetRenderProfiler().StartProfilingBlock("ProcessMessages"); MyGpuProfiler.IC_BeginBlock("ProcessMessageQueue"); TransferLocalMessages(); ProcessMessageQueue(); MyGpuProfiler.IC_EndBlock(); GetRenderProfiler().EndProfilingBlock(); if (draw) { m_drawScene = false; DispatchDrawQueue(); if (m_drawScene) { DrawScene(); } if (!(MyRender11.Settings.OffscreenSpritesRendering && m_drawScene)) { ProcessDrawQueue(); DrawSprites(MyRender11.Backbuffer); } MyFileTextureManager texManager = MyManagers.FileTextures; texManager.LoadAllRequested(); if (m_texturesToRender.Count > 0) { VRage.Render11.PostprocessStage.MySaveExportedTextures.RenderColoredTextures(m_texturesToRender); } } MyLinesRenderer.Clear(); MySpritesRenderer.Clear(); m_drawQueue.Clear(); MyGpuProfiler.IC_EndBlock(); } catch (SharpDXException e) { MyRender11.Log.IncreaseIndent(); MyRender11.Log.WriteLine(" " + e); if (e.Descriptor == SharpDX.DXGI.ResultCode.DeviceRemoved) { MyRender11.Log.WriteLine("Reason: " + Device.DeviceRemovedReason); } MyRender11.Log.DecreaseIndent(); throw; } }
internal static void RequestResources(ref MyMeshMaterialInfo info) { MyFileTextureManager texManager = MyManagers.FileTextures; string contentPath = info.ContentPath; texManager.GetTexture(GetFilepath(contentPath, info.ColorMetal_Texture.ToString()), MyFileTextureEnum.COLOR_METAL, false, info.Facing == MyFacingEnum.Impostor); texManager.GetTexture(GetFilepath(contentPath, info.NormalGloss_Texture.ToString()), MyFileTextureEnum.NORMALMAP_GLOSS); texManager.GetTexture(GetFilepath(contentPath, info.Extensions_Texture.ToString()), MyFileTextureEnum.EXTENSIONS); texManager.GetTexture(GetFilepath(contentPath, info.Alphamask_Texture.ToString()), MyFileTextureEnum.ALPHAMASK); }
//internal static void ReleaseResources() //{ // for (int i = 0; i < Table.Length; i++) // { // MyFileArrayTextureManager manager = MyManagers.FileArrayTextures; // if (Table[i].FoliageColorTextureArray != null) // manager.DisposeTex(ref Table[i].FoliageColorTextureArray); // if (Table[i].FoliageNormalTextureArray != null) // manager.DisposeTex(ref Table[i].FoliageNormalTextureArray); // } //} internal static void OnResourcesRequesting() { foreach (var id in MaterialQueryResourcesTable) { // query all textures MyVoxelMaterialDetailSet.RequestResources(ref Table[id].Resource); //MyTextureManager.GetTexture(Table[id].FoliageArray_Texture); MyFileTextureManager texManager = MyManagers.FileTextures; texManager.GetTexture(Table[id].FoliageArray_Texture, MyFileTextureEnum.COLOR_METAL); } }
internal static void RequestResources(ref MyVoxelMaterialDetailSet set) { MyFileTextureManager texManager = MyManagers.FileTextures; texManager.GetTexture(set.ColorMetalXZnY_Texture.ToString(), MyFileTextureEnum.COLOR_METAL); texManager.GetTexture(set.ColorMetalpY_Texture.ToString(), MyFileTextureEnum.COLOR_METAL); texManager.GetTexture(set.NormalGlossXZnY_Texture.ToString(), MyFileTextureEnum.NORMALMAP_GLOSS); texManager.GetTexture(set.NormalGlossY_Texture.ToString(), MyFileTextureEnum.NORMALMAP_GLOSS); texManager.GetTexture(set.ExtXZnY_Texture.ToString(), MyFileTextureEnum.EXTENSIONS); texManager.GetTexture(set.ExtY_Texture.ToString(), MyFileTextureEnum.EXTENSIONS); }
private static void RenderDirectionalEnvironmentLight(ISrvTexture postProcessedShadows, IRtvTexture ambientOcclusion) { PixelShaderId directionalPixelShader; MyShadowsQuality shadowsQuality = MyRender11.Settings.User.ShadowQuality.GetShadowsQuality(); if (!MyRender11.Settings.EnableShadows || !MyRender11.DebugOverrides.Shadows || shadowsQuality == MyShadowsQuality.DISABLED) { if (m_directionalEnvironmentLightNoShadow == PixelShaderId.NULL) { m_directionalEnvironmentLightNoShadow = MyShaders.CreatePs("Lighting/LightDir.hlsl", new[] { new ShaderMacro("NO_SHADOWS", null) }); } directionalPixelShader = m_directionalEnvironmentLightNoShadow; } else { directionalPixelShader = m_directionalEnvironmentLightPixel; } //context.VertexShader.Set(MyCommon.FullscreenShader.VertexShader); RC.PixelShader.Set(directionalPixelShader); RC.AllShaderStages.SetConstantBuffer(4, MyRender11.DynamicShadows.ShadowCascades.CascadeConstantBuffer); RC.PixelShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MySamplerStateManager.Shadowmap); MyFileTextureManager texManager = MyManagers.FileTextures; RC.PixelShader.SetSrv(MyCommon.SKYBOX_SLOT, texManager.GetTexture(MyRender11.Environment.Data.Skybox, MyFileTextureEnum.CUBEMAP, true)); ISrvBindable skybox = MyRender11.IsIntelBrokenCubemapsWorkaround ? MyGeneratedTextureManager.IntelFallbackCubeTex : (ISrvBindable)MyManagers.EnvironmentProbe.Cubemap; RC.PixelShader.SetSrv(MyCommon.SKYBOX_IBL_SLOT, skybox); RC.PixelShader.SetSrv(MyCommon.CASCADES_SM_SLOT, MyRender11.DynamicShadows.ShadowCascades.CascadeShadowmapArray); RC.PixelShader.SetSrv(MyCommon.SHADOW_SLOT, postProcessedShadows); RC.PixelShader.SetSrv(MyCommon.AMBIENT_BRDF_LUT_SLOT, MyCommon.GetAmbientBrdfLut()); RC.PixelShader.SetSrv(MyCommon.AO_SLOT, ambientOcclusion); MyScreenPass.RunFullscreenPixelFreq(MyGBuffer.Main.LBuffer); if (MyRender11.MultisamplingEnabled) { RC.PixelShader.Set(m_directionalEnvironmentLightSample); MyScreenPass.RunFullscreenSampleFreq(MyGBuffer.Main.LBuffer); } RC.PixelShader.SetSrv(MyCommon.SHADOW_SLOT, null); }
internal static unsafe void RunForwardPostprocess(IRtvBindable rt, IDsvBindable depthDsv, ISrvBindable depthSrv, ref Matrix viewMatrix, ref Matrix projMatrix) { MyGpuProfiler.IC_BeginBlock("Postprocess"); var viewMatrixT = Matrix.Transpose(viewMatrix); var projMatrixT = Matrix.Transpose(projMatrix); var mapping = MyMapping.MapDiscard(RC, TransformConstants); mapping.WriteAndPosition(ref viewMatrixT); mapping.WriteAndPosition(ref projMatrixT); mapping.WriteAndPosition(ref MyRender11.Environment.Data.EnvironmentLight.SunLightDirection); mapping.Unmap(); RC.AllShaderStages.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.AllShaderStages.SetConstantBuffer(MyCommon.OBJECT_SLOT, TransformConstants); RC.SetDepthStencilState(MyDepthStencilStateManager.IgnoreDepthStencil); RC.SetRtv(rt); RC.PixelShader.SetSrv(0, depthSrv); MyFileTextureManager texManager = MyManagers.FileTextures; RC.PixelShader.SetSrv(MyCommon.SKYBOX_SLOT, texManager.GetTexture(MyRender11.Environment.Data.Skybox, MyFileTextureEnum.CUBEMAP, true)); RC.PixelShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); RC.PixelShader.Set(m_ps); MyScreenPass.DrawFullscreenQuad(new MyViewport(m_viewportSize, m_viewportSize)); MyGpuProfiler.IC_EndBlock(); var nearestAtmosphereId = MyAtmosphereRenderer.GetNearestAtmosphereId(); if (nearestAtmosphereId != null) { MyGpuProfiler.IC_BeginBlock("Atmosphere"); RC.PixelShader.SetSrv(0, depthSrv); var viewProj = viewMatrix * projMatrix; MyAtmosphereRenderer.RenderEnvProbe(MyRender11.Environment.Matrices.CameraPosition, ref viewProj, nearestAtmosphereId.Value); MyGpuProfiler.IC_EndBlock(); } RC.SetRtv(null); }
public static void RegisterMaterials(Dictionary <string, List <MyDecalMaterialDesc> > descriptions) { MyFileTextureManager texManager = MyManagers.FileTextures; m_materials.Clear(); foreach (var pair in descriptions) { List <MyDecalTextures> list = new List <MyDecalTextures>(); foreach (var desc in pair.Value) { list.Add(new MyDecalTextures() { DecalType = MyMeshMaterials1.GetMaterialTextureTypes(desc.ColorMetalTexture, desc.NormalmapTexture, desc.ExtensionsTexture, null), ColorMetalTexture = texManager.GetTexture(desc.ColorMetalTexture, MyFileTextureEnum.COLOR_METAL), NormalmapTexture = texManager.GetTexture(desc.NormalmapTexture, MyFileTextureEnum.NORMALMAP_GLOSS), ExtensionsTexture = texManager.GetTexture(desc.ExtensionsTexture, MyFileTextureEnum.EXTENSIONS), AlphamaskTexture = texManager.GetTexture(desc.AlphamaskTexture, MyFileTextureEnum.ALPHAMASK), }); } m_materials[X.TEXT_(pair.Key)] = list; } }
internal static MyMaterialProxy_2 CreateProxy(ref MyMeshMaterialInfo info) { MyFileTextureManager texManager = MyManagers.FileTextures; string contentPath = info.ContentPath; var A = texManager.GetTexture(GetFilepath(contentPath, info.ColorMetal_Texture.ToString()), MyFileTextureEnum.COLOR_METAL); var B = texManager.GetTexture(GetFilepath(contentPath, info.NormalGloss_Texture.ToString()), MyFileTextureEnum.NORMALMAP_GLOSS); var C = texManager.GetTexture(GetFilepath(contentPath, info.Extensions_Texture.ToString()), MyFileTextureEnum.EXTENSIONS); var D = texManager.GetTexture(GetFilepath(contentPath, info.Alphamask_Texture.ToString()), MyFileTextureEnum.ALPHAMASK); var materialSrvs = new MySrvTable { BindFlag = MyBindFlag.BIND_PS, StartSlot = 0, Srvs = new ShaderResourceView[] { A.Srv, B.Srv, C.Srv, D.Srv }, Version = info.Id.GetHashCode() }; return (new MyMaterialProxy_2 { MaterialSrvs = materialSrvs }); }
static bool GatherInternal(Func <MyBillboard, bool> handleWindow) { m_batches.Clear(); // counting sorted billboards m_sortedCount = 0; m_unsortedCount = 0; m_windowCount = 0; PreGatherList(MyRenderProxy.BillboardsRead); PreGatherList(m_billboardsOnce); if (BillboardCount == 0) { return(false); } ResizeStorage(); int sortedIndex = 0; int unsortedIndex = 0; GatherList(MyRenderProxy.BillboardsRead, ref sortedIndex, ref unsortedIndex); GatherList(m_billboardsOnce, ref sortedIndex, ref unsortedIndex); Array.Sort(m_sortedBuffer, 0, m_sortedCount); int i = 0; bool resetBindings = false; int windowidx = 0; var N = BillboardCountSafe; int currentOffset = 0; ISrvBindable prevTex = null; ISrvBindable batchTex = null; MyTransparentMaterial prevMaterial = null; while (true) { if (i == N) { AddBatch(N, currentOffset, prevTex, prevMaterial); break; } MyBillboard billboard = m_sortedBuffer[i]; MyTransparentMaterial material = MyTransparentMaterials.GetMaterial(billboard.Material); if (material.UseAtlas) { var atlasItem = m_atlas.FindElement(material.Texture); batchTex = atlasItem.Texture; } else { MyFileTextureManager texManager = MyManagers.FileTextures; switch (material.TextureType) { case MyTransparentMaterialTextureType.FileTexture: batchTex = texManager.GetTexture(material.Texture, MyFileTextureEnum.GUI, true); break; case MyTransparentMaterialTextureType.RenderTarget: batchTex = MyRender11.DrawSpritesOffscreen(material.Name, material.TargetSize.X, material.TargetSize.Y); resetBindings = true; break; default: throw new Exception(); } } bool closeBatch = i > 0 && (batchTex != prevTex || i == m_sortedCount); if (closeBatch) { AddBatch(i, currentOffset, prevTex, prevMaterial); currentOffset = i; } var billboardData = new MyBillboardData(); var billboardVertices = new MyBillboardVertexData(); billboardData.CustomProjectionID = billboard.CustomViewProjection; billboardData.Color = billboard.Color; billboardData.Color.X *= billboard.ColorIntensity; billboardData.Color.Y *= billboard.ColorIntensity; billboardData.Color.Z *= billboard.ColorIntensity; billboardData.AlphaCutout = billboard.AlphaCutout; billboardData.AlphaSaturation = material.AlphaSaturation; billboardData.SoftParticleDistanceScale = billboard.SoftParticleDistanceScale * material.SoftParticleDistanceScale; billboardData.Reflective = billboard.Reflectivity; Vector3D pos0 = billboard.Position0; Vector3D pos1 = billboard.Position1; Vector3D pos2 = billboard.Position2; Vector3D pos3 = billboard.Position3; if (billboard.ParentID != -1) { if (MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID).WorldMatrix; Vector3D.Transform(ref pos0, ref matrix, out pos0); Vector3D.Transform(ref pos1, ref matrix, out pos1); Vector3D.Transform(ref pos2, ref matrix, out pos2); Vector3D.Transform(ref pos3, ref matrix, out pos3); } } MyEnvironmentMatrices envMatrices = MyRender11.Environment.Matrices; if (MyStereoRender.Enable) { if (MyStereoRender.RenderRegion == MyStereoRegion.LEFT) { envMatrices = MyStereoRender.EnvMatricesLeftEye; } else if (MyStereoRender.RenderRegion == MyStereoRegion.RIGHT) { envMatrices = MyStereoRender.EnvMatricesRightEye; } } if (billboard.CustomViewProjection != -1) { var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection]; //pos0 -= envMatrices.CameraPosition; //pos1 -= envMatrices.CameraPosition; //pos2 -= envMatrices.CameraPosition; //pos3 -= envMatrices.CameraPosition; } else { pos0 -= envMatrices.CameraPosition; pos1 -= envMatrices.CameraPosition; pos2 -= envMatrices.CameraPosition; pos3 -= envMatrices.CameraPosition; } var normal = Vector3.Cross(pos1 - pos0, pos2 - pos0); normal.Normalize(); billboardData.Normal = normal; billboardVertices.V0.Position = pos0; billboardVertices.V1.Position = pos1; billboardVertices.V2.Position = pos2; billboardVertices.V3.Position = pos3; var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y); var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y); if (material.UseAtlas) { var atlasItem = m_atlas.FindElement(material.Texture); uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); } billboardVertices.V0.Texcoord = new HalfVector2(uv0); billboardVertices.V1.Texcoord = new HalfVector2(uv1); billboardVertices.V2.Texcoord = new HalfVector2(uv2); billboardVertices.V3.Texcoord = new HalfVector2(uv3); pos0.AssertIsValid(); pos1.AssertIsValid(); pos2.AssertIsValid(); pos3.AssertIsValid(); MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard; if (triBillboard != null) { billboardVertices.V3.Position = pos2; // second triangle will die in rasterizer billboardVertices.V0.Texcoord = new HalfVector2(triBillboard.UV0); billboardVertices.V1.Texcoord = new HalfVector2(triBillboard.UV1); billboardVertices.V2.Texcoord = new HalfVector2(triBillboard.UV2); billboardData.Normal = triBillboard.Normal0; } m_arrayDataBillboards.Data[i] = billboardData; m_arrayDataBillboards.Vertex[i] = billboardVertices; if (billboard.Window && handleWindow(billboard)) { m_sorteWindowIndices[windowidx] = i; windowidx++; } prevTex = batchTex; prevMaterial = material; i++; } // Sort windows data from closer to farest int windowCount = WindowCountSafe; Array.Sort(m_sorteWindowIndices, 0, windowCount, BillboardComparer); for (int it = 0; it < windowCount; it++) { m_arrayDataWindows.Data[it] = m_arrayDataBillboards.Data[m_sorteWindowIndices[it]]; m_arrayDataWindows.Vertex[it] = m_arrayDataBillboards.Vertex[m_sorteWindowIndices[it]]; } return(resetBindings); }
internal static void RenderColoredTextures(List <renderColoredTextureProperties> texturesToRender) { if (texturesToRender.Count == 0) { return; } if (!m_initialized) { Init(); } const int RENDER_TEXTURE_RESOLUTION = 512; RC.SetBlendState(null); RC.SetInputLayout(null); RC.PixelShader.Set(m_ps); RC.AllShaderStages.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.AllShaderStages.SetConstantBuffer(1, m_cb); MyBorrowedRwTextureManager rwTexManager = MyManagers.RwTexturesPool; MyFileTextureManager fileTexManager = MyManagers.FileTextures; foreach (var texture in texturesToRender) { ISrvBindable tex = fileTexManager.GetTexture(texture.TextureName, MyFileTextureEnum.COLOR_METAL, true); if (tex == null) { continue; } Vector2 texSize = tex.Size; Vector2I renderTargetResolution = new Vector2I(RENDER_TEXTURE_RESOLUTION, RENDER_TEXTURE_RESOLUTION); if (texSize.Y > 0) { if (texSize.Y < RENDER_TEXTURE_RESOLUTION) { renderTargetResolution.X = (int)texSize.X; renderTargetResolution.Y = (int)texSize.Y; } else { renderTargetResolution.X *= (int)(texSize.X / texSize.Y); } } MyViewport viewport = new MyViewport(renderTargetResolution.X, renderTargetResolution.Y); IBorrowedRtvTexture renderTexture = rwTexManager.BorrowRtv("MySaveExportedTextures.RenderColoredTextures", renderTargetResolution.X, renderTargetResolution.Y, SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb, 1, 0); RC.SetRtv(renderTexture); // Set color var mapping = MyMapping.MapDiscard(m_cb); Vector4 color = new Vector4(texture.ColorMaskHSV, 1); mapping.WriteAndPosition(ref color); mapping.Unmap(); // Set texture RC.PixelShader.SetSrv(0, tex); // Draw MyScreenPass.DrawFullscreenQuad(viewport); // Save to file MyTextureData.ToFile(renderTexture, texture.PathToSave, ImageFileFormat.Png); renderTexture.Release(); } texturesToRender.Clear(); RC.SetRtv(null); RC.PixelShader.SetSrvs(0, MyGBuffer.Main); }
private static void ProcessDrawMessage(MyRenderMessageBase drawMessage) { switch (drawMessage.MessageType) { case MyRenderMessageEnum.SpriteScissorPush: { var msg = drawMessage as MyRenderMessageSpriteScissorPush; MySpritesRenderer.ScissorStackPush(msg.ScreenRectangle); break; } case MyRenderMessageEnum.SpriteScissorPop: { MySpritesRenderer.ScissorStackPop(); break; } case MyRenderMessageEnum.DrawSprite: { MyRenderMessageDrawSprite sprite = (MyRenderMessageDrawSprite)drawMessage; MyFileTextureManager texManager = MyManagers.FileTextures; MySpritesRenderer.AddSingleSprite(texManager.GetTexture(sprite.Texture, MyFileTextureEnum.GUI, waitTillLoaded: sprite.WaitTillLoaded), sprite.Color, sprite.Origin, sprite.RightVector, sprite.SourceRectangle, sprite.DestinationRectangle); break; } case MyRenderMessageEnum.DrawSpriteNormalized: { MyRenderMessageDrawSpriteNormalized sprite = (MyRenderMessageDrawSpriteNormalized)drawMessage; var rotation = sprite.Rotation; if (sprite.RotationSpeed != 0) { rotation += sprite.RotationSpeed * (float)(MyRender11.CurrentDrawTime - MyRender11.CurrentUpdateTime).Seconds; } Vector2 rightVector = rotation != 0f ? new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) : sprite.RightVector; int safeGuiSizeY = MyRender11.ResolutionI.Y; int safeGuiSizeX = (int)(safeGuiSizeY * 1.3333f); // This will mantain same aspect ratio for GUI elements var safeGuiRectangle = new VRageMath.Rectangle(MyRender11.ResolutionI.X / 2 - safeGuiSizeX / 2, 0, safeGuiSizeX, safeGuiSizeY); var safeScreenScale = (float)safeGuiSizeY / MyRenderGuiConstants.REFERENCE_SCREEN_HEIGHT; float fixedScale = sprite.Scale * safeScreenScale; var tex = MyManagers.FileTextures.GetTexture(sprite.Texture, MyFileTextureEnum.GUI, true); var normalizedCoord = sprite.NormalizedCoord; var screenCoord = new Vector2(safeGuiRectangle.Left + safeGuiRectangle.Width * normalizedCoord.X, safeGuiRectangle.Top + safeGuiRectangle.Height * normalizedCoord.Y); Vector2 sizeInPixels = tex.Size; var sizeInPixelsScaled = sizeInPixels * fixedScale; Vector2 alignedScreenCoord = screenCoord; var drawAlign = sprite.DrawAlign; if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP) { // Nothing to do as position is already at this point } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER) { // Move position to the texture center alignedScreenCoord -= sizeInPixelsScaled / 2.0f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP) { alignedScreenCoord.X -= sizeInPixelsScaled.X / 2.0f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM) { alignedScreenCoord.X -= sizeInPixelsScaled.X / 2.0f; alignedScreenCoord.Y -= sizeInPixelsScaled.Y; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_BOTTOM) { alignedScreenCoord -= sizeInPixelsScaled; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER) { alignedScreenCoord.Y -= sizeInPixelsScaled.Y / 2.0f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_CENTER) { alignedScreenCoord.X -= sizeInPixelsScaled.X; alignedScreenCoord.Y -= sizeInPixelsScaled.Y / 2.0f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_BOTTOM) { alignedScreenCoord.Y -= sizeInPixelsScaled.Y; // *0.75f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_TOP) { alignedScreenCoord.X -= sizeInPixelsScaled.X; } screenCoord = alignedScreenCoord; var rect = new RectangleF(screenCoord.X, screenCoord.Y, fixedScale * sizeInPixels.X, fixedScale * sizeInPixels.Y); Vector2 origin; if (sprite.OriginNormalized.HasValue) { origin = sprite.OriginNormalized.Value * sizeInPixels; } else { origin = sizeInPixels / 2; } sprite.OriginNormalized = sprite.OriginNormalized ?? new Vector2(0.5f); MyFileTextureManager texManager = MyManagers.FileTextures; MySpritesRenderer.AddSingleSprite(texManager.GetTexture(sprite.Texture, MyFileTextureEnum.GUI, waitTillLoaded: sprite.WaitTillLoaded), sprite.Color, origin, rightVector, null, rect); break; } case MyRenderMessageEnum.DrawSpriteAtlas: { MyRenderMessageDrawSpriteAtlas sprite = (MyRenderMessageDrawSpriteAtlas)drawMessage; MyFileTextureManager texManager = MyManagers.FileTextures; var tex = texManager.GetTexture(sprite.Texture, MyFileTextureEnum.GUI, true); var textureSize = tex.Size; Rectangle?sourceRect = new Rectangle( (int)(textureSize.X * sprite.TextureOffset.X), (int)(textureSize.Y * sprite.TextureOffset.Y), (int)(textureSize.X * sprite.TextureSize.X), (int)(textureSize.Y * sprite.TextureSize.Y)); VRageMath.RectangleF destRect = new VRageMath.RectangleF( (sprite.Position.X) * sprite.Scale.X, (sprite.Position.Y) * sprite.Scale.Y, sprite.HalfSize.X * sprite.Scale.X * 2, sprite.HalfSize.Y * sprite.Scale.Y * 2); Vector2 origin = new Vector2(textureSize.X * sprite.TextureSize.X * 0.5f, textureSize.Y * sprite.TextureSize.Y * 0.5f); MySpritesRenderer.AddSingleSprite(texManager.GetTexture(sprite.Texture, MyFileTextureEnum.GUI, true), sprite.Color, origin, sprite.RightVector, sourceRect, destRect); break; } case MyRenderMessageEnum.DrawString: { var message = drawMessage as MyRenderMessageDrawString; var font = MyRender11.GetFont(message.FontIndex); font.DrawString( message.ScreenCoord, message.ColorMask, message.Text, message.ScreenScale, message.ScreenMaxWidth); break; } default: throw new Exception(); } }
unsafe static void DrawBatches(MyRenderContext rc, MyStringId material, int matIndex, bool transparent) { if (m_jobs.Count == 0) { return; } var matDesc = m_materials[material][matIndex]; rc.PixelShader.SetSrv(0, MyGBuffer.Main.DepthStencil.SrvDepth); rc.PixelShader.SetSrv(1, MyGlobalResources.Gbuffer1Copy); if (transparent) { rc.PixelShader.Set(m_psColorMapTransparent); } else { rc.SetRtvs(MyGBuffer.Main, MyDepthStencilAccess.ReadOnly); MyFileTextureEnum type = matDesc.DecalType; switch (type) { case MyFileTextureEnum.NORMALMAP_GLOSS: rc.PixelShader.Set(m_psNormalMap); break; case MyFileTextureEnum.COLOR_METAL: rc.PixelShader.Set(m_psColorMap); break; case MyFileTextureEnum.COLOR_METAL | MyFileTextureEnum.NORMALMAP_GLOSS: rc.PixelShader.Set(m_psNormalColorMap); break; case MyFileTextureEnum.COLOR_METAL | MyFileTextureEnum.NORMALMAP_GLOSS | MyFileTextureEnum.EXTENSIONS: rc.PixelShader.Set(m_psNormalColorExtMap); break; default: throw new Exception("Unknown decal type"); } MyMeshMaterials1.BindMaterialTextureBlendStates(rc, type); } // factor 1 makes overwriting of gbuffer color & subtracting from ao MyFileTextureManager texManager = MyManagers.FileTextures; rc.PixelShader.SetSrv(3, texManager.GetTexture(matDesc.AlphamaskTexture, MyFileTextureEnum.ALPHAMASK)); rc.PixelShader.SetSrv(4, texManager.GetTexture(matDesc.ColorMetalTexture, MyFileTextureEnum.COLOR_METAL)); rc.PixelShader.SetSrv(5, texManager.GetTexture(matDesc.NormalmapTexture, MyFileTextureEnum.NORMALMAP_GLOSS)); rc.PixelShader.SetSrv(6, texManager.GetTexture(matDesc.ExtensionsTexture, MyFileTextureEnum.EXTENSIONS)); var decalCb = MyCommon.GetObjectCB(sizeof(MyDecalConstants) * DECAL_BATCH_SIZE); int batchCount = m_jobs.Count / DECAL_BATCH_SIZE + 1; int offset = 0; for (int i1 = 0; i1 < batchCount; i1++) { var mapping = MyMapping.MapDiscard(decalCb); int leftDecals = m_jobs.Count - offset; int decalCount = leftDecals > DECAL_BATCH_SIZE ? DECAL_BATCH_SIZE : leftDecals; for (int i2 = 0; i2 < decalCount; ++i2) { MyDecalConstants constants = new MyDecalConstants(); EncodeJobConstants(i2 + offset, ref constants); mapping.WriteAndPosition(ref constants); } mapping.Unmap(); // Draw a box without buffer: 36 vertices -> 12 triangles. 2 triangles per face -> 6 faces MyImmediateRC.RC.DrawIndexed(36 * decalCount, 0, 0); offset += DECAL_BATCH_SIZE; } }
internal static ISrvBindable GetAmbientBrdfLut() { MyFileTextureManager texManager = MyManagers.FileTextures; return(texManager.GetTexture("Textures/Miscellaneous/ambient_brdf.dds", MyFileTextureEnum.CUSTOM, true)); }
internal unsafe static void RunForwardPostprocess(IRtvBindable rt, ISrvBindable depth, ref Matrix viewMatrix, uint?atmosphereId) { MyGpuProfiler.IC_BeginBlock("Postprocess"); var transpose = Matrix.Transpose(viewMatrix); var mapping = MyMapping.MapDiscard(RC, MyCommon.ProjectionConstants); mapping.WriteAndPosition(ref transpose); mapping.Unmap(); RC.AllShaderStages.SetConstantBuffer(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.AllShaderStages.SetConstantBuffer(MyCommon.PROJECTION_SLOT, MyCommon.ProjectionConstants); RC.SetDepthStencilState(MyDepthStencilStateManager.IgnoreDepthStencil); RC.SetRtv(rt); RC.PixelShader.SetSrv(0, depth); MyFileTextureManager texManager = MyManagers.FileTextures; RC.PixelShader.SetSrv(MyCommon.SKYBOX_SLOT, texManager.GetTexture(MyRender11.Environment.Data.Skybox, MyFileTextureEnum.CUBEMAP, true)); RC.PixelShader.SetSamplers(0, MySamplerStateManager.StandardSamplers); RC.PixelShader.Set(m_ps); MyScreenPass.DrawFullscreenQuad(new MyViewport(m_viewportSize, m_viewportSize)); MyGpuProfiler.IC_EndBlock(); MyGpuProfiler.IC_BeginBlock("Atmosphere"); if (atmosphereId != null) { var atmosphere = MyAtmosphereRenderer.GetAtmosphere(atmosphereId.Value); var constants = new AtmosphereConstants(); //TODO(AF) These values are computed in MyAtmosphere as well. Find a way to remove the duplication var worldMatrix = atmosphere.WorldMatrix; worldMatrix.Translation -= MyRender11.Environment.Matrices.CameraPosition; double distance = worldMatrix.Translation.Length(); double atmosphereTop = atmosphere.AtmosphereRadius * atmosphere.Settings.AtmosphereTopModifier * atmosphere.PlanetScaleFactor * atmosphere.Settings.RayleighTransitionModifier; float rayleighHeight = atmosphere.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.Settings.RayleighHeight, atmosphere.Settings.RayleighHeightSpace, t); constants.PlanetCentre = (Vector3)worldMatrix.Translation; constants.AtmosphereRadius = atmosphere.AtmosphereRadius * atmosphere.Settings.AtmosphereTopModifier; constants.GroundRadius = atmosphere.PlanetRadius * 1.01f * atmosphere.Settings.SeaLevelModifier; constants.BetaRayleighScattering = atmosphere.BetaRayleighScattering / atmosphere.Settings.RayleighScattering; constants.BetaMieScattering = atmosphere.BetaMieScattering / atmosphere.Settings.MieColorScattering; constants.HeightScaleRayleighMie = atmosphere.HeightScaleRayleighMie * new Vector2(rayleighHeight, atmosphere.Settings.MieHeight); constants.MieG = atmosphere.Settings.MieG; constants.PlanetScaleFactor = atmosphere.PlanetScaleFactor; constants.AtmosphereScaleFactor = atmosphere.AtmosphereScaleFactor; constants.Intensity = atmosphere.Settings.Intensity; constants.FogIntensity = atmosphere.Settings.FogIntensity; var cb = MyCommon.GetObjectCB(sizeof(AtmosphereConstants)); mapping = MyMapping.MapDiscard(RC, cb); mapping.WriteAndPosition(ref constants); mapping.Unmap(); RC.SetBlendState(MyBlendStateManager.BlendAdditive); RC.PixelShader.SetConstantBuffer(2, cb); RC.PixelShader.SetSrv(2, MyAtmosphereRenderer.GetAtmosphereLuts(atmosphereId.Value).TransmittanceLut); RC.PixelShader.Set(m_atmosphere); MyScreenPass.DrawFullscreenQuad(new MyViewport(MyEnvironmentProbe.CubeMapResolution, MyEnvironmentProbe.CubeMapResolution)); } MyGpuProfiler.IC_EndBlock(); RC.SetRtv(null); }
internal static void CreateCloudLayer( uint ID, Vector3D centerPoint, double altitude, double minScaledAltitude, bool scalingEnabled, double fadeOutRelativeAltitudeStart, double fadeOutRelativeAltitudeEnd, float applyFogRelativeDistance, double maxPlanetHillRadius, string model, List <string> textures, Vector3D rotationAxis, float angularVelocity, float radiansAroundAxis) { MeshId mesh = MyMeshes.GetMeshId(X.TEXT_(model), 1.0f); MyCloudLayer.MyCloudTextureInfo textureInfo; if (textures != null && textures.Count > 0) // TODO: Multiple textures { var cmTexture = textures[0].Insert(textures[0].LastIndexOf('.'), "_cm"); var alphaTexture = textures[0].Insert(textures[0].LastIndexOf('.'), "_alphamask"); var normalGlossTexture = textures[0].Insert(textures[0].LastIndexOf('.'), "_ng"); MyFileTextureManager texManager = MyManagers.FileTextures; textureInfo = new MyCloudLayer.MyCloudTextureInfo { ColorMetalTexture = texManager.GetTexture(cmTexture, MyFileTextureEnum.COLOR_METAL), AlphaTexture = texManager.GetTexture(alphaTexture, MyFileTextureEnum.ALPHAMASK), NormalGlossTexture = texManager.GetTexture(normalGlossTexture, MyFileTextureEnum.NORMALMAP_GLOSS), }; } else { MyFileTextureManager texManager = MyManagers.FileTextures; textureInfo = new MyCloudLayer.MyCloudTextureInfo { ColorMetalTexture = texManager.GetTexture(MyMeshes.GetMeshPart(mesh, 0, 0).Info.Material.Info.ColorMetal_Texture.ToString(), MyFileTextureEnum.COLOR_METAL), AlphaTexture = texManager.GetTexture(MyMeshes.GetMeshPart(mesh, 0, 0).Info.Material.Info.Alphamask_Texture.ToString(), MyFileTextureEnum.ALPHAMASK), NormalGlossTexture = texManager.GetTexture(MyMeshes.GetMeshPart(mesh, 0, 0).Info.Material.Info.NormalGloss_Texture.ToString(), MyFileTextureEnum.NORMALMAP_GLOSS), }; } m_cloudLayers.Add(ID, new MyCloudLayer { CenterPoint = centerPoint, Altitude = altitude, MinScaledAltitude = minScaledAltitude, ScalingEnabled = scalingEnabled, FadeOutRelativeAltitudeStart = fadeOutRelativeAltitudeStart, FadeOutRelativeAltitudeEnd = fadeOutRelativeAltitudeEnd, ApplyFogRelativeDistance = applyFogRelativeDistance, MaxPlanetHillRadius = maxPlanetHillRadius, Mesh = mesh, TextureInfo = textureInfo, RotationAxis = rotationAxis, AngularVelocity = angularVelocity, }); m_modifiableCloudLayerData.Add(ID, new MyModifiableCloudLayerData { RadiansAroundAxis = radiansAroundAxis, LastGameplayFrameUpdate = MyRender11.GameplayFrameCounter }); }
static bool GatherInternal() { m_batches.Clear(); // counting sorted billboards ClearBucketCounts(); PreGatherList(MyRenderProxy.BillboardsRead); PreGatherList(m_billboardsOnce); int billboardCount = 0; for (int j = 0; j < BUCKETS_COUNT; j++) { billboardCount += m_bucketCounts[j]; } if (billboardCount == 0) { return(false); } m_billboardCountSafe = billboardCount > MAX_BILLBOARDS_SIZE ? MAX_BILLBOARDS_SIZE : billboardCount; InitGatherList(billboardCount, m_billboardCountSafe); InitBucketIndices(); GatherList(MyRenderProxy.BillboardsRead); GatherList(m_billboardsOnce); InitBucketIndices(); int i; for (i = 0; i < BUCKETS_COUNT; i++) { Array.Sort(m_tempBuffer, m_bucketIndices[i], m_bucketCounts[i]); } bool resetBindings = false; int currentOffset = 0; ISrvBindable prevTex = null; MyTransparentMaterial prevMaterial = null; for (i = 0; i < m_billboardCountSafe; i++) { MyBillboard billboard = m_tempBuffer[i]; MyTransparentMaterial material = MyTransparentMaterials.GetMaterial(billboard.Material); ISrvBindable batchTex = null; if (material.UseAtlas) { var atlasItem = m_atlas.FindElement(material.Texture); batchTex = atlasItem.Texture; } else { MyFileTextureManager texManager = MyManagers.FileTextures; switch (material.TextureType) { case MyTransparentMaterialTextureType.FileTexture: if (material.Texture == null || !m_fileTextures.TryGetValue(material.Texture, out batchTex)) { batchTex = texManager.GetTexture(material.Texture, MyFileTextureEnum.GUI, true); if (material.Texture != null) { m_fileTextures.Add(material.Texture, batchTex); } else { MyRenderProxy.Fail("Material: " + material.Name + " is missing a texture."); } } break; case MyTransparentMaterialTextureType.RenderTarget: batchTex = MyRender11.DrawSpritesOffscreen(material.Name, material.TargetSize.X, material.TargetSize.Y); resetBindings = true; break; default: throw new Exception(); } } bool boundary = IsBucketBoundary(i); bool closeBatch = i > 0 && (batchTex != prevTex || boundary); if (closeBatch) { AddBatch(i, currentOffset, prevTex, prevMaterial); currentOffset = i; } var billboardData = new MyBillboardData(); var billboardVertices = new MyBillboardVertexData(); billboardData.CustomProjectionID = billboard.CustomViewProjection; billboardData.Color = billboard.Color; billboardData.Color.X *= billboard.ColorIntensity; billboardData.Color.Y *= billboard.ColorIntensity; billboardData.Color.Z *= billboard.ColorIntensity; billboardData.AlphaCutout = billboard.AlphaCutout; billboardData.AlphaSaturation = material.AlphaSaturation; billboardData.SoftParticleDistanceScale = billboard.SoftParticleDistanceScale * material.SoftParticleDistanceScale; billboardData.Reflective = billboard.Reflectivity; Vector3D pos0 = billboard.Position0; Vector3D pos1 = billboard.Position1; Vector3D pos2 = billboard.Position2; Vector3D pos3 = billboard.Position3; if (billboard.ParentID != -1) { var parent = MyIDTracker <MyActor> .FindByID((uint)billboard.ParentID); if (parent != null) { var matrix = parent.WorldMatrix; Vector3D.Transform(ref pos0, ref matrix, out pos0); Vector3D.Transform(ref pos1, ref matrix, out pos1); Vector3D.Transform(ref pos2, ref matrix, out pos2); Vector3D.Transform(ref pos3, ref matrix, out pos3); } } MyEnvironmentMatrices envMatrices = MyRender11.Environment.Matrices; if (MyStereoRender.Enable) { if (MyStereoRender.RenderRegion == MyStereoRegion.LEFT) { envMatrices = MyStereoRender.EnvMatricesLeftEye; } else if (MyStereoRender.RenderRegion == MyStereoRegion.RIGHT) { envMatrices = MyStereoRender.EnvMatricesRightEye; } } if (billboard.CustomViewProjection == -1) { pos0 -= envMatrices.CameraPosition; pos1 -= envMatrices.CameraPosition; pos2 -= envMatrices.CameraPosition; pos3 -= envMatrices.CameraPosition; } var normal = Vector3D.Cross(pos1 - pos0, pos2 - pos0); normal.Normalize(); billboardData.Normal = normal; billboardVertices.V0.Position = pos0; billboardVertices.V1.Position = pos1; billboardVertices.V2.Position = pos2; billboardVertices.V3.Position = pos3; var uv0 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv1 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X * billboard.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y); var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y + material.UVSize.Y * billboard.UVSize.Y); if (material.UseAtlas) { var atlasItem = m_atlas.FindElement(material.Texture); uv0 = uv0 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv1 = uv1 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv2 = uv2 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); uv3 = uv3 * new Vector2(atlasItem.UvOffsetScale.Z, atlasItem.UvOffsetScale.W) + new Vector2(atlasItem.UvOffsetScale.X, atlasItem.UvOffsetScale.Y); } billboardVertices.V0.Texcoord = new HalfVector2(uv0); billboardVertices.V1.Texcoord = new HalfVector2(uv1); billboardVertices.V2.Texcoord = new HalfVector2(uv2); billboardVertices.V3.Texcoord = new HalfVector2(uv3); pos0.AssertIsValid(); pos1.AssertIsValid(); pos2.AssertIsValid(); pos3.AssertIsValid(); MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard; if (triBillboard != null) { billboardVertices.V3.Position = pos2; // second triangle will die in rasterizer billboardVertices.V0.Texcoord = new HalfVector2(triBillboard.UV0); billboardVertices.V1.Texcoord = new HalfVector2(triBillboard.UV1); billboardVertices.V2.Texcoord = new HalfVector2(triBillboard.UV2); billboardData.Normal = triBillboard.Normal0; } m_arrayDataBillboards.Data[i] = billboardData; m_arrayDataBillboards.Vertex[i] = billboardVertices; prevTex = batchTex; prevMaterial = material; } AddBatch(m_billboardCountSafe, currentOffset, prevTex, prevMaterial); TransferDataCustomProjections(); TransferDataBillboards(0, m_billboardCountSafe, ref m_arrayDataBillboards); return(resetBindings); }