gpt4 book ai didi

opengl - OpenGL 中的 Gradient "miter"在连接处显示接缝

转载 作者:行者123 更新时间:2023-12-04 11:15:41 27 4
gpt4 key购买 nike

我正在围绕 GL 中的一些 2D 工作做一些非常基本的实验。我正在尝试在矩形区域周围绘制一个“相框”。我希望框架始终具有一致的渐变,因此我使用看起来像四个四边形的几何图形来构建它,框架的每一侧都有一个,逐渐变细以制作梯形,从而有效地进行斜接.

“内部”和“外部”矩形的垂直坐标相同,所有内部和所有外部的颜色也相同,因此我希望在边缘看到完美的混合。

但请注意下图中的连接角处似乎有一条“接缝”,它比应有的颜色浅。

我觉得我在数学上遗漏了一些解释这一点的概念。这个工件是否是梯度斜率的结果?如果我将所有颜色更改为不透明的蓝色(比如说),我会得到一个完美的纯蓝色框架,正如预期的那样。

更新:下面添加了代码。抱歉有点啰嗦。对梯形使用 2-三角形风扇而不是四边形。

谢谢!

alt text

glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

// Prep the color array. This is the same for all trapezoids.
// 4 verts * 4 components/color = 16 values.
GLfloat colors[16];
colors[0] = 0.0;
colors[1] = 0.0;
colors[2] = 1.0;
colors[3] = 1.0;
colors[4] = 0.0;
colors[5] = 0.0;
colors[6] = 1.0;
colors[7] = 1.0;

colors[8] = 1.0;
colors[9] = 1.0;
colors[10] = 1.0;
colors[11] = 1.0;
colors[12] = 1.0;
colors[13] = 1.0;
colors[14] = 1.0;
colors[15] = 1.0;

// Draw the trapezoidal frame areas. Each one is two triangle fans.
// Fan of 2 triangles = 4 verts = 8 values
GLfloat vertices[8];

float insetOffset = 100;
float frameMaxDimension = 1000;

// Bottom
vertices[0] = 0;
vertices[1] = 0;
vertices[2] = frameMaxDimension;
vertices[3] = 0;
vertices[4] = frameMaxDimension - insetOffset;
vertices[5] = 0 + insetOffset;
vertices[6] = 0 + insetOffset;
vertices[7] = 0 + insetOffset;
glVertexPointer(2, GL_FLOAT , 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

// Left
vertices[0] = 0;
vertices[1] = frameMaxDimension;
vertices[2] = 0;
vertices[3] = 0;
vertices[4] = 0 + insetOffset;
vertices[5] = 0 + insetOffset;
vertices[6] = 0 + insetOffset;
vertices[7] = frameMaxDimension - inset;
glVertexPointer(2, GL_FLOAT , 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

/* top & right would be as expected... */

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

最佳答案

正如@Newbie 在评论中发布的那样,

@quixoto: open your image in Paint program, click with fill tool somewhere in the seam, and you see it makes 90 degree angle line there... means theres only 1 color, no brighter anywhere in the "seam". its just an illusion.



真的。虽然我不熟悉 OpenGL 下的这部分数学,但我相信这是三角形顶点之间颜色插值的隐含结果......我很肯定它被称为“双线性插值”。

那么该怎么做才能解决呢?一种可能性是使用纹理并仅绘制带纹理的四边形(或多个带纹理的四边形)。

但是,在 中生成这样的边框应该很容易。片段着色器 .

使用 GLSL 着色器的一个不错的解决方案......

假设您正在绘制一个矩形,其左下角的纹理坐标等于 (0,0),右上角的纹理坐标等于 (1,1)。

然后在片段着色器中以程序方式生成“斜接”看起来像这样,如果我是正确的:
varying vec2 coord;

uniform vec2 insetWidth; // width of the border in %, max would be 0.5

void main() {

vec3 borderColor = vec3(0,0,1);
vec3 backgroundColor = vec3(1,1,1);

// x and y inset, 0..1, 1 means border, 0 means centre

vec2 insets = max(-coord + insetWidth, vec2(0,0)) / insetWidth;

如果到目前为止我是正确的,那么现在每个像素的值 insets.x具有范围内的值 [0..1]
确定给定点水平进入边界的深度,
insets.y具有相似的垂直深度值。

左边的竖条有 insets.y == 0,底部水平栏有 insets.x = 0, ,左下角有一对 (insets.x, insets.y) 覆盖了从 (0,0) 到 (1,1) 的整个二维范围。为清楚起见,请参见图片:

insets

现在我们想要一个转换,对于给定的 (x,y) 对会给我们一个值 [0..1]确定如何混合背景色和前景色。 1 表示 100% 边框,0 表示 0% 边框。这可以通过多种方式完成!

该功能应符合要求:
  • 0 如果 x==0 和 y==0
  • 1 如果 x==1 或 y==1
  • 之间的平滑值。

  • 假设这样的功能:
    float bias = max(insets.x,insets.y);

    它满足这些要求。实际上,我很确定这个函数会给你和上面一样的“锐利”边缘。尝试在纸上计算它以选择左下角矩形内的坐标。

    如果我们想在那里有一个平滑的圆形斜接,我们只需要在这里添加另一个函数。我认为这样的事情就足够了:
    float bias = min( length(insets) , 1 );
    length()这里的功能只是 sqrt(insets.x*insets.x + insets.y*insets.y) .重要的是:这转化为:“我们离边界越远(就欧几里得距离而言),边界应该越明显”,而 min() 只是为了使结果不大于 1 (= 100%)。

    请注意,我们的原始函数遵循完全相同的定义 - 但距离是根据 Chessboard (Chebyshev) 度量计算的,而不是欧几里得度量。

    这意味着使用例如曼哈顿度量,您将拥有第三种可能的斜接形状!它将像这样定义:
    float bias = min(insets.x+insets.y, 1);

    我预测这个也会有一条可见的“对角线”,但对角线会在另一个方向( "\" )。

    好的,对于其余的代码,当我们有偏差 [0..1] 时,我们只需要混合背景色和前景色:
        vec3 finalColor = mix(borderColor, backgroundColor, bias);
    gl_FragColor = vec4(finalColor, 1); // return the calculated RGB, and set alpha to 1
    }

    就是这样!使用 GLSL 和 OpenGL 让生活更简单。希望有帮助!

    关于opengl - OpenGL 中的 Gradient "miter"在连接处显示接缝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4557899/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com