?>
?>
?>
大纲
1.准备阶段
FBX的模型导入 etc.
2.PmxEditor的基本概念
各种骨骼(肩P,肩C,足D, 捩骨…)的作用,
轴限制,Local轴,简单设置骨骼末端指向,
IK骨的设置,权重修正骨骼的设置
https://www.nicovideo.jp/watch/sm20439024
3.形态键的制作
1. 骨骼绑定
https://www.bilibili.com/video/BV13ZbRzPEyZ/
]]>当某一对象的性质或分布不依赖于方向时,称其为各向同性(isotropic);相反,如果其性质或分布依赖于方向,则称其为各向异性。
头发的高光之所以被称为各向异性高光,主要是因为它的反射特性受到头发丝的方向影响,而不是均匀地向所有方向反射光线。
Blinn-Phong模型中计算高光的方法是,将视向量与光源方向的半程向量H,去与法线N做点积。
但是对于头发来说这种算法有一点点小问题:一根发丝某处的法线可以有无数条!
当我们把头发看作非常细的细丝时,某点的垂直平面上所有的向量都可以看作此点的法向量。
没办法定义唯一法线的话,也就没办法计算高光了,那该怎么办呢(。•́︿•̀。)
]]>但是NexGiMa烘焙物理导入Blender的流程也有一些问题,比如如何导出60帧数据,如何解决无法导出表情等等。
使用NexGiMa烘焙物理并导入Blender的基本流程
①将模型以及动作文件导入NexGiMa
注意:模型的骨骼命名不可以使用非日文常用汉字,长度不可以超过16个字符,否则物理无法烘焙。
②在ツール→オプション面板进行如下设置
物理演算设置为120FPS(最高精度),編集フレームレート(编辑帧率)在确保动作已经导入之后设置为目标帧率——如果是想做30帧视频就设置为30FPS,想做60帧视频就设置为60FPS,默认的编辑帧率是30FPS,设置为60之后时间线上的总关键帧数会翻倍。
③在模型模式下(非相机模式),按A选中所有骨骼。打开ツール→キー焼き込み(关键帧烧录),进行如下设置。
输入起始帧到最终帧,勾选物理焼き込み(物理烧录),ベイク用物理演算設定(烘焙用物理演算设置)选择MMD互換120FPS。据其他博主,这里只能选择MMD互換120FPS,选择其他选项会导致奇怪的物理。最后点击OK开始烘焙。
]]>配布地址:Download
]]>基本思路就是,在屏幕空间中,沿着主光方向对刘海遮罩做一个偏移。
然后通过相机距离(视图距离)来控制偏移量近大远小,反正切函数或者平方反比都可以。最好再用min()卡一个上限 。
这边偏移量的衰减因子只使用了相机距离,还可以考虑到面部朝向和灯光的夹角,具体之后再想想怎么优化..)
BTW,在非NPR分支的Blender正式版本中可以使用AOV来输出向量到合成器中,AOV类型设置为颜色就行。
]]>
使用Python脚本创建平滑法线自定义属性,并在几何节点中引用。通过几何节点创建几何实例副本单独负责描边,不会影响原有网格法线。
import bpy
import bmesh
from mathutils import Vector
def store_average_normals_using_vertex_position(obj):
if obj.type != 'MESH':
print(f"Object {obj.name} is not a mesh. Skipping.")
return
# Switch to object mode if needed
if bpy.context.mode != 'OBJECT':
bpy.ops.object.mode_set(mode='OBJECT')
# Create BMesh from object data
mesh = obj.data
bm = bmesh.new()
bm.from_mesh(mesh)
# Ensure normals are updated
bm.normal_update()
# Prepare a custom vertex attribute layer for average normals
avg_normal_layer = bm.verts.layers.float_vector.new("average_normal")
# Create a dictionary to store average normals by vertex position
average_normal_hash = {}
# Iterate over all vertices to calculate average normals based on position
for vert in bm.verts:
position = tuple(vert.co)
if position not in average_normal_hash:
average_normal_hash[position] = vert.normal.copy()
else:
average_normal_hash[position] += vert.normal
# Normalize the accumulated normals
for position in average_normal_hash:
average_normal_hash[position].normalize()
# Assign the averaged normals back to vertices
for vert in bm.verts:
position = tuple(vert.co)
vert[avg_normal_layer] = average_normal_hash[position]
# Write the modified BMesh back to the mesh
bm.to_mesh(mesh)
bm.free()
# Apply the function to the selected object
obj = bpy.context.object
if obj:
store_average_normals_using_vertex_position(obj)
print(f"Average normals stored in custom data layer for {obj.name}.")
else:
print("No object selected.")
背面法描边是让顶点沿着法线移动一段距离,去做一个类似于鸡蛋壳的包裹来实现描边的。但是就拿一个正方体举例,一个角上其实有三个顶点。这三个顶点在不做处理的情况下,共享位置,但法线来自于各自属于的面。所以在扩张的时候就会沿着不同方向,导致三个点分离,从而产生描边断裂。
上面的代码的逻辑就是,将所有共享坐标的顶点的法线全部平均化再指定回去,这样就可以保证位置相同的顶点不会在向外扩展之后分离。
]]>