Я просто пишу это, чтобы прояснить возможное решение, на которое я пытался намекнуть в приведенном выше комментарии, используя Image Load Store. Во-первых, вам нужно создать новую текстуру того же размера, что и ваша равноугольная текстура (вы можете использовать GL_R8 в качестве внутреннего формата). Вы можете сделать это с помощью glTexImage2D или glTexStorage2D.
Затем вам нужно объявить точку привязки изображения в вашем шейдере и привязать первый уровень изображения маски к этой точке привязки изображения. Затем в шейдере, когда вы производите выборку из исходной цветовой текстуры, вы также собираетесь использовать функцию imageStore()
для записи в текстуру маски в этом месте текселя. Внимание: расположение текселей указано в фактических текселях, а не в части размера текстуры!
Для первого приближения мы просто используем усеченную целочисленную координату вашей исходной позиции выборки (для вашего вызова texture2D). На самом деле, поскольку вы используете GL_LINEAR в качестве функции фильтрации, вы должны вычислить ближайшие 4 текселя и записать их. См. Страницу PDF 150 https://www.khronos.org/registry/OpenGL/specs/gl/glspec13.pdf, чтобы узнать, какой алгоритм использует GL для определения четырех текселей для ЛИНЕЙНОЙ фильтрации.
Итак, части вашего шейдера будут выглядеть так:
#extension GL_ARB_shader_image_load_store : enable
layout(binding = 0, r8) writeonly uniform image2D maskImage;
...
ivec2 texel = ivec2(equirectangularTexturePos * textureSize(tex, 0));
imageStore(maskImage, texel, vec4(1.0, 0.0, 0.0, 0.0));
Чтобы привязать изображение к точке привязки изображения, вы должны использовать это в вашей хост-программе:
glBindImageTexture(0, maskTex, 0, false, 0, GL_WRITE_ONLY, GL_R8);
Также не забудьте очистить текстуру перед запуском шейдера. После того, как шейдер запустил и заполнил доступ к текселям уровня 0 вашей текстуры маски, вам нужно добавить соответствующий барьер синхронизации, чтобы дальнейшие вызовы GL из этой текстуры видели обновленные значения текстуры. Вы делаете это через:
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
Теперь вы можете использовать эту текстуру любым способом и получать ее, например, с помощью другого шейдера.