summaryrefslogtreecommitdiffstats
path: root/assets/shaders/tacmap
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-05-10 13:29:56 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-05-10 13:29:56 -0400
commit7f63ec5c10eb7e8dd4edaabd1a6a437328911d39 (patch)
tree36bd3d75ebc0c25256413c21a7cb28c9296953f5 /assets/shaders/tacmap
parentc9041e2e6fe59d6127bb1085b874e8e3cda8000e (diff)
downloadsystemic4x-7f63ec5c10eb7e8dd4edaabd1a6a437328911d39.tar.gz
systemic4x-7f63ec5c10eb7e8dd4edaabd1a6a437328911d39.tar.bz2
systemic4x-7f63ec5c10eb7e8dd4edaabd1a6a437328911d39.zip
fleets
Diffstat (limited to 'assets/shaders/tacmap')
-rw-r--r--assets/shaders/tacmap/body.wgsl51
-rw-r--r--assets/shaders/tacmap/fleet.wgsl73
-rw-r--r--assets/shaders/tacmap/orbit.wgsl22
3 files changed, 111 insertions, 35 deletions
diff --git a/assets/shaders/tacmap/body.wgsl b/assets/shaders/tacmap/body.wgsl
index 0cfd5f9..9e6419e 100644
--- a/assets/shaders/tacmap/body.wgsl
+++ b/assets/shaders/tacmap/body.wgsl
@@ -7,7 +7,6 @@ struct InstanceInput {
struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
@location(0) local_position: vec3<f32>,
- @location(1) distance: f32
};
struct CameraUniform {
@@ -40,46 +39,42 @@ fn vs_main(
let model = QUAD_VERTICES[index];
var view = camera.view;
- //Billboard the circle
- let camera_right = vec3<f32>(view[0][0], view[1][0], view[2][0]);
- let camera_up = vec3<f32>(view[0][1], view[1][1], view[2][1]);
- let model_pos = camera_right * model.x +
- camera_up * model.y;
+ out.local_position = model;
let min_size = 0.025;
+ let real_radius = max(min_size / 2.0, instance.radius * camera.scale);
//Scale the world around the camera scale and translate about the camera's
//absolute (/target) position
let relative_pos = instance.position;
- let origin_pos = instance.origin - camera.abs_pos;
-
- /*if all(relative_pos != origin_pos) {
- if length(relative_pos) < 0.01 / camera.scale {
- if length(relative_pos) != 0.0 {
- out.clip_position = vec4<f32>(0.0, 0.0, 0.0, 1.0);
- return out;
- }
- }
- }*/
-
- let instance_pos = (relative_pos + origin_pos - camera.rel_pos) * camera.scale;
+ let origin_pos = instance.origin - camera.abs_pos - camera.rel_pos;
let view_proj = camera.proj * view;
- let center_view_pos = view_proj * vec4<f32>(instance_pos, 1.0);
- let vertex_view_pos = view_proj * vec4<f32>(instance_pos + (model_pos * instance.radius * camera.scale), 1.0);
+ let origin_vp_pos = view_proj * vec4<f32>(origin_pos * camera.scale, 1.0);
+ let offset_vp = view_proj * vec4<f32>(relative_pos * camera.scale, 0.0);
+ let center_vp_pos = origin_vp_pos + offset_vp;
+
+ let offset_ndc = offset_vp.xy / origin_vp_pos.w;
+
+ if (length(offset_ndc) < 2.0 * min_size){
+ if all(offset_vp != vec4<f32>(0.0)) {
+ out.clip_position = vec4<f32>(0.0, 0.0, 0.0, 1.0);
+ return out;
+ }
+ }
+
+ let model_proj = camera.proj * vec4<f32>(model.xy, 0.0, 0.0);
+ let vertex_vp_pos = center_vp_pos + vec4<f32>(model_proj.xy * instance.radius * camera.scale, 0.0, 0.0);
- let vertex_dist = length(vertex_view_pos - center_view_pos) / center_view_pos.w;
+ let vertex_dist = length(vertex_vp_pos - center_vp_pos) / center_vp_pos.w;
if vertex_dist < min_size {
- out.clip_position = center_view_pos / center_view_pos.w;
- out.clip_position += camera.proj * vec4<f32>(model.xy * (min_size / 2.0), 0.0, 0.0);
+ out.clip_position = center_vp_pos / center_vp_pos.w;
+ out.clip_position += model_proj * (min_size / 2.0);
}else{
- out.clip_position = vertex_view_pos;
+ out.clip_position = vertex_vp_pos;
}
- out.local_position = model;
- out.distance = length(instance_pos);
-
return out;
}
@@ -91,6 +86,6 @@ fn fs_main(in: VertexOutput
if point_dist > 1.0 {
alpha = 0.0;
}
- let color = vec3<f32>(1.0, 1.0, 1.0) / clamp(in.distance, 1.0, 1.5);
+ let color = vec3<f32>(1.0);
return vec4<f32>(color, alpha);
}
diff --git a/assets/shaders/tacmap/fleet.wgsl b/assets/shaders/tacmap/fleet.wgsl
new file mode 100644
index 0000000..8a87fb9
--- /dev/null
+++ b/assets/shaders/tacmap/fleet.wgsl
@@ -0,0 +1,73 @@
+struct InstanceInput {
+ @location(0) rotmat_0: vec3<f32>,
+ @location(1) rotmat_1: vec3<f32>,
+ @location(2) rotmat_2: vec3<f32>,
+ @location(3) origin: vec3<f32>,
+ @location(4) offset: vec3<f32>,
+};
+
+struct VertexOutput {
+ @builtin(position) clip_position: vec4<f32>,
+ @location(0) color: vec3<f32>
+};
+
+struct CameraUniform {
+ view: mat4x4<f32>,
+ proj: mat4x4<f32>,
+ abs_pos: vec3<f32>,
+ rel_pos: vec3<f32>,
+ scale: f32,
+};
+
+@group(0) @binding(0)
+var<uniform> camera: CameraUniform;
+
+const FLEET_VERTICES = array<vec3<f32>,6>(
+ vec3<f32>(-1.0, -1.0, 0.0),
+ vec3<f32>(-1.0, 1.0 , 0.0),
+ vec3<f32>(1.0, 0.0 , 0.0),
+
+ vec3<f32>(-1.0, 0.0, -1.0),
+ vec3<f32>(-1.0, 0.0, 1.0 ),
+ vec3<f32>(1.0, 0.0, 0.0 ),
+);
+
+@vertex
+fn vs_main(
+ @builtin(vertex_index) index: u32,
+ instance: InstanceInput
+) -> VertexOutput {
+ var out: VertexOutput;
+
+ let rotmat = mat3x3<f32>(
+ instance.rotmat_0,
+ instance.rotmat_1,
+ instance.rotmat_2
+ );
+ let model_pos = rotmat * FLEET_VERTICES[index] * 0.025;
+ var view = camera.view;
+
+ let min_size = 0.025;
+
+ //Scale the world around the camera scale and translate about the camera's
+ //absolute (/target) position
+ let origin_pos = instance.origin - camera.abs_pos;
+ let offset_pos = instance.offset - camera.rel_pos;
+
+ let instance_pos = (offset_pos + origin_pos) * camera.scale;
+ let vertex_pos = instance_pos + model_pos;
+
+ let view_proj = camera.proj * view;
+ let instance_vp_pos = view_proj * vec4<f32>(instance_pos, 1.0);
+ let model_vp_pos = view_proj * vec4<f32>(model_pos, 0.0);
+
+ out.clip_position = instance_vp_pos + model_vp_pos;
+ out.color = vec3<f32>(0.75, 1.0, 0.75);
+ return out;
+}
+
+@fragment
+fn fs_main(in: VertexOutput
+) -> @location(0) vec4<f32> {
+ return vec4<f32>(in.color, 1.0);
+}
diff --git a/assets/shaders/tacmap/orbit.wgsl b/assets/shaders/tacmap/orbit.wgsl
index a890fd8..7276345 100644
--- a/assets/shaders/tacmap/orbit.wgsl
+++ b/assets/shaders/tacmap/orbit.wgsl
@@ -38,24 +38,32 @@ fn vs_main(
origins[model.origin][1],
origins[model.origin][2]);
- let model_pos = ((origin - camera.abs_pos - camera.rel_pos) + model.position) * camera.scale;
- let origin_pos = (origin - camera.abs_pos - camera.rel_pos) * camera.scale;
+ let offset_pos = model.position;
+ let origin_pos = origin - camera.abs_pos - camera.rel_pos;
- let view = camera.view;
+ let view_proj = camera.proj * camera.view;
+
+ let origin_view_pos = camera.view * vec4<f32>(origin_pos * camera.scale, 1.0);
+ let offset_view = camera.view * vec4<f32>(offset_pos * camera.scale, 0.0);
+ let point_view_pos = origin_view_pos + offset_view;
let orbit_normal = normalize(model.position);
var normal = orbit_normal;
- if length(model_pos - origin_pos) > 0.01 {
+ let offset_ndc = offset_view.xy / origin_view_pos.z;
+
+ let discard_radius = 0.05;
+
+ if length(offset_ndc) > discard_radius {
normal *= POINT_NORMALS[index];
}
- let view_proj = camera.proj * camera.view;
+ let point_vp_pos = camera.proj * point_view_pos;
//Scale the world around the camera scale and translate about the camera's
//absolute (/target) position
- let point_view_pos = view_proj * vec4<f32>(model_pos + normal * 0.005, 1.0);
- out.clip_position = point_view_pos;
+ let segment_vp_pos = point_vp_pos + (view_proj * vec4<f32>(normal * 0.005, 0.0));
+ out.clip_position = segment_vp_pos;
return out;
}