Opengl es 在opengles中绘制球体

Opengl es 在opengles中绘制球体,opengl-es,geometry,opengl-es-2.0,Opengl Es,Geometry,Opengl Es 2.0,我想画一个球体,我知道如何在OpenGL中使用glBegin()和glEnd()等调用来完成 但这里面什么都没有 建议/教程链接?既然您已经用OpenGL ES 2.0为其添加了标签,那么让我建议一种创建平滑球体的替代方法,即将其绘制为光线跟踪的视点替用画。与计算复制平滑球体所需的顶点数量不同,您可以利用球体从任何角度看都几乎相同这一事实 为此,您采用如下流程: 将表示两个三角形的四个顶点发送到顶点着色器,然后顶点着色器将其置换以创建始终面向用户的正方形。在该正方形中,使用片段着色器对每个像素

我想画一个球体,我知道如何在OpenGL中使用glBegin()和glEnd()等调用来完成

但这里面什么都没有


建议/教程链接?

既然您已经用OpenGL ES 2.0为其添加了标签,那么让我建议一种创建平滑球体的替代方法,即将其绘制为光线跟踪的视点替用画。与计算复制平滑球体所需的顶点数量不同,您可以利用球体从任何角度看都几乎相同这一事实

为此,您采用如下流程:

将表示两个三角形的四个顶点发送到顶点着色器,然后顶点着色器将其置换以创建始终面向用户的正方形。在该正方形中,使用片段着色器对每个像素进行光栅化,并提供球体在该点处的颜色(如果通过该正方形窗口查看)

此方法的优点是,球体的平滑度与显示分辨率所支持的一样,并且球体可以轻松地从小到大进行缩放,而无需对几何体进行任何重新计算。它确实将渲染的负担从顶点处理器转移到片段处理器,但对于单个球体,这在我使用的OpenGL ES 2.0设备上并不是什么大问题

我在中使用了这种技术,该页面上提供了该技术的源代码,并对此进行了详细讨论。我使用的顶点着色器的简化版本如下所示:

attribute vec4 position;
attribute vec4 inputImpostorSpaceCoordinate;

varying mediump vec2 impostorSpaceCoordinate;
varying mediump vec3 normalizedViewCoordinate;

uniform mat4 modelViewProjMatrix;
uniform mediump mat4 orthographicMatrix;
uniform mediump float sphereRadius;

void main()
{
    vec4 transformedPosition;
    transformedPosition = modelViewProjMatrix * position;
    impostorSpaceCoordinate = inputImpostorSpaceCoordinate.xy;

    transformedPosition.xy = transformedPosition.xy + inputImpostorSpaceCoordinate.xy * vec2(sphereRadius);
    transformedPosition = transformedPosition * orthographicMatrix;

    normalizedViewCoordinate = (transformedPosition.xyz + 1.0) / 2.0;
    gl_Position = transformedPosition;
}
简化的片段着色器如下所示:

precision mediump float;

uniform vec3 lightPosition;
uniform vec3 sphereColor;
uniform mediump float sphereRadius;

uniform sampler2D depthTexture;

varying mediump vec2 impostorSpaceCoordinate;
varying mediump vec3 normalizedViewCoordinate;

const mediump vec3 oneVector = vec3(1.0, 1.0, 1.0);

void main()
{
    float distanceFromCenter = length(impostorSpaceCoordinate);

    // Establish the visual bounds of the sphere
    if (distanceFromCenter > 1.0)
    {
        discard;
    }

    float normalizedDepth = sqrt(1.0 - distanceFromCenter * distanceFromCenter);

    // Current depth
    float depthOfFragment = sphereRadius * 0.5 * normalizedDepth;
    //        float currentDepthValue = normalizedViewCoordinate.z - depthOfFragment - 0.0025;
    float currentDepthValue = (normalizedViewCoordinate.z - depthOfFragment - 0.0025);

    // Calculate the lighting normal for the sphere
    vec3 normal = vec3(impostorSpaceCoordinate, normalizedDepth);

    vec3 finalSphereColor = sphereColor;

    // ambient
    float lightingIntensity = 0.3 + 0.7 * clamp(dot(lightPosition, normal), 0.0, 1.0);
    finalSphereColor *= lightingIntensity;

    // Per fragment specular lighting
    lightingIntensity  = clamp(dot(lightPosition, normal), 0.0, 1.0);
    lightingIntensity  = pow(lightingIntensity, 60.0);
    finalSphereColor += vec3(0.4, 0.4, 0.4) * lightingIntensity;

    gl_FragColor = vec4(finalSphereColor, 1.0);
}

这些着色器的当前优化版本有点难以遵循,我还使用了环境光遮挡照明,这在这些着色器中是不存在的。还未显示该球体的纹理,可以使用适当的映射函数在球体表面坐标和矩形纹理之间进行转换。这就是我如何为球体表面提供预先计算的环境光遮挡值的方法。

检查这个问题——正如URL上已经说的:我也使用了广告牌;我的关键输入是,为了获得最佳效果,您必须在第二遍中绘制边。在移动到OpenGLES 2/webGL时,我放弃了该技术,因为您无法再设置每个片段的深度:(你的代码中的
正交矩阵是什么?
是一个将正方形变成始终面向用户的矩阵吗?@SzałPał-它旨在纠正渲染视图的非正方形形状。你能解释什么是
inputImpostorSpaceCoordinate
以及片段的
距离中心
如何等于
长度吗(inputImpostorSpaceCoordinate.xy)
;@Nishant-
inputImpostorSpaceCoordinate
是上图中方框四条边上的值。四个顶点被输入其中,每个顶点具有相同的X、Y、Z坐标,但具有四个不同的视点替用符号空间坐标(-1,1)、(1,-1)、(1,1))。视点替用特效空间坐标用于将顶点变换到广告牌中的适当位置。通过获取这些坐标的插值版本的长度,您可以从广告牌的中心获得半径。如果该半径小于某个值,则像素位于您试图绘制的圆内。