gpt4 book ai didi

c++ - 使用 OpenGL 风扇而不是根据不同的位置创建圆有什么好处?

转载 作者:太空狗 更新时间:2023-10-29 20:21:14 24 4
gpt4 key购买 nike

我见过的所有 opengl 教程都展示了如何在 OpenGL 中创建一个圆使用“扇形”方法(或一些派生类),我还没有看到有人使用以下方法:

像这样创建一组顶点:

float vertices[] = {
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 1.0f, -1.0f, // bottom right
-0.5f, -0.5f, 0.0f, -1.0f, -1.0f,// bottom left
-0.5f, 0.5f, 0.0f, -1.0f, 1.0f// top left
};

创建以下顶点着色器,将不同格式的边界信息传递给片段着色器:
#version 330 core

in vec3 apos;
in vec2 abound;

out vec3 ourColor;
out vec2 ourBound;

void main() {
gl_Position = vec4(apos, 1.0);
ourBound = abound;
}

创建以下片段着色器,它采用内插边界值来计算当前片段距中心的距离
#version 330 core

in vec2 ourBound;

uniform vec4 setColor;

void main() {
float dist = sqrt((ourBound.x * ourBound.x) + (ourBound.y * ourBound.y));
vec4 color_used = vec4(vec3(1.0), 0.0);
if(dist < 1.0){
color_used = setColor;
}
gl_FragColor = color_used;
}
  • 加载着色器
  • 启用混合
  • 为 apos (offset = 0, stride = 5 * sizeof(float)) 和 abound (offset = 3, stride = 5 * sizeof(float)) 初始化 VBO/EBO 对象
  • 初始化 colorLocation
  • 在 VBA 中存储

  • 在绘制循环加载程序中:
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(shader_program);
    glUniform4f(colorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

    我的结果
    enter image description here

    我不明白创建粉丝的好处。是否有一些性能优势?它当然似乎并不简单。除了这里的解决方案之外,我根本无法通过谷歌找到替代解决方案。

    最佳答案

    I don't understand the benefit for creating a fan instead.



    这是一个教程。教程的目的是教授一些特定的技能,而不一定是展示做某事的最佳方式。教程中重要的不一定是结果,而是实现它的方式。

    创建圆圈的两种方法需要非常不同的技能。顶点方法涉及使用 sin/ cos 来计算圆边缘上的点,以及如何将这些数据上传到缓冲区并使用该缓冲区进行渲染。您的 impostor 方法演示了如何创建 2D impostors,以及如何判断一个点是否在(单位)圆内。

    知道如何做圆内点的人不知道如何使用 sincos 来计算圆上的点。因此,如果您然后继续做球体,您必须教他们有关 sincos 的知识。而如果您之前通过顶点做圆,那么他们领先一步,可以了解球坐标系,作为他们已经知道的扩展。

    此外,顶点方法是一种告诉用户更多顶点可以创建更平滑结果的简单方法。它还可以帮助他们了解这取决于分辨率;离基于顶点的圆越远,顶点的数量就越少。您甚至可以使用它来教人们如何进行动态 LOD,您可以在其中重新计算每一帧的顶点。这涉及将数据流式传输到动态缓冲对象。

    如果您永远不会将动态 LOD 仅用于一个圆圈,这并不重要。重要的是用户已经学会了如何进行缓冲区流。

    这是两种不同的技能。两组都有意义且有用,但它们是不同的。这两种方法都没有本质上的错误。这完全取决于您要教授什么技能。

    It certainly doesn't seem to be simpler.



    这取决于您如何定义“更简单”。如果本教程试图教用户理解三角形渲染,那么基于冒名顶替的方法并不简单。它也没有教授三角形渲染。

    您的方式要求用户对片段级别发生的事情有正式的了解。不要误会我的意思;这是好事。教用户如何制作冒名顶替者是一个非常好的工具。但这是用户在开发过程中准备好学习的工具吗?

    此外,着色器方法更受限制。假设您要向该圆圈添加纹理。使用顶点方法,您可以做正常的事情:将纹理坐标添加到顶点,将它们传递给片段着色器,然后让它从纹理中获取。使用着色器方法,FS 必须发明从纹理到圆的特定映射。

    这意味着任何时候您要更改此映射,都必须更改您的 FS。您可以向 FS 添加一些参数以支持缩放映射的变化,但即使这样也意味着您现在必须分解三角形批次才能更改映射参数。而使用顶点方法,您可以在单个绘制调用中渲染任意数量的风扇(感谢顶点重新启动),只需将映射烘焙到顶点数据中即可。

    事实上,使用顶点方法,您可以为您的圆使用与任何其他形状完全相同的着色器。着色器方法需要改变着色器来渲染不同的东西。

    就个人而言,我认为教程应该比他们更早地教授冒名顶替者的方法。但我不认为圈子冒名顶替者是最好的方法。

    Is there some performance benefit?



    好吧,如果你从抗锯齿的角度来看它。您的基于片段的方法需要特殊编码才能使用多重采样。要正确执行此操作,您需要计算每个样本位置的距离,然后输出与之对应的样本掩码。或者调用每个样本着色。无论哪种方式,这都会慢一点。

    但这将是一个有趣的教训。

    关于c++ - 使用 OpenGL 风扇而不是根据不同的位置创建圆有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45018441/

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