Проблема с отображением большого количества объектов

Общие вопросы о Unity3D

Проблема с отображением большого количества объектов

Сообщение ShyRec 14 фев 2017, 15:49

Добрый день, форумчане.
Уже неделю я пытаюсь побороть артефакты с отображением большого количества кубов.
Коротко: есть данные, файл data.txt, который содержит информацию о размере кубов по y-координате. Отображается всё это через GPU Instancing.
Всё хорошо, кроме артефактов. Где-то в середине фрейма чёрная полоса и с 2ух боков ощущение, будто постоянно меняется очередь отрисовки у кубов, но это не точно. Похоже на проблемы с буфером глубины.

Пытался:
-Уменьшать масштаб кубов и уменьшать far и near plane камеры
-Вместо gpu instancing использовать ручное комбинирование мешей (CombineMeshes), записав цвета в вершины и истанс через drawmeshnow
-Вместо массива цветов использовать текстурную рампу
-Перепробовал все Blend моды в шейдере
-Все culling modes
-Отключал и вкючал буфер глубины разными способами
-Менял фруструм камеры (зачем-то)
-Подключал анти-алайзинг

Ничего не помогает. Не пробовал манипулировать буфером глубины (z-buffer), ибо на это моих скудных знаний не хватает.
На всякий случай версия Юнити 5.5.0f3

Видео с демонстрацией артефактов (фпс такой плохой ибо запись экрана + слабый ноутбук со встроенной видеокартой):


тестовый проект:
Скрытый текст:
https://drive.google.com/file/d/0ByatJvaR7W02a3Rna1lOSmxUcmc/view?usp=sharing


GPU Instancing:
Синтаксис:
Используется csharp
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

public class BunchOfCubes : MonoBehaviour
{
        public Mesh mesh; // mesh to draw (cube in this case)
        public Material mat; //material to draw gpu instanced cubes
        // public Vector2 size; // not used

        // public Color color;

        List<Matrix4x4> listMatrices;
       
        public MatrixConteiner[] matConteiner; // container for matrices

        // private List<Vector4> colors; // I used colors instead of texture ramp before. Same result.
        private List<float> rampVals; //values for texture ramp

        private List<MaterialPropertyBlock> blocks; // property blocks

        void Start()
        {
                Generate();
        }

        public void Generate()
        {
                // mesh = GameObject.CreatePrimitive(PrimitiveType.Cube).GetComponent<MeshFilter>().mesh;

                listMatrices = new List<Matrix4x4>();
                //Props = new MaterialPropertyBlock();
                // colors = new List<Vector4>();
                rampVals = new List<float>();
                blocks = new List<MaterialPropertyBlock>();

                // for (int x = 0; x <= size.x; x++)
                // {
                //      for (int y = 0; y < size.y; y++)
                //      {
                //              float rand = Random.Range(1f, 255f);

                //              Color col = Color.Lerp(Color.blue, Color.red, rand / 255f);
                //              // col = Color.red;
                //              colors.Add(col);
                //              listMatrices.Add(Matrix4x4.TRS(new Vector3(x, rand / 2, y), Quaternion.identity, new Vector3(1f, rand, 1f)));
                //      }
                // }

                float[,] data = DataReader.Inst.GetData();

                for (int x = 0; x < data.GetLength(0); x++)
                {
                        for (int y = 0; y < data.GetLength(1); y++)
                        {
                                // float scaleY = Random.Range(1f, 255f);
                                float scaleY = data[x,y];
                                // Color col = Color.Lerp(mat.GetColor("_Color0"), color, scaleY / 255f);
                                // colors.Add(col);
                                float rampVal = scaleY / 255f;
                                rampVals.Add(rampVal);
                                listMatrices.Add(Matrix4x4.TRS(new Vector3(x, scaleY / 2, y), Quaternion.identity, new Vector3(1f, scaleY, 1f)));
                        }
                }

                 // simply split matrices and material blocks in chuncks of 1000
                int len = listMatrices.Count / 1000;

                if (listMatrices.Count % 1000 == 0)
                        matConteiner = new MatrixConteiner[len];
                else
                        matConteiner = new MatrixConteiner[len + 1];
               
                int q = 0;
                for (int i = 0; i < listMatrices.Count; i++)
                {
                        if ((float)(i) % 1000 == 0)
                        {
                                MaterialPropertyBlock prop = new MaterialPropertyBlock();
                                Matrix4x4[] mats;
                               
                                int count = 0;
                                if (listMatrices.Count - i >= 1000) count = 1000;
                                else count = listMatrices.Count - i;
                                mats = new Matrix4x4[count];
                                mats = listMatrices.GetRange(i, count).ToArray();
                                matConteiner[q] = new MatrixConteiner(i, mats, count);

                                //prop.SetVectorArray("_Color", colors.GetRange(i, count));
                                prop.SetFloatArray("_RampVal", rampVals.GetRange(i, count));
                               
                                blocks.Add(prop);

                                // matConteiner[i].matrix = mats;
                                // matConteiner[i].i = i;
                                // matConteiner[i].count = count;
                               
                                q++;
                        }
                }
                //Props.SetVectorArray("_Color", colors);
                //Initialize camera  
                Camera.main.GetComponent<GameCamera>().Init(new Vector3(data.GetLength(0) / 2, 0, data.GetLength(1) / 2));     
        }
         void LateUpdate ()
         {     
                for (int i = 0; i < matConteiner.Length; i++)
                {
                        Graphics.DrawMeshInstanced(mesh, 0, mat, matConteiner[i].matrix, matConteiner[i].count, blocks[i], ShadowCastingMode.Off, false, 0);
                }
         }

        public class MatrixConteiner
        {
                public int i;
                public Matrix4x4[] matrix;
                public int count;

                public MatrixConteiner(int _i, Matrix4x4[] _matrix, int _count)
                {
                        i = _i;
                        matrix = _matrix;
                        count = _count;
                }
        }
       
}
 


Shader:
Синтаксис:
Используется csharp
Shader "Custom/TextureRamp"
{
        Properties
        {
                _Ramp("Texture ramp", 2D) = "white" {}
        }
        SubShader
        {
                //Tags { "RenderType"="Opaque" "Queue" = "Geometry" } //"UNITY_MAX_INSTANCE_COUNT"="150"
                // LOD 100
                Tags { "RenderType"="Opaque" "IgnoreProjector"="True" }

                Pass
                {
                        Cull Off
                        Blend One Zero
                        CGPROGRAM
                        #pragma vertex vert
                        #pragma fragment frag
                        // #pragma target 3.0
                        #pragma multi_compile_instancing
                        #include "UnityCG.cginc"

                        struct appdata
                        {
                                half4 vertex : POSITION;
                                UNITY_VERTEX_INPUT_INSTANCE_ID
                        };

                        struct v2f
                        {
                                half4 vertex : SV_POSITION;
                                float4 col : TEXCOORD1;
                                UNITY_VERTEX_INPUT_INSTANCE_ID
                        };

                        uniform sampler2D _Ramp;

                        UNITY_INSTANCING_CBUFFER_START (Props)
            UNITY_DEFINE_INSTANCED_PROP (fixed, _RampVal)
            UNITY_INSTANCING_CBUFFER_END
                       
                        v2f vert (appdata v)
                        {
                                v2f o;
                                UNITY_SETUP_INSTANCE_ID (v);
                UNITY_TRANSFER_INSTANCE_ID (v, o);
                                o.vertex = UnityObjectToClipPos (v.vertex);
                                // o.vertex = v.vertex;

                                o.col = tex2Dlod(_Ramp, float4(0, UNITY_ACCESS_INSTANCED_PROP(_RampVal), 0, 0));
                                //o.col = UNITY_ACCESS_INSTANCED_PROP (_Color); //lerp(_Color0, UNITY_ACCESS_INSTANCED_PROP (_Color), v.vertex.y + 0.5);
                                return o;
                        }
                       
                        fixed4 frag (v2f i) : SV_Target
                        {
                                // fixed4 col = _Color0;
                                // UNITY_SETUP_INSTANCE_ID (i);
                                return i.col;
                //return UNITY_ACCESS_INSTANCED_PROP (_Color);
                        }
                        ENDCG
                }
        }
}
 


В чём может быть причина? Возможно, я просто туплю и ответ на поверхности.
Спасайте советом или напутствие, дорогие форумчане. Совсем встрял с этой задачей
Скрытый текст:
За хреновый английский в комментах к коду прошу сильно не бить
Alien West
Изображение
ShyRec
UNIт
 
Сообщения: 140
Зарегистрирован: 23 май 2013, 13:02
Откуда: Астрахань

Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14