Skip to content
122 changes: 99 additions & 23 deletions projector.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,26 +138,46 @@ def add_projector_node_tree_to_spot(spot):
map_1.location = auto_pos(200)

sep = nodes.new('ShaderNodeSeparateXYZ')
sep.location = auto_pos(350)

div_1 = nodes.new('ShaderNodeMath')
div_1.operation = 'DIVIDE'
div_1.name = ADDON_ID + 'div_01'
div_1.location = auto_pos(200)

div_2 = nodes.new('ShaderNodeMath')
div_2.operation = 'DIVIDE'
div_2.name = ADDON_ID + 'div_02'
div_2.location = auto_pos(y=-200)

com = nodes.new('ShaderNodeCombineXYZ')
com.inputs['Z'].default_value = 1.0
com.location = auto_pos(200)
sep.location = auto_pos(200, y=-150)

keystone_horizontal = nodes.new('ShaderNodeMath')
keystone_horizontal.operation = "MULTIPLY"
keystone_horizontal.name = 'keystone_horizontal'
keystone_horizontal.label = 'Horizontal Keystone'
keystone_horizontal.inputs[0].default_value = 0.0
keystone_horizontal.location = auto_pos(200, y=-100)

keystone_vertical = nodes.new('ShaderNodeMath')
keystone_vertical.operation = "MULTIPLY"
keystone_vertical.name = 'keystone_vertical'
keystone_vertical.label = 'Vertical Keystone'
keystone_vertical.inputs[1].default_value = 0.0
keystone_vertical.location = auto_pos(y= -300)

add_1 = nodes.new('ShaderNodeMath')
add_1.operation = "ADD"
add_1.name = ADDON_ID + 'add_01'
add_1.location = auto_pos(200, y=-100)

add_2 = nodes.new('ShaderNodeMath')
add_2.operation = "ADD"
add_2.name = ADDON_ID + 'add_02'
add_2.location = auto_pos(200,y=-150)

vec_div = nodes.new('ShaderNodeVectorMath')
vec_div.operation = "DIVIDE"
vec_div.name = ADDON_ID + 'vec_div'
vec_div.location = auto_pos(200, y=50)

map_2 = nodes.new('ShaderNodeMapping')
map_2.location = auto_pos(200)
map_2.vector_type = 'TEXTURE'

scale = nodes.new('ShaderNodeVectorMath')
scale.operation = "SCALE"
scale.name ='post_scale'
scale.location = auto_pos(200)

add = nodes.new('ShaderNodeMixRGB')
add.blend_type = 'ADD'
add.inputs[0].default_value = 1
Expand Down Expand Up @@ -211,19 +231,24 @@ def add_projector_node_tree_to_spot(spot):
tree.links.new(tex.outputs['Normal'], map_1.inputs['Vector'])
tree.links.new(map_1.outputs['Vector'], sep.inputs['Vector'])

tree.links.new(sep.outputs[0], div_1.inputs[0]) # X -> value0
tree.links.new(sep.outputs[2], div_1.inputs[1]) # Z -> value1
tree.links.new(sep.outputs[1], div_2.inputs[0]) # Y -> value0
tree.links.new(sep.outputs[2], div_2.inputs[1]) # Z -> value1
tree.links.new(sep.outputs[0], keystone_horizontal.inputs[1])
tree.links.new(sep.outputs[1], keystone_vertical.inputs[0])
tree.links.new(sep.outputs[2], add_1.inputs[1])

tree.links.new(div_1.outputs[0], com.inputs[0])
tree.links.new(div_2.outputs[0], com.inputs[1])
tree.links.new(keystone_horizontal.outputs[0], add_1.inputs[0])
tree.links.new(keystone_vertical.outputs[0], add_2.inputs[1])

tree.links.new(com.outputs['Vector'], map_2.inputs['Vector'])
tree.links.new(add_1.outputs[0], add_2.inputs[0])

tree.links.new(map_1.outputs['Vector'], vec_div.inputs[0])
tree.links.new(add_2.outputs[0], vec_div.inputs[1])

tree.links.new(vec_div.outputs['Vector'], map_2.inputs['Vector'])
tree.links.new(map_2.outputs['Vector'], scale.inputs[0])

# Textures
# a) generated texture
tree.links.new(map_2.outputs['Vector'], add.inputs['Color1'])
tree.links.new(scale.outputs['Vector'], add.inputs['Color1'])
tree.links.new(add.outputs['Color'], img.inputs['Vector'])
tree.links.new(add.outputs['Color'], group_output_node.inputs[0])
# b) checker texture
Expand Down Expand Up @@ -306,6 +331,40 @@ def update_throw_ratio(proj_settings, context):



def update_keystone(proj_settings, context):
"""
Apply the keystone parameters to the texture
"""
projector = get_projector(context)

h_keystone = proj_settings.get('h_keystone', 0.0)
v_keystone = proj_settings.get('v_keystone', 0.0)

spot = projector.children[0]
nodes = spot.data.node_tree.nodes['Group'].node_tree.nodes
if bpy.app.version < (2, 81):
nodes['keystone_horizontal'].translation[0] = h_keystone
nodes['keystone_vertical'].translation[1] = v_keystone
else:
nodes['keystone_horizontal'].inputs[0].default_value = h_keystone
nodes['keystone_vertical'].inputs[1].default_value = v_keystone

def update_post_scale(proj_settings, context):
"""
Apply the post scale parameters to the texture
"""

projector = get_projector(context)
post_scale = 1 / proj_settings.get('post_scale', 0.0)

spot = projector.children[0]
nodes = spot.data.node_tree.nodes['Group'].node_tree.nodes
if bpy.app.version < (2, 81):
nodes['post_scale'].translation[3] = post_scale
else:
nodes['post_scale'].inputs[3].default_value = post_scale


def update_lens_shift(proj_settings, context):
"""
Apply the shift to the camera and texture.
Expand Down Expand Up @@ -636,6 +695,23 @@ class ProjectorSettings(bpy.types.PropertyGroup):
soft_min=-20, soft_max=20,
update=update_lens_shift,
subtype='PERCENTAGE')
h_keystone: bpy.props.FloatProperty(
name="Horizontal KeyStone",
description="Amount of Horizontal Keystone Distortion",
soft_min=-1, soft_max=1,
update=update_keystone)
v_keystone: bpy.props.FloatProperty(
name="Vertical KeyStone",
description="Amount of Vertical Keystone Distortion",
soft_min=-1, soft_max=1,
update=update_keystone)
post_scale: bpy.props.FloatProperty(
name="Scale Factor",
description="Global scale factor of the projected image",
min=0.001,
default=1.0,
update=update_post_scale
)
projected_color: bpy.props.FloatVectorProperty(
subtype='COLOR',
update=update_checker_color)
Expand Down
17 changes: 14 additions & 3 deletions ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,22 @@ def draw(self, context):
res_row.enabled = True
# Lens Shift
col = box.column(align=True)
col.prop(proj_settings,
'h_shift', text='Horizontal Shift')
col.prop(proj_settings, 'v_shift', text='Vertical Shift')
col.prop(proj_settings, 'h_shift', text='H Shift')
col.prop(proj_settings, 'v_shift', text='V Shift')
layout.prop(proj_settings,
'projected_texture', text='Project')

#Keystone
col = box.column(align=True)
col.prop(proj_settings,
'h_keystone', text="H Keystone")
col.prop(proj_settings,
'v_keystone', text="V Keystone")

#Post Projection Scale
col = box.column(align=True)
col.prop(proj_settings,
"post_scale", text="Scale Adjustment Factor")
# Pixel Grid
box.prop(proj_settings, 'show_pixel_grid')

Expand Down