tasklist's Issues
已查出的兼容性问题整理
精度相关
lowp: 2位指数5位尾数, 1/32 = 0.03125
mediump: 10位尾数 1 / 1024 = 0.0009765625 ≈ 0.001
- 除了微信, 字节的其他小平台, 8888shadowmap float计算精度都有问题, 是贴图采样出来只有小数点后4位的样子,是因为sampler默认是lowp的,所以所有的数据贴图都必须在sampler前加highp来定义(已解决)
- vivo小平台, ubo数据标mediump的精度很低, 导致debug view单选数据对EPSILON的equalf失效, 改成EPSILON_LOWP就可以了(已解决) https://github.com/cocos/3d-tasks/issues/15562
- iPhoneX/11 + 字节小平台 https://github.com/cocos/3d-tasks/issues/12650
部分华为麒麟海思芯片(P30, P40等) 的原生GLES或WebGL中,浮点格式贴图读写精度不足导致shadowBias效果出错 https://github.com/cocos/3d-tasks/issues/13330
可以强制使用Packing, 或在每个sampler2D shadowmap的定义处(包括函数传参)都要加highp, 或直接shader头部加precisioni highp sampler2D(已解决) - 安卓原生平台, Oppo RenoZ这种机子vs输出ps的项必须指定一个精度, 否则就会传错误的值(1.0传下去变成了0.0) https://github.com/cocos/3d-tasks/issues/10955
- 安卓+webgl平台, ps中结构体所有成员的精度只能是mediump, 无法提升, 用到position之类对精度要求高的数据要注意进行pack/unpack, 使用宏方式来定义和赋值(已解决), 表现形式可能是高光或阴影有异常 https://github.com/cocos-creator/3d-tasks/issues/10538 https://github.com/cocos/3d-tasks/issues/13091
有时候normal精度不足也会造成错误, 可能需要对normal也做额外的补偿处理
- 安卓Chrome/UC浏览器会出现深度比较精度随时间抽风的问题 https://github.com/cocos-creator/3d-tasks/issues/9205 https://github.com/cocos-creator/3d-tasks/issues/10915 https://github.com/cocos-creator/3d-tasks/issues/10924
- 16bit float支持大值域导致数据精度更差,对于normalized value而言,最好还是用Normalized类型,但16bit下没有UN或SN格式,此时就使用8+8 packing来解决,精度会比16bit float格式更好 https://github.com/cocos-creator/3d-tasks/issues/9540
- iPhoneX/11 + 字节小平台, v_clip_pos精度为mediump, 无法提升 https://github.com/cocos/3d-tasks/issues/12655
要特别注意这种需要齐次除的数据, 一定要在ps里除, 尤其是透视投影
指令相关
- 注意不同平台下支持不一样, 安卓有些是不支持textureLod采样的,在代码中就只能用textureBias来替换, 这会造成 PBR反射的粗糙度不同(已知问题) https://github.com/cocos-creator/3d-tasks/issues/10492
- Vulkan下mod函数的被除数不能大于100 https://github.com/cocos-creator/3d-tasks/issues/9858
https://github.com/cocos-creator/engine/pull/9847/files
关联--https://github.com/cocos-creator/3d-tasks/issues/9858
shader里面pseudoRandom vk不兼容,具体是vk的shader不兼容此处mod的输入值,需要找一个替代写法才行
- oppo r11的step和大于小于写法, 只有两种执行是正确的:
[1] 大于小于用来判断常量:
if (xxx <= UBO.clipvalue)是错的, if (xxx <= 128)是对的, 大于小于只能拿来判断常量, 判断变量或者UBO常量就错
[2] step不能直接&&:
step可以判断任何变量和常量, 但step不能写成if (step && step),要写成a = step; b= step; if(a && b)
结论是: 推荐使用step代替大于小于, 但多个step不要出现在一个语句中
也可能要分Shader, VS用> <, PS用step会兼容性更好
https://github.com/cocos-creator/3d-tasks/issues/10249 PS中的用法
https://github.com/cocos-creator/3d-tasks/issues/9022 VS中的用法, 3.4.1好像又正确了
- oppo vivo等机型,或小米6安卓8系统下,在循环中如果出现break / continue / return等动态控制语句,可能导致crash,如https://github.com/cocos/3d-tasks/issues/10779
所以说在不是必须要动态分支的地方,尽量使用宏展开的unroll形式,就算写成for也不要有上述三个语句。
- 动态分支if内不能修改if外超过vec4大小的变量 https://github.com/cocos/3d-tasks/issues/9236
- pow需要注意, 指数不可以为0, 否则在安卓上可能出现一些异常的值导致锯齿, 黑线 亮线之类的
贴图及采样相关
- WebGL2.0不支持DS格式的图以linear方式采样, 否则会全黑 KhronosGroup/OpenGL-API#84
- iOS WebGL, 字节百度等小平台下, 如果图片带有A通道但没有开Alpha Blend, 也没有正常的透贴discard, WebGL底层在Shader采样贴图时会自动返回(RGB*A, 1)的值, 所以不可以在不开透贴和半透的情况下使用这样的图, 正常透贴是可以支持的
- iOS 微信小游戏,如果图片带有A通道(比如RGBE png),底层在Shader采样贴图时会自动将RGB处理成一些奇怪的值导致RGBE解码的颜色错误,a通道全填1就好了,不知如何解决 https://github.com/cocos/3d-tasks/issues/13050
- iOS WebGL, 如果开启Blend, ps的a通道输出0就会混出奇怪的颜色
- M1芯片mac, 回读R32F格式的贴图会失败, 只能换成R32G32B32F
函数参数
-
极少数机型 PS中不支持函数输出一个结构体(out StandardSurface s)这样的写法 , Unity中是改为结构体中的每项单独out之后编译的
https://github.com/cocos-creator/3d-tasks/issues/10131#issuecomment-979582484
https://github.com/cocos-creator/3d-tasks/issues/9303 -
注意函数参数中需要输出结构体的情况,如果函数A(out StructType s)、B(inout vec3 xx)和C(inout StructType s),在A中调用B(s.test)和C(s),都会造成兼容性问题,原生GL上会无法正常写入test项(WebGL可能是正常的)。反之A(inout StructType s)、B(out vec3 xx)和C(out StructType s)也是不行的,out必须严格对应所有调用处的out,inout必须严格对应inout
为了统一,所有和结构体及其内部单项数据相关的传参都应给inout参数 -
注意函数参数中使用分支条件修改out参数的时候, 在mac上可能造成强制初始化
不一定会修改的传参也都应给inout参数 -
也要注意函数参数中需要输出mat4的情况, 如CSMGetLevel(out mat4), 要改成输出4个vec4(out vec4, out vec4, out vec4, out vec4), 否则对out mat4参数赋值的语句放在for或if中会导致crash (如oppo r11st) https://github.com/cocos/3d-tasks/issues/12596
-
WebGL1.0不支持带参数的宏的写法,只能使用#pragma define使用预先处理的字符串展开
其他
- 百度平台 + oppo findx或一加机器上, 在vs的main函数中直接输出varying变量, 在ps中拿到的就是无效值(无理数), 如果main函数调用另一个函数输出该变量就可以, 相当于必须包一层函数调用, 不知道是否是gl编译器的bug https://github.com/cocos/3d-tasks/issues/13200#issuecomment-1198820757
- Vulkan + 安卓平台, 镜像法线标记在ps中访问可能会是接近0的值, 导致乘出来的bitangent为零向量, normalize之后变成无理数, 这里使用专门的判断使其必定是-1或1 https://github.com/cocos/3d-tasks/issues/14121
- 小米6 + Vulkan,某些Surface函数如SurfacesVertexModifyLocalPos直接返回xxx.xyz会导致crash,比如强行转换为vec3(xxx.xyz)才可以
- 小米 + GLES后端原生,如果先用默认RT,然后切其他RT,最后又切回默认RT的话(比如多相机的情景),可能导致Clear Depth出错,不管指定什么值,Clear进去的都是最小值 https://github.com/cocos/3d-tasks/issues/14077
- 微信 + WebGL2,shadowmap无法clear为正确的值,貌似都会clear为camera的clear color
硬件能力
- UC浏览器(所有硬件平台) 不支持Feature.INSTANCED_ARRAYS, 所以有半透明物体开启Instancing是无效的, 这会导致半透绘制顺序的变更, 因为半透物体先画Instancing的, 再画非Instancing https://github.com/cocos/3d-tasks/issues/14165
- 老苹果(SE 7等) 支持的maxFragmentUniformVectors比较少, 会导致加了CSM的一堆uniform之后编译报错, 在3.6.0添加了对此能力检测的支持 cocos/cocos-engine#12072
iOS 15.4.1报的maxVertexUniformVectors也很少, 导致骨骼使用的uniform越界, 自动计算之后可以修复 cocos/cocos-engine#13174
微信平台报的maxVertexUniformVectors很多但其实不能用, 会导致骨骼动画都画不出来, 通过写死root.ts中自动计算的Count为256可以检查是否正常 - Oppo小平台的IB只能支持16bit,所以模型顶点数不可以超64k
引擎相关代码
- shadowUBO在shader中include了但是没有使用(场景没开阴影), 但也必须在引擎中updateUBO, 否则在vivo7p上就会crash, 如https://github.com/cocos/3d-tasks/issues/10779
问题集查询
已知待查验: surface shader场景(同时开instancing和两盏局部光才)会导致vivox7p crash
test-case的鸭子场景material-upgrade, 鸭子使用legacy/toon.effect的话会在华为H60-L02的安卓原生上无光照
小游戏平台已知问题收集: https://github.com/cocos/2d-tasks/issues/2581
材质、面板等相关问题
- 1. 材质面板中开启或关闭BlendEnable, 不会提示或自动切换Technique, 会引人误解
- 2. https://github.com/cocos-creator/3d-tasks/issues/10093
- 3. 单独的ts脚本控制effect UI面板,而不是用yaml语言去描述https://github.com/cocos-creator/3d-tasks/issues/8508 https://github.com/cocos-creator/3d-tasks/issues/1821
DCC相关问题
ShadowMap相关问题
- 1. Shadowmap关闭状态改用uniform动态分支, 不能一直clear
- 2. JS-Engine 中 Shadows 类更名为 ShadowInfo https://github.com/cocos-creator/3d-tasks/issues/9538
- 1. https://github.com/cocos-creator/3d-tasks/issues/8436
- 2. enable shadowmap就要创建阴影图并初始化为白图, 不要在shadowflow中创建(rt需要支持clear的接口)
- 1. Mesh和Submesh级别也需要有额外的两个Bias https://github.com/cocos-creator/3d-tasks/issues/8538, 可以先做Mesh级别的, 要考虑instancingdata
- 2. submesh级别的可能需要在后面做材质变体,否则没地方存放此设置
- 3. https://github.com/cocos-creator/3d-tasks/issues/9093
- 4. R16f精度问题,造成非常严重的自阴影问题 https://github.com/cocos-creator/3d-tasks/issues/9540
- 5. Packing应该全平台都支持的, 为何还会有阴影截断的问题 https://github.com/cocos-creator/3d-tasks/issues/9378
- 6. shadowbias放到渲染阴影图中应用而非渲染期
- 7. 自动计算的slope bias
- 8. csm剪裁支持instancing物体
光照模型相关问题
- 1. 环境反射除噪选项
- 1. 局部光源提供Mobile和非Mobile两套GGX BRDF模型, 根据平台类型来切换, 前提是搞清楚DGF
- 2. 新增点光源 https://github.com/cocos-creator/3d-tasks/issues/10064
- 3. 点光衰减: 给定两套方案 PointLight Attenuation, two method for artists:
3.1 勾选物理真实范围: 绑定光通量 / 硬切 / 边缘柔化 三种模式可以UI下拉选择, 目前已有第三种方式
Checkbox for Physical Real Range: ListBox for (Bind Luminous Flux / Force Truncate / Edge Fade)
3.2 不勾选物理真实范围, 使用美术向的衰减计算公式以修改衰减曲线
Attenuation calculations for artists
AttenMode做成枚举,方便3.2扩展
https://github.com/cocos-creator/3d-tasks/issues/8347 - 4. 新增范围平行光(无阴影)
- 5. Sphere Light面光源计算, 配合PCSS软影
- 6. 环境反射图卷积Mip的功能 https://github.com/cocos-creator/3d-tasks/issues/10900
- 7. 反射采样漏光, 是否是GF积分函数未考虑G项 https://github.com/cocos-creator/3d-tasks/issues/10839
- 8. add pass SRGB+HDR叠加造成的精确光照问题: 需要移植cluster到forward
DCC材质信息转换算法
粗糙度
首先获取FbxDocumentInfo中的ApplicationVendor, 如果包含Blender就要使用以下转换:
使用roughness = 1.0 - min(1.0, sqrt(FbxSurfacePhong.Shininess) / 10.0f) 转换高光强度为粗糙度
metallic = FbxSurfacePhong.ReflectionFactor
若不包含Blender则使用以下转换: roughness = 1.0 - pow(2.0, -10.0 / (FbxSurfacePhong.Shininess + 0.0001))
metallic = 0.0
将两个值设置给内置材质
金属性
blinnphong模型的SpecularColor亮度大于0.9 && DiffuseColor亮度<0.1则金属性为1,否则为0
半透
导入时需要处理透明材质, 正常情况下导出FBX的材质transparentfactor大于0则说明是透明材质, 需要将Technique改为transparent
但要注意防止全透, 即transparentfactor=1的情况, 所以导入时albedocolor.a应该设为min(0.95, 1-TransparentFactor)
C4D材质的透明部分非常奇怪, transparentfactor永远是1, AppVendor是Blender的应该强行禁用透明材质
模型贴图资源相关问题
- 1. FBX模型导入的镜像法线标记(Tangent.w)有问题, 貌似都是0, 导致某些区域的凹凸效果会不一样 https://github.com/cocos-creator/3d-tasks/issues/11276
- 2. 需要一个简单的自定贴图容器格式, 可以存储Volume, 2DArray和MipChain (RGBE贴图, EnvCube, 植被底图, 体渲染等等都需要)
- 3. RGBE编码的贴图生成Mip需要一个特殊的流程,先转回FP格式再生成 (不转的话可能造成亮度丢失?)
------ 自动检查功能 ------
- 1. 使用UUID检查功能来清理无用资源: 先扫描prefab, 再扫描mtl, 再扫描mesh和texture
- 2. 内置材质中用到的albedo和normalmap等贴图检查mip是否有开
- 3. 指定的材质中如果包含名为normalmap参数的话, 检查节点缩放是否有负值
- 4. 场景相机near / far比例
性能相关优化和Shader代码书写
- 1. Shadowmap关闭状态改用uniform动态分支, 不能一直clear
- 2. shadow macros cocos/cocos-engine#11178
慎用if, 即便是只判断uniform也可能不是动态分支,(某些低端机如小米6 vivox9上会编译成静态展开,所有分支都要走), 尽量还是用宏, 就算用if也一定要只判断uniform, 非uniform的放在uniform条件内部if(uniform) { if(非uniform) {} } - 3. 背光面不要计算shadow和lighting,直接跳过, 怕动态分支的话至少跳过计算shadow
- 4. https://github.com/cocos-creator/3d-tasks/issues/8570
- 5. UpdateShadowUBO等函数中的ds->update, 需要放到更好一点的位置去调用, (最晚的位置在bind descriptorset之前), 可使用GlobalDSManager来绑定相关数据
- 6. SPOTLIGHTINGMAP改名为SPOTSHADOWMAP
- 7. #pragma optimize (on) 开启glsl编译代码优化? 或使用工具glsl_optimizer
- 8. vs output的varying数据字节数一旦超过76(19个float), m1等新芯片上metal性能狂跌3成
- 9. webgl1.0切2.0之后性能暴涨, 或者webgl/gles在ios上切metal之后性能暴涨, 当找不到瓶颈时可尝试切换
- 10. 不同透明度会影响 GPU blender 效率。多个不同透明度物体叠加显示比多个相同透明度物体叠加显示时GPU算力消耗高
测试用例场景
- 1. 烘焙+spotlight+半透明: scene_test
- 2. toon+自阴影+近视角
- 3. 地形+烘焙+spotlight+自阴影+半透明
- 4. NV那个免费场景
效果提升
- 1. 材质中添加宏, 支持对光滑表面的镜面反射去噪
- 2. 大气高度雾
- Color Grading: 首次开启Color Grading时,复制内置默认RGB对应表到场景文件夹内并设置为LUT图
点击编辑按钮后对当前RT进行screenshot并自动唤起PS同时打开LUT图和screenshot
当美术修改保存LUT图时,reload机制生效,场景颜色被更新的LUT刷新
Effect和Shader语法说明和编译Tricks
Effect Parser的一些功能介绍
- 所有用到#if 的地方都会被parse,这些宏会被收集起来,如果shader没有定义该宏,编译器会自动添加默认值
- 收集的宏会用于显示UI(#pragma define-meta或未定义的非CC_宏)
- 会parse IA输入(无视宏条件)
YAML部分的语法
- properties: *props 指的是复制第一个property的内容,可以在下面继续定义一部分property重载参数,该pass的property具有独立设置
- propertyIndex: # 指的是引用之前第#个pass定义的props内容,修改props定义内容则引用它的pass参数内容也会变
- 但需要注意,上两条对properties的复制或引用仅在当前technique生效,换technique的话就必须重新定义,不能复用
- migrations:参考builtin-unlit,可以进行方便的变量更名,但更复杂的迁移还是得写engine-extensions
预处理指令
- #pragma define-meta 名称 options/range/default(true) 这个是运行期宏, default编译期是常量,运行时从CPU传常量值
编译前预先字符串搜索替换,优先级高,匹配#if这样的用法,主要用于材质UI开关 - #pragma define 是effect编译期的宏, 主要为了支持WebGL1下的带参数宏, 以及定义UBO中数组的数量,
编译前预先字符串搜索替换,优先级高 - #define #ifndef是正常的宏定义, 和C++相同
完全不管,前两项处理完直接传入编译,优先级低
所以说低优先级的#ifndef必须包在高优先级的#if里,否则会在前两步处理时报错 - 什么都不声明的宏默认是1
- 1只能用#if, 2和3可以用#if及#ifdef/ifndef/defined()
- #include ""和<>是一样的, 先搜索chunks文件夹, 再搜索同级文件夹
- 想让一个子宏到主宏的UI组内, 只能用#if 主宏 && 子宏的方式, 会自动建立依赖关系, 但只能支持一层依赖,所以每一句的子宏只能有一个, 后面加多个也只有第一个生效
- 函数会预先字符串parse, 所以不能用宏分支来定义函数名, 否则会编译出错说调用处找不到该函数, 如#if XXX void Func(XXX) #else void Func(XXX) #endif {}
- ubo中的array必须前面加cc_,然后用#pragma define来定义array count
- shader头部加precision highp float/sampler2D/samplerCube 可以分别控制不同类型的默认精度
- 对于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)就好了
- #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相关
- 可以加embeddedMacros,但不要在里面直接给CC_SURFACES_宏,而是定义一个别名,如TECHNIQUE_XXX,然后在MacroRemapping中#if TECHNIQUE_XXX #define CC_SURFACES_XXX #endif这样,参考glass.effect
Shader代码相关
- 记得函数定义中如果有sampler类型,则定义和调用处必须处在同样的宏条件下,因为sampler需要Parser预判,否则可能因为宏条件不同导致函数对sampler类型解析出错
- 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里访问是[列][行]
HDR相关问题
- 1. deferred管线下的fpScale使用正确性? smaa tonemap中对FPSCALE_INV的使用正确性?
- 2. forward管线的ACES ToneMapping目前的曝光是通过修改光源强度实现的, shader中emissive, lightmap和fog等所有对finalcolor的线性操作都需要乘cc_exposure.w曝光值
Lightmap相关问题
- 1. lightmap目前是全烘焙(包括直接/间接/遮挡都混在一起)的状态, 因此应该用它替换掉所有实时光照,即#if USE_LIGHTMAP && !USE_BATCHING && !CC_FORWARD_ADD这一段放在StandardShading的最后,等以后支持了indirect only, shadow等模式再修改流程,lightmap也需要考虑曝光值
- 2. 烘焙期需要确定一组默认相机曝光参数, 相当于是在此曝光参数下烘焙的光强(无tonemapping), 渲染期要对lightmap先复原到无曝光的原始光强下, 然后再转换到当前相机曝光参数下
如何与UseHDR参数适配: 烘焙器永远烘焙HDR数据, 如果当前是LDR模式下, 则光源需要有一个函数GetBakeIntensity,会根据当前HDR状态自动将LDR亮度值映射为光度学灯光在默认相机曝光参数下的HDR值,即HDRIntensity = LDRIntensity / fixed_exposure再传入烘焙器即可 - 3. 需要调研Lightmap如何与实时光照结合,分离Shadow AO等通道, GIOnly的设定, 相关的UI等等
- 4. 流程自动控制,不能让用户干预, 材质宏USE_LIGHTMAP要去掉 https://github.com/cocos-creator/3d-tasks/issues/4668 https://github.com/cocos-creator/3d-tasks/issues/5957
- 5. https://github.com/cocos-creator/3d-tasks/issues/9132
- 6. 光照模型:需要加入金属性 https://github.com/cocos-creator/3d-tasks/issues/3950
- 7. 光照模型:精确光衰减等引擎完成之后与烘焙端对齐
- 8. 支持bump烘焙
- 9. 自动生成2U:接入Thekla_Atlas来生成光照图所用UV,所有模型拥有一致的texel密度.对光照图进行dilation处理以对抗UV接缝问题.接入BinPacking 处理光照图图集.
数学库的问题
- 1. lookat的问题, 和cameranode worldtransform的inverse对不上 cocos/cocos-engine#14470
- 2. transformMat4函数, 中间一行应该改为rhw = rhw ? 1.0 / rhw : 0.0;
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.