summaryrefslogtreecommitdiff
path: root/engine/src/shader
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/shader')
-rw-r--r--engine/src/shader/cursor.rs159
-rw-r--r--engine/src/shader/default.rs379
2 files changed, 0 insertions, 538 deletions
diff --git a/engine/src/shader/cursor.rs b/engine/src/shader/cursor.rs
deleted file mode 100644
index 8011012..0000000
--- a/engine/src/shader/cursor.rs
+++ /dev/null
@@ -1,159 +0,0 @@
-use crate::data_types::matrix::Matrix;
-use crate::data_types::vector::Vec3;
-use crate::rendering::object::Id as RenderingObjectId;
-use crate::shader::{TypeKind, TypeLayout, VariableLayout};
-
-/// Shader cursor
-#[derive(Clone)]
-pub struct Cursor<'a>
-{
- type_layout: TypeLayout<'a>,
- binding_location: BindingLocation,
-}
-
-impl<'a> Cursor<'a>
-{
- pub fn new(var_layout: VariableLayout<'a>) -> Self
- {
- let binding_location = BindingLocation {
- binding_index: var_layout.binding_index(),
- binding_size: 0,
- byte_offset: var_layout.offset(),
- };
-
- Self {
- type_layout: var_layout.type_layout().unwrap(),
- binding_location,
- }
- }
-
- pub fn field(&self, name: &str) -> Self
- {
- let Some(field_var_layout) = self.type_layout.get_field_by_name(name) else {
- panic!("Field '{name}' does not exist");
- };
-
- let field_type_kind = field_var_layout.ty().unwrap().kind();
-
- let field_var_layout = match field_type_kind {
- TypeKind::ConstantBuffer => field_var_layout
- .type_layout()
- .expect("Constant buffer field has no type layout")
- .element_var_layout()
- .expect("Constant buffer field type layout has no element var layout"),
- TypeKind::Array
- | TypeKind::Matrix
- | TypeKind::Scalar
- | TypeKind::Vector
- | TypeKind::Struct
- | TypeKind::Resource => field_var_layout,
- type_kind => unimplemented!("Type kind {type_kind:?} is not yet supported"),
- };
-
- Self {
- type_layout: field_var_layout.type_layout().unwrap(),
- binding_location: BindingLocation {
- binding_index: self.binding_location.binding_index
- + field_var_layout.binding_index(),
- binding_size: if field_type_kind == TypeKind::ConstantBuffer {
- field_var_layout
- .type_layout()
- .unwrap()
- .uniform_size()
- .unwrap()
- } else {
- self.binding_location.binding_size
- },
- byte_offset: self.binding_location.byte_offset
- + field_var_layout.offset(),
- },
- }
- }
-
- pub fn element(mut self, index: usize) -> Self
- {
- let element_type_layout = self.type_layout.element_type_layout().unwrap();
-
- self.binding_location.byte_offset += index * element_type_layout.stride();
-
- self.type_layout = element_type_layout;
-
- self
- }
-
- pub fn with_field(self, name: &str, func: impl FnOnce(Self) -> Self) -> Self
- {
- let _ = func(self.field(name));
-
- self
- }
-
- pub fn binding_location(&self) -> &BindingLocation
- {
- &self.binding_location
- }
-
- pub fn into_binding_location(self) -> BindingLocation
- {
- self.binding_location
- }
-}
-
-#[derive(Debug, Clone)]
-pub struct BindingLocation
-{
- pub binding_index: u32,
- pub binding_size: usize,
- pub byte_offset: usize,
-}
-
-#[derive(Debug, Clone)]
-pub enum BindingValue
-{
- Uint(u32),
- Int(i32),
- Float(f32),
- FVec3(Vec3<f32>),
- FMat4x4(Matrix<f32, 4, 4>),
- Texture(RenderingObjectId),
-}
-
-impl From<u32> for BindingValue
-{
- fn from(value: u32) -> Self
- {
- BindingValue::Uint(value)
- }
-}
-
-impl From<i32> for BindingValue
-{
- fn from(value: i32) -> Self
- {
- BindingValue::Int(value)
- }
-}
-
-impl From<f32> for BindingValue
-{
- fn from(value: f32) -> Self
- {
- BindingValue::Float(value)
- }
-}
-
-impl From<Vec3<f32>> for BindingValue
-{
- fn from(vec: Vec3<f32>) -> Self
- {
- BindingValue::FVec3(vec)
- }
-}
-
-impl From<Matrix<f32, 4, 4>> for BindingValue
-{
- fn from(matrix: Matrix<f32, 4, 4>) -> Self
- {
- BindingValue::FMat4x4(matrix)
- }
-}
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>,
-);