Is it possible to billboard control bones to the viewport camera?

I’d like to have non-deforming rig controls always face the viewport camera, to have them visible no matter the viewing angle.

Is this possible?


I think this is what you’re looking for

Hey @joseph, hope you’re doing great!

I’m trying to billboard the bone to the viewport camera (screenspace axis), not the render camera. Attempting to have certain control bones w/ custom shapes always face me when I’m animating.

Ah, I understand. You’re going to need drivers and scripting for that, you can’t directly access the view transform without going through the API

You’ll need a depsgraph update handler and a matrix calculation, something like this:

import bpy
import mathutils

def align_bone_to_view():
    context = bpy.context
    region_data = context.region_data
    if not region_data:
        return mathutils.Quaternion()
    
    view_matrix = region_data.view_matrix.inverted()

    forward = view_matrix.col[0].xyz.normalized()
    up = view_matrix.col[2].xyz.normalized()
    
    return mathutils.Quaternion((forward, up, forward.cross(up)))

def update_bone_alignment(scene):
    bone = bpy.data.objects["Armature"].pose.bones["Bone"]
    bone.rotation_quaternion = align_bone_to_view()

bpy.app.handlers.frame_change_pre.append(update_bone_alignment)

Then you’ll need to use this in a driver

I have not tested this extensively, I do not know if it will work correctly

Wow, thanks for taking your time making this script! Will take a look when I can later. Curious, should the driver be pasted in all three of the bone’s rotation values?

Years ago I was dabbling with an experiment that can change color of an object depending on its relative angle to the render viewport camera. But that’s of course done in shader nodes. Maybe there’s a way to come up with some smart solution that involves geo-nodes…

viewport_camera_to_color.blend (2.6 MB)