public static Material GenerateBillboardMaterial(FoliageTypeSpeedTreeData speedTreeData)
        {
            Material billboardMaterialBatch;

            // Try and retrieve it first
            billboardMaterialBatch = speedTreeData.m_BillboardMaterial;
            if (billboardMaterialBatch == null)
            {
                // Else create it
                Shader billboardShader = Shader.Find("Critias/WindTree_Billboard");
                billboardMaterialBatch = new Material(billboardShader);

                speedTreeData.m_BillboardMaterial = billboardMaterialBatch;
            }

            // Set the material universal data
            billboardMaterialBatch.SetTexture("_MainTex", speedTreeData.m_BillboardRenderer.sharedMaterial.GetTexture("_MainTex"));
            billboardMaterialBatch.SetTexture("_BumpMap", speedTreeData.m_BillboardRenderer.sharedMaterial.GetTexture("_BumpMap"));
            billboardMaterialBatch.SetColor("_HueVariation", speedTreeData.m_BillboardRenderer.sharedMaterial.GetColor("_HueVariation"));
            billboardMaterialBatch.SetVector("_Size", speedTreeData.m_Size);

            // Set the material UV data
            billboardMaterialBatch.SetVectorArray("_UVVert_U", speedTreeData.m_VertBillboardU);
            billboardMaterialBatch.SetVectorArray("_UVVert_V", speedTreeData.m_VertBillboardV);

            billboardMaterialBatch.SetVector("_UVHorz_U", speedTreeData.m_VertBillboardU[0]);
            billboardMaterialBatch.SetVector("_UVHorz_V", speedTreeData.m_VertBillboardV[0]);

            billboardMaterialBatch.enableInstancing = true;

            return(billboardMaterialBatch);
        }
Esempio n. 2
0
        /** Called in case that we need to set the volatile data for a billboard batch material or something like that */
        public void UpdateValues()
        {
            // Update all billboard distances
            if (m_IsSpeedTreeType)
            {
                FoliageTypeSpeedTreeData speedTreeData = m_RuntimeData.m_SpeedTreeData;
                Material billboardMaterialBatch        = m_RuntimeData.m_SpeedTreeData.m_BillboardMaterial;

                if (billboardMaterialBatch != null)
                {
                    billboardMaterialBatch.SetFloat("CRITIAS_MaxFoliageTypeDistance", m_RenderInfo.m_MaxDistance);
                    billboardMaterialBatch.SetFloat("CRITIAS_MaxFoliageTypeDistanceSqr", m_RenderInfo.m_MaxDistance * m_RenderInfo.m_MaxDistance);

                    billboardMaterialBatch.SetVectorArray("_UVVert_U", speedTreeData.m_VertBillboardU);
                    billboardMaterialBatch.SetVectorArray("_UVVert_V", speedTreeData.m_VertBillboardV);

                    billboardMaterialBatch.SetVector("_UVHorz_U", speedTreeData.m_VertBillboardU[0]);
                    billboardMaterialBatch.SetVector("_UVHorz_V", speedTreeData.m_VertBillboardV[0]);

                    billboardMaterialBatch.SetColor("_HueVariation", m_RenderInfo.m_Hue);
                    billboardMaterialBatch.SetColor("_Color", m_RenderInfo.m_Color);
                }

                // Update the hue variation
                if (m_IsGrassType)
                {
                    m_RuntimeData.m_LODDataGrass.m_Material.SetColor("_HueVariation", m_RenderInfo.m_Hue);
                    m_RuntimeData.m_LODDataGrass.m_Material.SetColor("_Color", m_RenderInfo.m_Color);
                }
                else
                {
                    for (int i = 0; i < m_RuntimeData.m_LODDataTree.Length; i++)
                    {
                        for (int m = 0; m < m_RuntimeData.m_LODDataTree[i].m_Materials.Length; m++)
                        {
                            m_RuntimeData.m_LODDataTree[i].m_Materials[m].SetColor("_Color", m_RenderInfo.m_Color);
                        }
                    }
                }
            }

            // Update all LOD distances
            if (IsGrassType == false)
            {
                LODGroup grp  = m_Prefab.GetComponent <LODGroup>();
                LOD[]    lods = grp != null?grp.GetLODs() : null;

                FoliageTypeUtilities.UpdateDistancesLOD(m_RuntimeData.m_LODDataTree, lods, m_RenderInfo.m_MaxDistance, IsSpeedTreeType);
            }
        }
        public static void ExtractBillboardData(BillboardRenderer billboardData, FoliageTypeSpeedTreeData data)
        {
            BillboardAsset billAsset = billboardData.billboard;

            Vector4 size = new Vector4(billAsset.width, billAsset.height, billAsset.bottom, 1);

            // UV Extraction
            Vector4[] uvs = billAsset.GetImageTexCoords();

            Vector2[] vertBillUV = new Vector2[uvs.Length * 4];
            Vector2[] horzBillUV = new Vector2[4];

            // Build the UV's
            for (int uvIdx = 0, billUv = 0; uvIdx < uvs.Length; uvIdx++, billUv += 4)
            {
                Vector4 extract = uvs[uvIdx];

                if (uvIdx == 0)
                {
                    horzBillUV[0] = new Vector2(extract.x, extract.y);
                    horzBillUV[1] = new Vector2(extract.x, extract.y) + new Vector2(0, Mathf.Abs(extract.w));
                    horzBillUV[2] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, Mathf.Abs(extract.w));
                    horzBillUV[3] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, 0);
                }

                // We are rotated
                if (extract.w < 0)
                {
                    vertBillUV[billUv + 0] = new Vector2(extract.x, extract.y);
                    vertBillUV[billUv + 1] = new Vector2(extract.x, extract.y) + new Vector2(0, Mathf.Abs(extract.w));
                    vertBillUV[billUv + 2] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, Mathf.Abs(extract.w));
                    vertBillUV[billUv + 3] = new Vector2(extract.x, extract.y) + new Vector2(-extract.z, 0);
                }
                else
                {
                    vertBillUV[billUv + 0] = new Vector2(extract.x, extract.y);
                    vertBillUV[billUv + 1] = new Vector2(extract.x, extract.y) + new Vector2(extract.z, 0);
                    vertBillUV[billUv + 2] = new Vector2(extract.x, extract.y) + new Vector2(extract.z, extract.w);
                    vertBillUV[billUv + 3] = new Vector2(extract.x, extract.y) + new Vector2(0, extract.w);
                }
            }

            // Build the UVs ready for the shader
            Vector4[] UV_U = new Vector4[8];
            Vector4[] UV_V = new Vector4[8];

            Vector2[] uv = vertBillUV;

            for (int i = 0; i < 8; i++)
            {
                // 4 by 4 elements
                UV_U[i].x = uv[4 * i + 0].x;
                UV_U[i].y = uv[4 * i + 1].x;
                UV_U[i].z = uv[4 * i + 2].x;
                UV_U[i].w = uv[4 * i + 3].x;

                UV_V[i].x = uv[4 * i + 0].y;
                UV_V[i].y = uv[4 * i + 1].y;
                UV_V[i].z = uv[4 * i + 2].y;
                UV_V[i].w = uv[4 * i + 3].y;
            }

            // Assign the data
            data.m_Size              = size;
            data.m_VertBillboardU    = UV_U;
            data.m_VertBillboardV    = UV_V;
            data.m_BillboardRenderer = billboardData;
            data.m_BillboardMaterial = GenerateBillboardMaterial(data);
        }