如何使用MVP在OpenGL中绘制椭圆

oti科

如何绘制圆/椭圆并使用“模型-视图-投影”进行变换。

我用绘制一个矩形的椭圆glDrawElements(GL_TRIANGLES, ...)

我制作了一个着色器,它可以工作,但是如何对其进行转换?

顶点着色器

#version 330 core

layout (location = 0) in vec2 position;

void main()
{
    gl_Position = vec4(position, 0.0, 1.0);
}

片段着色器

#version 400 core

uniform mat4 u_mvp;
uniform vec2 u_resolution;
out vec4 color;

float pow2(float x) { return x * x; }

void main()
{
    vec2 d = (gl_FragCoord.xy / u_resolution.xy) * 2 - vec2(1.0);
    vec4 pos = vec4(d, 0.0, 0.0);
    vec4 center = vec4(0.0);

    float r = distance(pos, center);
    r = step(0.5, r);
    color = vec4(0.7f, 0.8f, 0.1f, 1.0f - r);
} 

如何添加MVP支持?

拉比德76

有多种选择,可以实现您想要的。它们的基础是创建一个与射线和球面相交的函数。
以下算法摘自Peter Shirley的一个周末中的光线追踪》一
射线由origin定义direction球体由一个center点和一个定义radius

float hit_sphere(vec3 origin, vec3 direction, vec3 center, float radius)
{
    vec3 oc = origin - center;
    float a = dot(direction, direction);
    float b = 2.0 * dot(oc, direction);
    float c = dot(oc, oc) - radius*radius;
    float discriminant = b*b - 4*a*c;

    if (discriminant > 0.0)
    {
        float temp = (-b - sqrt(discriminant)) / (2*a);
        if (temp > 0.0)
            return 1.0;
        temp = (-b + sqrt(discriminant)) / (2*a);
        if (temp > 0.0)
            return 1.0;
    }
    return 0.0;
}

计算射线上的2点。标准化设备空间中具有xy坐标的每个点都在同一条xy = gl_FragCoord.xy / u_resolution.xy * 2.0 - 1.0射线上。vec4(xy, -1.0, 1.0)在近平面上,vec4(xy, 1.0, 1.0)并且在远平面上。通过inverse模型视图投影矩阵(u_mvp变换这些点,然后将这些xyz分量除以该分量,w以在笛卡尔坐标系的模型空间中获得射线。
调整算法的大小可以计算射线上的2个点,这适用于透视投影和正交投影。

vec4 pn = inverse(u_mvp) * vec4(xy, -1.0, 1.0);
vec4 pf = inverse(u_mvp) * vec4(xy, 1.0, 1.0);

vec3 orig = pn.xyz/pn.w;
vec3 dir  = pf.xyz/pf.w - orig;

使用射线在模型空间中相交球体:

vec3  center = vec3(0.0);
float radius = 1.0;
float r = hit_sphere(orig, dir, center, radius);

我已经用视图矩阵glm::translate(glm::mat4(1), glm::vec3(0, 0, -3))和投影矩阵测试了算法glm::perspective(glm::radians(90), aspect, 0.1, 10.0)

片段着色器:

#version 330 core

out vec4 frag_color;

uniform mat4 u_mvp; 
uniform vec2 u_resolution;

float hit_sphere(vec3 origin, vec3 direction, vec3 center, float radius)
{
    vec3 oc = origin - center;
    float a = dot(direction, direction);
    float b = 2.0 * dot(oc, direction);
    float c = dot(oc, oc) - radius*radius;
    float discriminant = b*b - 4*a*c;

    if (discriminant > 0.0)
    {
        float temp = (-b - sqrt(discriminant)) / (2*a);
        if (temp > 0.0)
            return 1.0;
        temp = (-b + sqrt(discriminant)) / (2*a);
        if (temp > 0.0)
            return 1.0;
    }
    return 0.0;
}

void main()
{
    vec2 xy = gl_FragCoord.xy / u_resolution.xy * 2.0 - 1.0;

    vec4 pn = inverse(u_mvp) * vec4(xy, -1.0, 1.0);
    vec4 pf = inverse(u_mvp) * vec4(xy, 1.0, 1.0);

    vec3 orig = pn.xyz/pn.w;
    vec3 dir  = pf.xyz/pf.w - orig;

    vec3  center = vec3(0.0);
    float radius = 1.0;
    float r = hit_sphere(orig, dir, center, radius);

    vec4 backcolor = vec4(0.2, 0.3, 0.3, 1.0);
    vec4 color = vec4(0.7, 0.8, 0.1, 1.0);

    frag_color = mix(backcolor, color, r);
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Python中绘制半椭圆?

来自分类Dev

如何使用Fabricjs自由绘制椭圆?

来自分类Dev

如何使用Pygame绘制旋转的椭圆?

来自分类Dev

如何使用Fabricjs自由绘制椭圆?

来自分类Dev

如何使用Matlab绘制椭圆体

来自分类Dev

使用UIBezierPath在Swift中绘制椭圆

来自分类Dev

如何绘制椭圆轴

来自分类Dev

如何使用多边形在opengl中建模椭圆体

来自分类Dev

如何在 Highchart 图上绘制椭圆(椭圆)

来自分类Dev

opengl绘制椭圆形而不是圆形

来自分类Dev

如何检测鼠标在pyside中绘制的椭圆上单击?

来自分类Dev

如何在JLabel中绘制椭圆形图像

来自分类Dev

如何在Maxima CAS中绘制旋转椭圆?

来自分类Dev

如何检测在pyside中绘制的椭圆上的鼠标单击?

来自分类Dev

如何在图像中的对象周围绘制椭圆形

来自分类Dev

如何在JLabel中绘制椭圆形图像

来自分类Dev

如何以一定角度使用UIBezierPath绘制椭圆?

来自分类Dev

如何在不使用Canvas的图像控件上绘制椭圆?

来自分类Dev

在Python中绘制椭圆形轨道(使用numpy,matplotlib)

来自分类Dev

如何在乌龟图形(python)中绘制椭圆/椭圆形?

来自分类Dev

如何在Python中根据椭圆的一般方程式绘制椭圆

来自分类Dev

如何在乌龟图形(python)中绘制椭圆/椭圆形?

来自分类Dev

如何使用opengl在pyglet中批量绘制图元?

来自分类Dev

如何使用XCODE中的VBO使OpenGL绘制某些内容?

来自分类Dev

如何使用glew在Qt 5.7中绘制OpenGL几何

来自分类Dev

在SageMath中绘制椭圆曲线

来自分类Dev

在java中绘制多个椭圆

来自分类Dev

无法在java中绘制椭圆

来自分类Dev

使用drawOval()方法绘制椭圆

Related 相关文章

热门标签

归档