[{"data":1,"prerenderedAt":303},["ShallowReactive",2],{"\u002F2018-01-01-ue4-material-deepdive-note":3},{"id":4,"title":5,"body":6,"date":280,"description":12,"extension":281,"meta":282,"navigation":285,"path":297,"seo":298,"stem":299,"tags":300,"__hash__":302},"blogs\u002F_legacy\u002F2018\u002F2018-01-01-ue4-material-deepdive-note.md","深入UE4材质管理",{"type":7,"value":8,"toc":258},"minimark",[9,13,16,20,23,26,31,34,37,41,44,47,50,53,56,60,63,66,69,72,75,79,82,89,92,95,98,101,105,108,113,117,120,125,128,131,134,138,141,145,148,153,156,161,167,170,173,176,181,184,187,192,195,200,203,208,211,215,220,223,228,231,236,239,243,246,249,252,255],[10,11,12],"p",{},"UE4的材质系统使用起来虽然很方便，但是如果不进行有效的管理，很快就会导致项目的体积变得不可控制，材质编译时间也会变成痛苦的折磨。",[10,14,15],{},"本文是EpicJapan UE4 DeepDive系列中材质管理部分的总结，对应UE4版本为4.12~14。部分截图来自4.18。",[17,18,19],"h2",{"id":19},"抽离共通逻辑",[10,21,22],{},"为了减少材质的编译尺寸，首先要做的就是将共通的逻辑都抽出来。",[10,24,25],{},"在材质系统中一共有以下两种做法",[27,28,30],"h3",{"id":29},"material-function","Material Function",[10,32,33],{},"材质函数可以将一些共同的操作逻辑抽取出来，这样在进行材质的编译的时候，就不会产生重复的部分了。",[10,35,36],{},"UE4本身就提供了大量的材质函数来方便进行材质的表现。",[27,38,40],{"id":39},"material-instance","Material Instance",[10,42,43],{},"材质实例通过将通用的材质统合起来，有效的减少材质的数量。",[10,45,46],{},"使用上，如果材质之间就只有贴图或者参数不同的话，就可以构建一个基础的材质，然后将需要变化的材质进行参数化。",[10,48,49],{},"并创建材质实例以应对不同的情况。",[17,51,52],{"id":52},"选项优化",[10,54,55],{},"材质在使用时有的选项需要进行优化，否则就会生成很多不会使用到的部分。导致编译时间变长且无端的占用发布体积。",[27,57,59],{"id":58},"usage","Usage",[10,61,62],{},"材质的选项中有一个Usage的选项，通常会自动勾选上Automatically Set Usage in Editor。",[10,64,65],{},"这个选项会在材质被特定的Usage使用的时候自动打开，针对每一种Usage会生成新的Shader来进行对应。",[10,67,68],{},"但是，Usage被打开后，如果不再在对应的Usage中使用的话，引擎并不会自动的关闭这个Usage，所以需要手动的进行关闭。",[10,70,71],{},"这个选项的作用在极端情况下特别大：使用全部Usage时1837K的材质在仅使用Static Light时却只有97K的。",[10,73,74],{},"因此在使用的时候还是需要进行额外的注意的，如果默认去掉这个选项的话，就可以有效的避免误操作导致的勾选了。当然使用起来就会有些麻烦。",[27,76,78],{"id":77},"shader-permutation-reduction","Shader Permutation Reduction",[10,80,81],{},"在项目设置>渲染中，能够看到",[10,83,84],{},[85,86],"img",{"alt":87,"src":88},"image","\u002Fwp-content\u002Fuploads\u002F2017\u002F12\u002Fimage_thumb.png",[10,90,91],{},"这个也是类似的选项，在没有使用对应的功能的时候去掉就好了。",[10,93,94],{},"这个如果去掉了却在使用对应的功能的话，编辑器内会有屏幕输出提示，可以放心使用。",[17,96,97],{"id":97},"材质实例关系",[10,99,100],{},"材质实例的继承关系会很大的影响到材质的编译过程，部分继承的属性重写是会导致材质实例需要生成新的Shader的。",[27,102,104],{"id":103},"override-properties","Override properties",[10,106,107],{},"材质属性覆盖会导致需要为实例生成新的Shader",[10,109,110],{},[85,111],{"alt":87,"src":112},"\u002Fwp-content\u002Fuploads\u002F2017\u002F12\u002Fimage_thumb-1.png",[27,114,116],{"id":115},"static-switch-parameter","Static Switch Parameter",[10,118,119],{},"开关是需要额外的生成Shader的",[10,121,122],{},[85,123],{"alt":87,"src":124},"\u002Fwp-content\u002Fuploads\u002F2017\u002F12\u002Fimage_thumb-2.png",[10,126,127],{},"当然也包括Static Component Mask Parameter。",[10,129,130],{},"因此在进行材质实例的继承的时候，应当进行规划，首先分支出Switch等需要重新生成Shader的材质实例后，再继承其他的如贴图、颜色这些不会导致重新生成的材质实例的继承。",[10,132,133],{},"同时，由于材质实例不携带Usage属性，所以这个问题上只能一开始就进行分开。",[17,135,137],{"id":136},"tips","Tips",[10,139,140],{},"这个是SE的演讲者给出的一些操作建议。",[27,142,144],{"id":143},"textrue","Textrue",[10,146,147],{},"尽量减少图形的分辨率，在使用单色的Textrue时，使用1x1的图片即可，在需要过渡特效时，使用一个小条就可以了。",[10,149,150],{},[85,151],{"alt":87,"src":152},"\u002Fwp-content\u002Fuploads\u002F2017\u002F12\u002Fimage_thumb-3.png",[10,154,155],{},"而有对称性的图片，可以通过调整Tilling Method来减小尺寸。",[10,157,158],{},[85,159],{"alt":87,"src":160},"\u002Fwp-content\u002Fuploads\u002F2017\u002F12\u002Fimage_thumb-4.png",[10,162,163],{},[164,165,166],"strong",{},"Mipmap",[10,168,169],{},"有一个ComputeMipLevel的节点可以用于将Mipmap进行可视化调节。",[10,171,172],{},"Mipmap虽然可以在贴图的选项中关掉，但是这样会导致原始贴图常驻内存，运行时消耗很大。",[10,174,175],{},"Texture的Uv入口被用于缩放时并不会对应到MipLevel上，使用时需要注意。",[10,177,178],{},[164,179,180],{},"Power",[10,182,183],{},"不要使用Power来进行2.2次方的运算而是直接相乘。也可以直接将同一个数相乘写成一个材质函数，方便使用。",[10,185,186],{},"因为两个的计算几乎无法目视区分，却有着明显的性能消耗。",[10,188,189],{},[164,190,191],{},"vector displacement map",[10,193,194],{},"矢量置换贴图采用BC7压缩可以大幅减小尺寸？",[10,196,197],{},[164,198,199],{},"Maximum Texture Size",[10,201,202],{},"比LOD Bias能够更好的对贴图尺寸进行控制。",[10,204,205],{},[164,206,207],{},"Never Stream",[10,209,210],{},"会一次性载入所有的MipLevel贴图，在使用频率很高的粒子的贴图上可以打开。",[27,212,214],{"id":213},"material","Material",[10,216,217],{},[164,218,219],{},"除0対策",[10,221,222],{},"为了防止0被传到除法运算上，可以考虑加上0.0001，虽然严格意义上应当使用Max或者Min来进行控制，但是Add的效率更高",[10,224,225],{},[164,226,227],{},"Texture参数",[10,229,230],{},"即便两个参数指定的是同一个Texture，也会进行两次采样。",[10,232,233],{},[164,234,235],{},"SamplerType",[10,237,238],{},"SamplerType选择为Alpha时在有的平台实际上用的确实R通道",[27,240,242],{"id":241},"trick","Trick",[10,244,245],{},"DynamicParameter 对于float2、float3、float4，如果实际上需要的参数是一样的话，是可以用float来代替的，会自动的被变为对应的类型。",[10,247,248],{},"ParticleColor 可以在EmissiveColor不需要通过这个参数指定时用于其他用途",[10,250,251],{},"ParticleRandom是GPU粒子独有的节点，值在0~1之间，可以用于添加随机特效",[10,253,254],{},"Static Component Mask Parameter可以为1张贴图提供四种变数",[10,256,257],{},"UV使用Time进行滚动时，可以先滚动再Tilling，这样的话Tilling进行调整时就不会影响UV动画的速度了。",{"title":259,"searchDepth":260,"depth":261,"links":262},"",2,3,[263,267,271,275],{"id":19,"depth":260,"text":19,"children":264},[265,266],{"id":29,"depth":261,"text":30},{"id":39,"depth":261,"text":40},{"id":52,"depth":260,"text":52,"children":268},[269,270],{"id":58,"depth":261,"text":59},{"id":77,"depth":261,"text":78},{"id":97,"depth":260,"text":97,"children":272},[273,274],{"id":103,"depth":261,"text":104},{"id":115,"depth":261,"text":116},{"id":136,"depth":260,"text":137,"children":276},[277,278,279],{"id":143,"depth":261,"text":144},{"id":213,"depth":261,"text":214},{"id":241,"depth":261,"text":242},"2018-01-01","md",{"layout":283,"status":284,"published":285,"author":286,"author_login":288,"author_email":289,"wordpress_id":290,"wordpress_url":291,"date_gmt":292,"excerpt":293},"post","publish",true,{"display_name":287,"login":288,"email":289,"url":259},"风铃","flinkor","flinkor@foxmail.com",2192,"\u002F\u002F?p=2192","2017-12-31 16:02:08 +0000",{"type":7,"value":294},[295],[10,296,12],{},"\u002F2018-01-01-ue4-material-deepdive-note",{"title":5,"description":12},"_legacy\u002F2018\u002F2018-01-01-ue4-material-deepdive-note",[301,214],"UE4","fKGSuTdtw5DEXqYUD_-VBIoQmLlq-aYwVtmxYL8eN0Q",1788763179432]