jk20012001 / TaskList

0 stars 0 forks source link

Effect和Shader语法说明和编译Tricks #14

Open jk20012001 opened 2 years ago

jk20012001 commented 2 years ago
                                              Effect Parser的一些功能介绍
  1. 所有用到#if 的地方都会被parse,这些宏会被收集起来,如果shader没有定义该宏,编译器会自动添加默认值
  2. 收集的宏会用于显示UI(#pragma define-meta或未定义的非CC_宏)
  3. 会parse IA输入(无视宏条件)

                                             YAML部分的语法
  4. properties: *props 指的是复制第一个property的内容,可以在下面继续定义一部分property重载参数,该pass的property具有独立设置
  5. propertyIndex: # 指的是引用之前第#个pass定义的props内容,修改props定义内容则引用它的pass参数内容也会变
  6. 但需要注意,上两条对properties的复制或引用仅在当前technique生效,换technique的话就必须重新定义,不能复用
  7. migrations:参考builtin-unlit,可以进行方便的变量更名,但更复杂的迁移还是得写engine-extensions

                                             预处理指令
  8. pragma define-meta 名称 options/range/default(true) 这个是运行期宏, default编译期是常量,运行时从CPU传常量值

    编译前预先字符串搜索替换,优先级高,匹配#if这样的用法,主要用于材质UI开关

  9. pragma define 是effect编译期的宏, 主要为了支持WebGL1下的带参数宏, 以及定义UBO中数组的数量,

    编译前预先字符串搜索替换,优先级高

  10. define #ifndef是正常的宏定义, 和C++相同

    完全不管,前两项处理完直接传入编译,优先级低 所以说低优先级的#ifndef必须包在高优先级的#if里,否则会在前两步处理时报错

  11. 什么都不声明的宏默认是1
  12. 1只能用#if, 2和3可以用#if及#ifdef/ifndef/defined()
  13. include ""和<>是一样的, 先搜索chunks文件夹, 再搜索同级文件夹

  14. 想让一个子宏到主宏的UI组内, 只能用#if 主宏 && 子宏的方式, 会自动建立依赖关系, 但只能支持一层依赖,所以每一句的子宏只能有一个, 后面加多个也只有第一个生效
  15. 函数会预先字符串parse, 所以不能用宏分支来定义函数名, 否则会编译出错说调用处找不到该函数, 如#if XXX void Func(XXX) #else void Func(XXX) #endif {}
  16. ubo中的array必须前面加cc_,然后用#pragma define来定义array count
  17. shader头部加precision highp float/sampler2D/samplerCube 可以分别控制不同类型的默认精度
  18. 对于forward和add两个pass, 公用的代码一定要在公共头文件下包含, 如果头文件A只在add pass下包含(如lighting.chunk或additive.chunk), 头文件B只在forward pass下包含(shading-base.chunk), 然后在A和B中分别又包含了包含了另一个头文件C, 此时可能出现什么预处理 1的错误, 将include C的语句挪到两个pass都包含的头文件中(shading-entry.chunk)就好了
  19. if A || B这种写法最好不要出现,尤其是定义IA数据时,目前支持收集B,但仅仅只是收集,可能在另外的流程中并不包含B,这个需要找小薛的调试代码来输出error


                                              __VERSION__相关

    110及以上支持用动态变量访问vector元素、数组元素,及动态的for循环 130及以上就统一用texture / textureGrad / textureLod函数采样,而无需贴图类型 130及以上支持textureSize获取分辨率 300及以上有GL_OES_standard_derivatives和 texelFetch指令,包括dFdx dFdy fwidth等 310以上可以声明32bit unsigned int的IA Input项 400及以上支持textureQueryLod 450及以上支持subpass

                                              Pass相关
  20. 可以加embeddedMacros,但不要在里面直接给CC_SURFACES_宏,而是定义一个别名,如TECHNIQUE_XXX,然后在MacroRemapping中#if TECHNIQUE_XXX #define CC_SURFACES_XXX #endif这样,参考glass.effect

                                              Shader代码相关
  21. 记得函数定义中如果有sampler类型,则定义和调用处必须处在同样的宏条件下,因为sampler需要Parser预判,否则可能因为宏条件不同导致函数对sampler类型解析出错
  22. VS Out和FS In不要传矩阵,可能导致vk的location的编排重叠,出现overlapping的错误提示,应该把矩阵拆成vec4来传,然后组装起来

                                              矩阵访问

    xScale 0 0 0 0 yScale 0 0 0 0 zf/(zf-zn) -zn*zf/(zf-zn)(引擎中[11]或shader中[2][3]) 0 0 1(引擎中[14]或shader中[3][2]) 0 shader里访问是[列][行]