Added starfield tinting

master
Mark 2023-12-24 11:59:39 -08:00
parent 67f10c940a
commit e138981c8c
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
4 changed files with 44 additions and 8 deletions

View File

@ -304,6 +304,7 @@ impl GPUState {
position: (s.pos + offset).into(),
parallax: s.parallax,
height: s.height,
tint: s.tint.into(),
})
}
}

View File

@ -3,6 +3,7 @@ struct InstanceInput {
@location(2) position: vec2<f32>,
@location(3) parallax: f32,
@location(4) height: f32,
@location(5) tint: vec2<f32>,
};
struct VertexInput {
@ -13,6 +14,7 @@ struct VertexInput {
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) texture_coords: vec2<f32>,
@location(1) tint: vec2<f32>,
}
@group(1) @binding(0)
@ -37,6 +39,10 @@ fn vertex_shader_main(
instance: InstanceInput,
) -> VertexOutput {
var out: VertexOutput;
out.texture_coords = vertex.texture_coords;
out.tint = instance.tint;
// Center of the tile the camera is currently in, in game coordinates.
// x div y = x - (x mod y)
let tile_center = (
@ -55,8 +61,15 @@ fn vertex_shader_main(
// Minimum scale to prevent flicker at large zoom levels
var real_size = scale * global.window_size.xy;
// TODO: configurable.
// Uniform distribution!
if (real_size.x < 0.5 || real_size.y < 0.5) {
out.position = vec4<f32>(2.0, 2.0, 0.0, 1.0);
return out;
}
if (real_size.x < 2.0 || real_size.y < 2.0) {
scale = 2.0 / min(global.window_size.x, global.window_size.y);
scale = 2.0 / max(global.window_size.x, global.window_size.y);
}
@ -77,9 +90,7 @@ fn vertex_shader_main(
/ vec2<f32>(global.window_aspect.x, 1.0)
);
var out: VertexOutput;
out.position = vec4<f32>(pos, 0.0, 1.0) * instance.parallax;
out.texture_coords = vertex.texture_coords;
return out;
}
@ -92,10 +103,17 @@ var sampler_array: binding_array<sampler>;
// Fragment shader
@fragment
fn fragment_shader_main(in: VertexOutput) -> @location(0) vec4<f32> {
let b = 1.0 - (in.tint.x / 1.2); // brightness
let c = in.tint.y; // color
let c_top = vec3<f32>(0.369, 0.819, 0.796);
let c_bot = vec3<f32>(0.979, 0.556, 0.556);
let c_del = c_bot - c_top;
return textureSampleLevel(
texture_array[global.starfield_texture.x],
sampler_array[global.starfield_texture.x],
in.texture_coords,
0.0
).rgba * vec4<f32>(0.5, 0.5, 0.5, 1.0);
).rgba * vec4<f32>((c_top + c_del * c) * b, 1.0);
}

View File

@ -46,6 +46,8 @@ pub struct StarfieldInstance {
/// Height of (unrotated) sprite in world units
pub height: f32,
pub tint: [f32; 2],
}
impl BufferObject for StarfieldInstance {
@ -72,6 +74,12 @@ impl BufferObject for StarfieldInstance {
shader_location: 4,
format: wgpu::VertexFormat::Float32,
},
// Tint
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
shader_location: 5,
format: wgpu::VertexFormat::Float32x2,
},
],
}
}

View File

@ -3,15 +3,20 @@ use crate::{
Doodad, Sprite, Spriteable, STARFIELD_COUNT, STARFIELD_PARALLAX_MAX, STARFIELD_PARALLAX_MIN,
STARFIELD_SIZE,
};
use cgmath::{Deg, Point2};
use cgmath::{Deg, Point2, Vector2};
use rand::{self, Rng};
pub struct StarfieldStar {
// Star coordinates, in world space.
// These are relative to the center of a starfield tile.
/// Star coordinates, in world space.
/// These are relative to the center of a starfield tile.
pub pos: Point2<Pfloat>,
pub parallax: Pfloat,
pub height: Pfloat,
/// Color/brightness variation.
/// See shader.
pub tint: Vector2<Pfloat>,
}
pub struct System {
@ -32,7 +37,11 @@ impl System {
y: rng.gen_range(-sz..=sz),
},
parallax: rng.gen_range(STARFIELD_PARALLAX_MIN..STARFIELD_PARALLAX_MAX),
height: rng.gen_range(1.0..2.0),
height: rng.gen_range(0.2..0.8), // TODO: configurable
tint: Vector2 {
x: rng.gen_range(0.0..=1.0),
y: rng.gen_range(0.0..=1.0),
},
})
.collect(),
};