Prototype implementation of specular maps
This commit is contained in:
parent
a0e6a16f03
commit
e412e589d1
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
Binary file not shown.
After Width: | Height: | Size: 457 KiB |
Binary file not shown.
|
@ -0,0 +1,160 @@
|
|||
{
|
||||
"asset":{
|
||||
"generator":"Khronos glTF Blender I/O v3.6.6",
|
||||
"version":"2.0"
|
||||
},
|
||||
"extensionsUsed":[
|
||||
"KHR_materials_specular",
|
||||
"KHR_materials_ior"
|
||||
],
|
||||
"scene":0,
|
||||
"scenes":[
|
||||
{
|
||||
"name":"Scene",
|
||||
"nodes":[
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes":[
|
||||
{
|
||||
"mesh":0,
|
||||
"name":"Cube"
|
||||
}
|
||||
],
|
||||
"materials":[
|
||||
{
|
||||
"doubleSided":true,
|
||||
"extensions":{
|
||||
"KHR_materials_specular":{
|
||||
"specularColorTexture":{
|
||||
"index":0
|
||||
}
|
||||
},
|
||||
"KHR_materials_ior":{
|
||||
"ior":1.4500000476837158
|
||||
}
|
||||
},
|
||||
"name":"Material",
|
||||
"pbrMetallicRoughness":{
|
||||
"baseColorTexture":{
|
||||
"index":1
|
||||
},
|
||||
"metallicFactor":0,
|
||||
"roughnessFactor":0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"meshes":[
|
||||
{
|
||||
"name":"Cube",
|
||||
"primitives":[
|
||||
{
|
||||
"attributes":{
|
||||
"POSITION":0,
|
||||
"TEXCOORD_0":1,
|
||||
"NORMAL":2
|
||||
},
|
||||
"indices":3,
|
||||
"material":0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"textures":[
|
||||
{
|
||||
"sampler":0,
|
||||
"source":0
|
||||
},
|
||||
{
|
||||
"sampler":0,
|
||||
"source":1
|
||||
}
|
||||
],
|
||||
"images":[
|
||||
{
|
||||
"mimeType":"image/png",
|
||||
"name":"Image",
|
||||
"uri":"Image.png"
|
||||
},
|
||||
{
|
||||
"mimeType":"image/png",
|
||||
"name":"container2",
|
||||
"uri":"container2.png"
|
||||
}
|
||||
],
|
||||
"accessors":[
|
||||
{
|
||||
"bufferView":0,
|
||||
"componentType":5126,
|
||||
"count":24,
|
||||
"max":[
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"min":[
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
],
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":1,
|
||||
"componentType":5126,
|
||||
"count":24,
|
||||
"type":"VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView":2,
|
||||
"componentType":5126,
|
||||
"count":24,
|
||||
"type":"VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView":3,
|
||||
"componentType":5123,
|
||||
"count":36,
|
||||
"type":"SCALAR"
|
||||
}
|
||||
],
|
||||
"bufferViews":[
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":288,
|
||||
"byteOffset":0,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":192,
|
||||
"byteOffset":288,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":288,
|
||||
"byteOffset":480,
|
||||
"target":34962
|
||||
},
|
||||
{
|
||||
"buffer":0,
|
||||
"byteLength":72,
|
||||
"byteOffset":768,
|
||||
"target":34963
|
||||
}
|
||||
],
|
||||
"samplers":[
|
||||
{
|
||||
"magFilter":9729,
|
||||
"minFilter":9987
|
||||
}
|
||||
],
|
||||
"buffers":[
|
||||
{
|
||||
"byteLength":840,
|
||||
"uri":"crate.bin"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -71,9 +71,10 @@ async fn main() {
|
|||
|
||||
let mut resman = world.get_resource_mut::<ResourceManager>().unwrap();
|
||||
//let diffuse_texture = resman.request::<Texture>("assets/happy-tree.png").unwrap();
|
||||
//let antique_camera_model = resman.request::<Model>("assets/AntiqueCamera.glb").unwrap();
|
||||
let antique_camera_model = resman.request::<Model>("assets/AntiqueCamera.glb").unwrap();
|
||||
//let cube_model = resman.request::<Model>("assets/cube-texture-bin.glb").unwrap();
|
||||
let cube_model = resman.request::<Model>("assets/texture-sep/texture-sep.gltf").unwrap();
|
||||
let crate_model = resman.request::<Model>("assets/crate/crate.gltf").unwrap();
|
||||
drop(resman);
|
||||
|
||||
/* world.spawn((
|
||||
|
@ -81,10 +82,10 @@ async fn main() {
|
|||
TransformComponent::from(Transform::from_xyz(3.0, 0.5, -2.2)),
|
||||
)); */
|
||||
|
||||
/* world.spawn((
|
||||
world.spawn((
|
||||
ModelComponent(antique_camera_model),
|
||||
TransformComponent::from(Transform::from_xyz(0.0, -5.0, -10.0)),
|
||||
)); */
|
||||
));
|
||||
|
||||
/* let light = PointLight {
|
||||
color: Vec3::new(1.0, 1.0, 1.0),
|
||||
|
@ -105,7 +106,7 @@ async fn main() {
|
|||
quadratic: 0.0075,
|
||||
}, */
|
||||
TransformComponent::from(cube_tran),
|
||||
ModelComponent(cube_model.clone()),
|
||||
ModelComponent(crate_model.clone()),
|
||||
CubeFlag,
|
||||
));
|
||||
|
||||
|
@ -114,7 +115,7 @@ async fn main() {
|
|||
world.spawn((
|
||||
PointLight {
|
||||
color: Vec3::new(1.0, 1.0, 1.0), //Vec3::new(0.361, 0.984, 0.0),
|
||||
intensity: 1.0,
|
||||
intensity: 1.2,
|
||||
/* constant: 1.0,
|
||||
linear: 0.045,
|
||||
quadratic: 0.0075, */
|
||||
|
@ -123,9 +124,9 @@ async fn main() {
|
|||
linear: 0.09,
|
||||
quadratic: 0.032,
|
||||
|
||||
ambient: 0.2,
|
||||
diffuse: 0.5,
|
||||
specular: 1.0,
|
||||
ambient: 0.3,
|
||||
diffuse: 1.0,
|
||||
specular: 1.3,
|
||||
},
|
||||
TransformComponent::from(light_tran),
|
||||
ModelComponent(cube_model),
|
||||
|
|
|
@ -10,7 +10,7 @@ anyhow = "1.0.75"
|
|||
base64 = "0.21.4"
|
||||
edict = "0.5.0"
|
||||
glam = "0.24.1"
|
||||
gltf = { version = "1.3.0", features = ["KHR_materials_pbrSpecularGlossiness"] }
|
||||
gltf = { version = "1.3.0", features = ["KHR_materials_pbrSpecularGlossiness", "KHR_materials_specular"] }
|
||||
image = "0.24.7"
|
||||
# not using custom matcher, or file type from file path
|
||||
infer = { version = "0.15.0", default-features = false }
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use std::{collections::hash_map::DefaultHasher, hash::{Hash, Hasher}};
|
||||
use std::{collections::{hash_map::DefaultHasher, HashMap}, hash::{Hash, Hasher}};
|
||||
|
||||
use tracing::debug;
|
||||
|
||||
use crate::{Texture, ResHandle, util, loader::model::GltfLoadContext};
|
||||
|
||||
|
@ -66,6 +68,20 @@ pub enum AlphaMode {
|
|||
Blend,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum MaterialExtension {
|
||||
SpecularTexture(ResHandle<Texture>),
|
||||
}
|
||||
|
||||
impl MaterialExtension {
|
||||
/// Returns the GLTF name of this extension
|
||||
pub fn gltf_name(&self) -> &str {
|
||||
match self {
|
||||
MaterialExtension::SpecularTexture(_) => "KHR_materials_specular",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<gltf::material::AlphaMode> for AlphaMode {
|
||||
fn from(value: gltf::material::AlphaMode) -> Self {
|
||||
match value {
|
||||
|
@ -76,6 +92,42 @@ impl From<gltf::material::AlphaMode> for AlphaMode {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Specular {
|
||||
/// The strength of the specular reflection, default of 1.0
|
||||
pub factor: f32,
|
||||
|
||||
/// The color of the specular reflection
|
||||
pub color_factor: glam::Vec3,
|
||||
|
||||
/// A texture that defines the strength of the specular reflection,
|
||||
/// stored in the alpha (`A`) channel. This will be multiplied by
|
||||
/// `specular_factor`.
|
||||
pub texture: Option<ResHandle<Texture>>,
|
||||
|
||||
/// A texture that defines the color of the specular reflection,
|
||||
/// stored in the `RGB` channels and encoded in sRGB. This texture
|
||||
/// will be multiplied by `specular_color_factor`.
|
||||
pub color_texture: Option<ResHandle<Texture>>,
|
||||
}
|
||||
|
||||
impl Specular {
|
||||
pub fn from_gltf(context: &mut GltfLoadContext, value: gltf::material::Specular) -> Self {
|
||||
let color_texture = value.specular_color_texture()
|
||||
.map(|t| Material::load_texture(context, t));
|
||||
|
||||
let spec_texture = value.specular_texture()
|
||||
.map(|t| Material::load_texture(context, t));
|
||||
|
||||
Self {
|
||||
factor: value.specular_factor(),
|
||||
color_factor: value.specular_color_factor().into(),
|
||||
color_texture,
|
||||
texture: spec_texture,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Material {
|
||||
pub shader_uuid: Option<u64>,
|
||||
|
@ -125,7 +177,7 @@ pub struct Material {
|
|||
/// operator).
|
||||
pub alpha_mode: AlphaMode,
|
||||
|
||||
//pub texture: Option<ResHandle<Texture>>,
|
||||
pub specular: Option<Specular>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -224,6 +276,8 @@ impl Material {
|
|||
let metallic_roughness_texture = pbr_rough.metallic_roughness_texture()
|
||||
.map(|info| Material::load_texture(context, info));
|
||||
|
||||
let specular = gltf_mat.specular().map(|s| Specular::from_gltf(context, s));
|
||||
|
||||
Material {
|
||||
name: gltf_mat.name()
|
||||
.map(|s| s.to_string()),
|
||||
|
@ -240,6 +294,7 @@ impl Material {
|
|||
// TODO
|
||||
base_color_texture,
|
||||
metallic_roughness_texture,
|
||||
specular,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#[repr(C)]
|
||||
#[derive(Default, Debug, Copy, Clone, edict::Component)]
|
||||
pub struct DirectionalLight {
|
||||
pub direction: glam::Quat,
|
||||
pub color: glam::Vec3,
|
||||
|
||||
pub ambient: glam::Vec3,
|
||||
pub diffuse: glam::Vec3,
|
||||
pub specular: glam::Vec3,
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
pub mod point;
|
||||
pub mod directional;
|
||||
|
||||
use std::{collections::{VecDeque, HashMap}, num::{NonZeroU64, NonZeroU32}, marker::PhantomData};
|
||||
|
||||
use edict::query::EpochOf;
|
||||
|
|
|
@ -1,29 +1,62 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use super::texture::RenderTexture;
|
||||
use super::texture::RenderTexture;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MaterialSpecular {
|
||||
pub factor: f32,
|
||||
pub color_factor: glam::Vec3,
|
||||
pub texture: Option<RenderTexture>,
|
||||
pub color_texture: Option<RenderTexture>,
|
||||
}
|
||||
|
||||
impl MaterialSpecular {
|
||||
pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Arc<wgpu::BindGroupLayout>, value: &lyra_resource::Specular) -> Self {
|
||||
let tex = value.texture.as_ref().map(|t| &t.data.as_ref().unwrap().image)
|
||||
.map(|i| RenderTexture::from_image(device, queue, bg_layout.clone(), i, None).unwrap());
|
||||
|
||||
let color_tex = value.color_texture.as_ref().map(|t| &t.data.as_ref().unwrap().image)
|
||||
.map(|i| RenderTexture::from_image(device, queue, bg_layout, i, None).unwrap());
|
||||
|
||||
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: RenderTexture,
|
||||
pub diffuse_texture: Option<RenderTexture>,
|
||||
pub ambient: glam::Vec3,
|
||||
pub diffuse: glam::Vec3,
|
||||
pub specular: glam::Vec3,
|
||||
pub shininess: f32,
|
||||
|
||||
pub specular: Option<MaterialSpecular>
|
||||
}
|
||||
|
||||
impl Material {
|
||||
pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, value: &lyra_resource::Material) -> Self {
|
||||
let image = value.base_color_texture.as_ref().map(|t| &t.data.as_ref().unwrap().image).unwrap();
|
||||
let diffuse_texture = RenderTexture::from_image(device, queue, image, None).unwrap();
|
||||
pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Arc<wgpu::BindGroupLayout>, value: &lyra_resource::Material) -> Self {
|
||||
let diffuse_texture = value.base_color_texture.as_ref().map(|t| &t.data.as_ref().unwrap().image)
|
||||
.map(|i| RenderTexture::from_image(device, queue, bg_layout.clone(), i, None).unwrap());
|
||||
|
||||
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),
|
||||
//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),
|
||||
//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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,17 +76,15 @@ pub struct MaterialUniform {
|
|||
|
||||
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(value.specular.x, value.specular.y, value.specular.z, 0.0),
|
||||
specular: glam::Vec4::new(specular_factor.x, specular_factor.y, specular_factor.z, 0.0),
|
||||
shininess: value.shininess,
|
||||
_padding1: [0; 3]
|
||||
|
||||
/* _padding: 0,
|
||||
_padding2: 0,
|
||||
_padding3: 0,
|
||||
_padding4: [0; 3], */
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,7 +50,7 @@ struct MeshBufferStorage {
|
|||
//#[allow(dead_code)]
|
||||
//render_texture: Option<RenderTexture>,
|
||||
material: Option<Material>,
|
||||
texture_bindgroup: Option<BindGroup>,
|
||||
diffuse_texture: Option<RenderTexture>,
|
||||
|
||||
// The index of the transform for this entity.
|
||||
// The tuple is structured like this: (transform index, index of transform inside the buffer)
|
||||
|
@ -90,8 +90,8 @@ pub struct BasicRenderer {
|
|||
camera_buffer: wgpu::Buffer,
|
||||
camera_bind_group: wgpu::BindGroup,
|
||||
|
||||
texture_bind_group_layout: BindGroupLayout,
|
||||
default_texture_bind_group: BindGroup,
|
||||
bgl_texture: Arc<BindGroupLayout>,
|
||||
default_texture: RenderTexture,
|
||||
depth_buffer_texture: RenderTexture,
|
||||
|
||||
material_buffer: BufferWrapper,
|
||||
|
@ -130,7 +130,7 @@ impl BasicRenderer {
|
|||
wgpu::Limits::downlevel_webgl2_defaults()
|
||||
} else {
|
||||
let mut v = wgpu::Limits::default();
|
||||
v.max_bind_groups = 5;
|
||||
v.max_bind_groups = 8;
|
||||
v
|
||||
},
|
||||
label: None,
|
||||
|
@ -163,30 +163,7 @@ impl BasicRenderer {
|
|||
};
|
||||
surface.configure(&device, &config);
|
||||
|
||||
let texture_bind_group_layout =
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
multisampled: false,
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
// This should match the filterable field of the
|
||||
// corresponding Texture entry above.
|
||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
label: Some("texture_bind_group_layout"),
|
||||
});
|
||||
let bgl_texture = Arc::new(RenderTexture::create_layout(&device));
|
||||
|
||||
let shader_src = include_str!("shaders/base.wgsl");
|
||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||
|
@ -235,23 +212,7 @@ impl BasicRenderer {
|
|||
|
||||
// load the default texture
|
||||
let bytes = include_bytes!("default_texture.png");
|
||||
let tex = RenderTexture::from_bytes(&device, &queue, bytes, "default_texture").unwrap();
|
||||
let default_tex_bindgroup = device.create_bind_group(
|
||||
&wgpu::BindGroupDescriptor {
|
||||
layout: &texture_bind_group_layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::TextureView(tex.view()),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::Sampler(tex.sampler()),
|
||||
}
|
||||
],
|
||||
label: Some("default_texture"),
|
||||
}
|
||||
);
|
||||
let default_texture = RenderTexture::from_bytes(&device, &queue, bgl_texture.clone(), bytes, "default_texture").unwrap();
|
||||
|
||||
let light_uniform_buffers = LightUniformBuffers::new(&device);
|
||||
|
||||
|
@ -287,8 +248,8 @@ impl BasicRenderer {
|
|||
camera_buffer,
|
||||
camera_bind_group,
|
||||
|
||||
texture_bind_group_layout,
|
||||
default_texture_bind_group: default_tex_bindgroup,
|
||||
bgl_texture,
|
||||
default_texture,
|
||||
depth_buffer_texture: depth_texture,
|
||||
entity_last_transforms: HashMap::new(),
|
||||
|
||||
|
@ -300,8 +261,9 @@ impl BasicRenderer {
|
|||
let mut pipelines = HashMap::new();
|
||||
pipelines.insert(0, Arc::new(FullRenderPipeline::new(&s.device, &s.config, &shader,
|
||||
vec![super::vertex::Vertex::desc(),],
|
||||
vec![&s.texture_bind_group_layout, &s.transform_buffers.bindgroup_layout, &camera_bind_group_layout,
|
||||
&s.light_buffers.bindgroup_layout, &s.material_buffer.bindgroup_pair.as_ref().unwrap().layout])));
|
||||
vec![&s.bgl_texture, &s.transform_buffers.bindgroup_layout, &camera_bind_group_layout,
|
||||
&s.light_buffers.bindgroup_layout, &s.material_buffer.bindgroup_pair.as_ref().unwrap().layout,
|
||||
&s.bgl_texture])));
|
||||
s.render_pipelines = pipelines;
|
||||
|
||||
s
|
||||
|
@ -396,33 +358,7 @@ impl BasicRenderer {
|
|||
fn create_mesh_buffers(&mut self, mesh: &Mesh, transform_indices: TransformBufferIndices) -> MeshBufferStorage {
|
||||
let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh);
|
||||
|
||||
let material = Material::from_resource(&self.device, &self.queue, &mesh.material());
|
||||
let diffuse_bindgroup = if let Some(model_texture) = &mesh.material().base_color_texture {
|
||||
let diffuse_texture = &material.diffuse_texture;
|
||||
|
||||
let diffuse_bind_group = self.device.create_bind_group(
|
||||
&wgpu::BindGroupDescriptor {
|
||||
layout: &self.texture_bind_group_layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::TextureView(diffuse_texture.view()),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::Sampler(diffuse_texture.sampler()),
|
||||
}
|
||||
],
|
||||
label: Some("diffuse_bind_group"),
|
||||
}
|
||||
);
|
||||
|
||||
Some(diffuse_bind_group)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
//let mat = Material::from_resource(&self.device, &self.queue, )
|
||||
let material = Material::from_resource(&self.device, &self.queue, self.bgl_texture.clone(), &mesh.material());
|
||||
let uni = MaterialUniform::from(&material);
|
||||
self.queue.write_buffer(&self.material_buffer.inner_buf, 0, bytemuck::bytes_of(&uni));
|
||||
debug!("Wrote material to buffer");
|
||||
|
@ -431,7 +367,7 @@ impl BasicRenderer {
|
|||
buffer_vertex: vertex_buffer,
|
||||
buffer_indices,
|
||||
material: Some(material),
|
||||
texture_bindgroup: diffuse_bindgroup,
|
||||
diffuse_texture: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,9 +380,6 @@ impl BasicRenderer {
|
|||
let indices = self.transform_buffers.update_or_insert(&self.queue, &self.render_limits,
|
||||
entity, || ( transform.calculate_mat4(), glam::Mat3::from_quat(transform.rotation) ));
|
||||
|
||||
//let mat = Material::from_resource(&self.device, &self.queue, )
|
||||
//self.queue.write_buffer(&self.material_buffer.inner_buf, 0, bytemuck::bytes_of(t))
|
||||
|
||||
#[allow(clippy::map_entry)]
|
||||
if !self.mesh_buffers.contains_key(&mesh.uuid) {
|
||||
// create the mesh's buffers
|
||||
|
@ -569,7 +502,7 @@ impl Renderer for BasicRenderer {
|
|||
})],
|
||||
// enable depth buffer
|
||||
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
|
||||
view: self.depth_buffer_texture.view(),
|
||||
view: &self.depth_buffer_texture.view,
|
||||
depth_ops: Some(wgpu::Operations {
|
||||
load: wgpu::LoadOp::Clear(1.0),
|
||||
store: true,
|
||||
|
@ -588,29 +521,30 @@ impl Renderer for BasicRenderer {
|
|||
let buffers = self.mesh_buffers.get(&job.mesh_buffer_id).unwrap();
|
||||
|
||||
// Bind the optional texture
|
||||
if let Some(tex) = buffers.texture_bindgroup.as_ref() {
|
||||
render_pass.set_bind_group(0, tex, &[]);
|
||||
if let Some(tex) = buffers.material.as_ref()
|
||||
.and_then(|m| m.diffuse_texture.as_ref()) {
|
||||
render_pass.set_bind_group(0, tex.bind_group(), &[]);
|
||||
} else {
|
||||
render_pass.set_bind_group(0, &self.default_texture_bind_group, &[]);
|
||||
render_pass.set_bind_group(0, &self.default_texture.bind_group(), &[]);
|
||||
}
|
||||
|
||||
if let Some(tex) = buffers.material.as_ref()
|
||||
.and_then(|m| m.specular.as_ref())
|
||||
.and_then(|s| s.texture.as_ref().or_else(|| s.color_texture.as_ref())) {
|
||||
render_pass.set_bind_group(5, tex.bind_group(), &[]);
|
||||
} else {
|
||||
render_pass.set_bind_group(5, &self.default_texture.bind_group(), &[]);
|
||||
}
|
||||
|
||||
// Get the bindgroup for job's transform and bind to it using an offset.
|
||||
let transform_indices = *self.transform_buffers.entity_indices(job.entity).unwrap();
|
||||
let bindgroup = self.transform_buffers.bind_group(transform_indices).unwrap();
|
||||
//let bindgroup = self.transform_buffers.entity_bind_group(job.entity).unwrap();
|
||||
let offset = TransformBuffers::index_offset(&self.render_limits, transform_indices) as u32;
|
||||
render_pass.set_bind_group(1, bindgroup, &[ offset, offset, ]);
|
||||
|
||||
// Bind camera
|
||||
render_pass.set_bind_group(2, &self.camera_bind_group, &[]);
|
||||
|
||||
// bind light
|
||||
//render_pass.set_bind_group(3, &self.point_light_bind_group, &[]);
|
||||
render_pass.set_bind_group(3, &self.light_buffers.bindgroup, &[]);
|
||||
|
||||
render_pass.set_bind_group(4, &self.material_buffer.bindgroup_pair.as_ref().unwrap().bindgroup, &[]);
|
||||
////self.light_buffers.bind_lights(&mut render_pass, 3);
|
||||
|
||||
|
||||
// if this mesh uses indices, use them to draw the mesh
|
||||
if let Some((idx_type, indices)) = buffers.buffer_indices.as_ref() {
|
||||
|
|
|
@ -100,30 +100,33 @@ var s_diffuse: sampler;
|
|||
@group(4) @binding(0)
|
||||
var<uniform> u_material: Material;
|
||||
|
||||
@group(5) @binding(0)
|
||||
var t_specular: texture_2d<f32>;
|
||||
@group(5) @binding(1)
|
||||
var s_specular: sampler;
|
||||
|
||||
@fragment
|
||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let object_color: vec4<f32> = textureSample(t_diffuse, s_diffuse, in.tex_coords);
|
||||
let specular_color: vec3<f32> = textureSample(t_specular, s_specular, in.tex_coords).xyz;
|
||||
|
||||
var light_res = vec3<f32>(0.0);
|
||||
for (var i = 0u; i < u_lights.point_light_count; i++) {
|
||||
light_res += blinn_phong_point_light(in.world_position, in.world_normal, u_lights.point_lights[i], u_material);
|
||||
light_res += blinn_phong_point_light(in.world_position, in.world_normal, u_lights.point_lights[i], u_material);
|
||||
light_res += blinn_phong_point_light(in.world_position, in.world_normal, u_lights.point_lights[i], u_material, specular_color);
|
||||
}
|
||||
let light_object_res = light_res * (object_color.xyz/* * u_material.diffuse.xyz*/);
|
||||
|
||||
return vec4<f32>(light_object_res, object_color.a);
|
||||
}
|
||||
|
||||
fn blinn_phong_point_light(world_pos: vec3<f32>, world_norm: vec3<f32>, point_light: PointLight, material: Material) -> vec3<f32> {
|
||||
fn blinn_phong_point_light(world_pos: vec3<f32>, world_norm: vec3<f32>, point_light: PointLight, material: Material, specular_factor: vec3<f32>) -> vec3<f32> {
|
||||
let light_color = point_light.color.xyz;
|
||||
let light_pos = point_light.position.xyz;
|
||||
let camera_view_pos = u_camera.view_pos.xyz;
|
||||
|
||||
// We don't need (or want) much ambient light, so 0.1 is fine
|
||||
//let ambient_strength = 0.1;
|
||||
var ambient_color = light_color * material.ambient.xyz;
|
||||
//let ambient_strength = 0.1;
|
||||
var ambient_color = light_color * material.ambient.xyz;
|
||||
var ambient_color = light_color * material.ambient.xyz * material.diffuse.xyz;
|
||||
|
||||
//// diffuse ////
|
||||
let light_dir = normalize(light_pos - world_pos);
|
||||
|
@ -137,10 +140,9 @@ fn blinn_phong_point_light(world_pos: vec3<f32>, world_norm: vec3<f32>, point_li
|
|||
let view_dir = normalize(camera_view_pos - world_pos);
|
||||
let half_dir = normalize(view_dir + light_dir);
|
||||
|
||||
|
||||
let specular_strength = pow(max(dot(world_norm, half_dir), 0.0), material.shininess);
|
||||
var specular_color = specular_strength * (light_color * material.specular.xyz);
|
||||
let specular_strength = pow(max(dot(world_norm, half_dir), 0.0), material.shininess);
|
||||
var specular_color = specular_strength * (light_color * material.specular.xyz);
|
||||
var specular_color = specular_strength * (light_color * specular_factor);
|
||||
//// end of specular ////
|
||||
|
||||
//// point light attenuation ////
|
||||
|
|
|
@ -3,6 +3,8 @@ use std::sync::Arc;
|
|||
use image::GenericImageView;
|
||||
use lyra_resource::{Resource, Texture};
|
||||
|
||||
use super::render_buffer::BindGroupPair;
|
||||
|
||||
/* #[derive(Clone)]
|
||||
pub struct Texture {
|
||||
texture_id: u32,
|
||||
|
@ -22,23 +24,75 @@ impl Texture {
|
|||
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct RenderTexture {
|
||||
texture: Arc<wgpu::Texture>,
|
||||
view: Arc<wgpu::TextureView>,
|
||||
sampler: Arc<wgpu::Sampler>,
|
||||
pub inner_texture: wgpu::Texture,
|
||||
pub view: wgpu::TextureView,
|
||||
pub sampler: wgpu::Sampler,
|
||||
|
||||
/// Most RenderTextures will have this, but things like depth buffers wont
|
||||
pub bindgroup_pair: Option<BindGroupPair>,
|
||||
}
|
||||
|
||||
impl RenderTexture {
|
||||
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
||||
|
||||
pub fn from_bytes(device: &wgpu::Device, queue: &wgpu::Queue, bytes: &[u8], label: &str) -> anyhow::Result<Self> {
|
||||
let img = image::load_from_memory(bytes)?;
|
||||
Self::from_image(device, queue, &img, Some(label))
|
||||
pub fn create_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
multisampled: false,
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
// This should match the filterable field of the
|
||||
// corresponding Texture entry above.
|
||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
label: Some("BGL_Texture"),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_image(device: &wgpu::Device, queue: &wgpu::Queue, img: &image::DynamicImage, label: Option<&str>) -> anyhow::Result<Self> {
|
||||
fn create_bind_group_pair(device: &wgpu::Device, layout: Arc<wgpu::BindGroupLayout>, view: &wgpu::TextureView, sampler: &wgpu::Sampler) -> BindGroupPair {
|
||||
let bg = device.create_bind_group(
|
||||
&wgpu::BindGroupDescriptor {
|
||||
layout: &layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::TextureView(view),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::Sampler(sampler),
|
||||
}
|
||||
],
|
||||
label: Some("default_texture"),
|
||||
}
|
||||
);
|
||||
|
||||
BindGroupPair {
|
||||
layout,
|
||||
bindgroup: bg
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_bytes(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Arc<wgpu::BindGroupLayout>, bytes: &[u8], label: &str) -> anyhow::Result<Self> {
|
||||
let img = image::load_from_memory(bytes)?;
|
||||
Self::from_image(device, queue, bg_layout, &img, Some(label))
|
||||
}
|
||||
|
||||
pub fn from_image(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Arc<wgpu::BindGroupLayout>, img: &image::DynamicImage, label: Option<&str>) -> anyhow::Result<Self> {
|
||||
let rgba = img.to_rgba8();
|
||||
let dimensions = img.dimensions();
|
||||
|
||||
|
@ -89,10 +143,13 @@ impl RenderTexture {
|
|||
}
|
||||
);
|
||||
|
||||
let bgp = Self::create_bind_group_pair(device, bg_layout, &view, &sampler);
|
||||
|
||||
Ok(Self {
|
||||
texture: Arc::new(texture),
|
||||
view: Arc::new(view),
|
||||
sampler: Arc::new(sampler),
|
||||
inner_texture: texture,
|
||||
view: view,
|
||||
sampler: sampler,
|
||||
bindgroup_pair: Some(bgp),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -109,7 +166,7 @@ impl RenderTexture {
|
|||
queue.write_texture(
|
||||
wgpu::ImageCopyTexture {
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
texture: &self.texture,
|
||||
texture: &self.inner_texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d::ZERO,
|
||||
},
|
||||
|
@ -159,21 +216,18 @@ impl RenderTexture {
|
|||
);
|
||||
|
||||
Self {
|
||||
texture: Arc::new(texture),
|
||||
view: Arc::new(view),
|
||||
sampler: Arc::new(sampler),
|
||||
inner_texture: texture,
|
||||
view: view,
|
||||
sampler: sampler,
|
||||
bindgroup_pair: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inner_texture(&self) -> &wgpu::Texture {
|
||||
&self.texture
|
||||
}
|
||||
|
||||
pub fn view(&self) -> &wgpu::TextureView {
|
||||
&self.view
|
||||
}
|
||||
|
||||
pub fn sampler(&self) -> &wgpu::Sampler {
|
||||
&self.sampler
|
||||
/// Returns the bind group stored inside the bind group pair.
|
||||
///
|
||||
/// Panics:
|
||||
/// * This will panic if the texture isn't storing its bind group.
|
||||
pub fn bind_group(&self) -> &wgpu::BindGroup {
|
||||
&self.bindgroup_pair.as_ref().unwrap().bindgroup
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue