Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Webgl 碎片着色器中纹理的边缘/轮廓检测_Webgl_Opengl Es 2.0_Contour_Edge Detection_Outline - Fatal编程技术网

Webgl 碎片着色器中纹理的边缘/轮廓检测

Webgl 碎片着色器中纹理的边缘/轮廓检测,webgl,opengl-es-2.0,contour,edge-detection,outline,Webgl,Opengl Es 2.0,Contour,Edge Detection,Outline,我试图在WebGL中显示纹理的清晰轮廓。 我将纹理传递给片段着色器,然后使用局部导数显示轮廓/轮廓,但是,它并不像我预期的那样平滑 仅打印纹理而不进行预期处理: vec2 texc = vec2(((vProjectedCoords.x / vProjectedCoords.w) + 1.0 ) / 2.0, ((vProjectedCoords.y / vProjectedCoords.w) + 1.0 ) / 2.0 ); vec4 color = texture2D

我试图在WebGL中显示纹理的清晰轮廓。 我将纹理传递给片段着色器,然后使用局部导数显示轮廓/轮廓,但是,它并不像我预期的那样平滑

仅打印纹理而不进行预期处理:

vec2 texc = vec2(((vProjectedCoords.x / vProjectedCoords.w) + 1.0 ) / 2.0,
            ((vProjectedCoords.y / vProjectedCoords.w) + 1.0 ) / 2.0 );
vec4 color = texture2D(uTextureFilled, texc);
gl_FragColor = color;

对于局部导数,它会遗漏一些边:

vec2 texc = vec2(((vProjectedCoords.x / vProjectedCoords.w) + 1.0 ) / 2.0,
            ((vProjectedCoords.y / vProjectedCoords.w) + 1.0 ) / 2.0 );
vec4 color = texture2D(uTextureFilled, texc);
float maxColor = length(color.rgb);
gl_FragColor.r = abs(dFdx(maxColor));
gl_FragColor.g = abs(dFdy(maxColor));
gl_FragColor.a = 1.;

理论上,您的代码是正确的

但在实践中,大多数GPU都在计算2x2像素块上的导数。 因此,对于此类块的所有4个像素,dFdX和dFdY值将相同。 (详细说明)

这将导致某种类型的锯齿,并且您将随机丢失形状轮廓的一些像素(当在2x2块的边界处发生从黑色到形状颜色的过渡时,会发生这种情况)

要解决这一问题,并获得实际的每像素导数,您可以自己计算,如下所示:

// get tex coordinates
vec2 texc = vec2(((vProjectedCoords.x / vProjectedCoords.w) + 1.0 ) / 2.0,
                 ((vProjectedCoords.y / vProjectedCoords.w) + 1.0 ) / 2.0 );

// compute the U & V step needed to read neighbor pixels
// for that you need to pass the texture dimensions to the shader, 
// so let's say those are texWidth and texHeight
float step_u = 1.0 / texWidth;
float step_v = 1.0 / texHeight;

// read current pixel
vec4 centerPixel = texture2D(uTextureFilled, texc);

// read nearest right pixel & nearest bottom pixel
vec4 rightPixel  = texture2D(uTextureFilled, texc + vec2(step_u, 0.0));
vec4 bottomPixel = texture2D(uTextureFilled, texc + vec2(0.0, step_v));

// now manually compute the derivatives
float _dFdX = length(rightPixel - centerPixel) / step_u;
float _dFdY = length(bottomPixel - centerPixel) / step_v;

// display
gl_FragColor.r = _dFdX;
gl_FragColor.g = _dFdY;
gl_FragColor.a = 1.;
一些重要的事情:

  • 纹理不应使用mipmap
  • 纹理最小值和最大值过滤应设置为GL_
  • 纹理夹紧模式应设置为夹紧(不重复)
下面是一个示例,演示了这一点: