OpenGL着色器 - 使用Frei-Chen边缘检测器进行边缘检测

时间:2016-05-07 15:23:08

标签: opengl glsl shader

我尝试创建一个着色器,将所有边缘涂成黑色,如cel shading所知。我搜索了很多,发现很多文章和源代码如何创建黑色轮廓。不幸的是,我不了解其中的大多数:

  • 我找到了关于功能边缘渲染的article,并尝试了this。不幸的是,只有轮廓是黑色的,而不是网格中的边缘。同样重要的是this article
  • 然后我找到了this关于Frei-Chen边缘探测器的文章,但我不知道整个事情是如何工作的,即使在研究了很长时间的描述之后。

有人可以给我一些帮助,如何编写这样的着色器吗?

编辑:我没有为我的网格使用纹理。

由于我得到了一些过于苛刻的暗示,我想参考Frei-Chen Edge探测器。这是来自Rastergrid的片段着色器代码:

MainLayout

我跳过了G [9]矩阵,因为这会过多地破坏代码。 所以如果有人能告诉我如何分配

,我会非常感激
#version 330 core

uniform sampler2D image;

out vec4 color;

void main(void)
 {
mat3 I;
float cnv[9];
vec3 sample;

/* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */
for (int i=0; i<3; i++)
for (int j=0; j<3; j++) {
    sample = texelFetch( image, ivec2(gl_FragCoord) + ivec2(i-1,j-1), 0 ).rgb;
    I[i][j] = length(sample); 
}

/* calculate the convolution values for all the masks */
for (int i=0; i<9; i++) {
    float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);
    cnv[i] = dp3 * dp3; 
}

float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);
float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M); 

color = vec4(sqrt(M/S));
}

应该工作,因为sqrt(M / S)将单个浮点数返回到vec4()?谢谢!

1 个答案:

答案 0 :(得分:1)

如果您阅读GLSL规范,将对此进行讨论。使用单个标量构造vec4构造vec4,并将每个组件设置为标量。

  

5.4.2向量和矩阵构造函数

     
    

构造函数可用于从一组标量,向量或矩阵创建向量或矩阵。这包括缩短载体的能力。

         

如果向量构造函数有一个标量参数,它用于将构造向量的所有组件初始化为该标量的值

  

这是多么有用,我不能说。跨图像的多个通道复制数据是对内存带宽的一大浪费......