Что именно происходит с альфа-цветами после смешивания?
Я работаю над тестовым проектом, в котором один большой трехмерный квад пересекается с несколькими другими трехмерными квадратами (повернутыми по-разному). Все четырехугольники имеют прозрачность (от полностью непрозрачной до полностью прозрачной). Маленькие четырехугольники никогда не перекрываются, ну, они могут, но расположение камеры и Z-буфер гарантируют, что только те части, которые могут перекрываться, фактически перекрываются.
Чтобы отобразить это, я сначала отрисовываю большой квад в другом фреймбуфере rgba для последующего поиска. Теперь я начинаю рендеринг на экран. Сначала выполняется рендеринг скайбокса, затем рендеринг небольших квадратов с включенным альфа-смешиванием: GL_SRC_ALHPA и GL_ONE_MINUS_SRC_ALPHA. После этого я снова рендерил большой квад с включенным альфа-смешиванием. Конечно, только пиксели перед квадраторами будут отображаться из-за Z-буфера.
Вот почему в фрагментном шейдере маленьких четырехугольников я делаю трассировку лучей, чтобы найти пересечение с большим четырехугольником. Если точка пересечения находится за маленьким квадратом, я выбираю тексель из первоначально созданного кадрового буфера и смешиваю этот тексель вручную с вычисленным цветом текселя маленького квадрата.
Но результат не тот же: цвета спереди отображаются правильно (GPU обрабатывает смешивание там), цвета позади них "странные". Они светлее или темнее, но я никогда не получу такой же результат. После рассмотрения я думаю, что это должно быть из-за того, что я не излучаю правильное значение альфа-канала из моего шейдера для небольших квадратов, так что выполняемое на GPU смешивание меняет цвета еще больше.
Итак, как именно рассчитывается альфа-значение при смешивании на графическом процессоре при использовании вышеупомянутого метода смешивания. В руководстве по opengl я нахожу: A * Srgba + (1 - A) * Drgba. Когда я получаю этот результат, смешивание не то же самое. Я совершенно уверен, что это потому, что результат снова проходит через смешивание GPU.
Трассировка лучей верна, я в этом уверен.
Итак, что я должен делать с моим ручным смешиванием? Или я должен использовать другой метод, чтобы получить правильный эффект?
Не очень нужно, я верю, но вот код (оптимизация на потом):
vec4 vRayOrg = vec4(0.0, 0.0, 0.0, 1.0);
vec4 vRayDir = vec4(normalize(vBBPosition.xyz), 0.0);
vec4 vPlaneOrg = mView * vec4(0.0, 0.0, 0.0, 1.0);
vec4 vPlaneNormal = mView * vec4(0.0, 1.0, 0.0, 0.0);
float div = dot(vRayDir.xyz, vPlaneNormal.xyz);
float t = dot(vPlaneOrg.xyz - vRayOrg.xyz, vPlaneNormal.xyz) / div;
vec4 pIntersection = vRayOrg + t * vRayDir;
vec3 normal = normalize(vec4(vCoord, 0.0, 0.0)).xyz;
vec3 vLight = normalize(vPosition.xyz / vPosition.w);
float distance = length(vCoord) - 1.0;
float distf = clamp(0.225 - distance, 0.0, 1.0);
float diffuse = clamp(0.25 + dot(-normal, vLight), 0.0, 1.0);
vec4 cOut = diffuse * 9.0 * distf * cGlow;
if (distance > 0.0 && t >= 0.0 && pIntersection.z <= vBBPosition.z)
{
vec2 vTexcoord = (vProjectedPosition.xy / vProjectedPosition.w) * 0.5 + 0.5;
vec4 cLookup = texture(tLookup, vTexcoord);
cOut = cLookup.a * cLookup + (1.0 - cLookup.a) * cOut;
}
vFragColor = cOut;