Пример #1
0
        public virtual void InitializeRuntimeDataAndBuffers(bool forceNew = true)
        {
            GPUInstancerUtility.SetPlatformDependentVariables();
            if (forceNew || !isInitialized)
            {
                instancingBounds = new Bounds(Vector3.zero, Vector3.one * GPUInstancerConstants.gpuiSettings.instancingBoundsSize);

                GPUInstancerUtility.ReleaseInstanceBuffers(runtimeDataList);
                GPUInstancerUtility.ReleaseSPBuffers(spData);
                if (runtimeDataList != null)
                {
                    runtimeDataList.Clear();
                }
                else
                {
                    runtimeDataList = new List <GPUInstancerRuntimeData>();
                }

                if (runtimeDataDictionary != null)
                {
                    runtimeDataDictionary.Clear();
                }
                else
                {
                    runtimeDataDictionary = new Dictionary <GPUInstancerPrototype, GPUInstancerRuntimeData>();
                }

                if (prototypeList == null)
                {
                    prototypeList = new List <GPUInstancerPrototype>();
                }
            }
        }
Пример #2
0
 public virtual void ClearInstancingData()
 {
     GPUInstancerUtility.ReleaseInstanceBuffers(runtimeDataList);
     GPUInstancerUtility.ReleaseSPBuffers(spData);
     if (runtimeDataList != null)
     {
         runtimeDataList.Clear();
     }
     spData = null;
     threadStartQueue.Clear();
     threadQueue.Clear();
     isInitialized = false;
 }
Пример #3
0
        public virtual void InitializeRuntimeDataAndBuffers(bool forceNew = true)
        {
            if (forceNew || !isInitialized)
            {
                instancingBounds = new Bounds(Vector3.zero, Vector3.one * 10000f);

                GPUInstancerUtility.ReleaseInstanceBuffers(runtimeDataList);
                GPUInstancerUtility.ReleaseSPBuffers(spData);
                if (runtimeDataList != null)
                {
                    runtimeDataList.Clear();
                }
                else
                {
                    runtimeDataList = new List <GPUInstancerRuntimeData>();
                }

                if (prototypeList == null)
                {
                    prototypeList = new List <GPUInstancerPrototype>();
                }
            }
        }
Пример #4
0
        public IEnumerator ReplaceUnityTrees()
        {
            _isCoroutineActive = true;
            if (prototypeList.Count > 0)
            {
                Vector4[] treeScales = new Vector4[prototypeList.Count];
                int       count      = 0;
                foreach (GPUInstancerTreePrototype tp in prototypeList)
                {
                    treeScales[count] = tp.isApplyPrefabScale ? tp.prefabObject.transform.localScale : Vector3.one;
                    count++;
                }
                int[] instanceCounts = new int[prototypeList.Count];

                List <Vector4> treeDataList = new List <Vector4>(); // prototypeIndex - positionx3 - rotation - scalex2

                int instanceTotal = 0;
                foreach (Terrain terrain in _terrains)
                {
                    if (terrain == null)
                    {
                        continue;
                    }
                    if (terrain.terrainData.treePrototypes.Length > prototypeList.Count)
                    {
                        Debug.LogError("Additional Terrain has more Tree protototypes than defined prototypes on the Tree Manager. Tree Manager requires every Terrain to have the same Tree prototypes defined.", terrain);
                        continue;
                    }

                    terrain.treeDistance = 0f; // will not persist if called at runtime.
                    Vector3        terrainSize     = terrain.terrainData.size;
                    Vector3        terrainPosition = terrain.GetPosition();
                    TreeInstance[] treeInstances   = terrain.terrainData.treeInstances;
                    instanceTotal += treeInstances.Length;
                    foreach (TreeInstance treeInstance in treeInstances)
                    {
                        treeDataList.Add(new Vector4(
                                             treeInstance.prototypeIndex,
                                             treeInstance.position.x * terrainSize.x + terrainPosition.x,
                                             treeInstance.position.y * terrainSize.y + terrainPosition.y,
                                             treeInstance.position.z * terrainSize.z + terrainPosition.z
                                             ));

                        treeDataList.Add(new Vector4(
                                             treeInstance.rotation,
                                             treeInstance.widthScale,
                                             treeInstance.heightScale,
                                             0
                                             ));
                        instanceCounts[treeInstance.prototypeIndex]++;
                    }
                }

                if (instanceTotal > 0)
                {
                    if (initializeWithCoroutine && !isInitialized)
                    {
                        yield return(null);
                    }

                    ComputeBuffer treeDataBuffer = new ComputeBuffer(treeDataList.Count, GPUInstancerConstants.STRIDE_SIZE_FLOAT4);
#if UNITY_2019_1_OR_NEWER
                    treeDataBuffer.SetData(treeDataList);
#else
                    treeDataBuffer.SetData(treeDataList.ToArray());
#endif
                    ComputeBuffer treeScalesBuffer = new ComputeBuffer(treeScales.Length, GPUInstancerConstants.STRIDE_SIZE_FLOAT4);
                    treeScalesBuffer.SetData(treeScales);
                    ComputeBuffer counterBuffer    = new ComputeBuffer(1, GPUInstancerConstants.STRIDE_SIZE_INT);
                    uint[]        emptyCounterData = new uint[1];

                    treeDataList = null;
                    treeScales   = null;

                    GPUInstancerRuntimeData runtimeData;
                    for (int i = 0; i < runtimeDataList.Count; i++)
                    {
                        runtimeData = runtimeDataList[i];
                        int instanceCount = instanceCounts[i];
                        runtimeData.bufferSize    = instanceCount;
                        runtimeData.instanceCount = instanceCount;
                        if (instanceCount == 0)
                        {
                            GPUInstancerUtility.ReleaseInstanceBuffers(runtimeData);
                            continue;
                        }

                        counterBuffer.SetData(emptyCounterData);
                        if (runtimeData.transformationMatrixVisibilityBuffer != null)
                        {
                            runtimeData.transformationMatrixVisibilityBuffer.Release();
                        }
                        runtimeData.transformationMatrixVisibilityBuffer = new ComputeBuffer(instanceCount, GPUInstancerConstants.STRIDE_SIZE_MATRIX4X4);

                        _treeInstantiationComputeShader.SetBuffer(0,
                                                                  GPUInstancerConstants.VisibilityKernelPoperties.INSTANCE_DATA_BUFFER, runtimeData.transformationMatrixVisibilityBuffer);
                        _treeInstantiationComputeShader.SetBuffer(0,
                                                                  GPUInstancerConstants.TreeKernelProperties.TREE_DATA, treeDataBuffer);
                        _treeInstantiationComputeShader.SetBuffer(0,
                                                                  GPUInstancerConstants.TreeKernelProperties.TREE_SCALES, treeScalesBuffer);
                        _treeInstantiationComputeShader.SetBuffer(0,
                                                                  GPUInstancerConstants.GrassKernelProperties.COUNTER_BUFFER, counterBuffer);
                        _treeInstantiationComputeShader.SetInt(
                            GPUInstancerConstants.VisibilityKernelPoperties.BUFFER_PARAMETER_BUFFER_SIZE, instanceTotal);
                        //_treeInstantiationComputeShader.SetVector(
                        //    GPUInstancerConstants.GrassKernelProperties.TERRAIN_SIZE_DATA, terrain.terrainData.size);
                        //_treeInstantiationComputeShader.SetVector(
                        //    GPUInstancerConstants.TreeKernelProperties.TERRAIN_POSITION, terrain.GetPosition());
                        _treeInstantiationComputeShader.SetBool(
                            GPUInstancerConstants.TreeKernelProperties.IS_APPLY_ROTATION, ((GPUInstancerTreePrototype)runtimeData.prototype).isApplyRotation);
                        _treeInstantiationComputeShader.SetBool(
                            GPUInstancerConstants.TreeKernelProperties.IS_APPLY_TERRAIN_HEIGHT, ((GPUInstancerTreePrototype)runtimeData.prototype).isApplyTerrainHeight);
                        _treeInstantiationComputeShader.SetInt(
                            GPUInstancerConstants.TreeKernelProperties.PROTOTYPE_INDEX, i);

                        _treeInstantiationComputeShader.Dispatch(0,
                                                                 Mathf.CeilToInt(instanceTotal / GPUInstancerConstants.COMPUTE_SHADER_THREAD_COUNT), 1, 1);

                        GPUInstancerUtility.InitializeGPUBuffer(runtimeData);

                        if (initializeWithCoroutine && !isInitialized)
                        {
                            yield return(null);
                        }
                    }

                    treeDataBuffer.Release();
                    treeScalesBuffer.Release();
                    counterBuffer.Release();
                }
                else
                {
                    GPUInstancerUtility.ReleaseInstanceBuffers(runtimeDataList);
                }
            }

            isInitial = true;
            if (!isInitialized)
            {
                GPUInstancerUtility.TriggerEvent(GPUInstancerEventType.TreeInitializationFinished);
            }
            _isCoroutineActive = false;
        }