Normally the Sally Camera Background Plugin + Quest 3 is the way to go.
But hey, why not for desktop? Make your own"virtual girl" "VAMtual girl" (lol) who hangs around all day while you work, using VAM and whatever animations/scenes you have sitting around.
Claude whipped this up this script for me. I don't personally know the windows API or python. feel free to make it better and repost it or whatever.
If you don't know / understand what this code does, you should probably ask your favorite GPT.
Don't trust anyone on the internet asking you to run python on your computer, especially me!
Since this manipulates the VAM desktop window via the low level windows API's this runs "outside" VAM in a seperate command line.
You need to have python installed, if you don't know how to do that, ask your favorite GPT.
Start Vam as normal using the desktop bat file.
Open a scene with the scene plugin sally cameracolorbackground running (default chroma is 0,0,255 blue)
make sure you don't have any walls/slates/skyboxes as that will get in the way of the blue background.
you should see your person/atom/whatever in front of a solid blue background.
set your vam window to the maximum size you want the scene to impinge on your desktop. (you can go full screen if you want)
Next: in windows,
create a folder such as /vam_chroma (where ever you want, i have mine at the same level as vam)
save the script as vam_chroma.py in the same folder
open cmd
install dependancies
Then run:
the VAM window border and blue background should disappear.
you should still have full control of the scene as long as you click on the controllers like you usually do
"u" to show menu
"f1" to toggle the bar.
other vam desktop keys/mouse buttons work as normal, as long as the last thing you clicked on was something visible in the scene
you can still interact with windows behind the "VAMtual girl" - VAM is set to always on top, so she may get in your way.
when you are done, hit enter in the cmd window to restore the standard VAM window state (not hidden)
you can edit the script if you want a different chroma key value.
But hey, why not for desktop? Make your own
Claude whipped this up this script for me. I don't personally know the windows API or python. feel free to make it better and repost it or whatever.
If you don't know / understand what this code does, you should probably ask your favorite GPT.
Don't trust anyone on the internet asking you to run python on your computer, especially me!
Since this manipulates the VAM desktop window via the low level windows API's this runs "outside" VAM in a seperate command line.
You need to have python installed, if you don't know how to do that, ask your favorite GPT.
Start Vam as normal using the desktop bat file.
Open a scene with the scene plugin sally cameracolorbackground running (default chroma is 0,0,255 blue)
make sure you don't have any walls/slates/skyboxes as that will get in the way of the blue background.
you should see your person/atom/whatever in front of a solid blue background.
set your vam window to the maximum size you want the scene to impinge on your desktop. (you can go full screen if you want)
Next: in windows,
create a folder such as /vam_chroma (where ever you want, i have mine at the same level as vam)
save the script as vam_chroma.py in the same folder
open cmd
install dependancies
Code:
pip install psutil
Then run:
Code:
python vam_chroma.py
the VAM window border and blue background should disappear.
you should still have full control of the scene as long as you click on the controllers like you usually do
"u" to show menu
"f1" to toggle the bar.
other vam desktop keys/mouse buttons work as normal, as long as the last thing you clicked on was something visible in the scene
you can still interact with windows behind the "VAMtual girl" - VAM is set to always on top, so she may get in your way.
when you are done, hit enter in the cmd window to restore the standard VAM window state (not hidden)
you can edit the script if you want a different chroma key value.
Python:
import ctypes
from ctypes import wintypes
import time
# Windows API constants
GWL_STYLE = -16
GWL_EXSTYLE = -20
WS_CAPTION = 0x00C00000
WS_THICKFRAME = 0x00040000
WS_MINIMIZEBOX = 0x00020000
WS_MAXIMIZEBOX = 0x00010000
WS_SYSMENU = 0x00080000
WS_EX_LAYERED = 0x00080000
LWA_COLORKEY = 0x00000001
SWP_FRAMECHANGED = 0x0020
SWP_NOMOVE = 0x0002
SWP_NOSIZE = 0x0001
SWP_NOZORDER = 0x0004
HWND_TOPMOST = -1
HWND_NOTOPMOST = -2
# Load Windows DLLs
user32 = ctypes.windll.user32
kernel32 = ctypes.windll.kernel32
# Define callback type for EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM)
def get_window_by_process_name(process_name):
"""Find window handle by process name (e.g., 'vam.exe')"""
import psutil
target_pids = []
for proc in psutil.process_iter(['pid', 'name']):
if proc.info['name'] and proc.info['name'].lower() == process_name.lower():
target_pids.append(proc.info['pid'])
if not target_pids:
print(f"Process '{process_name}' not found")
return None
print(f"Found PIDs for {process_name}: {target_pids}")
found_hwnd = []
def enum_callback(hwnd, lparam):
if user32.IsWindowVisible(hwnd):
pid = wintypes.DWORD()
user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
if pid.value in target_pids:
# Get window title
length = user32.GetWindowTextLengthW(hwnd) + 1
title = ctypes.create_unicode_buffer(length)
user32.GetWindowTextW(hwnd, title, length)
if title.value: # Only windows with titles
print(f" Found window: '{title.value}' (hwnd: {hwnd})")
found_hwnd.append((hwnd, title.value))
return True
user32.EnumWindows(EnumWindowsProc(enum_callback), 0)
if found_hwnd:
# Return the first main window found
return found_hwnd[0][0]
return None
def remove_window_border(hwnd):
"""Remove window border/frame"""
# Get window and client rects before removing border
window_rect = wintypes.RECT()
client_rect = wintypes.RECT()
user32.GetWindowRect(hwnd, ctypes.byref(window_rect))
user32.GetClientRect(hwnd, ctypes.byref(client_rect))
# Calculate frame offsets (border + title bar)
# Client rect is relative to client area, so we need screen coords
pt = wintypes.POINT(0, 0)
user32.ClientToScreen(hwnd, ctypes.byref(pt))
frame_left = pt.x - window_rect.left
frame_top = pt.y - window_rect.top
# Get current style
style = user32.GetWindowLongW(hwnd, GWL_STYLE)
# Remove border styles
style &= ~WS_CAPTION
style &= ~WS_THICKFRAME
style &= ~WS_MINIMIZEBOX
style &= ~WS_MAXIMIZEBOX
style &= ~WS_SYSMENU
# Apply new style
user32.SetWindowLongW(hwnd, GWL_STYLE, style)
# Calculate new position and size to keep client area in same place
new_x = window_rect.left + frame_left
new_y = window_rect.top + frame_top
new_width = client_rect.right - client_rect.left
new_height = client_rect.bottom - client_rect.top
# Reposition window so client area stays in the same screen position
user32.SetWindowPos(hwnd, None, new_x, new_y, new_width, new_height,
SWP_NOZORDER | SWP_FRAMECHANGED)
print("Window border removed")
def set_always_on_top(hwnd, on_top=True):
"""Set window to always be on top (or remove that flag)"""
hwnd_insert = wintypes.HWND(HWND_TOPMOST if on_top else HWND_NOTOPMOST)
result = user32.SetWindowPos(hwnd, hwnd_insert, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE)
if result:
print(f"Window set to {'always on top' if on_top else 'normal z-order'}")
else:
print("Failed to set window z-order")
return result
def apply_chroma_key(hwnd, color_rgb):
"""Apply chroma key (color key transparency) to window
color_rgb: tuple of (R, G, B) - pixels of this color will be transparent
"""
# Get current extended style
ex_style = user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
# Add layered window style
user32.SetWindowLongW(hwnd, GWL_EXSTYLE, ex_style | WS_EX_LAYERED)
# Convert RGB to COLORREF (BGR format)
r, g, b = color_rgb
colorref = r | (g << 8) | (b << 16)
# Set color key - pixels matching this color become transparent
result = user32.SetLayeredWindowAttributes(hwnd, colorref, 0, LWA_COLORKEY)
if result:
print(f"Chroma key applied: RGB({r}, {g}, {b})")
else:
print("Failed to apply chroma key")
return result
def restore_window(hwnd):
"""Restore window to normal state"""
# Restore default style
style = user32.GetWindowLongW(hwnd, GWL_STYLE)
style |= WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU
user32.SetWindowLongW(hwnd, GWL_STYLE, style)
# Remove layered style
ex_style = user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
ex_style &= ~WS_EX_LAYERED
user32.SetWindowLongW(hwnd, GWL_EXSTYLE, ex_style)
# Remove always-on-top
set_always_on_top(hwnd, False)
user32.SetWindowPos(hwnd, None, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED)
print("Window restored to normal")
def main():
print("Looking for vam.exe window...")
hwnd = get_window_by_process_name("vam.exe")
if not hwnd:
print("\nCould not find vam.exe window.")
print("Make sure VAM is running and has a visible window.")
return
print(f"\nFound window handle: {hwnd}")
# Blue chroma key color (pure blue)
# You can change this to match your desired chroma color
BLUE = (0, 0, 255)
# Apply modifications
print("\nApplying modifications...")
remove_window_border(hwnd)
apply_chroma_key(hwnd, BLUE)
set_always_on_top(hwnd)
print("\nDone! The window now has:")
print(" - No border")
print(" - Blue (0, 0, 255) pixels will be transparent")
print(" - Always on top")
print("\nPress Enter to restore the window to normal, or Ctrl+C to exit...")
try:
input()
restore_window(hwnd)
except KeyboardInterrupt:
print("\nExiting without restoring window")
if __name__ == "__main__":
main()