【问题标题】:Calculate point projection in GLSL shader在 GLSL 着色器中计算点投影
【发布时间】:2019-02-23 15:05:16
【问题描述】:

我需要在着色器 (OpenGL ES 2) 中计算特定线段上的点投影。
这是我测试算法的方法:
我用点 A(0, 0.5), B(1, -0.5), C(-1, -0.5) 绘制简单的三角形。
我计算线段 AC 上每个点的投影。
我在蓝色的线段 AC 的中间绘制带有投影的点。其余点为绿色。
我希望得到一个绿色三角形,其蓝线垂直于 AC 侧。但蓝线不垂直于 AC。
我检查了代码中的投影公式并在画布上绘图并得到了预期的结果。
我的错误是什么?

着色器的结果:

顶点着色器:

uniform mat4 matrix;
attribute vec4 position;
varying vec4 vPosition;

void main()
{
    vPosition = matrix * position;
    gl_Position = matrix * position;
}

片段着色器:

precision mediump float;

varying vec4 vPosition;

void main()
{

    vec2 P = vPosition.xy;
    vec2 A = vec2(0.0, 0.5);
    vec2 B = vec2(-1.0, -0.5);
    vec2 AP = P - A;
    vec2 AB = B - A;
    vec2 projection = A + dot(AP, AB) / dot(AB, AB) * AB;

    if(projection.x > -0.51 && projection.x < -0.49 && projection.y > -0.01 && projection.y < 0.01) {
        gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
    } else {
        gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
    }
}

【问题讨论】:

    标签: opengl opengl-es glsl shader


    【解决方案1】:

    您没有考虑窗口的矩形方面。当 [-1, 1] 范围内的标准化设备坐标映射到视口矩形(请参阅glViewport)时,三角形会被拉伸。这会导致无法保持 90 度角。

    uniform variable 添加到包含视口宽度和高度的片段着色器:

    uniform vec2 u_resolution;
    

    计算纵横比:

    float aspect = u_resolution.x / u_resolution.y;
    

    当然你也可以用常数值初始化变量float aspect
    例如float aspect = 16.0/9.0;

    根据纵横比校正点ABP的坐标:

    vec2 P = vPosition.xy;
    vec2 A = vec2(0.0, 0.5);
    vec2 B = vec2(-1.0, -0.5);
    
    A.x *= aspect;
    B.x *= aspect;
    P.x *= aspect;
    

    并在评估结果时考虑纵横比projection

    vec2 projection = A + dot(AP, AB) / dot(AB, AB) * AB;
    projection.x /= aspect;
    

    最终的片段着色器可能如下所示:

    precision mediump float;
    
    varying vec4 vPosition;
    
    uniform vec2 u_resolution;
    
    void main()
    {
        float aspect = u_resolution.x / u_resolution.y;
        vec2  as = vec2(aspect, 1.0);
    
        vec2 P = as * vPosition.xy;
        vec2 A = as * vec2(0.0, 0.5);
        vec2 B = as * vec2(-1.0, -0.5);
    
        vec2 AP = P - A;
        vec2 AB = B - A;
    
        vec2 projection = A + dot(AP, AB) / dot(AB, AB) * AB / as;
    
        if(projection.x > -0.51 && projection.x < -0.49 && projection.y > -0.01 && projection.y < 0.01) {
            gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
        } else {
            gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-25
      • 1970-01-01
      • 2023-04-10
      • 2019-03-09
      • 2013-02-12
      • 2021-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多