当前位置: 首页 > 知识库问答 >
问题:

片段着色器-绘制曲线

羊舌承颜
2023-03-14

如何使用片段着色器绘制一条线或一条曲线?

我有一个程序,根据用户指定的一组顶点计算贝塞尔曲线。在早期,我非常简单,只需在应用程序端处理每个顶点,就可以根据三次贝塞尔曲线方程生成一组插值点:

... 然后将所有处理过的顶点存储到GL_VERTEX_数组中,以便使用glDrawArrays(GL_LINE_STRIP,0,myArraySize)绘制。虽然解决方案很简单,但此实现的时间复杂度为O(n^2)。问题出现在我开始增加步数的地方,比如循环的每次迭代都将t增加0.01,再加上用户生成他们想要的任意多个顶点。

于是我开始研究着色器,尤其是片段着色器。据我所知,我们的片段着色器程序为GPU处理的当前片段指定颜色。我还没有认真研究着色器编程,但我目前的行着色器实现如下:

#version 120

uniform vec2 resolution;
uniform vec2 ptA;
uniform vec2 ptB;
uniform vec2 ptC;
uniform vec2 ptD;
uniform float stepTotal;

void main()
{
    vec2 uv = gl_FragCoord.xy / resolution.xy;
    vec2 curvePts[int(stepTotal)];

    float t = stepTotal;

    for(float i = 0.; i < 1.0; i += 1./t)
    {
        # Courtesy to: https://yalantis.com/blog/how-we-created-visualization-for-horizon-our-open-source-library-for-sound-visualization/
        vec2 q0 = mix(ptA, ptB, i);
        vec2 q1 = mix(ptB, ptC, i);
        vec2 q2 = mix(ptC, ptD, i);

        vec2 r0 = mix(q0, q1, i);
        vec2 r1 = mix(q1, q2, i);

        vec2 p_int = mix(r0, r1, i);
        curvePts[int(i) * int(stepTotal)] = p_int;
    }

    // TO DO:
    // Check if current fragment is within the curve. Not sure how
    // to proceed from here...
}

如你所见,我目前一直在研究如何检查当前片段是否在曲线内,以及如何为特定片段指定颜色,该片段在显示时最终成为曲线。

共有1个答案

单于季
2023-03-14

您可以使用距离函数绘制线段:

float DistanceToLineSegment(vec3 p, vec3 a, vec3 b)
{
    vec3 pa = p - a, ba = b - a;
    float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
    return length( pa - ba*h );
}

如果距离函数的结果小于某个阈值,则片段将在片段的“内部”。

也可以用平滑步长函数代替阈值测试来绘制抗锯齿线。

 类似资料:
  • 片段着色器调用每个需要渲染的像素。我们将开发一个红色透镜,它将会增加图片的红色通道的值。 配置场景(Setting up the scene) 首先我们配置我们的场景,在区域中央使用一个网格显示我们的源图片(source image)。 import QtQuick 2.0 Rectangle { width: 480; height: 240 color: '#1e1e1e'

  • WebGL的着色器代码分为顶点着色器代码和片元着色器代码两部分,顶点着色器代码会在GPU的顶点着色器单元执行,片元着色器代码会在GPU的片元着色器单元执行,在WebGL渲染管线流程中,或者说GPU的渲染流程中,顶点着色器代码先执行处理顶点,得到一系列片元,然后再执行片元着色器代码处理片元。 main()函数 顶点着色器和片元着色器代码都有一个唯一的主函数main(),attribute、varyi

  • 假设我遇到这样的问题:现在我有一个帧缓冲区,一个纹理只包含一个颜色组件(例如,GL_RED)已经绑定到它。碎片着色器会是什么样子?我想答案是: ...浮出ex_color; 颜色=。。。; 我的问题来了:着色器会自动检测帧缓冲区的格式并向其写入值吗?如果片段着色器输出浮点值但帧缓冲区格式GL_RGBA怎么办? 顺便问一下,创建只有一个组件的纹理的正确方法是什么?我阅读了g-truc的示例,其示例如

  • 在一个简单的hello world OpenGL程序中,它只是在窗口上绘制一个静态三角形,当我将三角形的3个顶点设置为红色、绿色和蓝色时,三角形将填充渐变。 但是当我使用这样的着色器时: 顶点着色器: 其中属性和来自顶点缓冲区,通过的调用传递。 片段着色器: 三角形仍然充满了梯度,问题来了: 如果顶点着色器是按顶点计算的,则应为的每个实例指定顶点的颜色。顶点颜色应为红色、绿色或蓝色,如顶点缓冲区中

  • 我对OpenGL有点生疏,我已经实现了一个场景的照明,场景中有小行星围绕行星旋转的实例。出于某种原因,我得到的唯一输出似乎是场景的环境照明。我无法使漫反射或镜面反射工作。 这是现场的一张照片(很难看到…)仅限环境 片段着色器代码如下所示。FragPos、Normal和TexCoords都是你所期待的。纹理_diffuse1是行星/小行星纹理,具体取决于使用的着色器。LightPos可以移动,它由图