March 15, 2023

RGBM-кодировка цвета

Хочется хранить цвета в вершинах как byte4, но значения у них могут быть сильно выше единицы. Следовательно, нужно как-то нормализовать.
Можно просто поделить на условную максимальную яркость и затем умножить в шейдере.
А можно использовать более хитрую кодировку в rgbm. Преимущество rgbm в том, что чем меньше значения цвета, тем меньше разница между оригиналом и декодированным значением, ошибка растет пропорционально яркости.

Кодировка цвета в скрипте

private static float MAX_BRIGHTNESS = 60;
private static Byte4 ColorToRGBM(Color color) {   
    float y = color.maxColorComponent;   
    y = math.clamp(math.ceil(y * 255 / MAX_BRIGHTNESS), 1, 255);   
    color *= 255 * 255 / (y * MAX_BRIGHTNESS);   
    Byte4 i = new Byte4((byte)color.r, (byte)color.g, (byte)color.b, (byte)y);   
    return i;
}

Декодировка в шейдере:

#define MAX_BRIGHTNESS 60
half3 DecodeColor(half4 data) {        
    return data.rgb * data.a * MAX_BRIGHTNESS;
}

https://t.me/lab_sborki