WebGL: неожиданные эффекты в холсте при установке альфа ниже 1.0 [duplicate]

Большинство ответов здесь затрагивают этот вопрос в очень сухих технических терминах. Я хотел бы остановиться на этом в терминах, которые могут понять обычные люди.

Представьте, что вы пытаетесь нарезать пиццу. У вас есть роботизированный резак для пиццы, который может разрезать кусочки пиццы ровно пополам. Он может вдвое сократить целую пиццу, или он может сократить вдвое существующий кусочек, но в любом случае половина всегда точна.

У этого резца пиццы очень хорошие движения, и если вы начнете с целой пиццы, затем уменьшите вдвое и продолжайте вдвое уменьшать наименьший срез каждый раз, вы можете сделать половину 53 раза , прежде чем срез слишком мал для даже его высокоточных способностей. В этот момент вы уже не можете вдвое уменьшить этот тонкий срез, но должны либо включать, либо исключать его, как есть.

Теперь, как бы вы отделили все срезы таким образом, чтобы добавить один (0,1) или одну пятую (0,2) пиццы? На самом деле подумайте об этом и попробуйте разобраться. Вы даже можете попытаться использовать настоящую пиццу, если у вас есть мифическая пресса для резки пиццы под рукой. : -)


Большинство опытных программистов, конечно же, знают реальный ответ, который заключается в том, что нет возможности собрать кусок точной десятой или пятой пиццы используя эти срезы, независимо от того, насколько мелко вы их нарезаете. Вы можете сделать довольно хорошее приближение, и если вы добавите аппроксимацию 0,1 с аппроксимацией 0,2, вы получите довольно хорошее приближение 0,3, но это все равно именно это, приближение.

Для двойного -оценки (это точность, которая позволяет вам вдвое сократить вашу пиццу 53 раза), цифры сразу меньше и больше 0,1 - 0.09999999999999999167332731531132594682276248931884765625 и 0,1000000000000000055511151231257827021181583404541015625. Последнее немного ближе к 0,1, чем первое, поэтому числовой синтаксический анализатор, учитывая ввод 0,1, благоприятствует последнему.

(Разница между этими двумя числами - это «самый маленький срез», который мы должны решить либо включить, что вводит восходящее смещение, либо исключить, что приводит к смещению вниз. Техническим термином для этого наименьшего среза является ulp .)

В случай 0,2, числа все одинаковы, просто увеличиваются в 2 раза. Опять же, мы одобряем значение, которое немного выше 0,2.

Обратите внимание, что в обоих случаях приближения для 0,1 и 0.2 имеют небольшое смещение вверх. Если мы добавим достаточно этих предубеждений, они будут толкать число дальше и дальше от того, что мы хотим, а на самом деле, в случае 0,1 + 0,2, смещение достаточно велико, чтобы получившееся число больше не было самым близким числом до 0,3.

в частности, 0,1 + 0,2 действительно 0.1000000000000000055511151231257827021181583404541015625 + 0.200000000000000011102230246251565404236316680908203125 = 0.3000000000000000444089209850062616169452667236328125, тогда как число ближе к 0,3 фактически 0,299999999999999988897769753748434595763683319091796875.

П.С. Некоторые языки программирования также предоставляют резаки для пиццы, которые могут разделять фрагменты на точные десятки . Хотя такие резаки для пиццы необычны, если у вас есть доступ к одному, вы должны использовать его, когда важно получить ровно одну десятую или одну пятую части среза.

( Первоначально опубликовано на Quora.)

ч>

7
задан shoosh 12 February 2016 в 22:14
поделиться

1 ответ

Вы установили, что холст не имеет большого значения?

gl = someCanvas.getContext("webgl", { premultipliedAlpha: false });

Значение по умолчанию для WebGL равно true. По умолчанию для большинства приложений OpenGL установлено значение false

В дополнение к этому WebGL компонуется с остальной частью страницы. Как минимум, это цвет фона холста или того, что внутри (тело вашего документа).

Чтобы убедиться, что это проблема, попробуйте установить цвет фона вашего холста на фиолетовый или что-то, что будет торчать

<canvas ... style="background-color: #F0F;"></canvas>

или в css

canvas { background-color: #F0F; }

Приложения OpenGL редко компонуются над чем-либо, где приложения WebGL эффективно компонуются ВСЕГДА.

Некоторые решения

  • Отключить альфа Если вам не нужна альфа в вашем пункте назначения, вы может отключить его
    gl = someCanvas.getContext("webgl", { alpha: false });
    
    Теперь альфа будет эффективно 1
  • Установите альфа-1 в конце кадра
    // clear only the alpha channel to 1
    gl.clearColor(1, 1, 1, 1);
    gl.colorMask(false, false, false, true);
    gl.clear(gl.COLOR_BUFFER_BIT);
    
    , не забудьте установить цветовую маску обратно ко всем true, если вы необходимо очистить цветной буфер позже
  • Установить цвет фона фона для черного
    canvas { background-color: #000; }
    

Если возможно, я бы выбрал отключение альфа. Причина, по которой альфа отключена, позволяет браузеру отключить смешение при рисовании холста в браузере. Это может быть увеличение скорости на 10-20% или более в зависимости от графического процессора. Нет никакой гарантии, что любой браузер сделает эту оптимизацию, только это можно сделать, тогда как с другими 2 решениями это невозможно или, по крайней мере, гораздо менее вероятно

11
ответ дан gman 28 August 2018 в 00:38
поделиться