8.8 KiB
Assimp入门
https://assimp-docs.readthedocs.io/en/latest/about/introduction.html
其他卡通渲染推主
VRoid商城地址
VRM格式地址
Unity3d导入插件
导入https://github.com/vrm-c/UniVRM/releases 导出Fbx插件:https://github.com/KellanHiggins/UnityFBXExporter
VRM4U
https://github.com/ruyo/UnrealEngine_VRM4UPlugin https://github.com/ruyo/VRM4U
渲染参考
原文(上/下): https://qiita.com/ruyo/items/ec082d81dea3033e1500 https://qiita.com/ruyo/items/71a3f2f694d2853b3f1e
光照: https://qiita.com/ruyo/items/28255f26725a6b6bd475
其他参考
MToon:https://dwango.github.io/vrm/univrm/shaders/mtoon/ Ue4中的卡通渲染:https://qiita.com/com04/items/a7895160df8d854fe924
曝光与ToneMapper问题解决
ToneMapper与曝光会影响贴图的亮度,所以需要尝试干掉或者抵消掉他们的影响。
手动去除了Gammer矫正以及ToneMapper取消,并且使用 人眼适应节点抵消曝光效果。
除此之外,还使用RayTracingQualitySwitchReplace节点与人眼适应节点做了Raytracing质量调整。(手机端为1)
阴影
使用了SceneCaptureComponent2D。
在Orthographic(平行投影*)中,将CaptureSource设置为 "SceneDepth in R",TexrureTarget格式设置为 "RTF R32f"。
这将导致深度在UnrealUnit中线性地写入缓冲区(默认为1=1cm)。 别紧张。
要用Shadowmap投出一个阴影,你只需要知道从光线中看到的深度,以及投影矩阵的矩阵。
我们会把这些东西找回来,传给材料。
https://www.shibuya24.info/entry/shadowmap
官方的SceneCaptureComponent2D会做很多无用的渲染工作,推荐自己重新写一个,以减少不必要的消耗。
蓝图传递逆矩阵
在蓝图中国计算出SceneCaptureComponent2D的逆矩阵后,将其传入材质中。
材质内
在一个自定义节点中,将参数打包成float4x4,并进行计算。
现在你可以从世界坐标中参考相应的影子图。
在材料函数中,结果返回0-1。
描边
在具体节点方面,
投影结果 → TransformPosition节点转换为ViewSpace的转换结果
Pixel Thickness → VectorLength的值。
乘以倒数→部分除以VectorLength的值,再乘以反数→部分除以VectorLength的值。
使用ScreenResolusion的原因是为了确保不影响窗口大小和宽高比。
我不确定我是否准备好了......
在MToon再现方面,我们需要能够选择 "恒定厚度模式 "和 "世界坐标参考模式"。
http://historia.co.jp/archives/5587/
使用PoseableMeshComponent,与CopyPoseFromSkeletalComponent函数实现外描边。到时候比对一下这个方法与我的重定义图元方法的效率。
轮廓光
使用MaterialCapture材质制作轮廓光。
光照模式
默认的MToon为无光照模式(自定义光照效果)
其余的工作将通过增加材料参数来体现数值。 我就不说了,因为这样做是多余的。 (我没有评论了...) 也可以应用ShadingShadingShift。
主源和GI可以通过在自定义节点中写出以下内容来获得。 如果你用GetSkySHDiffuseSimple或GetSkySHDiffuse搜索usf文件,会有帮助。 不要忘了在最终输出的SkyLight(ResolvedView.SkyLightColor.rgb)中乘以颜色。
//主光源.usf
return ResolvedView.DirectionalLightColor;
//GIの影響.usf,然而这个是天光
#if SIMPLE_FORWARD_SHADING
float4 NormalVector = float4(Normal, 1);
float3 Intermediate0;
Intermediate0.x = dot(View.SkyIrradianceEnvironmentMap[0], NormalVector);
Intermediate0.y = dot(View.SkyIrradianceEnvironmentMap[1], NormalVector);
Intermediate0.z = dot(View.SkyIrradianceEnvironmentMap[2], NormalVector);
// max to not get negative colors
return max(0, Intermediate0) * ResolvedView.SkyLightColor.rgb;
#else
float4 NormalVector = float4(Normal, 1);
float3 Intermediate0, Intermediate1, Intermediate2;
Intermediate0.x = dot(View.SkyIrradianceEnvironmentMap[0], NormalVector);
Intermediate0.y = dot(View.SkyIrradianceEnvironmentMap[1], NormalVector);
Intermediate0.z = dot(View.SkyIrradianceEnvironmentMap[2], NormalVector);
float4 vB = NormalVector.xyzz * NormalVector.yzzx;
Intermediate1.x = dot(View.SkyIrradianceEnvironmentMap[3], vB);
Intermediate1.y = dot(View.SkyIrradianceEnvironmentMap[4], vB);
Intermediate1.z = dot(View.SkyIrradianceEnvironmentMap[5], vB);
float vC = NormalVector.x * NormalVector.x - NormalVector.y * NormalVector.y;
Intermediate2 = View.SkyIrradianceEnvironmentMap[6].xyz * vC;
// max to not get negative colors
return max(0, Intermediate0 + Intermediate1 + Intermediate2) * ResolvedView.SkyLightColor.rgb;
#endif
其他光照模型
Runtime载入思路
NewObject<USkeletalMesh>()
SkeletalMesh->GetResourceForRendering()
->LODRenderData[0]
• StaticVertexBuffers
顶点信息。 最起码,这将填补。
• MultiSizeIndexContainer
- 绘图时的顶点信息。 如果你要运行时加载的话,也要埋下这一点。
- 从GameThread停止重写的成员从RenderThread重写。
• SkeletalMesh->GetImportedModel()->LODModels[0].Sections;
- 网格和材料信息。 我也要把这个埋了。
• SkeletalMesh->RegisterMorphTarget()
- 混合形状信息。 我也要把这个埋了。
- UE4的顶点权重为uint8,所以有一个分数。 最后,正常化。
VRM(glTF)转换时需要注意
改变坐标系。
- 转换为Z-up
- 转换比例尺为虚幻单位(x100)
- 支持多种根骨。
- 去除不必要的骨头
- 如果你不想移除的话,可以添加一个假根骨(root)。
字符与编码转换
物理资源导入
• bs = NewObject<USkeletalBodySetup>();
• ct = NewObject<UPhysicsConstraintTemplate>();
• physicsAsset->SkeletalBodySetups.Add(bs);
• physicsAsset->ConstraintSetup.Add(ct);
我想让我的骨头不至于发狂。
- 物理学变得很粗糙。 当碰撞被猛烈地掩埋时,就会引起注意。
- 增加计算次数,会在一定程度上改善它。
- 我想保持我想要的形状。
- 我的头发因为地心引力而垂下来。
- 可移动的范围可以指定,但移动不规范。 杂项:
VRMSpringBone是Unity的一个实现,目前已经发布了VRMSpringBone。
- 理论上可以移植到UE4上。
- 源码(VRMSpringBone.cs)只有329行。
- 我不知道这样可以吗?
于是作者移植了VRMSpringBone。
我现在可以看VRM了。
- 你现在可以导入/运行时加载
- 我现在也能读出混合形状和碰撞了!
- 现在,你可以重新创建VRMSpringBone
- 你现在可以干扰UE4的碰撞了。
StaticMesh的运行时加载也是可能的。
- 我可以创建一个自定义的摇摆骨质节点。
- 对于那些对PhysicalAsset和AnimDynamics节点的行为不满意的人。
- 你为什么不尝试着去做一个呢?
动画部分
要想导入动画,可以使用
- (一) 骨架通用化
- (二) 重新定位动画资产。
但两者都是编辑器功能,无法在runtime中使用。
使用AnimBP实现运行时重定向
复制源头网状物。 设置在编辑器中创建的AnimBP
要复制的网状物。 设置VrmAnimInstanceCopy
IM4U
https://github.com/bm9/IM4U https://github.com/bm9/UnrealEngine_IM4UPlugin
Blender和pmx2fbx
Muro_CG
使用Unity卡通着色的3D动画表达 https://qiita.com/MuRo_CG/items/c417ef6d6cbeed3dd42b
Unity トゥーンシェーディングを使った3Dアニメ表現 https://qiita.com/MuRo_CG/items/c417ef6d6cbeed3dd42b https://github.com/unity3d-jp/unitychan-crs
https://ja.whotwi.com/MuRo_CG/tweets/popular https://togetter.com/li/1438719
Unity_Japan
【Unite 2017 Tokyo】VR MAGIC! ~キャラクターに命を吹き込んだこの4年間の記録~ https://www.slideshare.net/Unite2017Tokyo/unite-2017-tokyovr-magic4
https://www.youtube.com/watch?v=N4_x9w7wNNY&feature=youtu.be