Hey guys, I’m trying to use a billboarding script to enable my 2d trees etc. to always face me - and despite trawling the Unity spaces of the internet and trying many different scripts, I can’t seem to get any of them to work.
The closest I’ve got is making my object rotating towards the camera correctly, but it seems to want to lay down (face the sky) and I can’t figure out why.
Here’s the script I’ve got at the moment:
using UnityEngine;
using System.Collections;
public class billy : MonoBehaviour
{
public Camera cameraToLookAt;
void Update()
{
Vector3 v = cameraToLookAt.transform.position - transform.position;
v.x = v.z = 0.0f;
transform.LookAt(cameraToLookAt.transform.position - v);
}
}
Would be grateful if anyone could tell me what’s going onnnn!
Have you thought about doing it in the shader? I have 2D trees and other objects that I have always billboarding rotating only on single axis, but do it in the shader since I have thousands… so much faster.
Hey there,
I’ve read a couple of things about shader-based billboarding, if you think it’s easier I’d definitely give it a go - any idea where I could pick one up?
I’ve successfully implemented a billboard shader that works very nicely, but now my problem is that I need it to not respond to my camera’s ‘roll’ axis (I’m using the Durovis Dive VR plugin so my camera has 3 degrees of freedom) - all my trees basically ‘lay down’ when I roll my head to the side!
Shader "Billboard/SimpleTransparentColor" {
Properties {
_Color("Color", color) = (1,1,1,1)
_MainTex ("Texture Image", 2D) = "white" {}
}
SubShader {
Tags { "Queue" = "Transparent" }
Pass {
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// User-specified uniforms
uniform sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform float4 _Color;
struct vertexInput {
float4 vertex : POSITION;
float4 tex : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_P,
mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
- float4(input.vertex.x, input.vertex.y, 0.0, 0.0));
output.tex = input.tex;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
return tex2D(_MainTex, float2(_MainTex_ST.xy * input.tex.xy + _MainTex_ST.zw)) * _Color;
}
ENDCG
}
}
}
If you static batch your trees and setup a custom uv2 then you can use this shader:
Shader "Custom/MobileAlphaDiscard_rotate_CG" {
Properties {
_MainTex ("RGBA Texture Image", 2D) = "white" {}
//_Cutoff ("Alpha Cutoff", Float) = 0.5
}
SubShader {
Pass {
Cull Back
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
};
float4 _MainTex_ST;
v2f vert (appdata_full v)
{
v2f o;
o.texcoord = TRANSFORM_TEX (v.texcoord, _MainTex);
float position_NotBatched_X = v.texcoord1.x / unity_Scale.w;
float2 centerOfQuad_XZ = v.vertex.xz * _Object2World[0].x - float2(position_NotBatched_X, 0.0);
float2 zVector_XZ = normalize(_WorldSpaceCameraPos.xz + _World2Object[3].xz - centerOfQuad_XZ);
position_NotBatched_X /= _Object2World[0].x;
float4 position_Object = v.vertex;
position_Object.x += zVector_XZ[1] * position_NotBatched_X - position_NotBatched_X;
position_Object.z -= zVector_XZ.x * position_NotBatched_X;
o.vertex = mul (UNITY_MATRIX_MVP, position_Object);
return o;
}
half4 frag (v2f i) : COLOR
{
half4 texcol = tex2D (_MainTex, i.texcoord);
if (texcol.a < 0.2) {
discard;
}
return texcol;
}
ENDCG
}
}
// The definition of a fallback shader should be commented out
// during development:
// Fallback "Unlit/Transparent Cutout"
}
So what you need to do when you make your quad for the tree billboard, is make the UV2 vertex positions match the real vertex positions. So if your quad upper right vertex is 1.5,5.5, make that UV2 vertex the same number. This is how it knows when it’s batched what the actual rotations need to be. This code locks it in single axis rotation too!