简体   繁体   English

OpenGL ES球体上的照明不平滑

[英]Lighting on OpenGL ES sphere not smooth

In OpenGL ES 2.0 for Android, I am drawing a sphere. 在适用于Android的OpenGL ES 2.0中,我正在绘制一个球体。 The sphere appears on the screen as a circle, so I need to add lighting. 该球体在屏幕上显示为圆形,因此我需要添加照明。 When I added lighting, instead of it being smooth, like it would be in real life, it is a fine line between light and dark, as shown here: 当我添加照明时,与其像在现实生活中那样不平滑,不如在现实中,它是明暗之间的细线,如下所示:
在此处输入图片说明
However, I want it to look like this, where the shading is much smoother and blended: 但是,我希望它看起来像这样,其中阴影更加平滑和融合:

Here is my vertex shader code: 这是我的顶点着色器代码:

uniform mat4 u_Matrix;
uniform vec3 u_VectorToLight;

attribute vec4 a_Position;
attribute vec3 a_Color;
attribute vec3 a_Normal;

varying vec3 v_Color;

void main() {
  v_Color = a_Color;
  vec3 scaledNormal = a_Normal;
  scaledNormal = normalize(scaledNormal);
  float diffuse = max(dot(scaledNormal, u_VectorToLight), 0.0);
  v_Color *= diffuse;
  float ambient = 0.1;
  v_Color += ambient;
  gl_Position = u_Matrix * a_Position;
}

And my fragment shader: 还有我的片段着色器:

precision mediump float;

varying vec3 v_Color;

void main() {
  gl_FragColor = vec4(v_Color, 1.0);
}

The normal is calculated by getting the vector from the center of the sphere to the point on the sphere, then normalizing it (giving it a length of 1) 通过从球体中心到球体上的点获取向量,然后对其进行归一化(使其长度为1)来计算法线。

Here is how I set the colors: 这是我设置颜色的方法:

vertices[offset++] = Color.red(color);
vertices[offset++] = Color.green(color);
vertices[offset++] = Color.blue(color);

Where color is 0xffea00. 颜色为0xffea00。

The problem is with the range of color values you use. 问题在于您使用的颜色值范围。 OpenGL operates with color component values in the range [0.0, 1.0]. OpenGL使用[0.0,1.0]范围内的颜色分量值进行操作。 But you are specifying colors in the range [0, 255] in your Java code. 但是,您正在Java代码中指定[0,255]范围内的颜色。

You have two options to fix this: 您可以通过以下两种方法解决此问题:

  • Divide the color values you get from the Color class by 255.0f. 用从Color类获得的颜色值除以255.0f。
  • Specify the colors with type GL_UNSIGNED_BYTE . 使用GL_UNSIGNED_BYTE类型指定颜色。 To do this, store the values in an array/buffer with element type byte , store those values in a VBO, and then set up the vertex attribute with: 为此,将值存储在元素类型为byte的数组/缓冲区中,将这些值存储在VBO中,然后使用以下命令设置顶点属性:

     glVertexAttribPointer(attrLoc, 3, GL_UNSIGNED_BYTE, GL_TRUE, stride, 0); 

    Note the value for the 4th argument. 注意第四个参数的值。 While it does not matter for GL_FLOAT attributes, it is critical that you use GL_TRUE in this case, because the byte values need to be normalized. 尽管对于GL_FLOAT属性无关紧要,但在这种情况下使用GL_TRUE是至关重要的,因为需要对字节值进行规范化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM