public static BillboardAsset CreateBillboardAsset(GBillboardCreatorArgs args) { BillboardAsset billboard = new BillboardAsset(); billboard.SetVertices(args.Vertices); billboard.SetIndices(Triangulate(args.Vertices)); billboard.width = args.Width; billboard.height = args.Height; billboard.bottom = args.Bottom; Vector4[] texcoords = new Vector4[args.Row * args.Column]; Vector2 imageSize = new Vector2(1f / args.Column, 1f / args.Row); Vector2 imageTopLeft = new Vector2(0, 0); for (int y = 0; y < args.Row; ++y) { for (int x = 0; x < args.Column; ++x) { imageTopLeft = new Vector2(x * imageSize.x, y * imageSize.y); texcoords[GUtilities.To1DIndex(x, y, args.Column)] = new Vector4(imageTopLeft.x, imageTopLeft.y, imageSize.x, imageSize.y); } } billboard.SetImageTexCoords(texcoords); billboard.name = args.Target.name + "_Billboard"; return(billboard); }
public static void PrepareRenderTexture(ref RenderTexture rt, GBillboardCreatorArgs args) { int width = args.Column * args.CellSize; int height = args.Row * args.CellSize; if (args.Mode == GBillboardRenderMode.Flipbook) { width = args.CellSize; height = args.CellSize; } int depth = 16; RenderTextureFormat format = args.Mode == GBillboardRenderMode.Normal ? RenderTextureFormat.ARGBFloat : RenderTextureFormat.ARGB32; if (rt == null || rt.width != width || rt.height != height || rt.depth != depth || rt.format != format) { if (rt != null) { rt.Release(); } rt = new RenderTexture(width, height, depth, format, RenderTextureReadWrite.Linear); } }
private void RenderPreview() { GBillboardCreatorArgs args = ConstructArgs(); GBillboardCreator.PrepareRenderTexture(ref previewRt, args); GBillboardCreator.RenderPreview(previewRt, args); }
private static void RenderPreviewFlipbook(RenderTexture rt, GBillboardCreatorArgs args) { Clear(rt, Color.clear); if (args.AtlasMaterial == null) { return; } args.Mode = GBillboardRenderMode.Flipbook; Camera cam = CreatePreviewCamera(args); cam.targetTexture = rt; GameObject g = CreatePreviewGameObject(cam.transform, args); int imageCount = args.Row * args.Column; float angleStep = 360f / imageCount; g.transform.rotation = Quaternion.Euler(0, args.CellIndex * angleStep, 0); cam.rect = new Rect(0, 0, 1, 1); cam.Render(); cam.targetTexture = null; GUtilities.DestroyGameobject(cam.gameObject); GUtilities.DestroyGameobject(g); }
private GBillboardCreatorArgs ConstructArgs() { GBillboardCreatorArgs args = new GBillboardCreatorArgs(); args.Mode = mode; args.Target = target; args.Row = row; args.Column = column; args.CellSize = cellSize; args.CameraOffset = cameraOffset; args.CameraSize = cameraSize; args.AtlasMaterial = atlasMaterial; args.NormalMaterial = normalMaterial; args.SrcColorProps = srcColorProps; //args.DesColorProps = desColorProps; args.DesColorProps = "_Color"; args.SrcTextureProps = srcTextureProps; //args.DesTextureProps = desTextureProps; args.DesTextureProps = "_MainTex"; args.CellIndex = cellIndex % (args.Row * args.Column); args.Vertices = vertices.ToArray(); args.Width = width; args.Height = height; args.Bottom = bottom; return(args); }
public static void RenderPreview(RenderTexture rt, GBillboardCreatorArgs args) { if (args.Mode == GBillboardRenderMode.Atlas) { RenderPreviewAtlas(rt, args); } else if (args.Mode == GBillboardRenderMode.Normal) { RenderPreviewNormal(rt, args); } else if (args.Mode == GBillboardRenderMode.Flipbook) { RenderPreviewFlipbook(rt, args); } }
public static Texture2D RenderNormal(GBillboardCreatorArgs args) { args.Mode = GBillboardRenderMode.Normal; RenderTexture rt = null; PrepareRenderTexture(ref rt, args); RenderPreviewNormal(rt, args); Texture2D atlas = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, true, true); GCommon.CopyFromRT(atlas, rt); rt.Release(); GUtilities.DestroyObject(rt); atlas.name = args.Target.name + "_Normal"; return(atlas); }
private void DrawUtilities() { string label = "Utilites"; string id = "billboardeditor-utilities"; GEditorCommon.Foldout(label, false, id, () => { Rect fitButtonRect = EditorGUILayout.GetControlRect(); if (GUI.Button(fitButtonRect, "Fit Camera")) { GBillboardCreatorArgs args = GBillboardCreator.FitCameraToTarget(ConstructArgs()); CopyArgs(args); } }); }
private void DrawTargetSettings() { string label = "Target"; string id = "billboardeditor-target"; GEditorCommon.Foldout(label, false, id, () => { EditorGUI.BeginChangeCheck(); target = EditorGUILayout.ObjectField("Prefab", target, typeof(GameObject), true) as GameObject; if (EditorGUI.EndChangeCheck()) { GBillboardCreatorArgs args = GBillboardCreator.FitCameraToTarget(ConstructArgs()); CopyArgs(args); RefreshMaterialPropsSuggestions(); } }); }
private static Camera CreatePreviewCamera(GBillboardCreatorArgs args) { GameObject previewCam = new GameObject("~BillboardEditorCam"); //previewCam.hideFlags = HideFlags.HideAndDontSave; previewCam.transform.position = -Vector3.one * 10000; previewCam.transform.rotation = Quaternion.identity; previewCam.transform.localScale = Vector3.one; Camera cam = previewCam.AddComponent <Camera>(); cam.orthographic = true; cam.orthographicSize = args.CameraSize; cam.clearFlags = CameraClearFlags.SolidColor; cam.backgroundColor = args.Mode == GBillboardRenderMode.Normal ? new Color(0.5f, 0.5f, 1f, 1f) : Color.clear; cam.depth = -1000; cam.aspect = 1; cam.enabled = false; return(cam); }
private static void RenderPreviewAtlas(RenderTexture rt, GBillboardCreatorArgs args) { Clear(rt, Color.clear); if (args.AtlasMaterial == null) { return; } args.Mode = GBillboardRenderMode.Atlas; Vector2 viewPortSize = new Vector2(1f / args.Column, 1f / args.Row); Vector2 viewPortPosition = new Vector2(0, 0); RenderTexture tempRt = new RenderTexture(Mathf.RoundToInt(viewPortSize.x * rt.width), Mathf.RoundToInt(viewPortSize.y * rt.height), 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); Camera cam = CreatePreviewCamera(args); cam.targetTexture = tempRt; GameObject g = CreatePreviewGameObject(cam.transform, args); int imageCount = args.Row * args.Column; float angleStep = 360f / imageCount; for (int y = 0; y < args.Row; ++y) { for (int x = 0; x < args.Column; ++x) { Clear(tempRt, Color.clear); g.transform.rotation = Quaternion.Euler(0, GUtilities.To1DIndex(x, y, args.Column) * angleStep - 90, 0); cam.Render(); viewPortPosition = new Vector2(x * viewPortSize.x, y * viewPortSize.y); GCommon.DrawTexture(rt, tempRt, new Rect(viewPortPosition, viewPortSize), GInternalMaterials.UnlitTransparentMaterial); } } cam.targetTexture = null; GUtilities.DestroyGameobject(cam.gameObject); GUtilities.DestroyGameobject(g); tempRt.Release(); GUtilities.DestroyObject(tempRt); }
private void CopyArgs(GBillboardCreatorArgs args) { mode = args.Mode; target = args.Target; row = args.Row; column = args.Column; cellSize = args.CellSize; cameraOffset = args.CameraOffset; cameraSize = args.CameraSize; atlasMaterial = args.AtlasMaterial; normalMaterial = args.NormalMaterial; srcColorProps = args.SrcColorProps; desColorProps = args.DesColorProps; srcTextureProps = args.SrcTextureProps; desTextureProps = args.DesTextureProps; cellIndex = args.CellIndex; vertices = new List <Vector2>(args.Vertices); width = args.Width; height = args.Height; bottom = args.Bottom; tris = GBillboardCreator.Triangulate(vertices.ToArray()); }
public static GBillboardCreatorArgs FitCameraToTarget(GBillboardCreatorArgs args) { if (args.Target == null) { return(args); } Renderer[] renderers = args.Target.GetComponentsInChildren <Renderer>(); if (renderers.Length > 0) { Bounds b = new Bounds(); b.SetMinMax( renderers[0].bounds.min, renderers[0].bounds.max); for (int i = 1; i < renderers.Length; ++i) { Bounds bi = renderers[i].bounds; b.Encapsulate(bi.min); b.Encapsulate(bi.max); } b.Encapsulate(args.Target.transform.position); Vector3 center = args.Target.transform.position; float dWidth = 2 * Mathf.Max( Vector3.Distance(center, new Vector3(b.min.x, center.y, b.min.z)), Vector3.Distance(center, new Vector3(b.max.x, center.y, b.max.z))); float dHeight = b.size.y; float bottom = b.min.y - center.y; args.CameraSize = Mathf.Max(dWidth, dHeight) * 0.5f; args.CameraOffset = -(b.center - center) + Vector3.forward * dWidth * 2; args.Height = dHeight - bottom; args.Bottom = bottom; args.Width = dHeight; } return(args); }
private static GameObject CreatePreviewGameObject(Transform cameraTransform, GBillboardCreatorArgs args) { if (args.Target == null) { return(new GameObject("~EmptyBillboardCreatorTarget")); } GameObject g = GameObject.Instantiate(args.Target) as GameObject; g.name = "~BillboardCreatorTarget"; //g.hideFlags = HideFlags.HideAndDontSave; g.transform.position = cameraTransform.transform.TransformPoint(args.CameraOffset); g.transform.rotation = cameraTransform.rotation; g.transform.localScale = Vector3.one; Material baseMaterial = args.Mode == GBillboardRenderMode.Normal ? args.NormalMaterial : args.AtlasMaterial; MeshRenderer[] renderers = g.GetComponentsInChildren <MeshRenderer>(); for (int i = 0; i < renderers.Length; ++i) { Material[] sharedMaterials = renderers[i].sharedMaterials; for (int j = 0; j < sharedMaterials.Length; ++j) { //Material mat = Object.Instantiate<Material>(baseMaterial); Material mat = new Material(baseMaterial.shader); mat.SetColor(args.DesColorProps, Color.white); mat.SetTexture(args.DesTextureProps, null); //mat.CopyPropertiesFromMaterial(sharedMaterials[j]); try { if (sharedMaterials[j].HasProperty(args.SrcColorProps)) { Color color = sharedMaterials[j].GetColor(args.SrcColorProps); color.a = 1; if (mat.HasProperty(args.DesColorProps)) { mat.SetColor(args.DesColorProps, color); } } else { if (mat.HasProperty(args.DesColorProps)) { mat.SetColor(args.DesColorProps, Color.white); } } } catch { } try { if (sharedMaterials[j].HasProperty(args.SrcTextureProps)) { Texture tex = sharedMaterials[j].GetTexture(args.SrcTextureProps); if (mat.HasProperty(args.DesTextureProps)) { mat.SetTexture(args.DesTextureProps, tex); } } } catch { } sharedMaterials[j] = mat; } renderers[i].sharedMaterials = sharedMaterials; } return(g); }
private void SaveAssets() { string folder = EditorUtility.OpenFolderPanel("Select Folder", "Assets/", ""); if (string.IsNullOrEmpty(folder)) { return; } try { GAnalytics.Record(GAnalytics.BILLBOARD_SAVE); EditorUtility.DisplayProgressBar("Saving", "Saving assets...", 1f); GBillboardCreatorArgs args = ConstructArgs(); BillboardAsset billboard = GBillboardCreator.CreateBillboardAsset(args); Texture2D atlas = GBillboardCreator.RenderAtlas(args); Texture2D normal = GBillboardCreator.RenderNormal(args); string billboardPath = Path.Combine(FileUtil.GetProjectRelativePath(folder), billboard.name + ".asset"); BillboardAsset billboardAsset = AssetDatabase.LoadAssetAtPath <BillboardAsset>(billboardPath); if (billboardAsset == null) { AssetDatabase.CreateAsset(billboard, billboardPath); billboardAsset = billboard; } else { billboardAsset.SetVertices(billboard.GetVertices()); billboardAsset.SetIndices(billboard.GetIndices()); billboardAsset.SetImageTexCoords(billboard.GetImageTexCoords()); billboardAsset.width = billboard.width; billboardAsset.height = billboard.height; billboardAsset.bottom = billboard.bottom; billboardAsset.name = billboard.name; } string atlasPath = Path.Combine(FileUtil.GetProjectRelativePath(folder), atlas.name + ".png"); byte[] atlasData = atlas.EncodeToPNG(); File.WriteAllBytes(atlasPath, atlasData); GUtilities.DestroyObject(atlas); string normalPath = Path.Combine(FileUtil.GetProjectRelativePath(folder), normal.name + ".png"); byte[] normalData = normal.EncodeToPNG(); File.WriteAllBytes(normalPath, normalData); GUtilities.DestroyObject(normal); AssetDatabase.Refresh(); TextureImporter atlasImporter = AssetImporter.GetAtPath(atlasPath) as TextureImporter; atlasImporter.wrapMode = TextureWrapMode.Clamp; atlasImporter.alphaIsTransparency = true; atlasImporter.SaveAndReimport(); atlas = AssetDatabase.LoadAssetAtPath <Texture2D>(atlasPath); TextureImporter normalImporter = AssetImporter.GetAtPath(normalPath) as TextureImporter; normalImporter.textureType = TextureImporterType.NormalMap; normalImporter.wrapMode = TextureWrapMode.Clamp; normalImporter.SaveAndReimport(); normal = AssetDatabase.LoadAssetAtPath <Texture2D>(normalPath); Material mat = null; if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Universal) { mat = Object.Instantiate(GGriffinSettings.Instance.TerrainDataDefault.Foliage.TreeBillboardMaterialURP); } else if (GCommon.CurrentRenderPipeline == GRenderPipelineType.Lightweight) { mat = Object.Instantiate(GGriffinSettings.Instance.TerrainDataDefault.Foliage.TreeBillboardMaterialLWRP); } else { mat = Object.Instantiate(GGriffinSettings.Instance.TerrainDataDefault.Foliage.TreeBillboardMaterial); } if (mat != null) { if (mat.HasProperty("_MainTex")) { mat.SetTexture("_MainTex", atlas); } if (mat.HasProperty("_BumpMap")) { mat.SetTexture("_BumpMap", normal); } mat.name = args.Target.name + "_BillboardMaterial"; string matPath = Path.Combine(FileUtil.GetProjectRelativePath(folder), mat.name + ".mat"); AssetDatabase.CreateAsset(mat, matPath); billboardAsset.material = mat; } AssetDatabase.Refresh(); } catch (System.Exception e) { Debug.LogError(e.ToString()); } EditorUtility.ClearProgressBar(); }