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