mirror of
https://github.com/bdnugget/zig-gamedev.git
synced 2026-11-07 09:07:31 +00:00
monolith: demo is prettier, debug rendering in progress
This commit is contained in:
1 parent
f6252a8c41
commit
d59a7fe371
5 files changed
+117
-31
No files matched your search
@@ -178,6 +178,7 @@ fn samplesCrossPlatform(b: *std.Build, options: Options) void {
|
||||
const layers_wgpu = @import("samples/layers_wgpu/build.zig");
|
||||
const gamepad_wgpu = @import("samples/gamepad_wgpu/build.zig");
|
||||
const physics_test_wgpu = @import("samples/physics_test_wgpu/build.zig");
|
||||
const monolith = @import("samples/monolith/build.zig");
|
||||
|
||||
install(b, minimal_gl.build(b, options), "minimal_gl");
|
||||
install(b, triangle_wgpu.build(b, options), "triangle_wgpu");
|
||||
@@ -190,6 +191,7 @@ fn samplesCrossPlatform(b: *std.Build, options: Options) void {
|
||||
install(b, bullet_physics_test_wgpu.build(b, options), "bullet_physics_test_wgpu");
|
||||
install(b, procedural_mesh_wgpu.build(b, options), "procedural_mesh_wgpu");
|
||||
install(b, physics_test_wgpu.build(b, options), "physics_test_wgpu");
|
||||
install(b, monolith.build(b, options), "monolith");
|
||||
install(b, audio_experiments_wgpu.build(b, options), "audio_experiments_wgpu");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
const std = @import("std");
|
||||
|
||||
const Options = @import("../../build.zig").Options;
|
||||
const content_dir = "monolith_content/";
|
||||
|
||||
pub fn build(b: *std.Build, options: Options) *std.Build.CompileStep {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "monolith",
|
||||
.root_source_file = .{ .path = thisDir() ++ "/src/monolith.zig" },
|
||||
.target = options.target,
|
||||
.optimize = options.optimize,
|
||||
});
|
||||
|
||||
const zgui_pkg = @import("../../build.zig").zgui_pkg;
|
||||
const zmath_pkg = @import("../../build.zig").zmath_pkg;
|
||||
const zgpu_pkg = @import("../../build.zig").zgpu_pkg;
|
||||
const zglfw_pkg = @import("../../build.zig").zglfw_pkg;
|
||||
const zmesh_pkg = @import("../../build.zig").zmesh_pkg;
|
||||
|
||||
const zphysics_pkg = @import("../../libs/zphysics/build.zig").package(b, options.target, options.optimize, .{
|
||||
.options = .{
|
||||
.use_double_precision = false,
|
||||
.enable_debug_renderer = true,
|
||||
.enable_asserts = true,
|
||||
},
|
||||
});
|
||||
|
||||
zmath_pkg.link(exe);
|
||||
zgui_pkg.link(exe);
|
||||
zgpu_pkg.link(exe);
|
||||
zglfw_pkg.link(exe);
|
||||
zmesh_pkg.link(exe);
|
||||
zphysics_pkg.link(exe);
|
||||
|
||||
const exe_options = b.addOptions();
|
||||
exe.addOptions("build_options", exe_options);
|
||||
exe_options.addOption([]const u8, "content_dir", content_dir);
|
||||
|
||||
const install_content_step = b.addInstallDirectory(.{
|
||||
.source_dir = thisDir() ++ "/" ++ content_dir,
|
||||
.install_dir = .{ .custom = "" },
|
||||
.install_subdir = "bin/" ++ content_dir,
|
||||
});
|
||||
exe.step.dependOn(&install_content_step.step);
|
||||
|
||||
return exe;
|
||||
}
|
||||
|
||||
inline fn thisDir() []const u8 {
|
||||
return comptime std.fs.path.dirname(@src().file) orelse ".";
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8559132c89ad51d8a2ba5b171887a44a7ba93776e205f553573de228e64b45f8
|
||||
size 162588
|
||||
+20
-12
@@ -7,16 +7,18 @@ const zgui = @import("zgui");
|
||||
const zm = @import("zmath");
|
||||
const zphy = @import("zphysics");
|
||||
const zmesh = @import("zmesh");
|
||||
const wgsl = @import("physics_debug_rendering_wgsl.zig");
|
||||
const wgsl = @import("monolith_wgsl.zig");
|
||||
|
||||
const content_dir = @import("build_options").content_dir;
|
||||
const window_title = "zig-gamedev: physics test (wgpu)";
|
||||
|
||||
const FrameUniforms = extern struct {
|
||||
world_to_clip: zm.Mat align(16),
|
||||
floor_material: [4]f32 align(16),
|
||||
box_rotation: [3][4]f32 align(16), // GPU will expect each element to be 16-aligned too, so extra f32 here to pad.
|
||||
box_center: [4]f32 align(16), // Only [3]f32 logically, but [4]f32 in memory, so 3 or 4 works the same.
|
||||
box_radius: [4]f32 align(16), // Only [3]f32 logically, but [4]f32 in memory, so 3 or 4 works the same.
|
||||
box_inv_radius: [4]f32 align(16), // Only [3]f32 logically, but [4]f32 in memory, so 3 or 4 works the same.
|
||||
camera_position: [3]f32 align(16), // Only [3]f32 logically, but [4]f32 in memory, so 3 or 4 works the same.
|
||||
};
|
||||
|
||||
@@ -170,9 +172,9 @@ const DemoState = struct {
|
||||
physics_debug_renderer: MyDebugRenderer,
|
||||
|
||||
camera: struct {
|
||||
position: [3]f32 = .{ 0.0, 8.0, -32.0 },
|
||||
position: [3]f32 = .{ 0.0, 32.0, -32.0 },
|
||||
forward: [3]f32 = .{ 0.0, 0.0, 1.0 },
|
||||
pitch: f32 = 0.1 * math.pi,
|
||||
pitch: f32 = 0.16 * math.pi,
|
||||
yaw: f32 = 0.0,
|
||||
} = .{},
|
||||
mouse: struct {
|
||||
@@ -706,23 +708,24 @@ fn draw(demo: *DemoState) void {
|
||||
);
|
||||
pass.setPipeline(mesh_render_pipe);
|
||||
|
||||
const box_scale = zm.scaling(10, 30, 5);
|
||||
const box_rotate = zm.mul(zm.rotationZ(0.4), zm.rotationY(0.5));
|
||||
// const box_center = zm.f32x4(-25, 10, 50, 1);
|
||||
const box_center = zm.f32x4(0, 10, 0, 1);
|
||||
const box_scale = zm.scaling(10, 50, 5);
|
||||
const box_rotate = zm.mul(zm.rotationZ(0.24), zm.rotationY(0.3));
|
||||
const box_center = zm.f32x4(-15, 0, 30, 1);
|
||||
const box_radius = zm.mul(box_scale, zm.f32x4(0.4999, 0.4999, 0.4999, 0)); // .4999 is anti-artifact bias
|
||||
const box_translate = zm.transpose(zm.translationV(box_center));
|
||||
const box_transform = zm.mul(box_translate, zm.mul(box_rotate, box_scale));
|
||||
const box_radius = zm.mul(box_scale, zm.f32x4(0.499, 0.499, 0.499, 0)); // .499 is anti-artifacting
|
||||
const box_rotate_t = zm.transpose(box_rotate);
|
||||
const box_rotation: [3][4]f32 = .{ box_rotate_t[0], box_rotate_t[1], box_rotate_t[2] };
|
||||
const floor_material = zm.f32x4(-0.9, -0.9, -0.9, 0.8);
|
||||
|
||||
{ // Update frame uniforms
|
||||
const mem = gctx.uniformsAllocate(FrameUniforms, 1);
|
||||
mem.slice[0] = .{
|
||||
.world_to_clip = zm.transpose(cam_world_to_clip),
|
||||
.floor_material = floor_material,
|
||||
.box_rotation = .{ box_rotate_t[0], box_rotate_t[1], box_rotate_t[2] },
|
||||
.box_center = box_center,
|
||||
.box_radius = box_radius,
|
||||
.box_rotation = box_rotation,
|
||||
.box_inv_radius = .{ 1.0 / box_radius[0], 1.0 / box_radius[1], 1.0 / box_radius[2], 0 },
|
||||
.camera_position = demo.camera.position,
|
||||
};
|
||||
pass.setBindGroup(0, uniform_bg, &.{mem.offset});
|
||||
@@ -732,7 +735,8 @@ fn draw(demo: *DemoState) void {
|
||||
const mem = gctx.uniformsAllocate(DrawUniforms, 1);
|
||||
mem.slice[0] = .{
|
||||
.object_to_world = zm.identity(),
|
||||
.basecolor_roughness = .{ 0.9, 0.9, 0.9, -0.3 },
|
||||
.basecolor_roughness = floor_material,
|
||||
// .basecolor_roughness = .{ 0.9, 0.9, 0.9, -0.3 },
|
||||
};
|
||||
pass.setBindGroup(1, uniform_bg, &.{mem.offset});
|
||||
pass.drawIndexed(
|
||||
@@ -764,7 +768,11 @@ fn draw(demo: *DemoState) void {
|
||||
const mem = gctx.uniformsAllocate(DrawUniforms, 1);
|
||||
mem.slice[0] = .{
|
||||
.object_to_world = box_transform,
|
||||
.basecolor_roughness = .{ 0.9, 0.9, 0.9, -0.3 },
|
||||
// .basecolor_roughness = .{ 0.03, 0.02, 0.04, -0.16 },
|
||||
// .basecolor_roughness = .{ 0.3, 0.3, 0.3, -0.02 },
|
||||
// .basecolor_roughness = .{ 0.92, 0.9, 0.94, -0.24 },
|
||||
.basecolor_roughness = .{ 0.010, 0.010, 0.014, -0.05 },
|
||||
// .basecolor_roughness = .{ 0.010, 0.010, 0.014, -0.3 },
|
||||
};
|
||||
pass.setBindGroup(1, uniform_bg, &.{mem.offset});
|
||||
pass.drawIndexed(
|
||||
+41
-19
@@ -8,9 +8,11 @@ const common =
|
||||
\\
|
||||
\\ struct FrameUniforms {
|
||||
\\ world_to_clip: mat4x4<f32>,
|
||||
\\ floor_material: vec4<f32>,
|
||||
\\ box_rotation: mat3x3<f32>,
|
||||
\\ box_center: vec3<f32>,
|
||||
\\ box_radius: vec3<f32>,
|
||||
\\ box_inv_radius: vec3<f32>,
|
||||
\\ camera_position: vec3<f32>,
|
||||
\\ }
|
||||
\\ @group(0) @binding(0) var<uniform> frame_uniforms: FrameUniforms;
|
||||
@@ -102,19 +104,26 @@ pub const mesh = struct {
|
||||
\\ struct Box {
|
||||
\\ center: vec3<f32>,
|
||||
\\ radius: vec3<f32>,
|
||||
\\ inv_radius: vec3<f32>,
|
||||
\\ rotation: mat3x3<f32>,
|
||||
\\ };
|
||||
\\ struct Ray {
|
||||
\\ origin: vec3<f32>,
|
||||
\\ direction: vec3<f32>,
|
||||
\\ };
|
||||
\\ // Alexander Majercik, Cyril Crassin, Peter Shirley, and Morgan McGuire, A Ray-Box Intersection Algorithm and
|
||||
\\ // Efficient Dynamic Voxel Rendering, Journal of Computer Graphics Techniques (JCGT), vol. 7, no. 3, 66-81, 2018
|
||||
\\ // This wgsl implementation of the algorithm is customized to fit the assumptions of this use case.
|
||||
\\ fn intersect_box(box: Box, ray: Ray, distance: ptr<function, f32>, normal: ptr<function, vec3<f32>>) -> bool {
|
||||
\\ let r = Ray(
|
||||
\\ (ray.origin - box.center) * box.rotation,
|
||||
\\ ray.direction * box.rotation,
|
||||
\\ );
|
||||
\\ var winding: f32 = 1.0;
|
||||
\\ let winding_vec = abs(r.origin) * box.inv_radius;
|
||||
\\ if (max(max(winding_vec.x, winding_vec.y), winding_vec.z) < 1.0) { winding = -1.0; }
|
||||
\\ var sgn: vec3<f32> = -sign(r.direction);
|
||||
\\ var plane_dist: vec3<f32> = box.radius * sgn - r.origin;
|
||||
\\ var plane_dist: vec3<f32> = box.radius * winding * sgn - r.origin;
|
||||
\\ plane_dist = plane_dist / r.direction;
|
||||
\\
|
||||
\\ let test = vec3<bool>(
|
||||
@@ -141,17 +150,22 @@ pub const mesh = struct {
|
||||
\\ @location(1) normal: vec3<f32>,
|
||||
\\ ) -> @location(0) vec4<f32> {
|
||||
\\ let v = normalize(frame_uniforms.camera_position - position);
|
||||
\\
|
||||
\\ let r_x = rand2(floor(2 * position.xz));
|
||||
\\ let r_z = rand2(floor(2 * position.zx));
|
||||
\\ let r_vec = vec3(r_x, 0, r_z);
|
||||
\\ let r_strength = 0.04;
|
||||
\\ let n = normalize(normal + r_vec * r_strength);
|
||||
\\
|
||||
\\ let base_color = draw_uniforms.basecolor_roughness.xyz;
|
||||
\\ var base_color = draw_uniforms.basecolor_roughness.xyz;
|
||||
\\ var roughness = draw_uniforms.basecolor_roughness.a;
|
||||
\\
|
||||
\\ var n: vec3<f32>;
|
||||
\\ if (base_color.x < 0.0) {
|
||||
\\ let r_x = rand2(floor(2 * position.xz));
|
||||
\\ let r_z = rand2(floor(2 * position.zx));
|
||||
\\ let r_vec = vec3(r_x, 0, r_z);
|
||||
\\ let r_strength = 0.04;
|
||||
\\ n = normalize(normal + r_vec * r_strength);
|
||||
\\ roughness += min(0, -dot(r_vec, r_vec) * 0.6 + 0.64);
|
||||
\\ } else { n = normalize(normal); }
|
||||
\\
|
||||
\\ var metallic: f32;
|
||||
\\ if (roughness < 0.0) { metallic = 0.95; } else { metallic = 0.0; }
|
||||
\\ if (roughness < 0.0) { metallic = 0.95; } else { metallic = 0.05; }
|
||||
\\ base_color = abs(base_color);
|
||||
\\ roughness = abs(roughness);
|
||||
\\
|
||||
\\ let alpha = roughness * roughness;
|
||||
@@ -177,26 +191,34 @@ pub const mesh = struct {
|
||||
\\ vec3(0.70, 1.00, 0.70),
|
||||
\\ );
|
||||
\\
|
||||
\\ let monolith = Box(
|
||||
\\ frame_uniforms.box_center,
|
||||
\\ frame_uniforms.box_radius,
|
||||
\\ frame_uniforms.box_inv_radius,
|
||||
\\ frame_uniforms.box_rotation,
|
||||
\\ );
|
||||
\\
|
||||
\\ var lo = vec3(0.0);
|
||||
\\ for (var light_index: i32 = 0; light_index < 9; light_index = light_index + 1) {
|
||||
\\ let lvec = light_positions[light_index] - position;
|
||||
\\
|
||||
\\ let l = normalize(lvec);
|
||||
\\ let h = normalize(l + v);
|
||||
\\
|
||||
\\ let box = Box(
|
||||
\\ frame_uniforms.box_center,
|
||||
\\ frame_uniforms.box_radius,
|
||||
\\ frame_uniforms.box_rotation,
|
||||
\\ );
|
||||
\\ let pl_ray = Ray(position, l);
|
||||
\\ var pl_hit_dist: f32;
|
||||
\\ var pl_hit_norm: vec3<f32>;
|
||||
\\ let pl_did_hit: bool = intersect_box(box, pl_ray, &pl_hit_dist, &pl_hit_norm);
|
||||
\\ let pl_did_hit: bool = intersect_box(monolith, pl_ray, &pl_hit_dist, &pl_hit_norm);
|
||||
\\ if (!pl_did_hit || pl_hit_dist > length(lvec)) {
|
||||
\\ let distance_sq = dot(lvec, lvec);
|
||||
\\ let attenuation = 1.0 / distance_sq;
|
||||
\\ let radiance = 100 * light_colors[light_index] * attenuation;
|
||||
\\ var radiance = 100 * light_colors[light_index] * attenuation;
|
||||
\\
|
||||
\\ if (position.y > 0.0001) { // reflection of floor lighting on monolith surface
|
||||
\\ let mirror_cam = vec3<f32>(position.x, -position.y, position.z);
|
||||
\\ let mirror_vec = light_positions[light_index] - mirror_cam;
|
||||
\\ let t = -mirror_cam.y / (light_positions[light_index].y - mirror_cam.y);
|
||||
\\ let mirror_pos = mirror_cam + t * mirror_vec;
|
||||
\\ }
|
||||
\\
|
||||
\\ let f = fresnelSchlick(saturate(dot(h, v)), f0);
|
||||
\\
|
||||
@@ -220,7 +242,7 @@ pub const mesh = struct {
|
||||
\\ let cl_ray = Ray(frame_uniforms.camera_position, cfn);
|
||||
\\ var cl_hit_dist: f32;
|
||||
\\ var cl_hit_norm: vec3<f32>;
|
||||
\\ let cl_did_hit: bool = intersect_box(box, cl_ray, &cl_hit_dist, &cl_hit_norm);
|
||||
\\ let cl_did_hit: bool = intersect_box(monolith, cl_ray, &cl_hit_dist, &cl_hit_norm);
|
||||
\\ if (cl_did_hit && cl_hit_dist < length(cl)) { continue; }
|
||||
\\ let negs = (dot(normalize(cl), cfn) - 1.0) * dot(cl, cl);
|
||||
\\ let peak = 0.2;
|
||||
Reference in new issue
Block a user