Add tangents

This commit is contained in:
sergeypdev 2024-02-19 04:12:19 +04:00
parent e764879f17
commit 6e75910bef
5 changed files with 52 additions and 12 deletions

View File

@ -30,6 +30,7 @@ VERTEX_EXPORT VertexData {
vec3 position;
vec3 normal;
vec2 uv;
vec3 tangent;
} VertexOut;
#if VERTEX_SHADER
@ -37,6 +38,7 @@ VERTEX_EXPORT VertexData {
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNorm;
layout(location = 2) in vec2 aUV;
layout(location = 3) in vec3 aTangent;
void main() {
gl_Position = projection * view * model * vec4(aPos.xyz, 1.0);
@ -44,6 +46,7 @@ void main() {
VertexOut.position = posWorld.xyz / posWorld.w;
VertexOut.normal = aNorm;
VertexOut.uv = aUV;
VertexOut.tangent = aTangent;
}
#endif // VERTEX_SHADER

View File

@ -235,6 +235,11 @@ const NullMesh = LoadedMesh{
.offset = 0,
.stride = 0,
},
.tangents = BufferSlice{
.buffer = 0,
.offset = 0,
.stride = 0,
},
.uvs = BufferSlice{
.buffer = 0,
.offset = 0,
@ -265,7 +270,7 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
const data = try self.loadFile(self.frame_arena, path, MESH_MAX_BYTES);
const mesh = formats.Mesh.fromBuffer(data.bytes);
var bufs = [_]gl.GLuint{ 0, 0, 0, 0 };
var bufs = [_]gl.GLuint{ 0, 0, 0, 0, 0 };
gl.createBuffers(bufs.len, &bufs);
errdefer gl.deleteBuffers(bufs.len, &bufs);
@ -273,38 +278,44 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
std.debug.assert(vertices != 0);
const normals = bufs[1];
std.debug.assert(normals != 0);
const uvs = bufs[2];
const tangents = bufs[2];
std.debug.assert(tangents != 0);
const uvs = bufs[3];
std.debug.assert(uvs != 0);
const indices = bufs[3];
const indices = bufs[4];
std.debug.assert(indices != 0);
gl.namedBufferStorage(
vertices,
@intCast(mesh.vertices.len * @sizeOf(formats.Vector3)),
@ptrCast(mesh.vertices),
@ptrCast(mesh.vertices.ptr),
0,
);
gl.namedBufferStorage(
normals,
@intCast(mesh.normals.len * @sizeOf(formats.Vector3)),
@ptrCast(mesh.normals),
@ptrCast(mesh.normals.ptr),
0,
);
gl.namedBufferStorage(
tangents,
@intCast(mesh.tangents.len * @sizeOf(formats.Vector3)),
@ptrCast(mesh.tangents.ptr),
0,
);
gl.namedBufferStorage(
uvs,
@intCast(mesh.uvs.len * @sizeOf(formats.Vector2)),
@ptrCast(mesh.uvs),
@ptrCast(mesh.uvs.ptr),
0,
);
gl.namedBufferStorage(
indices,
@intCast(mesh.indices.len * @sizeOf(formats.Index)),
@ptrCast(mesh.indices),
@ptrCast(mesh.indices.ptr),
0,
);
// gl.bindVertexBuffer(_bindingindex: GLuint, _buffer: GLuint, _offset: GLintptr, _stride: GLsizei)
const loaded_mesh = LoadedMesh{
.aabb = .{
.min = Vec3.new(mesh.aabb.min.x, mesh.aabb.min.y, mesh.aabb.min.z),
@ -320,6 +331,11 @@ fn loadMeshErr(self: *AssetManager, id: AssetId) !*const LoadedMesh {
.offset = 0,
.stride = @sizeOf(formats.Vector3),
},
.tangents = .{
.buffer = tangents,
.offset = 0,
.stride = @sizeOf(formats.Vector3),
},
.uvs = .{
.buffer = uvs,
.offset = 0,
@ -422,6 +438,7 @@ const LoadedMesh = struct {
aabb: AABB,
positions: BufferSlice,
normals: BufferSlice,
tangents: BufferSlice,
uvs: BufferSlice,
indices: IndexSlice,
};
@ -572,7 +589,7 @@ fn unloadAssetWithDependees(self: *AssetManager, id: AssetId) void {
switch (asset.*) {
.mesh => |*mesh| {
gl.deleteBuffers(4, &[_]gl.GLuint{ mesh.positions.buffer, mesh.normals.buffer, mesh.uvs.buffer, mesh.indices.buffer });
gl.deleteBuffers(5, &[_]gl.GLuint{ mesh.positions.buffer, mesh.normals.buffer, mesh.tangents.buffer, mesh.uvs.buffer, mesh.indices.buffer });
},
.shader => |*shader| {
self.allocator.free(shader.source);

View File

@ -51,13 +51,16 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetm
gl.vertexArrayAttribFormat(vao, Attrib.Position.value(), 3, gl.FLOAT, gl.FALSE, 0);
// normals
// gl.vertexArrayVertexBuffer(vao, 1, normals, 0, @sizeOf(formats.Vector3));
gl.enableVertexArrayAttrib(vao, Attrib.Normal.value());
gl.vertexArrayAttribBinding(vao, Attrib.Normal.value(), 1);
gl.vertexArrayAttribFormat(vao, Attrib.Normal.value(), 3, gl.FLOAT, gl.FALSE, 0);
// tangents
gl.enableVertexArrayAttrib(vao, Attrib.Tangent.value());
gl.vertexArrayAttribBinding(vao, Attrib.Tangent.value(), 3);
gl.vertexArrayAttribFormat(vao, Attrib.Tangent.value(), 3, gl.FLOAT, gl.FALSE, 0);
// uvs
// gl.vertexArrayVertexBuffer(vao, 1, normals, 0, @sizeOf(formats.Vector3));
gl.enableVertexArrayAttrib(vao, Attrib.UV.value());
gl.vertexArrayAttribBinding(vao, Attrib.UV.value(), 2);
gl.vertexArrayAttribFormat(vao, Attrib.UV.value(), 2, gl.FLOAT, gl.FALSE, 0);
@ -185,6 +188,7 @@ pub fn draw(self: *Render, cmd: DrawCommand) void {
const mesh = self.assetman.resolveMesh(cmd.mesh);
mesh.positions.bind(Render.Attrib.Position.value());
mesh.normals.bind(Render.Attrib.Normal.value());
mesh.tangents.bind(Render.Attrib.Tangent.value());
mesh.uvs.bind(Render.Attrib.UV.value());
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indices.buffer);
gl.drawElements(
@ -237,6 +241,7 @@ pub const Attrib = enum(gl.GLuint) {
Position = 0,
Normal = 1,
UV = 2,
Tangent = 3,
pub inline fn value(self: Attrib) gl.GLuint {
return @intFromEnum(self);

View File

@ -24,6 +24,7 @@ pub const Mesh = struct {
vertices: []align(1) Vector3,
normals: []align(1) Vector3,
tangents: []align(1) Vector3,
uvs: []align(1) Vector2,
indices: []align(1) Index,
@ -54,6 +55,8 @@ pub const Mesh = struct {
offset += size;
const normals = std.mem.bytesAsSlice(Vector3, buffer[offset .. offset + size]);
offset += size;
const tangents = std.mem.bytesAsSlice(Vector3, buffer[offset .. offset + size]);
offset += size;
size = vert_len * @sizeOf(Vector2);
const uvs = std.mem.bytesAsSlice(Vector2, buffer[offset .. offset + size]);
@ -67,6 +70,7 @@ pub const Mesh = struct {
.aabb = aabb,
.vertices = vertices,
.normals = normals,
.tangents = tangents,
.uvs = uvs,
.indices = indices,
};
@ -92,6 +96,9 @@ pub fn writeMesh(writer: anytype, value: Mesh, endian: std.builtin.Endian) !void
for (value.normals) |n| {
try writeVector3(writer, n, endian);
}
for (value.tangents) |t| {
try writeVector3(writer, t, endian);
}
for (value.uvs) |uv| {
try writeVector2(writer, uv, endian);
}

View File

@ -83,11 +83,13 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
const mesh: *c.aiMesh = @ptrCast(scene.mMeshes[0]);
if (mesh.mNormals == null) return error.MissingNormals;
if (mesh.mTangents == null) return error.MissingTangents;
if (mesh.mTextureCoords[0] == null) return error.MissingUVs;
if (mesh.mNumUVComponents[0] != 2) return error.WrongUVComponents;
var vertices = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices));
var normals = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices));
var tangents = try allocator.alloc(Vector3, @intCast(mesh.mNumVertices));
var uvs = try allocator.alloc(Vector2, @intCast(mesh.mNumVertices));
var indices = try allocator.alloc(formats.Index, @intCast(mesh.mNumFaces * 3)); // triangles
@ -103,6 +105,11 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
.y = mesh.mNormals[i].y,
.z = mesh.mNormals[i].z,
};
tangents[i] = .{
.x = mesh.mTangents[i].x,
.y = mesh.mTangents[i].y,
.z = mesh.mTangents[i].z,
};
uvs[i] = .{
.x = mesh.mTextureCoords[0][i].x,
.y = mesh.mTextureCoords[0][i].y,
@ -136,6 +143,7 @@ fn processMesh(allocator: std.mem.Allocator, input: [*:0]const u8, output: []con
},
.vertices = vertices,
.normals = normals,
.tangents = tangents,
.uvs = uvs,
.indices = indices,
};