【问题标题】:Drawing circles on a sphere在球体上画圆
【发布时间】:2010-11-07 03:15:02
【问题描述】:

我正在尝试使用着色器在球体上绘制很多圆圈。基本算法是这样的:

  1. 计算从片段(使用它的纹理坐标)到圆心位置的距离(圆心也在纹理坐标中指定)
  2. 计算从碎片到圆心的角度。
  3. 根据角度,访问纹理(其中有 360 个像素,红色通道指定半径距离)并检索给定角度的半径
  4. 如果片段到圆心的距离小于检索到的半径,则片段的颜色为红色,否则为蓝色。

我想在蓝色球体上画 60 个红色圆圈。我让 y 着色器为一个圆圈工作,但如何做 60?到目前为止,这是我尝试过的......

  1. 我传入了一个指定给定角度半径的数据纹理,但我注意到伪影蔓延。我相信这是由于我尝试使用以下方法从数据纹理中检索信息时的线性插值:

    float returnV = texture2D(angles, vec2(x, y)).r; 
    

    其中角度是包含给定角度半径的数据纹理 (Sampler2D),x = 角度 / 360.0(角度为 0 到 360)和 y = 0 到 60(y 是圆数)

  2. 我尝试传入一个统一的浮点半径 [360],但我无法通过动态索引访问半径。我什至试过这个烂摊子......

    getArrayValue(int index) {
      if (index == 0) {
        return radii[0];
      }
      else if (index == 1) {
        return radii[1];
      }
    

    等等……

如果我创建一个纹理并将所有圆圈放在该纹理上,然后将蓝色球体与包含圆圈的球体进行多重纹理处理,但正如您所料,我的锯齿非常糟糕。我喜欢根据片段的位置和圆的位置在程序上生成圆的想法,因为几乎没有混叠。但是,我做的不止一个吗?

谢谢!!!

~螺栓

【问题讨论】:

    标签: glsl shader


    【解决方案1】:

    我有一个可以在地形上画圆的着色器。它由鼠标移动。 也许你得到了灵感?

    这是一个片段程序。它不是主程序,但您可以将其添加到您的程序中。 试试这个...

    现在你可以在硬编码中给出一些统一的参数。

    uniform float showCircle;
    uniform float radius;
    uniform vec4 mousePosition;
    
    varying vec3 vertexCoord;
    
    void calculateTerrainCircle(inout vec4 pixelColor)
    {
     if(showCircle == 1)
     {  
        float xDist = vertexCoord.x - mousePosition.x;
        float yDist = vertexCoord.y - mousePosition.y;
    
        float dist = xDist * xDist + yDist * yDist;
        float radius2 = radius * radius;
    
        if (dist < radius2 * 1.44f && dist > radius2 * 0.64f)
        {
            vec4 temp = pixelColor;
    
            float diff;
            if (dist < radius2)
                diff = (radius2 - dist) / (0.36f * radius2);
            else
                diff = (dist - radius2) / (0.44f * radius2);
    
            pixelColor = vec4(1, 0, 0, 1.0) * (1 - diff) + pixelColor * diff;   
    
            pixelColor = mix(pixelColor, temp, diff);
        }               
    }   
    }
    

    并在顶点着色器中添加:

    varying vec3 vertexCoord;
    
    void main()
    {
        gl_Position = ftransform();
    
        vec4 v = vec4(gl_ModelViewMatrix * gl_Vertex);
        vertexCoord = vec3(gl_ModelViewMatrixInverse * v);
    }
    

    【讨论】:

    • 谢谢!我认为它很可能必须在顶点程序中做一些工作。谢谢你的灵感!
    • 我已对此答案添加了评论。 (由于格式和大小限制,它在下面显示为答案)。
    【解决方案2】:

    ufukgun,如果你将一个矩阵乘以它的逆矩阵,你就会得到恒等式。
    你的;

    vec4 v = vec4(gl_ModelViewMatrix * gl_Vertex);
    vertexCoord = vec3(gl_ModelViewMatrixInverse * v);
    

    因此等价于

    vertexCoord = vec3(gl_Vertex);
    

    【讨论】:

    • 实际上您对第一条评论是正确的,即关于 verteCoord = vec3(gl_Vertex);但第二个不是。我使用 dist 作为 dist^2,所以我与 radius^2 进行比较。我不想计算 sqrt,所以我使用了 dist^2。无论如何,你可以改变你所说的功能。 (两者都是真的)
    • 啊,很好。 Ty澄清=)。我看到了我的错误;我将编辑我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多