diff options
Diffstat (limited to 'engine/src/shader/default.rs')
| -rw-r--r-- | engine/src/shader/default.rs | 379 |
1 files changed, 0 insertions, 379 deletions
diff --git a/engine/src/shader/default.rs b/engine/src/shader/default.rs deleted file mode 100644 index c174e8b..0000000 --- a/engine/src/shader/default.rs +++ /dev/null @@ -1,379 +0,0 @@ -use std::path::Path; -use std::sync::LazyLock; - -use ecs::query::term::With; - -use crate::asset::{Assets, Label as AssetLabel}; -use crate::camera::{Active as ActiveCamera, Camera}; -use crate::data_types::dimens::Dimens; -use crate::draw_flags::NoDraw; -use crate::ecs::actions::Actions; -use crate::ecs::query::term::Without; -use crate::ecs::sole::Single; -use crate::ecs::Query; -use crate::lighting::{DirectionalLight, GlobalLight, PointLight}; -use crate::material::{Flags as MaterialFlags, Material}; -use crate::matrix::Matrix; -use crate::model::{MaterialSearchResult, Model}; -use crate::projection::{ClipVolume as ProjectionClipVolume, Projection}; -use crate::rendering::{ - PendingShaderBindings, - SurfaceSpec, - TargetWindow as RenderingTargetWindow, -}; -use crate::shader::cursor::{BindingValue as ShaderBindingValue, Cursor as ShaderCursor}; -use crate::shader::{ - Context as ShaderContext, - ModuleSource as ShaderModuleSource, - Shader, -}; -use crate::texture::WHITE_1X1_ASSET_LABEL as TEXTURE_WHITE_1X1_ASSET_LABEL; -use crate::transform::{Scale, Transform, WorldPosition}; -use crate::vector::Vec3; -use crate::windowing::dpi::PhysicalSize; -use crate::windowing::window::Window; - -pub static ASSET_LABEL: LazyLock<AssetLabel> = LazyLock::new(|| AssetLabel { - path: Path::new("").into(), - name: Some("default_shader".into()), -}); - -pub fn enqueue_set_shader_bindings( - renderable_query: Query<RenderableEntity<'_>, (Without<NoDraw>,)>, - camera_query: Query<(&Camera, &WorldPosition, &ActiveCamera)>, - window_query: Query<(&Window, &SurfaceSpec), (With<RenderingTargetWindow>,)>, - point_light_query: Query<(&PointLight, &WorldPosition)>, - directional_light_query: Query<(&DirectionalLight,)>, - assets: Single<Assets>, - shader_context: Single<ShaderContext>, - global_light: Single<GlobalLight>, - mut actions: Actions, -) -{ - let Some((camera, camera_world_pos, _)) = camera_query.iter().next() else { - tracing::trace!("No current camera"); - return; - }; - - let default_shader_asset = assets - .get_handle_to_loaded::<ShaderModuleSource>(ASSET_LABEL.clone()) - .unwrap(); - - for ( - entity_id, - (model, material_flags, world_pos, scale, shader, mut pending_shader_bindings), - ) in renderable_query.iter_with_euids() - { - let shader_asset = match &shader { - Some(shader) => &shader.asset_handle, - None => &default_shader_asset, - }; - - if shader_asset.id() != default_shader_asset.id() { - continue; - } - - let has_pending_shader_bindings_comp = pending_shader_bindings.is_some(); - - let shader_bindings = match pending_shader_bindings.as_deref_mut() { - Some(pending_shader_bindings) => pending_shader_bindings, - None => &mut PendingShaderBindings::default(), - }; - - // Bindings are cleared to prevent them from growing infinitely - shader_bindings.bindings.clear(); - shader_bindings.surface_specific_bindings.clear(); - - let Some(shader_program) = shader_context.get_program(&shader_asset.id()) else { - continue; - }; - - let Some(model_spec) = assets.get(&model.spec_asset) else { - continue; - }; - - let shader_cursor = ShaderCursor::new( - shader_program - .reflection(0) - .unwrap() - .global_params_var_layout() - .unwrap(), - ); - - let model_matrix = create_model_matrix(Transform { - position: world_pos.as_deref().cloned().unwrap_or_default().position, - scale: scale.as_deref().cloned().unwrap_or_default().scale, - }); - - let inverted_model_matrix = model_matrix.inverse(); - - let model_material = match model_spec.find_first_material(&assets) { - MaterialSearchResult::Found(model_material_asset) => { - let Some(model_material) = assets.get(&model_material_asset) else { - continue; - }; - - model_material - } - MaterialSearchResult::NotFound => { - continue; - } - MaterialSearchResult::NoMaterials => &const { Material::builder().build() }, - }; - - if [ - &model_material.ambient_map, - &model_material.diffuse_map, - &model_material.specular_map, - ] - .into_iter() - .flatten() - .any(|texture_asset| !assets.is_loaded_and_has_type(&texture_asset)) - { - continue; - } - - let material_flags = material_flags - .as_deref() - .unwrap_or(&const { MaterialFlags::builder().build() }); - - let model_3d_shader_cursor = shader_cursor.field("Uniforms").field("model_3d"); - let lighting_shader_cursor = shader_cursor.field("Uniforms").field("lighting"); - let material_shader_cursor = lighting_shader_cursor.field("material"); - - shader_bindings.extend([ - (model_3d_shader_cursor.field("model"), model_matrix.into()), - ( - model_3d_shader_cursor.field("model_inverted"), - inverted_model_matrix.into(), - ), - ( - model_3d_shader_cursor.field("view"), - create_view_matrix(&camera, camera_world_pos.position).into(), - ), - ( - lighting_shader_cursor.field("view_pos"), - camera_world_pos.position.into(), - ), - ( - material_shader_cursor.field("ambient"), - Vec3::from( - if material_flags.use_ambient_color { - &model_material.ambient - } else { - &global_light.ambient - } - .clone(), - ) - .into(), - ), - ( - material_shader_cursor.field("diffuse"), - Vec3::from(model_material.diffuse.clone()).into(), - ), - ( - material_shader_cursor.field("specular"), - Vec3::from(model_material.specular.clone()).into(), - ), - ( - material_shader_cursor.field("shininess"), - model_material.shininess.into(), - ), - ( - lighting_shader_cursor.field("directional_light_cnt"), - u32::try_from(directional_light_query.iter().count()) - .expect( - "Directional light count does not fit in 32-bit unsigned integer", - ) - .into(), - ), - ( - lighting_shader_cursor.field("point_light_cnt"), - u32::try_from(point_light_query.iter().count()) - .expect("Point light count does not fit in 32-bit unsigned integer") - .into(), - ), - ]); - - for (window, window_surface_spec) in &window_query { - shader_bindings.surface_specific_bindings.push(( - window_surface_spec.id, - model_3d_shader_cursor - .field("projection") - .into_binding_location(), - create_projection_matrix(&camera, &window.inner_size).into(), - )); - } - - shader_bindings.extend(point_light_query.iter().enumerate().flat_map( - |(point_light_index, (point_light, point_light_world_pos))| { - let point_light_shader_cursor = lighting_shader_cursor - .field("point_lights") - .element(point_light_index); - - let phong_shader_cursor = point_light_shader_cursor.field("phong"); - - let attenuation_props_shader_cursor = - point_light_shader_cursor.field("attenuation_props"); - - [ - ( - phong_shader_cursor.field("diffuse"), - Vec3::from(point_light.diffuse.clone()).into(), - ), - ( - phong_shader_cursor.field("specular"), - Vec3::from(point_light.specular.clone()).into(), - ), - ( - point_light_shader_cursor.field("position"), - (point_light_world_pos.position + point_light.local_position) - .into(), - ), - ( - attenuation_props_shader_cursor.field("constant"), - point_light.attenuation_params.constant.into(), - ), - ( - attenuation_props_shader_cursor.field("linear"), - point_light.attenuation_params.linear.into(), - ), - ( - attenuation_props_shader_cursor.field("quadratic"), - point_light.attenuation_params.quadratic.into(), - ), - ] - }, - )); - - shader_bindings.extend(directional_light_query.iter().enumerate().flat_map( - |(directional_light_index, (directional_light,))| { - let directional_light_shader_cursor = lighting_shader_cursor - .field("directional_lights") - .element(directional_light_index); - - let phong_shader_cursor = directional_light_shader_cursor.field("phong"); - - [ - ( - phong_shader_cursor.field("diffuse"), - Vec3::from(directional_light.diffuse.clone()).into(), - ), - ( - phong_shader_cursor.field("specular"), - Vec3::from(directional_light.specular.clone()).into(), - ), - ( - directional_light_shader_cursor.field("direction"), - directional_light.direction.into(), - ), - ] - }, - )); - - shader_bindings.bindings.push(( - shader_cursor.field("ambient_map").into_binding_location(), - ShaderBindingValue::Texture( - model_material - .ambient_map - .as_ref() - .map(|ambient_map| ambient_map.clone()) - .unwrap_or_else(|| { - assets - .get_handle_to_loaded(TEXTURE_WHITE_1X1_ASSET_LABEL.clone()) - .expect("Not possible") - }) - .id() - .into(), - ), - )); - - shader_bindings.bindings.push(( - shader_cursor.field("diffuse_map").into_binding_location(), - ShaderBindingValue::Texture( - model_material - .diffuse_map - .as_ref() - .map(|diffuse_map| diffuse_map.clone()) - .unwrap_or_else(|| { - assets - .get_handle_to_loaded(TEXTURE_WHITE_1X1_ASSET_LABEL.clone()) - .expect("Not possible") - }) - .id() - .into(), - ), - )); - - shader_bindings.bindings.push(( - shader_cursor.field("specular_map").into_binding_location(), - ShaderBindingValue::Texture( - model_material - .specular_map - .as_ref() - .map(|specular_map| specular_map.clone()) - .unwrap_or_else(|| { - assets - .get_handle_to_loaded(TEXTURE_WHITE_1X1_ASSET_LABEL.clone()) - .expect("Not possible") - }) - .id() - .into(), - ), - )); - - if !has_pending_shader_bindings_comp { - actions.add_components(entity_id, (shader_bindings.clone(),)); - } - } -} - -fn create_model_matrix(transform: Transform) -> Matrix<f32, 4, 4> -{ - let mut matrix = Matrix::new_identity(); - - matrix.translate(&transform.position); - matrix.scale(&transform.scale); - - matrix -} - -fn create_view_matrix(camera: &Camera, camera_world_pos: Vec3<f32>) -> Matrix<f32, 4, 4> -{ - let mut view = Matrix::new(); - - // tracing::debug!("Camera target: {:?}", camera.target); - - view.look_at(camera_world_pos, camera.target, camera.global_up); - - view -} - -fn create_projection_matrix( - camera: &Camera, - window_size: &PhysicalSize<u32>, -) -> Matrix<f32, 4, 4> -{ - match &camera.projection { - Projection::Perspective(perspective_proj) => perspective_proj.to_matrix_rh( - window_size.width as f32 / window_size.height as f32, - ProjectionClipVolume::NegOneToOne, - ), - Projection::Orthographic(orthographic_proj) => orthographic_proj.to_matrix_rh( - Dimens { - width: window_size.width as f32, - height: window_size.height as f32, - }, - ProjectionClipVolume::NegOneToOne, - ), - } -} - -type RenderableEntity<'a> = ( - &'a Model, - Option<&'a MaterialFlags>, - Option<&'a WorldPosition>, - Option<&'a Scale>, - Option<&'a Shader>, - Option<&'a mut PendingShaderBindings>, -); |
