Skip to content

Instantly share code, notes, and snippets.

@lampysprites
Created January 7, 2021 20:15
Show Gist options
  • Save lampysprites/990c564dc881e8f95a36bf34bfa56b52 to your computer and use it in GitHub Desktop.
Save lampysprites/990c564dc881e8f95a36bf34bfa56b52 to your computer and use it in GitHub Desktop.
Blender script for rounding vertices to camera pixels (aka playstation wobble)
import bpy
import bmesh
# PROOF OF CONCEPT VERSION
#
# THIS SCRIPT "PROJECTS" THE EDGES OF CAMERA PIXELS INTO 3D SPACE, SO THAT YOU CAN IMITATE
# "PLAYSTATION WOBBLE" BY SHRINKWRAPPING YOUR MESHES TO BOTH OF THEM THE SAME TIME
#
# TO CREATE A BIGGER MESH, CHANGE THE DEPTH VARIABLE BELOW
#
# IF A VERTEX LEAVES THE GENERATED GRID, THE EDGES WILL DISTORT - PERHAPS WILL FIX LATER
#
# USAGE:
# - MOVE THE CAMERA TO THE CENTER AND UNDO ITS ROTATION
# - SELECT THE CAMERA
# - RUN THE SCRIPT
#
# BY twitter.com/lampysprites
# ORIGINAL IDEA BY twitter.com/@Lev_Protter
#buncha vars
cam = bpy.context.scene.camera
cam_obj = bpy.context.active_object
depth = 10 # FIXME i'm hardcoded
frame = cam.data.view_frame(scene=bpy.context.scene)
resolutionX = int(bpy.context.scene.render.resolution_x * (bpy.context.scene.render.resolution_percentage / 100))
resolutionY = int(bpy.context.scene.render.resolution_y * (bpy.context.scene.render.resolution_percentage / 100))
topRight = frame[0]
bottomRight = frame[1]
bottomLeft = frame[2]
topLeft = frame[3]
px_right = (topRight-topLeft) / resolutionX
px_up = (topRight-bottomRight) / resolutionY
# editable meshes
bmx = bmesh.new()
bmy = bmesh.new()
for x in range(0, resolutionX):
start_dn = bottomLeft + x * px_right
dir_dn = (start_dn - cam_obj.location).normalized()
start_up = topLeft + x * px_right
dir_up = (start_up - cam_obj.location).normalized()
a = bmx.verts.new(start_up)
b = bmx.verts.new(start_dn)
c = bmx.verts.new(start_up + dir_up * depth)
d = bmx.verts.new(start_dn + dir_dn * depth)
bmx.faces.new([a,b,d,c])
for y in range(0, resolutionY):
start_left = bottomLeft + y * px_up
dir_left = (start_left - cam_obj.location).normalized()
start_right = bottomRight + y * px_up
dir_right = (start_right - cam_obj.location).normalized()
a = bmy.verts.new(start_left)
b = bmy.verts.new(start_right)
c = bmy.verts.new(start_left + dir_left * depth)
d = bmy.verts.new(start_right + dir_right * depth)
bmy.faces.new([a,b,d,c])
# create the permanent mesth
mex = bpy.data.meshes.new("SnapMeshX")
bmx.to_mesh(mex)
bmx.free() # free and prevent further access
mey = bpy.data.meshes.new("SnapMeshY")
bmy.to_mesh(mey)
bmy.free() # free and prevent further access
# add to scene
obx = bpy.data.objects.new("SnapMeX",mex)
bpy.context.collection.objects.link(obx)
oby = bpy.data.objects.new("SnapMeY",mey)
bpy.context.collection.objects.link(oby)
# parent to the camera
obx.parent = cam_obj
obx.matrix_parent_inverse = cam_obj.matrix_world.inverted()
oby.parent = cam_obj
oby.matrix_parent_inverse = cam_obj.matrix_world.inverted()
@lampysprites
Copy link
Author

If it's not clear, unlike Lev Protter's method, this expects the Nearest Surface Point shrinkwraps, not Nearest Vertex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment