public void Dispose()
        {
            for (int i = 0; i <= VegetationItemMatrixList.Count - 1; i++)
            {
                VegetationItemMatrixList[i].Dispose();
            }

            VegetationItemMatrixList.Clear();

            for (int i = 0; i <= VegetationItemInstancedIndirectInstanceList.Count - 1; i++)
            {
                if (VegetationItemInstancedIndirectInstanceList[i].Created)
                {
                    VegetationItemInstancedIndirectInstanceList[i].InstancedIndirectInstanceList.Dispose();
                }
            }

            for (int i = 0; i <= VegetationItemComputeBufferList.Count - 1; i++)
            {
                ComputeBufferInfo computeBufferInfo = VegetationItemComputeBufferList[i];
                if (computeBufferInfo.Created)
                {
                    computeBufferInfo.ComputeBuffer.Dispose();
                    computeBufferInfo.Created = false;
                }
            }
            if (LoadStateList.IsCreated)
            {
                LoadStateList.Dispose();
            }
        }
Ejemplo n.º 2
0
        void DrawCellsIndirectComputeShader()
        {
            Profiler.BeginSample("Draw instanced indirect vegetation");

            float lodBias = QualitySettings.lodBias * VegetationSettings.LODDistanceFactor;

            Vector4 floatingOriginOffsetVector4 = new Vector4(FloatingOriginOffset.x, FloatingOriginOffset.y, FloatingOriginOffset.z, 0);

            Vector3 sunLightDirection = SunDirectionalLight ? SunDirectionalLight.transform.forward : new Vector3(0, 0, 0);
            float   minBoundsHeight   = VegetationSystemBounds.center.y - VegetationSystemBounds.extents.y;
            Vector3 planeOrigin       = new Vector3(0, minBoundsHeight, 0);
            bool    shadowCulling     = (SunDirectionalLight != null);

            for (int i = 0; i <= VegetationStudioCameraList.Count - 1; i++)
            {
                if (!VegetationStudioCameraList[i].Enabled)
                {
                    continue;
                }
                if (VegetationStudioCameraList[i].RenderBillboardsOnly)
                {
                    continue;
                }

                SetFrustumCullingPlanes(VegetationStudioCameraList[i].SelectedCamera);

                var targetCamera = VegetationStudioCameraList[i].RenderDirectToCamera
                    ? VegetationStudioCameraList[i].SelectedCamera
                    : null;

                for (int j = 0; j <= VegetationPackageProList.Count - 1; j++)
                {
                    for (int k = 0; k <= VegetationPackageProList[j].VegetationInfoList.Count - 1; k++)
                    {
                        VegetationItemInfoPro vegetationItemInfo = VegetationPackageProList[j].VegetationInfoList[k];
                        if (vegetationItemInfo.VegetationRenderMode != VegetationRenderMode.InstancedIndirect)
                        {
                            continue;
                        }

                        VegetationItemModelInfo vegetationItemModelInfo =
                            VegetationPackageProModelsList[j].VegetationItemModelList[k];



                        float vegetationItemCullDistance;

                        float renderDistanceFactor = vegetationItemModelInfo.VegetationItemInfo.RenderDistanceFactor;
                        if (VegetationSettings.DisableRenderDistanceFactor)
                        {
                            renderDistanceFactor = 1;
                        }

                        //if (vegetationItemModelInfo.DistanceBand == 0)
                        if (vegetationItemModelInfo.VegetationItemInfo.VegetationType == VegetationType.Tree || vegetationItemModelInfo.VegetationItemInfo.VegetationType == VegetationType.LargeObjects)
                        {
                            vegetationItemCullDistance = VegetationSettings.GetTreeDistance() * renderDistanceFactor;
                        }
                        else
                        {
                            vegetationItemCullDistance = VegetationSettings.GetVegetationDistance() * renderDistanceFactor;
                        }

                        ShadowCastingMode shadowCastingMode =
                            VegetationSettings.GetShadowCastingMode(vegetationItemInfo.VegetationType);

                        if (vegetationItemInfo.DisableShadows)
                        {
                            shadowCastingMode = ShadowCastingMode.Off;
                        }

                        bool useShadowCulling = shadowCulling && shadowCastingMode == ShadowCastingMode.On;
                        useShadowCulling = useShadowCulling && vegetationItemModelInfo.DistanceBand == 1;

                        LayerMask layer = VegetationSettings.GetLayer(vegetationItemInfo.VegetationType);

                        int totalInstanceCount = 0;
                        _hasBufferList.Clear();
                        for (int l = 0;
                             l <= VegetationStudioCameraList[i].JobCullingGroup.VisibleCellIndexList.Length - 1;
                             l++)
                        {
                            int potentialVisibleCellIndex =
                                VegetationStudioCameraList[i].JobCullingGroup.VisibleCellIndexList[l];
                            VegetationCell vegetationCell = VegetationStudioCameraList[i]
                                                            .PotentialVisibleCellList[potentialVisibleCellIndex];

                            BoundingSphereInfo boundingSphereInfo = VegetationStudioCameraList[i]
                                                                    .GetBoundingSphereInfo(potentialVisibleCellIndex);

                            int vegetationItemDistanceBand = vegetationItemModelInfo.DistanceBand;

                            if (boundingSphereInfo.CurrentDistanceBand > vegetationItemDistanceBand)
                            {
                                continue;
                            }

                            if (vegetationCell.VegetationPackageInstancesList[j].VegetationItemMatrixList[k].Length == 0)
                            {
                                continue;
                            }

                            ComputeBufferInfo computeBufferInfo = vegetationCell.VegetationPackageInstancesList[j]
                                                                  .VegetationItemComputeBufferList[k];
                            if (!computeBufferInfo.Created)
                            {
                                continue;
                            }

                            _hasBufferList.Add(vegetationCell);
                        }

                        if (_hasBufferList.Count == 0)
                        {
                            continue;
                        }

                        int buffercount = 15;
                        for (int m = 0; m <= _hasBufferList.Count - 1; m++)
                        {
                            totalInstanceCount += _hasBufferList[m].VegetationPackageInstancesList[j]
                                                  .VegetationItemMatrixList[k].Length;
                        }

                        if (totalInstanceCount == 0)
                        {
                            continue;
                        }

                        CameraComputeBuffers cameraComputeBuffers = vegetationItemModelInfo.CameraComputeBufferList[i];

                        if (totalInstanceCount > cameraComputeBuffers.MergeBuffer.count)
                        {
                            cameraComputeBuffers.UpdateComputeBufferSize(totalInstanceCount + 5000);
                        }

                        cameraComputeBuffers.MergeBuffer.SetCounterValue(0);
                        MergeBufferShader.SetBuffer(MergeBufferKernelHandle, _mergeBufferID,
                                                    cameraComputeBuffers.MergeBuffer);

                        for (int m = 0; m <= _hasBufferList.Count - 1; m += buffercount)
                        {
                            int instanceCount0 = _hasBufferList[m].VegetationPackageInstancesList[j]
                                                 .VegetationItemMatrixList[k].Length;

                            for (int n = 1; n <= buffercount - 1; n++)
                            {
                                if (m + n < _hasBufferList.Count)
                                {
                                    int tempInstanceCount = _hasBufferList[m + n].VegetationPackageInstancesList[j]
                                                            .VegetationItemMatrixList[k].Length;
                                    if (tempInstanceCount > instanceCount0)
                                    {
                                        instanceCount0 = tempInstanceCount;
                                    }
                                }
                            }

                            // ReSharper disable once RedundantCast
                            int threadGroups = Mathf.CeilToInt((float)instanceCount0 / 32f);
                            if (threadGroups == 0)
                            {
                                continue;
                            }

                            SetComputeShaderBuffer(_mergeSourceBuffer0ID, _mergeInstanceCount0ID, m, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer1ID, _mergeInstanceCount1ID, m + 1, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer2ID, _mergeInstanceCount2ID, m + 2, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer3ID, _mergeInstanceCount3ID, m + 3, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer4ID, _mergeInstanceCount4ID, m + 4, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer5ID, _mergeInstanceCount5ID, m + 5, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer6ID, _mergeInstanceCount6ID, m + 6, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer7ID, _mergeInstanceCount7ID, m + 7, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer8ID, _mergeInstanceCount8ID, m + 8, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer9ID, _mergeInstanceCount9ID, m + 9, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer10ID, _mergeInstanceCount10ID, m + 10, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer11ID, _mergeInstanceCount11ID, m + 11, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer12ID, _mergeInstanceCount12ID, m + 12, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer13ID, _mergeInstanceCount13ID, m + 13, j, k);
                            SetComputeShaderBuffer(_mergeSourceBuffer14ID, _mergeInstanceCount14ID, m + 14, j, k);

                            MergeBufferShader.Dispatch(MergeBufferKernelHandle, threadGroups, 1, 1);
                        }

                        for (int n = 0; n <= vegetationItemModelInfo.VegetationMeshLod0.subMeshCount - 1; n++)
                        {
                            ComputeBuffer.CopyCount(cameraComputeBuffers.MergeBuffer,
                                                    cameraComputeBuffers.ArgsBufferMergedLOD0List[n], sizeof(uint) * 1);
                        }

                        int threadGroupsFrustum = Mathf.CeilToInt(totalInstanceCount / 32f);
                        if (threadGroupsFrustum == 0)
                        {
                            continue;
                        }

                        cameraComputeBuffers.VisibleBufferLOD0.SetCounterValue(0);
                        cameraComputeBuffers.VisibleBufferLOD1.SetCounterValue(0);
                        cameraComputeBuffers.VisibleBufferLOD2.SetCounterValue(0);
                        cameraComputeBuffers.VisibleBufferLOD3.SetCounterValue(0);

                        cameraComputeBuffers.ShadowBufferLOD0.SetCounterValue(0);
                        cameraComputeBuffers.ShadowBufferLOD1.SetCounterValue(0);
                        cameraComputeBuffers.ShadowBufferLOD2.SetCounterValue(0);
                        cameraComputeBuffers.ShadowBufferLOD3.SetCounterValue(0);

                        bool useLODs = true;

                        FrusumMatrixShader.SetFloat(_cullFarStartID, vegetationItemCullDistance);

                        FrusumMatrixShader.SetVector(_floatingOriginOffsetID, floatingOriginOffsetVector4);

                        FrusumMatrixShader.SetBuffer(FrustumKernelHandle, _sourceBufferID,
                                                     cameraComputeBuffers.MergeBuffer);
                        FrusumMatrixShader.SetBuffer(FrustumKernelHandle, _visibleBufferLod0ID,
                                                     cameraComputeBuffers.VisibleBufferLOD0);
                        FrusumMatrixShader.SetBuffer(FrustumKernelHandle, _visibleBufferLod1ID,
                                                     cameraComputeBuffers.VisibleBufferLOD1);
                        FrusumMatrixShader.SetBuffer(FrustumKernelHandle, _visibleBufferLod2ID,
                                                     cameraComputeBuffers.VisibleBufferLOD2);
                        FrusumMatrixShader.SetBuffer(FrustumKernelHandle, _visibleBufferLod3ID,
                                                     cameraComputeBuffers.VisibleBufferLOD3);

                        FrusumMatrixShader.SetBuffer(FrustumKernelHandle, _shadowBufferLod0ID,
                                                     cameraComputeBuffers.ShadowBufferLOD0);
                        FrusumMatrixShader.SetBuffer(FrustumKernelHandle, _shadowBufferLod1ID,
                                                     cameraComputeBuffers.ShadowBufferLOD1);
                        FrusumMatrixShader.SetBuffer(FrustumKernelHandle, _shadowBufferLod2ID,
                                                     cameraComputeBuffers.ShadowBufferLOD2);
                        FrusumMatrixShader.SetBuffer(FrustumKernelHandle, _shadowBufferLod3ID,
                                                     cameraComputeBuffers.ShadowBufferLOD3);

                        FrusumMatrixShader.SetInt(_instanceCountID, totalInstanceCount);
                        FrusumMatrixShader.SetBool(_useLodsID, useLODs);
                        FrusumMatrixShader.SetBool(_noFrustumCullingID, VegetationStudioCameraList[i].CameraCullingMode == CameraCullingMode.Complete360);
                        FrusumMatrixShader.SetBool(_shadowCullingID, useShadowCulling);

                        FrusumMatrixShader.SetFloat(_boundingSphereRadiusID,
                                                    vegetationItemModelInfo.BoundingSphereRadius);

                        FrusumMatrixShader.SetFloat(_lod1Distance, vegetationItemModelInfo.LOD1Distance);
                        FrusumMatrixShader.SetFloat(_lod2Distance, vegetationItemModelInfo.LOD2Distance);
                        FrusumMatrixShader.SetFloat(_lod3Distance, vegetationItemModelInfo.LOD3Distance);

                        FrusumMatrixShader.SetVector(_lightDirection, sunLightDirection);
                        FrusumMatrixShader.SetVector(_planeOrigin, planeOrigin);
                        FrusumMatrixShader.SetVector(_boundsSize, vegetationItemModelInfo.VegetationItemInfo.Bounds.size);

                        FrusumMatrixShader.SetFloat(_lodFactor, vegetationItemInfo.LODFactor);
                        FrusumMatrixShader.SetFloat(_lodBias, lodBias * 2);
                        FrusumMatrixShader.SetFloat(_lodFadeDistance, 10);
                        FrusumMatrixShader.SetInt(_lodCount, vegetationItemModelInfo.LODCount);

                        FrusumMatrixShader.Dispatch(FrustumKernelHandle, threadGroupsFrustum, 1, 1);

                        for (int n = 0; n <= vegetationItemModelInfo.VegetationMeshLod0.subMeshCount - 1; n++)
                        {
                            ComputeBuffer.CopyCount(cameraComputeBuffers.VisibleBufferLOD0,
                                                    cameraComputeBuffers.ArgsBufferMergedLOD0List[n], sizeof(uint) * 1);

                            ComputeBuffer.CopyCount(cameraComputeBuffers.ShadowBufferLOD0,
                                                    cameraComputeBuffers.ShadowArgsBufferMergedLOD0List[n], sizeof(uint) * 1);
                        }

                        if (useLODs)
                        {
                            for (int n = 0; n <= vegetationItemModelInfo.VegetationMeshLod1.subMeshCount - 1; n++)
                            {
                                ComputeBuffer.CopyCount(cameraComputeBuffers.VisibleBufferLOD1,
                                                        cameraComputeBuffers.ArgsBufferMergedLOD1List[n], sizeof(uint) * 1);

                                ComputeBuffer.CopyCount(cameraComputeBuffers.ShadowBufferLOD1,
                                                        cameraComputeBuffers.ShadowArgsBufferMergedLOD1List[n], sizeof(uint) * 1);
                            }

                            for (int n = 0; n <= vegetationItemModelInfo.VegetationMeshLod2.subMeshCount - 1; n++)
                            {
                                ComputeBuffer.CopyCount(cameraComputeBuffers.VisibleBufferLOD2,
                                                        cameraComputeBuffers.ArgsBufferMergedLOD2List[n], sizeof(uint) * 1);

                                ComputeBuffer.CopyCount(cameraComputeBuffers.ShadowBufferLOD2,
                                                        cameraComputeBuffers.ShadowArgsBufferMergedLOD2List[n], sizeof(uint) * 1);
                            }

                            for (int n = 0; n <= vegetationItemModelInfo.VegetationMeshLod3.subMeshCount - 1; n++)
                            {
                                ComputeBuffer.CopyCount(cameraComputeBuffers.VisibleBufferLOD3,
                                                        cameraComputeBuffers.ArgsBufferMergedLOD3List[n], sizeof(uint) * 1);

                                ComputeBuffer.CopyCount(cameraComputeBuffers.ShadowBufferLOD3,
                                                        cameraComputeBuffers.ShadowArgsBufferMergedLOD3List[n], sizeof(uint) * 1);
                            }
                        }

                        //TODO calculate bounds one for each LOD
                        float boundsDistance = vegetationItemCullDistance * 2 +
                                               vegetationItemModelInfo.BoundingSphereRadius;
                        Bounds cellBounds = new Bounds(VegetationStudioCameraList[i].SelectedCamera.transform.position,
                                                       new Vector3(boundsDistance, boundsDistance, boundsDistance));

                        RenderVegetationItemLODIndirect(vegetationItemModelInfo, cellBounds, 0, i,
                                                        targetCamera, shadowCastingMode, layer, false);

                        if (shadowCastingMode == ShadowCastingMode.On)
                        {
                            RenderVegetationItemLODIndirect(vegetationItemModelInfo, cellBounds, 0, i,
                                                            targetCamera, ShadowCastingMode.ShadowsOnly, layer, true);
                        }

                        if (useLODs)
                        {
                            if (vegetationItemModelInfo.LODCount > 1)
                            {
                                RenderVegetationItemLODIndirect(vegetationItemModelInfo, cellBounds, 1, i,
                                                                targetCamera, shadowCastingMode, layer, false);

                                if (shadowCastingMode == ShadowCastingMode.On)
                                {
                                    RenderVegetationItemLODIndirect(vegetationItemModelInfo, cellBounds, 1, i,
                                                                    targetCamera, ShadowCastingMode.ShadowsOnly, layer, true);
                                }
                            }

                            if (vegetationItemModelInfo.LODCount > 2)
                            {
                                RenderVegetationItemLODIndirect(vegetationItemModelInfo, cellBounds, 2, i,
                                                                targetCamera, shadowCastingMode, layer, false);

                                if (shadowCastingMode == ShadowCastingMode.On)
                                {
                                    RenderVegetationItemLODIndirect(vegetationItemModelInfo, cellBounds, 2, i,
                                                                    targetCamera, ShadowCastingMode.ShadowsOnly, layer, true);
                                }
                            }

                            if (vegetationItemModelInfo.LODCount > 3)
                            {
                                RenderVegetationItemLODIndirect(vegetationItemModelInfo, cellBounds, 3, i,
                                                                targetCamera, shadowCastingMode, layer, false);
                                if (shadowCastingMode == ShadowCastingMode.On)
                                {
                                    RenderVegetationItemLODIndirect(vegetationItemModelInfo, cellBounds, 3, i,
                                                                    targetCamera, ShadowCastingMode.ShadowsOnly, layer, true);
                                }
                            }
                        }
                    }
                }
            }
            Profiler.EndSample();
        }