Force gpu skinning

This commit is contained in:
unknown 2019-04-06 14:13:38 +02:00
parent 5b2b6428d5
commit 4ecec19ad3
8 changed files with 24 additions and 75 deletions

View file

@ -1,20 +0,0 @@
uniform vec4 skinBones[skinMaxBones * 3];
mat4 getBoneMat(const int boneIndex) {
int bonei = boneIndex * 3;
return mat4(skinBones[bonei],
skinBones[bonei + 1],
skinBones[bonei + 2],
0.0, 0.0, 0.0, 1.0);
}
mat4 getSkinningMat(const ivec4 bone, const vec4 weight) {
return weight.x * getBoneMat(bone.x) +
weight.y * getBoneMat(bone.y) +
weight.z * getBoneMat(bone.z) +
weight.w * getBoneMat(bone.w);
}
mat3 getSkinningMatVec(const mat4 skinningMat) {
return mat3(skinningMat[0].xyz, skinningMat[1].xyz, skinningMat[2].xyz);
}

View file

@ -1017,15 +1017,10 @@ class ArmoryExporter:
# Write the bind pose transform array
oskin['transformsI'] = []
if rpdat.arm_skin == 'CPU':
for i in range(bone_count):
skeletonI = (armature.matrix_world @ bone_array[i].matrix_local).inverted_safe()
oskin['transformsI'].append(self.write_matrix(skeletonI))
else:
for i in range(bone_count):
skeletonI = (armature.matrix_world @ bone_array[i].matrix_local).inverted_safe()
skeletonI = (skeletonI @ bobject.matrix_world)
oskin['transformsI'].append(self.write_matrix(skeletonI))
for i in range(bone_count):
skeletonI = (armature.matrix_world @ bone_array[i].matrix_local).inverted_safe()
skeletonI = (skeletonI @ bobject.matrix_world)
oskin['transformsI'].append(self.write_matrix(skeletonI))
# Export the per-vertex bone influence data
group_remap = []

View file

@ -311,15 +311,10 @@ def export_skin(self, bobject, armature, vert_list, o):
# Write the bind pose transform array
oskin['transformsI'] = []
if rpdat.arm_skin == 'CPU':
for i in range(bone_count):
skeletonI = (armature.matrix_world @ bone_array[i].matrix_local).inverted_safe()
oskin['transformsI'].append(self.write_matrix(skeletonI))
else:
for i in range(bone_count):
skeletonI = (armature.matrix_world @ bone_array[i].matrix_local).inverted_safe()
skeletonI = (skeletonI @ bobject.matrix_world)
oskin['transformsI'].append(self.write_matrix(skeletonI))
for i in range(bone_count):
skeletonI = (armature.matrix_world @ bone_array[i].matrix_local).inverted_safe()
skeletonI = (skeletonI @ bobject.matrix_world)
oskin['transformsI'].append(self.write_matrix(skeletonI))
# Export the per-vertex bone influence data
group_remap = []

View file

@ -4,32 +4,17 @@ def skin_pos(vert):
vert.add_include('compiled.inc')
rpdat = arm.utils.get_rp()
if rpdat.arm_skin == 'GPU (Matrix)':
vert.add_include('std/skinning_mat.glsl')
vert.add_uniform('vec4 skinBones[skinMaxBones * 3]', link='_skinBones', included=True)
vert.add_uniform('float posUnpack', link='_posUnpack')
vert.write_attrib('mat4 skinningMat = getSkinningMat(ivec4(bone * 32767), weight);')
vert.write_attrib('spos.xyz *= posUnpack;')
vert.write_attrib('spos *= skinningMat;')
vert.write_attrib('spos.xyz /= posUnpack;')
else: # Dual Quat
vert.add_include('std/skinning.glsl')
vert.add_uniform('vec4 skinBones[skinMaxBones * 2]', link='_skinBones', included=True)
vert.add_uniform('float posUnpack', link='_posUnpack')
vert.write_attrib('vec4 skinA;')
vert.write_attrib('vec4 skinB;')
vert.write_attrib('getSkinningDualQuat(ivec4(bone * 32767), weight, skinA, skinB);')
vert.write_attrib('spos.xyz *= posUnpack;')
vert.write_attrib('spos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, spos.xyz) + skinA.w * spos.xyz); // Rotate')
vert.write_attrib('spos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz)); // Translate')
vert.write_attrib('spos.xyz /= posUnpack;')
vert.add_include('std/skinning.glsl')
vert.add_uniform('vec4 skinBones[skinMaxBones * 2]', link='_skinBones', included=True)
vert.add_uniform('float posUnpack', link='_posUnpack')
vert.write_attrib('vec4 skinA;')
vert.write_attrib('vec4 skinB;')
vert.write_attrib('getSkinningDualQuat(ivec4(bone * 32767), weight, skinA, skinB);')
vert.write_attrib('spos.xyz *= posUnpack;')
vert.write_attrib('spos.xyz += 2.0 * cross(skinA.xyz, cross(skinA.xyz, spos.xyz) + skinA.w * spos.xyz); // Rotate')
vert.write_attrib('spos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz)); // Translate')
vert.write_attrib('spos.xyz /= posUnpack;')
def skin_nor(vert, prep):
rpdat = arm.utils.get_rp()
if rpdat.arm_skin == 'GPU (Matrix)':
vert.write('mat3 skinningMatVec = getSkinningMatVec(skinningMat);')
vert.write(prep + 'wnormal = normalize(N * (vec3(nor.xy, pos.w) * skinningMatVec));')
else: # Dual Quat
vert.write(prep + 'wnormal = normalize(N * (vec3(nor.xy, pos.w) + 2.0 * cross(skinA.xyz, cross(skinA.xyz, vec3(nor.xy, pos.w)) + skinA.w * vec3(nor.xy, pos.w))));')
vert.write(prep + 'wnormal = normalize(N * (vec3(nor.xy, pos.w) + 2.0 * cross(skinA.xyz, cross(skinA.xyz, vec3(nor.xy, pos.w)) + skinA.w * vec3(nor.xy, pos.w))));')

View file

@ -482,11 +482,9 @@ class ArmRPListItem(bpy.types.PropertyGroup):
arm_lensflare: BoolProperty(name="Lens Flare", default=False, update=assets.invalidate_shader_cache)
arm_lut_texture: StringProperty(name="LUT Texture", description="Color Grading", default="", update=assets.invalidate_shader_cache)
arm_skin: EnumProperty(
items=[('GPU (Dual-Quat)', 'GPU (Dual-Quat)', 'GPU (Dual-Quat)'),
('GPU (Matrix)', 'GPU (Matrix)', 'GPU (Matrix)'),
('CPU', 'CPU', 'CPU'),
items=[('On', 'On', 'On'),
('Off', 'Off', 'Off')],
name='Skinning', description='Skinning method', default='GPU (Dual-Quat)', update=assets.invalidate_shader_cache)
name='Skinning', description='Enable skinning', default='On', update=assets.invalidate_shader_cache)
arm_skin_max_bones_auto: BoolProperty(name="Auto Bones", description="Calculate amount of maximum bones based on armatures", default=True, update=assets.invalidate_compiled_data)
arm_skin_max_bones: IntProperty(name="Max Bones", default=50, min=1, max=3000, update=assets.invalidate_shader_cache)
arm_particles: EnumProperty(

View file

@ -768,7 +768,7 @@ class ARM_PT_RenderPathRendererPanel(bpy.types.Panel):
layout.prop(rpdat, 'arm_particles')
layout.prop(rpdat, 'arm_skin')
row = layout.row()
row.enabled = rpdat.arm_skin.startswith('GPU')
row.enabled = rpdat.arm_skin == 'On'
row.prop(rpdat, 'arm_skin_max_bones_auto')
row = layout.row()
row.enabled = not rpdat.arm_skin_max_bones_auto

View file

@ -522,7 +522,7 @@ def is_bone_animation_enabled(bobject):
return False
def export_bone_data(bobject):
return bobject.find_armature() and is_bone_animation_enabled(bobject) and get_rp().arm_skin.startswith('GPU')
return bobject.find_armature() and is_bone_animation_enabled(bobject) and get_rp().arm_skin == 'On'
def kode_studio_mklink_win(sdk_path):
# Fight long-path issues on Windows

View file

@ -251,10 +251,6 @@ project.addSources('Sources');
assets.add_khafile_def('arm_stream')
rpdat = arm.utils.get_rp()
if rpdat.arm_skin == 'CPU':
assets.add_khafile_def('arm_skin_cpu')
elif rpdat.arm_skin == 'GPU (Matrix)':
assets.add_khafile_def('arm_skin_mat')
if rpdat.arm_skin != 'Off':
assets.add_khafile_def('arm_skin')
@ -598,7 +594,7 @@ const float voxelgiAperture = """ + str(round(rpdat.arm_voxelgi_aperture * 100)
""")
# Skinning
if rpdat.arm_skin.startswith('GPU'):
if rpdat.arm_skin == 'On':
f.write(
"""const int skinMaxBones = """ + str(rpdat.arm_skin_max_bones) + """;
""")