【问题标题】:How to optimize color reduction and dithering如何优化色彩还原和抖动
【发布时间】:2021-04-26 14:26:39
【问题描述】:

我在片段着色器中有以下函数,但它会将 fps 降低 7

half3 ClusterAndDithering(half3 color, half2 uv)
{
    half2 clusters = half2(16, 16);
    
    color.xyz = RgbToHsv(color.xyz);
    color.yz = round(color.yz * clusters);

    half2 centerUV = half2(0, 0);
    centerUV.x = floor(uv.x * _BaseMap_TexelSize.z) / _BaseMap_TexelSize.z;
    centerUV.y = ceil(uv.y * _BaseMap_TexelSize.w) / _BaseMap_TexelSize.w;
    half2 UVDither = fmod(centerUV, _BaseMap_TexelSize.xy * 2) * _BaseMap_TexelSize.zw;
    half Min = min(UVDither.x, UVDither.y);
    half Odd = 1 - fmod(color.z, 2);
    half Val = color.z > clusters / 2 ? 0 : 1;
    half Dither = Min * Odd * Val;
    color.z = (color.z + Dither);
    color.yz /= clusters;
    color = HsvToRgb(color);
    return color;
}

此代码减少了 SV chanel 变体并制作抖动(从 UV 中心制作网格)。 例如这里的最小值结果: 奇怪的: 瓦尔: 没有聚类或抖动: 抖动和聚类: 任何想法如何优化它?

更新: 稍微更改了代码(没有帮助,但看起来更好)。

half3 ClusterAndDithering(half3 color, half2 uv)
{
    half2 clusters = half2(8,8);
        
    color.xyz = RgbToHsv(color.xyz);
    color.yz = round(color.yz * clusters);
    
    half2 centerUV = half2(0, 0);
    centerUV.x = floor(uv.x * _BaseMap_TexelSize.z);
    centerUV.y = ceil(uv.y * _BaseMap_TexelSize.w);
    centerUV = fmod(centerUV, 2);
    half Min = min(centerUV.x, centerUV.y);
    half Odd = 1 - fmod(color.z, 2);
    half Val = color.z > clusters.y / 2 ? 0 : 1;
    half Dither = Min * Odd * Val;
    color.z = (color.z + Dither);
    color.yz /= clusters;
    color = HsvToRgb(color);
    return color;
}

片段函数内部使用:

half4 LitPassFragment(Varyings input) : SV_Target
{
    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

    SurfaceData surfaceData;
    InitializeStandardLitSurfaceData(input.uv, surfaceData);

    InputData inputData;
    InitializeInputData(input, surfaceData.normalTS, inputData);

    half4 color = UniversalFragmentPBR(inputData, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha);
    color.rgb = ClusterAndDithering(color.rgb, input.uv);
    color.rgb = MixFog(color.rgb, inputData.fogCoord);
    return color;
}

【问题讨论】:

  • 我知道它会完全破坏输出,但如果你删除 RgbToHsvHsvToRgb,你会获得多少 fps?我很好奇这些费用是多少,因为在我看来,其余的费用并不特别贵,因为您没有进行任何采样或任何事情……
  • 我在这里看不到任何性能高的代码。也许分享你的完整着色器,你确定着色器是罪魁祸首吗?
  • 我发现大多数加权函数都是计算 Min 并转换为 HSV
  • HSV 大约需要 2-3 fps,Min 函数大约需要 2 fps。
  • 我宁愿担心没有这些的你已经拥有的 14ms,也不愿担心它造成的 2ms ^^

标签: unity3d hlsl fragment-shader


【解决方案1】:

终于找到自定义function 将RGB 转换为HSV,反之亦然。它比 Unity 内置的更快。没有其他方法可以优化该代码,至少您知道如何将值与一个函数相乘和相除。

【讨论】:

    猜你喜欢
    • 2010-09-10
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    相关资源
    最近更新 更多