private void InitFrame(Camera cam) { foliage = terrain.TerrainData.Foliage; terrainPosition = terrain.transform.position; terrainSize = terrain.TerrainData.Geometry.Size; treeDistance = terrain.TerrainData.Rendering.TreeDistance; billboardStart = terrain.TerrainData.Rendering.BillboardStart; cullVolumeBias = GRuntimeSettings.Instance.renderingDefault.cullVolumeBias; if (terrain.TerrainData.Foliage.Trees != null) { prototypes = terrain.TerrainData.Foliage.Trees.Prototypes; } else { prototypes = new List <GTreePrototype>(); } if (prototypeCache == null || prototypeCache.Length != prototypes.Count) { prototypeCache = new PrototypeCache[prototypes.Count]; } for (int i = 0; i < prototypes.Count; ++i) { GTreePrototype p = prototypes[i]; PrototypeCache cache = prototypeCache[i]; bool valid = prototypes[i].IsValid; cache.validation = valid; if (valid) { cache.subMeshCount = p.sharedMesh.subMeshCount; cache.canDrawInstanced = IsInstancingEnabledForAllMaterials(p); cache.canDrawBillboardInstanced = p.billboard != null && p.billboard.material != null && p.billboard.material.enableInstancing; } if (p.billboard != null) { cache.billboardMesh = GBillboardUtilities.GetMesh(p.billboard); } if (p.billboard != null && p.billboard.material != null) { if (cache.billboardImageTexcoords == null || cache.billboardImageTexcoords.Length != p.billboard.imageCount) { cache.billboardImageTexcoords = p.billboard.GetImageTexCoords(); } Material mat = p.billboard.material; mat.SetVectorArray(BILLBOARD_IMAGE_TEXCOORDS, cache.billboardImageTexcoords); mat.SetInt(BILLBOARD_IMAGE_COUNT, p.billboard.imageCount); } prototypeCache[i] = cache; } enableInstancing = terrain.TerrainData.Rendering.EnableInstancing && SystemInfo.supportsInstancing; normalizedToLocalMatrix = Matrix4x4.Scale(terrainSize); localToWorldMatrix = terrain.transform.localToWorldMatrix; normalizedToWorldMatrix = localToWorldMatrix * normalizedToLocalMatrix; camera = cam; if (frustum == null) { frustum = new Plane[6]; } GFrustumUtilities.Calculate(camera, frustum, treeDistance); if (nearFrustumCorners == null) { nearFrustumCorners = new Vector3[4]; } if (farFrustumCorners == null) { farFrustumCorners = new Vector3[4]; } if (batchContainer == null) { batchContainer = new Matrix4x4[BATCH_MAX_INSTANCE_COUNT]; } if (billboardBatchContainer == null) { billboardBatchContainer = new Matrix4x4[BATCH_MAX_INSTANCE_COUNT]; } if (!isWarningLogged) { for (int i = 0; i < prototypes.Count; ++i) { if (!prototypes[i].IsValid) { string msg = string.Format( "Tree prototye {0}: " + "The prototype is not valid, make sure you've assigned a prefab with correct mesh and materials setup.", i); Debug.LogWarning(msg); } if (enableInstancing && prototypes[i].IsValid) { if (!IsInstancingEnabledForAllMaterials(prototypes[i])) { string msg = string.Format( "Tree prototype {0} ({1}): " + "Instancing need to be enabled for all materials for the renderer to work at its best. " + "Otherwise it will fallback to non-instanced for this prototype.", i, prototypes[i].Prefab.name); Debug.LogWarning(msg); } if (prototypes[i].billboard != null && prototypes[i].billboard.material != null && prototypes[i].billboard.material.enableInstancing == false) { string msg = string.Format( "Tree prototype {0} ({1}): " + "Instancing need to be enabled for billboard material for the renderer to work at its best. " + "Otherwise it will fallback to non-instanced for this prototype when render billboards.", i, prototypes[i].Prefab.name); Debug.LogWarning(msg); } } } isWarningLogged = true; } }
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); } }