Я попытался сделать что-то, что работает с нормалями от лиц, я не знаю, работает ли оно, и я получаю плавное затенение на моей модели.LWJGL на лицевое освещение
Кажется, что он отлично работает как квадроцикл, но когда я попробовал куб, он отображал только 1 квад сверху, который становится случайным, гладким, а все остальное черным. Если я выключу освещение, он отображает только 1 квад, который находится наверху.
Класс Модель:
public class Model {
private int vbo, ibo, vao, tbo, nbo;
private int count = 0;
private float[] normal;
private Matrix4f modelMatrix;
private Vector3f position, rotation;
private Texture texture;
private boolean hasTexture = false;
private String matrixName;
public Model(float[] vertices, String matrixName, int[] ... indices) {
if (!initialized) {
log.err("JORL not initialized", "Run 'init()' at the start of your program");
System.exit(1);
}
this.matrixName = matrixName;
vao = glGenVertexArrays();
vbo = glGenBuffers();
ibo = glGenBuffers();
nbo = glGenBuffers();
for (int[] face : indices)
count += face.length;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
for (int[] face : indices)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, put(face), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, put(vertices), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
normal = new float[count];
int current = 0;
for (int[] face : indices) {
Vector3f p1 = new Vector3f(vertices[face[0] * 3], vertices[face[0] * 3 + 1], vertices[face[0] * 3 + 2]);
Vector3f p2 = new Vector3f(vertices[face[1] * 3], vertices[face[1] * 3 + 1], vertices[face[1] * 3 + 2]);
Vector3f p3 = new Vector3f(vertices[face[2] * 3], vertices[face[2] * 3 + 1], vertices[face[2] * 3 + 2]);
log.info(p1.toString());
log.info(p2.toString());
log.info(p3.toString());
Vector3f U = p2;
Vector3f V = p3;
U.sub(p1);
V.sub(p1);
normal[current * 3] = (U.y * V.z) - (U.z * V.y);
normal[current * 3 + 1] = (U.z * V.x) - (U.x * V.z);
normal[current * 3 + 2] = (U.x * V.y) - (U.y * V.x);
System.out.println(normal[current * 3]);
System.out.println(normal[current * 3 + 1]);
System.out.println(normal[current * 3 + 2]);
current++;
}
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, nbo);
glBufferData(GL_ARRAY_BUFFER, put(normal), GL_STATIC_DRAW);
glVertexAttribPointer(2, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
modelMatrix = new Matrix4f();
position = new Vector3f(0, 0, 0);
rotation = new Vector3f(0, 0, 0);
}
public void setTexture(ShaderProgram shader, Texture texture, float[] coords) {
this.texture = texture;
hasTexture = true;
shader.bind();
shader.editUniform(1, "has_texture");
shader.editUniform(texture.getSampler(), "tex");
shader.bind();
tbo = glGenBuffers();
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, tbo);
glBufferData(GL_ARRAY_BUFFER, put(coords), GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
private FloatBuffer put(float[] data) {
FloatBuffer pData = BufferUtils.createFloatBuffer(data.length);
pData.put(data).flip();
return pData;
}
private IntBuffer put(int[] data) {
IntBuffer pData = BufferUtils.createIntBuffer(data.length);
pData.put(data).flip();
return pData;
}
public void increaseX(float increase) { position.x += increase; }
public void increaseY(float increase) { position.y += increase; }
public void increaseZ(float increase) { position.z += increase; }
public void increaseRotX(float increase) { rotation.x += increase; }
public void increaseRotY(float increase) { rotation.y += increase; }
public void increaseRotZ(float increase) { rotation.z += increase; }
public void render(ShaderProgram shader) {
modelMatrix.identity();
modelMatrix.translate(position);
modelMatrix.rotateX((float) Math.toRadians(rotation.x));
modelMatrix.rotateY((float) Math.toRadians(rotation.y));
modelMatrix.rotateZ((float) Math.toRadians(rotation.z));
shader.editUniform(modelMatrix, matrixName);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
if (hasTexture) {
glEnableVertexAttribArray(1);
texture.bind();
}
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(0);
if (hasTexture) {
glDisableVertexAttribArray(1);
texture.unbind();
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
public void delete() {
glDeleteBuffers(vbo);
glDeleteBuffers(ibo);
glDeleteBuffers(nbo);
if (hasTexture) {
glDeleteBuffers(tbo);
texture.delete();
}
glDeleteVertexArrays(vao);
}
}
У меня есть легкий класс, который просто выводит цвет и положение вектора к шейдера. Камера работает нормально, и все остальное прекрасно работает, если я не использую освещение. (кроме более одного лица).
геометрия шейдеров:
#version 400
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in vec4 colour[];
in vec2 pass_tex_coords[];
in vec3 pass_normal[];
out vec3 t_normal;
out vec3 t_light;
out vec2 pass_tex_coords_;
out vec4 pass_colour;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform vec3 light_position;
void main(void) {
for (int i = 0; i < gl_in.length(); i++) {
vec4 world_pos = projection * view * model * gl_in[i].gl_Position;
gl_Position = world_pos;
pass_tex_coords_ = pass_tex_coords[i];
pass_colour = colour[i];
t_normal = (view * model * vec4(pass_normal[i], 0)).xyz;
t_light = (view * vec4(light_position, 1)).xyz;
EmitVertex();
}
EndPrimitive();
}
пиксельный шейдер:
#version 400
in vec4 pass_colour;
in vec2 pass_tex_coords_;
in vec3 t_normal;
in vec3 t_light;
out vec4 out_colour;
uniform int has_texture;
uniform sampler2D tex;
uniform vec4 light_colour;
void main(void) {
vec3 n_normal = normalize(t_normal);
vec3 n_light = normalize(t_light);
float cosTheta = dot(n_normal, n_light);
if (has_texture != 1) {
out_colour = texture(tex, pass_tex_coords_) * pass_colour * cosTheta;
} else {
out_colour = pass_colour;
}
}
Если кто имеет какие-либо ссылки на на лицо освещение, которое было бы здорово, я не смог найти. Я действительно думаю, что это имеет какое-то отношение к моему грязному классу модели с параметром индексов.
EDIT Все лица визуализируют сейчас, теперь как я могу исправить странное плавное освещение градиента, чтобы быть плоским освещением на лице?
Хорошо спасибо, теперь он отображает весь куб. Но как насчет освещения? Он проявляет себя как плавный градиент, но его просто массивный беспорядок. Кажется, только 2 лица подвержены влиянию света, а лица, затронутые, просто делают какую-то сумасшедшую вещь –