mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 06:00:20 +00:00
separate albedo color and make it required
I worked really hard to make ColorSource work, but sadly we need color to be instanceable and making it optional would add too much complexity. Maybe at some point in the future we can add it back. On the plus side, albedo color now modulates the albedo texture
This commit is contained in:
parent
ffa0bbe9ee
commit
04590de678
16 changed files with 146 additions and 76 deletions
|
@ -138,7 +138,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
}).map(|(f, attrs)| {
|
||||
let field_name = f.ident.as_ref().unwrap().to_string();
|
||||
let uniform = format!("{}_{}", struct_name, field_name);
|
||||
let texture = format!("{}_texture", uniform);
|
||||
let texture = format!("{}", uniform);
|
||||
let sampler = format!("{}_sampler", uniform);
|
||||
uniform_name_strings.push(uniform.clone());
|
||||
texture_and_sampler_name_strings.push(texture.clone());
|
||||
|
@ -184,7 +184,6 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
});
|
||||
|
||||
impl bevy::render::shader::AsUniforms for #struct_name {
|
||||
// TODO: max this an iterator that feeds on field_uniform_names_ident
|
||||
fn get_field_infos(&self) -> &[bevy::render::shader::FieldInfo] {
|
||||
#field_infos_ident
|
||||
}
|
||||
|
@ -192,7 +191,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
|||
fn get_field_bind_type(&self, name: &str) -> Option<bevy::render::shader::FieldBindType> {
|
||||
use bevy::render::shader::AsFieldBindType;
|
||||
match name {
|
||||
#(#active_uniform_field_name_strings => Some(self.#active_uniform_field_names.get_field_bind_type()),)*
|
||||
#(#active_uniform_field_name_strings => self.#active_uniform_field_names.get_field_bind_type(),)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
..Default::default()
|
||||
},
|
||||
material: MyMaterial {
|
||||
color: Color::rgb(0.0, 0.8, 0.0).into(),
|
||||
color: Color::rgb(0.0, 0.8, 0.0),
|
||||
always_red: false,
|
||||
},
|
||||
translation: Translation::new(-2.0, 0.0, 0.0),
|
||||
|
@ -99,7 +99,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
..Default::default()
|
||||
},
|
||||
material: MyMaterial {
|
||||
color: Color::rgb(0.0, 0.0, 0.0).into(),
|
||||
color: Color::rgb(0.0, 0.0, 0.0),
|
||||
always_red: true,
|
||||
},
|
||||
translation: Translation::new(2.0, 0.0, 0.0),
|
||||
|
|
|
@ -16,7 +16,8 @@ fn create_entities_insert_vec(
|
|||
vec![(
|
||||
plane_handle,
|
||||
StandardMaterial {
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1),
|
||||
..Default::default()
|
||||
},
|
||||
LocalToWorld::identity(),
|
||||
Translation::new(0.0, 0.0, 0.0),
|
||||
|
@ -29,7 +30,8 @@ fn create_entities_insert_vec(
|
|||
vec![(
|
||||
cube_handle,
|
||||
StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3).into(),
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3),
|
||||
..Default::default()
|
||||
},
|
||||
LocalToWorld::identity(),
|
||||
Translation::new(0.0, 0.0, 1.0),
|
||||
|
@ -79,7 +81,8 @@ fn create_entities_builder_add_component(
|
|||
.build_entity()
|
||||
.add(plane_handle)
|
||||
.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1),
|
||||
..Default::default()
|
||||
})
|
||||
.add(LocalToWorld::identity())
|
||||
.add(Translation::new(0.0, 0.0, 0.0))
|
||||
|
@ -87,7 +90,8 @@ fn create_entities_builder_add_component(
|
|||
.build_entity()
|
||||
.add(cube_handle)
|
||||
.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3).into(),
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3),
|
||||
..Default::default()
|
||||
})
|
||||
.add(LocalToWorld::identity())
|
||||
.add(Translation::new(0.0, 0.0, 1.0))
|
||||
|
@ -167,10 +171,12 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3).into(),
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3),
|
||||
..Default::default()
|
||||
});
|
||||
let plane_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
// no-archetype precompile: 1.24 sec
|
||||
|
|
|
@ -19,10 +19,8 @@ fn build_move_system() -> Box<dyn Schedulable> {
|
|||
for (mut translation, material_handle) in person_query.iter_mut(world) {
|
||||
let material = material_storage.get_mut(&material_handle).unwrap();
|
||||
translation.0 += math::vec3(1.0, 0.0, 0.0) * time.delta_seconds;
|
||||
if let ColorSource::Color(ref mut color) = material.albedo {
|
||||
*color = *color
|
||||
material.albedo = material.albedo
|
||||
+ Color::rgb(-time.delta_seconds, -time.delta_seconds, time.delta_seconds);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -35,10 +33,12 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
});
|
||||
let plane_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let mut builder = world
|
||||
|
@ -84,8 +84,8 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
rng.gen_range(0.0, 1.0),
|
||||
rng.gen_range(0.0, 1.0),
|
||||
rng.gen_range(0.0, 1.0),
|
||||
)
|
||||
.into(),
|
||||
),
|
||||
..Default::default()
|
||||
});
|
||||
builder = builder.add_entity(MeshEntity {
|
||||
mesh: cube_handle,
|
||||
|
|
|
@ -159,6 +159,7 @@ fn create_person(world: &mut World, mesh_handle: Handle<Mesh>, translation: Tran
|
|||
},
|
||||
StandardMaterial {
|
||||
albedo: (math::vec4(0.5, 0.3, 0.3, 1.0) * random::<f32>()).into(),
|
||||
..Default::default()
|
||||
},
|
||||
Renderable {
|
||||
instanced: true,
|
||||
|
|
|
@ -30,7 +30,8 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
world
|
||||
|
|
|
@ -24,7 +24,7 @@ pub fn setup(world: &mut World, resources: &mut Resources) {
|
|||
.add_entity(MeshEntity {
|
||||
mesh: plane_handle,
|
||||
material: StandardMaterial {
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1),
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
|
@ -32,7 +32,7 @@ pub fn setup(world: &mut World, resources: &mut Resources) {
|
|||
.add_entity(MeshEntity {
|
||||
mesh: cube_handle,
|
||||
material: StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
},
|
||||
translation: Translation::new(0.0, 0.0, 1.0),
|
||||
..Default::default()
|
||||
|
|
|
@ -12,10 +12,12 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
});
|
||||
let plane_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
world
|
||||
|
|
|
@ -19,10 +19,8 @@ fn build_move_system() -> Box<dyn Schedulable> {
|
|||
for (mut translation, material_handle) in person_query.iter_mut(world) {
|
||||
let material = material_storage.get_mut(&material_handle).unwrap();
|
||||
translation.0 += math::vec3(1.0, 0.0, 0.0) * time.delta_seconds;
|
||||
if let ColorSource::Color(ref mut color) = material.albedo {
|
||||
*color = *color
|
||||
+ Color::rgb(-time.delta_seconds, -time.delta_seconds, time.delta_seconds);
|
||||
}
|
||||
material.albedo = material.albedo
|
||||
+ Color::rgb(-time.delta_seconds, -time.delta_seconds, time.delta_seconds);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -35,10 +33,12 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let plane_handle = mesh_storage.add(Mesh::load(MeshType::Plane { size: 10.0 }));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3).into(),
|
||||
albedo: Color::rgb(0.5, 0.4, 0.3),
|
||||
..Default::default()
|
||||
});
|
||||
let plane_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1).into(),
|
||||
albedo: Color::rgb(0.1, 0.2, 0.1),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let mut builder = world
|
||||
|
@ -84,8 +84,8 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
rng.gen_range(0.0, 1.0),
|
||||
rng.gen_range(0.0, 1.0),
|
||||
rng.gen_range(0.0, 1.0),
|
||||
)
|
||||
.into(),
|
||||
),
|
||||
..Default::default()
|
||||
});
|
||||
builder = builder.add_entity(MeshEntity {
|
||||
mesh: cube_handle,
|
||||
|
|
|
@ -19,7 +19,14 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
.unwrap();
|
||||
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: texture_handle.into(),
|
||||
albedo_texture: Some(texture_handle),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let modulated_cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgba(1.0, 0.0, 0.0, 0.5),
|
||||
albedo_texture: Some(texture_handle),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
world
|
||||
|
@ -28,7 +35,14 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
.add_entity(MeshEntity {
|
||||
mesh: cube_handle,
|
||||
material: cube_material_handle,
|
||||
translation: Translation::new(0.0, 0.0, 0.0),
|
||||
translation: Translation::new(1.0, 0.0, 0.0),
|
||||
..Default::default()
|
||||
})
|
||||
// cube modulated
|
||||
.add_entity(MeshEntity {
|
||||
mesh: cube_handle,
|
||||
material: modulated_cube_material_handle,
|
||||
translation: Translation::new(-1.0, 0.0, 0.0),
|
||||
..Default::default()
|
||||
})
|
||||
// light
|
||||
|
|
|
@ -11,7 +11,8 @@ fn setup(world: &mut World, resources: &mut Resources) {
|
|||
.unwrap();
|
||||
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
|
||||
let cube_material_handle = material_storage.add(StandardMaterial {
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3).into(),
|
||||
albedo: Color::rgb(0.5, 0.3, 0.3),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
world
|
||||
|
|
|
@ -23,19 +23,20 @@ layout(set = 0, binding = 1) uniform Lights {
|
|||
Light SceneLights[MAX_LIGHTS];
|
||||
};
|
||||
|
||||
# ifdef STANDARD_MATERIAL_ALBEDO_TEXTURE
|
||||
layout(set = 2, binding = 1) uniform texture2D StandardMaterial_albedo_texture;
|
||||
layout(set = 2, binding = 2) uniform sampler StandardMaterial_albedo_sampler;
|
||||
# else
|
||||
layout(set = 2, binding = 1) uniform StandardMaterial_albedo {
|
||||
vec4 Albedo;
|
||||
};
|
||||
|
||||
# ifdef STANDARD_MATERIAL_ALBEDO_TEXTURE
|
||||
layout(set = 3, binding = 1) uniform texture2D StandardMaterial_albedo_texture;
|
||||
layout(set = 3, binding = 2) uniform sampler StandardMaterial_albedo_texture_sampler;
|
||||
# endif
|
||||
|
||||
void main() {
|
||||
vec4 albedo = Albedo;
|
||||
# ifdef STANDARD_MATERIAL_ALBEDO_TEXTURE
|
||||
vec4 Albedo = texture(
|
||||
sampler2D(StandardMaterial_albedo_texture, StandardMaterial_albedo_sampler),
|
||||
albedo *= texture(
|
||||
sampler2D(StandardMaterial_albedo_texture, StandardMaterial_albedo_texture_sampler),
|
||||
v_Uv);
|
||||
# endif
|
||||
vec3 normal = normalize(v_Normal);
|
||||
|
@ -51,5 +52,5 @@ void main() {
|
|||
color += diffuse * light.color.xyz;
|
||||
}
|
||||
// multiply the light by material color
|
||||
o_Target = vec4(color, 1.0) * Albedo;
|
||||
o_Target = vec4(color, 1.0) * albedo;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
|||
core::GetBytes,
|
||||
render::{
|
||||
color::ColorSource,
|
||||
pipeline::{VertexBufferDescriptor, BindType},
|
||||
pipeline::{BindType, VertexBufferDescriptor},
|
||||
texture::{Texture, TextureViewDimension},
|
||||
},
|
||||
};
|
||||
|
@ -72,35 +72,36 @@ where
|
|||
bind_type: BindType::Sampler,
|
||||
})
|
||||
} else {
|
||||
if self.index == self.field_infos.len() {
|
||||
if self.index >= self.field_infos.len() {
|
||||
None
|
||||
} else {
|
||||
let index = self.index;
|
||||
self.index += 1;
|
||||
let ref field_info = self.field_infos[index];
|
||||
let bind_type = self
|
||||
.uniforms
|
||||
.get_field_bind_type(field_info.name)
|
||||
.unwrap();
|
||||
Some(match bind_type {
|
||||
FieldBindType::Uniform => UniformInfo {
|
||||
bind_type: BindType::Uniform {
|
||||
dynamic: false,
|
||||
properties: Vec::new(),
|
||||
},
|
||||
name: field_info.uniform_name,
|
||||
},
|
||||
FieldBindType::Texture => {
|
||||
self.add_sampler = true;
|
||||
UniformInfo {
|
||||
bind_type: BindType::SampledTexture {
|
||||
dimension: TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
let bind_type = self.uniforms.get_field_bind_type(field_info.name);
|
||||
if let Some(bind_type) = bind_type {
|
||||
Some(match bind_type {
|
||||
FieldBindType::Uniform => UniformInfo {
|
||||
bind_type: BindType::Uniform {
|
||||
dynamic: false,
|
||||
properties: Vec::new(),
|
||||
},
|
||||
name: field_info.texture_name,
|
||||
name: field_info.uniform_name,
|
||||
},
|
||||
FieldBindType::Texture => {
|
||||
self.add_sampler = true;
|
||||
UniformInfo {
|
||||
bind_type: BindType::SampledTexture {
|
||||
dimension: TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
name: field_info.texture_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
self.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,28 +112,43 @@ pub struct FieldInfo {
|
|||
pub uniform_name: &'static str,
|
||||
pub texture_name: &'static str,
|
||||
pub sampler_name: &'static str,
|
||||
pub is_instanceable: bool,
|
||||
pub is_instanceable: bool,
|
||||
}
|
||||
|
||||
pub trait AsFieldBindType {
|
||||
fn get_field_bind_type(&self) -> FieldBindType;
|
||||
fn get_field_bind_type(&self) -> Option<FieldBindType>;
|
||||
}
|
||||
|
||||
impl AsFieldBindType for ColorSource {
|
||||
fn get_field_bind_type(&self) -> FieldBindType {
|
||||
match *self {
|
||||
fn get_field_bind_type(&self) -> Option<FieldBindType> {
|
||||
Some(match *self {
|
||||
ColorSource::Texture(_) => FieldBindType::Texture,
|
||||
ColorSource::Color(_) => FieldBindType::Uniform,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl AsFieldBindType for Option<Handle<Texture>> {
|
||||
fn get_field_bind_type(&self) -> Option<FieldBindType> {
|
||||
match *self {
|
||||
Some(_) => Some(FieldBindType::Texture),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsFieldBindType for Handle<Texture> {
|
||||
fn get_field_bind_type(&self) -> Option<FieldBindType> {
|
||||
Some(FieldBindType::Texture)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsFieldBindType for T
|
||||
where
|
||||
T: GetBytes,
|
||||
{
|
||||
default fn get_field_bind_type(&self) -> FieldBindType {
|
||||
FieldBindType::Uniform
|
||||
default fn get_field_bind_type(&self) -> Option<FieldBindType> {
|
||||
Some(FieldBindType::Uniform)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,6 +173,12 @@ impl GetTexture for Handle<Texture> {
|
|||
}
|
||||
}
|
||||
|
||||
impl GetTexture for Option<Handle<Texture>> {
|
||||
fn get_texture(&self) -> Option<Handle<Texture>> {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl GetTexture for ColorSource {
|
||||
fn get_texture(&self) -> Option<Handle<Texture>> {
|
||||
match self {
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
use crate::render::{Color, ColorSource};
|
||||
use crate::{asset::Handle, render::{Color, texture::Texture}};
|
||||
|
||||
use crate as bevy; // for macro imports
|
||||
use bevy_derive::Uniforms;
|
||||
|
||||
#[derive(Uniforms)]
|
||||
pub struct StandardMaterial {
|
||||
pub albedo: Color,
|
||||
#[uniform(shader_def)]
|
||||
pub albedo: ColorSource,
|
||||
pub albedo_texture: Option<Handle<Texture>>,
|
||||
}
|
||||
|
||||
impl Default for StandardMaterial {
|
||||
fn default() -> Self {
|
||||
StandardMaterial {
|
||||
albedo: Color::rgb(0.3, 0.3, 0.3).into(),
|
||||
albedo: Color::rgb(1.0, 1.0, 1.0),
|
||||
albedo_texture: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use crate::asset::Asset;
|
||||
use crate::{
|
||||
asset::{Asset, Handle},
|
||||
core::GetBytes,
|
||||
render::shader::ShaderDefSuffixProvider,
|
||||
};
|
||||
use std::fs::File;
|
||||
|
||||
pub enum TextureType {
|
||||
|
@ -55,3 +59,22 @@ pub fn create_texels(size: usize) -> Vec<u8> {
|
|||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
impl ShaderDefSuffixProvider for Option<Handle<Texture>> {
|
||||
fn get_shader_def(&self) -> Option<&'static str> {
|
||||
match *self {
|
||||
Some(_) => Some(""),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GetBytes for Option<Handle<Texture>> {
|
||||
fn get_bytes(&self) -> Vec<std::primitive::u8> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn get_bytes_ref(&self) -> Option<&[std::primitive::u8]> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ run_example() {
|
|||
timeout "$duration" cargo run --release --example $1
|
||||
}
|
||||
|
||||
|
||||
|
||||
for entry in examples/*
|
||||
do
|
||||
IFS='/'
|
||||
|
|
Loading…
Reference in a new issue