Exemplo n.º 1
0
        public void Configure(GStylizedTerrain terrain, int prototypeIndex, MaterialPropertyBlock propertyBlock)
        {
            GGrassPrototype proto = terrain.TerrainData.Foliage.Grasses.Prototypes[prototypeIndex];

            propertyBlock.SetTexture(NOISE_TEX, GRuntimeSettings.Instance.foliageRendering.windNoiseTexture);

            IEnumerator <GWindZone> windZone = GWindZone.ActiveWindZones.GetEnumerator();

            if (windZone.MoveNext())
            {
                GWindZone w = windZone.Current;
                propertyBlock.SetVector(WIND, w.GetWindParams());
            }

            propertyBlock.SetColor(COLOR, proto.Color);
            if (proto.Shape != GGrassShape.DetailObject && proto.Texture != null)
            {
                propertyBlock.SetTexture(MAIN_TEX, proto.Texture);
            }
            propertyBlock.SetFloat(BEND_FACTOR, proto.BendFactor);

            if (terrain.TerrainData.Foliage.EnableInteractiveGrass)
            {
                propertyBlock.SetTexture(VECTOR_FIELD, terrain.GetGrassVectorFieldRenderTexture());
                propertyBlock.SetMatrix(WORLD_TO_NORMALIZED, terrain.GetWorldToNormalizedMatrix());
            }

            float fadeMaxDistance = terrain.TerrainData.Rendering.GrassDistance;
            float fadeMinDistance = Mathf.Clamp(terrain.TerrainData.Rendering.GrassFadeStart, 0f, 0.99f) * fadeMaxDistance;

            propertyBlock.SetFloat(FADE_MIN_DISTANCE, fadeMinDistance);
            propertyBlock.SetFloat(FADE_MAX_DISTANCE, fadeMaxDistance);
        }
        private void DrawOnTerrain(GStylizedTerrain t)
        {
            Vector3[] worldCorners = GCommon.GetBrushQuadCorners(transform.position, Radius, 0);
            Vector2[] uvCorners    = new Vector2[worldCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = t.WorldPointToUV(worldCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);

            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            RenderTexture rt  = t.GetGrassVectorFieldRenderTexture();
            Material      mat = GInternalMaterials.InteractiveGrassVectorFieldMaterial;

            mat.SetFloat("_Opacity", t.TerrainData.Foliage.BendSensitive);
            int pass = 0;

            GCommon.DrawQuad(rt, uvCorners, mat, pass);
        }
Exemplo n.º 3
0
        private static void RenderGrass(GStylizedTerrain t, Camera cam)
        {
            if (t.TerrainData.Foliage.Grasses == null ||
                t.TerrainData.Foliage.Grasses.Prototypes.Count == 0)
            {
                return;
            }
            List <GGrassPrototype> prototypes = t.TerrainData.Foliage.Grasses.Prototypes;

            GGrassPatch[] patches = t.TerrainData.Foliage.GrassPatches;
            if (patches == null)
            {
                return;
            }

            float   grassDistance = t.TerrainData.Rendering.GrassDistance;
            Vector3 dimension     = new Vector3(
                t.TerrainData.Geometry.Width,
                t.TerrainData.Geometry.Height,
                t.TerrainData.Geometry.Length);
            float   patchWorldRadius = dimension.x * 0.5f / t.TerrainData.Foliage.PatchGridSize;
            Vector3 boundLocalPos    = Vector3.zero;
            Vector3 boundWorldPos    = Vector3.zero;

            int FLAG_CULLED  = 0;
            int FLAG_DIRTY   = 1;
            int FLAG_BATCHED = 2;

            int[]  flags     = new int[patches.Length];
            Rect[] dirtyRect = t.TerrainData.Foliage.GetGrassDirtyRegions();
            for (int i = 0; i < patches.Length; ++i)
            {
                Rect uvRect = patches[i].GetUvRange();
                boundLocalPos.Set(
                    uvRect.center.x * dimension.x,
                    0,
                    uvRect.center.y * dimension.z);
                boundWorldPos   = t.transform.TransformPoint(boundLocalPos);
                boundWorldPos.y = cam.transform.position.y;
                if (Vector3.Distance(boundWorldPos, cam.transform.position) - patchWorldRadius > grassDistance)
                {
                    flags[i] = FLAG_CULLED;
                    continue;
                }

                for (int r = 0; r < dirtyRect.Length; ++r)
                {
                    if (dirtyRect[r].Overlaps(uvRect))
                    {
                        flags[i] = FLAG_DIRTY;
                        break;
                    }
                }

                if (flags[i] == FLAG_DIRTY)
                {
                    continue;
                }

                flags[i] = FLAG_BATCHED;
            }

            Vector3 meshLocalPos = Vector3.zero;
            Vector3 meshWorldPos = Vector3.zero;

            grassMaterialPropertyBlock.Clear();
            if (t.TerrainData.Foliage.EnableInteractiveGrass)
            {
                grassMaterialPropertyBlock.SetTexture(VECTOR_FIELD_PROPERTY, t.GetGrassVectorFieldRenderTexture());
                grassMaterialPropertyBlock.SetMatrix(WORLD_TO_NORMALIZED_PROPERTY, t.GetWorldToNormalizedMatrix());
            }

            grassMaterialPropertyBlock.SetTexture(NOISETEX_PROPERTY, GGriffinSettings.Instance.DefaultNoiseTexture);
            IEnumerator <GWindZone> windZone = GWindZone.ActiveWindZones.GetEnumerator();

            if (windZone.MoveNext())
            {
                GWindZone w = windZone.Current;
                grassMaterialPropertyBlock.SetVector(WIND_PROPERTY, w.GetWindParams());
            }

            //draw batched
            //Material grassMat = GCommon.CurrentRenderPipeline == GRenderPipelineType.Lightweight ?
            //    GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterialLW :
            //    GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterial;
            Material grassMat = null;

            if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Builtin)
            {
                grassMat = t.TerrainData.Foliage.EnableInteractiveGrass ?
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassInteractiveMaterial :
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterial;
                if (grassMat == null)
                {
                    Debug.Log("Grass material missing. Try re-installing the Polaris V2 package.");
                }
            }
            else if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Lightweight)
            {
                grassMat = t.TerrainData.Foliage.EnableInteractiveGrass ?
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassInteractiveMaterialLWRP :
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterialLWRP;
                if (grassMat == null)
                {
                    Debug.Log("Grass material missing. Try installing the 'Lightweight Render Pipeline Support' extension from the Extension Window (Window>Griffin>Tools>Extension)");
                }
            }
            else if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Universal)
            {
                grassMat = t.TerrainData.Foliage.EnableInteractiveGrass ?
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassInteractiveMaterialURP :
                           GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassMaterialURP;
                if (grassMat == null)
                {
                    Debug.Log("Grass material missing. Try installing the 'Universal Render Pipeline Support' extension from the Extension Window (Window>Griffin>Tools>Extension)");
                }
            }

            if (grassMat == null)
            {
                return;
            }

            for (int i = 0; i < patches.Length; ++i)
            {
                if (flags[i] != FLAG_BATCHED)
                {
                    continue;
                }
                for (int p = 0; p < prototypes.Count; ++p)
                {
                    grassMaterialPropertyBlock.SetColor(COLOR_PROPERTY, prototypes[p].Color);
                    grassMaterialPropertyBlock.SetFloat(BEND_FACTOR_PROPERTY, prototypes[p].BendFactor);
                    if (prototypes[p].Shape != GGrassShape.DetailObject && prototypes[p].Texture != null)
                    {
                        grassMaterialPropertyBlock.SetTexture(MAINTEX_PROPERTY, prototypes[p].Texture);
                    }
                    Mesh mesh = patches[i].GetMesh(p);
                    if (mesh != null)
                    {
                        meshLocalPos = mesh.bounds.center;
                        meshWorldPos = t.transform.TransformPoint(meshLocalPos);
                        if (Vector3.Distance(meshWorldPos, cam.transform.position) - patchWorldRadius > grassDistance)
                        {
                            continue;
                        }

                        Graphics.DrawMesh(
                            mesh,
                            Matrix4x4.TRS(t.transform.position, Quaternion.identity, Vector3.one),
                            prototypes[p].Shape == GGrassShape.DetailObject ? prototypes[p].DetailMaterial : grassMat,
                            prototypes[p].Layer,
                            cam,
                            0,
                            prototypes[p].Shape == GGrassShape.DetailObject ? null : grassMaterialPropertyBlock,
                            prototypes[p].Shape == GGrassShape.DetailObject ? prototypes[p].ShadowCastingMode : ShadowCastingMode.On,
                            prototypes[p].Shape == GGrassShape.DetailObject ? prototypes[p].ReceiveShadow : true,
                            null,
                            LightProbeUsage.BlendProbes,
                            null);
                    }
                }
            }

            if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Builtin)
            {
                return;
            }

            Vector3 localPos = Vector3.zero;
            Vector3 worldPos = Vector3.zero;
            Vector3 scale    = Vector3.zero;

            Material previewMat = GGriffinSettings.Instance.TerrainDataDefault.Foliage.GrassPreviewMaterial;

            for (int pIndex = 0; pIndex < prototypes.Count; ++pIndex)
            {
                GGrassPrototype proto = prototypes[pIndex];
                //grassMaterialPropertyBlock.Clear();
                //grassMaterialPropertyBlock.SetTexture(MAINTEX_PROPERTY, proto.Texture);

                for (int i = 0; i < patches.Length; ++i)
                {
                    if (flags[i] != FLAG_DIRTY)
                    {
                        continue;
                    }
                    GGrassPatch patch         = patches[i];
                    int         instanceCount = patch.Instances.Count;
                    for (int j = 0; j < instanceCount; ++j)
                    {
                        GGrassInstance grass = patch.Instances[j];
                        if (grass.PrototypeIndex != pIndex)
                        {
                            continue;
                        }

                        localPos.Set(
                            dimension.x * grass.Position.x,
                            dimension.y * grass.Position.y,
                            dimension.z * grass.Position.z);
                        worldPos = t.transform.TransformPoint(localPos);
                        scale.Set(
                            prototypes[grass.PrototypeIndex].Size.x * grass.Scale.x,
                            prototypes[grass.PrototypeIndex].Size.y * grass.Scale.y,
                            prototypes[grass.PrototypeIndex].Size.z * grass.Scale.z);

                        Mesh mesh = prototypes[grass.PrototypeIndex].GetBaseMesh();
                        Graphics.DrawMesh(
                            mesh,
                            Matrix4x4.TRS(worldPos, grass.Rotation, scale),
                            previewMat,
                            prototypes[grass.PrototypeIndex].Layer,
                            cam,
                            0,
                            null,     //grassMaterialPropertyBlock
                            ShadowCastingMode.On,
                            true,
                            null,
                            LightProbeUsage.BlendProbes,
                            null);
                    }
                }
            }
        }