internal static FlareId Update(int parentGID, FlareId flareId, MyFlareDesc desc) { if (desc.Enabled) { if (flareId == FlareId.NULL) { flareId = new FlareId { Index = m_flares.Allocate() } } ; var gid = parentGID; if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix; Vector3.TransformNormal(ref desc.Direction, ref matrix, out desc.Direction); } desc.MaxDistance = (desc.MaxDistance > 0) ? (float)Math.Min(MyRenderConstants.MAX_GPU_OCCLUSION_QUERY_DISTANCE, desc.MaxDistance) : MyRenderConstants.MAX_GPU_OCCLUSION_QUERY_DISTANCE; m_flares.Data[flareId.Index] = desc; } else if (flareId != FlareId.NULL) { m_flares.Free(flareId.Index); flareId = FlareId.NULL; } return(flareId); }
internal static void Update() { // touch all lights again, because they don't get updated always when parent is foreach (var light in IdIndex.Values) { var spotPosition = light.LocalSpotPosition; var pointPosition = light.LocalPointPosition; var gid = light.ParentGID; if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix; Vector3D.Transform(ref spotPosition, ref matrix, out spotPosition); Vector3D.Transform(ref pointPosition, ref matrix, out pointPosition); } Lights.Data[light.Index].SpotPosition = spotPosition; Lights.Data[light.Index].PointPosition = pointPosition; Spotlights[light.Index].ViewProjectionDirty = true; } if (DirtyPointlights.Count > 0) { foreach (var id in DirtyPointlights) { var proxy = Pointlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].PointPosition; var range = Pointlights[id.Index].Light.Range; var aabb = new BoundingBoxD(position - range, position + range); Pointlights[id.Index].BvhProxyId = UpdateBvh(PointlightsBvh, id, Pointlights[id.Index].Enabled, proxy, ref aabb); Pointlights[id.Index].LastBvhUpdatePosition = position; } DirtyPointlights.Clear(); } if (DirtySpotlights.Count > 0) { foreach (var id in DirtySpotlights) { var proxy = Spotlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].SpotPosition; var range = Spotlights[id.Index].Spotlight.Light.Range; var aabb = MakeAabbFromSpotlightCone(ref Spotlights[id.Index], position); Spotlights[id.Index].BvhProxyId = UpdateBvh(SpotlightsBvh, id, Spotlights[id.Index].Enabled, proxy, ref aabb); Spotlights[id.Index].LastBvhUpdatePosition = position; } DirtySpotlights.Clear(); } }
internal void Construct() { m_components.Clear(); m_visible = true; m_renderProxyDirty = true; m_ID = new MyIDTracker <MyActor>(); m_localAabb = null; m_relativeTransform = null; Aabb = BoundingBoxD.CreateInvalid(); }
internal static void Update(FlareId flareId) { var gid = m_flares.Data[flareId.Index].Desc.ParentGID; if (gid != -1 && m_flares.Data[flareId.Index].Desc.Type == Lights.MyGlareTypeEnum.Directional) { var actor = MyIDTracker <MyActor> .FindByID((uint)gid); if (actor != null) { var matrix = actor.WorldMatrix; Vector3.TransformNormal(ref m_flares.Data[flareId.Index].Desc.Direction, ref matrix, out m_flares.Data[flareId.Index].DirectionWorld); } } }
internal static void UpdateEntity(LightId light, ref MyLightInfo info) { Lights.Data[light.Index] = info; var position = info.Position; var gid = info.ParentGID; if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix; Vector3.Transform(ref position, ref matrix, out position); } Lights.Data[light.Index].Position = position; }
internal static void AddDecal(uint ID, uint ParentID, ref MyDecalTopoData topoData, MyDecalFlags flags, string sourceTarget, string material, int matIndex) { if (m_decals.Count >= m_decalsQueueSize && m_decals.Count != 0) { MarkForRemove(m_decals.First); } MyScreenDecal decal = new MyScreenDecal(); decal.FadeTimestamp = uint.MaxValue; decal.ID = ID; decal.ParentID = ParentID; decal.TopoData = topoData; decal.Flags = flags; decal.SourceTarget = sourceTarget; decal.Material = material; decal.MaterialId = X.TEXT_(material); decal.MaterialIndex = matIndex; if (!flags.HasFlag(MyDecalFlags.World)) { var parent = MyIDTracker <MyActor> .FindByID(ParentID); if (parent == null) { return; } decal.TopoData.WorldPosition = Vector3D.Transform(topoData.MatrixCurrent.Translation, ref parent.WorldMatrix); } DecalNode node = m_decals.AddLast(decal); m_nodeMap[ID] = node; List <DecalNode> handles; bool found = m_entityDecals.TryGetValue(ParentID, out handles); if (!found) { handles = new List <DecalNode>(); m_entityDecals.Add(ParentID, handles); } handles.Add(node); }
private static void PrepareMaterialBatches(MyRenderContext RC, MyStringId material, List <MyScreenDecal> decals) { if (decals.Count == 0) { return; } foreach (MyScreenDecal decal in decals) { var parent = MyIDTracker <MyActor> .FindByID(decal.ParentID); Matrix volumeMatrix; if (parent == null) { // FIXME: This is a temporary hack to allow see decals on voxel maps. Not good! // Won't work if the voxels are moving. Better to find a way to locate the actor // in the map volumeMatrix = decal.LocalOBB * Matrix.CreateTranslation(-MyEnvironment.CameraPosition); } else { volumeMatrix = decal.LocalOBB * parent.WorldMatrix * Matrix.CreateTranslation(-MyEnvironment.CameraPosition); } m_matrices.Add(volumeMatrix); if (MyRenderProxy.Settings.DebugDrawDecals) { Matrix worldMatrix; if (parent == null) { worldMatrix = decal.LocalOBB; } else { worldMatrix = decal.LocalOBB * parent.WorldMatrix; } VRageRender.MyRenderProxy.DebugDrawSphere(worldMatrix.Translation, 0.02f, Color.Red, 0, false); VRageRender.MyRenderProxy.DebugDrawAxis(worldMatrix, 0.2f, false); } } decals.Clear(); }
// can be on another job internal static void Draw() { // calculate box () var cubeVertices = new Vector3[8] { new Vector3(-0.5f, -0.5f, -0.5f), new Vector3(-0.5f, 0.5f, -0.5f), new Vector3(0.5f, 0.5f, -0.5f), new Vector3(0.5f, -0.5f, -0.5f), new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(0.5f, 0.5f, 0.5f), new Vector3(0.5f, -0.5f, 0.5f) }; var worldVertices = new Vector3[8]; var decals = IdIndex.Values.ToArray(); // sort visible decals by material Array.Sort(decals, DecalsMaterialComparer); /// // copy gbuffer with normals for read (uhoh) // bind copy and depth for read // bind gbuffer for write var batch = MyLinesRenderer.CreateBatch(); for (int i = 0; i < decals.Length; ++i) { var index = decals[i]; var parentMatrix = MyIDTracker <MyActor> .FindByID(Decals.Data[index].ParentID).WorldMatrix; var volumeMatrix = Decals.Data[index].LocalOBB * parentMatrix; var invVolumeMatrix = Matrix.Invert(volumeMatrix); Vector3.Transform(cubeVertices, ref volumeMatrix, worldVertices); batch.Add6FacedConvex(worldVertices, Color.Red); } batch.Commit(); }
internal static void AddDecal(uint ID, uint ParentID, Matrix localOBB, string material) { var handle = Decals.Allocate(); Decals.Data[handle].ID = ID; Decals.Data[handle].ParentID = ParentID; Decals.Data[handle].LocalOBB = localOBB; Decals.Data[handle].Material = MyStringId.GetOrCompute(material); IdIndex[ID] = handle; if (!EntityDecals.ContainsKey(ParentID)) { EntityDecals[ParentID] = new List <int>(); } EntityDecals[ParentID].Add(handle); Debug.Assert(MyIDTracker <MyActor> .FindByID(ParentID) != null, "Decal added to non-existing render entity"); }
internal static void UpdateSpotlight(LightId light, bool enabled, float intensity, float reflectorConeMaxAnglecos, MySpotLightLayout data, ISrvBindable reflectorTexture) { // Convert as in dx9 float coneMaxAngleCos = 1 - reflectorConeMaxAnglecos; coneMaxAngleCos = (float)Math.Min(Math.Max(coneMaxAngleCos, 0.01), 0.99f); data.Light.Color *= intensity; data.ApertureCos = coneMaxAngleCos; var info = Spotlights[light.Index]; var gid = light.ParentGID; if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix; Vector3.TransformNormal(ref data.Direction, ref matrix, out data.Direction); Vector3.TransformNormal(ref data.Up, ref matrix, out data.Up); } bool aabbChanged = info.Spotlight.Direction != data.Direction || info.Spotlight.Light.Range != data.Light.Range || info.Spotlight.ApertureCos != data.ApertureCos || info.Spotlight.Up != data.Up; Spotlights[light.Index].Enabled = enabled; Spotlights[light.Index].Spotlight = data; Spotlights[light.Index].ReflectorTexture = reflectorTexture; var proxy = Spotlights[light.Index].BvhProxyId; var positionDifference = Vector3D.RectangularDistance(ref Spotlights[light.Index].LastBvhUpdatePosition, ref Lights.Data[light.Index].SpotPosition); bool dirty = (enabled && ((proxy == -1) || (positionDifference > MOVE_TOLERANCE || aabbChanged))) || (!enabled && proxy != -1); if (dirty) { DirtySpotlights.Add(light); } else { DirtySpotlights.Remove(light); } }
internal static void UpdateSpotlight(LightId light, bool enabled, Vector3 direction, float range, float apertureCos, Vector3 up, Vector3 color, float falloff, float glossFactor, TexId reflectorTexture) { var info = Spotlights[light.Index]; var gid = light.ParentGID; if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix; Vector3.TransformNormal(ref direction, ref matrix, out direction); Vector3.TransformNormal(ref up, ref matrix, out up); } bool aabbChanged = info.Direction != direction || info.Range != range || info.ApertureCos != apertureCos || info.Up != up; Spotlights[light.Index].Enabled = enabled; Spotlights[light.Index].Direction = direction; Spotlights[light.Index].Range = range; Spotlights[light.Index].ApertureCos = apertureCos; Spotlights[light.Index].Up = up; Spotlights[light.Index].Falloff = falloff; Spotlights[light.Index].GlossFactor = glossFactor; Spotlights[light.Index].Color = color; Spotlights[light.Index].ReflectorTexture = reflectorTexture; var proxy = Spotlights[light.Index].BvhProxyId; var positionDifference = Vector3D.RectangularDistance(ref Spotlights[light.Index].LastBvhUpdatePosition, ref Lights.Data[light.Index].SpotPosition); bool dirty = (enabled && ((proxy == -1) || (positionDifference > MOVE_TOLERANCE || aabbChanged))) || (!enabled && proxy != -1); if (dirty) { DirtySpotlights.Add(light); } else { DirtySpotlights.Remove(light); } }
internal void Destruct() { if (m_ID == null) { return; } for (int i = 0; i < m_components.Count; i++) { m_components[i].OnRemove(this); } m_components.Clear(); if (m_ID.Value != null) { m_ID.Deregister(); } m_ID = null; }
internal override void Construct() { base.Construct(); Type = MyActorComponentEnum.Instancing; m_capacity = 0; m_input = MyVertexInputLayout.Empty(); m_ID = new MyIDTracker <MyInstancingComponent>(); VB = VertexBufferId.NULL; if (m_owners == null) { m_owners = new List <MyActor>(); } else { m_owners.Clear(); } }
static bool IsDecalWithinRadius(MyScreenDecal decal, float squaredDistanceMax) { var parent = MyIDTracker <MyActor> .FindByID(decal.ParentID); bool world = decal.Flags.HasFlag(MyDecalFlags.World); Vector3 distance; if (world) { distance = (decal.TopoData.WorldPosition - MyRender11.Environment.Matrices.CameraPosition); } else { MatrixD volumeMatrixD = ((MatrixD)decal.TopoData.MatrixCurrent) * parent.WorldMatrix; distance = (volumeMatrixD.Translation - MyRender11.Environment.Matrices.CameraPosition); } float squaredDistance = (float)distance.LengthSquared(); return(squaredDistance <= squaredDistanceMax); }
internal static void UpdateGlare(LightId light, MyGlareDesc desc) { if (desc.Enabled) { var gid = light.ParentGID; if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix; Vector3.TransformNormal(ref desc.Direction, ref matrix, out desc.Direction); } desc.MaxDistance = (desc.MaxDistance > 0) ? (float)Math.Min(MyRenderConstants.MAX_GPU_OCCLUSION_QUERY_DISTANCE, desc.MaxDistance) : MyRenderConstants.MAX_GPU_OCCLUSION_QUERY_DISTANCE; Glares[light] = desc; } else { Glares.Remove(light); } }
public static void UpdateDecals(IReadOnlyList <MyDecalPositionUpdate> decals) { uint currentObjectId = MyRenderProxy.RENDER_ID_UNASSIGNED; MatrixD currentWorldMatrix = new MatrixD(); for (int it = 0; it < decals.Count; it++) { MyDecalPositionUpdate position = decals[it]; DecalNode node; bool found = m_nodeMap.TryGetValue(position.ID, out node); if (!found) { continue; } MyScreenDecal decal = node.Value; if (decal.Flags.HasFlag(MyDecalFlags.World)) { decal.TopoData.WorldPosition = position.Position; } else { if (currentObjectId != decal.ParentID) { var parent = MyIDTracker <MyActor> .FindByID(decal.ParentID); currentWorldMatrix = parent.WorldMatrix; currentObjectId = decal.ParentID; } decal.TopoData.WorldPosition = Vector3D.Transform(position.Transform.Translation, ref currentWorldMatrix); } node.Value.TopoData.MatrixCurrent = position.Transform; } }
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); }
static void Gather() { // counting sorted billboards m_batches.Clear(); m_sortedNum = 0; PreGatherList(MyRenderProxy.BillboardsRead); PreGatherList(m_billboardsOnce); m_sortedBillboardsNum = m_sortedNum; m_unsorted = 0; m_sorted = 0; GatherList(MyRenderProxy.BillboardsRead); GatherList(m_billboardsOnce); Array.Sort(m_sortBuffer, 0, m_sortedNum); //Array.Reverse(m_sortBuffer, 0, m_sortedNum); //Array.Sort(m_sortBuffer, m_sortedNum, m_unsorted); var N = m_sorted + m_unsorted; var batch = new MyBillboardBatch(); //MyAssetTexture prevTexture = null; var prevTexId = TexId.NULL; int currentOffset = 0; if (N > 0) { var material = MyTransparentMaterials.GetMaterial(m_sortBuffer[0].Material); if (material.UseAtlas) { var item = m_atlasedTextures[material.Texture]; prevTexId = item.TextureId; } else { PreloadTexture(material.Texture); //prevTexture = MyTextureManager.GetTextureFast(material.Texture); prevTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } } TexId batchTexId = TexId.NULL; MyTransparentMaterial prevMaterial = null; for (int i = 0; i < N; i++) { var billboard = m_sortBuffer[i]; var material = MyTransparentMaterials.GetMaterial(billboard.Material); var billboardData = new MyBillboardData(); billboardData.CustomProjectionID = billboard.CustomViewProjection; billboardData.Color = billboard.Color; if (material.UseAtlas) { var atlasItem = m_atlasedTextures[material.Texture]; //billboardData.UvModifiers = new HalfVector4(atlasItem.UvOffsetScale); batchTexId = atlasItem.TextureId; } else { batchTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } 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); } } if (billboard.CustomViewProjection != -1) { var billboardViewProjection = MyRenderProxy.BillboardsViewProjectionRead[billboard.CustomViewProjection]; //pos0 -= MyEnvironment.CameraPosition; //pos1 -= MyEnvironment.CameraPosition; //pos2 -= MyEnvironment.CameraPosition; //pos3 -= MyEnvironment.CameraPosition; } else { pos0 -= MyEnvironment.CameraPosition; pos1 -= MyEnvironment.CameraPosition; pos2 -= MyEnvironment.CameraPosition; pos3 -= MyEnvironment.CameraPosition; } var normal = Vector3.Cross(pos1 - pos0, pos2 - pos0); normal.Normalize(); billboardData.Normal = normal; m_vertexData[i * 4 + 0].Position = pos0; m_vertexData[i * 4 + 1].Position = pos1; m_vertexData[i * 4 + 2].Position = pos2; m_vertexData[i * 4 + 3].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.UVOffset.X, material.UVOffset.Y + billboard.UVOffset.Y); var uv2 = new Vector2(material.UVOffset.X + material.UVSize.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y); var uv3 = new Vector2(material.UVOffset.X + billboard.UVOffset.X, material.UVOffset.Y + material.UVSize.Y + billboard.UVOffset.Y); if (material.UseAtlas) { var atlasItem = m_atlasedTextures[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); } m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(uv0); m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(uv1); m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(uv2); m_vertexData[i * 4 + 3].Texcoord = new HalfVector2(uv3); pos0.AssertIsValid(); pos1.AssertIsValid(); pos2.AssertIsValid(); pos3.AssertIsValid(); MyTriangleBillboard triBillboard = billboard as MyTriangleBillboard; if (triBillboard != null) { m_vertexData[i * 4 + 3].Position = pos2; // second triangle will die in rasterizer m_vertexData[i * 4 + 0].Texcoord = new HalfVector2(triBillboard.UV0); m_vertexData[i * 4 + 1].Texcoord = new HalfVector2(triBillboard.UV1); m_vertexData[i * 4 + 2].Texcoord = new HalfVector2(triBillboard.UV2); billboardData.Normal = triBillboard.Normal0; // pew pew pew :O } m_billboardData[i] = billboardData; bool closeBatch = (batchTexId != prevTexId) || ((i == m_sortedNum) && (i > 0)); if (closeBatch) { batch = new MyBillboardBatch(); batch.Offset = currentOffset; batch.Num = i - currentOffset; batch.Texture = prevTexId != TexId.NULL ? MyTextures.Views[prevTexId.Index] : null; batch.Lit = prevMaterial.CanBeAffectedByOtherLights; m_batches.Add(batch); currentOffset = i; } prevTexId = batchTexId; prevMaterial = material; } if (N > 0) { batch = new MyBillboardBatch(); batch.Offset = currentOffset; batch.Num = N - currentOffset; batch.Texture = prevTexId != TexId.NULL ? MyTextures.GetView(prevTexId) : null; batch.Lit = prevMaterial.CanBeAffectedByOtherLights; m_batches.Add(batch); } }
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); }
private static void ProcessMessageInternal(IMyRenderMessage message) { switch (message.MessageType) { case MyRenderMessageEnum.SetCameraViewMatrix: { var rMessage = (MyRenderMessageSetCameraViewMatrix)message; SetupCameraMatrices(rMessage); break; } case MyRenderMessageEnum.DrawScene: { var rMessage = (IMyRenderMessage)message; m_drawQueue.Enqueue(rMessage); m_messageTracker.Clear(); break; } case MyRenderMessageEnum.RebuildCullingStructure: { break; } #region Profiler case MyRenderMessageEnum.RenderProfiler: { var profMessage = (MyRenderMessageRenderProfiler)message; MyRenderProfiler.HandleInput(profMessage.Command, profMessage.Index); break; } #endregion #region Characters case MyRenderMessageEnum.CreateRenderCharacter: { var rMessage = (MyRenderMessageCreateRenderCharacter)message; var actor = MyActorFactory.CreateCharacter(); Matrix worldMatrixF = rMessage.WorldMatrix; //actor.GetRenderable().SetModel(MyAssetsLoader.GetModel(rMessage.Model)); actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(rMessage.Model))); actor.SetMatrix(ref worldMatrixF); if (rMessage.ColorMaskHSV.HasValue) { var color = ColorFromMask(rMessage.ColorMaskHSV.Value); actor.GetRenderable().SetKeyColor(new Vector4(color, 1)); } actor.SetID(rMessage.ID); //var entity = MyComponents.CreateEntity(rMessage.ID); //MyComponents.CreateRenderable( // entity, // MyMeshes.GetMeshId(X.TEXT(rMessage.Model)), // rMessage.ColorMaskHSV.HasValue ? rMessage.ColorMaskHSV.Value : Vector3.One); //MyComponents.SetMatrix(entity, ref rMessage.WorldMatrix); break; } case MyRenderMessageEnum.SetCharacterSkeleton: { var rMessage = (MyRenderMessageSetCharacterSkeleton)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.CharacterID); if (actor != null) { actor.GetSkinning().SetSkeleton(rMessage.SkeletonBones, rMessage.SkeletonIndices); } //var entity = MyComponents.GetEntity(rMessage.CharacterID); //MyComponents.SetSkeleton(entity, rMessage.SkeletonBones, rMessage.SkeletonIndices); break; }; case MyRenderMessageEnum.SetCharacterTransforms: { var rMessage = (MyRenderMessageSetCharacterTransforms)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.CharacterID); if (actor != null) { actor.GetSkinning().SetAnimationBones(rMessage.RelativeBoneTransforms); } //var entity = MyComponents.GetEntity(rMessage.CharacterID); //MyComponents.SetAnimation(entity, rMessage.RelativeBoneTransforms); break; } case MyRenderMessageEnum.UpdateRenderEntity: { var rMessage = (MyRenderMessageUpdateRenderEntity)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID); if (actor != null && actor.GetRenderable() != null) { if (rMessage.ColorMaskHSV.HasValue) { actor.GetRenderable().SetKeyColor(new Vector4(ColorFromMask(rMessage.ColorMaskHSV.Value), 1)); } actor.GetRenderable().SetDithering(rMessage.Dithering); if (rMessage.Dithering < 0) { } } break; } case MyRenderMessageEnum.ChangeModelMaterial: { var rMessage = (MyRenderMessageChangeModelMaterial)message; //var matId = MyMeshMaterialId.NULL; //if (rMessage.Material.ToLower().Contains("debug")) //{ // matId = MyMeshMaterials1.DebugMaterialId; //} //else //{ // matId = MyMeshMaterials1.GetMaterialId(rMessage.Material); //} //MyAssetsLoader.GetModel(rMessage.Model).SetMaterial_SLOW(MyMeshMaterials1.GetProxyId(matId)); break; } #endregion #region Render objects case MyRenderMessageEnum.CreateRenderEntity: { var rMessage = (MyRenderMessageCreateRenderEntity)message; Matrix m = (Matrix)rMessage.WorldMatrix; var actor = MyActorFactory.CreateSceneObject(); if (rMessage.Model != null) { var model = MyAssetsLoader.ModelRemap.Get(rMessage.Model, rMessage.Model); actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(model))); //if (MyDestructionMesh.ModelsDictionary.ContainsKey(model)) //{ // //actor.GetRenderable().SetModel(MyDestructionMesh.ModelsDictionary.Get(model)); // actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(model))); //} //else //{ // //actor.GetRenderable().SetModel(MyAssetsLoader.GetModel(model)); // actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(model))); //} } actor.SetID(rMessage.ID); actor.SetMatrix(ref m); break; } case MyRenderMessageEnum.CreateRenderVoxelDebris: { var rMessage = (MyRenderMessageCreateRenderVoxelDebris)message; Matrix m = (Matrix)rMessage.WorldMatrix; var actor = MyActorFactory.CreateSceneObject(); if (rMessage.Model != null) { actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(rMessage.Model))); } actor.SetID(rMessage.ID); actor.SetMatrix(ref m); MyRenderableComponent.DebrisEntityVoxelMaterial[rMessage.ID] = rMessage.VoxelMaterialIndex; break; } case MyRenderMessageEnum.UpdateRenderObject: { var rMessage = (MyRenderMessageUpdateRenderObject)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID); if (actor != null) { Matrix m = (Matrix)rMessage.WorldMatrix; actor.SetMatrix(ref m); if (rMessage.AABB.HasValue) { actor.SetAabb((BoundingBox)rMessage.AABB.Value); } } var entity = MyComponents.GetEntity(rMessage.ID); if (entity != EntityId.NULL) { MyComponents.SetMatrix(entity, ref rMessage.WorldMatrix); if (rMessage.AABB.HasValue) { var aabb = rMessage.AABB.Value; MyComponents.SetAabb(entity, ref aabb); } } break; } case MyRenderMessageEnum.RemoveRenderObject: { var rMessage = (MyRenderMessageRemoveRenderObject)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID); if (actor != null) { if (actor.GetRenderable() != null && actor.GetRenderable().GetModel().Info.Dynamic) { MyMeshes.RemoveMesh(actor.GetRenderable().GetModel()); } actor.Destruct(); } var instancing = MyInstancing.Get(rMessage.ID); if (instancing != InstancingId.NULL) { MyInstancing.Remove(rMessage.ID, instancing); } var light = MyLights.Get(rMessage.ID); if (light != LightId.NULL) { MyLights.Remove(rMessage.ID, light); } var clipmap = MyClipmapFactory.ClipmapByID.Get(rMessage.ID); if (clipmap != null) { clipmap.RemoveFromUpdate(); } break; } case MyRenderMessageEnum.UpdateRenderObjectVisibility: { var rMessage = (MyRenderMessageUpdateRenderObjectVisibility)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID); if (actor != null) { actor.SetVisibility(rMessage.Visible); } break; } case MyRenderMessageEnum.CreateRenderInstanceBuffer: { var rMessage = (MyRenderMessageCreateRenderInstanceBuffer)message; //var instancing = MyComponentFactory<MyInstancingComponent>.Create(); //instancing.SetID(rMessage.ID); //instancing.Init(rMessage.Type); //instancing.SetDebugName(rMessage.DebugName); MyInstancing.Create(rMessage.ID, rMessage.Type, rMessage.DebugName); break; } case MyRenderMessageEnum.UpdateRenderInstanceBuffer: { var rMessage = (MyRenderMessageUpdateRenderInstanceBuffer)message; //var instancing = MyIDTracker<MyInstancingComponent>.FindByID(rMessage.ID); //if(instancing != null) //{ // instancing.UpdateGeneric(rMessage.InstanceData, rMessage.Capacity); //} MyInstancing.UpdateGeneric(MyInstancing.Get(rMessage.ID), rMessage.InstanceData, rMessage.Capacity); rMessage.InstanceData.Clear(); break; } case MyRenderMessageEnum.UpdateRenderCubeInstanceBuffer: { var rMessage = (MyRenderMessageUpdateRenderCubeInstanceBuffer)message; //var instancing = MyIDTracker<MyInstancingComponent>.FindByID(rMessage.ID); //if (instancing != null) //{ // instancing.UpdateCube(rMessage.InstanceData, rMessage.Capacity); //} MyInstancing.UpdateCube(MyInstancing.Get(rMessage.ID), rMessage.InstanceData, rMessage.Capacity); rMessage.InstanceData.Clear(); break; } case MyRenderMessageEnum.SetInstanceBuffer: { var rMessage = (MyRenderMessageSetInstanceBuffer)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID); //var instancing = MyIDTracker<MyInstancingComponent>.FindByID(rMessage.InstanceBufferId); if (actor != null) { //if (actor.GetComponent(MyActorComponentEnum.Instancing) != instancing) //{ // actor.AddComponent(instancing); //} //actor.SetLocalAabb(rMessage.LocalAabb); //actor.GetRenderable().SetInstancingCounters(rMessage.InstanceCount, rMessage.InstanceStart); actor.GetRenderable().SetInstancing(MyInstancing.Get(rMessage.InstanceBufferId)); actor.SetLocalAabb(rMessage.LocalAabb); actor.GetRenderable().SetInstancingCounters(rMessage.InstanceCount, rMessage.InstanceStart); } break; } case MyRenderMessageEnum.CreateManualCullObject: { var rMessage = (MyRenderMessageCreateManualCullObject)message; var actor = MyActorFactory.CreateGroup(); actor.SetID(rMessage.ID); Matrix m = (Matrix)rMessage.WorldMatrix; actor.SetMatrix(ref m); break; } case MyRenderMessageEnum.SetParentCullObject: { var rMessage = (MyRenderMessageSetParentCullObject)message; var child = MyIDTracker <MyActor> .FindByID(rMessage.ID); var parent = MyIDTracker <MyActor> .FindByID(rMessage.CullObjectID); if (child != null && parent != null && parent.GetGroupRoot() != null && child.GetGroupLeaf() == null) { child.SetRelativeTransform(rMessage.ChildToParent); parent.GetGroupRoot().Add(child); } break; } case MyRenderMessageEnum.CreateLineBasedObject: { var rMessage = (MyRenderMessageCreateLineBasedObject)message; var actor = MyActorFactory.CreateSceneObject(); //actor.GetRenderable().SetModel(new MyDynamicMesh()); actor.SetID(rMessage.ID); actor.SetMatrix(ref Matrix.Identity); MyMeshMaterials1.GetMaterialId("__ROPE_MATERIAL", null, "Textures/rope_cm.dds", "Textures/rope_ng.dds", "Textures/rope_add.dds", MyMesh.DEFAULT_MESH_TECHNIQUE); actor.GetRenderable().SetModel(MyMeshes.CreateRuntimeMesh(X.TEXT("LINE" + rMessage.ID), 1, true)); break; } case MyRenderMessageEnum.UpdateLineBasedObject: { var rMessage = (MyRenderMessageUpdateLineBasedObject)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID); if (actor != null) { //var mesh = actor.GetRenderable().GetMesh() as MyDynamicMesh; MyVertexFormatPositionH4 [] stream0; MyVertexFormatTexcoordNormalTangent [] stream1; MyLineHelpers.GenerateVertexData(ref rMessage.WorldPointA, ref rMessage.WorldPointB, out stream0, out stream1); var indices = MyLineHelpers.GenerateIndices(stream0.Length); var sections = new MySectionInfo[] { new MySectionInfo { TriCount = indices.Length / 3, IndexStart = 0, MaterialName = "__ROPE_MATERIAL" } }; MyMeshes.UpdateRuntimeMesh(MyMeshes.GetMeshId(X.TEXT("LINE" + rMessage.ID)), indices, stream0, stream1, sections, (BoundingBox)MyLineHelpers.GetBoundingBox(ref rMessage.WorldPointA, ref rMessage.WorldPointB)); //actor.SetAabb((BoundingBox)MyLineHelpers.GetBoundingBox(ref rMessage.WorldPointA, ref rMessage.WorldPointB)); actor.MarkRenderDirty(); var matrix = Matrix.CreateTranslation((Vector3)(rMessage.WorldPointA + rMessage.WorldPointB) * 0.5f); actor.SetMatrix(ref matrix); } break; } case MyRenderMessageEnum.SetRenderEntityData: { var rMessage = (MyRenderMessageSetRenderEntityData)message; Debug.Assert(false, "MyRenderMessageSetRenderEntityData is deprecated!"); break; } case MyRenderMessageEnum.AddRuntimeModel: { var rMessage = (MyRenderMessageAddRuntimeModel)message; //MyDestructionMesh mesh = MyDestructionMesh.ModelsDictionary.Get(rMessage.Name); //if (mesh == null) //{ //mesh = new MyDestructionMesh(rMessage.Name); //ProfilerShort.Begin("LoadBuffers"); //mesh.Fill(rMessage.ModelData.Indices, rMessage.ModelData.Positions, rMessage.ModelData.Normals, rMessage.ModelData.Tangents, rMessage.ModelData.TexCoords, rMessage.ModelData.Sections, rMessage.ModelData.AABB); //ProfilerShort.End(); if (!MyMeshes.Exists(rMessage.Name)) { { ushort[] indices = new ushort[rMessage.ModelData.Indices.Count]; for (int i = 0; i < rMessage.ModelData.Indices.Count; i++) { indices[i] = (ushort)rMessage.ModelData.Indices[i]; } var verticesNum = rMessage.ModelData.Positions.Count; MyVertexFormatPositionH4[] stream0 = new MyVertexFormatPositionH4[verticesNum]; MyVertexFormatTexcoordNormalTangent[] stream1 = new MyVertexFormatTexcoordNormalTangent[verticesNum]; for (int i = 0; i < verticesNum; i++) { stream0[i] = new MyVertexFormatPositionH4(rMessage.ModelData.Positions[i]); stream1[i] = new MyVertexFormatTexcoordNormalTangent( rMessage.ModelData.TexCoords[i], rMessage.ModelData.Normals[i], rMessage.ModelData.Tangents[i]); } var id = MyMeshes.CreateRuntimeMesh(X.TEXT(rMessage.Name), rMessage.ModelData.Sections.Count, false); MyMeshes.UpdateRuntimeMesh(id, indices, stream0, stream1, rMessage.ModelData.Sections.ToArray(), rMessage.ModelData.AABB); } if (rMessage.ReplacedModel != null) { //MyAssetsLoader.ModelRemap[rMessage.ReplacedModel] = rMessage.Name; MyAssetsLoader.ModelRemap[rMessage.Name] = rMessage.ReplacedModel; } //if (MyAssetsLoader.LOG_MESH_STATISTICS) //{ // mesh.DebugWriteInfo(); //} } break; } case MyRenderMessageEnum.UpdateModelProperties: { var rMessage = (MyRenderMessageUpdateModelProperties)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID); if (actor != null) { var key = new MyEntityMaterialKey { LOD = rMessage.LOD, Material = X.TEXT(rMessage.MaterialName) }; if (rMessage.Enabled.HasValue) { if (!MyScene.EntityDisabledMaterials.ContainsKey(rMessage.ID)) { MyScene.EntityDisabledMaterials.Add(rMessage.ID, new HashSet <MyEntityMaterialKey>()); } if (!rMessage.Enabled.Value) { MyScene.EntityDisabledMaterials[rMessage.ID].Add(key); } else { MyScene.EntityDisabledMaterials[rMessage.ID].Remove(key); } } var r = actor.GetRenderable(); if ((rMessage.Emissivity.HasValue || rMessage.DiffuseColor.HasValue) && !r.ModelProperties.ContainsKey(key)) { r.ModelProperties[key] = new MyModelProperties(); } if (rMessage.Emissivity.HasValue) { r.ModelProperties[key].Emissivity = rMessage.Emissivity.Value; } if (rMessage.DiffuseColor.HasValue) { r.ModelProperties[key].ColorMul = rMessage.DiffuseColor.Value; } actor.MarkRenderDirty(); } break; } case MyRenderMessageEnum.PreloadModel: { var rMessage = (MyRenderMessagePreloadModel)message; //MyAssetsLoader.GetModel(rMessage.Name); MyMeshes.GetMeshId(X.TEXT(rMessage.Name)); break; } case MyRenderMessageEnum.ChangeMaterialTexture: { var rMessage = (MyRenderMessageChangeMaterialTexture)message; var actor = MyIDTracker <MyActor> .FindByID(rMessage.RenderObjectID); if (actor != null) { var r = actor.GetRenderable(); var key = new MyEntityMaterialKey { LOD = 0, Material = X.TEXT(rMessage.MaterialName) }; if (!r.ModelProperties.ContainsKey(key)) { r.ModelProperties[key] = new MyModelProperties(); } r.ModelProperties[key].TextureSwap = new MyMaterialTextureSwap { TextureName = X.TEXT(rMessage.TextureName) }; r.FreeCustomRenderTextures(key); actor.MarkRenderDirty(); } break; } case MyRenderMessageEnum.DrawTextToMaterial: { var rMessage = (MyRenderMessageDrawTextToMaterial)message; //rMessage.EntityId //rMessage.FontColor //rMessage.MaterialName //rMessage.Text; //rMessage.TextScale; var actor = MyIDTracker <MyActor> .FindByID(rMessage.RenderObjectID); if (actor != null) { var r = actor.GetRenderable(); var key = new MyEntityMaterialKey { LOD = 0, Material = X.TEXT(rMessage.MaterialName) }; if (!r.ModelProperties.ContainsKey(key)) { r.ModelProperties[key] = new MyModelProperties(); } else { r.ModelProperties[key].TextureSwap = null; } RwTexId handle = r.ModelProperties[key].CustomRenderedTexture; if (handle == RwTexId.NULL && MyModelProperties.CustomTextures < MyModelProperties.MaxCustomTextures) { handle = MyRwTextures.CreateRenderTarget(rMessage.TextureResolution * rMessage.TextureAspectRatio, rMessage.TextureResolution, SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb, true); r.ModelProperties[key].CustomRenderedTexture = handle; ++MyModelProperties.CustomTextures; } if (handle != RwTexId.NULL) { var clearColor = new SharpDX.Color4(rMessage.BackgroundColor.PackedValue); clearColor.Alpha = 0; MyRender11.ImmediateContext.ClearRenderTargetView(handle.Rtv, clearColor); // my sprites renderer -> push state MySpritesRenderer.PushState(new Vector2(rMessage.TextureResolution * rMessage.TextureAspectRatio, rMessage.TextureResolution)); MySpritesRenderer.DrawText(Vector2.Zero, new StringBuilder(rMessage.Text), rMessage.FontColor, rMessage.TextScale); // render text with fonts to rt // update texture of proxy MySpritesRenderer.Draw(handle.Rtv, new MyViewport(rMessage.TextureResolution * rMessage.TextureAspectRatio, rMessage.TextureResolution)); // render to rt // my sprites renderer -> pop state MySpritesRenderer.PopState(); MyRender11.ImmediateContext.GenerateMips(handle.ShaderView); actor.MarkRenderDirty(); } else { MyRenderProxy.TextNotDrawnToTexture(rMessage.EntityId); } } else { MyRenderProxy.TextNotDrawnToTexture(rMessage.EntityId); } break; } case MyRenderMessageEnum.PreloadMaterials: { var rMessage = (MyRenderMessagePreloadMaterials)message; //MyAssetsLoader.GetMaterials(rMessage.Name); MyMeshes.GetMeshId(X.TEXT(rMessage.Name)); break; } #endregion #region Voxels case MyRenderMessageEnum.CreateClipmap: { var rMessage = (MyRenderMessageCreateClipmap)message; var clipmap = new MyClipmapHandler(rMessage.ClipmapId, rMessage.ScaleGroup, rMessage.WorldMatrix, rMessage.SizeLod0); MyClipmapFactory.ClipmapByID[rMessage.ClipmapId] = clipmap; clipmap.Base.LoadContent(); break; } case MyRenderMessageEnum.UpdateClipmapCell: { var rMessage = (MyRenderMessageUpdateClipmapCell)message; var clipmap = MyClipmapFactory.ClipmapByID.Get(rMessage.ClipmapId); if (clipmap != null) { clipmap.Base.UpdateCell(rMessage); } rMessage.Batches.Clear(); break; } case MyRenderMessageEnum.InvalidateClipmapRange: { var rMessage = (MyRenderMessageInvalidateClipmapRange)message; var clipmap = MyClipmapFactory.ClipmapByID.Get(rMessage.ClipmapId); if (clipmap != null) { clipmap.Base.InvalidateRange(rMessage.MinCellLod0, rMessage.MaxCellLod0); } break; } case MyRenderMessageEnum.CreateRenderVoxelMaterials: { var rMessage = (MyRenderMessageCreateRenderVoxelMaterials)message; Debug.Assert(MyVoxelMaterials1.CheckIndices(rMessage.Materials)); MyVoxelMaterials1.Set(rMessage.Materials); rMessage.Materials = null; break; } #endregion #region Lights case MyRenderMessageEnum.CreateRenderLight: { var rMessage = (MyRenderMessageCreateRenderLight)message; //MyLight.Create(rMessage.ID); MyLights.Create(rMessage.ID); break; } case MyRenderMessageEnum.UpdateRenderLight: { var rMessage = (MyRenderMessageUpdateRenderLight)message; var light = MyLights.Get(rMessage.ID); if (light != LightId.NULL) { var lightInfo = new MyLightInfo { Position = rMessage.Position, PositionWithOffset = rMessage.Position + rMessage.Offset * rMessage.Range * rMessage.ReflectorDirection, CastsShadows = rMessage.CastShadows, ShadowsDistance = rMessage.ShadowDistance, ParentGID = rMessage.ParentID, UsedInForward = rMessage.UseInForwardRender }; MyLights.UpdateEntity(light, ref lightInfo); if ((rMessage.Type & LightTypeEnum.PointLight) > 0) { MyLights.UpdatePointlight(light, rMessage.LightOn, rMessage.Range, new Vector3(rMessage.Color.R, rMessage.Color.G, rMessage.Color.B) / 255.0f * rMessage.Intensity, rMessage.Falloff); } if ((rMessage.Type & LightTypeEnum.Hemisphere) > 0) { //rMessage.Color; //rMessage.Falloff; //rMessage.Intensity; //rMessage.LightOn; //rMessage.ReflectorDirection; //rMessage.ReflectorUp; } if ((rMessage.Type & LightTypeEnum.Spotlight) > 0) { // because it's so in dx9... float coneMaxAngleCos = 1 - rMessage.ReflectorConeMaxAngleCos; coneMaxAngleCos = (float)Math.Min(Math.Max(coneMaxAngleCos, 0.01), 0.99f); MyLights.UpdateSpotlight(light, rMessage.ReflectorOn, rMessage.ReflectorDirection, rMessage.ReflectorRange, coneMaxAngleCos, rMessage.ReflectorUp, new Vector3(rMessage.ReflectorColor.R, rMessage.ReflectorColor.G, rMessage.ReflectorColor.B) / 255.0f * rMessage.Intensity, rMessage.ReflectorFalloff, MyTextures.GetTexture(rMessage.ReflectorTexture, MyTextureEnum.CUSTOM)); } if (rMessage.GlareOn) { MyLights.UpdateGlare(light, new MyGlareDesc { Enabled = rMessage.GlareOn, Material = X.TEXT(rMessage.GlareMaterial), Intensity = rMessage.GlareIntensity, QuerySize = rMessage.GlareQuerySize, Type = rMessage.GlareType, Size = rMessage.GlareSize, MaxDistance = rMessage.GlareMaxDistance, Color = rMessage.Color, Direction = rMessage.ReflectorDirection, Range = rMessage.Range }); } } break; } case MyRenderMessageEnum.SetLightShadowIgnore: { var rMessage = (MyRenderMessageSetLightShadowIgnore)message; var light = MyLights.Get(rMessage.ID); var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID2); if (light != LightId.NULL && actor != null) { if (!MyLights.IgnoredEntitites.ContainsKey(light)) { MyLights.IgnoredEntitites[light] = new HashSet <uint>(); } MyLights.IgnoredEntitites[light].Add(rMessage.ID2); } break; } case MyRenderMessageEnum.ClearLightShadowIgnore: { var rMessage = (MyRenderMessageClearLightShadowIgnore)message; var light = MyLights.Get(rMessage.ID); if (light != LightId.NULL) { MyLights.IgnoredEntitites.Remove(light); } break; } case MyRenderMessageEnum.UpdateFogSettings: { var rMessage = (MyRenderMessageUpdateFogSettings)message; MyEnvironment.FogSettings = rMessage.Settings; break; } case MyRenderMessageEnum.UpdateRenderEnvironment: { var rMessage = (MyRenderMessageUpdateRenderEnvironment)message; MyEnvironment.DirectionalLightDir = VRageMath.Vector3.Normalize(rMessage.SunDirection); MyEnvironment.DirectionalLightIntensity = rMessage.SunIntensity * rMessage.SunColor.ToVector3(); MyEnvironment.DirectionalLightEnabled = rMessage.SunLightOn; MyEnvironment.DayTime = (float)(rMessage.DayTime - Math.Truncate(rMessage.DayTime)); MyEnvironment.SunDistance = rMessage.DistanceToSun; MyEnvironment.SunColor = rMessage.SunColor; MyEnvironment.SunMaterial = rMessage.SunMaterial; MyEnvironment.SunSizeMultiplier = rMessage.SunSizeMultiplier; var skybox = rMessage.BackgroundTexture; m_resetEyeAdaptation = m_resetEyeAdaptation || rMessage.ResetEyeAdaptation; break; } case MyRenderMessageEnum.UpdateEnvironmentMap: { break; } case MyRenderMessageEnum.UpdatePostprocessSettings: { var rMessage = (MyRenderMessageUpdatePostprocessSettings)message; m_postprocessSettings = rMessage.Settings; break; } case MyRenderMessageEnum.UpdateSSAOSettings: { var rMessage = (MyRenderMessageUpdateSSAOSettings)message; MySSAO.Params.MinRadius = rMessage.MinRadius; MySSAO.Params.MaxRadius = rMessage.MaxRadius; MySSAO.Params.RadiusGrow = rMessage.RadiusGrowZScale; MySSAO.Params.RadiusBias = rMessage.Bias; MySSAO.Params.Falloff = rMessage.Falloff; MySSAO.Params.Normalization = rMessage.NormValue; MySSAO.Params.Contrast = rMessage.Contrast; break; } #endregion #region Sprites case MyRenderMessageEnum.DrawSprite: case MyRenderMessageEnum.DrawSpriteNormalized: case MyRenderMessageEnum.DrawSpriteAtlas: case MyRenderMessageEnum.SpriteScissorPush: case MyRenderMessageEnum.SpriteScissorPop: { m_drawQueue.Enqueue(message); break; } #endregion #region Fonts and text case MyRenderMessageEnum.CreateFont: { var createFontMessage = message as MyRenderMessageCreateFont; Debug.Assert(createFontMessage != null); var renderFont = new MyRenderFont(createFontMessage.FontPath); renderFont.LoadContent(); AddFont(createFontMessage.FontId, renderFont, createFontMessage.IsDebugFont); break; } case MyRenderMessageEnum.DrawString: { m_drawQueue.Enqueue(message); break; } #endregion #region Textures case MyRenderMessageEnum.PreloadTextures: { var preloadMsg = message as MyRenderMessagePreloadTextures; //MyTextureManager.PreloadTextures(preloadMsg.InDirectory, preloadMsg.Recursive); //MyTextures.UnloadTexture(texMessage.Texture); break; } case MyRenderMessageEnum.UnloadTexture: { var texMessage = (MyRenderMessageUnloadTexture)message; //MyTextureManager.UnloadTexture(texMessage.Texture); MyTextures.UnloadTexture(texMessage.Texture); break; } case MyRenderMessageEnum.ReloadTextures: { var reloadMsg = (MyRenderMessageReloadTextures)message; MyVoxelMaterials1.InvalidateMaterials(); MyMeshMaterials1.InvalidateMaterials(); MyTextures.ReloadAssetTextures(); //MyTextureManager.UnloadTextures(); //MyMaterialProxyFactory.ReloadTextures(); break; } case MyRenderMessageEnum.ReloadModels: { var reloadMsg = (MyRenderMessageReloadModels)message; //MyMaterials.Clear(); MyAssetsLoader.ReloadMeshes(); MyRenderableComponent.MarkAllDirty(); break; } #endregion case MyRenderMessageEnum.TakeScreenshot: { var rMessage = (MyRenderMessageTakeScreenshot)message; m_screenshot = new MyScreenshot(rMessage.PathToSave, rMessage.SizeMultiplier, rMessage.IgnoreSprites); break; } case MyRenderMessageEnum.ReloadEffects: { m_reloadShaders = true; //MyShaderBundleFactory.ClearCache(); //MyShaderMaterial.ClearCache(); //MyShaderPass.ClearCache(); MyShaders.Recompile(); MyMaterialShaders.Recompile(); MyRenderableComponent.MarkAllDirty(); foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll()) { f.Dispose(); } break; } case MyRenderMessageEnum.PlayVideo: { var rMessage = (MyRenderMessagePlayVideo)message; MyVideoFactory.Create(rMessage.ID, rMessage.VideoFile); var video = MyVideoFactory.Videos.Get(rMessage.ID); if (video != null) { video.Volume = rMessage.Volume; } break; } case MyRenderMessageEnum.CloseVideo: { var rMessage = (MyRenderMessageCloseVideo)message; var video = MyVideoFactory.Videos.Get(rMessage.ID); if (video != null) { video.Stop(); video.Dispose(); MyVideoFactory.Videos.Remove(rMessage.ID); } break; } case MyRenderMessageEnum.DrawVideo: { var rMessage = (MyRenderMessageDrawVideo)message; var video = MyVideoFactory.Videos.Get(rMessage.ID); if (video != null) { video.Draw(rMessage.Rectangle, rMessage.Color, rMessage.FitMode); } break; } case MyRenderMessageEnum.UpdateVideo: { var rMessage = (MyRenderMessageUpdateVideo)message; var video = MyVideoFactory.Videos.Get(rMessage.ID); if (video != null) { video.Update(); } break; } case MyRenderMessageEnum.SetVideoVolume: { var rMessage = (MyRenderMessageSetVideoVolume)message; var video = MyVideoFactory.Videos.Get(rMessage.ID); if (video != null) { video.Volume = rMessage.Volume; } break; } case MyRenderMessageEnum.VideoAdaptersRequest: { MyRenderProxy.SendVideoAdapters(GetAdaptersList()); break; } case MyRenderMessageEnum.SwitchDeviceSettings: { MyRenderProxy.RenderThread.SwitchSettings((message as MyRenderMessageSwitchDeviceSettings).Settings); break; } case MyRenderMessageEnum.SwitchRenderSettings: break; // Can be ignored as we're handling newer version of the message. case MyRenderMessageEnum.SwitchRenderSettings1: { UpdateRenderSettings((message as MyRenderMessageSwitchRenderSettings1).Settings); break; } case MyRenderMessageEnum.UnloadData: { MyRender11.UnloadData(); break; } case MyRenderMessageEnum.CollectGarbage: { GC.Collect(); break; } #region Debug draw case MyRenderMessageEnum.DebugDrawPoint: case MyRenderMessageEnum.DebugDrawLine3D: case MyRenderMessageEnum.DebugDrawLine2D: case MyRenderMessageEnum.DebugDrawSphere: case MyRenderMessageEnum.DebugDrawAABB: case MyRenderMessageEnum.DebugDrawAxis: case MyRenderMessageEnum.DebugDrawOBB: case MyRenderMessageEnum.DebugDrawCone: case MyRenderMessageEnum.DebugDrawTriangle: case MyRenderMessageEnum.DebugDrawCapsule: case MyRenderMessageEnum.DebugDrawText2D: case MyRenderMessageEnum.DebugDrawText3D: case MyRenderMessageEnum.DebugDrawModel: case MyRenderMessageEnum.DebugDrawTriangles: case MyRenderMessageEnum.DebugDrawPlane: case MyRenderMessageEnum.DebugDrawCylinder: { m_debugDrawMessages.Enqueue(message); } break; case MyRenderMessageEnum.DebugCrashRenderThread: { throw new InvalidOperationException("Forced exception"); } #endregion } }
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); }
static void Gather() { 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; } 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; int windowidx = 0; var N = BillboardCountSafe; int currentOffset = 0; TexId prevTexId = TexId.NULL; TexId batchTexId = TexId.NULL; MyTransparentMaterial prevMaterial = null; while (true) { if (i == N) { AddBatch(N, currentOffset, prevTexId, prevMaterial); break; } MyBillboard billboard = m_sortedBuffer[i]; MyTransparentMaterial material = MyTransparentMaterials.GetMaterial(billboard.Material); if (material.UseAtlas) { var atlasItem = m_atlas.FindElement(material.Texture); batchTexId = atlasItem.TextureId; } else { batchTexId = MyTextures.GetTexture(material.Texture, MyTextureEnum.GUI, true); } bool closeBatch = i > 0 && (batchTexId != prevTexId || i == m_sortedCount); if (closeBatch) { AddBatch(i, currentOffset, prevTexId, 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; 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 && MyScreenDecals.HasEntityDecals((uint)billboard.ParentID)) { m_arrayDataWindows.Data[windowidx] = billboardData; m_arrayDataWindows.Vertex[windowidx] = billboardVertices; windowidx++; } prevTexId = batchTexId; prevMaterial = material; i++; } }
// can be on another job internal unsafe static void Draw() { var decals = IdIndex.Values.ToArray(); // sort visible decals by material Array.Sort(decals, DecalsMaterialComparer); /// // copy gbuffer with normals for read (uhoh) // bind copy and depth for read // bind gbuffer for write var RC = MyImmediateRC.RC; RC.Context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; RC.SetIB(m_IB.Buffer, m_IB.Format); RC.SetIL(null); RC.Context.Rasterizer.SetViewport(0, 0, MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); RC.SetCB(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); RC.BindDepthRT( MyGBuffer.Main.Get(MyGbufferSlot.DepthStencil), DepthStencilAccess.DepthReadOnly, MyGBuffer.Main.Get(MyGbufferSlot.GBuffer0), MyGBuffer.Main.Get(MyGbufferSlot.GBuffer1), MyGBuffer.Main.Get(MyGbufferSlot.GBuffer2)); RC.SetVS(m_vs); RC.SetPS(m_ps); RC.SetDS(MyDepthStencilState.DepthTest); RC.Context.PixelShader.SetSamplers(0, MyRender11.StandardSamplers); RC.BindSRV(0, MyGBuffer.Main.DepthStencil.Depth); RC.Context.PixelShader.SetShaderResources(1, MyRender11.m_gbuffer1Copy.ShaderView); var decalCb = MyCommon.GetObjectCB(sizeof(MyDecalConstants) * MAX_DECALS); RC.SetCB(2, decalCb); var prevMaterial = new MyStringId(); MyScreenDecalType decalType = MyScreenDecalType.ScreenDecalBump; for (int i = 0; i < decals.Length; ++i) { var index = decals[i]; var material = Decals.Data[index].Material; if (i == 0 || material != prevMaterial) { DrawBatch(decalType); var matDesc = Materials[material]; decalType = matDesc.DecalType; // factor 1 makes overwriting of gbuffer color & subtracting from ao RC.SetBS(MyRender11.BlendDecal, matDesc.DecalType == MyScreenDecalType.ScreenDecalBump ? new SharpDX.Color4(0) : SharpDX.Color4.White); RC.Context.PixelShader.SetShaderResources(3, MyTextures.GetView(matDesc.AlphamaskTexture), MyTextures.GetView(matDesc.ColorMetalTexture), MyTextures.GetView(matDesc.NormalmapTexture)); } var parent = MyIDTracker <MyActor> .FindByID(Decals.Data[index].ParentID); if (parent != null) { var parentMatrix = parent.WorldMatrix; var volumeMatrix = Decals.Data[index].LocalOBB * parentMatrix * Matrix.CreateTranslation(-MyEnvironment.CameraPosition); m_matrices.Add(volumeMatrix); } } DrawBatch(decalType); RC.SetBS(null); }
public static void Run(IRtvBindable target, ICustomTexture fxaaTarget, IDepthStencil depthStencilCopy) { if (!HasHighlights) { return; } ProfilerShort.Begin("MyHighlight.Run"); MyGpuProfiler.IC_BeginBlock("MyHighlight.Run"); // set resolved depth/ stencil // render all with proper depth-stencil state // blur // blend to main target testing with stencil again MyHighlightPass.Instance.ViewProjection = MyRender11.Environment.Matrices.ViewProjectionAt0; MyHighlightPass.Instance.Viewport = new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); MyHighlightPass.Instance.PerFrame(); MyHighlightPass.Instance.Begin(); int samples = MyRender11.Settings.User.AntialiasingMode.SamplesCount(); IBorrowedRtvTexture rgba8_1 = MyManagers.RwTexturesPool.BorrowRtv("MyHighlight.Rgba8_1", Format.R8G8B8A8_UNorm_SRgb, samples); RC.ClearRtv(rgba8_1, new SharpDX.Color4(0, 0, 0, 0)); RC.SetRtv(depthStencilCopy, MyDepthStencilAccess.DepthReadOnly, rgba8_1); foreach (var pair in m_highlights) { MyActor actor = MyIDTracker <MyActor> .FindByID(pair.Key); if (actor == null) { MyRenderProxy.Fail("The actor cannot be found for highlight. This bug is outside of the renderer."); continue; } MyRenderableComponent renderableComponent = actor.GetRenderable(); MyInstanceComponent instanceComponent = actor.GetInstance(); if (renderableComponent != null) { DrawRenderableComponent(actor, renderableComponent, pair.Value); } else if (instanceComponent != null) { DrawInstanceComponent(instanceComponent, pair.Value); } else { // If an actor has been removed without removing outlines, just remove the outlines too m_keysToRemove.Add(pair.Key); MyRenderProxy.Fail("The actor has been removed, but the highligh is still active. This bug is caused by the issue out of the renderer."); } } MyHighlightPass.Instance.End(); RC.SetBlendState(null); foreach (var outlineKey in m_keysToRemove) { m_highlights.Remove(outlineKey); } m_keysToRemove.Clear(); ISrvBindable initialSourceView = rgba8_1; IRtvBindable renderTargetview = rgba8_1; float maxThickness = 0f; foreach (var pair in m_highlights) { foreach (MyHighlightDesc descriptor in pair.Value) { maxThickness = Math.Max(maxThickness, descriptor.Thickness); } } if (maxThickness > 0) { IBorrowedRtvTexture rgba8_2 = MyManagers.RwTexturesPool.BorrowRtv("MyHighlight.Rgba8_2", Format.R8G8B8A8_UNorm_SRgb); MyBlur.Run(renderTargetview, rgba8_2, initialSourceView, (int)Math.Round(maxThickness), MyBlur.MyBlurDensityFunctionType.Exponential, 0.25f, MyDepthStencilStateManager.IgnoreDepthStencil); rgba8_2.Release(); } MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); BlendHighlight(target, rgba8_1, fxaaTarget, depthStencilCopy); }
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); }
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 PrepareMaterialBatches(MyRenderContext rc, List <MyScreenDecal> decals, uint sinceStartTs) { if (decals.Count == 0) { return; } List <uint> decalsToRemove = new List <uint>(); foreach (MyScreenDecal decal in decals) { var parent = MyIDTracker <MyActor> .FindByID(decal.ParentID); bool world = decal.Flags.HasFlag(MyDecalFlags.World); if (parent == null && !world) { decalsToRemove.Add(decal.ID); continue; } Matrix volumeMatrix; if (world) { volumeMatrix = decal.TopoData.MatrixCurrent; volumeMatrix.Translation = decal.TopoData.WorldPosition - MyRender11.Environment.Matrices.CameraPosition; } else { volumeMatrix = decal.TopoData.MatrixCurrent * parent.WorldMatrix; volumeMatrix.Translation = volumeMatrix.Translation - MyRender11.Environment.Matrices.CameraPosition; } uint fadeDiff = decal.FadeTimestamp - sinceStartTs; float fadeAlpha = decal.FadeTimestamp - sinceStartTs >= DECAL_FADE_DURATION ? 1 : fadeDiff / (float)DECAL_FADE_DURATION; m_jobs.Add(new MyDecalJob() { WorldMatrix = volumeMatrix, FadeAlpha = fadeAlpha }); if (MyRender11.Settings.DebugDrawDecals) { MatrixD worldMatrix; if (parent == null) { worldMatrix = decal.TopoData.MatrixCurrent; worldMatrix.Translation = decal.TopoData.WorldPosition; } else { worldMatrix = decal.TopoData.MatrixCurrent * parent.WorldMatrix; } MyRenderProxy.DebugDrawAxis(worldMatrix, 0.2f, false, true); MyRenderProxy.DebugDrawOBB(worldMatrix, Color.Blue, 0.1f, false, false); Vector3 position = worldMatrix.Translation; MyRenderProxy.DebugDrawText3D(position, decal.SourceTarget, Color.White, 0.5f, false); } } foreach (uint id in decalsToRemove) { DecalNode node = m_nodeMap[id]; RemoveDecalByNode(node); } }