zoukankan      html  css  js  c++  java
  • ue上 sceneColorMobile 在android 和ios上表现不同的问题

    遇到个比较奇特的问题

    一个值 (4.2,0,0) 在ios上和android都在sceneColorMobile写入这个值

    ios mobile采样的时候这个值就变成1.8

    android PC MAC是不变的

    msaa resolve的问题 和msaaresolve无关 有关 从定义宏的方式 和 判断方式可以确认是有关的 也能解释为什么 drawcall中间没有什么设置但rtv和srv的值不一样

    METAL_MSAA_HDR_DECODE

    倾向是 ios上特殊encode的值不一样 要处理

    SceneColor.rgb *= rcp(SceneColor.r*(-0.299)+SceneColor.g*(-0.587)+SceneColor*(-0.114)+1.0);

    这是个颜色空间的亮度转换

    1.86/(1-1.86x0.299) =4.196

    经验证确实如此

    //The input scene color has been encoded to non-linear space and needs to decode somewhere if MSAA enabled on Metal platform
    bool bMetalMSAAHDRDecode = GSupportsShaderFramebufferFetch && IsMetalMobilePlatform(View.GetShaderPlatform()) && CVarMobileMSAA && CVarMobileMSAA->GetValueOnRenderThread() > 1;

    这地方值的变化乍看很像srgb的转换 但因为sceneColorMObile 是rgba16float是不会有srgb格式的rt的 也没有shader里的转换

    这样理解好一些 是linear相关的转换 功能上 但encode估计是在msaa resolve的时候做的 这比较能解释的通

    哇我好厉害(因为不用一个小时就修出来了,因为ue处理了这件事)

     这是spce里的srgb的转换公式 所以注释里说的 linear肯定不是gamma到linear的转换

    那三个dot的值 明显是亮度值的转换

    目前看还是比较倾向在 msaa resolve 做了这步encode

    encode我大概找到了 就是这个

    //
    // Pre-tonemap before hardware box-filtered resolve.
    //

    void PreTonemapMSAA_ES2(
    float4 InUVPos : TEXCOORD0,
    out half4 OutColor : SV_Target0
    )
    {
    #if (COMPILER_GLSL_ES3_1) || (METAL_PROFILE && !MAC)
    // On-chip pre-tonemap before MSAA resolve.
    OutColor = FramebufferFetchES2();
    OutColor.rgb *= rcp(OutColor.r*0.299 + OutColor.g*0.587 + OutColor.b*0.114 + 1.0);
    #endif
    }

    Texture2D InputTexture;
    SamplerState InputSampler;

    void MSAADecodeAndCopyRectPS(
    noperspective float4 UVAndScreenPos : TEXCOORD0,
    out half4 OutColor : SV_Target0
    )
    {
    #if (METAL_PROFILE && !MAC)
    float2 UV = UVAndScreenPos.xy;
    OutColor = Texture2DSample(InputTexture, InputSampler, UV);
    OutColor.rgb *= rcp(OutColor.r*(-0.299) + OutColor.g*(-0.587) + OutColor.b*(-0.114) + 1.0);
    #endif
    }

    这段就是encode 和对应的decode了 确实像之前推断的那样在 resolve msaa之前

    encode 4.2-1.8

    4.2/(4.2x0.299+1) = 1.86

    decode

    1.86/(1-1.86x0.299) = 4.196

    x /(1+x) = y encode

    x = y + xy

    x - xy = y

    x(1-y) = y

    x = y/(1-y) decode

    完全理清

    然后  为什么这样做呢

    hdr rgba16float 的rt 里的值可以是特别大比如100 用y = x/(1+x)映射到0-1做msaa 得到的msaa resolve值 更合理 下面是例子

    感谢JIN 

     下来的问题是ue上 ios和android 的实现流程

    ios肯定是上面的流程

    android看上去没encode 也没decode 所以推测如果值很大 锯齿会特别明显 可以测下ue下android windows 和 mac应该都会这样

    MaterialTemplate.ush

    #if POST_PROCESS_MATERIAL
    		MaterialFloat4 Input0 = Texture2DSample(PostProcessInput_0_Texture, PostProcessInput_0_SharedSampler, UV);
    		#if POST_PROCESS_MATERIAL_BEFORE_TONEMAP
    			#if METAL_PROFILE
    				// Decode the input color since the color is encoded for MSAA 
    				// The decode instructions might be able to skip with dynamic branch
    				if (bMetalMSAAHDRDecode)
    				{
    					Input0.rgb = Input0.rgb * rcp(Input0.r*(-0.299) + Input0.g*(-0.587) + Input0.b*(-0.114) + 1.0);
    				}
    			#endif
    		#endif
    		// We need to preserve original SceneColor Alpha as it's used by tonemapper on mobile
    		Parameters.BackupSceneColorAlpha = Input0.a;
    		return Input0;
    #endif// POST_PROCESS_MATERIAL
    

      

  • 相关阅读:
    超值干货:微服务架构下如何解耦,对于已经紧耦合下如何重构?
    程序员收藏不看系列:近三万字总结Spring注解开发!
    干货收藏:6 款能挣钱的 Spring Boot 开源后台管理系统
    美团二面:你向 Mysql 数据库插入 100w 条数据用了多久?
    5分钟快速掌握阿里内部MySQL性能优化的核心技术!
    优秀!一鼓作气学会“一致性哈希”,就靠这 18 张图了
    分库分表神器 Sharding-JDBC,几千万的数据你不搞一下?
    熬夜肝出5大点,18张图带你彻底弄懂MySQL事务日志
    jdk8新特性Stream
    java多线程
  • 原文地址:https://www.cnblogs.com/minggoddess/p/13957809.html
Copyright © 2011-2022 走看看