11 KiB
Raw Blame History

Assimp入门

https://assimp-docs.readthedocs.io/en/latest/about/introduction.html

其他卡通渲染推主

https://twitter.com/rukikuri

VRM格式地址

https://vrm.dev/

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

MToonhttps://dwango.github.io/vrm/univrm/shaders/mtoon/ Ue4中的卡通渲染https://qiita.com/com04/items/a7895160df8d854fe924

材质: https://qiita.com/ruyo/items/ddf727e9fa81a24070fb (细节都在这里) https://qiita.com/ruyo/items/28255f26725a6b6bd475

Unlit

PBR

SSS

灯光调整

2种方法

  • 开启天光的LowerHemisphereIsSolidColor但这样会场景效果变得有些奇怪
  • 添加一个从下往上的方向光

使用这个方法 以及 PBR材质中的BaseColor与Emissive进行插值来接近HalfLambda的效果。

调整面部法线来柔化面部阴影

曝光与ToneMapper问题解决

ToneMapper与曝光会影响贴图的亮度所以需要尝试干掉或者抵消掉他们的影响。

image

image

手动去除了Gammer矫正以及ToneMapper取消并且使用 人眼适应节点抵消曝光效果。

除此之外还使用RayTracingQualitySwitchReplace节点与人眼适应节点做了Raytracing质量调整。手机端为1

阴影

image 使用了SceneCaptureComponent2D。 在Orthographic平行投影*将CaptureSource设置为 "SceneDepth in R"TexrureTarget格式设置为 "RTF R32f"。 这将导致深度在UnrealUnit中线性地写入缓冲区默认为1=1cm。 别紧张。

image 要用Shadowmap投出一个阴影你只需要知道从光线中看到的深度以及投影矩阵的矩阵。 我们会把这些东西找回来,传给材料。 https://www.shibuya24.info/entry/shadowmap

官方的SceneCaptureComponent2D会做很多无用的渲染工作推荐自己重新写一个以减少不必要的消耗。

蓝图传递逆矩阵

在蓝图中国计算出SceneCaptureComponent2D的逆矩阵后将其传入材质中。 image

材质内

在一个自定义节点中将参数打包成float4x4并进行计算。 现在你可以从世界坐标中参考相应的影子图。 在材料函数中结果返回0-1。 image

描边

在具体节点方面, 投影结果 → TransformPosition节点转换为ViewSpace的转换结果 Pixel Thickness → VectorLength的值。 乘以倒数→部分除以VectorLength的值再乘以反数→部分除以VectorLength的值。 使用ScreenResolusion的原因是为了确保不影响窗口大小和宽高比。 我不确定我是否准备好了...... 在MToon再现方面我们需要能够选择 "恒定厚度模式 "和 "世界坐标参考模式"。 image

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所以有一个分数。 最后,正常化。

VRMglTF转换时需要注意

改变坐标系。

  • 转换为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实现运行时重定向

image 将复制资产设置为AnimInstance你就可以走了。

复制源头网状物。 设置在编辑器中创建的AnimBP

要复制的网状物。 设置VrmAnimInstanceCopy

IM4U

https://github.com/bm9/IM4U https://github.com/bm9/UnrealEngine_IM4UPlugin

Blender和pmx2fbx

U3d日本分部分项

『崩壊3rd』開発者が語るアニメ風レンダリングの極意 ユニティちゃんトゥーンシェーダー2.0使いこなしスペシャル ~こだわりの活用法を紹介します!~

〈七つの大罪〉をゲームで! 高品質グラフィックを具現化するための技法と開発最適化のご紹介 by Jaeseong Ryu 他

Muro_CG

使用Unity卡通着色的3D动画表达 https://qiita.com/MuRo_CG/items/c417ef6d6cbeed3dd42b

Unity トゥーンシェーディングを使ったDアニメ表現 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

米哈游

http://www.uniteseoul.com/2018/download_files/T1_0503_2.pdf

米哈游面部阴影实现: Improved Alpha-Tested Magnification for Vector Textures and Special Effects

https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf