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(), position: (s.pos + offset).into(),
parallax: s.parallax, parallax: s.parallax,
height: s.height, height: s.height,
tint: s.tint.into(),
}) })
} }
} }

View File

@ -3,6 +3,7 @@ struct InstanceInput {
@location(2) position: vec2<f32>, @location(2) position: vec2<f32>,
@location(3) parallax: f32, @location(3) parallax: f32,
@location(4) height: f32, @location(4) height: f32,
@location(5) tint: vec2<f32>,
}; };
struct VertexInput { struct VertexInput {
@ -13,6 +14,7 @@ struct VertexInput {
struct VertexOutput { struct VertexOutput {
@builtin(position) position: vec4<f32>, @builtin(position) position: vec4<f32>,
@location(0) texture_coords: vec2<f32>, @location(0) texture_coords: vec2<f32>,
@location(1) tint: vec2<f32>,
} }
@group(1) @binding(0) @group(1) @binding(0)
@ -37,6 +39,10 @@ fn vertex_shader_main(
instance: InstanceInput, instance: InstanceInput,
) -> VertexOutput { ) -> 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. // Center of the tile the camera is currently in, in game coordinates.
// x div y = x - (x mod y) // x div y = x - (x mod y)
let tile_center = ( let tile_center = (
@ -55,8 +61,15 @@ fn vertex_shader_main(
// Minimum scale to prevent flicker at large zoom levels // Minimum scale to prevent flicker at large zoom levels
var real_size = scale * global.window_size.xy; 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) { 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) / vec2<f32>(global.window_aspect.x, 1.0)
); );
var out: VertexOutput;
out.position = vec4<f32>(pos, 0.0, 1.0) * instance.parallax; out.position = vec4<f32>(pos, 0.0, 1.0) * instance.parallax;
out.texture_coords = vertex.texture_coords;
return out; return out;
} }
@ -92,10 +103,17 @@ var sampler_array: binding_array<sampler>;
// Fragment shader // Fragment shader
@fragment @fragment
fn fragment_shader_main(in: VertexOutput) -> @location(0) vec4<f32> { 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( return textureSampleLevel(
texture_array[global.starfield_texture.x], texture_array[global.starfield_texture.x],
sampler_array[global.starfield_texture.x], sampler_array[global.starfield_texture.x],
in.texture_coords, in.texture_coords,
0.0 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 /// Height of (unrotated) sprite in world units
pub height: f32, pub height: f32,
pub tint: [f32; 2],
} }
impl BufferObject for StarfieldInstance { impl BufferObject for StarfieldInstance {
@ -72,6 +74,12 @@ impl BufferObject for StarfieldInstance {
shader_location: 4, shader_location: 4,
format: wgpu::VertexFormat::Float32, 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, Doodad, Sprite, Spriteable, STARFIELD_COUNT, STARFIELD_PARALLAX_MAX, STARFIELD_PARALLAX_MIN,
STARFIELD_SIZE, STARFIELD_SIZE,
}; };
use cgmath::{Deg, Point2}; use cgmath::{Deg, Point2, Vector2};
use rand::{self, Rng}; use rand::{self, Rng};
pub struct StarfieldStar { pub struct StarfieldStar {
// Star coordinates, in world space. /// Star coordinates, in world space.
// These are relative to the center of a starfield tile. /// These are relative to the center of a starfield tile.
pub pos: Point2<Pfloat>, pub pos: Point2<Pfloat>,
pub parallax: Pfloat, pub parallax: Pfloat,
pub height: Pfloat, pub height: Pfloat,
/// Color/brightness variation.
/// See shader.
pub tint: Vector2<Pfloat>,
} }
pub struct System { pub struct System {
@ -32,7 +37,11 @@ impl System {
y: rng.gen_range(-sz..=sz), y: rng.gen_range(-sz..=sz),
}, },
parallax: rng.gen_range(STARFIELD_PARALLAX_MIN..STARFIELD_PARALLAX_MAX), 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(), .collect(),
}; };