Мягкие, прозрачные текстуры мазка не смешиваются, как я ожидал

Я пытаюсь внедрить мягкие кисти в мое приложение GL 4.5. Я достиг 100% жестких кистей, но функциональность мягких кистей ниже нормы. Этот тип режима рисования, который я пытаюсь реализовать, называется «стирка» в Krita и является нормальным режимом в GIMP.

Например: в фотошопе у меня круглая кисть с низкой твердостью и непрозрачностью кисти на 10% и, удерживая мышь и перетаскивая курсор, я получаю равномерный ход с нарастанием текстуры до непрозрачности 10%, за исключением краев, где она исчезает. Если я нажму еще раз, он увеличится в сторону, скажем, белого на 10% больше из-за добавок (?)

В моем приложении с мягкой текстурой кисти я всегда получаю полосы при движении мыши из-за непрозрачности текстуры. Я пробовал различные режимы смешивания и ограничения непрозрачности после смешивания текущего обводки и текстуры BG, и все они более или менее выглядят следующим образом:

http://i.imgur.com/bZWDhoF.jpg

pPaintStroke_washF полноэкранный четырехъядерный шейдер

#version 450 core
#extension GL_ARB_bindless_texture : require

in Vert
{
vec2 uv;
} v;

layout(bindless_sampler, location = 0) uniform sampler2D blended_64; // blended bg + stroke
layout(location = 0) out vec4 Ci;

uniform vec4 brushRGBA = vec4(1.f, 1.f, 1.f, .001f);

void main()
{
vec4 blended = texture(blended_64, v.uv);

if (blended.a == 0.f)
Ci = vec4(0.f);

else
{
Ci.rgb = brushRGBA.rgb;
Ci.a = clamp(blended.a, 0.f, brushRGBA.a);
// Ci.a = clamp(blended.a, blended.a, brushRGBA.a);
}
}

заявка

glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

for (int i = 0; i < Bresenham.size(); ++i)
{
/*
//bind brushTempN.fbo1
//render Bresenham[i] into it
*/

glBindFramebuffer(GL_FRAMEBUFFER, brushTempN.fbo1);
glViewport(0, 0, brushTempN.width, brushTempN.height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.f, 0.f, 0.f, 0.f);

myWin.myGLWidgetSh->glUseProgram2("pPaintStroke_unwashed");

myWin.paintStroke->s->val_3 = glm::vec3((float)Bresenham[i].size / 100);
myWin.paintStroke->t->val_3 = glm::vec3(Bresenham[i].coord, 0.f);
myWin.paintStroke->mvpGet(myWin.allGL[GLidx]);
myWin.paintStroke->render(myWin.allGL[GLidx]);

/*
//bind brushTempN.fbo2
//render bg - starts as 0 (brushBGN.tex1)
//render curr stroke (brushTempN.tex1)
//this blends them
*/

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glBindFramebuffer(GL_FRAMEBUFFER, brushTempN.fbo2);
glViewport(0, 0, brushTempN.width, brushTempN.height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.f, 0.f, 0.f, 0.f);

myWin.myGLWidgetSh->glUseProgram2("pPaintStroke_washBlend");

washBlendPhase = 0; myWin.myFSQ->render(myWin.allGL[GLidx]); //render BG

washBlendPhase = 1; myWin.myFSQ->render(myWin.allGL[GLidx]); //render the curr stroke (brushTempN.tex1)

/*
//bind brushN.fbo1
//read brushTempN.tex2_64
//clamp the blended alpha with Ci.a = clamp(in.a, 0.f, brushRGBA.a)
*/

glBindFramebuffer(GL_FRAMEBUFFER, brushN.fbo1);
glViewport(0, 0, brushN.width, brushN.height);

myWin.myGLWidgetSh->glUseProgram2("pPaintStroke_wash");
myWin.myFSQ->render(myWin.allGL[GLidx]);

/*
//bind brushBGN.fbo1
//copy the above brushN.tex1 into it
*/

glBindFramebuffer(GL_FRAMEBUFFER, brushBGN.fbo1);
glViewport(0, 0, brushBGN.width, brushBGN.height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.f, 0.f, 0.f, 0.f);

myWin.myGLWidgetSh->glUseProgram2("pPaintStroke_washBlend");

washBlendPhase = 2; myWin.myFSQ->render(myWin.allGL[GLidx]); //render new BG
}

1

Решение

Вы должны также использовать смешивание добавок.

glBlendFunc(GL_SRC_ALPHA, GL_ONE);
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]