微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在OpenGL片段着色器中绘制三角形

如何解决在OpenGL片段着色器中绘制三角形

我正在尝试使用OpenGL片段着色器绘制三角形。

我成功绘制了一个圆,但是在处理方程式/逻辑或代码来绘制三角形时遇到了问题。

draw_triangle(vec2 v1,vec2 v2,vec2 v3)

这是片段着色器:

#version 330 core

out vec4 frag_color;

void draw_circle(vec2 shift_val,int radius,int color)
{
    vec2 res = vec2(1280,720);
    vec2 norm_cord = gl_FragCoord.xy;
    float dist = length(norm_cord - (res*shift_val));
    if( dist < radius )
    {
        if( color ==1 )
            frag_color = vec4(1.0,1.0,1.0);
            else
            frag_color = vec4(0.0,0.0,1.0);
    }
}

void draw_triangle(vec2 v1,vec2 v3)
{
    vec2 res = vec2(1280,720)*vec2(0.58,0.4);
    vec2 v = vec2(gl_FragCoord.x,gl_FragCoord.y);

    float slope1 = abs((v1.y-v2.y)/(v1.x-v2.x)); //y2-y1/x2-x1
    float slope2 = abs((v2.y-v3.y)/(v2.x-v3.x)); //y2-y1/x2-x1
    float slope3 = abs((v1.y-v3.y)/(v1.x-v3.x)); //y2-y1/x2-x1

    float slope_ref1 = abs((v.y-v1.y)/(v.x-v1.x)); //y2-y1/x2-x1
    float slope_ref2 = abs((v.y-v2.y)/(v.x-v2.x)); //y2-y1/x2-x1
    float slope_ref3 = abs((v.y-v3.y)/(v.x-v3.x)); //y2-y1/x2-x1

    float slope_RES1 = abs((res.y-v1.y)/(res.x-v1.x)); //y2-y1/x2-x1
    float slope_RES2 = abs((res.y-v2.y)/(res.x-v2.x)); //y2-y1/x2-x1
    float slope_RES3 = abs((res.y-v3.y)/(res.x-v3.x)); //y2-y1/x2-x1

    if (slope_RES1 < slope1 )
    {
        if(slope_ref1 < slope1)// && slope_ref3 < slope2 )//slope_ref1 < slope1 &&
            frag_color = vec4(1.0,1.0);
    }

    if (slope_RES2 > slope2)
        {
            if(slope_ref2 > slope2)
                frag_color = vec4(1.0,0.5,1.0);
        }

    /*if (slope_RES3 < slope3)
        {
            if(slope_ref3 > slope3)
                frag_color = vec4(1.0,1.0);
        }*/
}

// This is entry point of the fragment shader and it will be called for every fragment covered by the rasterized geometry
void main() {
    // Here we just output a constant color which is red (R=1,G=0,B=0,A=1)
    //frag_color = vec4(0.0,1.0);
    draw_circle(vec2(0.5,0.5),100,1); //draws face of circle
    draw_circle(vec2(0.5,0.58),16,0); //draws eye (1 for white and anynumber for black)
    draw_triangle(vec2(0.5f,0.5f),vec2(-0.5,0.0f),vec2(0.5f,-0.5f));
}

解决方法

要使用相同边技术计算点是否在三角形中,您需要针对三条线测试候选点,以查看其在每条线的哪一侧。如果所有三条线都符合 sideness 测试,则它在三角形内。

条件测试将为C(0) && C(1) && C(2)

C(n)的意思是:“该点位于边n的正确边上吗”

通常通过检查AB × AX叉积的符号来检查条件“线AB的哪一侧是点X”。按照惯例,您可以为三角形分配绕线顺序,并始终检查此叉积的符号是否为正。 当然,这取决于三角形顶点的缠绕顺序。 (例如,顺时针的顶点需要一个负的叉积,逆时针的顶点需要一个正的叉积。根据多边形的定义,选择您喜欢的约定或最方便的约定。)

您也可以使用重心技术进行测试。

有关详细信息,请参见:this site

,

希望您正在渲染覆盖视图/屏幕的QUAD ...

片段着色器友好的三角形渲染方式是:

  1. 计算片段的barycentric s,t coordinates

    在GLSL中获得mat3,vec3时开始使用矩阵方法...

  2. 确定它在内部还是外部

    只需测试s+t<=1.0

  3. 然后设置输出颜色或discard;

    但是随着形状的增加,丢弃不是您的选择...

所以计算:

--------------------------------------------------------
| s |           | (p1.a - p0.a),(p2.a - p0.a),p0.a |   | p.a |
| t | = inverse | (p1.b - p0.b),(p2.b - p0.b),p0.b | * | p.b |
| 1 |           |       0,1  |   |  1  |
------------------------------------------------------------------
if (s+t<=1.0) set output color

您也可以使用s,t进行纹理化(甚至是程序化纹理)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。