Add skybox rendering support
This commit is contained in:
parent
f6a9d18c5c
commit
f943e4c945
4 changed files with 93 additions and 3 deletions
22
resources/shaders/skybox.frag
Normal file
22
resources/shaders/skybox.frag
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 direction;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
uniform sampler2D equirect;
|
||||||
|
|
||||||
|
const vec2 inv_atan = vec2(0.15915494309, 0.31830988618);
|
||||||
|
|
||||||
|
vec2 sample_spherical_map(vec3 v) {
|
||||||
|
vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
|
||||||
|
uv *= inv_atan;
|
||||||
|
uv += 0.5;
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = sample_spherical_map(normalize(direction));
|
||||||
|
vec3 color = texture(equirect, uv).rgb;
|
||||||
|
frag_color = vec4(color, 1.0);
|
||||||
|
}
|
||||||
15
resources/shaders/skybox.vert
Normal file
15
resources/shaders/skybox.vert
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 position;
|
||||||
|
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
out vec3 direction;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
direction = position;
|
||||||
|
vec4 pos = projection * view * vec4(position, 1.0);
|
||||||
|
gl_Position = pos.xyww;
|
||||||
|
}
|
||||||
BIN
resources/skyboxes/sky_24_2k.png
Normal file
BIN
resources/skyboxes/sky_24_2k.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
|
|
@ -1,12 +1,14 @@
|
||||||
use crate::camera::Camera;
|
use crate::camera::Camera;
|
||||||
use crate::ecs::{ModelHandle, Transform};
|
use crate::ecs::{ModelHandle, Transform};
|
||||||
use crate::model::{Model};
|
use crate::model::{Model, Mesh};
|
||||||
use glium::texture::{RawImage2d, SrgbTexture2d};
|
use glium::texture::{RawImage2d, SrgbTexture2d};
|
||||||
use glium::{uniform, Program, Surface};
|
use glium::{uniform, Program, Surface};
|
||||||
use glium::uniforms::{MinifySamplerFilter, MagnifySamplerFilter, SamplerWrapFunction};
|
use glium::uniforms::{MinifySamplerFilter, MagnifySamplerFilter, SamplerWrapFunction};
|
||||||
use glam::Vec3;
|
use glam::{Vec3, Vec4};
|
||||||
use hecs::World;
|
use hecs::World;
|
||||||
use glium::glutin::surface::WindowSurface;
|
use glium::glutin::surface::WindowSurface;
|
||||||
|
use image::io::Reader as ImageReader;
|
||||||
|
use glium::draw_parameters::DepthTest;
|
||||||
|
|
||||||
pub struct GliumRenderer {
|
pub struct GliumRenderer {
|
||||||
display: glium::Display<WindowSurface>,
|
display: glium::Display<WindowSurface>,
|
||||||
|
|
@ -16,6 +18,10 @@ pub struct GliumRenderer {
|
||||||
pub models: Vec<Model>,
|
pub models: Vec<Model>,
|
||||||
|
|
||||||
params: glium::DrawParameters<'static>,
|
params: glium::DrawParameters<'static>,
|
||||||
|
|
||||||
|
skybox_program: Program,
|
||||||
|
skybox_texture: SrgbTexture2d,
|
||||||
|
skybox_mesh: Mesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GliumRenderer {
|
impl GliumRenderer {
|
||||||
|
|
@ -40,12 +46,27 @@ impl GliumRenderer {
|
||||||
.. Default::default()
|
.. Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let sky_vert = include_str!("../resources/shaders/skybox.vert");
|
||||||
|
let sky_frag = include_str!("../resources/shaders/skybox.frag");
|
||||||
|
let skybox_program = Program::from_source(&display, sky_vert, sky_frag, None)?;
|
||||||
|
|
||||||
|
let image = ImageReader::open("resources/skyboxes/sky_24_2k.png")?.decode()?.to_rgba8();
|
||||||
|
let dimensions = image.dimensions();
|
||||||
|
let raw = RawImage2d::from_raw_rgba(image.into_raw(), dimensions);
|
||||||
|
let skybox_texture = SrgbTexture2d::new(&display, raw)?;
|
||||||
|
|
||||||
|
let cube_model = crate::gltf_loader::load_gltf("resources/models/cube.gltf", &display)?;
|
||||||
|
let skybox_mesh = cube_model.mesh;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
display,
|
display,
|
||||||
program,
|
program,
|
||||||
white_tex,
|
white_tex,
|
||||||
models: Vec::new(),
|
models: Vec::new(),
|
||||||
params,
|
params,
|
||||||
|
skybox_program,
|
||||||
|
skybox_texture,
|
||||||
|
skybox_mesh,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,6 +115,38 @@ impl GliumRenderer {
|
||||||
&self.params,
|
&self.params,
|
||||||
).unwrap();
|
).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render skybox
|
||||||
|
let mut sky_view = cam.view();
|
||||||
|
sky_view.w_axis = Vec4::new(0.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
let mut sampler = self.skybox_texture.sampled();
|
||||||
|
sampler = sampler.wrap_function(SamplerWrapFunction::Clamp);
|
||||||
|
sampler = sampler.minify_filter(MinifySamplerFilter::Linear);
|
||||||
|
sampler = sampler.magnify_filter(MagnifySamplerFilter::Linear);
|
||||||
|
|
||||||
|
let uniforms = uniform! {
|
||||||
|
view: sky_view.to_cols_array_2d(),
|
||||||
|
projection: cam.projection().to_cols_array_2d(),
|
||||||
|
equirect: sampler,
|
||||||
|
};
|
||||||
|
|
||||||
|
let sky_params = glium::DrawParameters {
|
||||||
|
depth: glium::Depth {
|
||||||
|
test: DepthTest::IfLessOrEqual,
|
||||||
|
write: false,
|
||||||
|
.. Default::default()
|
||||||
|
},
|
||||||
|
.. Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
target.draw(
|
||||||
|
&self.skybox_mesh.vbuf,
|
||||||
|
&self.skybox_mesh.ibuf,
|
||||||
|
&self.skybox_program,
|
||||||
|
&uniforms,
|
||||||
|
&sky_params,
|
||||||
|
).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_into<S: Surface>(&mut self, world: &World, target: &mut S) {
|
pub fn render_into<S: Surface>(&mut self, world: &World, target: &mut S) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue