public static MyTexture2D GetTexture(MyTransparentMaterial material)
 {
     if (material.RenderTexture == null)
     {
         material.RenderTexture = material.UseAtlas ? m_atlasTexture : MyTextureManager.GetTexture<MyTexture2D>(material.Texture);
         if (material.RenderTexture == null)
         {
             Debug.Fail("Null particle texture: " + material.Texture);
             material.RenderTexture = new object(); // We don't want to try loading every call
         }
     }
     return material.RenderTexture as MyTexture2D;
 }
        private static void SetupEffect(ref MyTransparentMaterial materialProperties, MyTransparentMaterial blendMaterialProperties, bool colorize, float colorizeSoftDist, bool near, bool ignoreDepth, ref Matrix projectionMatrix)
        {
            MyEffectTransparentGeometry effect = MyRender.GetEffect(MyEffects.TransparentGeometry) as MyEffectTransparentGeometry;

            effect.SetBillboardTexture(GetTexture(materialProperties));
            effect.SetBillboardBlendTexture(GetTexture(blendMaterialProperties));

            effect.SetSoftParticleDistanceScale(materialProperties.SoftParticleDistanceScale);

            effect.SetAlphaMultiplierAndSaturation(1, materialProperties.AlphaSaturation);

            if (near)
            {
                effect.SetProjectionMatrix(ref MyRenderCamera.ProjectionMatrixForNearObjects);
                Matrix invProjectionMatrix = Matrix.Invert(MyRenderCamera.ProjectionMatrixForNearObjects);
                effect.SetInverseDefaultProjectionMatrix(ref invProjectionMatrix);
            }
            else
            {
                effect.SetProjectionMatrix(ref projectionMatrix);
                Matrix invProjectionMatrix = Matrix.Invert((MyRenderCamera.m_backupMatrix.HasValue ? MyRenderCamera.m_backupMatrix.Value : MyRenderCamera.ProjectionMatrix));
                effect.SetInverseDefaultProjectionMatrix(ref invProjectionMatrix);
            }

            if (MyRender.Settings.VisualizeOverdraw)
            {
                effect.SetTechnique(MyEffectTransparentGeometry.Technique.VisualizeOverdraw);
            }
            else
            {
                if (colorize)
                {
                    effect.SetColorizeSoftDistance(colorizeSoftDist);
                    effect.SetColorizeColor(ColorizeColor);
                    effect.SetColorizePlane(ColorizePlaneNormal, ColorizePlaneDistance);
                    effect.SetTechnique(MyEffectTransparentGeometry.Technique.ColorizeHeight);
                }
                else if (materialProperties.IgnoreDepth || ignoreDepth)
                {
                    effect.SetTechnique(MyEffectTransparentGeometry.Technique.IgnoreDepth);
                }
                else if (materialProperties.CanBeAffectedByOtherLights)
                {
                    effect.SetTechnique(MyEffectTransparentGeometry.Technique.Lit);
                }
                else if (materialProperties.Reflectivity > 0)
                {
                    effect.SetTechnique(MyEffectTransparentGeometry.Technique.Reflection);
                }
                else
                {
                    effect.SetTechnique(MyEffectTransparentGeometry.Technique.Unlit);
                }
            }
        }
 public static void AddMaterial(MyTransparentMaterial material)
 {
     m_materialsByName[material.Name] = material;
 }
        static MyTransparentMaterials()
        {
            ErrorMaterial = new MyTransparentMaterial("ErrorMaterial", "Textures\\FAKE.dds", 9999, false, false, Color.Pink.ToVector4());

            Clear();
        }
 public static bool TryGetMaterial(string materialName, out MyTransparentMaterial material)
 {
     return m_materialsByName.TryGetValue(materialName, out material);
 }
        static void AddBatch(int counter, int offset, TexId prevTexture, MyTransparentMaterial prevMaterial)
        {
            MyBillboardRendererBatch batch = new MyBillboardRendererBatch();

            batch.Offset = offset;
            batch.Num = counter - offset;
            batch.Texture = prevTexture;

            batch.Lit = prevMaterial.CanBeAffectedByOtherLights;
            batch.AlphaCutout = prevMaterial.AlphaCutout;

            m_batches.Add(batch);
        }
        static MyTransparentMaterials()
        {
            ErrorMaterial = new MyTransparentMaterial("ErrorMaterial", "Textures\\FAKE.dds", 9999, false, false, Color.Pink.ToVector4());

            Clear();
        }
 public static void AddMaterial(MyTransparentMaterial material)
 {
     m_materialsByName[material.Name] = material;
 }
Beispiel #9
0
        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);
            }
        }
        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++;
            }
        }
Beispiel #11
0
 public static bool TryGetMaterial(string materialName, out MyTransparentMaterial material)
 {
     return(m_materialsByName.TryGetValue(materialName, out material));
 }