<p>I did a little code cleaning and came up with this:</p>
<pre><code>static const float3 BILLBOARD[] = {
    float3(-1, 1, 0),   // 0
    float3(1, 1, 0),    // 1
    float3(-1, -1, 0),  // 2
    float3(-1, -1, 0),  // 3
    float3(1, 1, 0),    // 4
    float3(1, -1, 0),  // 5
};

float4 bpos = float4( input.position.xy, 0, 0);
float4 bbOffset = float4(BILLBOARD[vertexID],0);

matrix WV = mul(worldMatrix, viewMatrix);
float4 Vpos = mul(WV, bpos);
float4 OffsetPos = Vpos + bbOffset;
float4 projected = mul( projectionMatrix, OffsetPos);

output.position = projected;
</code></pre>
<p>The code you posted is using the billboard offset to compute the Vpos, but what you really want is to use the input.position (the billboard position) to compute the camera space position. This became clear after doing the code clean up. I'm not sure if it will &quot;fix&quot; the code, but it should get you a step closer.</p>
<hr />
<p>There are a number of ways to compute billboard orientation. One trick is to simply overwrite the upper 3x3 portion of the view matrix with the identity matrix before using it to compute the vertex.</p>
<p>Another is to compute a forward vector ie</p>
<pre><code>n = normalize(camera_pos - bb_pos);
</code></pre>
<p>then, a right vector ie</p>
<pre><code>d = normalize(cross(n, camera_down);
</code></pre>
<p>and finally a down/up vector</p>
<pre><code>r = cross( n, d);
</code></pre>
<p>These can be used to rotate the bb position with matrix multiplication.</p>

CC BY-SA 4.0
2021-11-11T18:32:32.560Z
Thanks for your answer, this code alone doesn't rotate the quad towards the camera like one would expect for a billboard, it looks like the bbOffset still needs to be modified by another parameter to complete the effect... see my edit if you're interested
H3XXX
CC BY-SA 4.0
2021-11-12T11:55:44.087Z
I added a bit to my answer hopefully this will get you a little closer to what you want.
pmw1234
CC BY-SA 4.0
2021-11-12T18:10:39.803Z
The view/identity matrix trick worked perfectly. Thanks!
H3XXX
CC BY-SA 4.0
2021-11-11T12:07:44.667Z
2021-11-12T12:52:48.860Z
2021-11-12T12:52:48.860Z
pmw1234
<p>I'm trying to create a vertex shader that billboards a quad. Most resources online show the code to be some variation of the following</p>
<pre><code>gl_Position = project * (view * model * billbrd_pos + vec4(position.xy, 0, 0));
</code></pre>
<p>So I tried doing something similar in HLSL after doing some research</p>
<pre><code>static const float3 BILLBOARD[] = {
    float3(-1, 1, 0),   // 0
    float3(1, 1, 0),    // 1
    float3(-1, -1, 0),  // 2
    float3(-1, -1, 0),  // 3
    float3(1, 1, 0),    // 4
    float3(1, -1, 0),  // 5
};

input.position.w = 1.0f;

float3 bpos = BILLBOARD[vertexID];

matrix WV = mul(worldMatrix, viewMatrix);

output.position = mul(projectionMatrix,
    mul(WV, float4(bpos, 1.0f))
    + float4(input.position.x, input.position.y, 0.0f, 0.0f)
    * float4(1.0f, 1.0f, 1.0f, 1.0f));
</code></pre>
<p>But this doesn't work as the quad disappears from the screen. How can I achieve billboarding in a vertex shader in HLSL?</p>
<p><strong>Edit</strong></p>
<p>As per @pmw1234 's answer I changed the upper 3x3 section of the view matrix to an identity matrix as shown below, the billboard now works correctly.</p>
<pre><code>matrix viewIdentity = viewMatrix;
viewIdentity[0][0] = 1;
viewIdentity[0][1] = 0;
viewIdentity[0][2] = 0;

viewIdentity[1][0] = 0;
viewIdentity[1][1] = 1;
viewIdentity[1][2] = 0;

viewIdentity[2][0] = 0;
viewIdentity[2][1] = 0;
viewIdentity[2][2] = 1;

float4 Vpos = mul(bpos, worldMatrix);
Vpos = mul(Vpos, viewIdentity);
</code></pre>

<hlsl><directx>
Billboarding in Vertex Shader
H3XXX
# Billboarding in Vertex Shader

(Asked by: username_0 on 2021-11-10)

I'm trying to create a vertex shader that billboards a quad. Most resources online show the code to be some variation of the following

```
gl_Position = project * (view * model * billbrd_pos + vec4(position.xy, 0, 0));

```

So I tried doing something similar in HLSL after doing some research

```
static const float3 BILLBOARD[] = {
    float3(-1, 1, 0),   // 0
    float3(1, 1, 0),    // 1
    float3(-1, -1, 0),  // 2
    float3(-1, -1, 0),  // 3
    float3(1, 1, 0),    // 4
    float3(1, -1, 0),  // 5
};

input.position.w = 1.0f;

float3 bpos = BILLBOARD[vertexID];

matrix WV = mul(worldMatrix, viewMatrix);

output.position = mul(projectionMatrix,
    mul(WV, float4(bpos, 1.0f))
    + float4(input.position.x, input.position.y, 0.0f, 0.0f)
    * float4(1.0f, 1.0f, 1.0f, 1.0f));

```

But this doesn't work as the quad disappears from the screen. How can I achieve billboarding in a vertex shader in HLSL?

**Edit**

As per @username_1 's answer I changed the upper 3x3 section of the view matrix to an identity matrix as shown below, the billboard now works correctly.

```
matrix viewIdentity = viewMatrix;
viewIdentity[0][0] = 1;
viewIdentity[0][1] = 0;
viewIdentity[0][2] = 0;

viewIdentity[1][0] = 0;
viewIdentity[1][1] = 1;
viewIdentity[1][2] = 0;

viewIdentity[2][0] = 0;
viewIdentity[2][1] = 0;
viewIdentity[2][2] = 1;

float4 Vpos = mul(bpos, worldMatrix);
Vpos = mul(Vpos, viewIdentity);

```

**Tags:** hlsl, directx


---

## 1 answers

### Answer by username_1 on 2021-11-11. Score: 1 | Accepted answer

I did a little code cleaning and came up with this:

```
static const float3 BILLBOARD[] = {
    float3(-1, 1, 0),   // 0
    float3(1, 1, 0),    // 1
    float3(-1, -1, 0),  // 2
    float3(-1, -1, 0),  // 3
    float3(1, 1, 0),    // 4
    float3(1, -1, 0),  // 5
};

float4 bpos = float4( input.position.xy, 0, 0);
float4 bbOffset = float4(BILLBOARD[vertexID],0);

matrix WV = mul(worldMatrix, viewMatrix);
float4 Vpos = mul(WV, bpos);
float4 OffsetPos = Vpos + bbOffset;
float4 projected = mul( projectionMatrix, OffsetPos);

output.position = projected;

```

The code you posted is using the billboard offset to compute the Vpos, but what you really want is to use the input.position (the billboard position) to compute the camera space position. This became clear after doing the code clean up. I'm not sure if it will "fix" the code, but it should get you a step closer.

---

There are a number of ways to compute billboard orientation. One trick is to simply overwrite the upper 3x3 portion of the view matrix with the identity matrix before using it to compute the vertex.

Another is to compute a forward vector ie

```
n = normalize(camera_pos - bb_pos);

```

then, a right vector ie

```
d = normalize(cross(n, camera_down);

```

and finally a down/up vector

```
r = cross( n, d);

```

These can be used to rotate the bb position with matrix multiplication.

> **Comments:**
> **username_0**: Thanks for your answer, this code alone doesn't rotate the quad towards the camera like one would expect for a billboard, it looks like the bbOffset still needs to be modified by another parameter to complete the effect... see my edit if you're interested  
> **username_1**: I added a bit to my answer hopefully this will get you a little closer to what you want.  
> **username_0**: The view/identity matrix trick worked perfectly. Thanks!  

---

