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 mut resman = world.get_resource_mut::<ResourceManager>().unwrap();
|
||||||
//let diffuse_texture = resman.request::<Texture>("assets/happy-tree.png").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/cube-texture-bin.glb").unwrap();
|
||||||
let cube_model = resman.request::<Model>("assets/texture-sep/texture-sep.gltf").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);
|
drop(resman);
|
||||||
|
|
||||||
/* world.spawn((
|
/* world.spawn((
|
||||||
|
@ -81,10 +82,10 @@ async fn main() {
|
||||||
TransformComponent::from(Transform::from_xyz(3.0, 0.5, -2.2)),
|
TransformComponent::from(Transform::from_xyz(3.0, 0.5, -2.2)),
|
||||||
)); */
|
)); */
|
||||||
|
|
||||||
/* world.spawn((
|
world.spawn((
|
||||||
ModelComponent(antique_camera_model),
|
ModelComponent(antique_camera_model),
|
||||||
TransformComponent::from(Transform::from_xyz(0.0, -5.0, -10.0)),
|
TransformComponent::from(Transform::from_xyz(0.0, -5.0, -10.0)),
|
||||||
)); */
|
));
|
||||||
|
|
||||||
/* let light = PointLight {
|
/* let light = PointLight {
|
||||||
color: Vec3::new(1.0, 1.0, 1.0),
|
color: Vec3::new(1.0, 1.0, 1.0),
|
||||||
|
@ -105,7 +106,7 @@ async fn main() {
|
||||||
quadratic: 0.0075,
|
quadratic: 0.0075,
|
||||||
}, */
|
}, */
|
||||||
TransformComponent::from(cube_tran),
|
TransformComponent::from(cube_tran),
|
||||||
ModelComponent(cube_model.clone()),
|
ModelComponent(crate_model.clone()),
|
||||||
CubeFlag,
|
CubeFlag,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -114,7 +115,7 @@ async fn main() {
|
||||||
world.spawn((
|
world.spawn((
|
||||||
PointLight {
|
PointLight {
|
||||||
color: Vec3::new(1.0, 1.0, 1.0), //Vec3::new(0.361, 0.984, 0.0),
|
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,
|
/* constant: 1.0,
|
||||||
linear: 0.045,
|
linear: 0.045,
|
||||||
quadratic: 0.0075, */
|
quadratic: 0.0075, */
|
||||||
|
@ -123,9 +124,9 @@ async fn main() {
|
||||||
linear: 0.09,
|
linear: 0.09,
|
||||||
quadratic: 0.032,
|
quadratic: 0.032,
|
||||||
|
|
||||||
ambient: 0.2,
|
ambient: 0.3,
|
||||||
diffuse: 0.5,
|
diffuse: 1.0,
|
||||||
specular: 1.0,
|
specular: 1.3,
|
||||||
},
|
},
|
||||||
TransformComponent::from(light_tran),
|
TransformComponent::from(light_tran),
|
||||||
ModelComponent(cube_model),
|
ModelComponent(cube_model),
|
||||||
|
|
|
@ -10,7 +10,7 @@ anyhow = "1.0.75"
|
||||||
base64 = "0.21.4"
|
base64 = "0.21.4"
|
||||||
edict = "0.5.0"
|
edict = "0.5.0"
|
||||||
glam = "0.24.1"
|
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"
|
image = "0.24.7"
|
||||||
# not using custom matcher, or file type from file path
|
# not using custom matcher, or file type from file path
|
||||||
infer = { version = "0.15.0", default-features = false }
|
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};
|
use crate::{Texture, ResHandle, util, loader::model::GltfLoadContext};
|
||||||
|
|
||||||
|
@ -66,6 +68,20 @@ pub enum AlphaMode {
|
||||||
Blend,
|
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 {
|
impl From<gltf::material::AlphaMode> for AlphaMode {
|
||||||
fn from(value: gltf::material::AlphaMode) -> Self {
|
fn from(value: gltf::material::AlphaMode) -> Self {
|
||||||
match value {
|
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)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Material {
|
pub struct Material {
|
||||||
pub shader_uuid: Option<u64>,
|
pub shader_uuid: Option<u64>,
|
||||||
|
@ -125,7 +177,7 @@ pub struct Material {
|
||||||
/// operator).
|
/// operator).
|
||||||
pub alpha_mode: AlphaMode,
|
pub alpha_mode: AlphaMode,
|
||||||
|
|
||||||
//pub texture: Option<ResHandle<Texture>>,
|
pub specular: Option<Specular>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -224,6 +276,8 @@ impl Material {
|
||||||
let metallic_roughness_texture = pbr_rough.metallic_roughness_texture()
|
let metallic_roughness_texture = pbr_rough.metallic_roughness_texture()
|
||||||
.map(|info| Material::load_texture(context, info));
|
.map(|info| Material::load_texture(context, info));
|
||||||
|
|
||||||
|
let specular = gltf_mat.specular().map(|s| Specular::from_gltf(context, s));
|
||||||
|
|
||||||
Material {
|
Material {
|
||||||
name: gltf_mat.name()
|
name: gltf_mat.name()
|
||||||
.map(|s| s.to_string()),
|
.map(|s| s.to_string()),
|
||||||
|
@ -240,6 +294,7 @@ impl Material {
|
||||||
// TODO
|
// TODO
|
||||||
base_color_texture,
|
base_color_texture,
|
||||||
metallic_roughness_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 point;
|
||||||
|
pub mod directional;
|
||||||
|
|
||||||
use std::{collections::{VecDeque, HashMap}, num::{NonZeroU64, NonZeroU32}, marker::PhantomData};
|
use std::{collections::{VecDeque, HashMap}, num::{NonZeroU64, NonZeroU32}, marker::PhantomData};
|
||||||
|
|
||||||
use edict::query::EpochOf;
|
use edict::query::EpochOf;
|
||||||
|
|
|
@ -1,29 +1,62 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::texture::RenderTexture;
|
use super::texture::RenderTexture;
|
||||||
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 struct Material {
|
||||||
pub shader_id: u64,
|
pub shader_id: u64,
|
||||||
pub diffuse_texture: RenderTexture,
|
pub diffuse_texture: Option<RenderTexture>,
|
||||||
pub ambient: glam::Vec3,
|
pub ambient: glam::Vec3,
|
||||||
pub diffuse: glam::Vec3,
|
pub diffuse: glam::Vec3,
|
||||||
pub specular: glam::Vec3,
|
|
||||||
pub shininess: f32,
|
pub shininess: f32,
|
||||||
|
|
||||||
|
pub specular: Option<MaterialSpecular>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Material {
|
impl Material {
|
||||||
pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, value: &lyra_resource::Material) -> Self {
|
pub fn from_resource(device: &wgpu::Device, queue: &wgpu::Queue, bg_layout: Arc<wgpu::BindGroupLayout>, 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 = value.base_color_texture.as_ref().map(|t| &t.data.as_ref().unwrap().image)
|
||||||
let diffuse_texture = RenderTexture::from_image(device, queue, image, None).unwrap();
|
.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 {
|
Self {
|
||||||
shader_id: value.shader_uuid.unwrap_or(0),
|
shader_id: value.shader_uuid.unwrap_or(0),
|
||||||
diffuse_texture,
|
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(value.base_color.x, value.base_color.y, value.base_color.z),
|
||||||
diffuse: glam::Vec3::new(1.0, 0.5, 0.31),
|
//diffuse: glam::Vec3::new(1.0, 0.5, 0.31),
|
||||||
specular: glam::Vec3::new(0.5, 0.5, 0.5),
|
//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,
|
shininess: 32.0,
|
||||||
|
|
||||||
|
specular
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,17 +76,15 @@ pub struct MaterialUniform {
|
||||||
|
|
||||||
impl From<&Material> for MaterialUniform {
|
impl From<&Material> for MaterialUniform {
|
||||||
fn from(value: &Material) -> Self {
|
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 {
|
Self {
|
||||||
ambient: glam::Vec4::new(value.ambient.x, value.ambient.y, value.ambient.z, 0.0),
|
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),
|
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,
|
shininess: value.shininess,
|
||||||
_padding1: [0; 3]
|
_padding1: [0; 3]
|
||||||
|
|
||||||
/* _padding: 0,
|
|
||||||
_padding2: 0,
|
|
||||||
_padding3: 0,
|
|
||||||
_padding4: [0; 3], */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -50,7 +50,7 @@ struct MeshBufferStorage {
|
||||||
//#[allow(dead_code)]
|
//#[allow(dead_code)]
|
||||||
//render_texture: Option<RenderTexture>,
|
//render_texture: Option<RenderTexture>,
|
||||||
material: Option<Material>,
|
material: Option<Material>,
|
||||||
texture_bindgroup: Option<BindGroup>,
|
diffuse_texture: Option<RenderTexture>,
|
||||||
|
|
||||||
// The index of the transform for this entity.
|
// The index of the transform for this entity.
|
||||||
// The tuple is structured like this: (transform index, index of transform inside the buffer)
|
// 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_buffer: wgpu::Buffer,
|
||||||
camera_bind_group: wgpu::BindGroup,
|
camera_bind_group: wgpu::BindGroup,
|
||||||
|
|
||||||
texture_bind_group_layout: BindGroupLayout,
|
bgl_texture: Arc<BindGroupLayout>,
|
||||||
default_texture_bind_group: BindGroup,
|
default_texture: RenderTexture,
|
||||||
depth_buffer_texture: RenderTexture,
|
depth_buffer_texture: RenderTexture,
|
||||||
|
|
||||||
material_buffer: BufferWrapper,
|
material_buffer: BufferWrapper,
|
||||||
|
@ -130,7 +130,7 @@ impl BasicRenderer {
|
||||||
wgpu::Limits::downlevel_webgl2_defaults()
|
wgpu::Limits::downlevel_webgl2_defaults()
|
||||||
} else {
|
} else {
|
||||||
let mut v = wgpu::Limits::default();
|
let mut v = wgpu::Limits::default();
|
||||||
v.max_bind_groups = 5;
|
v.max_bind_groups = 8;
|
||||||
v
|
v
|
||||||
},
|
},
|
||||||
label: None,
|
label: None,
|
||||||
|
@ -163,30 +163,7 @@ impl BasicRenderer {
|
||||||
};
|
};
|
||||||
surface.configure(&device, &config);
|
surface.configure(&device, &config);
|
||||||
|
|
||||||
let texture_bind_group_layout =
|
let bgl_texture = Arc::new(RenderTexture::create_layout(&device));
|
||||||
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 shader_src = include_str!("shaders/base.wgsl");
|
let shader_src = include_str!("shaders/base.wgsl");
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
@ -235,23 +212,7 @@ impl BasicRenderer {
|
||||||
|
|
||||||
// load the default texture
|
// load the default texture
|
||||||
let bytes = include_bytes!("default_texture.png");
|
let bytes = include_bytes!("default_texture.png");
|
||||||
let tex = RenderTexture::from_bytes(&device, &queue, bytes, "default_texture").unwrap();
|
let default_texture = RenderTexture::from_bytes(&device, &queue, bgl_texture.clone(), 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 light_uniform_buffers = LightUniformBuffers::new(&device);
|
let light_uniform_buffers = LightUniformBuffers::new(&device);
|
||||||
|
|
||||||
|
@ -287,8 +248,8 @@ impl BasicRenderer {
|
||||||
camera_buffer,
|
camera_buffer,
|
||||||
camera_bind_group,
|
camera_bind_group,
|
||||||
|
|
||||||
texture_bind_group_layout,
|
bgl_texture,
|
||||||
default_texture_bind_group: default_tex_bindgroup,
|
default_texture,
|
||||||
depth_buffer_texture: depth_texture,
|
depth_buffer_texture: depth_texture,
|
||||||
entity_last_transforms: HashMap::new(),
|
entity_last_transforms: HashMap::new(),
|
||||||
|
|
||||||
|
@ -300,8 +261,9 @@ impl BasicRenderer {
|
||||||
let mut pipelines = HashMap::new();
|
let mut pipelines = HashMap::new();
|
||||||
pipelines.insert(0, Arc::new(FullRenderPipeline::new(&s.device, &s.config, &shader,
|
pipelines.insert(0, Arc::new(FullRenderPipeline::new(&s.device, &s.config, &shader,
|
||||||
vec![super::vertex::Vertex::desc(),],
|
vec![super::vertex::Vertex::desc(),],
|
||||||
vec![&s.texture_bind_group_layout, &s.transform_buffers.bindgroup_layout, &camera_bind_group_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.light_buffers.bindgroup_layout, &s.material_buffer.bindgroup_pair.as_ref().unwrap().layout,
|
||||||
|
&s.bgl_texture])));
|
||||||
s.render_pipelines = pipelines;
|
s.render_pipelines = pipelines;
|
||||||
|
|
||||||
s
|
s
|
||||||
|
@ -396,33 +358,7 @@ impl BasicRenderer {
|
||||||
fn create_mesh_buffers(&mut self, mesh: &Mesh, transform_indices: TransformBufferIndices) -> MeshBufferStorage {
|
fn create_mesh_buffers(&mut self, mesh: &Mesh, transform_indices: TransformBufferIndices) -> MeshBufferStorage {
|
||||||
let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh);
|
let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh);
|
||||||
|
|
||||||
let material = Material::from_resource(&self.device, &self.queue, &mesh.material());
|
let material = Material::from_resource(&self.device, &self.queue, self.bgl_texture.clone(), &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 uni = MaterialUniform::from(&material);
|
let uni = MaterialUniform::from(&material);
|
||||||
self.queue.write_buffer(&self.material_buffer.inner_buf, 0, bytemuck::bytes_of(&uni));
|
self.queue.write_buffer(&self.material_buffer.inner_buf, 0, bytemuck::bytes_of(&uni));
|
||||||
debug!("Wrote material to buffer");
|
debug!("Wrote material to buffer");
|
||||||
|
@ -431,7 +367,7 @@ impl BasicRenderer {
|
||||||
buffer_vertex: vertex_buffer,
|
buffer_vertex: vertex_buffer,
|
||||||
buffer_indices,
|
buffer_indices,
|
||||||
material: Some(material),
|
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,
|
let indices = self.transform_buffers.update_or_insert(&self.queue, &self.render_limits,
|
||||||
entity, || ( transform.calculate_mat4(), glam::Mat3::from_quat(transform.rotation) ));
|
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)]
|
#[allow(clippy::map_entry)]
|
||||||
if !self.mesh_buffers.contains_key(&mesh.uuid) {
|
if !self.mesh_buffers.contains_key(&mesh.uuid) {
|
||||||
// create the mesh's buffers
|
// create the mesh's buffers
|
||||||
|
@ -569,7 +502,7 @@ impl Renderer for BasicRenderer {
|
||||||
})],
|
})],
|
||||||
// enable depth buffer
|
// enable depth buffer
|
||||||
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
|
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
|
||||||
view: self.depth_buffer_texture.view(),
|
view: &self.depth_buffer_texture.view,
|
||||||
depth_ops: Some(wgpu::Operations {
|
depth_ops: Some(wgpu::Operations {
|
||||||
load: wgpu::LoadOp::Clear(1.0),
|
load: wgpu::LoadOp::Clear(1.0),
|
||||||
store: true,
|
store: true,
|
||||||
|
@ -588,29 +521,30 @@ impl Renderer for BasicRenderer {
|
||||||
let buffers = self.mesh_buffers.get(&job.mesh_buffer_id).unwrap();
|
let buffers = self.mesh_buffers.get(&job.mesh_buffer_id).unwrap();
|
||||||
|
|
||||||
// Bind the optional texture
|
// Bind the optional texture
|
||||||
if let Some(tex) = buffers.texture_bindgroup.as_ref() {
|
if let Some(tex) = buffers.material.as_ref()
|
||||||
render_pass.set_bind_group(0, tex, &[]);
|
.and_then(|m| m.diffuse_texture.as_ref()) {
|
||||||
|
render_pass.set_bind_group(0, tex.bind_group(), &[]);
|
||||||
} else {
|
} 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.
|
// 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 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.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;
|
let offset = TransformBuffers::index_offset(&self.render_limits, transform_indices) as u32;
|
||||||
render_pass.set_bind_group(1, bindgroup, &[ offset, offset, ]);
|
render_pass.set_bind_group(1, bindgroup, &[ offset, offset, ]);
|
||||||
|
|
||||||
// Bind camera
|
|
||||||
render_pass.set_bind_group(2, &self.camera_bind_group, &[]);
|
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(3, &self.light_buffers.bindgroup, &[]);
|
||||||
|
|
||||||
render_pass.set_bind_group(4, &self.material_buffer.bindgroup_pair.as_ref().unwrap().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 this mesh uses indices, use them to draw the mesh
|
||||||
if let Some((idx_type, indices)) = buffers.buffer_indices.as_ref() {
|
if let Some((idx_type, indices)) = buffers.buffer_indices.as_ref() {
|
||||||
|
|
|
@ -100,30 +100,33 @@ var s_diffuse: sampler;
|
||||||
@group(4) @binding(0)
|
@group(4) @binding(0)
|
||||||
var<uniform> u_material: Material;
|
var<uniform> u_material: Material;
|
||||||
|
|
||||||
|
@group(5) @binding(0)
|
||||||
|
var t_specular: texture_2d<f32>;
|
||||||
|
@group(5) @binding(1)
|
||||||
|
var s_specular: sampler;
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
let object_color: vec4<f32> = textureSample(t_diffuse, s_diffuse, in.tex_coords);
|
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);
|
var light_res = vec3<f32>(0.0);
|
||||||
for (var i = 0u; i < u_lights.point_light_count; i++) {
|
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, specular_color);
|
||||||
light_res += blinn_phong_point_light(in.world_position, in.world_normal, u_lights.point_lights[i], u_material);
|
|
||||||
}
|
}
|
||||||
let light_object_res = light_res * (object_color.xyz/* * u_material.diffuse.xyz*/);
|
let light_object_res = light_res * (object_color.xyz/* * u_material.diffuse.xyz*/);
|
||||||
|
|
||||||
return vec4<f32>(light_object_res, object_color.a);
|
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_color = point_light.color.xyz;
|
||||||
let light_pos = point_light.position.xyz;
|
let light_pos = point_light.position.xyz;
|
||||||
let camera_view_pos = u_camera.view_pos.xyz;
|
let camera_view_pos = u_camera.view_pos.xyz;
|
||||||
|
|
||||||
// We don't need (or want) much ambient light, so 0.1 is fine
|
// We don't need (or want) much ambient light, so 0.1 is fine
|
||||||
//let ambient_strength = 0.1;
|
//let ambient_strength = 0.1;
|
||||||
var ambient_color = light_color * material.ambient.xyz;
|
var ambient_color = light_color * material.ambient.xyz * material.diffuse.xyz;
|
||||||
//let ambient_strength = 0.1;
|
|
||||||
var ambient_color = light_color * material.ambient.xyz;
|
|
||||||
|
|
||||||
//// diffuse ////
|
//// diffuse ////
|
||||||
let light_dir = normalize(light_pos - world_pos);
|
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 view_dir = normalize(camera_view_pos - world_pos);
|
||||||
let half_dir = normalize(view_dir + light_dir);
|
let half_dir = normalize(view_dir + light_dir);
|
||||||
|
|
||||||
|
|
||||||
let specular_strength = pow(max(dot(world_norm, half_dir), 0.0), material.shininess);
|
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);
|
||||||
let specular_strength = pow(max(dot(world_norm, half_dir), 0.0), material.shininess);
|
|
||||||
var specular_color = specular_strength * (light_color * material.specular.xyz);
|
|
||||||
//// end of specular ////
|
//// end of specular ////
|
||||||
|
|
||||||
//// point light attenuation ////
|
//// point light attenuation ////
|
||||||
|
|
|
@ -3,6 +3,8 @@ use std::sync::Arc;
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
use lyra_resource::{Resource, Texture};
|
use lyra_resource::{Resource, Texture};
|
||||||
|
|
||||||
|
use super::render_buffer::BindGroupPair;
|
||||||
|
|
||||||
/* #[derive(Clone)]
|
/* #[derive(Clone)]
|
||||||
pub struct Texture {
|
pub struct Texture {
|
||||||
texture_id: u32,
|
texture_id: u32,
|
||||||
|
@ -22,23 +24,75 @@ impl Texture {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct RenderTexture {
|
pub struct RenderTexture {
|
||||||
texture: Arc<wgpu::Texture>,
|
pub inner_texture: wgpu::Texture,
|
||||||
view: Arc<wgpu::TextureView>,
|
pub view: wgpu::TextureView,
|
||||||
sampler: Arc<wgpu::Sampler>,
|
pub sampler: wgpu::Sampler,
|
||||||
|
|
||||||
|
/// Most RenderTextures will have this, but things like depth buffers wont
|
||||||
|
pub bindgroup_pair: Option<BindGroupPair>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderTexture {
|
impl RenderTexture {
|
||||||
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
|
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> {
|
pub fn create_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||||
let img = image::load_from_memory(bytes)?;
|
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
Self::from_image(device, queue, &img, Some(label))
|
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 rgba = img.to_rgba8();
|
||||||
let dimensions = img.dimensions();
|
let dimensions = img.dimensions();
|
||||||
|
|
||||||
|
@ -89,10 +143,13 @@ impl RenderTexture {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let bgp = Self::create_bind_group_pair(device, bg_layout, &view, &sampler);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
texture: Arc::new(texture),
|
inner_texture: texture,
|
||||||
view: Arc::new(view),
|
view: view,
|
||||||
sampler: Arc::new(sampler),
|
sampler: sampler,
|
||||||
|
bindgroup_pair: Some(bgp),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +166,7 @@ impl RenderTexture {
|
||||||
queue.write_texture(
|
queue.write_texture(
|
||||||
wgpu::ImageCopyTexture {
|
wgpu::ImageCopyTexture {
|
||||||
aspect: wgpu::TextureAspect::All,
|
aspect: wgpu::TextureAspect::All,
|
||||||
texture: &self.texture,
|
texture: &self.inner_texture,
|
||||||
mip_level: 0,
|
mip_level: 0,
|
||||||
origin: wgpu::Origin3d::ZERO,
|
origin: wgpu::Origin3d::ZERO,
|
||||||
},
|
},
|
||||||
|
@ -159,21 +216,18 @@ impl RenderTexture {
|
||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
texture: Arc::new(texture),
|
inner_texture: texture,
|
||||||
view: Arc::new(view),
|
view: view,
|
||||||
sampler: Arc::new(sampler),
|
sampler: sampler,
|
||||||
|
bindgroup_pair: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inner_texture(&self) -> &wgpu::Texture {
|
/// Returns the bind group stored inside the bind group pair.
|
||||||
&self.texture
|
///
|
||||||
}
|
/// Panics:
|
||||||
|
/// * This will panic if the texture isn't storing its bind group.
|
||||||
pub fn view(&self) -> &wgpu::TextureView {
|
pub fn bind_group(&self) -> &wgpu::BindGroup {
|
||||||
&self.view
|
&self.bindgroup_pair.as_ref().unwrap().bindgroup
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sampler(&self) -> &wgpu::Sampler {
|
|
||||||
&self.sampler
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue