From 73733776d896cbf9478e770093b54f61c13a4201 Mon Sep 17 00:00:00 2001 From: sergeypdev Date: Wed, 21 Feb 2024 02:58:53 +0400 Subject: [PATCH] Do lighting calculations in view space --- assets/shaders/mesh.glsl | 39 ++++++++++++++++++++++++++------------- src/Render.zig | 29 ++++++++++++++++++++++++++++- src/game.zig | 5 ++++- 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/assets/shaders/mesh.glsl b/assets/shaders/mesh.glsl index dc914f2..39b92c6 100644 --- a/assets/shaders/mesh.glsl +++ b/assets/shaders/mesh.glsl @@ -4,7 +4,7 @@ // Types struct Light { - vec4 pos; + vec4 vPos; vec4 color; }; @@ -21,16 +21,28 @@ layout(std140, binding = 1) uniform Lights { // Uniforms layout(location = 1) uniform mat4 model; + layout(location = 2) uniform vec3 color; layout(location = 3, bindless_sampler) uniform sampler2D albedo_map; + layout(location = 4, bindless_sampler) uniform sampler2D normal_map; +layout(location = 5) uniform float metallic; +layout(location = 6, bindless_sampler) uniform sampler2D metallic_map; + +layout(location = 7) uniform float roughness; +layout(location = 8, bindless_sampler) uniform sampler2D roughness_map; + +layout(location = 9) uniform float emission; +layout(location = 10, bindless_sampler) uniform sampler2D emission_map; + + // Input, output blocks VERTEX_EXPORT VertexData { - vec3 position; + vec3 vPos; vec2 uv; - mat3 TBN; + mat3 vTBN; } VertexOut; #if VERTEX_SHADER @@ -41,15 +53,16 @@ layout(location = 2) in vec2 aUV; layout(location = 3) in vec3 aTangent; void main() { - gl_Position = projection * view * model * vec4(aPos.xyz, 1.0); - vec4 posWorld = model * vec4(aPos, 1.0); - VertexOut.position = posWorld.xyz / posWorld.w; + vec4 vPos = view * model * vec4(aPos.xyz, 1.0); + gl_Position = projection * vPos; + + VertexOut.vPos = vPos.xyz / vPos.w; // I don't think this is needed, but leaving just in case VertexOut.uv = aUV; vec3 aBitangent = cross(aTangent, aNormal); - vec3 T = normalize(vec3(model * vec4(aTangent, 0.0))); - vec3 B = normalize(vec3(model * vec4(aBitangent, 0.0))); - vec3 N = normalize(vec3(model * vec4(aNormal, 0.0))); - VertexOut.TBN = mat3(T, B, N); + vec3 T = normalize(vec3(view * model * vec4(aTangent, 0.0))); + vec3 B = normalize(vec3(view * model * vec4(aBitangent, 0.0))); + vec3 N = normalize(vec3(view * model * vec4(aNormal, 0.0))); + VertexOut.vTBN = mat3(T, B, N); } #endif // VERTEX_SHADER @@ -64,13 +77,13 @@ void main() { N = N * 2.0 - 1.0; N.z = sqrt(clamp(1 - N.x * N.x - N.y * N.y, 0, 1)); N = normalize(N); - N = normalize(VertexOut.TBN * N); + N = normalize(VertexOut.vTBN * N); vec3 finalColor = vec3(0); for (int i = 0; i < lights_count; i++) { - float radius = lights[i].pos.w; - vec3 L = lights[i].pos.xyz - VertexOut.position; + float radius = lights[i].vPos.w; + vec3 L = lights[i].vPos.xyz - VertexOut.vPos; float dist = length(L); float d = max(dist - radius, 0); L /= dist; diff --git a/src/Render.zig b/src/Render.zig index db1448c..13c201b 100644 --- a/src/Render.zig +++ b/src/Render.zig @@ -188,6 +188,21 @@ pub fn draw(self: *Render, cmd: DrawCommand) void { Uniform.NormalMap.value(), self.assetman.resolveTexture(cmd.material.normal_map).handle, ); + gl.uniform1fv(Uniform.Metallic.value(), 1, &cmd.material.metallic); + gl.GL_ARB_bindless_texture.uniformHandleui64ARB( + Uniform.MetallicMap.value(), + self.assetman.resolveTexture(cmd.material.metallic_map).handle, + ); + gl.uniform1fv(Uniform.Roughness.value(), 1, &cmd.material.roughness); + gl.GL_ARB_bindless_texture.uniformHandleui64ARB( + Uniform.RoughnessMap.value(), + self.assetman.resolveTexture(cmd.material.roughness_map).handle, + ); + gl.uniform1fv(Uniform.Emission.value(), 1, &cmd.material.emission); + gl.GL_ARB_bindless_texture.uniformHandleui64ARB( + Uniform.EmissionMap.value(), + self.assetman.resolveTexture(cmd.material.emission_map).handle, + ); const mesh = self.assetman.resolveMesh(cmd.mesh); mesh.positions.bind(Render.Attrib.Position.value()); @@ -265,6 +280,12 @@ pub const Uniform = enum(gl.GLint) { Color = 2, AlbedoMap = 3, NormalMap = 4, + Metallic = 5, + MetallicMap = 6, + Roughness = 7, + RoughnessMap = 8, + Emission = 9, + EmissionMap = 10, pub inline fn value(self: Uniform) gl.GLint { return @intFromEnum(self); @@ -291,7 +312,7 @@ const CameraMatrices = extern struct { view: Mat4, }; pub const PointLight = extern struct { - pos_radius: Vec4, // x, y, z - pos, w - radius + pos_radius: Vec4, // x, y, z - vPos, w - radius color_intensity: Vec4, // x, y, z - color, w - intensity }; @@ -304,4 +325,10 @@ pub const Material = struct { albedo: Vec3 = Vec3.one(), albedo_map: AssetManager.Handle.Texture = .{}, normal_map: AssetManager.Handle.Texture = .{}, + metallic: f32 = 0, + metallic_map: AssetManager.Handle.Texture = .{}, + roughness: f32 = 1, + roughness_map: AssetManager.Handle.Texture = .{}, + emission: f32 = 0, + emission_map: AssetManager.Handle.Texture = .{}, }; diff --git a/src/game.zig b/src/game.zig index 9e55fd1..2a421e9 100644 --- a/src/game.zig +++ b/src/game.zig @@ -346,8 +346,11 @@ export fn game_update() bool { if (ent.flags.point_light) { const pos = ent.transform.pos; + var pos4 = Vec4.new(pos.x(), pos.y(), pos.z(), 1.0); + pos4 = gmem.render.camera.view_mat.mulByVec4(pos4); + point_lights.lights[point_lights.count] = .{ - .pos_radius = Vec4.new(pos.x(), pos.y(), pos.z(), ent.point_light.radius), + .pos_radius = Vec4.new(pos4.x(), pos4.y(), pos4.z(), ent.point_light.radius), .color_intensity = ent.point_light.color_intensity, }; point_lights.count += 1;