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); } }
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); } }