[{"data":1,"prerenderedAt":642},["ShallowReactive",2],{"\u002F2021-01-24-ue4-fest-npr-note\u002F":3},{"id":4,"title":5,"body":6,"date":618,"description":12,"extension":619,"meta":620,"navigation":623,"path":635,"seo":636,"stem":637,"tags":638,"__hash__":641},"blogs\u002F_legacy\u002F2021\u002F2021-01-24-ue4-fest-npr-note.md","UE4-Fest-NPR笔记",{"type":7,"value":8,"toc":592},"minimark",[9,13,22,29,32,35,38,41,44,47,54,57,60,63,69,72,81,85,88,91,123,126,129,132,135,138,145,148,152,155,158,164,167,173,176,190,193,196,202,205,213,216,219,225,228,234,237,240,246,249,255,259,262,268,271,277,281,284,290,296,299,305,308,311,314,320,323,326,329,340,343,346,352,355,366,369,372,378,381,385,388,391,405,408,411,417,420,426,429,435,438,444,448,451,457,460,466,470,473,476,484,487,493,496,499,502,512,515,522,528,531,535,538,541,550,554,557,586,589],[10,11,12],"p",{},"UEFest2020上一篇关于NPR效果实现的演讲。",[10,14,15,16],{},"PPT在这里：",[17,18,19],"a",{"href":19,"rel":20},"https:\u002F\u002Fwww.slideshare.net\u002FEpicGamesJapan\u002Funreal-festext2020winter-npr",[21],"nofollow",[10,23,24,25],{},"后面发现的视频在这里：",[17,26,27],{"href":27,"rel":28},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=L1tC6wnub2k",[21],[10,30,31],{},"npr是个很宽泛的概念，这边主要是讲ToonShader。",[10,33,34],{},"演讲的内容基于U4.25.4。",[10,36,37],{},"这边由于没有一个明确的生产目标，所以更多的关注流程的实现。",[10,39,40],{},"由于原始的PPT有很多思考和选择过程的记录，在这里会稍微重新组织下内容。",[10,42,43],{},"笔记是基于PPT制作的，后面虽然找到Youtube的视频，不过没找到时间从头看一遍……所以可能有的地方和视频说的不一样~",[10,45,46],{},"完成之后的效果：",[10,48,49],{},[50,51],"img",{"alt":52,"src":53},"image-20210117215700253","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117215700253_thumb.png",[10,55,56],{},"角色名 :齋藤胡桃",[10,58,59],{},"原本是准备做来放到MarketPlace上去卖的，为了这次演示重新设计，全部重做了一下。",[10,61,62],{},"角色设计方案：",[10,64,65],{},[50,66],{"alt":67,"src":68},"image-20210117220008747","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117220008747_thumb.png",[10,70,71],{},"最初的目标：",[73,74,75,78],"blockquote",{},[10,76,77],{},"不是实现单纯的CellShader，而是希望将一些插画绘制的手法融合进来。",[10,79,80],{},"希望是能够在相对较暗的空间中也能够很好的渲染出结果来。",[82,83,84],"h2",{"id":84},"引擎改造",[10,86,87],{},"和Unity不同，要在UE4实现渲染的改造是需要修改引擎代码的。",[10,89,90],{},"网络上也能找到一些改造UE4的Shading Model的方法介绍。",[92,93,94,102,109,116],"ul",{},[95,96,97],"li",{},[17,98,101],{"href":99,"rel":100},"https:\u002F\u002Fqiita.com\u002Fdgtanaka\u002Fitems\u002F41f96ef2090820035609",[21],"UE4のShading Modelを拡張する",[95,103,104],{},[17,105,108],{"href":106,"rel":107},"https:\u002F\u002Fforums.unrealengine.com\u002Fcommunity\u002Fwork-in-progress\u002F41288-toon-shading-model",[21],"Toon shading model",[95,110,111],{},[17,112,115],{"href":113,"rel":114},"https:\u002F\u002Fforums.unrealengine.com\u002Fdevelopment-discussion\u002Frendering\u002F1537277-toon-shading-models-stylized-rendering-experiments",[21],"Toon Shading Models, Stylized Rendering Experiments",[95,117,118],{},[17,119,122],{"href":120,"rel":121},"https:\u002F\u002Fforums.unrealengine.com\u002Fdevelopment-discussion\u002Frendering\u002F1704696-wip-anime-toon-stylized-shading-model",[21],"[WIP] Anime\u002FToon Stylized Shading Model",[10,124,125],{},"改造引擎主要的问题是实现方式很难和别人共享，改造后的版本只能内部使用。",[10,127,128],{},"重新编译C++和Shader的成本也很高，最大的麻烦是，引擎升级。",[10,130,131],{},"所以演讲中使用的制作流程没有对引擎进行改造。",[82,133,134],{"id":134},"基于向量",[10,136,137],{},"基于向量计算，使用蓝图和材质节点来达到目标。",[10,139,140,141],{},"参考的文章是这篇：",[17,142,143],{"href":143,"rel":144},"https:\u002F\u002Funrealengine.hatenablog.com\u002Fentry\u002F2019\u002F12\u002F01\u002F000735",[21],[10,146,147],{},"使用向量的内积来在材质节点中获取更多的信息。",[149,150,151],"h3",{"id":151},"光照向量",[10,153,154],{},"由于材质中的Light Vector只能在前向渲染中使用，所以在蓝图中写入到Material Parameter Collection中。",[10,156,157],{},"之后便可以使用法线与光照向量相乘来达到模拟计算光照的效果",[10,159,160],{},[50,161],{"alt":162,"src":163},"image-20210118232253776","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210118232253776_thumb.png",[10,165,166],{},"前面的内积结果会在模型上生成灰阶的渲染值，使用这个值作为下一步的Mask的基础。上图比较简单，当前的渲染结果是这样的：",[10,168,169],{},[50,170],{"alt":171,"src":172},"image-20210118233129915","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210118233129915_thumb.png",[10,174,175],{},"为了模仿通常ToonShader的效果，基于上面的内积的结果，总共计算了四个层的内容：",[92,177,178,181,184,187],{},[95,179,180],{},"Shadow: 模拟阴影计算，连接到SubSurface",[95,182,183],{},"HightLight: 模拟高光，连接到Emmisive",[95,185,186],{},"RimLight: 连接到Emmisive",[95,188,189],{},"Patten: 连接到SubSurface",[10,191,192],{},"上面三种都是比较常见的效果，所谓的Patten，其实是模仿有的漫画里的那种网点图的感觉",[10,194,195],{},"对于用于计算基础的内积结果，根据贴图会采用不同的插值方式。",[10,197,198],{},[50,199],{"alt":200,"src":201},"image-20210119230758187_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230758187_thumb.png",[10,203,204],{},"同时会按照需求使用一些其他的向量节点：CameraVector、ReflectionVector。",[10,206,207,208,212],{},"贴图提供的信息并不一定会按照0",[209,210,211],"del",{},"1来插值，有的会设定为1.0是必然使用，而0","0.5才会插值，总之这个可以按照需求来进行灵活的控制，毕竟贴图是自己制作的。",[149,214,215],{"id":215},"阴影",[10,217,218],{},"用于模仿阴影计算：",[10,220,221],{},[50,222],{"alt":223,"src":224},"image-20210119230028530_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230028530_thumb.png",[10,226,227],{},"效果是这样的：",[10,229,230],{},[50,231],{"alt":232,"src":233},"image-20210119230049261_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230049261_thumb.png",[149,235,236],{"id":236},"高光",[10,238,239],{},"用于高光模拟计算，由于是连接到Emmisive，所以可以受到Bloom的影响。",[10,241,242],{},[50,243],{"alt":244,"src":245},"image-20210119230329943_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230329943_thumb.png",[10,247,248],{},"最终结果是这样的：",[10,250,251],{},[50,252],{"alt":253,"src":254},"image-20210119230350972_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230350972_thumb.png",[149,256,258],{"id":257},"rimlight","RimLight",[10,260,261],{},"就是边缘高光，通常用Fresnel进行模拟的那个效果。",[10,263,264],{},[50,265],{"alt":266,"src":267},"image-20210119230505405_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230505405_thumb.png",[10,269,270],{},"最终效果是这样的：",[10,272,273],{},[50,274],{"alt":275,"src":276},"image-20210119230527413_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230527413_thumb.png",[149,278,280],{"id":279},"patten","Patten",[10,282,283],{},"这个不是很常见，是用于模仿漫画的那种类似网点的感觉：",[10,285,286],{},[50,287],{"alt":288,"src":289},"image-20210119230616663_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230616663_thumb.png",[10,291,292],{},[50,293],{"alt":294,"src":295},"image-20210119230707458_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230707458_thumb.png",[10,297,298],{},"最终结果像是这样：",[10,300,301],{},[50,302],{"alt":303,"src":304},"image-20210119225712396_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119225712396_thumb.png",[82,306,307],{"id":307},"光照问题",[10,309,310],{},"光照模型选用的是SubSurface，虽然有尝试过Preintegrated Skin和Subsurface Profile，但是效果都有些微妙。",[10,312,313],{},"SubSurface存在一个问题，就是从上面来的DirectionalLight会对模型造成一种类似贯通的效果：",[10,315,316],{},[50,317],{"alt":318,"src":319},"image-20210119231317537_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119231317537_thumb.png",[10,321,322],{},"使用Mesh进行遮挡也无法取消掉这个效果，似乎是SubSurface光照模型的计算特性导致的。只能暂时放弃。",[10,324,325],{},"对于主导的DirectionalLight向上的时候，会出现阴影很重的感觉。只能通过限制光的角度，或者额外的打一些光来解决。",[10,327,328],{},"另外就是拟似计算的光照不够硬，通过调整自己的参数来解决：",[92,330,331,334,337],{},[95,332,333],{},"『Shadow Bias 』=>『1.0 』",[95,335,336],{},"『Shadow Slope Bias 』=>『0.0 』",[95,338,339],{},"『Shadow Filter Sharpe 』=>『1.0 』",[149,341,342],{"id":342},"法线整理",[10,344,345],{},"脸部不需要阴影，所以对模型进行处理，让法线全部朝向一个方向。",[10,347,348],{},[50,349],{"alt":350,"src":351},"image-20210119231922084_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119231922084_thumb.png",[10,353,354],{},"这种处理方式参照的是：",[73,356,357,360],{},[10,358,359],{},"GUILTY GEAR Xrd開発スタッフが送るアニメ調キャラモデリングTIPS",[10,361,362],{},[17,363,364],{"href":364,"rel":365},"https:\u002F\u002Fwww.slideshare.net\u002FASW_Yokohama\u002Fguilty-gear-xrdtips-124324946",[21],[149,367,368],{"id":368},"眼球高光",[10,370,371],{},"很强的那个高光是靠UnLit的材质内部计算出来的。",[10,373,374],{},[50,375],{"alt":376,"src":377},"image-20210119232139763_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119232139763_thumb.png",[10,379,380],{},"眼球有添加一个假的各向异性光照来提高立体感，根据光照的方向不同这个高光的位置会移动。",[149,382,384],{"id":383},"outline","OutLine",[10,386,387],{},"没有使用PostProcess，而是在Blender里面制作了一个反转的Mesh，直接包含在骨骼模型里面。",[10,389,390],{},"此外还提供了以下的功能：",[92,392,393,396,399,402],{},[95,394,395],{},"使用VertexColor来控制OutLine的粗细",[95,397,398],{},"轮廓线是带颜色的",[95,400,401],{},"根据摄像的距离调整粗细",[95,403,404],{},"根据FOV调整粗细",[10,406,407],{},"粗细控制基于Vertex Color，会使用Opacity Mask额外的处理，当数值小于0.1时，就不会绘制轮廓线。",[10,409,410],{},"不过主要的还是依靠将计算结果连接到World Position Offset进行的控制：",[10,412,413],{},[50,414],{"alt":415,"src":416},"image-20210119233127332_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233127332_thumb.png",[10,418,419],{},"颜色则是通过UV查找基础颜色，并与另外准备的OutLine颜色进行叠加计算，实际进行的计算比较简单：",[10,421,422],{},[50,423],{"alt":424,"src":425},"image-20210119233437571_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233437571_thumb.png",[10,427,428],{},"摄像的距离来调整Offset，这是通过内置的相机位置和Actor位置节点来计算的：",[10,430,431],{},[50,432],{"alt":433,"src":434},"image-20210119233551957_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233551957_thumb.png",[10,436,437],{},"FOV也是类似的，直接用Hlsl的custom node去取出来：",[10,439,440],{},[50,441],{"alt":442,"src":443},"image-20210119233636756_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233636756_thumb.png",[149,445,447],{"id":446},"textureinline","TextureInline",[10,449,450],{},"最后还使用了TextureInLine的技巧，实际上并不在OutLine的计算中，只是专门的准备了贴图，用于模拟一些不是很容易计算出来的描画效果。",[10,452,453],{},[50,454],{"alt":455,"src":456},"image-20210119233840764_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233840764_thumb.png",[10,458,459],{},"并不是单纯的打包在角色贴图里面，而是另外有一张贴图，可以动态的在叠加时对RGBA通道进行强弱和颜色调整。计算节点：",[10,461,462],{},[50,463],{"alt":464,"src":465},"image-20210119233935788_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233935788_thumb.png",[82,467,469],{"id":468},"postprocess","PostProcess",[10,471,472],{},"主要不是介绍UE4本身的pp，而是指希望达到的一些后处理效果，主要有",[149,474,475],{"id":475},"模造纸效果",[10,477,478,483],{},[17,479,482],{"href":480,"rel":481},"https:\u002F\u002Fja.wikipedia.org\u002Fwiki\u002F%E3%83%91%E3%83%A9%E3%83%95%E3%82%A3%E3%83%B3%E7%B4%99",[21],"パラフィン紙","，一时找不到准确的术语翻译，就硬翻成模造纸吧。总之是一种纸，在上个世代的动画制作中用到。这种带颜色的透明的纸叠加到原画上，能够模拟出类似反光或者阴影的效果。",[10,485,486],{},"实现上使用了PP的Dirt Mask功能：",[10,488,489],{},[50,490],{"alt":491,"src":492},"image-20210120193421631_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120193421631_thumb.png",[10,494,495],{},"贴图使用黑白的就ok了。",[149,497,498],{"id":498},"柔光滤镜",[10,500,501],{},"Diffusion Filter",[73,503,504],{},[10,505,506,507,511],{},"似乎是摄影术语，不是很明确是否采用了正确的翻译。虽然在镜片厂商看到的繁中译法是",[508,509,510],"em",{},"擴散濾光片","，但是其他一些地方又似乎分类为柔光滤镜。不纠结了……",[10,513,514],{},"总之就是这样一种滤镜，会将光线进行柔和的扩散，对降低图像在高光区域的对比度非常有效。据说可以在摄影时消除脸部的毛刺和皱纹，不是很确定是不是一个东西~",[10,516,517,518],{},"参考的这里：",[17,519,520],{"href":520,"rel":521},"https:\u002F\u002Ftwitter.com\u002Fmonsho1977\u002Fstatus\u002F670634806124920832",[21],[10,523,524],{},[50,525],{"alt":526,"src":527},"image-20210120195648749_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120195648749_thumb.png",[10,529,530],{},"印象中虚幻应该也有模糊用的节点，可能有什么限制达不到需求吧。",[149,532,534],{"id":533},"kuwahara滤镜","Kuwahara滤镜",[10,536,537],{},"桑原道義老师所发明的平滑化用的滤镜。",[10,539,540],{},"能够让画面产生油画一样的效果，有利于让渲染结果看起来更接近动画的背景的感觉。",[10,542,543,544,549],{},"这边这篇介绍的很详细的实现方式：",[17,545,548],{"href":546,"rel":547},"https:\u002F\u002Fwww.raywenderlich.com\u002F100-unreal-engine-4-paint-filter-tutorial#toc-anchor-004",[21],"Unreal Engine 4 Paint Filter Tutorial","。",[149,551,553],{"id":552},"其他pp特效","其他PP特效",[10,555,556],{},"还列出了一些其他的后处理特效，应该都是默认的特效",[92,558,559,562,565,568,571,574,577,580,583],{},[95,560,561],{},"Cinematic DoF",[95,563,564],{},"Lens Flares",[95,566,567],{},"Bloom",[95,569,570],{},"Exposure",[95,572,573],{},"Chromatic Aberration",[95,575,576],{},"Vignette Intensity",[95,578,579],{},"Color Grading LUT",[95,581,582],{},"Motion Blur",[95,584,585],{},"etc ...",[82,587,588],{"id":588},"总结",[10,590,591],{},"总之在不使用自定义引擎特效的情况下达到了一开始设定的ToonShader的效果。",{"title":593,"searchDepth":594,"depth":595,"links":596},"",2,3,[597,598,605,611,617],{"id":84,"depth":594,"text":84},{"id":134,"depth":594,"text":134,"children":599},[600,601,602,603,604],{"id":151,"depth":595,"text":151},{"id":215,"depth":595,"text":215},{"id":236,"depth":595,"text":236},{"id":257,"depth":595,"text":258},{"id":279,"depth":595,"text":280},{"id":307,"depth":594,"text":307,"children":606},[607,608,609,610],{"id":342,"depth":595,"text":342},{"id":368,"depth":595,"text":368},{"id":383,"depth":595,"text":384},{"id":446,"depth":595,"text":447},{"id":468,"depth":594,"text":469,"children":612},[613,614,615,616],{"id":475,"depth":595,"text":475},{"id":498,"depth":595,"text":498},{"id":533,"depth":595,"text":534},{"id":552,"depth":595,"text":553},{"id":588,"depth":594,"text":588},"2021-01-24","md",{"layout":621,"status":622,"published":623,"author":624,"author_login":626,"author_email":627,"wordpress_id":628,"wordpress_url":629,"date_gmt":630,"excerpt":631},"post","publish",true,{"display_name":625,"login":626,"email":627,"url":593},"风铃","flinkor","flinkor@foxmail.com",3258,"\u002F?p=3258","2021-01-24 04:01:00 +0000",{"type":7,"value":632},[633],[10,634,12],{},"\u002F2021-01-24-ue4-fest-npr-note",{"title":5,"description":12},"_legacy\u002F2021\u002F2021-01-24-ue4-fest-npr-note",[639,640],"unreal fest","NPR","okWPDXLenIskJvqhFh5Rbfa9MxWxVV-ezWOKLVF8v64",1788763178553]