在Android的OpenGL ES 2.0中,我正在绘制一个球体。球体在屏幕上显示为圆形,因此我需要添加光照。当我添加灯光时,而不是像现实生活中那样光滑,它是明暗之间的细线,如下所示:
但是,我希望它看起来像这样,阴影更平滑和混合:
这是我的顶点着色器代码:
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;
}
我的片段着色器:
precision mediump float;
varying vec3 v_Color;
void main() {
gl_FragColor = vec4(v_Color, 1.0);
}
通过从球体中心到球体上的点获取矢量,然后将其标准化(给它的长度为1)来计算法线
以下是我设置颜色的方法:
vertices[offset++] = Color.red(color);
vertices[offset++] = Color.green(color);
vertices[offset++] = Color.blue(color);
颜色为0xffea00。
答案 0 :(得分:1)
问题在于您使用的颜色值范围。 OpenGL使用[0.0,1.0]范围内的颜色分量值进行操作。但是您要在Java代码中指定[0,255]范围内的颜色。
您有两种方法可以解决此问题:
Color
类获得的颜色值除以255.0f。指定类型为GL_UNSIGNED_BYTE
的颜色。为此,将值存储在元素类型为byte
的数组/缓冲区中,将这些值存储在VBO中,然后使用以下命令设置顶点属性:
glVertexAttribPointer(attrLoc, 3, GL_UNSIGNED_BYTE, GL_TRUE, stride, 0);
注意第四个参数的值。虽然GL_FLOAT
属性无关紧要,但在这种情况下使用GL_TRUE
至关重要,因为字节值需要规范化。