Beispiel #1
0
    private void RunCPUSorting(ref Vector3 _cameraPosition)
    {
        int index = 0;

        for (int i = 0; i < m_renderers.Count; i++)
        {
            List <ComputeShaderInputData> data = m_renderers[i].computeInstances;
            int dataSize = data.Count;

            // Update the cam to obj distances
            for (int p = 0; p < dataSize; p++)
            {
                ComputeShaderInputData d = data[p];
                d.distanceToCamera = Vector3.Distance(d.position, _cameraPosition);
                data[p]            = d;
            }

            // Sort
            data.Sort(
                (a, b) =>
            {
                return(a.distanceToCamera <= b.distanceToCamera ? -1 : 1);
            }
                );

            for (int j = 0; j < dataSize; j++)
            {
                instancesPositionsArray[index] = data[j];
                index++;
            }
        }
        m_positionsBuffer.SetData(instancesPositionsArray);
    }
Beispiel #2
0
    private void Log00Sorting()
    {
        if (m_debugLog != DebugLog.AfterSorting)
        {
            return;
        }
        m_debugLog = DebugLog.DontLog;

        StringBuilder sb = new StringBuilder();

        ComputeShaderInputData[] distanceData = new ComputeShaderInputData[m_numberOfInstances];
        m_positionsBuffer.GetData(distanceData);
        sb.AppendLine("00 distances:");
        for (int i = 0; i < distanceData.Length; i++)
        {
            if (i % 350 == 0)
            {
                Debug.Log(sb.ToString());
                sb = new StringBuilder();
            }
            sb.AppendLine(i + ": " + distanceData[i].drawCallID + " => " + distanceData[i].distanceToCamera + " => " + distanceData[i].position);
        }
        Debug.Log(sb.ToString());
    }
Beispiel #3
0
    public void Initialize()
    {
        m_00_lodSortingCSKernelID          = m_00_lodSortingCS.FindKernel("BitonicSort");
        m_00_lodSortingTransposeCSKernelID = m_00_lodSortingCS.FindKernel("MatrixTranspose");
        m_01_occlusionKernelID             = m_01_occlusionCS.FindKernel("CSMain");
        m_02_scanInstancesKernelID         = m_02_scanInstancesCS.FindKernel("CSMain");
        m_03_scanGroupSumsKernelID         = m_03_scanGroupSumsCS.FindKernel("CSMain");
        m_04_copyInstanceDataKernelID      = m_04_copyInstanceDataCS.FindKernel("CSMain");
        m_05_calcInstanceOffsetsKernelID   = m_05_calcInstanceOffsetsCS.FindKernel("CSMain");

        int materialPropertyCounter = 0;
        int instanceCounter         = 0;

        m_args = new uint[m_instances.Count * NUMBER_OF_ARGS_PER_INSTANCE];
        for (int i = 0; i < m_instances.Count; i++)
        {
            IndirectRenderingMesh irm  = new IndirectRenderingMesh();
            IndirectInstanceData  data = m_instances[i];

            // Initialize Mesh
            irm.mesh = new Mesh();
            irm.mesh.CombineMeshes(
                new CombineInstance[] {
                new CombineInstance()
                {
                    mesh = data.lod00Mesh
                },
                new CombineInstance()
                {
                    mesh = data.lod01Mesh
                },
                new CombineInstance()
                {
                    mesh = data.lod02Mesh
                }
            },
                true,                           // Merge Submeshes
                false,                          // Use Matrices
                false                           // Has lightmap data
                );

            // Arguments
            int argsIndex = i * NUMBER_OF_ARGS_PER_INSTANCE;

            // Buffer with arguments has to have five integer numbers
            // LOD00
            m_args[argsIndex + 0] = data.lod00Mesh.GetIndexCount(0);                            // 0 - index count per instance,
            m_args[argsIndex + 1] = 0;                                                          // 1 - instance count
            m_args[argsIndex + 2] = 0;                                                          // 2 - start index location
            m_args[argsIndex + 3] = 0;                                                          // 3 - base vertex location
            m_args[argsIndex + 4] = 0;                                                          // 4 - start instance location

            // LOD01
            m_args[argsIndex + 5] = data.lod01Mesh.GetIndexCount(0);                    // 0 - index count per instance,
            m_args[argsIndex + 6] = 0;                                                  // 1 - instance count
            m_args[argsIndex + 7] = m_args[argsIndex + 0] + m_args[argsIndex + 2];      // 2 - start index location
            m_args[argsIndex + 8] = 0;                                                  // 3 - base vertex location
            m_args[argsIndex + 9] = 0;                                                  // 4 - start instance location

            // LOD02
            m_args[argsIndex + 10] = data.lod02Mesh.GetIndexCount(0);                   // 0 - index count per instance,
            m_args[argsIndex + 11] = 0;                                                 // 1 - instance count
            m_args[argsIndex + 12] = m_args[argsIndex + 5] + m_args[argsIndex + 7];     // 2 - start index location
            m_args[argsIndex + 13] = 0;                                                 // 3 - base vertex location
            m_args[argsIndex + 14] = 0;                                                 // 4 - start instance location


            // Materials
            irm.Lod00MatPropBlock = new MaterialPropertyBlock();
            irm.Lod01MatPropBlock = new MaterialPropertyBlock();
            irm.Lod02MatPropBlock = new MaterialPropertyBlock();

            // ----------------------------------------------------------
            // Silly workaround for a shadow bug.
            // If we don't set a unique value to the property block we
            // only get shadows in one of our draw calls.
            irm.Lod00MatPropBlock.SetFloat("_Whatever" + materialPropertyCounter++, 1);
            irm.Lod01MatPropBlock.SetFloat("_Whatever" + materialPropertyCounter++, 2);
            irm.Lod02MatPropBlock.SetFloat("_Whatever" + materialPropertyCounter++, 3);
            // End of silly workaround!
            // ----------------------------------------------------------

            irm.Lod00MatPropBlock.SetBuffer("positionBuffer", m_culledInstanceBuffer);
            irm.Lod01MatPropBlock.SetBuffer("positionBuffer", m_culledInstanceBuffer);
            irm.Lod02MatPropBlock.SetBuffer("positionBuffer", m_culledInstanceBuffer);

            irm.material = new Material(data.material);

            // Add the instance data (positions, rotations, scaling, bounds...)
            for (int j = 0; j < m_instances[i].positions.Length; j++)
            {
                instanceCounter++;
                IndirectInstanceData   _data   = m_instances[i];
                ComputeShaderInputData newData = new ComputeShaderInputData();

                Bounds b = new Bounds();
                b.Encapsulate(_data.lod00Mesh.bounds);
                b.Encapsulate(_data.lod01Mesh.bounds);
                b.Encapsulate(_data.lod02Mesh.bounds);
                // b.extents *= _data.uniformScales[j];

                newData.drawCallID       = (uint)i * NUMBER_OF_ARGS_PER_INSTANCE;
                newData.position         = _data.positions[j];
                newData.rotation         = _data.rotations[j];
                newData.uniformScale     = _data.uniformScales[j];
                newData.boundsCenter     = _data.positions[j];
                newData.boundsExtents    = b.extents * 0.5f;
                newData.distanceToCamera = Vector3.Distance(newData.position, m_camera.transform.position);

                irm.computeInstances.Add(newData);
            }

            // Add the data to the renderer list
            m_renderers.Add(irm);
        }

        // HACK! Padding the data so it becomes the power of two.
        if (!Mathf.IsPowerOfTwo(instanceCounter))
        {
            int iterations = Mathf.NextPowerOfTwo(instanceCounter) - instanceCounter;
            for (int j = 0; j < iterations; j++)
            {
                m_renderers[0].computeInstances.Add(new ComputeShaderInputData()
                {
                    drawCallID = HACK_POT_PADDING_DRAW_ID
                });
            }
        }

        List <ComputeShaderInputData> tempInstancesPositionsList = new List <ComputeShaderInputData>();

        for (int i = 0; i < m_renderers.Count; i++)
        {
            tempInstancesPositionsList.AddRange(m_renderers[i].computeInstances);
        }

        instancesPositionsArray = tempInstancesPositionsList.ToArray();
        m_numberOfInstances     = tempInstancesPositionsList.Count;

        InitializeBuffers();
    }