Пример #1
0
        private void Submit(int cellIndex)
        {
            GGrassPatchData data = cellsData[cellIndex];

            if (data == null)
            {
                return;
            }
            GInstancedBatch[] batches = data.instancedBatches;
            if (batches == null)
            {
                return;
            }
            for (int i = 0; i < batches.Length; ++i)
            {
                GInstancedBatch b = batches[i];
                if (b.prototypeIndex >= prototypes.Count)
                {
                    continue;
                }

                GGrassPrototype       proto         = prototypes[b.prototypeIndex];
                MaterialPropertyBlock propertyBlock = propertyBlocks[b.prototypeIndex];

                Mesh baseMesh = baseMeshes[b.prototypeIndex];
                if (baseMesh == null)
                {
                    continue;
                }

                Material material = materials[b.prototypeIndex];
                if (material == null || !material.enableInstancing)
                {
                    continue;
                }

                Graphics.DrawMeshInstanced(
                    baseMesh,
                    0,
                    material,
                    b.transforms,
                    b.instanceCount,
                    propertyBlock,
                    proto.shadowCastingMode,
                    proto.receiveShadow,
                    proto.layer,
                    camera,
                    LightProbeUsage.BlendProbes);
            }
        }
Пример #2
0
        private void InitFrame(Camera cam)
        {
            terrainPosition     = terrain.transform.position;
            terrainSize         = terrain.TerrainData.Geometry.Size;
            grassDistance       = terrain.TerrainData.Rendering.GrassDistance;
            cells               = terrain.TerrainData.Foliage.GrassPatches;
            willIgnoreCellLimit =
                cellsData == null ||
                GRuntimeSettings.Instance.isEditingFoliage;

            if (cellsData == null || cellsData.Length != cells.Length)
            {
                cellsData = new GGrassPatchData[cells.Length];
            }
            for (int i = 0; i < cellsData.Length; ++i)
            {
                if (cellsData[i] == null)
                {
                    cellsData[i] = new GGrassPatchData();
                }
            }

            if (cellsNativeData == null || cellsNativeData.Length != cells.Length)
            {
                cellsNativeData = new GGrassPatchNativeData[cells.Length];
            }

            if (visibleCells == null)
            {
                visibleCells = new List <int>();
            }
            if (cellToProcess == null)
            {
                cellToProcess = new List <int>();
            }

            if (terrain.TerrainData.Foliage.Grasses != null)
            {
                prototypes = terrain.TerrainData.Foliage.Grasses.Prototypes;
                if (propertyBlocks == null || propertyBlocks.Length != prototypes.Count)
                {
                    propertyBlocks = new MaterialPropertyBlock[prototypes.Count];
                }
            }
            else
            {
                prototypes = new List <GGrassPrototype>();
            }

            if (materialConfigurator == null)
            {
                materialConfigurator = System.Activator.CreateInstance <GSimpleGrassMaterialConfigurator>();
            }

            normalizedToLocalMatrix = Matrix4x4.Scale(terrainSize);
            localToWorldMatrix      = terrain.transform.localToWorldMatrix;
            normalizedToWorldMatrix = localToWorldMatrix * normalizedToLocalMatrix;

            camera = cam;
            if (frustum == null)
            {
                frustum = new Plane[6];
            }
            GFrustumUtilities.Calculate(camera, frustum, grassDistance);

            if (cellCullResults == null || cellCullResults.Length != cells.Length)
            {
                cellCullResults = new int[cells.Length];
            }

            if (cellCulledFrameCount == null || cellCulledFrameCount.Length != cells.Length)
            {
                cellCulledFrameCount = new int[cells.Length];
            }

            if (cellSqrDistanceToCam == null || cellSqrDistanceToCam.Length != cells.Length)
            {
                cellSqrDistanceToCam = new float[cells.Length];
            }

            if (cellWorldBounds == null || cellWorldBounds.Length != cells.Length)
            {
                cellWorldBounds = new Bounds[cells.Length];
                for (int i = 0; i < cells.Length; ++i)
                {
                    cellWorldBounds[i] = new Bounds()
                    {
                        center = normalizedToWorldMatrix.MultiplyPoint(cells[i].bounds.center),
                        size   = normalizedToWorldMatrix.MultiplyVector(cells[i].bounds.size)
                    };
                }
            }

            GUtilities.EnsureArrayLength(ref baseMeshes, prototypes.Count);
            GUtilities.EnsureArrayLength(ref materials, prototypes.Count);
            for (int i = 0; i < prototypes.Count; ++i)
            {
                baseMeshes[i] = prototypes[i].GetBaseMesh();
                materials[i]  =
                    prototypes[i].Shape == GGrassShape.DetailObject ?
                    prototypes[i].DetailMaterial :
                    GGrassMaterialProvider.GetMaterial(terrain.TerrainData.Foliage.EnableInteractiveGrass, prototypes[i].IsBillboard);
            }
        }