Switch to using [0, 1] depth in NDC like DirectX and Vulkan
This commit is contained in:
parent
83b9d64235
commit
2e8ae535a8
@ -220,7 +220,8 @@ vec3 microfacetModel(Material mat, int light_idx, Light light, vec3 P, vec3 N) {
|
|||||||
vec4 shadow_pos = light.shadow_vp * vec4(VertexOut.wPos, 1.0);
|
vec4 shadow_pos = light.shadow_vp * vec4(VertexOut.wPos, 1.0);
|
||||||
shadow_pos.xy = (light.shadow_vp * (vec4(VertexOut.wPos, 1.0) + shadow_offset)).xy;
|
shadow_pos.xy = (light.shadow_vp * (vec4(VertexOut.wPos, 1.0) + shadow_offset)).xy;
|
||||||
shadow_pos /= shadow_pos.w;
|
shadow_pos /= shadow_pos.w;
|
||||||
shadow_pos.xyz = shadow_pos.xyz * 0.5 + 0.5; // [-1, 1] to [0, 1]
|
shadow_pos.xy = shadow_pos.xy * 0.5 + 0.5; // [-1, 1] to [0, 1]
|
||||||
|
shadow_pos.z = min(shadow_pos.z, 1);
|
||||||
shadow_pos.z -= constant_bias;
|
shadow_pos.z -= constant_bias;
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +53,8 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetm
|
|||||||
.assetman = assetman,
|
.assetman = assetman,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gl.clipControl(gl.LOWER_LEFT, gl.ZERO_TO_ONE); // use [0, 1] depth in NDC
|
||||||
|
|
||||||
var buffer_align_int: gl.GLint = 0;
|
var buffer_align_int: gl.GLint = 0;
|
||||||
gl.getIntegerv(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT, &buffer_align_int);
|
gl.getIntegerv(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT, &buffer_align_int);
|
||||||
|
|
||||||
@ -151,11 +153,15 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetm
|
|||||||
|
|
||||||
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
|
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
|
||||||
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_COMPARE_FUNC, gl.LESS);
|
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_COMPARE_FUNC, gl.LESS);
|
||||||
|
|
||||||
|
var border = [_]f32{1} ** 4;
|
||||||
|
gl.textureParameterfv(render.shadow_texture_array, gl.TEXTURE_BORDER_COLOR, &border);
|
||||||
|
checkGLError();
|
||||||
|
|
||||||
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_BORDER);
|
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_BORDER);
|
||||||
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_BORDER);
|
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_BORDER);
|
||||||
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||||
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
gl.textureParameteri(render.shadow_texture_array, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||||
gl.textureParameterfv(render.shadow_texture_array, gl.TEXTURE_BORDER_COLOR, @ptrCast(&Vec4.one().data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// First shadow texture handle
|
// First shadow texture handle
|
||||||
@ -199,6 +205,8 @@ pub fn init(allocator: std.mem.Allocator, frame_arena: std.mem.Allocator, assetm
|
|||||||
gl.createFramebuffers(1, &render.shadow_framebuffer);
|
gl.createFramebuffers(1, &render.shadow_framebuffer);
|
||||||
checkGLError();
|
checkGLError();
|
||||||
std.debug.assert(render.shadow_framebuffer != 0);
|
std.debug.assert(render.shadow_framebuffer != 0);
|
||||||
|
gl.namedFramebufferDrawBuffer(render.shadow_framebuffer, gl.NONE);
|
||||||
|
gl.namedFramebufferReadBuffer(render.shadow_framebuffer, gl.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.namedFramebufferTextureLayer(render.shadow_framebuffer, gl.DEPTH_ATTACHMENT, render.shadow_texture_array, 0, 0);
|
gl.namedFramebufferTextureLayer(render.shadow_framebuffer, gl.DEPTH_ATTACHMENT, render.shadow_texture_array, 0, 0);
|
||||||
@ -311,7 +319,7 @@ pub fn finish(self: *Render) void {
|
|||||||
|
|
||||||
const camera_matrix = &self.shadow_matrices;
|
const camera_matrix = &self.shadow_matrices;
|
||||||
camera_matrix.* = .{
|
camera_matrix.* = .{
|
||||||
.projection = Mat4.orthographic(-2, 2, -2, 2, -5, 5),
|
.projection = math.orthographic(-4, 4, -4, 4, -5, 5),
|
||||||
.view = Mat4.lookAt(
|
.view = Mat4.lookAt(
|
||||||
Vec3.new(light.pos.x(), light.pos.y(), light.pos.z()).scale(-1),
|
Vec3.new(light.pos.x(), light.pos.y(), light.pos.z()).scale(-1),
|
||||||
Vec3.zero(),
|
Vec3.zero(),
|
||||||
@ -349,7 +357,7 @@ pub fn finish(self: *Render) void {
|
|||||||
const near_far = Vec2.new(0.1, 10);
|
const near_far = Vec2.new(0.1, 10);
|
||||||
const camera_matrix = &self.shadow_matrices;
|
const camera_matrix = &self.shadow_matrices;
|
||||||
camera_matrix.* = .{
|
camera_matrix.* = .{
|
||||||
.projection = Mat4.perspective(90, 1, near_far.x(), near_far.y()),
|
.projection = math.perspective(90, 1, near_far.x(), near_far.y()),
|
||||||
.view = Mat4.lookAt(
|
.view = Mat4.lookAt(
|
||||||
pos,
|
pos,
|
||||||
pos.add(cam_dir.target),
|
pos.add(cam_dir.target),
|
||||||
@ -359,6 +367,7 @@ pub fn finish(self: *Render) void {
|
|||||||
|
|
||||||
const shadow_view_proj = camera_matrix.projection.mul(camera_matrix.view);
|
const shadow_view_proj = camera_matrix.projection.mul(camera_matrix.view);
|
||||||
const light_frustum = math.Frustum.new(shadow_view_proj);
|
const light_frustum = math.Frustum.new(shadow_view_proj);
|
||||||
|
//light.shadow_vp = shadow_view_proj;
|
||||||
light.near_far = near_far;
|
light.near_far = near_far;
|
||||||
gl.uniform2f(Uniform.NearFarPlanes.value(), near_far.x(), near_far.y());
|
gl.uniform2f(Uniform.NearFarPlanes.value(), near_far.x(), near_far.y());
|
||||||
|
|
||||||
@ -646,7 +655,7 @@ pub const Camera = struct {
|
|||||||
view_mat: Mat4 = Mat4.identity(),
|
view_mat: Mat4 = Mat4.identity(),
|
||||||
|
|
||||||
pub fn projection(self: *const Camera) Mat4 {
|
pub fn projection(self: *const Camera) Mat4 {
|
||||||
return Mat4.perspective(self.fovy, self.aspect, self.near, self.far);
|
return math.perspective(self.fovy, self.aspect, self.near, self.far);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ fn loadGL() void {
|
|||||||
@panic("gl.load");
|
@panic("gl.load");
|
||||||
};
|
};
|
||||||
gl.debugMessageCallback(glDebugCallback, null);
|
gl.debugMessageCallback(glDebugCallback, null);
|
||||||
// gl.enable(gl.DEBUG_OUTPUT);
|
gl.enable(gl.DEBUG_OUTPUT);
|
||||||
gl.enable(gl.DEBUG_OUTPUT_SYNCHRONOUS);
|
gl.enable(gl.DEBUG_OUTPUT_SYNCHRONOUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
src/math.zig
34
src/math.zig
@ -170,3 +170,37 @@ pub fn checkAABBIntersectionNDC(aabb: *const AABB, mvp: *const Mat4) bool {
|
|||||||
|
|
||||||
return !(outside_left_plane or outside_right_plane or outside_bottom_plane or outside_top_plane or outside_near_plane or outside_far_plane);
|
return !(outside_left_plane or outside_right_plane or outside_bottom_plane or outside_top_plane or outside_near_plane or outside_far_plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Formulas from D3DXMatrixPerspectiveFovRH
|
||||||
|
/// Maps z to [0, 1]
|
||||||
|
pub fn perspective(fovy_in_degrees: f32, aspect_ratio: f32, z_near: f32, z_far: f32) Mat4 {
|
||||||
|
var result = Mat4.identity();
|
||||||
|
|
||||||
|
const f = 1 / @tan(za.toRadians(fovy_in_degrees) * 0.5);
|
||||||
|
|
||||||
|
result.data[0][0] = f / aspect_ratio;
|
||||||
|
result.data[1][1] = f;
|
||||||
|
result.data[2][2] = z_far / (z_near - z_far);
|
||||||
|
result.data[2][3] = -1;
|
||||||
|
result.data[3][2] = z_far * z_near / (z_near - z_far);
|
||||||
|
result.data[3][3] = 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Formulas from D3DXMatrixOrthoOffCenterRH
|
||||||
|
/// Maps z to [0, 1]
|
||||||
|
pub fn orthographic(left: f32, right: f32, bottom: f32, top: f32, z_near: f32, z_far: f32) Mat4 {
|
||||||
|
var result = Mat4.zero();
|
||||||
|
|
||||||
|
result.data[0][0] = 2 / (right - left);
|
||||||
|
result.data[1][1] = 2 / (top - bottom);
|
||||||
|
result.data[2][2] = 2 / (z_near - z_far);
|
||||||
|
result.data[3][3] = 1;
|
||||||
|
|
||||||
|
result.data[3][0] = (left + right) / (left - right);
|
||||||
|
result.data[3][1] = (bottom + top) / (bottom - top);
|
||||||
|
result.data[3][2] = z_near / (z_near - z_far);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user