Android 용 OpenGL ES 2.0을 사용하여 지구 모델을 만들고 있습니다. 저는 구를 그립니다. 매번 버텍스 쉐이더에서 회전시키고 싶습니다. 그릴 때마다 회전 각도를 나타내는 유니폼을 설정했습니다.OpenGL 쉐이더에서 구를 회전
Vertex Shader
:
uniform mat4 u_Matrix;
uniform vec3 u_VectorToLight;
uniform vec3 u_Center;
uniform float u_RotationAngle;
attribute vec4 a_Position;
attribute vec2 a_TextureCoordinates;
attribute vec3 a_Normal;
varying vec2 v_TextureCoordinates;
varying vec3 v_VectorToLight;
varying vec3 v_Normal;
vec2 rotate(vec2 c, vec2 p, float a);
void main() {
v_TextureCoordinates = a_TextureCoordinates;
v_VectorToLight = u_VectorToLight;
v_Normal = a_Normal;
vec2 point = rotate(u_Center.xz, a_Position.xz, radians(u_RotationAngle));
gl_Position = a_Position;
gl_Position *= u_Matrix;
gl_Position.x = point.x;
gl_Position.z = point.y;
}
vec2 rotate(vec2 c, vec2 p, float a) {
p.x -= c.x;
p.y -= c.y;
float x1 = p.x * cos(a) - p.y * sin(a);
float y1 = p.x * sin(a) + p.y * cos(a);
p.x = c.x + x1;
p.y = c.y + y1;
return p;
}
Fragment Shader
:
precision mediump float;
uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;
varying vec3 v_VectorToLight;
varying vec3 v_Normal;
void main() {
gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
vec4 color = gl_FragColor.rgba;
vec3 scaledNormal = v_Normal;
scaledNormal = normalize(scaledNormal);
float diffuse = max(dot(scaledNormal, v_VectorToLight), 0.0);
gl_FragColor.rgb *= diffuse;
float ambient = 0.2;
gl_FragColor.rgb += ambient * color;
}
내가 정점에
rotate()
방법을 사용하여, 구의 중심을 각각의 점을 회전 여기에 내가 새로운 점을 계산하는 방법이다 쉐이더를 사용하면 왜곡 된 지구가 생기고 X 축과 Z 축에서는 더 작게 만들어 지지만 Y는 그렇게 만들지 않습니다 (지구의 매우 얇은 버전을 상상해보십시오). 훨씬 더 혼란스러운 점은 매번 회전 각도에 대한 새로운 값을 전달하더라도 여전히 동일한 정지 이미지를 얻는다는 것입니다. 왜곡 된 경우에도 매번 다른 각도를 사용하기 때문에 매번 다른 방식으로 보일 것입니다.
point
이후
vec2 point = rotate(u_Center.xz, a_Position.xz, radians(u_RotationAngle));
gl_Position = a_Position;
gl_Position *= u_Matrix;
gl_Position.x = point.x;
gl_Position.z = point.y;
는 회전을 포함 : 난 당신이 u_Matrix
에 포함 된 글로벌 회전 축을 중심으로 회전을 결합하는 방법에 문제가있는 생각
public void setUniforms(float[] matrix, Vector vectorToLight, int texture, Point center, float angle) {
glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(uTextureUnitLocation, 0);
glUniform3f(uRadiusLocation, center.x, center.y, center.z);
glUniform3f(uVectorToLightLocation, vectorToLight.x, vectorToLight.y, vectorToLight.z);
glUniform1f(uRotationAngleLocation, angle); // <-- I set the rotation angle
}
셰이더 밖에서 변환 행렬을 계산하여 전달하는 것이 더 일반적입니다. 모든 정점에 대해이를 다시 계산하여 저장합니다. – Alan
나는 모든 것을 연구하지는 않았지만 원래 좌표에'u_Matrix'를 적용한 다음 결과 좌표 중 두 좌표를 축 회전으로 만 처리 된 좌표로 바꾼 것처럼 보입니다. 당신이하려는 일을 이해한다면, 먼저 축 회전을 적용한 다음 결과에'u_Matrix'를 적용해야합니다. –