WebGL (2.0) смешивание холста с HTML в линейном цветовом пространстве - PullRequest
2 голосов
/ 12 февраля 2020

Описание проблемы

Привет! Я создаю рендерер векторных фигур WebGL 2.0 и столкнулся с серьезной проблемой, которую не знаю, как ее решить. Мой текущий конвейер рендеринга выглядит следующим образом:

  1. Я рисую фигуры в своих шейдерах предварительно умноженными цветами в линейном пространстве RGB.
  2. Когда две фигуры перекрываются, я смешиваю их (либо в шейдерах или в проходах рендера), используя blendEquationSeparate(FUNC_ADD,FUNC_ADD); blendFuncSeparate(ONE,ONE_MINUS_SRC_ALPHA,ONE,ONE_MINUS_SRC_ALPHA );. См. Ссылку, чтобы узнать, почему: http://www.realtimerendering.com/blog/gpus-prefer-premultiplication
  3. После того, как все фигуры нарисованы, цвета конечного буфера не умножаются, преобразуются в пространство sRGB и снова умножаются. Это приводит к предварительно умноженному цветовому пространству sRGB, которое браузер хочет для меня (насколько я знаю).

Однако, кажется, что браузер вместо этого выполняет альфа-смешение в пространстве sRGB ( не линейный). Это дает очень странные результаты, особенно на больших прозрачных участках (которые мне нужны). Чтобы ясно увидеть проблему, рассмотрите скриншот ниже:

enter image description here

Здесь вы видите красный кружок на 2 зеленых фонах . Зеленый фон в правой части изображения - это фон, составленный в моих шейдерах в линейном пространстве sRGB. Фон на левой стороне картинки - просто веб-сайт HTML. Как видите, у меня правильное смешение цветов (нет темных переходных пикселей). Подробнее о том, почему смешивание в линейном пространстве является правильным, можно найти здесь: http://www.realtimerendering.com/blog/?s=srgb

Вот более убедительный пример - это тень. Верхняя часть изображения составлена ​​в линейном RGB (правильный путь), нижняя часть составлена ​​Chrome в пространстве sRGB (неправильный путь):

enter image description here

К сожалению, похоже, что браузер composer работает в пространстве sRGB. Даже если мы сделаем 2 деления, они смешаны неправильно

.circle{
    position:absolute;
    background:#ff0000;
    width:100px;
    height:100px;
    text-align:center;    
    -webkit-border-radius: 50px;  
    -moz-border-radius: 50px;  
    border-radius: 50px;
}


.circle2{
    position:absolute;
    margin-left:40px;
    background:#00ff00;
    width:100px;
    height:100px;
    text-align:center;    
    -webkit-border-radius: 50px;  
    -moz-border-radius: 50px;  
    border-radius: 50px;
}
<div class="circle"> </div>
<div class="circle2"> </div> 

Вопрос

Вопрос прост - можем ли мы как-то спросить браузер (я спрашиваю и о кросс-браузерном тоже как решение для браузера c) для смешивания холста WebGL с HTML на заднем плане в линейном пространстве RGB?

...