lyra-engine/lyra-game/src/render/material.rs

95 lines
3.2 KiB
Rust
Executable File

use std::rc::Rc;
use lyra_resource::{ResHandle, Texture};
use super::texture::RenderTexture;
pub struct MaterialSpecular {
pub factor: f32,
pub color_factor: glam::Vec3,
pub texture: Option<RenderTexture>,
pub color_texture: Option<RenderTexture>,
}
fn texture_to_render(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: &Rc<wgpu::BindGroupLayout>, i: &Option<ResHandle<Texture>>) -> Option<RenderTexture> {
if let Some(tex) = i {
RenderTexture::from_resource(device, queue, bg_layout.clone(), tex, None).ok()
} else {
None
}
}
impl MaterialSpecular {
pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Rc<wgpu::BindGroupLayout>, value: &lyra_resource::gltf::Specular) -> Self {
let tex = texture_to_render(device, queue, &bg_layout, &value.texture);
let color_tex = texture_to_render(device, queue, &bg_layout, &value.color_texture);
Self {
factor: value.factor,
color_factor: value.color_factor,
texture: tex,
color_texture: color_tex,
}
}
}
//#[derive(Clone)]
pub struct Material {
pub shader_id: u64,
pub diffuse_texture: Option<RenderTexture>,
pub ambient: glam::Vec3,
pub diffuse: glam::Vec3,
pub shininess: f32,
pub specular: Option<MaterialSpecular>
}
impl Material {
pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Rc<wgpu::BindGroupLayout>, value: &lyra_resource::gltf::Material) -> Self {
let diffuse_texture = texture_to_render(device, queue, &bg_layout, &value.base_color_texture);
let specular = value.specular.as_ref().map(|s| MaterialSpecular::from_resource(device, queue, bg_layout.clone(), s));
Self {
shader_id: value.shader_uuid.unwrap_or(0),
diffuse_texture,
//ambient: glam::Vec3::new(1.0, 0.5, 0.31),
//diffuse: glam::Vec3::new(value.base_color.x, value.base_color.y, value.base_color.z),
//diffuse: glam::Vec3::new(1.0, 0.5, 0.31),
//specular: glam::Vec3::new(0.5, 0.5, 0.5),
ambient: glam::Vec3::new(1.0, 1.0, 1.0),
diffuse: glam::Vec3::new(1.0, 1.0, 1.0),
shininess: 32.0,
specular
}
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, bytemuck::Pod, bytemuck::Zeroable)]
pub struct MaterialUniform {
pub ambient: glam::Vec4,
//pub _padding: u32,
pub diffuse: glam::Vec4,
//pub _padding2: u32,
pub specular: glam::Vec4,
//pub _padding3: u32,
pub shininess: f32,
pub _padding1: [u32; 3],
}
impl From<&Material> for MaterialUniform {
fn from(value: &Material) -> Self {
let specular_factor = value.specular.as_ref().map(|s| glam::Vec3::new(s.factor, s.factor, s.factor))
.unwrap_or_else(|| glam::Vec3::new(0.5, 0.5, 0.5));
Self {
ambient: glam::Vec4::new(value.ambient.x, value.ambient.y, value.ambient.z, 0.0),
diffuse: glam::Vec4::new(value.diffuse.x, value.diffuse.y, value.diffuse.z, 0.0),
specular: glam::Vec4::new(specular_factor.x, specular_factor.y, specular_factor.z, 0.0),
shininess: value.shininess,
_padding1: [0; 3]
}
}
}