Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by Casto · Aug 14, 2013 at 08:16 AM · treelodbillboardprogrammatically

How to create billboard version of a tree?

I want to create a billboard version (for LOD) of my trees programmatically.

Unity does that automatically when trees are placed on a terrain, but I don't use Unity's terrains, that's why I need to make it by myself.

So, what would be the best way to create a billboard version of a tree?

Thanks!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
5
Best Answer

Answer by Casto · Aug 14, 2013 at 02:41 PM

I think I found what I need. In case someone else is interested, I found a script showing how to generate a billboard from any object:

     using UnityEngine;
     using System.Collections;
      
     public class TreeToBillboard : MonoBehaviour
     {
         /*
         Make a billboard out of an object in the scene
         The camera will auto-place to get the best view of the object so no need for camera adjustment
        
         To use - place an object in an empty scene with just camera and any lighting you want.
         Add this script to your scene camera and link to the object you want to render.
         Press play and you will get a snapshot of the object (looking down the +Z-axis at it) saved out to billboard.png in your project folder
         Any pixels colored the same as the camera background color will be transparent
         */
      
         public GameObject objectToRender;
         public int imageWidth = 128;
         public int imageHeight = 128;
        
         void Start()
         {
             if(objectToRender)
                 ConvertToImage();
         }
        
         IEnumerator ConvertToImage()
         {
             //grab the main camera and mess with it for rendering the object - make sure orthographic
             Camera cam = Camera.main;
             cam.orthographic = true;
            
             //render to screen rect area equal to out image size
             float rw  = imageWidth;
             rw /= Screen.width;
             float rh = imageHeight;
             rh /= Screen.height;
             cam.rect = new Rect(0,0,rw,rh);
            
             //grab size of object to render - place/size camera to fit
             Bounds bb = objectToRender.GetComponent<Renderer>().bounds;
            
             //place camera looking at centre of object - and backwards down the z-axis from it
             cam.transform.position = bb.center;
             cam.transform.position.Set(cam.transform.position.x, cam.transform.position.y, -1.0f + (bb.min.z * 2.0f));
             //make clip planes fairly optimal and enclose whole mesh
             cam.nearClipPlane = 0.5f;
             cam.farClipPlane = -cam.transform.position.z + 10.0f + bb.max.z;
             //set camera size to just cover entire mesh
             cam.orthographicSize = 1.01f * Mathf.Max( (bb.max.y - bb.min.y)/2.0f, (bb.max.x - bb.min.x)/2.0f);
             cam.transform.position.Set(cam.transform.position.x, cam.orthographicSize * 0.05f, cam.transform.position.y);
        
             //render
             yield return new WaitForEndOfFrame();
            
             var tex = new Texture2D( imageWidth, imageHeight, TextureFormat.ARGB32, false );
             // Read screen contents into the texture
             tex.ReadPixels(new Rect(0, 0, imageWidth, imageHeight), 0, 0 );
             tex.Apply();
        
             //turn all pixels == background-color to transparent
             Color bCol = cam.backgroundColor;
             Color alpha = bCol;
             alpha.a = 0.0f;
             for(int y = 0; y < imageHeight; y++)
             {
                 for(int x = 0; x < imageWidth; x++)
                 {
                     Color c = tex.GetPixel(x,y);
                     if (c.r == bCol.r)
                         tex.SetPixel(x,y,alpha);
                 }
             }
             tex.Apply();
        
             // Encode texture into PNG
             byte[] bytes = tex.EncodeToPNG();
             Destroy( tex );
             System.IO.File.WriteAllBytes(Application.dataPath + "/../billboard.png", bytes);
         }
     }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image MMOERPG · May 26, 2014 at 06:07 AM 0
Share

Hi Castro, I'm working on the same issue, I found the same script. I got the script working, it takes the screenshot and saves it to a resources folder within my assets folder. I checked the alpha is transparent box to make the transparency take effect. I then applied the texture to a material, created a plane mesh, rotated it 90 degrees on the X axis and applied the material to it. The problem I'm having now is the tree appears in the middle of the plane as it should however the area of the plane that should be transparent is filled in with the colors of the tree. Basically the tree texture was stretched around the material rather than being stamped on to it. Did you have this issue and if so, how did you overcome it?

If you've progressed further than this with your work on tree billboards, I would love to see what you've accomplished and work with you in progression.

avatar image MMOERPG · May 26, 2014 at 06:28 AM 0
Share

I overcame the issue by simply changing the shader to transparent/diffuse.

avatar image
2

Answer by Twobitboolean · Mar 16, 2017 at 08:27 PM

I've modified the first c# codes and is currently working with Unity 5.5.0f3. My changes are commented with //**. Important: For this to work you must not have any skybox. Go to Window>>Lighting>>Scene>>Skybox and set it to none!

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Script_Billboard_Create : MonoBehaviour {
 
     /*
 Make a billboard out of an object in the scene
 The camera will auto-place to get the best view of the object so no need for camera adjustment
 
 To use - place an object in an empty scene with just camera and any lighting you want.
 Add this script to your scene camera and link to the object you want to render.
 Press play and you will get a snapshot of the object (looking down the +Z-axis at it) saved out to billboard.png in your project folder
 Any pixels colored the same as the camera background color will be transparent
 */
 
     
     public GameObject objectToRender;
     public int imageWidth = 128;
     public int imageHeight = 128;
     //**bool to only conver once
     private bool grab = false;
 
     void Start()
     {
         CameraSetup();
     }
 
     void OnPostRender()
     {
         if (!grab) { ConvertToImage(); grab = true; }
     }
 
     //**split into two methods
     void CameraSetup()
     {
         //grab the main camera and mess with it for rendering the object - make sure orthographic
         Camera cam = Camera.main;
         cam.orthographic = true;
 
         //render to screen rect area equal to out image size
         float rw = imageWidth;
         rw /= Screen.width;
         float rh = imageHeight;
         rh /= Screen.height;
         cam.rect = new Rect(0, 0, rw, rh);
         //**manually set the background color
         cam.backgroundColor = new Vector4(0,0,0,0);
 
         //grab size of object to render - place/size camera to fit
         Bounds bb = objectToRender.GetComponent<Renderer>().bounds;
 
         //place camera looking at centre of object - and backwards down the z-axis from it
         cam.transform.position = bb.center;
         cam.transform.position.Set(cam.transform.position.x, cam.transform.position.y, -1.0f + (bb.min.z * 2.0f));
         //make clip planes fairly optimal and enclose whole mesh
         cam.nearClipPlane = 0.5f;
         cam.farClipPlane = -cam.transform.position.z + 10.0f + bb.max.z;
         //set camera size to just cover entire mesh
         cam.orthographicSize = 1.01f * Mathf.Max((bb.max.y - bb.min.y) / 2.0f, (bb.max.x - bb.min.x) / 2.0f);
         cam.transform.position.Set(cam.transform.position.x, cam.orthographicSize * 0.05f, cam.transform.position.y);
     }
 
     void ConvertToImage()
     {
         var tex = new Texture2D(imageWidth, imageHeight);
         // Read screen contents into the texture
         tex.ReadPixels(new Rect(0, 0, imageWidth, imageHeight), 0, 0);
         tex.Apply();
 
         //turn all pixels == background-color to transparent
         Camera cam = Camera.main;
         Color bCol = cam.backgroundColor;
         Color alpha = new Vector4(0,0,0,0);
         alpha.a = 0.0f;
         for (int y = 0; y < imageHeight; y++)
         {
             for (int x = 0; x < imageWidth; x++)
             {
                 Color c = tex.GetPixel(x, y);
                 //**check for difference
                 if (c.r != bCol.r)
                     tex.SetPixel(x, y, new Vector4(c.r, c.g, c.b, 1));
             }
         }
         tex.Apply();
         
         // Encode texture into PNG
         byte[] bytes = tex.EncodeToPNG();
         Destroy(tex);
 
         //**path is in Assets, you must refresh Unity to see the file (can be done by clicking away then click on Unity window again, etc)
         System.IO.File.WriteAllBytes(Application.dataPath + "/billboard.png", bytes);
     }
 }


Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by thieum · Feb 18, 2016 at 02:03 PM

Interesting script, but not working for me in Unity 5 or 4.6 neither. The .js version found in another thread works... but with plain textures only (alpha is discarded, which makes it useless when you apply this to meshes using transparent textures.

But I found a workaround : change this single line as below :

if (c.r == bCol.r || c.a != 1)

(Last be sure to set up a camera looking in world z axis, and you'll find your png at the very root of your project folder)

 #pragma strict
 
 /* 
 Make a billboard out of an object in the scene 
 The camera will auto-place to get the best view of the object so no need for camera adjustment 
 
 To use - place an object in an empty scene with just camera and any lighting you want. 
 Add this script to your scene camera and link to the object you want to render. 
 Press play and you will get a snapshot of the object (looking down the +Z-axis at it) saved out to billboard.png in your project folder 
 Any pixels colored the same as the camera background color will be transparent 
 */ 
 
 var objectToRender : GameObject; 
 var imageWidth : int = 128; 
 var imageHeight : int = 128; 
 
 function Start() 
 { 
     if (!objectToRender) return; 
 
     //grab the main camera and mess with it for rendering the object - make sure orthographic 
     var cam : Camera = Camera.main; 
     cam.orthographic = true; 
      
     //render to screen rect area equal to out image size 
     var rw : float = imageWidth; rw /= Screen.width; 
     var rh : float = imageHeight; rh /= Screen.height; 
     cam.rect = Rect(0,0,rw,rh); 
      
     //grab size of object to render - place/size camera to fit 
     var bb : Bounds = objectToRender.GetComponent(Renderer).bounds; 
      
         //place camera looking at centre of object - and backwards down the z-axis from it 
     cam.transform.position = bb.center; 
     cam.transform.position.z = -1.0 + (bb.min.z * 2.0); 
         //make clip planes fairly optimal and enclose whole mesh 
     cam.nearClipPlane = 0.5; 
     cam.farClipPlane = -cam.transform.position.z + 10.0 + bb.max.z; 
         //set camera size to just cover entire mesh 
     cam.orthographicSize = 1.01 * Mathf.Max( (bb.max.y - bb.min.y)/2.0, (bb.max.x - bb.min.x)/2.0); 
     cam.transform.position.y += cam.orthographicSize * 0.05; 
 
     //render 
     yield new WaitForEndOfFrame(); 
      
     var tex = new Texture2D( imageWidth, imageHeight, TextureFormat.ARGB32, false ); 
     // Read screen contents into the texture 
     tex.ReadPixels( Rect(0, 0, imageWidth, imageHeight), 0, 0 ); 
     tex.Apply(); 
 
     //turn all pixels == background-color to transparent 
     var bCol : Color = cam.backgroundColor; 
     var alpha = bCol; 
     alpha.a = 0.0; 
     for(var y : int = 0; y < imageHeight; y++) 
     { 
         for(var x : int = 0; x < imageWidth; x++) 
         { 
             var c : Color = tex.GetPixel(x,y); 
             // if (c.r == bCol.r)
             if (c.r == bCol.r || c.a != 1) 
                 tex.SetPixel(x,y,alpha); 
         } 
     } 
     tex.Apply(); 
 
     // Encode texture into PNG 
     var bytes = tex.EncodeToPNG(); 
     Destroy( tex ); 
     System.IO.File.WriteAllBytes(Application.dataPath + "/../billboard.png", bytes);
     Debug.Log("tex saved!"); 
 }

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

custom tree shading issue 1 Answer

Unity LOD billboard asset example? 3 Answers

Leaf Billboard light issues 0 Answers

Invisible Tree Billboards....???? 1 Answer

Tree shadow problem / billboard trees 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges