Пример #1
0
        public VegetationPackageProModelInfo(VegetationPackagePro vegetationPackagePro, EnvironmentSettings environmentSettings, List <GameObject> windSamplerList, int cameraCount)
        {
            EnvironmentSettings = environmentSettings;

            for (int i = 0; i <= vegetationPackagePro.VegetationInfoList.Count - 1; i++)
            {
                VegetationItemModelInfo vegetationItemModelInfo =
                    new VegetationItemModelInfo(vegetationPackagePro.VegetationInfoList[i], EnvironmentSettings, windSamplerList, cameraCount);
                VegetationItemModelList.Add(vegetationItemModelInfo);
            }
        }
Пример #2
0
        void RenderVegetationItemLODIndirect(VegetationItemModelInfo vegetationItemModelInfo, Bounds cellBounds, int lodIndex, int cameraIndex, Camera selectedCamera, ShadowCastingMode shadowCastingMode, int layer, bool shadows)
        {
            MaterialPropertyBlock materialPropertyBlock = vegetationItemModelInfo.GetLODMaterialPropertyBlock(lodIndex);

            materialPropertyBlock.Clear();

            ComputeBuffer visibleBuffer = vegetationItemModelInfo.GetLODVisibleBuffer(lodIndex, cameraIndex, shadows);

            Mesh mesh = vegetationItemModelInfo.GetLODMesh(lodIndex);

            Material[] materials = vegetationItemModelInfo.GetLODMaterials(lodIndex);

            if (vegetationItemModelInfo.ShaderControler != null &&
                vegetationItemModelInfo.ShaderControler.Settings.SampleWind)
            {
                MeshRenderer meshRenderer = vegetationItemModelInfo.WindSamplerMeshRendererList[cameraIndex];
                if (meshRenderer)
                {
                    meshRenderer.GetPropertyBlock(materialPropertyBlock);
                }
            }

            materialPropertyBlock.SetBuffer(_visibleShaderDataBufferID, visibleBuffer);
            materialPropertyBlock.SetBuffer(_indirectShaderDataBufferID, visibleBuffer);

            List <ComputeBuffer> argsBufferList = vegetationItemModelInfo.GetLODArgsBufferList(lodIndex, cameraIndex, shadows);

            //int[] data = new int[5];
            //argsBufferList[0].GetData(data);
            //Debug.Log("Indirect - LOD" + lodIndex + ":" + data[1]);
            int submeshesToRender = Mathf.Min(mesh.subMeshCount, materials.Length);

            for (int i = 0; i <= submeshesToRender - 1; i++)
            {
                Graphics.DrawMeshInstancedIndirect(mesh, i, materials[i], cellBounds,
                                                   argsBufferList[i], 0, materialPropertyBlock, shadowCastingMode, true, layer,
                                                   selectedCamera, LightProbeUsage.Off);
            }
        }
Пример #3
0
        JobHandle ExecuteSpawnRules(VegetationCell vegetationCell, Rect vegetationCellRect, int vegetationPackageIndex, int vegetationItemIndex)
        {
            int firstUnityTerrainIndex = GetFirstUnityTerrainIndex();
            VegetationItemInfoPro   vegetationItemInfoPro   = VegetationPackageProList[vegetationPackageIndex].VegetationInfoList[vegetationItemIndex];
            VegetationPackagePro    vegetationPackagePro    = VegetationPackageProList[vegetationPackageIndex];
            VegetationItemModelInfo vegetationItemModelInfo =
                VegetationPackageProModelsList[vegetationPackageIndex].VegetationItemModelList[vegetationItemIndex];
            BiomeType currentBiome          = VegetationPackageProList[vegetationPackageIndex].BiomeType;
            int       currentBiomeSortOrder = VegetationPackageProList[vegetationPackageIndex].BiomeSortOrder;

            float globalDensity =
                VegetationSettings.GetVegetationItemDensity(vegetationItemInfoPro.VegetationType);

            if (vegetationCell.VegetationPackageInstancesList[vegetationPackageIndex].LoadStateList[vegetationItemIndex] == 1)
            {
                return(default(JobHandle));
            }
            vegetationCell.VegetationPackageInstancesList[vegetationPackageIndex].LoadStateList[vegetationItemIndex] = 1;

            bool doRuntimeSpawn = !(currentBiome != BiomeType.Default && !vegetationCell.HasBiome(currentBiome));

            NativeList <MatrixInstance> matrixList =
                vegetationCell.VegetationPackageInstancesList[vegetationPackageIndex].VegetationItemMatrixList[vegetationItemIndex];

            matrixList.Clear();

            if (!vegetationItemInfoPro.EnableRuntimeSpawn)
            {
                doRuntimeSpawn = false;
            }

            if (vegetationItemInfoPro.UseVegetationMask)
            {
                bool hasVegetationTypeIndex = false;
                if (vegetationCell.VegetationMaskList != null)
                {
                    for (int k = 0; k <= vegetationCell.VegetationMaskList.Count - 1; k++)
                    {
                        if (vegetationCell.VegetationMaskList[k]
                            .HasVegetationTypeIndex(vegetationItemInfoPro.VegetationTypeIndex))
                        {
                            hasVegetationTypeIndex = true;
                            break;
                        }
                    }
                }

                if (!hasVegetationTypeIndex)
                {
                    doRuntimeSpawn = false;
                }
            }

            JobHandle vegetationItemHandle = default(JobHandle);

            if (doRuntimeSpawn)
            {
                VegetationInstanceData instanceData = VegetationInstanceDataPool.GetObject();
                instanceData.Clear();
                vegetationCell.VegetationInstanceDataList.Add(instanceData);

                float sampleDistance = vegetationItemInfoPro.SampleDistance / globalDensity;
                float density        = 1;

                float calculatedSampleDistance = Mathf.Clamp(sampleDistance / density, 0.1f,
                                                             vegetationCell.VegetationCellBounds.size.x / 2f);
                int xSamples    = Mathf.CeilToInt(vegetationCell.VegetationCellBounds.size.x / calculatedSampleDistance);
                int zSamples    = Mathf.CeilToInt(vegetationCell.VegetationCellBounds.size.z / calculatedSampleDistance);
                int sampleCount = xSamples * zSamples;

                matrixList.Capacity = sampleCount;
                instanceData.SpawnLocations.ResizeUninitialized(sampleCount);

                if (firstUnityTerrainIndex > -1)
                {
                    instanceData.ResizeUninitialized(sampleCount);
                    InitInstanceData initInstanceData = new InitInstanceData
                    {
                        HeightmapSampled = instanceData.HeightmapSampled.ToDeferredJobArray(),
                        Excluded         = instanceData.Excluded.ToDeferredJobArray()
                    };
                    vegetationItemHandle = initInstanceData.Schedule(sampleCount, 256, vegetationItemHandle);
                }
                else
                {
                    instanceData.SetCapasity(sampleCount);
                }
                float defaultSpawnChance = 0;
                if (currentBiome == BiomeType.Default)
                {
                    defaultSpawnChance = 1;
                }

                CalculateCellSpawnLocationsWideJob calculateCellSpawnLocationsWideJob =
                    new CalculateCellSpawnLocationsWideJob
                {
                    SpawnLocations = instanceData.SpawnLocations.ToDeferredJobArray(),
                    CellSize       = vegetationCell.VegetationCellBounds.size,
                    CellCorner     =
                        vegetationCell.VegetationCellBounds.center -
                        vegetationCell.VegetationCellBounds.extents,
                    SampleDistance     = sampleDistance,
                    RandomizePosition  = vegetationItemInfoPro.RandomizePosition,
                    Density            = 1,
                    DefaultSpawnChance = defaultSpawnChance,
                    RandomNumbers      = RandomNumbers,
                    CellRect           = vegetationCellRect,
                    CellIndex          = vegetationCell.Index,
                    Seed = vegetationItemInfoPro.Seed + VegetationSettings.Seed,
                    UseSamplePointOffset     = vegetationItemInfoPro.UseSamplePointOffset,
                    SamplePointMinOffset     = vegetationItemInfoPro.SamplePointMinOffset,
                    SamplePointMaxOffset     = vegetationItemInfoPro.SamplePointMaxOffset,
                    XSamples                 = xSamples,
                    ZSamples                 = zSamples,
                    CalculatedSampleDistance = calculatedSampleDistance
                };

                vegetationItemHandle = calculateCellSpawnLocationsWideJob.Schedule(sampleCount, 64, vegetationItemHandle);

                if (vegetationCell.BiomeMaskList != null)
                {
                    for (int k = 0; k <= vegetationCell.BiomeMaskList.Count - 1; k++)
                    {
                        if (vegetationCell.BiomeMaskList[k].BiomeSortOrder < currentBiomeSortOrder)
                        {
                            continue;
                        }
                        vegetationItemHandle = vegetationCell.BiomeMaskList[k]
                                               .FilterSpawnLocations(instanceData.SpawnLocations, currentBiome, sampleCount, vegetationItemHandle);
                    }
                }

                if (vegetationItemInfoPro.UseNoiseCutoff)
                {
                    PerlinNoiseCutoffJob perlinNoiseCutoffJob =
                        new PerlinNoiseCutoffJob
                    {
                        InversePerlinMask = vegetationItemInfoPro.NoiseCutoffInverse,
                        PerlinCutoff      = vegetationItemInfoPro.NoiseCutoffValue,
                        PerlinScale       = vegetationItemInfoPro.NoiseCutoffScale,
                        Offset            = vegetationItemInfoPro.NoiseCutoffOffset,
                        SpawnLocationList = instanceData.SpawnLocations.ToDeferredJobArray()
                    };

                    vegetationItemHandle = perlinNoiseCutoffJob.Schedule(sampleCount, 64, vegetationItemHandle);
                }

                if (vegetationItemInfoPro.UseNoiseDensity)
                {
                    PerlinNoiseDensityJob perlinNoiseDensityJob =
                        new PerlinNoiseDensityJob
                    {
                        InversePerlinMask = vegetationItemInfoPro.NoiseDensityInverse,
                        PerlinScale       = vegetationItemInfoPro.NoiseDensityScale,
                        Offset            = vegetationItemInfoPro.NoiseDensityOffset,
                        SpawnLocationList = instanceData.SpawnLocations.ToDeferredJobArray()
                    };
                    vegetationItemHandle = perlinNoiseDensityJob.Schedule(sampleCount, 64, vegetationItemHandle);
                }

                FilterSpawnLocationsChanceJob filterSpawnLocationsChanceJob =
                    new FilterSpawnLocationsChanceJob
                {
                    SpawnLocationList = instanceData.SpawnLocations.ToDeferredJobArray(),
                    RandomNumbers     = RandomNumbers,
                    Density           = vegetationItemInfoPro.Density
                };

                vegetationItemHandle = filterSpawnLocationsChanceJob.Schedule(sampleCount, 64, vegetationItemHandle);

                for (int k = 0; k <= VegetationStudioTerrainList.Count - 1; k++)
                {
                    vegetationItemHandle = VegetationStudioTerrainList[k]
                                           .SampleTerrain(instanceData.SpawnLocations, instanceData, sampleCount, vegetationCellRect,
                                                          vegetationItemHandle);
                }

                if (vegetationItemInfoPro.UseTerrainSourceExcludeRule)
                {
                    TerrainSourceExcludeRuleJob terrainSourceExcludeRuleJob =
                        new TerrainSourceExcludeRuleJob
                    {
                        Excluded          = instanceData.Excluded.ToDeferredJobArray(),
                        TerrainSourceID   = instanceData.TerrainSourceID.ToDeferredJobArray(),
                        TerrainSourceRule = vegetationItemInfoPro.TerrainSourceExcludeRule
                    };
                    vegetationItemHandle = terrainSourceExcludeRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                }

                if (vegetationItemInfoPro.UseTerrainSourceIncludeRule)
                {
                    TerrainSourceIncludeRuleJob terrainSourceIncludeRuleJob =
                        new TerrainSourceIncludeRuleJob
                    {
                        Excluded          = instanceData.Excluded.ToDeferredJobArray(),
                        TerrainSourceID   = instanceData.TerrainSourceID.ToDeferredJobArray(),
                        TerrainSourceRule = vegetationItemInfoPro.TerrainSourceIncludeRule
                    };
                    vegetationItemHandle = terrainSourceIncludeRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                }

                if (vegetationItemInfoPro.UseSteepnessRule)
                {
                    InstanceSteepnessRuleJob instanceSteepnessRuleJob =
                        new InstanceSteepnessRuleJob
                    {
                        Excluded                = instanceData.Excluded.ToDeferredJobArray(),
                        TerrainNormal           = instanceData.TerrainNormal.ToDeferredJobArray(),
                        RandomNumberIndex       = instanceData.RandomNumberIndex.ToDeferredJobArray(),
                        MinSteepness            = vegetationItemInfoPro.MinSteepness,
                        MaxSteepness            = vegetationItemInfoPro.MaxSteepness,
                        Advanced                = vegetationItemInfoPro.UseAdvancedSteepnessRule,
                        SteepnessRuleCurveArray = vegetationItemModelInfo.SteepnessRuleCurveArray,
                        RandomNumbers           = RandomNumbers
                    };
                    vegetationItemHandle = instanceSteepnessRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                }

                if (vegetationItemInfoPro.UseHeightRule)
                {
                    InstanceHeightRuleJob instanceHeightRuleJob =
                        new InstanceHeightRuleJob
                    {
                        Excluded             = instanceData.Excluded.ToDeferredJobArray(),
                        Position             = instanceData.Position.ToDeferredJobArray(),
                        RandomNumberIndex    = instanceData.RandomNumberIndex.ToDeferredJobArray(),
                        MinHeight            = vegetationItemInfoPro.MinHeight + WorldspaceSeaLevel,
                        MaxHeight            = vegetationItemInfoPro.MaxHeight + WorldspaceSeaLevel,
                        Advanced             = vegetationItemInfoPro.UseAdvancedHeightRule,
                        HeightRuleCurveArray = vegetationItemModelInfo.HeightRuleCurveArray,
                        RandomNumbers        = RandomNumbers,
                        MaxCurveHeight       = vegetationItemInfoPro.MaxCurveHeight
                    };
                    vegetationItemHandle = instanceHeightRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                }

                if (!vegetationItemInfoPro.UseVegetationMask && vegetationCell.VegetationMaskList != null)
                {
                    for (int k = 0; k <= vegetationCell.VegetationMaskList.Count - 1; k++)
                    {
                        vegetationItemHandle = vegetationCell.VegetationMaskList[k].SampleMask(instanceData,
                                                                                               vegetationItemInfoPro.VegetationType, vegetationItemHandle);
                    }
                }
                else
                {
                    if (vegetationCell.VegetationMaskList != null)
                    {
                        for (int k = 0; k <= vegetationCell.VegetationMaskList.Count - 1; k++)
                        {
                            vegetationItemHandle = vegetationCell.VegetationMaskList[k].SampleIncludeVegetationMask(
                                instanceData,
                                vegetationItemInfoPro.VegetationTypeIndex, vegetationItemHandle);
                        }

                        if (vegetationCell.VegetationMaskList.Count > 0)
                        {
                            ProcessIncludeVegetationMaskJob processIncludeVegetationMaskJob =
                                new ProcessIncludeVegetationMaskJob
                            {
                                Excluded              = instanceData.Excluded.ToDeferredJobArray(),
                                Scale                 = instanceData.Scale.ToDeferredJobArray(),
                                RandomNumberIndex     = instanceData.RandomNumberIndex.ToDeferredJobArray(),
                                VegetationMaskDensity = instanceData.VegetationMaskDensity.ToDeferredJobArray(),
                                VegetationMaskScale   = instanceData.VegetationMaskScale.ToDeferredJobArray(),
                                RandomNumbers         = RandomNumbers
                            };
                            vegetationItemHandle = processIncludeVegetationMaskJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                        }
                    }
                }

                if (vegetationItemInfoPro.UseConcaveLocationRule)
                {
                    for (int k = 0; k <= VegetationStudioTerrainList.Count - 1; k++)
                    {
                        vegetationItemHandle = VegetationStudioTerrainList[k].SampleConcaveLocation(instanceData,
                                                                                                    vegetationItemInfoPro.ConcaveLoactionMinHeightDifference,
                                                                                                    vegetationItemInfoPro.ConcaveLoactionDistance, vegetationItemInfoPro.ConcaveLocationInverse,
                                                                                                    vegetationItemInfoPro.ConcaveLoactionAverage, vegetationCellRect, vegetationItemHandle);
                    }
                }

                if (vegetationItemInfoPro.UseTextureMaskIncludeRules)
                {
                    for (int k = 0; k <= vegetationItemInfoPro.TextureMaskIncludeRuleList.Count - 1; k++)
                    {
                        TextureMaskGroup textureMaskGroup =
                            vegetationPackagePro.GetTextureMaskGroup(vegetationItemInfoPro
                                                                     .TextureMaskIncludeRuleList[k].TextureMaskGroupID);
                        if (textureMaskGroup != null)
                        {
                            vegetationItemHandle = textureMaskGroup.SampleIncludeMask(instanceData, vegetationCellRect,
                                                                                      vegetationItemInfoPro.TextureMaskIncludeRuleList[k], vegetationItemHandle);
                        }
                    }

                    FilterIncludeMaskJob filterIncludeMaskJob =
                        new FilterIncludeMaskJob
                    {
                        Excluded        = instanceData.Excluded.ToDeferredJobArray(),
                        TextureMaskData = instanceData.TextureMaskData.ToDeferredJobArray()
                    };
                    vegetationItemHandle = filterIncludeMaskJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                }

                if (vegetationItemInfoPro.UseTextureMaskExcludeRules)
                {
                    for (int k = 0; k <= vegetationItemInfoPro.TextureMaskExcludeRuleList.Count - 1; k++)
                    {
                        TextureMaskGroup textureMaskGroup =
                            vegetationPackagePro.GetTextureMaskGroup(vegetationItemInfoPro
                                                                     .TextureMaskExcludeRuleList[k].TextureMaskGroupID);
                        if (textureMaskGroup != null)
                        {
                            vegetationItemHandle = textureMaskGroup.SampleExcludeMask(instanceData, vegetationCellRect,
                                                                                      vegetationItemInfoPro.TextureMaskExcludeRuleList[k], vegetationItemHandle);
                        }
                    }
                }

                OffsetAndRotateScaleVegetationInstanceMathJob offsetAndRotateScaleVegetationInstanceJob =
                    new OffsetAndRotateScaleVegetationInstanceMathJob
                {
                    RandomNumbers          = RandomNumbers,
                    Excluded               = instanceData.Excluded.ToDeferredJobArray(),
                    Scale                  = instanceData.Scale.ToDeferredJobArray(),
                    Position               = instanceData.Position.ToDeferredJobArray(),
                    Rotation               = instanceData.Rotation.ToDeferredJobArray(),
                    RandomNumberIndex      = instanceData.RandomNumberIndex.ToDeferredJobArray(),
                    TerrainNormal          = instanceData.TerrainNormal.ToDeferredJobArray(),
                    VegetationRotationType = vegetationItemInfoPro.Rotation,
                    MinScale               = vegetationItemInfoPro.MinScale,
                    MaxScale               = vegetationItemInfoPro.MaxScale,
                    Offset                 = vegetationItemInfoPro.Offset,
                    RotationOffset         = vegetationItemInfoPro.RotationOffset,
                    ScaleMultiplier        = vegetationItemInfoPro.ScaleMultiplier
                };
                vegetationItemHandle = offsetAndRotateScaleVegetationInstanceJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);


                if (vegetationItemInfoPro.UseNoiseScaleRule)
                {
                    PerlinNoiseScaleJob perlinNoiseScaleJob =
                        new PerlinNoiseScaleJob
                    {
                        Excluded          = instanceData.Excluded.ToDeferredJobArray(),
                        Position          = instanceData.Position.ToDeferredJobArray(),
                        Scale             = instanceData.Scale.ToDeferredJobArray(),
                        PerlinScale       = vegetationItemInfoPro.NoiseScaleScale,
                        MinScale          = vegetationItemInfoPro.NoiseScaleMinScale,
                        MaxScale          = vegetationItemInfoPro.NoiseScaleMaxScale,
                        InversePerlinMask = vegetationItemInfoPro.NoiseScaleInverse,
                        Offset            = vegetationItemInfoPro.NoiseScaleOffset
                    };
                    vegetationItemHandle = perlinNoiseScaleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                }

                if (vegetationItemInfoPro.UseBiomeEdgeScaleRule && currentBiome != BiomeType.Default)
                {
                    BiomeEdgeDistanceScaleRuleJob biomeEdgeDistanceScaleRuleJob =
                        new BiomeEdgeDistanceScaleRuleJob
                    {
                        Excluded      = instanceData.Excluded.ToDeferredJobArray(),
                        Scale         = instanceData.Scale.ToDeferredJobArray(),
                        BiomeDistance = instanceData.BiomeDistance.ToDeferredJobArray(),
                        MinScale      = vegetationItemInfoPro.BiomeEdgeScaleMinScale,
                        MaxScale      = vegetationItemInfoPro.BiomeEdgeScaleMaxScale,
                        MaxDistance   = vegetationItemInfoPro.BiomeEdgeScaleDistance,
                        InverseScale  = vegetationItemInfoPro.BiomeEdgeScaleInverse
                    };
                    vegetationItemHandle = biomeEdgeDistanceScaleRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                }

                if (vegetationItemInfoPro.UseBiomeEdgeIncludeRule && currentBiome != BiomeType.Default)
                {
                    BiomeEdgeDistanceIncludeRuleJob biomeEdgeDistanceIncludeRuleJob =
                        new BiomeEdgeDistanceIncludeRuleJob
                    {
                        Excluded      = instanceData.Excluded.ToDeferredJobArray(),
                        BiomeDistance = instanceData.BiomeDistance.ToDeferredJobArray(),
                        MaxDistance   = vegetationItemInfoPro.BiomeEdgeIncludeDistance,
                        Inverse       = vegetationItemInfoPro.BiomeEdgeIncludeInverse
                    };
                    vegetationItemHandle = biomeEdgeDistanceIncludeRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                }

                if (vegetationItemInfoPro.UseTerrainTextureIncludeRules)
                {
                    for (int k = 0; k <= VegetationStudioTerrainList.Count - 1; k++)
                    {
                        vegetationItemHandle = VegetationStudioTerrainList[k]
                                               .ProcessSplatmapRules(vegetationItemInfoPro.TerrainTextureIncludeRuleList, instanceData,
                                                                     true,
                                                                     vegetationCellRect,
                                                                     vegetationItemHandle);
                    }
                }

                if (vegetationItemInfoPro.UseTerrainTextureExcludeRules)
                {
                    for (int k = 0; k <= VegetationStudioTerrainList.Count - 1; k++)
                    {
                        vegetationItemHandle = VegetationStudioTerrainList[k]
                                               .ProcessSplatmapRules(vegetationItemInfoPro.TerrainTextureExcludeRuleList, instanceData,
                                                                     false,
                                                                     vegetationCellRect,
                                                                     vegetationItemHandle);
                    }
                }

                if (vegetationItemInfoPro.UseDistanceFalloff)
                {
                    DistanceFalloffJob distanceFalloffJob =
                        new DistanceFalloffJob
                    {
                        Excluded                     = instanceData.Excluded.ToDeferredJobArray(),
                        RandomNumberIndex            = instanceData.RandomNumberIndex.ToDeferredJobArray(),
                        DistanceFalloff              = instanceData.DistanceFalloff.ToDeferredJobArray(),
                        RandomNumbers                = RandomNumbers,
                        DistanceFalloffStartDistance = vegetationItemInfoPro.DistanceFalloffStartDistance
                    };
                    vegetationItemHandle = distanceFalloffJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle);
                }

                NewCreateInstanceMatrixJob createInstanceMatrixJob =
                    new NewCreateInstanceMatrixJob
                {
                    Excluded        = instanceData.Excluded,
                    Position        = instanceData.Position,
                    Scale           = instanceData.Scale,
                    Rotation        = instanceData.Rotation,
                    DistanceFalloff = instanceData.DistanceFalloff,
                    VegetationInstanceMatrixList = matrixList
                };

                vegetationItemHandle = createInstanceMatrixJob.Schedule(vegetationItemHandle);
            }

            if (!doRuntimeSpawn)
            {
                if (PersistentVegetationStorage && !PersistentVegetationStorage.DisablePersistentStorage)
                {
                    PersistentVegetationCell persistentVegetationCell = PersistentVegetationStorage.GetPersistentVegetationCell(vegetationCell.Index);
                    PersistentVegetationInfo persistentVegetationInfo = persistentVegetationCell?.GetPersistentVegetationInfo(vegetationItemInfoPro.VegetationItemID);
                    if (persistentVegetationInfo != null && persistentVegetationInfo.VegetationItemList.Count > 0)
                    {
                        persistentVegetationInfo.CopyToNativeArray();
                        matrixList.ResizeUninitialized(persistentVegetationInfo.NativeVegetationItemArray.Length);

                        LoadPersistentStorageToMatrixWideJob loadPersistentStorageToMatrixJob =
                            new LoadPersistentStorageToMatrixWideJob
                        {
                            InstanceList = persistentVegetationInfo.NativeVegetationItemArray,
                            VegetationInstanceMatrixList = matrixList.ToDeferredJobArray(),
                            VegetationSystemPosition     = VegetationSystemPro.VegetationSystemPosition
                        };
                        vegetationItemHandle = loadPersistentStorageToMatrixJob.Schedule(matrixList, 64, vegetationItemHandle);
                    }
                }
            }
            else
            {
                if (PersistentVegetationStorage && !PersistentVegetationStorage.DisablePersistentStorage)
                {
                    PersistentVegetationCell persistentVegetationCell = PersistentVegetationStorage.GetPersistentVegetationCell(vegetationCell.Index);
                    PersistentVegetationInfo persistentVegetationInfo = persistentVegetationCell?.GetPersistentVegetationInfo(vegetationItemInfoPro.VegetationItemID);
                    if (persistentVegetationInfo != null && persistentVegetationInfo.VegetationItemList.Count > 0)
                    {
                        persistentVegetationInfo.CopyToNativeArray();
                        LoadPersistentStorageToMatrixJob loadPersistentStorageToMatrixJob =
                            new LoadPersistentStorageToMatrixJob
                        {
                            InstanceList = persistentVegetationInfo.NativeVegetationItemArray,
                            VegetationInstanceMatrixList = matrixList,
                            VegetationSystemPosition     = VegetationSystemPro.VegetationSystemPosition
                        };

                        vegetationItemHandle = loadPersistentStorageToMatrixJob.Schedule(vegetationItemHandle);
                    }
                }
            }

            Profiler.BeginSample("Schedule batched jobs");
            JobHandle.ScheduleBatchedJobs();
            Profiler.EndSample();

            return(vegetationItemHandle);
        }
Пример #4
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();
        }