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>(); } } }
public virtual void ClearInstancingData() { GPUInstancerUtility.ReleaseInstanceBuffers(runtimeDataList); GPUInstancerUtility.ReleaseSPBuffers(spData); if (runtimeDataList != null) { runtimeDataList.Clear(); } spData = null; threadStartQueue.Clear(); threadQueue.Clear(); isInitialized = false; }
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>(); } } }
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; }