OpenGL - 在纹理多边形上创建边框

时间:2013-02-26 14:25:27

标签: opengl textures shader cocos2d-x

我正在使用cocos2d-x 2.0.4。我通过这两个图像来说明我想要做的事情。

convex_poly http://img542.imageshack.us/img542/2554/convexpoly.png convex_poly_with_border http://img40.imageshack.us/img40/8007/convexpolywithborder.png

我想要的是以编程方式创建一个模糊的边框或带有渐变的边框。我有两个想法,但我不确定这是否是正确的方法。第一种解决方案是对仅包含模糊颜色的多边形进行三角测量(在这种情况下为带凹孔的凹面多边形),并在其上使用渐变渲染颜色,多边形外侧的顶点将为全α和内部零点上的顶点-α。然后插值将完成渐变的工作。 第二种解决方案是在着色器内部进行。我只需要计算像素的距离和多边形的最近边缘。然后在一定的阈值下,我会根据距离(距离最短,最大的alpha值)影响像素白色,并具有一定的α值。

无论如何,我对openGL的东西很新,我担心第二个解决方案最终会有大的处理时间,因为我必须计算多边形的每个像素的距离。你觉得这个家伙怎么样?这些想法往往会证实我的猜测,或者我对此完全错了吗?

编辑: 我最终选择的解决方案是在多边形中使用每个角度的平分线(易于用3个连续顶点计算),并在该平分线上取一个点,该平分线将成为内部多边形的顶点。然后我采用外部多边形顶点或内部多边形顶点来构建可以适合GL_TRIANGLE_STRIP参数的顶点数组。我把下面的图片更好地理解了。

expl http://img571.imageshack.us/img571/892/convexpolyexplanation.png

2 个答案:

答案 0 :(得分:2)

边框灯光着色器会做你想要的吗? Link to an example

GLSL边框照明着色器的示例代码:

const float rimStart = 0.5f;
const float rimEnd = 1.0f;
const float rimMultiplier = 0.0f;
vec3  rimColor = vec3(1.0f, 1.0f, 1.0f);

float NormalToCam = 1.0 - dot(normalize(outNormal), normalize(camPos - vertexWorldPos.xyz));
float rim = smoothstep(rimStart, rimEnd, NormalToCam) * rimMultiplier;

outColor.rgb += (rimColor * rim);

答案 1 :(得分:1)

为了从3D场景中的任何视点看起来正确,您需要执行一些剪影。这主要涉及使用几何着色器来确定对象的哪些边缘具有面向屏幕的相邻面以及不面向屏幕的相邻面。我相信这可以通过测试一个相邻面法线和相机方向之间的点积是否<= 0而另一个相邻面法线和你的相机方向的点积是> 0来实现。 0

一旦知道了以某个角度勾勒出多边形的所有边,就可以将该边框定义的多边形细分为三角形条(仍然在几何着色器中)。然后,您将每个顶点的颜色传递给片段着色器;其中位于边界上的所有顶点在完整的alpha和非边界点处传递边框颜色时,会传递零alpha的颜色。片段着色器将在中间片段处从边框颜色插入到中心Alpha颜色,为您提供所需的渐变。你的总体方法应该是这样的:

  1. 使用非边框着色器程序绘制对象作为背景颜色。
  2. 启用Alpha混合。

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 
    
  3. 使用剪影程序绘制对象,使用边框颜色确定构成边框的边缘,并将非边界点绘制为零alpha。

  4. glDisable(GL_BLEND);