Point shadows placeholder.
This commit is contained in:
parent
8acd7bad43
commit
c4e3c144e0
|
@ -106,6 +106,15 @@ vec3 SSSSTransmittance(float translucency, float sssWidth, vec3 worldPosition, v
|
|||
float shadowTest(vec4 lPos) {
|
||||
lPos.xyz /= lPos.w;
|
||||
lPos.xy = lPos.xy * 0.5 + 0.5;
|
||||
|
||||
#ifdef _Clampstc
|
||||
// Filtering out of bounds, remove
|
||||
if (lPos.x < 0.0) return 1.0;
|
||||
if (lPos.y < 0.0) return 1.0;
|
||||
if (lPos.x > 1.0) return 1.0;
|
||||
if (lPos.y > 1.0) return 1.0;
|
||||
#endif
|
||||
|
||||
#ifdef _PCSS
|
||||
return PCSS(lPos.xy, lPos.z - shadowsBias);
|
||||
#else
|
||||
|
|
|
@ -778,7 +778,7 @@ class ArmoryExporter:
|
|||
if (action):
|
||||
for fcurve in action.fcurves:
|
||||
kind = ArmoryExporter.classify_animation_curve(fcurve)
|
||||
if (kind != kAnimationSampled):
|
||||
if kind != kAnimationSampled:
|
||||
if (fcurve.data_path == "location"):
|
||||
for i in range(3):
|
||||
if ((fcurve.array_index == i) and (not locAnimCurve[i])):
|
||||
|
@ -786,35 +786,35 @@ class ArmoryExporter:
|
|||
locAnimKind[i] = kind
|
||||
if (ArmoryExporter.animation_present(fcurve, kind)):
|
||||
locAnimated[i] = True
|
||||
elif (fcurve.data_path == "delta_location"):
|
||||
elif fcurve.data_path == "delta_location":
|
||||
for i in range(3):
|
||||
if ((fcurve.array_index == i) and (not deltaPosAnimCurve[i])):
|
||||
deltaPosAnimCurve[i] = fcurve
|
||||
deltaPosAnimKind[i] = kind
|
||||
if (ArmoryExporter.animation_present(fcurve, kind)):
|
||||
deltaPosAnimated[i] = True
|
||||
elif (fcurve.data_path == "rotation_euler"):
|
||||
elif fcurve.data_path == "rotation_euler":
|
||||
for i in range(3):
|
||||
if ((fcurve.array_index == i) and (not rotAnimCurve[i])):
|
||||
rotAnimCurve[i] = fcurve
|
||||
rotAnimKind[i] = kind
|
||||
if (ArmoryExporter.animation_present(fcurve, kind)):
|
||||
rotAnimated[i] = True
|
||||
elif (fcurve.data_path == "delta_rotation_euler"):
|
||||
elif fcurve.data_path == "delta_rotation_euler":
|
||||
for i in range(3):
|
||||
if ((fcurve.array_index == i) and (not deltaRotAnimCurve[i])):
|
||||
deltaRotAnimCurve[i] = fcurve
|
||||
deltaRotAnimKind[i] = kind
|
||||
if (ArmoryExporter.animation_present(fcurve, kind)):
|
||||
deltaRotAnimated[i] = True
|
||||
elif (fcurve.data_path == "scale"):
|
||||
elif fcurve.data_path == "scale":
|
||||
for i in range(3):
|
||||
if ((fcurve.array_index == i) and (not sclAnimCurve[i])):
|
||||
sclAnimCurve[i] = fcurve
|
||||
sclAnimKind[i] = kind
|
||||
if (ArmoryExporter.animation_present(fcurve, kind)):
|
||||
sclAnimated[i] = True
|
||||
elif (fcurve.data_path == "delta_scale"):
|
||||
elif fcurve.data_path == "delta_scale":
|
||||
for i in range(3):
|
||||
if ((fcurve.array_index == i) and (not deltaSclAnimCurve[i])):
|
||||
deltaSclAnimCurve[i] = fcurve
|
||||
|
@ -846,7 +846,7 @@ class ArmoryExporter:
|
|||
|
||||
o['transform']['values'] = self.write_matrix(bobject.matrix_local)
|
||||
|
||||
if (sampledAnimation):
|
||||
if sampledAnimation:
|
||||
self.export_object_sampled_animation(bobject, scene, o)
|
||||
else:
|
||||
structFlag = False
|
||||
|
@ -857,7 +857,7 @@ class ArmoryExporter:
|
|||
o['animation_transforms'] = []
|
||||
|
||||
deltaTranslation = bobject.delta_location
|
||||
if (deltaPositionAnimated):
|
||||
if deltaPositionAnimated:
|
||||
# When the delta location is animated, write the x, y, and z components separately
|
||||
# so they can be targeted by different tracks having different sets of keys.
|
||||
for i in range(3):
|
||||
|
@ -888,7 +888,7 @@ class ArmoryExporter:
|
|||
structFlag = True
|
||||
|
||||
translation = bobject.location
|
||||
if (locationAnimated):
|
||||
if locationAnimated:
|
||||
# When the location is animated, write the x, y, and z components separately
|
||||
# so they can be targeted by different tracks having different sets of keys.
|
||||
for i in range(3):
|
||||
|
@ -908,7 +908,7 @@ class ArmoryExporter:
|
|||
animo['values'] = self.write_vector3d(translation)
|
||||
structFlag = True
|
||||
|
||||
if (deltaRotationAnimated):
|
||||
if deltaRotationAnimated:
|
||||
# When the delta rotation is animated, write three separate Euler angle rotations
|
||||
# so they can be targeted by different tracks having different sets of keys.
|
||||
for i in range(3):
|
||||
|
@ -925,7 +925,7 @@ class ArmoryExporter:
|
|||
else:
|
||||
# When the delta rotation is not animated, write it in the representation given by
|
||||
# the object's current rotation mode. (There is no axis-angle delta rotation.)
|
||||
if (mode == "QUATERNION"):
|
||||
if mode == "QUATERNION":
|
||||
quaternion = bobject.delta_rotation_quaternion
|
||||
if ((math.fabs(quaternion[0] - 1.0) > kExportEpsilon) or (math.fabs(quaternion[1]) > kExportEpsilon) or (math.fabs(quaternion[2]) > kExportEpsilon) or (math.fabs(quaternion[3]) > kExportEpsilon)):
|
||||
animo = {}
|
||||
|
@ -945,7 +945,7 @@ class ArmoryExporter:
|
|||
animo['value'] = angle
|
||||
structFlag = True
|
||||
|
||||
if (rotationAnimated):
|
||||
if rotationAnimated:
|
||||
# When the rotation is animated, write three separate Euler angle rotations
|
||||
# so they can be targeted by different tracks having different sets of keys.
|
||||
for i in range(3):
|
||||
|
@ -1182,6 +1182,31 @@ class ArmoryExporter:
|
|||
return space.region_3d.perspective_matrix
|
||||
return None
|
||||
|
||||
def make_fake_omni_lamps(self, o, bobject):
|
||||
# Look down
|
||||
o['transform']['values'] = [1.0, 0.0, 0.0, bobject.location.x, 0.0, 1.0, 0.0, bobject.location.y, 0.0, 0.0, 1.0, bobject.location.z, 0.0, 0.0, 0.0, 1.0]
|
||||
if not hasattr(o, 'children'):
|
||||
o['children'] = []
|
||||
# Make child lamps
|
||||
for i in range(0, 5):
|
||||
child_lamp = {}
|
||||
child_lamp['name'] = o['name'] + '__' + str(i)
|
||||
child_lamp['data_ref'] = o['data_ref']
|
||||
child_lamp['type'] = 'lamp_object'
|
||||
if i == 0:
|
||||
mat = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
elif i == 1:
|
||||
mat = [0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
elif i == 2:
|
||||
mat = [0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
elif i == 3:
|
||||
mat = [0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
elif i == 4:
|
||||
mat = [-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
|
||||
child_lamp['transform'] = {}
|
||||
child_lamp['transform']['values'] = mat
|
||||
o['children'].append(child_lamp)
|
||||
|
||||
def export_object(self, bobject, scene, poseBone = None, parento = None):
|
||||
# This function exports a single object in the scene and includes its name,
|
||||
# object reference, material references (for meshes), and transform.
|
||||
|
@ -1190,7 +1215,7 @@ class ArmoryExporter:
|
|||
return
|
||||
|
||||
bobjectRef = self.bobjectArray.get(bobject)
|
||||
if (bobjectRef):
|
||||
if bobjectRef:
|
||||
type = bobjectRef["objectType"]
|
||||
|
||||
o = {}
|
||||
|
@ -1218,8 +1243,8 @@ class ArmoryExporter:
|
|||
# Export the object reference and material references.
|
||||
objref = bobject.data
|
||||
|
||||
if (type == kNodeTypeMesh):
|
||||
if (not objref in self.meshArray):
|
||||
if type == kNodeTypeMesh:
|
||||
if not objref in self.meshArray:
|
||||
self.meshArray[objref] = {"structName" : objref.name, "objectTable" : [bobject]}
|
||||
else:
|
||||
self.meshArray[objref]["objectTable"].append(bobject)
|
||||
|
@ -1257,28 +1282,28 @@ class ArmoryExporter:
|
|||
# self.ExportMorphWeights(bobject, shapeKeys, scene, o)
|
||||
# TODO
|
||||
|
||||
elif (type == kNodeTypeLamp):
|
||||
if (not objref in self.lampArray):
|
||||
elif type == kNodeTypeLamp:
|
||||
if not objref in self.lampArray:
|
||||
self.lampArray[objref] = {"structName" : objref.name, "objectTable" : [bobject]}
|
||||
else:
|
||||
self.lampArray[objref]["objectTable"].append(bobject)
|
||||
o['data_ref'] = self.lampArray[objref]["structName"]
|
||||
|
||||
elif (type == kNodeTypeCamera):
|
||||
if (not objref in self.cameraArray):
|
||||
elif type == kNodeTypeCamera:
|
||||
if not objref in self.cameraArray:
|
||||
self.cameraArray[objref] = {"structName" : objref.name, "objectTable" : [bobject]}
|
||||
else:
|
||||
self.cameraArray[objref]["objectTable"].append(bobject)
|
||||
o['data_ref'] = self.cameraArray[objref]["structName"]
|
||||
|
||||
elif (type == kNodeTypeSpeaker):
|
||||
if (not objref in self.speakerArray):
|
||||
elif type == kNodeTypeSpeaker:
|
||||
if not objref in self.speakerArray:
|
||||
self.speakerArray[objref] = {"structName" : objref.name, "objectTable" : [bobject]}
|
||||
else:
|
||||
self.speakerArray[objref]["objectTable"].append(bobject)
|
||||
o['data_ref'] = self.speakerArray[objref]["structName"]
|
||||
|
||||
if (poseBone):
|
||||
if poseBone:
|
||||
# If the object is parented to a bone and is not relative, then undo the bone's transform
|
||||
o['transform'] = {}
|
||||
o['transform']['values'] = self.write_matrix(poseBone.matrix.inverted())
|
||||
|
@ -1286,6 +1311,10 @@ class ArmoryExporter:
|
|||
# Export the transform. If object is animated, then animation tracks are exported here
|
||||
self.export_object_transform(bobject, scene, o)
|
||||
|
||||
# 6 directional lamps
|
||||
if type == kNodeTypeLamp and objref.lamp_omni_shadows:
|
||||
self.make_fake_omni_lamps(o, bobject)
|
||||
|
||||
# Viewport Camera - overwrite active camera matrix with viewport matrix
|
||||
if type == kNodeTypeCamera and bpy.data.worlds['Arm'].arm_play_viewport_camera and self.scene.camera != None and bobject.name == self.scene.camera.name:
|
||||
viewport_matrix = self.get_viewport_view_matrix()
|
||||
|
@ -1336,7 +1365,7 @@ class ArmoryExporter:
|
|||
armutils.write_arm(fp, bones_obj)
|
||||
armdata.data_cached = True
|
||||
|
||||
if (parento == None):
|
||||
if parento == None:
|
||||
self.output['objects'].append(o)
|
||||
else:
|
||||
parento['children'].append(o)
|
||||
|
@ -1943,6 +1972,12 @@ class ArmoryExporter:
|
|||
|
||||
# Parse nodes
|
||||
make_material.parse_lamp(objref.node_tree, o)
|
||||
|
||||
# Fake omni shadows
|
||||
if objref.lamp_omni_shadows:
|
||||
o['fov'] = 1.57
|
||||
o['strength'] /= 6
|
||||
|
||||
self.output['lamp_datas'].append(o)
|
||||
|
||||
def export_camera(self, objectRef):
|
||||
|
|
|
@ -74,7 +74,7 @@ def make_set_target(stage, node_group, node, currentNode=None, target_index=1, v
|
|||
|
||||
currentNode = nodes.find_node_by_link(node_group, currentNode, currentNode.inputs[target_index])
|
||||
|
||||
if currentNode.bl_idname == 'TargetNodeType':
|
||||
if currentNode.bl_idname == 'TargetNodeType' or currentNode.bl_idname == 'ShadowMapNodeType':
|
||||
targetId = currentNode.inputs[0].default_value
|
||||
stage['params'].append(targetId)
|
||||
# Store current target size
|
||||
|
@ -172,7 +172,10 @@ def make_bind_target(stage, node_group, node, constant_name, currentNode=None, t
|
|||
stage['params'].append(targetId)
|
||||
stage['params'].append(constant_name)
|
||||
|
||||
|
||||
elif currentNode.bl_idname == 'ShadowMapNodeType':
|
||||
targetId = currentNode.inputs[0].default_value
|
||||
stage['params'].append(targetId)
|
||||
stage['params'].append(constant_name)
|
||||
|
||||
elif currentNode.bl_idname == 'DepthBufferNodeType':
|
||||
targetId = '_' + currentNode.inputs[0].default_value
|
||||
|
@ -758,7 +761,7 @@ def parse_render_target(node, node_group, render_targets, depth_buffers):
|
|||
tnode = nodes.find_node_by_link(node_group, node, node.inputs[0])
|
||||
parse_render_target(tnode, node_group, render_targets, depth_buffers)
|
||||
|
||||
elif node.bl_idname == 'TargetNodeType':
|
||||
elif node.bl_idname == 'TargetNodeType' or node.bl_idname == 'ShadowMapNodeType':
|
||||
# Target already exists
|
||||
id = node.inputs[0].default_value
|
||||
for t in render_targets:
|
||||
|
@ -766,7 +769,7 @@ def parse_render_target(node, node_group, render_targets, depth_buffers):
|
|||
return
|
||||
|
||||
depth_buffer_id = None
|
||||
if node.inputs[3].is_linked:
|
||||
if node.bl_idname == 'TargetNodeType' and node.inputs[3].is_linked:
|
||||
# Find depth buffer
|
||||
depth_node = nodes.find_node_by_link(node_group, node, node.inputs[3])
|
||||
depth_buffer_id = depth_node.inputs[0].default_value
|
||||
|
@ -790,8 +793,23 @@ def parse_render_target(node, node_group, render_targets, depth_buffers):
|
|||
scale = size_node.inputs[0].default_value
|
||||
|
||||
# Append target
|
||||
target = make_render_target(node, scale, depth_buffer_id=depth_buffer_id)
|
||||
render_targets.append(target)
|
||||
if node.bl_idname == 'TargetNodeType':
|
||||
target = make_render_target(node, scale, depth_buffer_id=depth_buffer_id)
|
||||
render_targets.append(target)
|
||||
else: # ShadowMapNodeType
|
||||
target = make_shadowmap_target(node, scale)
|
||||
render_targets.append(target)
|
||||
|
||||
# Second shadowmap for point lamps
|
||||
# TODO: check if lamp users are visible
|
||||
for lamp in bpy.data.lamps:
|
||||
if lamp.type == 'POINT':
|
||||
# target = make_shadowmap_target(node, scale, '2')
|
||||
# render_targets.append(target)
|
||||
# break
|
||||
# Clamp omni-shadows, remove
|
||||
if lamp.lamp_omni_shadows:
|
||||
bpy.data.worlds['Arm'].world_defs += '_Clampstc'
|
||||
|
||||
elif node.bl_idname == 'ImageNodeType' or node.bl_idname == 'Image3DNodeType':
|
||||
# Target already exists
|
||||
|
@ -834,6 +852,17 @@ def make_render_target(n, scale, depth_buffer_id=None):
|
|||
target['depth_buffer'] = depth_buffer_id
|
||||
return target
|
||||
|
||||
def make_shadowmap_target(n, scale, postfix=''):
|
||||
target = {}
|
||||
# target['name'] = '_shadow_' + n.inputs[0].default_value + postfix
|
||||
target['name'] = n.inputs[0].default_value + postfix
|
||||
target['width'] = n.inputs[1].default_value
|
||||
target['height'] = n.inputs[2].default_value
|
||||
target['format'] = n.inputs[3].default_value
|
||||
if scale != 1.0:
|
||||
target['scale'] = scale
|
||||
return target
|
||||
|
||||
def make_image_target(n, scale):
|
||||
target = {}
|
||||
target['is_image'] = True
|
||||
|
|
|
@ -457,6 +457,20 @@ class TargetNode(Node, CGPipelineTreeNode):
|
|||
|
||||
self.outputs.new('NodeSocketShader', "Target")
|
||||
|
||||
class ShadowMapNode(Node, CGPipelineTreeNode):
|
||||
'''Create new shadow map target node'''
|
||||
bl_idname = 'ShadowMapNodeType'
|
||||
bl_label = 'Shadow Map'
|
||||
bl_icon = 'SOUND'
|
||||
|
||||
def init(self, context):
|
||||
self.inputs.new('NodeSocketString', "ID")
|
||||
self.inputs.new('NodeSocketInt', "Width")
|
||||
self.inputs.new('NodeSocketInt', "Height")
|
||||
self.inputs.new('NodeSocketString', "Format")
|
||||
|
||||
self.outputs.new('NodeSocketShader', "Target")
|
||||
|
||||
class ImageNode(Node, CGPipelineTreeNode):
|
||||
'''Create new image node'''
|
||||
bl_idname = 'ImageNodeType'
|
||||
|
@ -779,6 +793,7 @@ node_categories = [
|
|||
]),
|
||||
MyTargetNodeCategory("TARGETNODES", "Target", items=[
|
||||
NodeItem("TargetNodeType"),
|
||||
NodeItem("ShadowMapNodeType"),
|
||||
NodeItem("ImageNodeType"),
|
||||
NodeItem("Image3DNodeType"),
|
||||
NodeItem("TargetArrayNodeType"),
|
||||
|
|
|
@ -260,6 +260,7 @@ def init_properties():
|
|||
bpy.types.Lamp.lamp_clip_end = bpy.props.FloatProperty(name="Clip End", default=50.0)
|
||||
bpy.types.Lamp.lamp_fov = bpy.props.FloatProperty(name="Field of View", default=0.84)
|
||||
bpy.types.Lamp.lamp_shadows_bias = bpy.props.FloatProperty(name="Shadows Bias", description="Depth offset for shadow acne", default=0.0002)
|
||||
bpy.types.Lamp.lamp_omni_shadows = bpy.props.BoolProperty(name="Omnidirectional Shadows", description="Fakes omnidirectional shadows by creating 6 directional lights. Will result in preformance loss. Usable for deferred renderers only.", default=False)
|
||||
|
||||
if not 'Arm' in bpy.data.worlds:
|
||||
wrd = bpy.data.worlds.new('Arm')
|
||||
|
|
|
@ -163,6 +163,10 @@ class DataPropsPanel(bpy.types.Panel):
|
|||
layout.prop(obj.data, 'lamp_clip_end')
|
||||
layout.prop(obj.data, 'lamp_fov')
|
||||
layout.prop(obj.data, 'lamp_shadows_bias')
|
||||
layout.prop(obj.data, 'lamp_omni_shadows')
|
||||
if obj.data.lamp_omni_shadows:
|
||||
layout.label('Warning: Will result in performance loss.')
|
||||
layout.label('Temporary implementation.')
|
||||
elif obj.type == 'SPEAKER':
|
||||
layout.prop(obj.data, 'loop')
|
||||
layout.prop(obj.data, 'stream')
|
||||
|
|
Loading…
Reference in a new issue