Do lighting calculations in view space

This commit is contained in:
sergeypdev 2024-02-21 02:58:53 +04:00
parent 1c5b0357a8
commit 73733776d8
3 changed files with 58 additions and 15 deletions

View File

@ -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;

View File

@ -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 = .{},
};

View File

@ -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;