[{"data":1,"prerenderedAt":2058},["ShallowReactive",2],{"blog-page-5":3,"blog-count":2057},[4,568,899,1513,1720],{"id":5,"title":6,"body":7,"date":545,"description":13,"extension":546,"meta":547,"navigation":550,"path":562,"seo":563,"stem":564,"tags":565,"__hash__":567},"blogs\u002F_legacy\u002F2021\u002F2021-02-01-game-narrative-notes-two.md","游戏叙事笔记两则",{"type":8,"value":9,"toc":507},"minimark",[10,14,17,20,24,27,36,39,42,45,50,53,56,59,63,66,69,72,75,79,82,85,88,92,100,111,115,118,121,125,128,131,134,138,144,147,151,154,159,162,166,169,174,177,181,187,190,194,197,200,203,206,209,212,219,226,229,236,239,243,254,257,264,267,270,274,277,280,284,287,290,293,297,300,303,306,310,313,316,320,323,326,330,333,336,339,343,346,349,352,356,359,362,365,368,371,374,377,380,406,409,413,424,427,431,442,446,449,463,466,469,475,478,484,487,490,493],[11,12,13],"p",{},"虽然之前看过一些叙事相关的，但是还是不得其门而入，最近看到两篇比较简单一些的，作了些笔记。",[11,15,16],{},"原本两篇是打算分开的，但是整理笔记的时候发现这两篇的理论有很高的相似性，所以就记录在一起了~",[11,18,19],{},"情节设计这块，似乎是有一些通用的设计术语的。比如三幕结构、激励事件这些，不过由于是专业外，所以有的词汇可能就会出现一些偏差……",[21,22,23],"h2",{"id":23},"叙事的五个转折点",[11,25,26],{},"这篇是之前看到有人推荐的比较适合入门的情节设置的文章：",[11,28,29],{},[30,31,35],"a",{"href":32,"rel":33},"https:\u002F\u002Fwww.storymastery.com\u002Fstory\u002Fscreenplay-structure-five-key-turning-points-successful-scripts\u002F",[34],"nofollow","STORY STRUCTURE: The 5 Key Turning Points of All Successful Screenplays",[11,37,38],{},"由五个转折点划分出六个阶段。总体而言和《救猫咪》的那套划分方式有些类似，不过更加简明易懂一些。",[11,40,41],{},"其实对这种划分方式一直有种强迫症，转折点的长度到底是多少呢？是一个场景吗？还是一个序列？",[11,43,44],{},"这个作者网站上还有一些其他的文章，基本上都是在同一个体系框架内的，有兴趣的可以延申阅读。不过感觉最核心的部分就在这篇文章里面了。",[46,47,49],"h3",{"id":48},"stage-1-the-setup","Stage 1: The Setup",[11,51,52],{},"剧情开始阶段的10%",[11,54,55],{},"所谓的铺垫阶段，用于将读者或者观众吸引到叙事之中，揭示主角的日常生活，并建立主角的形象。",[11,57,58],{},"大概就是所谓的“救猫咪”场景出现的地方。",[46,60,62],{"id":61},"turning-point-1-the-opportunity10","TURNING POINT #1: The opportunity(10%)",[11,64,65],{},"发生在10%处的第一个转折点",[11,67,68],{},"主角将得到一个机会，会为主角创造一个新的可见的目标，让主角踏上旅途。虽然说是一个机会，大抵上应当相当于“激励事件”。",[11,70,71],{},"这个点就是《黑客帝国》中，Neo被带去见Morpheus的地方。",[11,73,74],{},"需要注意的是，这里所产生的目标，并不是整个故事概念中的外部目标。而是这样一个目标，让主角进入下一个阶段……",[46,76,78],{"id":77},"stage-2-the-new-situation","Stage 2: The new situation",[11,80,81],{},"接下来的15%，主角开始应对由机会带来的新情况中。",[11,83,84],{},"他开始适应新的情况，试图辨别究竟什么在发生，或者形成一个计划来完成他的目标。",[11,86,87],{},"通常这个新情形会伴随着地理位置的变更，在很多剧本中主角是以乐观的情绪进入新的情况的。至少主角这个时候认为他所面临的新问题并没有那么严重。但是随着冲突逐渐构建，他开始意识到眼前的障碍比预想中的更加困难，然后他将会……",[46,89,91],{"id":90},"turning-point-2-the-change-of-plans-25","TURNING POINT #2: The Change of Plans (25%)",[11,93,94,95,99],{},"在剧情四分之一的地方，必须发生一些事情，将主角的原始目标导向一个明确可见的目标。这个目标就是主角的",[96,97,98],"strong",{},"外部目标","，也是定义故事概念的那个目标。",[101,102,103,108],"blockquote",{},[11,104,105,107],{},[96,106,98],{},"是主角在故事中明确可见的行动目标，观众也会明白，当这个目标实现或者彻底失败的时候，电影就结束了。",[11,109,110],{},"外部目标与主角的内在旅途是不同的。主角的内在渴望，过去的伤口，恐惧，勇气和成长，这些反映主角成长的元素通常是在故事构思阶段使用的，在故事中展现的话还是需要简单易懂的目标。",[46,112,114],{"id":113},"stage-3-progress","Stage 3: Progress",[11,116,117],{},"接下来的25%，新的计划似乎起了作用，他开始接近他的目标。",[11,119,120],{},"这个阶段并不是没有冲突，而是无论主角面对的是什么困难，他都能克服，直到他到达……",[46,122,124],{"id":123},"turning-point-3-the-point-of-no-return-50","TURNING POINT #3: The Point of No Return (50%)",[11,126,127],{},"中间点，在中间点之后，主角必须完全投入到他的目标。",[11,129,130],{},"在这个点之前，他还有机会退出，放弃计划，回到他在故事开始时的生活中。但是，这个时候，主角必须做出决定，斩断自己的退路。",[11,132,133],{},"从这个时刻开始，主角开始承担更多的风险，跨过了这个“不归点”之后，主角将会面对……",[46,135,137],{"id":136},"stage-4-complications-and-higher-stakes","Stage 4: Complications and Higher Stakes",[11,139,140,141,143],{},"在接下来的25%的剧情中，要达到",[96,142,98],{},"变得更加困难，如果主角失败也将承担更多的风险。",[11,145,146],{},"随着主角不断的经历各种冲突，在眼看着主角就要达到目标的时候，他遇到了……",[46,148,150],{"id":149},"turning-point-4-the-major-setback-75","TURNING POINT #4: The Major Setback (75%)",[11,152,153],{},"在第90页的时候，主角将会面临一无所有的时刻。在《黑客帝国》中，就是Morpheus被抓走的那个点。如果是爱情喜剧，这里就是主角的谎言被揭露和爱情破灭的时候。",[101,155,156],{},[11,157,158],{},"这里90页，对应的是120页剧本的描述。有的作者会假定剧本是110页的，所以特意算了一下",[11,160,161],{},"这些悲惨的场景，让主角只留下了一个选项：他必须做一个，最后的，非死即生的决定……",[46,163,165],{"id":164},"stage-5-the-final-push","Stage 5: The final push",[11,167,168],{},"被击倒之后，主角必须堵上他所拥有的一切，聚集他所拥有的所有力量和勇气来达成他的最终目标。",[101,170,171],{},[11,172,173],{},"这里应该是通常所谓的第三幕，结局序列",[11,175,176],{},"在这个阶段中，冲突开始加重，节奏开始提升，所有的东西都在与主角作对，直到他抵达……",[46,178,180],{"id":179},"turning-point-5-the-climax-90-99","TURNING POINT #5: The Climax (90-99%)",[11,182,183,184,186],{},"剧情的高潮部分必须发生几件事：主角必须面临整个故事中最大的障碍；他必须决定自己的命运；",[96,185,98],{},"必须被达成或是彻底失败。",[11,188,189],{},"高潮场景可以位于剧情的90%到最后的几分钟为止的地方，准确的位置取决于……",[46,191,193],{"id":192},"stage-6-the-aftermath","Stage 6: The Aftermath",[11,195,196],{},"不会有电影在主角解决问题后立刻就结束，你必须展现主角在完成旅途之后的新生活。",[11,198,199],{},"在一些电影，例如《洛基》、《楚门的世界》，几乎没有什么可以用于展示或解释的，作者的目的就是将观众至于一种震撼或者高昂的状态中。这时高潮场景会放置在非常接近末尾的地方。",[11,201,202],{},"但是，对于大部分浪漫喜剧、神秘剧和戏剧中，尾声通常占据最后的5~10页脚本。",[21,204,205],{"id":205},"游戏叙事设计工具",[11,207,208],{},"这个是GDC的一篇演讲",[11,210,211],{},"GDC 2017, Storytelling Tools to Boost Your Indie Game's Narrative and Gameplay",[11,213,214,215],{},"演讲地址：",[30,216,217],{"href":217,"rel":218},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=8fXE-E1hjKk&t=1419s",[34],[11,220,221,222],{},"演讲者的Twitter: ",[30,223,224],{"href":224,"rel":225},"https:\u002F\u002Ftwitter.com\u002Fmatahaggis",[34],[11,227,228],{},"作者首先提到，心流模型和叙事张力具有一些相似性：",[11,230,231],{},[232,233],"img",{"alt":234,"src":235},"image-20210113201010992","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210113201010992_thumb.png",[11,237,238],{},"游戏中能够提供的张力可以来自叙事或者机制，或者同时来自两者。",[46,240,242],{"id":241},"motivation","Motivation",[11,244,245,246,249,250,253],{},"对于角色，其行动动机可以分为",[96,247,248],{},"外部动机","和",[96,251,252],{},"内部动机","。",[11,255,256],{},"外部动机通常是试图改变外部世界的渴望，例如财富、旅行目标、情感目标等。",[11,258,259,260,263],{},"内部动机则是试图改变自己内部的渴望，例如满足复仇、",[96,261,262],{},"理解","到新的东西(通常他已经知道)。",[11,265,266],{},"在俄罗斯方块中也能作这样的目标划分：外部目标是积分，内部目标是让世界变得更有秩序。",[11,268,269],{},"故事中必须发生改变，渴望得到满足，或者彻底的失败。",[46,271,273],{"id":272},"plot-structure","Plot structure",[11,275,276],{},"角色或者玩家具有了他们的目标，此时，我们需要精心设置一些事件来让改变发生。",[11,278,279],{},"情节控制着故事弧光的节奏。",[281,282,283],"h4",{"id":283},"铺垫",[11,285,286],{},"要将故事的开始放在关键事件发生之前，在叙事上就是要首先让观众能够与主角建立共情。",[11,288,289],{},"游戏上，就是需要让玩家首先体验游戏的基本规则和背景故事。通常就是\"教学关卡\"。",[11,291,292],{},"我们想要让玩家完成游戏中的挑战，在让玩家面临挑战之前，需要让玩家了解游戏世界，设置好玩家的外部和内部目标。",[281,294,296],{"id":295},"inciting-incident","Inciting incident",[11,298,299],{},"激励事件",[11,301,302],{},"玩家了解了游戏世界之后，就可以开始设置挑战了。增加叙事的或者机制上的张力。让对抗者登场，添加新的敌人，让风险上升或者打破通常情形。",[11,304,305],{},"克服这个出现的挑战通常就是情节结构中的外部目标。",[281,307,309],{"id":308},"explore","Explore",[11,311,312],{},"此时玩家通常不会直接开始与问题对抗，而是试图对机制进行摸索、回避或者在路途中进行一些小的战斗。通常最开始的时候，玩家甚至会没有目标的四处闲逛。",[11,314,315],{},"不过最终他们还是会开始实现游戏设置的目标。无论是因为已经没有什么可以探索的了，还是他们决定自己开始挑战。",[281,317,319],{"id":318},"the-complexity-increases","The complexity increases",[11,321,322],{},"随着探索的进行，基础的能力将会变得没有那么有效。新的敌人具有新的能力，或者新的故事要素会揭示事情比表面上看起来更复杂。",[11,324,325],{},"在射击游戏中，通常会出现新的攻击模式或者敌人组合方式。",[281,327,329],{"id":328},"hope-overcomes-fear-with-effort","Hope overcomes fear.. With effort",[11,331,332],{},"玩家将会找到新的武器或者新的策略来对抗敌人(外部改变)",[11,334,335],{},"角色将会发现自己内在的勇气(内部改变)",[11,337,338],{},"角色学会如何组织自己的力量来与困难对抗，风险上升了，但是这是唯一的希望。",[281,340,342],{"id":341},"the-black-moment","The Black Moment",[11,344,345],{},"所有战胜困难的可能性都充满了危险。",[11,347,348],{},"最终boss被打败了...但是它还有新的形态！",[11,350,351],{},"玩家\u002F主角必须使用至今为止所学到的全部知识、羁绊以及掌握的策略，才能跨越眼前的最终障碍。",[281,353,355],{"id":354},"ending","Ending",[11,357,358],{},"尽快的结束，结局应当尽量简洁。",[11,360,361],{},"当然，对于一些恐怖类或者动作类游戏会使用剧情钩子以及...",[11,363,364],{},"这通常是，恐怖类游戏在开始前，事先展示恐怖的情景",[11,366,367],{},"或者是，动作类游戏一开始玩家可以使用所有的能力，然后再从头开始收集能力",[11,369,370],{},"另外，在一些惊悚类故事中，结局之后还会揭示\"惊人\"的新事实。",[46,372,373],{"id":373},"关卡结构",[11,375,376],{},"整体故事的结构同样可以应用到每个关卡上，虽然会稍微简化一些。",[11,378,379],{},"所有的关卡或者场景都必须具有：",[381,382,383,390,396],"ul",{},[384,385,386,389],"li",{},[96,387,388],{},"目标","，一个玩家的目标或者体验",[384,391,392,395],{},[96,393,394],{},"冲突","，在叙事或者机制上让目标难以实现",[384,397,398,401,402],{},[96,399,400],{},"结果","，玩家通过后所获得的",[403,404,405],"em",{},"改变",[11,407,408],{},"整个关卡过后，虽然玩家获得了改变，但是……",[281,410,412],{"id":411},"aliens-versus-predator","Aliens Versus Predator",[381,414,415,418,421],{},[384,416,417],{},"目标：重启电源让基地重新运作",[384,419,420],{},"冲突：玩家成功开启电源，但是却烧坏了整个基地的电路",[384,422,423],{},"结果：基地面临的危险变高了，角色所面临的情境变得更加复杂",[11,425,426],{},"玩家获得了成功，但是角色的情况变得更加糟糕了",[281,428,430],{"id":429},"god-of-war","God of War",[381,432,433,436,439],{},[384,434,435],{},"目标：继续前进",[384,437,438],{},"冲突：出现了新的持盾的敌人",[384,440,441],{},"结果：玩家必须使用新的攻击来击败这种敌人，战斗变得更复杂了",[46,443,445],{"id":444},"check-list","Check list",[11,447,448],{},"如果你的游戏感觉很平淡，可以尝试使用分析玩家体验的方式来寻找问题。",[381,450,451,454,457,460],{},[384,452,453],{},"玩家的目标是否清晰？",[384,455,456],{},"是否有新的机制或者叙事上的冲突，还是只是单纯的在重复？",[384,458,459],{},"关卡的结果是否有意义的对机制或者叙事或者两者产生了影响？",[384,461,462],{},"在整个关卡或者游戏中，改变是否发生在了玩家或者角色或者两者上？",[46,464,465],{"id":465},"总结",[11,467,468],{},"作者自己把所有的内容总结到了两张PPT里面，虽然一些表述稍有出入，总体而言还是和前面的内容差不多，这里就直接上原图了。",[11,470,471],{},[232,472],{"alt":473,"src":474},"image-20210113212122268","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210113212122268_thumb.png",[11,476,477],{},"这张图里面的比例划分，与第一篇的基本一致。可以说和第一篇能够互相进行补充。",[11,479,480],{},[232,481],{"alt":482,"src":483},"image-20210113212201148","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210113212201148_thumb.png",[21,485,486],{"id":486},"纸上得来终觉浅",[11,488,489],{},"看这种入门文章容易产生一种幻觉：我已经掌握了其中的技巧。",[11,491,492],{},"但是实际操作的时候还是会遇到不少问题。这种的只能……",[101,494,495,498,501,504],{},[11,496,497],{},"《冬夜读书示子聿》",[11,499,500],{},"（南宋）陆游",[11,502,503],{},"古人学问无遗力，少壮工夫老始成。",[11,505,506],{},"纸上得来终觉浅，绝知此事要躬行。",{"title":508,"searchDepth":509,"depth":510,"links":511},"",2,3,[512,525,544],{"id":23,"depth":509,"text":23,"children":513},[514,515,516,517,518,519,520,521,522,523,524],{"id":48,"depth":510,"text":49},{"id":61,"depth":510,"text":62},{"id":77,"depth":510,"text":78},{"id":90,"depth":510,"text":91},{"id":113,"depth":510,"text":114},{"id":123,"depth":510,"text":124},{"id":136,"depth":510,"text":137},{"id":149,"depth":510,"text":150},{"id":164,"depth":510,"text":165},{"id":179,"depth":510,"text":180},{"id":192,"depth":510,"text":193},{"id":205,"depth":509,"text":205,"children":526},[527,528,538,542,543],{"id":241,"depth":510,"text":242},{"id":272,"depth":510,"text":273,"children":529},[530,532,533,534,535,536,537],{"id":283,"depth":531,"text":283},4,{"id":295,"depth":531,"text":296},{"id":308,"depth":531,"text":309},{"id":318,"depth":531,"text":319},{"id":328,"depth":531,"text":329},{"id":341,"depth":531,"text":342},{"id":354,"depth":531,"text":355},{"id":373,"depth":510,"text":373,"children":539},[540,541],{"id":411,"depth":531,"text":412},{"id":429,"depth":531,"text":430},{"id":444,"depth":510,"text":445},{"id":465,"depth":510,"text":465},{"id":486,"depth":509,"text":486},"2021-02-01","md",{"layout":548,"status":549,"published":550,"author":551,"author_login":553,"author_email":554,"wordpress_id":555,"wordpress_url":556,"date_gmt":557,"excerpt":558},"post","publish",true,{"display_name":552,"login":553,"email":554,"url":508},"风铃","flinkor","flinkor@foxmail.com",3124,"\u002F?p=3124","2021-01-31 19:22:50 +0000",{"type":8,"value":559},[560],[11,561,13],{},"\u002F2021-02-01-game-narrative-notes-two",{"title":6,"description":13},"_legacy\u002F2021\u002F2021-02-01-game-narrative-notes-two",[566],"narrative","UibioiQLJ6LiOhcwuFZ1LcA9Kc-q3xGWpwEYPLGOXh8",{"id":569,"title":570,"body":571,"date":883,"description":575,"extension":546,"meta":884,"navigation":550,"path":893,"seo":894,"stem":895,"tags":896,"__hash__":898},"blogs\u002F_legacy\u002F2021\u002F2021-01-24-cedec-2016-sfv-note.md","CEDEC2016-《街头霸王5》的美术设计笔记",{"type":8,"value":572,"toc":870},[573,576,579,586,593,596,599,602,605,611,614,617,620,626,629,632,638,641,647,650,653,664,670,673,676,682,685,688,691,697,700,706,709,712,715,721,724,730,733,737,740,743,749,752,758,761,764,771,774,777,783,786,789,795,798,804,807,810,813,819,825,831,834,840,843,849,852,855,858,864,867],[11,574,575],{},"CEDEC2016上街霸5的分享。",[11,577,578],{},"主要参考以下内容：",[11,580,581,582],{},"PPT: ",[30,583,584],{"href":584,"rel":585},"https:\u002F\u002Fcedil.cesa.or.jp\u002Fcedil_sessions\u002Fview\u002F1540",[34],[11,587,588,589],{},"gamesindustry.biz: ",[30,590,591],{"href":591,"rel":592},"https:\u002F\u002Fjp.gamesindustry.biz\u002Farticle\u002F1609\u002F16090703\u002F",[34],[11,594,595],{},"街霸5，是使用UE4制作的。",[21,597,598],{"id":598},"格斗游戏美术制作",[11,600,601],{},"格斗游戏要让玩家能够瞬间对状况进行把握，所以很多地方不会遵循现实规律。",[11,603,604],{},"卡普空的街霸项目组内部，有一整套相关的方法论：",[11,606,607],{},[232,608],{"alt":609,"src":610},"image-20210120205628473","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120205628473_thumb.png",[11,612,613],{},"在像素时代有着非常大的作用，但是由于并不是完全按照现实的身体构造来的，要使用3D来制作就会有些问题。",[46,615,616],{"id":616},"模型身高",[11,618,619],{},"在官方设定中，隆的身高是175cm，而贝卡的身高是182cm。",[11,621,622],{},[232,623],{"alt":624,"src":625},"image-20210120210652818","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120210652818_thumb.png",[11,627,628],{},"但是在3D模型上看，两人的身高基本差不多。",[11,630,631],{},"最终选择以玩家能看到的印象为主，在战斗中待机时，让贝卡的动作改为直立来解决",[11,633,634],{},[232,635],{"alt":636,"src":637},"image-20210120210717273","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120210717273_thumb.png",[11,639,640],{},"实际上就变成了这样：",[11,642,643],{},[232,644],{"alt":645,"src":646},"image-20210120210739498","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120210739498_thumb.png",[46,648,649],{"id":649},"动画",[11,651,652],{},"角色的动画在制作时主要考虑三个方面：",[381,654,655,658,661],{},[384,656,657],{},"格斗技：空手道专家一眼就明白是怎样的攻击方式",[384,659,660],{},"重心与节奏：看起来要帅要流畅",[384,662,663],{},"性能：格斗游戏设计上的攻击判定",[11,665,666],{},[232,667],{"alt":668,"src":669},"image-20210120211322219","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120211322219_thumb.png",[11,671,672],{},"例如：桑吉尔夫的行走动画，刻意采用了正面视角进行动作的修正。防止实际上是以一种怪异的姿势在走路。",[11,674,675],{},"另外，为了表现原本的2D游戏中的感觉，部分角色的姿势采取了旋转5度的形式。",[11,677,678],{},[232,679],{"alt":680,"src":681},"image-20210120212141746","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120212141746_thumb.png",[11,683,684],{},"必杀技的设计上，一定要让玩家能够轻松的使用语句对其进行描述，这样才能让玩家方便的共享感动的情绪。",[46,686,687],{"id":687},"背景中的颜色设计",[11,689,690],{},"要让背景与角色有很好的层次感，以下是2D时代的例子：",[11,692,693],{},[232,694],{"alt":695,"src":696},"image-20210120212427714","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120212427714_thumb.png",[11,698,699],{},"为了在3D世界上达到这个效果，实现了Multi Color Grading的功能：",[11,701,702],{},[232,703],{"alt":704,"src":705},"image-20210120212640514","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120212640514_thumb.png",[11,707,708],{},"场景的不同区域采用了不同的LookupTable。上图的例子并不是针对所有的场景，对于不同的场景会根据其特点采用不同的Multi Color Grading分布。",[46,710,711],{"id":711},"摄像角度修正",[11,713,714],{},"如果使用默认的3D摄像，角色越靠近边缘时，就会出现扭曲，导致影响玩家对攻击判定的感觉。",[11,716,717],{},[232,718],{"alt":719,"src":720},"image-20210120212904843","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120212904843_thumb.png",[11,722,723],{},"对投影的方式进行了修改，采用了Fix Projection",[11,725,726],{},[232,727],{"alt":728,"src":729},"image-20210120213012818","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120213012818_thumb.png",[11,731,732],{},"这种投影的修正只针对角色，可以让角色从背景中突显出来的同时保证角色不会因为在画面中移动出现“扭曲”。",[21,734,736],{"id":735},"npr","NPR",[11,738,739],{},"SFV的画面目标是油画的风格以及丰富的色彩。",[11,741,742],{},"在光照向量与模型法线上作了很多的研究。",[11,744,745],{},[232,746],{"alt":747,"src":748},"image-20210120213351356","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120213351356_thumb.png",[11,750,751],{},"最终的材质并不会特别复杂：",[11,753,754],{},[232,755],{"alt":756,"src":757},"image-20210120213524861","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120213524861_thumb.png",[46,759,760],{"id":760},"笔触感的再现",[11,762,763],{},"前作SFIV，是通过在法线贴图上直接添加皱纹感来实现的。",[11,765,766,767,770],{},"操作上，是在PhostoShop中使用",[403,768,769],{},"ちりめんじわ","的功能对法线贴图直接进行处理。",[11,772,773],{},"SFV由于包括法线贴图在内的所有贴图的分辨率都上升了，导致使用这个方法产生的纹路很难在渲染结果上体现纹路感。最终，使用了Photoshop的SnapArt插件来对图片进行修正，这个插件本来是给图片添加油画感的。",[11,775,776],{},"为了能够使用这个插件，法线贴图的处理流程稍稍变长了：",[11,778,779],{},[232,780],{"alt":781,"src":782},"image-20210120214144524","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120214144524_thumb.png",[11,784,785],{},"会先将法线贴图转换到Object Space，经过SnapArt的处理后再重新转换回来。",[11,787,788],{},"对于身体的不同部分，会采用不同的处理程度：",[11,790,791],{},[232,792],{"alt":793,"src":794},"image-20210120214255524","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120214255524_thumb.png",[11,796,797],{},"以实现在游戏中信息密度的控制：",[11,799,800],{},[232,801],{"alt":802,"src":803},"image-20210120214326820","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120214326820_thumb.png",[46,805,806],{"id":806},"边界的强调",[11,808,809],{},"与传统的根据法线计算轮廓线的方法不同，是使用颜色来进行的。在渲染结果中，当像素的RGB的颜色差很大时，填充轮廓线。",[11,811,812],{},"首先将渲染结果左右移位n个像素然后相减：",[11,814,815],{},[232,816],{"alt":817,"src":818},"image-20210120214718395","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120214718395_thumb.png",[11,820,821],{},[232,822],{"alt":823,"src":824},"image-20210120214733171","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120214733171_thumb.png",[11,826,827],{},[232,828],{"alt":829,"src":830},"image-20210120214744645","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120214744645_thumb.png",[11,832,833],{},"同样的操作在上下方向上再执行一次，然后将两个结果相加：",[11,835,836],{},[232,837],{"alt":838,"src":839},"image-20210120214812460","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120214812460_thumb.png",[11,841,842],{},"再乘以当前场景所设置的轮廓线颜色，最后叠加到原图上就可以了。",[11,844,845],{},[232,846],{"alt":847,"src":848},"image-20210120215208468","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120215208468_thumb.png",[11,850,851],{},"这个效果是在PostProcess上完成的。",[46,853,854],{"id":854},"间接光",[11,856,857],{},"SFV引入Enlighten，在虚幻默认的ILC的基础上更加强化了间接光照的效果",[11,859,860],{},[232,861],{"alt":862,"src":863},"image-20210120215346772","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120215346772_thumb.png",[11,865,866],{},"Enlighten的作用是，可以实时的对间接光照的效果进行调整。比如，想要让间接光的色调变青的话，就加重青的要素。这与想要接近油画画风而不是真实的物理光照的目标相一致。",[11,868,869],{},"Enlighten只要在场景构造没有变的情况下，可以自由的调整间接光的效果，可以说非常的符合需求。",{"title":508,"searchDepth":509,"depth":510,"links":871},[872,878],{"id":598,"depth":509,"text":598,"children":873},[874,875,876,877],{"id":616,"depth":510,"text":616},{"id":649,"depth":510,"text":649},{"id":687,"depth":510,"text":687},{"id":711,"depth":510,"text":711},{"id":735,"depth":509,"text":736,"children":879},[880,881,882],{"id":760,"depth":510,"text":760},{"id":806,"depth":510,"text":806},{"id":854,"depth":510,"text":854},"2021-01-24",{"layout":548,"status":549,"published":550,"author":885,"author_login":553,"author_email":554,"wordpress_id":886,"wordpress_url":887,"date_gmt":888,"excerpt":889},{"display_name":552,"login":553,"email":554,"url":508},3350,"\u002F?p=3350","2021-01-24 04:00:44 +0000",{"type":8,"value":890},[891],[11,892,575],{},"\u002F2021-01-24-cedec-2016-sfv-note",{"title":570,"description":575},"_legacy\u002F2021\u002F2021-01-24-cedec-2016-sfv-note",[897,736],"CEDEC","r_blFGbTBPV57haZRO6BbQsvxGh0ZuZR2in9HkJMans",{"id":900,"title":901,"body":902,"date":883,"description":906,"extension":546,"meta":1498,"navigation":550,"path":1507,"seo":1508,"stem":1509,"tags":1510,"__hash__":1512},"blogs\u002F_legacy\u002F2021\u002F2021-01-24-ue4-fest-npr-note.md","UE4-Fest-NPR笔记",{"type":8,"value":903,"toc":1475},[904,907,914,921,924,927,930,933,936,939,945,948,951,954,960,963,971,974,977,980,1010,1013,1016,1019,1022,1025,1032,1035,1038,1041,1044,1050,1053,1059,1062,1076,1079,1082,1088,1091,1099,1102,1105,1111,1114,1120,1123,1126,1132,1135,1141,1145,1148,1154,1157,1163,1167,1170,1176,1182,1185,1191,1194,1197,1200,1206,1209,1212,1215,1226,1229,1232,1238,1241,1252,1255,1258,1264,1267,1271,1274,1277,1291,1294,1297,1303,1306,1312,1315,1321,1324,1330,1334,1337,1343,1346,1352,1356,1359,1362,1370,1373,1379,1382,1385,1388,1397,1400,1407,1413,1416,1420,1423,1426,1434,1438,1441,1470,1472],[11,905,906],{},"UEFest2020上一篇关于NPR效果实现的演讲。",[11,908,909,910],{},"PPT在这里：",[30,911,912],{"href":912,"rel":913},"https:\u002F\u002Fwww.slideshare.net\u002FEpicGamesJapan\u002Funreal-festext2020winter-npr",[34],[11,915,916,917],{},"后面发现的视频在这里：",[30,918,919],{"href":919,"rel":920},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=L1tC6wnub2k",[34],[11,922,923],{},"npr是个很宽泛的概念，这边主要是讲ToonShader。",[11,925,926],{},"演讲的内容基于U4.25.4。",[11,928,929],{},"这边由于没有一个明确的生产目标，所以更多的关注流程的实现。",[11,931,932],{},"由于原始的PPT有很多思考和选择过程的记录，在这里会稍微重新组织下内容。",[11,934,935],{},"笔记是基于PPT制作的，后面虽然找到Youtube的视频，不过没找到时间从头看一遍……所以可能有的地方和视频说的不一样~",[11,937,938],{},"完成之后的效果：",[11,940,941],{},[232,942],{"alt":943,"src":944},"image-20210117215700253","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117215700253_thumb.png",[11,946,947],{},"角色名 :齋藤胡桃",[11,949,950],{},"原本是准备做来放到MarketPlace上去卖的，为了这次演示重新设计，全部重做了一下。",[11,952,953],{},"角色设计方案：",[11,955,956],{},[232,957],{"alt":958,"src":959},"image-20210117220008747","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117220008747_thumb.png",[11,961,962],{},"最初的目标：",[101,964,965,968],{},[11,966,967],{},"不是实现单纯的CellShader，而是希望将一些插画绘制的手法融合进来。",[11,969,970],{},"希望是能够在相对较暗的空间中也能够很好的渲染出结果来。",[21,972,973],{"id":973},"引擎改造",[11,975,976],{},"和Unity不同，要在UE4实现渲染的改造是需要修改引擎代码的。",[11,978,979],{},"网络上也能找到一些改造UE4的Shading Model的方法介绍。",[381,981,982,989,996,1003],{},[384,983,984],{},[30,985,988],{"href":986,"rel":987},"https:\u002F\u002Fqiita.com\u002Fdgtanaka\u002Fitems\u002F41f96ef2090820035609",[34],"UE4のShading Modelを拡張する",[384,990,991],{},[30,992,995],{"href":993,"rel":994},"https:\u002F\u002Fforums.unrealengine.com\u002Fcommunity\u002Fwork-in-progress\u002F41288-toon-shading-model",[34],"Toon shading model",[384,997,998],{},[30,999,1002],{"href":1000,"rel":1001},"https:\u002F\u002Fforums.unrealengine.com\u002Fdevelopment-discussion\u002Frendering\u002F1537277-toon-shading-models-stylized-rendering-experiments",[34],"Toon Shading Models, Stylized Rendering Experiments",[384,1004,1005],{},[30,1006,1009],{"href":1007,"rel":1008},"https:\u002F\u002Fforums.unrealengine.com\u002Fdevelopment-discussion\u002Frendering\u002F1704696-wip-anime-toon-stylized-shading-model",[34],"[WIP] Anime\u002FToon Stylized Shading Model",[11,1011,1012],{},"改造引擎主要的问题是实现方式很难和别人共享，改造后的版本只能内部使用。",[11,1014,1015],{},"重新编译C++和Shader的成本也很高，最大的麻烦是，引擎升级。",[11,1017,1018],{},"所以演讲中使用的制作流程没有对引擎进行改造。",[21,1020,1021],{"id":1021},"基于向量",[11,1023,1024],{},"基于向量计算，使用蓝图和材质节点来达到目标。",[11,1026,1027,1028],{},"参考的文章是这篇：",[30,1029,1030],{"href":1030,"rel":1031},"https:\u002F\u002Funrealengine.hatenablog.com\u002Fentry\u002F2019\u002F12\u002F01\u002F000735",[34],[11,1033,1034],{},"使用向量的内积来在材质节点中获取更多的信息。",[46,1036,1037],{"id":1037},"光照向量",[11,1039,1040],{},"由于材质中的Light Vector只能在前向渲染中使用，所以在蓝图中写入到Material Parameter Collection中。",[11,1042,1043],{},"之后便可以使用法线与光照向量相乘来达到模拟计算光照的效果",[11,1045,1046],{},[232,1047],{"alt":1048,"src":1049},"image-20210118232253776","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210118232253776_thumb.png",[11,1051,1052],{},"前面的内积结果会在模型上生成灰阶的渲染值，使用这个值作为下一步的Mask的基础。上图比较简单，当前的渲染结果是这样的：",[11,1054,1055],{},[232,1056],{"alt":1057,"src":1058},"image-20210118233129915","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210118233129915_thumb.png",[11,1060,1061],{},"为了模仿通常ToonShader的效果，基于上面的内积的结果，总共计算了四个层的内容：",[381,1063,1064,1067,1070,1073],{},[384,1065,1066],{},"Shadow: 模拟阴影计算，连接到SubSurface",[384,1068,1069],{},"HightLight: 模拟高光，连接到Emmisive",[384,1071,1072],{},"RimLight: 连接到Emmisive",[384,1074,1075],{},"Patten: 连接到SubSurface",[11,1077,1078],{},"上面三种都是比较常见的效果，所谓的Patten，其实是模仿有的漫画里的那种网点图的感觉",[11,1080,1081],{},"对于用于计算基础的内积结果，根据贴图会采用不同的插值方式。",[11,1083,1084],{},[232,1085],{"alt":1086,"src":1087},"image-20210119230758187_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230758187_thumb.png",[11,1089,1090],{},"同时会按照需求使用一些其他的向量节点：CameraVector、ReflectionVector。",[11,1092,1093,1094,1098],{},"贴图提供的信息并不一定会按照0",[1095,1096,1097],"del",{},"1来插值，有的会设定为1.0是必然使用，而0","0.5才会插值，总之这个可以按照需求来进行灵活的控制，毕竟贴图是自己制作的。",[46,1100,1101],{"id":1101},"阴影",[11,1103,1104],{},"用于模仿阴影计算：",[11,1106,1107],{},[232,1108],{"alt":1109,"src":1110},"image-20210119230028530_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230028530_thumb.png",[11,1112,1113],{},"效果是这样的：",[11,1115,1116],{},[232,1117],{"alt":1118,"src":1119},"image-20210119230049261_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230049261_thumb.png",[46,1121,1122],{"id":1122},"高光",[11,1124,1125],{},"用于高光模拟计算，由于是连接到Emmisive，所以可以受到Bloom的影响。",[11,1127,1128],{},[232,1129],{"alt":1130,"src":1131},"image-20210119230329943_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230329943_thumb.png",[11,1133,1134],{},"最终结果是这样的：",[11,1136,1137],{},[232,1138],{"alt":1139,"src":1140},"image-20210119230350972_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230350972_thumb.png",[46,1142,1144],{"id":1143},"rimlight","RimLight",[11,1146,1147],{},"就是边缘高光，通常用Fresnel进行模拟的那个效果。",[11,1149,1150],{},[232,1151],{"alt":1152,"src":1153},"image-20210119230505405_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230505405_thumb.png",[11,1155,1156],{},"最终效果是这样的：",[11,1158,1159],{},[232,1160],{"alt":1161,"src":1162},"image-20210119230527413_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230527413_thumb.png",[46,1164,1166],{"id":1165},"patten","Patten",[11,1168,1169],{},"这个不是很常见，是用于模仿漫画的那种类似网点的感觉：",[11,1171,1172],{},[232,1173],{"alt":1174,"src":1175},"image-20210119230616663_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230616663_thumb.png",[11,1177,1178],{},[232,1179],{"alt":1180,"src":1181},"image-20210119230707458_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119230707458_thumb.png",[11,1183,1184],{},"最终结果像是这样：",[11,1186,1187],{},[232,1188],{"alt":1189,"src":1190},"image-20210119225712396_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119225712396_thumb.png",[21,1192,1193],{"id":1193},"光照问题",[11,1195,1196],{},"光照模型选用的是SubSurface，虽然有尝试过Preintegrated Skin和Subsurface Profile，但是效果都有些微妙。",[11,1198,1199],{},"SubSurface存在一个问题，就是从上面来的DirectionalLight会对模型造成一种类似贯通的效果：",[11,1201,1202],{},[232,1203],{"alt":1204,"src":1205},"image-20210119231317537_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119231317537_thumb.png",[11,1207,1208],{},"使用Mesh进行遮挡也无法取消掉这个效果，似乎是SubSurface光照模型的计算特性导致的。只能暂时放弃。",[11,1210,1211],{},"对于主导的DirectionalLight向上的时候，会出现阴影很重的感觉。只能通过限制光的角度，或者额外的打一些光来解决。",[11,1213,1214],{},"另外就是拟似计算的光照不够硬，通过调整自己的参数来解决：",[381,1216,1217,1220,1223],{},[384,1218,1219],{},"『Shadow Bias 』=>『1.0 』",[384,1221,1222],{},"『Shadow Slope Bias 』=>『0.0 』",[384,1224,1225],{},"『Shadow Filter Sharpe 』=>『1.0 』",[46,1227,1228],{"id":1228},"法线整理",[11,1230,1231],{},"脸部不需要阴影，所以对模型进行处理，让法线全部朝向一个方向。",[11,1233,1234],{},[232,1235],{"alt":1236,"src":1237},"image-20210119231922084_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119231922084_thumb.png",[11,1239,1240],{},"这种处理方式参照的是：",[101,1242,1243,1246],{},[11,1244,1245],{},"GUILTY GEAR Xrd開発スタッフが送るアニメ調キャラモデリングTIPS",[11,1247,1248],{},[30,1249,1250],{"href":1250,"rel":1251},"https:\u002F\u002Fwww.slideshare.net\u002FASW_Yokohama\u002Fguilty-gear-xrdtips-124324946",[34],[46,1253,1254],{"id":1254},"眼球高光",[11,1256,1257],{},"很强的那个高光是靠UnLit的材质内部计算出来的。",[11,1259,1260],{},[232,1261],{"alt":1262,"src":1263},"image-20210119232139763_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119232139763_thumb.png",[11,1265,1266],{},"眼球有添加一个假的各向异性光照来提高立体感，根据光照的方向不同这个高光的位置会移动。",[46,1268,1270],{"id":1269},"outline","OutLine",[11,1272,1273],{},"没有使用PostProcess，而是在Blender里面制作了一个反转的Mesh，直接包含在骨骼模型里面。",[11,1275,1276],{},"此外还提供了以下的功能：",[381,1278,1279,1282,1285,1288],{},[384,1280,1281],{},"使用VertexColor来控制OutLine的粗细",[384,1283,1284],{},"轮廓线是带颜色的",[384,1286,1287],{},"根据摄像的距离调整粗细",[384,1289,1290],{},"根据FOV调整粗细",[11,1292,1293],{},"粗细控制基于Vertex Color，会使用Opacity Mask额外的处理，当数值小于0.1时，就不会绘制轮廓线。",[11,1295,1296],{},"不过主要的还是依靠将计算结果连接到World Position Offset进行的控制：",[11,1298,1299],{},[232,1300],{"alt":1301,"src":1302},"image-20210119233127332_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233127332_thumb.png",[11,1304,1305],{},"颜色则是通过UV查找基础颜色，并与另外准备的OutLine颜色进行叠加计算，实际进行的计算比较简单：",[11,1307,1308],{},[232,1309],{"alt":1310,"src":1311},"image-20210119233437571_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233437571_thumb.png",[11,1313,1314],{},"摄像的距离来调整Offset，这是通过内置的相机位置和Actor位置节点来计算的：",[11,1316,1317],{},[232,1318],{"alt":1319,"src":1320},"image-20210119233551957_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233551957_thumb.png",[11,1322,1323],{},"FOV也是类似的，直接用Hlsl的custom node去取出来：",[11,1325,1326],{},[232,1327],{"alt":1328,"src":1329},"image-20210119233636756_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233636756_thumb.png",[46,1331,1333],{"id":1332},"textureinline","TextureInline",[11,1335,1336],{},"最后还使用了TextureInLine的技巧，实际上并不在OutLine的计算中，只是专门的准备了贴图，用于模拟一些不是很容易计算出来的描画效果。",[11,1338,1339],{},[232,1340],{"alt":1341,"src":1342},"image-20210119233840764_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233840764_thumb.png",[11,1344,1345],{},"并不是单纯的打包在角色贴图里面，而是另外有一张贴图，可以动态的在叠加时对RGBA通道进行强弱和颜色调整。计算节点：",[11,1347,1348],{},[232,1349],{"alt":1350,"src":1351},"image-20210119233935788_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210119233935788_thumb.png",[21,1353,1355],{"id":1354},"postprocess","PostProcess",[11,1357,1358],{},"主要不是介绍UE4本身的pp，而是指希望达到的一些后处理效果，主要有",[46,1360,1361],{"id":1361},"模造纸效果",[11,1363,1364,1369],{},[30,1365,1368],{"href":1366,"rel":1367},"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",[34],"パラフィン紙","，一时找不到准确的术语翻译，就硬翻成模造纸吧。总之是一种纸，在上个世代的动画制作中用到。这种带颜色的透明的纸叠加到原画上，能够模拟出类似反光或者阴影的效果。",[11,1371,1372],{},"实现上使用了PP的Dirt Mask功能：",[11,1374,1375],{},[232,1376],{"alt":1377,"src":1378},"image-20210120193421631_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120193421631_thumb.png",[11,1380,1381],{},"贴图使用黑白的就ok了。",[46,1383,1384],{"id":1384},"柔光滤镜",[11,1386,1387],{},"Diffusion Filter",[101,1389,1390],{},[11,1391,1392,1393,1396],{},"似乎是摄影术语，不是很明确是否采用了正确的翻译。虽然在镜片厂商看到的繁中译法是",[403,1394,1395],{},"擴散濾光片","，但是其他一些地方又似乎分类为柔光滤镜。不纠结了……",[11,1398,1399],{},"总之就是这样一种滤镜，会将光线进行柔和的扩散，对降低图像在高光区域的对比度非常有效。据说可以在摄影时消除脸部的毛刺和皱纹，不是很确定是不是一个东西~",[11,1401,1402,1403],{},"参考的这里：",[30,1404,1405],{"href":1405,"rel":1406},"https:\u002F\u002Ftwitter.com\u002Fmonsho1977\u002Fstatus\u002F670634806124920832",[34],[11,1408,1409],{},[232,1410],{"alt":1411,"src":1412},"image-20210120195648749_thumb","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210120195648749_thumb.png",[11,1414,1415],{},"印象中虚幻应该也有模糊用的节点，可能有什么限制达不到需求吧。",[46,1417,1419],{"id":1418},"kuwahara滤镜","Kuwahara滤镜",[11,1421,1422],{},"桑原道義老师所发明的平滑化用的滤镜。",[11,1424,1425],{},"能够让画面产生油画一样的效果，有利于让渲染结果看起来更接近动画的背景的感觉。",[11,1427,1428,1429,253],{},"这边这篇介绍的很详细的实现方式：",[30,1430,1433],{"href":1431,"rel":1432},"https:\u002F\u002Fwww.raywenderlich.com\u002F100-unreal-engine-4-paint-filter-tutorial#toc-anchor-004",[34],"Unreal Engine 4 Paint Filter Tutorial",[46,1435,1437],{"id":1436},"其他pp特效","其他PP特效",[11,1439,1440],{},"还列出了一些其他的后处理特效，应该都是默认的特效",[381,1442,1443,1446,1449,1452,1455,1458,1461,1464,1467],{},[384,1444,1445],{},"Cinematic DoF",[384,1447,1448],{},"Lens Flares",[384,1450,1451],{},"Bloom",[384,1453,1454],{},"Exposure",[384,1456,1457],{},"Chromatic Aberration",[384,1459,1460],{},"Vignette Intensity",[384,1462,1463],{},"Color Grading LUT",[384,1465,1466],{},"Motion Blur",[384,1468,1469],{},"etc ...",[21,1471,465],{"id":465},[11,1473,1474],{},"总之在不使用自定义引擎特效的情况下达到了一开始设定的ToonShader的效果。",{"title":508,"searchDepth":509,"depth":510,"links":1476},[1477,1478,1485,1491,1497],{"id":973,"depth":509,"text":973},{"id":1021,"depth":509,"text":1021,"children":1479},[1480,1481,1482,1483,1484],{"id":1037,"depth":510,"text":1037},{"id":1101,"depth":510,"text":1101},{"id":1122,"depth":510,"text":1122},{"id":1143,"depth":510,"text":1144},{"id":1165,"depth":510,"text":1166},{"id":1193,"depth":509,"text":1193,"children":1486},[1487,1488,1489,1490],{"id":1228,"depth":510,"text":1228},{"id":1254,"depth":510,"text":1254},{"id":1269,"depth":510,"text":1270},{"id":1332,"depth":510,"text":1333},{"id":1354,"depth":509,"text":1355,"children":1492},[1493,1494,1495,1496],{"id":1361,"depth":510,"text":1361},{"id":1384,"depth":510,"text":1384},{"id":1418,"depth":510,"text":1419},{"id":1436,"depth":510,"text":1437},{"id":465,"depth":509,"text":465},{"layout":548,"status":549,"published":550,"author":1499,"author_login":553,"author_email":554,"wordpress_id":1500,"wordpress_url":1501,"date_gmt":1502,"excerpt":1503},{"display_name":552,"login":553,"email":554,"url":508},3258,"\u002F?p=3258","2021-01-24 04:01:00 +0000",{"type":8,"value":1504},[1505],[11,1506,906],{},"\u002F2021-01-24-ue4-fest-npr-note",{"title":901,"description":906},"_legacy\u002F2021\u002F2021-01-24-ue4-fest-npr-note",[1511,736],"unreal fest","okWPDXLenIskJvqhFh5Rbfa9MxWxVV-ezWOKLVF8v64",{"id":1514,"title":1515,"body":1516,"date":883,"description":1520,"extension":546,"meta":1705,"navigation":550,"path":1714,"seo":1715,"stem":1716,"tags":1717,"__hash__":1719},"blogs\u002F_legacy\u002F2021\u002F2021-01-24-ue4-level-editor-notes.md","UE4关卡编辑问题记录",{"type":8,"value":1517,"toc":1693},[1518,1521,1524,1528,1531,1534,1537,1547,1550,1556,1559,1562,1568,1571,1577,1580,1586,1589,1595,1598,1601,1607,1610,1613,1616,1620,1623,1626,1629,1632,1635,1647,1651,1654,1657,1661,1664,1669,1672,1678,1681,1687,1690],[11,1519,1520],{},"最近自己摆弄关卡遇到的一些问题的记录。",[11,1522,1523],{},"由于近段时间基本一直在作逻辑开发，所以很少自己碰编辑器，发现一些常见的问题也不知道该如何应对。于是统一的记录了起来，方便下次查找原因。",[21,1525,1527],{"id":1526},"texture-streaming-over-budget","Texture streaming over budget",[11,1529,1530],{},"结论写在前面，基本原因是默认配置太小，调大就可以了。",[11,1532,1533],{},"主要是直接输出一个红色的错误日志在顶部，让人担心自己是不是做错了什么。",[11,1535,1536],{},"首先，找到日志输出的地方：",[1538,1539,1544],"pre",{"className":1540,"code":1542,"language":1543},[1541],"language-text","SmallTextItem.SetColor(FLinearColor::Red); \nSmallTextItem.Text = FText::Format(LOCTEXT(\"TEXTURE_STREAMING_POOL_OVER_BUDGET_FMT\", \"TEXTURE STREAMING POOL OVER {0} BUDGET\"), FText::AsMemory(MemOver)); \nCanvas->DrawItem(SmallTextItem, FVector2D(MessageX, MessageY));\n","text",[1545,1546,1542],"code",{"__ignoreMap":508},[11,1548,1549],{},"这个东西的计算在：",[1538,1551,1554],{"className":1552,"code":1553,"language":1543},[1541],"FRenderAssetStreamingMipCalcTask::UpdateStats_Async\n",[1545,1555,1553],{"__ignoreMap":508},[11,1557,1558],{},"中，主要有两个来源：",[46,1560,1561],{"id":1561},"内存池超过限制",[1538,1563,1566],{"className":1564,"code":1565,"language":1543},[1541],"Stats.OverBudget += FMath::Max\u003Cint64>(Stats.RequiredPool - Stats.StreamingPool, 0);\n",[1545,1567,1565],{"__ignoreMap":508},[11,1569,1570],{},"用实际消耗的内存大小减去MemoryBudget，RequairedPool就是每一个FStreamingRenderAsset的消耗加起来",[1538,1572,1575],{"className":1573,"code":1574,"language":1543},[1541],"Stats.RequiredPool += RequiredSize;\n",[1545,1576,1574],{"__ignoreMap":508},[46,1578,1579],{"id":1579},"单个物体超过限制",[1538,1581,1584],{"className":1582,"code":1583,"language":1543},[1541],"\u002F\u002F All persistent mip bias bigger than the expected is considered overbudget. \nconst int32 OverBudgetBias = FMath::Max\u003Cint32>(0, StreamingRenderAsset.BudgetMipBias - Settings.GlobalMipBias); \nStats.OverBudget += StreamingRenderAsset.GetSize(StreamingRenderAsset.MaxAllowedMips + OverBudgetBias) - MaxSize;\n",[1545,1585,1583],{"__ignoreMap":508},[11,1587,1588],{},"这里累计进去的就是OverBudgetBias，因为前面",[1538,1590,1593],{"className":1591,"code":1592,"language":1543},[1541],"const int64 MaxSize = StreamingRenderAsset.GetSize(StreamingRenderAsset.MaxAllowedMips);\n",[1545,1594,1592],{"__ignoreMap":508},[46,1596,1597],{"id":1597},"实际分析",[11,1599,1600],{},"这样的话，直接stat streaming，看结果",[11,1602,1603],{},[232,1604],{"alt":1605,"src":1606},"image-20201227191346947","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20201227191346947_thumb.png",[11,1608,1609],{},"这里就是配置太小了，不知为什么默认只有76M，这样随便上几个大点的pbr贴图就超过了。通过指令上调配置就好。",[11,1611,1612],{},"r.Streaming.PoolSize 2000",[11,1614,1615],{},"也就是说，实际上是默认配置太小导致的，不是哪里操作有问题。",[21,1617,1619],{"id":1618},"instancemesh","InstanceMesh",[11,1621,1622],{},"目前共有UInstancedStaticMeshComponent和UHierarchicalInstancedStaticMeshComponent两个组件，但是他们有什么区别呢？一旦开始纠结就不知道应该选哪一个了。",[11,1624,1625],{},"稍微查了下资料，主要的区别是。UHierarchicalInstancedStaticMeshComponent是会按instance更新LOD的，而UInstancedStaticMeshComponent则全部统一使用同一个LOD。",[46,1627,1628],{"id":1628},"本身的限制",[11,1630,1631],{},"由于目前的版本会自动合批，不是很确定UInstancedStaticMeshComponent还有没有必要性。不过至少会减少Actor的数量，也方便使用Cluster来减少GC负担。",[11,1633,1634],{},"InstanceMesh的限制：",[1636,1637,1638,1641,1644],"ol",{},[384,1639,1640],{},"无法使用负数的Scale",[384,1642,1643],{},"无法分别指定材质(per instance random可用于一些效果)",[384,1645,1646],{},"碰撞不会在运行时更新(这个现在应该没有了)",[46,1648,1650],{"id":1649},"crash","Crash",[11,1652,1653],{},"实际使用instancemesh，发现在编辑器里面直接ctrl+w会崩溃，主要原因是instance的生成直接放到构造函数里面了。",[11,1655,1656],{},"正确的做法是，将生成放到OnConstruction里面，还能在改变属性时自动更新。",[21,1658,1660],{"id":1659},"bound","Bound",[11,1662,1663],{},"在愉快的拖动关卡的时候，突然出现了这样的报错：",[101,1665,1666],{},[11,1667,1668],{},"The actor will be placed outside the bounds of the current level. Continue?",[11,1670,1671],{},"于是找了下输出来源，这个Bound似乎是实时计算的",[1538,1673,1676],{"className":1674,"code":1675,"language":1543},[1541],"FBox CurrentLevelBounds(ForceInit);\nif (InLevel-&gt;LevelBoundsActor.IsValid())\n{\n    CurrentLevelBounds = InLevel-&gt;LevelBoundsActor.Get()-&gt;GetComponentsBoundingBox();\n}\nelse\n{\n    CurrentLevelBounds = ALevelBounds::CalculateLevelBounds(InLevel);\n}\n",[1545,1677,1675],{"__ignoreMap":508},[11,1679,1680],{},"在有LevelBoundsActor的情况下，会使用指定的Bound",[1538,1682,1685],{"className":1683,"code":1684,"language":1543},[1541],"\u002F**\n *\n * Defines level bounds\n * Updates bounding box automatically based on actors transformation changes or holds fixed user defined bounding box\n * Uses only actors where AActor::IsLevelBoundsRelevant() == true\n *\u002F\n",[1545,1686,1684],{"__ignoreMap":508},[11,1688,1689],{},"也就是说，没有自己指定边界Actor为自定义的话，其实没什么太大的意义。",[11,1691,1692],{},"可以在编辑器设置中关闭bPromptWhenAddingToLevelOutsideBounds。",{"title":508,"searchDepth":509,"depth":510,"links":1694},[1695,1700,1704],{"id":1526,"depth":509,"text":1527,"children":1696},[1697,1698,1699],{"id":1561,"depth":510,"text":1561},{"id":1579,"depth":510,"text":1579},{"id":1597,"depth":510,"text":1597},{"id":1618,"depth":509,"text":1619,"children":1701},[1702,1703],{"id":1628,"depth":510,"text":1628},{"id":1649,"depth":510,"text":1650},{"id":1659,"depth":509,"text":1660},{"layout":548,"status":549,"published":550,"author":1706,"author_login":553,"author_email":554,"wordpress_id":1707,"wordpress_url":1708,"date_gmt":1709,"excerpt":1710},{"display_name":552,"login":553,"email":554,"url":508},3226,"\u002F?p=3226","2021-01-24 03:19:43 +0000",{"type":8,"value":1711},[1712],[11,1713,1520],{},"\u002F2021-01-24-ue4-level-editor-notes",{"title":1515,"description":1520},"_legacy\u002F2021\u002F2021-01-24-ue4-level-editor-notes",[1718],"UE4","aC2fbb4Y1BSs1AdibFkWM6TlG677lO2kh_AymzB3kJo",{"id":1721,"title":1722,"body":1723,"date":883,"description":1727,"extension":546,"meta":2043,"navigation":550,"path":2052,"seo":2053,"stem":2054,"tags":2055,"__hash__":2056},"blogs\u002F_legacy\u002F2021\u002F2021-01-24-unreal-fest-trials-of-mana-3-note.md","UE4-Fest-圣剑传说3笔记",{"type":8,"value":1724,"toc":2024},[1725,1728,1735,1742,1745,1748,1751,1754,1757,1760,1763,1769,1772,1778,1781,1785,1788,1794,1797,1805,1808,1811,1814,1817,1820,1823,1826,1829,1832,1835,1842,1848,1851,1860,1863,1866,1869,1872,1875,1878,1881,1884,1891,1894,1897,1900,1906,1910,1913,1919,1922,1925,1928,1931,1937,1940,1944,1947,1950,1959,1966,1969,1972,1975,1983,1986,1989,1992,1995,1999,2002,2005,2008,2012,2015,2018,2021],[11,1726,1727],{},"UEFest2020的圣剑传说3的分享",[11,1729,1730,1731],{},"PPT参考的这里：",[30,1732,1733],{"href":1733,"rel":1734},"https:\u002F\u002Fwww.slideshare.net\u002FEpicGamesJapan\u002Funreal-festext2020winter-xeen",[34],[11,1736,1737,1738],{},"后面才发现有原始视频：",[30,1739,1740],{"href":1740,"rel":1741},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=NHZRn4OHa1g",[34],[11,1743,1744],{},"最终使用引擎版本4.22.3",[11,1746,1747],{},"渲染方面没有使用任何引擎改造，全部使用引擎标准机能实现。",[21,1749,1750],{"id":1750},"角色",[11,1752,1753],{},"美术上的参考主要有：原作的像素风格、插画。以及本作的插画。",[11,1755,1756],{},"从中寻找共通的魅力，以手绘的风格为目标进行制作。",[46,1758,1759],{"id":1759},"轮廓线",[11,1761,1762],{},"轮廓线使用PostProcess来制作。",[11,1764,1765],{},[232,1766],{"alt":1767,"src":1768},"image-20210117185504080","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117185504080_thumb.png",[11,1770,1771],{},"使用深度数据比较的方法来计算轮廓线，对于深度差别不大的地方，会并用Detail normal map进行角度比较，抽出轮廓线数据。",[11,1773,1774],{},[232,1775],{"alt":1776,"src":1777},"image-20210117185821442","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117185821442_thumb.png",[11,1779,1780],{},"轮廓线的粗细使用World normal进行Mask来控制。",[46,1782,1784],{"id":1783},"shading","Shading",[11,1786,1787],{},"使用NPR渲染，作为特征的Specular和阴影是在材质中实现的。",[11,1789,1790],{},[232,1791],{"alt":1792,"src":1793},"image-20210117190629938","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117190629938_thumb.png",[11,1795,1796],{},"阴影的部分使用了两种颜色的阶调来进行实现，在计算的时候使用Rim进行遮罩，就能在原本的颜色上表现出RimLight的感觉。在对边界和背光进行表现时能够起作用。（这部分不是很确定是不是理解正确了……）",[11,1798,1799,1800,1804],{},"法线贴图在制作时会在Photoshop中使用滤镜来实现最终渲染时类似笔触的画风，这个应该和",[30,1801,1803],{"href":1802},"\u002F2021-01-24-cedec-2016-sfv-note\u002F","街霸5的分享","里面提到的操作方法类似。但是使用的滤镜没有明确说明。",[46,1806,1807],{"id":1807},"光照",[11,1809,1810],{},"在地图中使用一个Stationary的直射光作为天光来使用，其他的光照基本上都是static light。",[11,1812,1813],{},"对于每一个关卡，都有一个曲线来控制24小时的光照。",[46,1815,1816],{"id":1816},"菜单画面",[11,1818,1819],{},"游戏中的菜单画面没有使用RenderTarget，而是直接进行3D绘制。",[11,1821,1822],{},"主要原因是开发时出于抗锯齿、处理负荷等因素，以及无法准备高分辨率的贴图等原因。",[11,1824,1825],{},"这样直接绘制的问题是，场景内的光照因素会反映到菜单画面来。",[11,1827,1828],{},"处理的方法是，首先使用light channel来避免被场景中的光达到。",[11,1830,1831],{},"同时从PostProcess中关闭GI的影响。",[11,1833,1834],{},"最后将r.SkyLightingQuality置为0。",[11,1836,1837,1838,1841],{},"消除掉环境的影响后，使用",[96,1839,1840],{},"Ambient Cubemaps","来添加光照。",[11,1843,1844],{},[232,1845],{"alt":1846,"src":1847},"image-20210117195359304","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117195359304_thumb.png",[46,1849,1850],{"id":1850},"动态装饰物体",[11,1852,1853,1854,1859],{},"混合使用了",[30,1855,1858],{"href":1856,"rel":1857},"https:\u002F\u002Fgithub.com\u002Fpafuhana1213\u002FKawaiiPhysics",[34],"KawaiiPhysics","与AnimDynamics。",[11,1861,1862],{},"使用KawaiiPhysics是因为其设置简单，动作起来很萌。",[11,1864,1865],{},"开发初期使用的是PhysicsAsset，由于初期性能优化不好，在帧率下降时，出现了穿模等一系列物理模拟不准确的问题，在各个平台上进行运行测试后，判断要使用需要花费的成本过高。",[11,1867,1868],{},"于是中期就切换到了AnimDynamics，虽然比PhysicsAsset要安定许多，但是在性能下降时还是会出现穿模的现象。为了达到理想的效果，进行了很多试错……",[11,1870,1871],{},"在开发终盘，性能已经稳定下来了。再次对PhysicsAsset进行验证，发现在帧率下降时还是会有穿模现象，同时从AnimDnamic切换过去会花费额外的成本，放弃使用了。",[11,1873,1874],{},"最后发现了KawaiiPhysics，KawaiiPhysics本身在帧率下降后的表现依然很稳定，很少发生穿模，形状出现问题的情况也必须少。与现存的AnimDynamic可以并用，替换的成本也较低，在终盘也能安定的进行。",[21,1876,1877],{"id":1877},"程序编制",[46,1879,1880],{"id":1880},"过场动画",[11,1882,1883],{},"圣剑传说3在游戏过程中，需要从6个主要角色中选择3个人来进行游戏。可组合的方式导致过场动画制作起来有不少的难度。在有的场景中，由于所选的角色组合不同，所播放的内容会有很大不同。",[11,1885,1886,1887,1890],{},"对应方法是，在",[403,1888,1889],{},"Sequencer","中使用一个专用的共通Actor来进行表演的设置，在游戏运行时。则将对应的角色替换到这个共通Actor中。这样就能让队伍的角色成员反映出来，也能保持玩家所携带的装备。",[11,1892,1893],{},"为了实现这一点，所有的角色都会采用一样的命名规范。在进行Sequencer播放时，会由代码按照规则取出对应角色的对应动画。各个角色的动画会通过转换器进行自动收集并输入到csv文件中，最终在UE4中加载成为DataTable。",[11,1895,1896],{},"语音台词和LipSync动画也遵循类似的规则进行取出。",[11,1898,1899],{},"动画在设置上，分为身体、眉毛、眼睛和嘴巴四个层次进行控制。",[11,1901,1902],{},[232,1903],{"alt":1904,"src":1905},"image-20210117204320733","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117204320733_thumb.png",[46,1907,1909],{"id":1908},"event","Event",[11,1911,1912],{},"有的时候，对于特定的组合而言，需要额外的播放一些场景。此时会对当前的角色进行判定，来决定是否播放特定的子动画。",[11,1914,1915],{},[232,1916],{"alt":1917,"src":1918},"image-20210117204241149","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117204241149_thumb.png",[46,1920,1921],{"id":1921},"视线和头的朝向",[11,1923,1924],{},"分为角度型和目标指定型的LookAt两种。",[11,1926,1927],{},"但是主角色的眼球大小会有所不同，所以需要设定眼睛的可达角度限制，在实际运行时进行控制。",[11,1929,1930],{},"由于各个角色的身高不同，所以根据角色的不同会使用不同的摄像。在Sequencer中会提供不同的角色的相机位置设置，可以在运行时进行取出。",[11,1932,1933],{},[232,1934],{"alt":1935,"src":1936},"image-20210117205036407","\u002Fwp-content\u002Fuploads\u002F2021\u002F01\u002Fimage-20210117205036407_thumb.png",[11,1938,1939],{},"似乎会通过代码进行CameraTrack的实时替换。",[46,1941,1943],{"id":1942},"lipsync","LipSync",[11,1945,1946],{},"语音对应了日语和英语两种，分别有相应的LipSync数据。",[11,1948,1949],{},"规则上，要求台词的文本ID与语音的文件名一致。",[11,1951,1952,1953,1958],{},"使用SE的",[30,1954,1957],{"href":1955,"rel":1956},"https:\u002F\u002Fcedil.cesa.or.jp\u002Fcedil_sessions\u002Fview\u002F1742",[34],"Byblos","进行文本的管理。",[11,1960,1961,1962,253],{},"LipSync使用了Oculus的OVRLipSync进行录制，参考这个",[30,1963,1964],{"href":1964,"rel":1965},"https:\u002F\u002Fpafuhana1213.hatenablog.com\u002Fentry\u002F2018\u002F11\u002F26\u002F011057",[34],[11,1967,1968],{},"对于录制的LipSync数据，必要的话会手工进行调整。",[11,1970,1971],{},"流程上，同样是使用转换器收集成csv并导入到UE4成为DataTable。",[11,1973,1974],{},"运行时在场景中生成时，由台词的文本显示同步触发：",[381,1976,1977,1980],{},[384,1978,1979],{},"同名的语音文件播放",[384,1981,1982],{},"在对应的角色上播放LipSync动画",[21,1984,1985],{"id":1985},"其他",[11,1987,1988],{},"避免使用资源的硬链接",[11,1990,1991],{},"使用Interface在设计上避免耦合。",[11,1993,1994],{},"蓝图C++化，由于游戏逻辑9成使用的都是蓝图，实际处理时风险过大。最后只将一部分比较重的逻辑移植到了C++中。",[46,1996,1998],{"id":1997},"削减load时间比较有效的方法","削减Load时间比较有效的方法",[11,2000,2001],{},"玩家相关、特效相关、SE相关的常驻处理",[11,2003,2004],{},"Widget、图标贴图事先进行Cache缓存",[11,2006,2007],{},"防止不必要的资源进入地图",[46,2009,2011],{"id":2010},"对于cpu性能改善比较有效的方法","对于CPU性能改善比较有效的方法",[11,2013,2014],{},"尽可能的关掉Tick，在新建项目的时候一起关掉，只有必要的Actor才Tick",[11,2016,2017],{},"复杂的处理果然还是放到C++里面比较快",[11,2019,2020],{},"PGO(Profile Guided Optimization)，利用游戏中的Profile结果进行最优化处理",[11,2022,2023],{},"URO(Enable Update Rate Optimizations)，对远离摄像的动画更新进行降频",{"title":508,"searchDepth":509,"depth":510,"links":2025},[2026,2033,2039],{"id":1750,"depth":509,"text":1750,"children":2027},[2028,2029,2030,2031,2032],{"id":1759,"depth":510,"text":1759},{"id":1783,"depth":510,"text":1784},{"id":1807,"depth":510,"text":1807},{"id":1816,"depth":510,"text":1816},{"id":1850,"depth":510,"text":1850},{"id":1877,"depth":509,"text":1877,"children":2034},[2035,2036,2037,2038],{"id":1880,"depth":510,"text":1880},{"id":1908,"depth":510,"text":1909},{"id":1921,"depth":510,"text":1921},{"id":1942,"depth":510,"text":1943},{"id":1985,"depth":509,"text":1985,"children":2040},[2041,2042],{"id":1997,"depth":510,"text":1998},{"id":2010,"depth":510,"text":2011},{"layout":548,"status":549,"published":550,"author":2044,"author_login":553,"author_email":554,"wordpress_id":2045,"wordpress_url":2046,"date_gmt":2047,"excerpt":2048},{"display_name":552,"login":553,"email":554,"url":508},3243,"\u002F?p=3243","2021-01-24 04:08:31 +0000",{"type":8,"value":2049},[2050],[11,2051,1727],{},"\u002F2021-01-24-unreal-fest-trials-of-mana-3-note",{"title":1722,"description":1727},"_legacy\u002F2021\u002F2021-01-24-unreal-fest-trials-of-mana-3-note",[1511,736],"w76ga3vPnRwZGTYJffVzsbZqAiFFfGMDM85SQ_10Ka8",222,1788763176487]