mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added clouds
This commit is contained in:
parent
18ec6dbbec
commit
aa111d34e5
@ -39,7 +39,7 @@ void main() {
|
|||||||
vec3 surf_color = illuminate(srgb_to_linear(model_col.rgb * f_col), light, diffuse_light, ambient_light);
|
vec3 surf_color = illuminate(srgb_to_linear(model_col.rgb * f_col), light, diffuse_light, ambient_light);
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, true);
|
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, f_pos, true);
|
||||||
vec3 color = mix(surf_color, fog_color, fog_level);
|
vec3 color = mix(surf_color, fog_color, fog_level);
|
||||||
|
|
||||||
tgt_color = vec4(color, 1.0);
|
tgt_color = vec4(color, 1.0);
|
||||||
|
@ -50,7 +50,7 @@ float wave_height(vec3 pos) {
|
|||||||
0.0
|
0.0
|
||||||
);
|
);
|
||||||
|
|
||||||
return pow(abs(height), 0.5) * sign(height) * 3.0;
|
return pow(abs(height), 0.5) * sign(height) * 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -113,13 +113,13 @@ void main() {
|
|||||||
vec3 surf_color = illuminate(srgb_to_linear(f_col), light, diffuse_light, ambient_light);
|
vec3 surf_color = illuminate(srgb_to_linear(f_col), light, diffuse_light, ambient_light);
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, true);
|
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, f_pos, true);
|
||||||
|
|
||||||
vec3 reflect_ray_dir = reflect(cam_to_frag, norm);
|
vec3 reflect_ray_dir = reflect(cam_to_frag, norm);
|
||||||
// Hack to prevent the reflection ray dipping below the horizon and creating weird blue spots in the water
|
// Hack to prevent the reflection ray dipping below the horizon and creating weird blue spots in the water
|
||||||
reflect_ray_dir.z = max(reflect_ray_dir.z, 0.05);
|
reflect_ray_dir.z = max(reflect_ray_dir.z, 0.05);
|
||||||
|
|
||||||
vec3 reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, false) * f_light;
|
vec3 reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, f_pos, false) * f_light;
|
||||||
// 0 = 100% reflection, 1 = translucent water
|
// 0 = 100% reflection, 1 = translucent water
|
||||||
float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag), -cam_to_frag), 0.5);
|
float passthrough = pow(dot(faceforward(f_norm, f_norm, cam_to_frag), -cam_to_frag), 0.5);
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include <random.glsl>
|
#include <random.glsl>
|
||||||
|
|
||||||
|
uniform sampler2D t_noise;
|
||||||
|
|
||||||
const float PI = 3.141592;
|
const float PI = 3.141592;
|
||||||
|
|
||||||
const vec3 SKY_DAY_TOP = vec3(0.1, 0.2, 0.9);
|
const vec3 SKY_DAY_TOP = vec3(0.1, 0.2, 0.9);
|
||||||
@ -43,6 +45,22 @@ float get_moon_brightness(vec3 moon_dir) {
|
|||||||
return max(-moon_dir.z + 0.6, 0.0) * 0.07;
|
return max(-moon_dir.z + 0.6, 0.0) * 0.07;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 get_sun_color(vec3 sun_dir) {
|
||||||
|
return mix(
|
||||||
|
mix(
|
||||||
|
DUSK_LIGHT,
|
||||||
|
NIGHT_LIGHT,
|
||||||
|
max(sun_dir.z, 0)
|
||||||
|
),
|
||||||
|
DAY_LIGHT,
|
||||||
|
max(-sun_dir.z, 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 get_moon_color(vec3 moon_dir) {
|
||||||
|
return vec3(0.15, 0.15, 1.5);
|
||||||
|
}
|
||||||
|
|
||||||
void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diffuse_light, out vec3 ambient_light, float diffusion) {
|
void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diffuse_light, out vec3 ambient_light, float diffusion) {
|
||||||
const float SUN_AMBIANCE = 0.1;
|
const float SUN_AMBIANCE = 0.1;
|
||||||
|
|
||||||
@ -54,17 +72,9 @@ void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diff
|
|||||||
|
|
||||||
// clamp() changed to max() as sun_dir.z is produced from a cos() function and therefore never greater than 1
|
// clamp() changed to max() as sun_dir.z is produced from a cos() function and therefore never greater than 1
|
||||||
|
|
||||||
vec3 sun_color = mix(
|
vec3 sun_color = get_sun_color(sun_dir);
|
||||||
mix(
|
|
||||||
DUSK_LIGHT,
|
|
||||||
NIGHT_LIGHT,
|
|
||||||
max(sun_dir.z, 0)
|
|
||||||
),
|
|
||||||
DAY_LIGHT,
|
|
||||||
max(-sun_dir.z, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
vec3 moon_color = vec3(0.1, 0.1, 1) * 1.5;
|
vec3 moon_color = get_moon_color(moon_dir);
|
||||||
|
|
||||||
vec3 sun_chroma = sun_color * sun_light;
|
vec3 sun_chroma = sun_color * sun_light;
|
||||||
vec3 moon_chroma = moon_color * moon_light;
|
vec3 moon_chroma = moon_color * moon_light;
|
||||||
@ -104,7 +114,70 @@ float is_star_at(vec3 dir) {
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_sky_color(vec3 dir, float time_of_day, bool with_stars) {
|
vec3 pos_at_height(vec3 dir, float height) {
|
||||||
|
float dist = height / dir.z;
|
||||||
|
return dir * dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float CLOUD_AVG_HEIGHT = 1500.0;
|
||||||
|
const float CLOUD_HEIGHT_MIN = CLOUD_AVG_HEIGHT - 100.0;
|
||||||
|
const float CLOUD_HEIGHT_MAX = CLOUD_AVG_HEIGHT + 100.0;
|
||||||
|
const float CLOUD_THRESHOLD = 0.3;
|
||||||
|
const float CLOUD_SCALE = 1.0;
|
||||||
|
const float CLOUD_DENSITY = 50.0;
|
||||||
|
|
||||||
|
float spow(float x, float e) {
|
||||||
|
return sign(x) * pow(abs(x), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 cloud_at(vec3 pos) {
|
||||||
|
float hdist = distance(pos.xy, cam_pos.xy) / 100000.0;
|
||||||
|
if (hdist > 1.0) { // Maximum cloud distance
|
||||||
|
return vec4(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float value = (
|
||||||
|
0.0
|
||||||
|
+ texture(t_noise, pos.xy / CLOUD_SCALE * 0.0003 - tick.x * 0.01).x
|
||||||
|
+ texture(t_noise, pos.xy / CLOUD_SCALE * 0.0009 + tick.x * 0.03).x * 0.5
|
||||||
|
+ texture(t_noise, pos.xy / CLOUD_SCALE * 0.0025 - tick.x * 0.05).x * 0.25
|
||||||
|
) / 2.75;
|
||||||
|
|
||||||
|
float density = max((value - CLOUD_THRESHOLD) - abs(pos.z - CLOUD_AVG_HEIGHT) / 2000.0, 0.0) * CLOUD_DENSITY;
|
||||||
|
|
||||||
|
vec3 color = vec3(1.0) * (1.0 - pow(max(CLOUD_AVG_HEIGHT - pos.z, 0.0), 0.25) / 2.5);
|
||||||
|
|
||||||
|
return vec4(color, density / max((hdist - 0.7) * 100.0, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 get_cloud_color(vec3 dir, float time_of_day, float max_dist) {
|
||||||
|
float mind = (CLOUD_HEIGHT_MIN - cam_pos.z) / dir.z;
|
||||||
|
float maxd = (CLOUD_HEIGHT_MAX - cam_pos.z) / dir.z;
|
||||||
|
|
||||||
|
float start = max(min(mind, maxd), 0.0);
|
||||||
|
float delta = abs(mind - maxd);
|
||||||
|
|
||||||
|
if (delta <= 0.0) {
|
||||||
|
return vec4(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 cloud_col = vec3(1);
|
||||||
|
float passthrough = 1.0;
|
||||||
|
const float INCR = 0.05;
|
||||||
|
for (float d = 0.0; d < 1.0; d += INCR) {
|
||||||
|
float dist = start + d * delta;
|
||||||
|
vec3 pos = cam_pos.xyz + dir * dist;
|
||||||
|
vec4 sample = cloud_at(pos);
|
||||||
|
if (dist < max_dist) {
|
||||||
|
passthrough *= (1.0 - sample.a * INCR);
|
||||||
|
cloud_col = mix(cloud_col, sample.rgb, passthrough * sample.a * INCR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec4(cloud_col, 1.0 - passthrough / (1.0 + delta * 0.0003));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 f_pos, bool with_stars) {
|
||||||
// Sky color
|
// Sky color
|
||||||
vec3 sun_dir = get_sun_dir(time_of_day);
|
vec3 sun_dir = get_sun_dir(time_of_day);
|
||||||
vec3 moon_dir = get_moon_dir(time_of_day);
|
vec3 moon_dir = get_moon_dir(time_of_day);
|
||||||
@ -179,7 +252,11 @@ vec3 get_sky_color(vec3 dir, float time_of_day, bool with_stars) {
|
|||||||
vec3 moon_surf = pow(max(dot(dir, -moon_dir) - 0.001, 0.0), 3000.0) * MOON_SURF_COLOR;
|
vec3 moon_surf = pow(max(dot(dir, -moon_dir) - 0.001, 0.0), 3000.0) * MOON_SURF_COLOR;
|
||||||
vec3 moon_light = clamp(moon_halo + moon_surf, vec3(0), vec3(clamp(dir.z * 3.0, 0, 1)));
|
vec3 moon_light = clamp(moon_halo + moon_surf, vec3(0), vec3(clamp(dir.z * 3.0, 0, 1)));
|
||||||
|
|
||||||
return sky_color + sun_light + moon_light;
|
// Clouds
|
||||||
|
vec4 clouds = get_cloud_color(dir, time_of_day, distance(cam_pos.xyz, f_pos));
|
||||||
|
clouds.rgb *= get_sun_brightness(sun_dir) * get_sun_color(sun_dir) + get_moon_brightness(moon_dir) * get_moon_color(moon_dir);
|
||||||
|
|
||||||
|
return mix(sky_color + sun_light + moon_light, clouds.rgb, clouds.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
float fog(vec3 f_pos, vec3 focus_pos, uint medium) {
|
float fog(vec3 f_pos, vec3 focus_pos, uint medium) {
|
||||||
|
@ -13,5 +13,5 @@ uniform u_locals {
|
|||||||
out vec4 tgt_color;
|
out vec4 tgt_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, true), 1.0);
|
tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, vec3(100000), true), 1.0);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ void main() {
|
|||||||
vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
|
vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, true);
|
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, f_pos, true);
|
||||||
vec3 color = mix(surf_color, fog_color, fog_level);
|
vec3 color = mix(surf_color, fog_color, fog_level);
|
||||||
|
|
||||||
tgt_color = vec4(color, 1.0 - clamp((distance(focus_pos.xy, f_pos.xy) - (RENDER_DIST - FADE_DIST)) / FADE_DIST, 0, 1));
|
tgt_color = vec4(color, 1.0 - clamp((distance(focus_pos.xy, f_pos.xy) - (RENDER_DIST - FADE_DIST)) / FADE_DIST, 0, 1));
|
||||||
|
@ -40,7 +40,7 @@ void main() {
|
|||||||
vec3 surf_color = illuminate(srgb_to_linear(f_col), light, diffuse_light, ambient_light);
|
vec3 surf_color = illuminate(srgb_to_linear(f_col), light, diffuse_light, ambient_light);
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, true);
|
vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x, f_pos, true);
|
||||||
vec3 color = mix(surf_color, fog_color, fog_level);
|
vec3 color = mix(surf_color, fog_color, fog_level);
|
||||||
|
|
||||||
tgt_color = vec4(color, 1.0);
|
tgt_color = vec4(color, 1.0);
|
||||||
|
BIN
assets/voxygen/texture/noise.png
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/texture/noise.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -40,6 +40,8 @@ gfx_defines! {
|
|||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
|
||||||
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ gfx_defines! {
|
|||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
|
||||||
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
waves: gfx::TextureSampler<[f32; 4]> = "t_waves",
|
waves: gfx::TextureSampler<[f32; 4]> = "t_waves",
|
||||||
|
|
||||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||||
|
@ -28,6 +28,8 @@ gfx_defines! {
|
|||||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
|
|
||||||
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::PASS_TEST,
|
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::PASS_TEST,
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,8 @@ gfx_defines! {
|
|||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
|
||||||
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ gfx_defines! {
|
|||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
|
||||||
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||||
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
tgt_depth: gfx::DepthTarget<TgtDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,8 @@ pub struct Renderer {
|
|||||||
|
|
||||||
shader_reload_indicator: ReloadIndicator,
|
shader_reload_indicator: ReloadIndicator,
|
||||||
|
|
||||||
|
noise_tex: Texture<(gfx::format::R8, gfx::format::Unorm)>,
|
||||||
|
|
||||||
aa_mode: AaMode,
|
aa_mode: AaMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +104,13 @@ impl Renderer {
|
|||||||
|
|
||||||
let sampler = factory.create_sampler_linear();
|
let sampler = factory.create_sampler_linear();
|
||||||
|
|
||||||
|
let noise_tex = Texture::new(
|
||||||
|
&mut factory,
|
||||||
|
&assets::load_expect("voxygen.texture.noise"),
|
||||||
|
Some(gfx::texture::FilterMethod::Trilinear),
|
||||||
|
Some(gfx::texture::WrapMode::Tile),
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
device,
|
device,
|
||||||
encoder: factory.create_command_buffer().into(),
|
encoder: factory.create_command_buffer().into(),
|
||||||
@ -126,6 +135,8 @@ impl Renderer {
|
|||||||
|
|
||||||
shader_reload_indicator,
|
shader_reload_indicator,
|
||||||
|
|
||||||
|
noise_tex,
|
||||||
|
|
||||||
aa_mode,
|
aa_mode,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -351,27 +362,24 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new texture from the provided image.
|
/// Create a new texture from the provided image.
|
||||||
pub fn create_texture<P: Pipeline>(
|
pub fn create_texture(
|
||||||
&mut self,
|
&mut self,
|
||||||
image: &image::DynamicImage,
|
image: &image::DynamicImage,
|
||||||
filter_method: Option<gfx::texture::FilterMethod>,
|
filter_method: Option<gfx::texture::FilterMethod>,
|
||||||
wrap_mode: Option<gfx::texture::WrapMode>,
|
wrap_mode: Option<gfx::texture::WrapMode>,
|
||||||
) -> Result<Texture<P>, RenderError> {
|
) -> Result<Texture, RenderError> {
|
||||||
Texture::new(&mut self.factory, image, filter_method, wrap_mode)
|
Texture::new(&mut self.factory, image, filter_method, wrap_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new dynamic texture (gfx::memory::Usage::Dynamic) with the specified dimensions.
|
/// Create a new dynamic texture (gfx::memory::Usage::Dynamic) with the specified dimensions.
|
||||||
pub fn create_dynamic_texture<P: Pipeline>(
|
pub fn create_dynamic_texture(&mut self, dims: Vec2<u16>) -> Result<Texture, RenderError> {
|
||||||
&mut self,
|
|
||||||
dims: Vec2<u16>,
|
|
||||||
) -> Result<Texture<P>, RenderError> {
|
|
||||||
Texture::new_dynamic(&mut self.factory, dims.x, dims.y)
|
Texture::new_dynamic(&mut self.factory, dims.x, dims.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a texture with the provided offset, size, and data.
|
/// Update a texture with the provided offset, size, and data.
|
||||||
pub fn update_texture<P: Pipeline>(
|
pub fn update_texture(
|
||||||
&mut self,
|
&mut self,
|
||||||
texture: &Texture<P>,
|
texture: &Texture,
|
||||||
offset: [u16; 2],
|
offset: [u16; 2],
|
||||||
size: [u16; 2],
|
size: [u16; 2],
|
||||||
data: &[[u8; 4]],
|
data: &[[u8; 4]],
|
||||||
@ -444,6 +452,7 @@ impl Renderer {
|
|||||||
vbuf: model.vbuf.clone(),
|
vbuf: model.vbuf.clone(),
|
||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth: self.tgt_depth_view.clone(),
|
tgt_depth: self.tgt_depth_view.clone(),
|
||||||
},
|
},
|
||||||
@ -476,6 +485,7 @@ impl Renderer {
|
|||||||
bones: bones.buf.clone(),
|
bones: bones.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth: self.tgt_depth_view.clone(),
|
tgt_depth: self.tgt_depth_view.clone(),
|
||||||
},
|
},
|
||||||
@ -506,6 +516,7 @@ impl Renderer {
|
|||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth: self.tgt_depth_view.clone(),
|
tgt_depth: self.tgt_depth_view.clone(),
|
||||||
},
|
},
|
||||||
@ -520,7 +531,7 @@ impl Renderer {
|
|||||||
locals: &Consts<terrain::Locals>,
|
locals: &Consts<terrain::Locals>,
|
||||||
lights: &Consts<Light>,
|
lights: &Consts<Light>,
|
||||||
shadows: &Consts<Shadow>,
|
shadows: &Consts<Shadow>,
|
||||||
waves: &Texture<fluid::FluidPipeline>,
|
waves: &Texture,
|
||||||
) {
|
) {
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
@ -537,6 +548,7 @@ impl Renderer {
|
|||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
waves: (waves.srv.clone(), waves.sampler.clone()),
|
waves: (waves.srv.clone(), waves.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth: self.tgt_depth_view.clone(),
|
tgt_depth: self.tgt_depth_view.clone(),
|
||||||
@ -568,6 +580,7 @@ impl Renderer {
|
|||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth: self.tgt_depth_view.clone(),
|
tgt_depth: self.tgt_depth_view.clone(),
|
||||||
},
|
},
|
||||||
@ -578,7 +591,7 @@ impl Renderer {
|
|||||||
pub fn render_ui_element(
|
pub fn render_ui_element(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &Model<ui::UiPipeline>,
|
model: &Model<ui::UiPipeline>,
|
||||||
tex: &Texture<ui::UiPipeline>,
|
tex: &Texture,
|
||||||
scissor: Aabr<u16>,
|
scissor: Aabr<u16>,
|
||||||
globals: &Consts<Globals>,
|
globals: &Consts<Globals>,
|
||||||
locals: &Consts<ui::Locals>,
|
locals: &Consts<ui::Locals>,
|
||||||
|
@ -1,26 +1,32 @@
|
|||||||
use super::{gfx_backend, Pipeline, RenderError};
|
use super::{gfx_backend, RenderError};
|
||||||
use gfx::{self, traits::Factory};
|
use gfx::{self, traits::Factory};
|
||||||
use image::{DynamicImage, GenericImageView};
|
use image::{DynamicImage, GenericImageView};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use vek::Vec2;
|
use vek::Vec2;
|
||||||
|
|
||||||
type ShaderFormat = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
|
type DefaultShaderFormat = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb);
|
||||||
|
|
||||||
/// Represents an image that has been uploaded to the GPU.
|
/// Represents an image that has been uploaded to the GPU.
|
||||||
pub struct Texture<P: Pipeline> {
|
pub struct Texture<F: gfx::format::Formatted = DefaultShaderFormat>
|
||||||
pub tex: gfx::handle::Texture<
|
where
|
||||||
gfx_backend::Resources,
|
F::Surface: gfx::format::TextureSurface,
|
||||||
<ShaderFormat as gfx::format::Formatted>::Surface,
|
F::Channel: gfx::format::TextureChannel,
|
||||||
>,
|
<F::Surface as gfx::format::SurfaceTyped>::DataType: Copy,
|
||||||
|
{
|
||||||
|
pub tex: gfx::handle::Texture<gfx_backend::Resources, <F as gfx::format::Formatted>::Surface>,
|
||||||
pub srv: gfx::handle::ShaderResourceView<
|
pub srv: gfx::handle::ShaderResourceView<
|
||||||
gfx_backend::Resources,
|
gfx_backend::Resources,
|
||||||
<ShaderFormat as gfx::format::Formatted>::View,
|
<F as gfx::format::Formatted>::View,
|
||||||
>,
|
>,
|
||||||
pub sampler: gfx::handle::Sampler<gfx_backend::Resources>,
|
pub sampler: gfx::handle::Sampler<gfx_backend::Resources>,
|
||||||
_phantom: PhantomData<P>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> Texture<P> {
|
impl<F: gfx::format::Formatted> Texture<F>
|
||||||
|
where
|
||||||
|
F::Surface: gfx::format::TextureSurface,
|
||||||
|
F::Channel: gfx::format::TextureChannel,
|
||||||
|
<F::Surface as gfx::format::SurfaceTyped>::DataType: Copy,
|
||||||
|
{
|
||||||
pub fn new(
|
pub fn new(
|
||||||
factory: &mut gfx_backend::Factory,
|
factory: &mut gfx_backend::Factory,
|
||||||
image: &DynamicImage,
|
image: &DynamicImage,
|
||||||
@ -28,14 +34,14 @@ impl<P: Pipeline> Texture<P> {
|
|||||||
wrap_mode: Option<gfx::texture::WrapMode>,
|
wrap_mode: Option<gfx::texture::WrapMode>,
|
||||||
) -> Result<Self, RenderError> {
|
) -> Result<Self, RenderError> {
|
||||||
let (tex, srv) = factory
|
let (tex, srv) = factory
|
||||||
.create_texture_immutable_u8::<ShaderFormat>(
|
.create_texture_immutable_u8::<F>(
|
||||||
gfx::texture::Kind::D2(
|
gfx::texture::Kind::D2(
|
||||||
image.width() as u16,
|
image.width() as u16,
|
||||||
image.height() as u16,
|
image.height() as u16,
|
||||||
gfx::texture::AaMode::Single,
|
gfx::texture::AaMode::Single,
|
||||||
),
|
),
|
||||||
gfx::texture::Mipmap::Provided,
|
gfx::texture::Mipmap::Provided,
|
||||||
&[&image.to_rgba().into_raw()],
|
&[&image.raw_pixels()],
|
||||||
)
|
)
|
||||||
.map_err(|err| RenderError::CombinedError(err))?;
|
.map_err(|err| RenderError::CombinedError(err))?;
|
||||||
|
|
||||||
@ -46,7 +52,6 @@ impl<P: Pipeline> Texture<P> {
|
|||||||
filter_method.unwrap_or(gfx::texture::FilterMethod::Scale),
|
filter_method.unwrap_or(gfx::texture::FilterMethod::Scale),
|
||||||
wrap_mode.unwrap_or(gfx::texture::WrapMode::Clamp),
|
wrap_mode.unwrap_or(gfx::texture::WrapMode::Clamp),
|
||||||
)),
|
)),
|
||||||
_phantom: PhantomData,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,16 +69,12 @@ impl<P: Pipeline> Texture<P> {
|
|||||||
1 as gfx::texture::Level,
|
1 as gfx::texture::Level,
|
||||||
gfx::memory::Bind::SHADER_RESOURCE,
|
gfx::memory::Bind::SHADER_RESOURCE,
|
||||||
gfx::memory::Usage::Dynamic,
|
gfx::memory::Usage::Dynamic,
|
||||||
Some(<<ShaderFormat as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type()),
|
Some(<<F as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type()),
|
||||||
)
|
)
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
||||||
|
|
||||||
let srv = factory
|
let srv = factory
|
||||||
.view_texture_as_shader_resource::<ShaderFormat>(
|
.view_texture_as_shader_resource::<F>(&tex, (0, 0), gfx::format::Swizzle::new())
|
||||||
&tex,
|
|
||||||
(0, 0),
|
|
||||||
gfx::format::Swizzle::new(),
|
|
||||||
)
|
|
||||||
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Resource(err)))?;
|
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Resource(err)))?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -83,7 +84,6 @@ impl<P: Pipeline> Texture<P> {
|
|||||||
gfx::texture::FilterMethod::Scale,
|
gfx::texture::FilterMethod::Scale,
|
||||||
gfx::texture::WrapMode::Clamp,
|
gfx::texture::WrapMode::Clamp,
|
||||||
)),
|
)),
|
||||||
_phantom: PhantomData,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ impl<P: Pipeline> Texture<P> {
|
|||||||
encoder: &mut gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
encoder: &mut gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
||||||
offset: [u16; 2],
|
offset: [u16; 2],
|
||||||
size: [u16; 2],
|
size: [u16; 2],
|
||||||
data: &[[u8; 4]],
|
data: &[<F::Surface as gfx::format::SurfaceTyped>::DataType],
|
||||||
) -> Result<(), RenderError> {
|
) -> Result<(), RenderError> {
|
||||||
let info = gfx::texture::ImageInfoCommon {
|
let info = gfx::texture::ImageInfoCommon {
|
||||||
xoffset: offset[0],
|
xoffset: offset[0],
|
||||||
@ -106,7 +106,7 @@ impl<P: Pipeline> Texture<P> {
|
|||||||
mipmap: 0,
|
mipmap: 0,
|
||||||
};
|
};
|
||||||
encoder
|
encoder
|
||||||
.update_texture::<<ShaderFormat as gfx::format::Formatted>::Surface, ShaderFormat>(
|
.update_texture::<<F as gfx::format::Formatted>::Surface, F>(
|
||||||
&self.tex, None, info, data,
|
&self.tex, None, info, data,
|
||||||
)
|
)
|
||||||
.map_err(|err| RenderError::TexUpdateError(err))
|
.map_err(|err| RenderError::TexUpdateError(err))
|
||||||
|
@ -212,7 +212,7 @@ pub struct Terrain<V: RectRasterableVol> {
|
|||||||
|
|
||||||
// GPU data
|
// GPU data
|
||||||
sprite_models: HashMap<(BlockKind, usize), Model<SpritePipeline>>,
|
sprite_models: HashMap<(BlockKind, usize), Model<SpritePipeline>>,
|
||||||
waves: Texture<FluidPipeline>,
|
waves: Texture,
|
||||||
|
|
||||||
phantom: PhantomData<V>,
|
phantom: PhantomData<V>,
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ const POSITION_TOLERANCE: f32 = 0.1;
|
|||||||
|
|
||||||
pub struct Cache {
|
pub struct Cache {
|
||||||
glyph_cache: GlyphCache<'static>,
|
glyph_cache: GlyphCache<'static>,
|
||||||
glyph_cache_tex: Texture<UiPipeline>,
|
glyph_cache_tex: Texture,
|
||||||
graphic_cache: GraphicCache,
|
graphic_cache: GraphicCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,10 +38,10 @@ impl Cache {
|
|||||||
graphic_cache: GraphicCache::new(renderer),
|
graphic_cache: GraphicCache::new(renderer),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn glyph_cache_tex(&self) -> &Texture<UiPipeline> {
|
pub fn glyph_cache_tex(&self) -> &Texture {
|
||||||
&self.glyph_cache_tex
|
&self.glyph_cache_tex
|
||||||
}
|
}
|
||||||
pub fn glyph_cache_mut_and_tex(&mut self) -> (&mut GlyphCache<'static>, &Texture<UiPipeline>) {
|
pub fn glyph_cache_mut_and_tex(&mut self) -> (&mut GlyphCache<'static>, &Texture) {
|
||||||
(&mut self.glyph_cache, &self.glyph_cache_tex)
|
(&mut self.glyph_cache, &self.glyph_cache_tex)
|
||||||
}
|
}
|
||||||
pub fn graphic_cache(&self) -> &GraphicCache {
|
pub fn graphic_cache(&self) -> &GraphicCache {
|
||||||
|
@ -84,7 +84,7 @@ pub struct GraphicCache {
|
|||||||
|
|
||||||
// Atlases with the index of their texture in the textures vec
|
// Atlases with the index of their texture in the textures vec
|
||||||
atlases: Vec<(SimpleAtlasAllocator, usize)>,
|
atlases: Vec<(SimpleAtlasAllocator, usize)>,
|
||||||
textures: Vec<Texture<UiPipeline>>,
|
textures: Vec<Texture>,
|
||||||
// Stores the location of graphics rendered at a particular resolution and cached on the cpu
|
// Stores the location of graphics rendered at a particular resolution and cached on the cpu
|
||||||
cache_map: HashMap<Parameters, CachedDetails>,
|
cache_map: HashMap<Parameters, CachedDetails>,
|
||||||
}
|
}
|
||||||
@ -131,7 +131,7 @@ impl GraphicCache {
|
|||||||
self.graphic_map.get(&id)
|
self.graphic_map.get(&id)
|
||||||
}
|
}
|
||||||
/// Used to aquire textures for rendering
|
/// Used to aquire textures for rendering
|
||||||
pub fn get_tex(&self, id: TexId) -> &Texture<UiPipeline> {
|
pub fn get_tex(&self, id: TexId) -> &Texture {
|
||||||
self.textures.get(id.0).expect("Invalid TexId used")
|
self.textures.get(id.0).expect("Invalid TexId used")
|
||||||
}
|
}
|
||||||
pub fn clear_cache(&mut self, renderer: &mut Renderer) {
|
pub fn clear_cache(&mut self, renderer: &mut Renderer) {
|
||||||
@ -302,7 +302,7 @@ fn draw_graphic(graphic_map: &GraphicMap, graphic_id: Id, dims: Vec2<u16>) -> Op
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_atlas_texture(renderer: &mut Renderer) -> (SimpleAtlasAllocator, Texture<UiPipeline>) {
|
fn create_atlas_texture(renderer: &mut Renderer) -> (SimpleAtlasAllocator, Texture) {
|
||||||
let (w, h) = renderer.get_resolution().into_tuple();
|
let (w, h) = renderer.get_resolution().into_tuple();
|
||||||
|
|
||||||
let max_texture_size = renderer.max_texture_size();
|
let max_texture_size = renderer.max_texture_size();
|
||||||
@ -326,12 +326,7 @@ fn aabr_from_alloc_rect(rect: guillotiere::Rectangle) -> Aabr<u16> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upload_image(
|
fn upload_image(renderer: &mut Renderer, aabr: Aabr<u16>, tex: &Texture, image: &RgbaImage) {
|
||||||
renderer: &mut Renderer,
|
|
||||||
aabr: Aabr<u16>,
|
|
||||||
tex: &Texture<UiPipeline>,
|
|
||||||
image: &RgbaImage,
|
|
||||||
) {
|
|
||||||
let offset = aabr.min.into_array();
|
let offset = aabr.min.into_array();
|
||||||
let size = aabr.size().into_array();
|
let size = aabr.size().into_array();
|
||||||
if let Err(err) = renderer.update_texture(
|
if let Err(err) = renderer.update_texture(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user