mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
Migrate meshes and materials to required components (#15524)
# Objective A big step in the migration to required components: meshes and materials! ## Solution As per the [selected proposal](https://hackmd.io/@bevy/required_components/%2Fj9-PnF-2QKK0on1KQ29UWQ): - Deprecate `MaterialMesh2dBundle`, `MaterialMeshBundle`, and `PbrBundle`. - Add `Mesh2d` and `Mesh3d` components, which wrap a `Handle<Mesh>`. - Add `MeshMaterial2d<M: Material2d>` and `MeshMaterial3d<M: Material>`, which wrap a `Handle<M>`. - Meshes *without* a mesh material should be rendered with a default material. The existence of a material is determined by `HasMaterial2d`/`HasMaterial3d`, which is required by `MeshMaterial2d`/`MeshMaterial3d`. This gets around problems with the generics. Previously: ```rust commands.spawn(MaterialMesh2dBundle { mesh: meshes.add(Circle::new(100.0)).into(), material: materials.add(Color::srgb(7.5, 0.0, 7.5)), transform: Transform::from_translation(Vec3::new(-200., 0., 0.)), ..default() }); ``` Now: ```rust commands.spawn(( Mesh2d(meshes.add(Circle::new(100.0))), MeshMaterial2d(materials.add(Color::srgb(7.5, 0.0, 7.5))), Transform::from_translation(Vec3::new(-200., 0., 0.)), )); ``` If the mesh material is missing, previously nothing was rendered. Now, it renders a white default `ColorMaterial` in 2D and a `StandardMaterial` in 3D (this can be overridden). Below, only every other entity has a material: ![Näyttökuva 2024-09-29 181746](https://github.com/user-attachments/assets/5c8be029-d2fe-4b8c-ae89-17a72ff82c9a) ![Näyttökuva 2024-09-29 181918](https://github.com/user-attachments/assets/58adbc55-5a1e-4c7d-a2c7-ed456227b909) Why white? This is still open for discussion, but I think white makes sense for a *default* material, while *invalid* asset handles pointing to nothing should have something like a pink material to indicate that something is broken (I don't handle that in this PR yet). This is kind of a mix of Godot and Unity: Godot just renders a white material for non-existent materials, while Unity renders nothing when no materials exist, but renders pink for invalid materials. I can also change the default material to pink if that is preferable though. ## Testing I ran some 2D and 3D examples to test if anything changed visually. I have not tested all examples or features yet however. If anyone wants to test more extensively, it would be appreciated! ## Implementation Notes - The relationship between `bevy_render` and `bevy_pbr` is weird here. `bevy_render` needs `Mesh3d` for its own systems, but `bevy_pbr` has all of the material logic, and `bevy_render` doesn't depend on it. I feel like the two crates should be refactored in some way, but I think that's out of scope for this PR. - I didn't migrate meshlets to required components yet. That can probably be done in a follow-up, as this is already a huge PR. - It is becoming increasingly clear to me that we really, *really* want to disallow raw asset handles as components. They caused me a *ton* of headache here already, and it took me a long time to find every place that queried for them or inserted them directly on entities, since there were no compiler errors for it. If we don't remove the `Component` derive, I expect raw asset handles to be a *huge* footgun for users as we transition to wrapper components, especially as handles as components have been the norm so far. I personally consider this to be a blocker for 0.15: we need to migrate to wrapper components for asset handles everywhere, and remove the `Component` derive. Also see https://github.com/bevyengine/bevy/issues/14124. --- ## Migration Guide Asset handles for meshes and mesh materials must now be wrapped in the `Mesh2d` and `MeshMaterial2d` or `Mesh3d` and `MeshMaterial3d` components for 2D and 3D respectively. Raw handles as components no longer render meshes. Additionally, `MaterialMesh2dBundle`, `MaterialMeshBundle`, and `PbrBundle` have been deprecated. Instead, use the mesh and material components directly. Previously: ```rust commands.spawn(MaterialMesh2dBundle { mesh: meshes.add(Circle::new(100.0)).into(), material: materials.add(Color::srgb(7.5, 0.0, 7.5)), transform: Transform::from_translation(Vec3::new(-200., 0., 0.)), ..default() }); ``` Now: ```rust commands.spawn(( Mesh2d(meshes.add(Circle::new(100.0))), MeshMaterial2d(materials.add(Color::srgb(7.5, 0.0, 7.5))), Transform::from_translation(Vec3::new(-200., 0., 0.)), )); ``` If the mesh material is missing, a white default material is now used. Previously, nothing was rendered if the material was missing. The `WithMesh2d` and `WithMesh3d` query filter type aliases have also been removed. Simply use `With<Mesh2d>` or `With<Mesh3d>`. --------- Co-authored-by: Tim Blackbird <justthecooldude@gmail.com> Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
parent
0fe17b8b30
commit
54006b107b
144 changed files with 2044 additions and 2088 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -432,6 +432,6 @@ jobs:
|
|||
echo -e "$errors"
|
||||
echo " Avoid importing internal Bevy crates, they should not be used directly"
|
||||
echo " Fix the issue by replacing 'bevy_*' with 'bevy'"
|
||||
echo " Example: 'use bevy::sprite::MaterialMesh2dBundle;' instead of 'bevy_internal::sprite::MaterialMesh2dBundle;'"
|
||||
echo " Example: 'use bevy::sprite::Mesh2d;' instead of 'bevy_internal::sprite::Mesh2d;'"
|
||||
exit 1
|
||||
fi
|
||||
|
|
|
@ -17,7 +17,8 @@ use bevy_ecs::{
|
|||
use bevy_hierarchy::{BuildChildren, ChildBuild, WorldChildBuilder};
|
||||
use bevy_math::{Affine2, Mat4, Vec3};
|
||||
use bevy_pbr::{
|
||||
DirectionalLight, PbrBundle, PointLight, SpotLight, StandardMaterial, UvChannel, MAX_JOINTS,
|
||||
DirectionalLight, MeshMaterial3d, PointLight, SpotLight, StandardMaterial, UvChannel,
|
||||
MAX_JOINTS,
|
||||
};
|
||||
use bevy_render::{
|
||||
alpha::AlphaMode,
|
||||
|
@ -25,7 +26,7 @@ use bevy_render::{
|
|||
mesh::{
|
||||
morph::{MeshMorphWeights, MorphAttributes, MorphTargetImage, MorphWeights},
|
||||
skinning::{SkinnedMesh, SkinnedMeshInverseBindposes},
|
||||
Indices, Mesh, MeshVertexAttribute, VertexAttributeValues,
|
||||
Indices, Mesh, Mesh3d, MeshVertexAttribute, VertexAttributeValues,
|
||||
},
|
||||
prelude::SpatialBundle,
|
||||
primitives::Aabb,
|
||||
|
@ -1456,12 +1457,13 @@ fn load_node(
|
|||
};
|
||||
let bounds = primitive.bounding_box();
|
||||
|
||||
let mut mesh_entity = parent.spawn(PbrBundle {
|
||||
let mut mesh_entity = parent.spawn((
|
||||
// TODO: handle missing label handle errors here?
|
||||
mesh: load_context.get_label_handle(primitive_label.to_string()),
|
||||
material: load_context.get_label_handle(&material_label),
|
||||
..Default::default()
|
||||
});
|
||||
Mesh3d(load_context.get_label_handle(primitive_label.to_string())),
|
||||
MeshMaterial3d::<StandardMaterial>(
|
||||
load_context.get_label_handle(&material_label),
|
||||
),
|
||||
));
|
||||
|
||||
let target_count = primitive.morph_targets().len();
|
||||
if target_count != 0 {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#![expect(deprecated)]
|
||||
|
||||
use crate::{
|
||||
CascadeShadowConfig, Cascades, DirectionalLight, Material, PointLight, SpotLight,
|
||||
StandardMaterial,
|
||||
CascadeShadowConfig, Cascades, DirectionalLight, Material, MeshMaterial3d, PointLight,
|
||||
SpotLight, StandardMaterial,
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_derive::{Deref, DerefMut};
|
||||
use bevy_ecs::{
|
||||
bundle::Bundle,
|
||||
|
@ -14,21 +13,29 @@ use bevy_ecs::{
|
|||
};
|
||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||
use bevy_render::{
|
||||
mesh::Mesh,
|
||||
mesh::Mesh3d,
|
||||
primitives::{CascadesFrusta, CubemapFrusta, Frustum},
|
||||
view::{InheritedVisibility, ViewVisibility, Visibility},
|
||||
world_sync::SyncToRenderWorld,
|
||||
};
|
||||
use bevy_transform::components::{GlobalTransform, Transform};
|
||||
|
||||
/// A component bundle for PBR entities with a [`Mesh`] and a [`StandardMaterial`].
|
||||
/// A component bundle for PBR entities with a [`Mesh3d`] and a [`MeshMaterial3d<StandardMaterial>`].
|
||||
#[deprecated(
|
||||
since = "0.15.0",
|
||||
note = "Use the `Mesh3d` and `MeshMaterial3d` components instead. Inserting them will now also insert the other components required by them automatically."
|
||||
)]
|
||||
pub type PbrBundle = MaterialMeshBundle<StandardMaterial>;
|
||||
|
||||
/// A component bundle for entities with a [`Mesh`] and a [`Material`].
|
||||
/// A component bundle for entities with a [`Mesh3d`] and a [`MeshMaterial3d`].
|
||||
#[derive(Bundle, Clone)]
|
||||
#[deprecated(
|
||||
since = "0.15.0",
|
||||
note = "Use the `Mesh3d` and `MeshMaterial3d` components instead. Inserting them will now also insert the other components required by them automatically."
|
||||
)]
|
||||
pub struct MaterialMeshBundle<M: Material> {
|
||||
pub mesh: Handle<Mesh>,
|
||||
pub material: Handle<M>,
|
||||
pub mesh: Mesh3d,
|
||||
pub material: MeshMaterial3d<M>,
|
||||
pub transform: Transform,
|
||||
pub global_transform: GlobalTransform,
|
||||
/// User indication of whether an entity is visible
|
||||
|
|
|
@ -34,6 +34,7 @@ mod light;
|
|||
mod light_probe;
|
||||
mod lightmap;
|
||||
mod material;
|
||||
mod mesh_material;
|
||||
mod parallax;
|
||||
mod pbr_material;
|
||||
mod prepass;
|
||||
|
@ -53,6 +54,7 @@ pub use light::*;
|
|||
pub use light_probe::*;
|
||||
pub use lightmap::*;
|
||||
pub use material::*;
|
||||
pub use mesh_material::*;
|
||||
pub use parallax::*;
|
||||
pub use pbr_material::*;
|
||||
pub use prepass::*;
|
||||
|
@ -83,6 +85,7 @@ pub mod prelude {
|
|||
LightProbe,
|
||||
},
|
||||
material::{Material, MaterialPlugin},
|
||||
mesh_material::MeshMaterial3d,
|
||||
parallax::ParallaxMappingMethod,
|
||||
pbr_material::StandardMaterial,
|
||||
ssao::ScreenSpaceAmbientOcclusionPlugin,
|
||||
|
@ -411,13 +414,13 @@ impl Plugin for PbrPlugin {
|
|||
app.add_plugins(DeferredPbrLightingPlugin);
|
||||
}
|
||||
|
||||
// Initialize the default material.
|
||||
app.world_mut()
|
||||
.resource_mut::<Assets<StandardMaterial>>()
|
||||
.insert(
|
||||
&Handle::<StandardMaterial>::default(),
|
||||
StandardMaterial {
|
||||
base_color: Color::srgb(1.0, 0.0, 0.5),
|
||||
unlit: true,
|
||||
base_color: Color::WHITE,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
@ -428,7 +431,14 @@ impl Plugin for PbrPlugin {
|
|||
|
||||
// Extract the required data from the main world
|
||||
render_app
|
||||
.add_systems(ExtractSchedule, (extract_clusters, extract_lights))
|
||||
.add_systems(
|
||||
ExtractSchedule,
|
||||
(
|
||||
extract_clusters,
|
||||
extract_lights,
|
||||
extract_default_materials.after(clear_material_instances::<StandardMaterial>),
|
||||
),
|
||||
)
|
||||
.add_systems(
|
||||
Render,
|
||||
(
|
||||
|
|
|
@ -7,7 +7,7 @@ use bevy_render::{
|
|||
camera::{Camera, CameraProjection},
|
||||
extract_component::ExtractComponent,
|
||||
extract_resource::ExtractResource,
|
||||
mesh::Mesh,
|
||||
mesh::Mesh3d,
|
||||
primitives::{Aabb, CascadesFrusta, CubemapFrusta, Frustum, Sphere},
|
||||
view::{
|
||||
InheritedVisibility, NoFrustumCulling, RenderLayers, ViewVisibility, VisibilityRange,
|
||||
|
@ -440,11 +440,11 @@ fn calculate_cascade(
|
|||
texel_size: cascade_texel_size,
|
||||
}
|
||||
}
|
||||
/// Add this component to make a [`Mesh`] not cast shadows.
|
||||
/// Add this component to make a [`Mesh3d`] not cast shadows.
|
||||
#[derive(Debug, Component, Reflect, Default)]
|
||||
#[reflect(Component, Default, Debug)]
|
||||
pub struct NotShadowCaster;
|
||||
/// Add this component to make a [`Mesh`] not receive shadows.
|
||||
/// Add this component to make a [`Mesh3d`] not receive shadows.
|
||||
///
|
||||
/// **Note:** If you're using diffuse transmission, setting [`NotShadowReceiver`] will
|
||||
/// cause both “regular” shadows as well as diffusely transmitted shadows to be disabled,
|
||||
|
@ -452,7 +452,7 @@ pub struct NotShadowCaster;
|
|||
#[derive(Debug, Component, Reflect, Default)]
|
||||
#[reflect(Component, Default, Debug)]
|
||||
pub struct NotShadowReceiver;
|
||||
/// Add this component to make a [`Mesh`] using a PBR material with [`diffuse_transmission`](crate::pbr_material::StandardMaterial::diffuse_transmission)`> 0.0`
|
||||
/// Add this component to make a [`Mesh3d`] using a PBR material with [`diffuse_transmission`](crate::pbr_material::StandardMaterial::diffuse_transmission)`> 0.0`
|
||||
/// receive shadows on its diffuse transmission lobe. (i.e. its “backside”)
|
||||
///
|
||||
/// Not enabled by default, as it requires carefully setting up [`thickness`](crate::pbr_material::StandardMaterial::thickness)
|
||||
|
@ -697,7 +697,7 @@ pub fn check_dir_light_mesh_visibility(
|
|||
(
|
||||
Without<NotShadowCaster>,
|
||||
Without<DirectionalLight>,
|
||||
With<Handle<Mesh>>,
|
||||
With<Mesh3d>,
|
||||
),
|
||||
>,
|
||||
visible_entity_ranges: Option<Res<VisibleEntityRanges>>,
|
||||
|
@ -866,7 +866,7 @@ pub fn check_point_light_mesh_visibility(
|
|||
(
|
||||
Without<NotShadowCaster>,
|
||||
Without<DirectionalLight>,
|
||||
With<Handle<Mesh>>,
|
||||
With<Mesh3d>,
|
||||
),
|
||||
>,
|
||||
visible_entity_ranges: Option<Res<VisibleEntityRanges>>,
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
//! with an addon like [The Lightmapper]. The tools in the [`bevy-baked-gi`]
|
||||
//! project support other lightmap baking methods.
|
||||
//!
|
||||
//! When a [`Lightmap`] component is added to an entity with a [`Mesh`] and a
|
||||
//! [`StandardMaterial`](crate::StandardMaterial), Bevy applies the lightmap when rendering. The brightness
|
||||
//! When a [`Lightmap`] component is added to an entity with a [`Mesh3d`] and a
|
||||
//! [`MeshMaterial3d<StandardMaterial>`], Bevy applies the lightmap when rendering. The brightness
|
||||
//! of the lightmap may be controlled with the `lightmap_exposure` field on
|
||||
//! `StandardMaterial`.
|
||||
//! [`StandardMaterial`].
|
||||
//!
|
||||
//! During the rendering extraction phase, we extract all lightmaps into the
|
||||
//! [`RenderLightmaps`] table, which lives in the render world. Mesh bindgroup
|
||||
|
@ -25,7 +25,9 @@
|
|||
//! appropriately.
|
||||
//!
|
||||
//! [The Lightmapper]: https://github.com/Naxela/The_Lightmapper
|
||||
//!
|
||||
//! [`Mesh3d`]: bevy_render::mesh::Mesh3d
|
||||
//! [`MeshMaterial3d<StandardMaterial>`]: crate::StandardMaterial
|
||||
//! [`StandardMaterial`]: crate::StandardMaterial
|
||||
//! [`bevy-baked-gi`]: https://github.com/pcwalton/bevy-baked-gi
|
||||
|
||||
use bevy_app::{App, Plugin};
|
||||
|
@ -61,10 +63,10 @@ pub struct LightmapPlugin;
|
|||
/// A component that applies baked indirect diffuse global illumination from a
|
||||
/// lightmap.
|
||||
///
|
||||
/// When assigned to an entity that contains a [`Mesh`] and a
|
||||
/// [`StandardMaterial`](crate::StandardMaterial), if the mesh has a second UV
|
||||
/// layer ([`ATTRIBUTE_UV_1`](bevy_render::mesh::Mesh::ATTRIBUTE_UV_1)), then
|
||||
/// the lightmap will render using those UVs.
|
||||
/// When assigned to an entity that contains a [`Mesh3d`](bevy_render::mesh::Mesh3d) and a
|
||||
/// [`MeshMaterial3d<StandardMaterial>`](crate::StandardMaterial), if the mesh
|
||||
/// has a second UV layer ([`ATTRIBUTE_UV_1`](bevy_render::mesh::Mesh::ATTRIBUTE_UV_1)),
|
||||
/// then the lightmap will render using those UVs.
|
||||
#[derive(Component, Clone, Reflect)]
|
||||
#[reflect(Component, Default)]
|
||||
pub struct Lightmap {
|
||||
|
|
|
@ -24,14 +24,15 @@ use bevy_reflect::std_traits::ReflectDefault;
|
|||
use bevy_reflect::Reflect;
|
||||
use bevy_render::{
|
||||
camera::TemporalJitter,
|
||||
extract_instances::{ExtractInstancesPlugin, ExtractedInstances},
|
||||
extract_instances::ExtractedInstances,
|
||||
extract_resource::ExtractResource,
|
||||
mesh::{MeshVertexBufferLayoutRef, RenderMesh},
|
||||
mesh::{Mesh3d, MeshVertexBufferLayoutRef, RenderMesh},
|
||||
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
|
||||
render_phase::*,
|
||||
render_resource::*,
|
||||
renderer::RenderDevice,
|
||||
view::{ExtractedView, Msaa, RenderVisibilityRanges, VisibleEntities, WithMesh},
|
||||
view::{ExtractedView, Msaa, RenderVisibilityRanges, ViewVisibility, VisibleEntities},
|
||||
Extract,
|
||||
};
|
||||
use bevy_utils::tracing::error;
|
||||
use core::{
|
||||
|
@ -43,26 +44,28 @@ use core::{
|
|||
|
||||
use self::{irradiance_volume::IrradianceVolume, prelude::EnvironmentMapLight};
|
||||
|
||||
/// Materials are used alongside [`MaterialPlugin`] and [`MaterialMeshBundle`]
|
||||
/// Materials are used alongside [`MaterialPlugin`], [`Mesh3d`], and [`MeshMaterial3d`]
|
||||
/// to spawn entities that are rendered with a specific [`Material`] type. They serve as an easy to use high level
|
||||
/// way to render [`Mesh`](bevy_render::mesh::Mesh) entities with custom shader logic.
|
||||
/// way to render [`Mesh3d`] entities with custom shader logic.
|
||||
///
|
||||
/// Materials must implement [`AsBindGroup`] to define how data will be transferred to the GPU and bound in shaders.
|
||||
/// [`AsBindGroup`] can be derived, which makes generating bindings straightforward. See the [`AsBindGroup`] docs for details.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Here is a simple Material implementation. The [`AsBindGroup`] derive has many features. To see what else is available,
|
||||
/// Here is a simple [`Material`] implementation. The [`AsBindGroup`] derive has many features. To see what else is available,
|
||||
/// check out the [`AsBindGroup`] documentation.
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_pbr::{Material, MaterialMeshBundle};
|
||||
/// # use bevy_pbr::{Material, MeshMaterial3d};
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// # use bevy_reflect::TypePath;
|
||||
/// # use bevy_render::{render_resource::{AsBindGroup, ShaderRef}, texture::Image};
|
||||
/// # use bevy_render::{mesh::{Mesh, Mesh3d}, render_resource::{AsBindGroup, ShaderRef}, texture::Image};
|
||||
/// # use bevy_color::LinearRgba;
|
||||
/// # use bevy_color::palettes::basic::RED;
|
||||
/// # use bevy_asset::{Handle, AssetServer, Assets, Asset};
|
||||
///
|
||||
/// # use bevy_math::primitives::Capsule3d;
|
||||
/// #
|
||||
/// #[derive(AsBindGroup, Debug, Clone, Asset, TypePath)]
|
||||
/// pub struct CustomMaterial {
|
||||
/// // Uniform bindings must implement `ShaderType`, which will be used to convert the value to
|
||||
|
@ -84,17 +87,23 @@ use self::{irradiance_volume::IrradianceVolume, prelude::EnvironmentMapLight};
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // Spawn an entity using `CustomMaterial`.
|
||||
/// fn setup(mut commands: Commands, mut materials: ResMut<Assets<CustomMaterial>>, asset_server: Res<AssetServer>) {
|
||||
/// commands.spawn(MaterialMeshBundle {
|
||||
/// material: materials.add(CustomMaterial {
|
||||
/// // Spawn an entity with a mesh using `CustomMaterial`.
|
||||
/// fn setup(
|
||||
/// mut commands: Commands,
|
||||
/// mut meshes: ResMut<Assets<Mesh>>,
|
||||
/// mut materials: ResMut<Assets<CustomMaterial>>,
|
||||
/// asset_server: Res<AssetServer>
|
||||
/// ) {
|
||||
/// commands.spawn((
|
||||
/// Mesh3d(meshes.add(Capsule3d::default())),
|
||||
/// MeshMaterial3d(materials.add(CustomMaterial {
|
||||
/// color: RED.into(),
|
||||
/// color_texture: asset_server.load("some_image.png"),
|
||||
/// }),
|
||||
/// ..Default::default()
|
||||
/// });
|
||||
/// })),
|
||||
/// ));
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// In WGSL shaders, the material's binding would look like this:
|
||||
///
|
||||
/// ```wgsl
|
||||
|
@ -258,20 +267,25 @@ where
|
|||
M::Data: PartialEq + Eq + Hash + Clone,
|
||||
{
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_asset::<M>().add_plugins((
|
||||
ExtractInstancesPlugin::<AssetId<M>>::extract_visible(),
|
||||
RenderAssetPlugin::<PreparedMaterial<M>>::default(),
|
||||
));
|
||||
app.init_asset::<M>()
|
||||
.register_type::<MeshMaterial3d<M>>()
|
||||
.register_type::<HasMaterial3d>()
|
||||
.add_plugins(RenderAssetPlugin::<PreparedMaterial<M>>::default());
|
||||
|
||||
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
render_app
|
||||
.init_resource::<DrawFunctions<Shadow>>()
|
||||
.init_resource::<ExtractedInstances<AssetId<M>>>()
|
||||
.add_render_command::<Shadow, DrawPrepass<M>>()
|
||||
.add_render_command::<Transmissive3d, DrawMaterial<M>>()
|
||||
.add_render_command::<Transparent3d, DrawMaterial<M>>()
|
||||
.add_render_command::<Opaque3d, DrawMaterial<M>>()
|
||||
.add_render_command::<AlphaMask3d, DrawMaterial<M>>()
|
||||
.init_resource::<SpecializedMeshPipelines<MaterialPipeline<M>>>()
|
||||
.add_systems(
|
||||
ExtractSchedule,
|
||||
(clear_material_instances::<M>, extract_mesh_materials::<M>).chain(),
|
||||
)
|
||||
.add_systems(
|
||||
Render,
|
||||
queue_material_meshes::<M>
|
||||
|
@ -527,6 +541,35 @@ pub const fn screen_space_specular_transmission_pipeline_key(
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn clear_material_instances<M: Material>(
|
||||
mut material_instances: ResMut<RenderMaterialInstances<M>>,
|
||||
) {
|
||||
material_instances.clear();
|
||||
}
|
||||
|
||||
fn extract_mesh_materials<M: Material>(
|
||||
mut material_instances: ResMut<RenderMaterialInstances<M>>,
|
||||
query: Extract<Query<(Entity, &ViewVisibility, &MeshMaterial3d<M>), With<Mesh3d>>>,
|
||||
) {
|
||||
for (entity, view_visibility, material) in &query {
|
||||
if view_visibility.get() {
|
||||
material_instances.insert(entity, material.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extracts default materials for 3D meshes with no [`MeshMaterial3d`].
|
||||
pub(super) fn extract_default_materials(
|
||||
mut material_instances: ResMut<RenderMaterialInstances<StandardMaterial>>,
|
||||
query: Extract<Query<(Entity, &ViewVisibility), (With<Mesh3d>, Without<HasMaterial3d>)>>,
|
||||
) {
|
||||
for (entity, view_visibility) in &query {
|
||||
if view_visibility.get() {
|
||||
material_instances.insert(entity, AssetId::default());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// For each view, iterates over all the meshes visible from that view and adds
|
||||
/// them to [`BinnedRenderPhase`]s or [`SortedRenderPhase`]s as appropriate.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
|
@ -686,7 +729,7 @@ pub fn queue_material_meshes<M: Material>(
|
|||
}
|
||||
|
||||
let rangefinder = view.rangefinder3d();
|
||||
for visible_entity in visible_entities.iter::<WithMesh>() {
|
||||
for visible_entity in visible_entities.iter::<With<Mesh3d>>() {
|
||||
let Some(material_asset_id) = render_material_instances.get(visible_entity) else {
|
||||
continue;
|
||||
};
|
||||
|
|
106
crates/bevy_pbr/src/mesh_material.rs
Normal file
106
crates/bevy_pbr/src/mesh_material.rs
Normal file
|
@ -0,0 +1,106 @@
|
|||
use crate::Material;
|
||||
use bevy_asset::{AssetId, Handle};
|
||||
use bevy_derive::{Deref, DerefMut};
|
||||
use bevy_ecs::{component::Component, reflect::ReflectComponent};
|
||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||
|
||||
/// A [material](Material) for a [`Mesh3d`].
|
||||
///
|
||||
/// See [`Material`] for general information about 3D materials and how to implement your own materials.
|
||||
///
|
||||
/// [`Mesh3d`]: bevy_render::mesh::Mesh3d
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_pbr::{Material, MeshMaterial3d, StandardMaterial};
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// # use bevy_render::mesh::{Mesh, Mesh3d};
|
||||
/// # use bevy_color::palettes::basic::RED;
|
||||
/// # use bevy_asset::Assets;
|
||||
/// # use bevy_math::primitives::Capsule3d;
|
||||
/// #
|
||||
/// // Spawn an entity with a mesh using `StandardMaterial`.
|
||||
/// fn setup(
|
||||
/// mut commands: Commands,
|
||||
/// mut meshes: ResMut<Assets<Mesh>>,
|
||||
/// mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
/// ) {
|
||||
/// commands.spawn((
|
||||
/// Mesh3d(meshes.add(Capsule3d::default())),
|
||||
/// MeshMaterial3d(materials.add(StandardMaterial {
|
||||
/// base_color: RED.into(),
|
||||
/// ..Default::default()
|
||||
/// })),
|
||||
/// ));
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ## Default Material
|
||||
///
|
||||
/// Meshes without a [`MeshMaterial3d`] are rendered with a default [`StandardMaterial`].
|
||||
/// This material can be overridden by inserting a custom material for the default asset handle.
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_pbr::{Material, MeshMaterial3d, StandardMaterial};
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// # use bevy_render::mesh::{Mesh, Mesh3d};
|
||||
/// # use bevy_color::Color;
|
||||
/// # use bevy_asset::{Assets, Handle};
|
||||
/// # use bevy_math::primitives::Capsule3d;
|
||||
/// #
|
||||
/// fn setup(
|
||||
/// mut commands: Commands,
|
||||
/// mut meshes: ResMut<Assets<Mesh>>,
|
||||
/// mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
/// ) {
|
||||
/// // Optional: Insert a custom default material.
|
||||
/// materials.insert(
|
||||
/// &Handle::<StandardMaterial>::default(),
|
||||
/// StandardMaterial::from(Color::srgb(1.0, 0.0, 1.0)),
|
||||
/// );
|
||||
///
|
||||
/// // Spawn a capsule with no material.
|
||||
/// // The mesh will be rendered with the default material.
|
||||
/// commands.spawn(Mesh3d(meshes.add(Capsule3d::default())));
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`StandardMaterial`]: crate::StandardMaterial
|
||||
#[derive(Component, Clone, Debug, Deref, DerefMut, Reflect, PartialEq, Eq)]
|
||||
#[reflect(Component, Default)]
|
||||
#[require(HasMaterial3d)]
|
||||
pub struct MeshMaterial3d<M: Material>(pub Handle<M>);
|
||||
|
||||
impl<M: Material> Default for MeshMaterial3d<M> {
|
||||
fn default() -> Self {
|
||||
Self(Handle::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Material> From<Handle<M>> for MeshMaterial3d<M> {
|
||||
fn from(handle: Handle<M>) -> Self {
|
||||
Self(handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Material> From<MeshMaterial3d<M>> for AssetId<M> {
|
||||
fn from(material: MeshMaterial3d<M>) -> Self {
|
||||
material.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Material> From<&MeshMaterial3d<M>> for AssetId<M> {
|
||||
fn from(material: &MeshMaterial3d<M>) -> Self {
|
||||
material.id()
|
||||
}
|
||||
}
|
||||
|
||||
/// A component that marks an entity as having a [`MeshMaterial3d`].
|
||||
/// [`Mesh3d`] entities without this component are rendered with a [default material].
|
||||
///
|
||||
/// [`Mesh3d`]: bevy_render::mesh::Mesh3d
|
||||
/// [default material]: crate::MeshMaterial3d#default-material
|
||||
#[derive(Component, Clone, Debug, Default, Reflect)]
|
||||
#[reflect(Component, Default)]
|
||||
pub struct HasMaterial3d;
|
|
@ -1,9 +1,8 @@
|
|||
mod prepass_bindings;
|
||||
|
||||
use bevy_render::{
|
||||
mesh::{MeshVertexBufferLayoutRef, RenderMesh},
|
||||
mesh::{Mesh3d, MeshVertexBufferLayoutRef, RenderMesh},
|
||||
render_resource::binding_types::uniform_buffer,
|
||||
view::WithMesh,
|
||||
world_sync::RenderEntity,
|
||||
};
|
||||
pub use prepass_bindings::*;
|
||||
|
@ -220,9 +219,9 @@ pub fn update_previous_view_data(
|
|||
pub struct PreviousGlobalTransform(pub Affine3A);
|
||||
|
||||
#[cfg(not(feature = "meshlet"))]
|
||||
type PreviousMeshFilter = With<Handle<Mesh>>;
|
||||
type PreviousMeshFilter = With<Mesh3d>;
|
||||
#[cfg(feature = "meshlet")]
|
||||
type PreviousMeshFilter = Or<(With<Handle<Mesh>>, With<Handle<MeshletMesh>>)>;
|
||||
type PreviousMeshFilter = Or<(With<Mesh3d>, With<Handle<MeshletMesh>>)>;
|
||||
|
||||
pub fn update_mesh_previous_global_transforms(
|
||||
mut commands: Commands,
|
||||
|
@ -766,7 +765,7 @@ pub fn queue_prepass_material_meshes<M: Material>(
|
|||
view_key |= MeshPipelineKey::MOTION_VECTOR_PREPASS;
|
||||
}
|
||||
|
||||
for visible_entity in visible_entities.iter::<WithMesh>() {
|
||||
for visible_entity in visible_entities.iter::<With<Mesh3d>>() {
|
||||
let Some(material_asset_id) = render_material_instances.get(visible_entity) else {
|
||||
continue;
|
||||
};
|
||||
|
|
|
@ -567,7 +567,7 @@ pub struct RenderMeshInstanceGpuQueues(Parallel<RenderMeshInstanceGpuQueue>);
|
|||
impl RenderMeshInstanceShared {
|
||||
fn from_components(
|
||||
previous_transform: Option<&PreviousGlobalTransform>,
|
||||
handle: &Handle<Mesh>,
|
||||
mesh: &Mesh3d,
|
||||
not_shadow_caster: bool,
|
||||
no_automatic_batching: bool,
|
||||
) -> Self {
|
||||
|
@ -583,8 +583,7 @@ impl RenderMeshInstanceShared {
|
|||
);
|
||||
|
||||
RenderMeshInstanceShared {
|
||||
mesh_asset_id: handle.id(),
|
||||
|
||||
mesh_asset_id: mesh.id(),
|
||||
flags: mesh_instance_flags,
|
||||
material_bind_group_id: AtomicMaterialBindGroupId::default(),
|
||||
}
|
||||
|
@ -870,7 +869,7 @@ pub fn extract_meshes_for_cpu_building(
|
|||
&ViewVisibility,
|
||||
&GlobalTransform,
|
||||
Option<&PreviousGlobalTransform>,
|
||||
&Handle<Mesh>,
|
||||
&Mesh3d,
|
||||
Has<NotShadowReceiver>,
|
||||
Has<TransmittedShadowReceiver>,
|
||||
Has<NotShadowCaster>,
|
||||
|
@ -887,7 +886,7 @@ pub fn extract_meshes_for_cpu_building(
|
|||
view_visibility,
|
||||
transform,
|
||||
previous_transform,
|
||||
handle,
|
||||
mesh,
|
||||
not_shadow_receiver,
|
||||
transmitted_receiver,
|
||||
not_shadow_caster,
|
||||
|
@ -912,7 +911,7 @@ pub fn extract_meshes_for_cpu_building(
|
|||
|
||||
let shared = RenderMeshInstanceShared::from_components(
|
||||
previous_transform,
|
||||
handle,
|
||||
mesh,
|
||||
not_shadow_caster,
|
||||
no_automatic_batching,
|
||||
);
|
||||
|
@ -969,7 +968,7 @@ pub fn extract_meshes_for_gpu_building(
|
|||
Option<&PreviousGlobalTransform>,
|
||||
Option<&Lightmap>,
|
||||
Option<&Aabb>,
|
||||
&Handle<Mesh>,
|
||||
&Mesh3d,
|
||||
Has<NotShadowReceiver>,
|
||||
Has<TransmittedShadowReceiver>,
|
||||
Has<NotShadowCaster>,
|
||||
|
@ -1003,7 +1002,7 @@ pub fn extract_meshes_for_gpu_building(
|
|||
previous_transform,
|
||||
lightmap,
|
||||
aabb,
|
||||
handle,
|
||||
mesh,
|
||||
not_shadow_receiver,
|
||||
transmitted_receiver,
|
||||
not_shadow_caster,
|
||||
|
@ -1028,7 +1027,7 @@ pub fn extract_meshes_for_gpu_building(
|
|||
|
||||
let shared = RenderMeshInstanceShared::from_components(
|
||||
previous_transform,
|
||||
handle,
|
||||
mesh,
|
||||
not_shadow_caster,
|
||||
no_automatic_batching,
|
||||
);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
use crate::{Material, MaterialPipeline, MaterialPipelineKey, MaterialPlugin};
|
||||
use crate::{Material, MaterialPipeline, MaterialPipelineKey, MaterialPlugin, MeshMaterial3d};
|
||||
use bevy_app::{Plugin, Startup, Update};
|
||||
use bevy_asset::{load_internal_asset, Asset, Assets, Handle};
|
||||
use bevy_color::{Color, LinearRgba};
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect, TypePath};
|
||||
use bevy_render::{
|
||||
extract_resource::ExtractResource, mesh::MeshVertexBufferLayoutRef, prelude::*,
|
||||
extract_resource::ExtractResource,
|
||||
mesh::{Mesh3d, MeshVertexBufferLayoutRef},
|
||||
prelude::*,
|
||||
render_resource::*,
|
||||
};
|
||||
|
||||
|
@ -129,12 +131,12 @@ fn global_color_changed(
|
|||
fn wireframe_color_changed(
|
||||
mut materials: ResMut<Assets<WireframeMaterial>>,
|
||||
mut colors_changed: Query<
|
||||
(&mut Handle<WireframeMaterial>, &WireframeColor),
|
||||
(&mut MeshMaterial3d<WireframeMaterial>, &WireframeColor),
|
||||
(With<Wireframe>, Changed<WireframeColor>),
|
||||
>,
|
||||
) {
|
||||
for (mut handle, wireframe_color) in &mut colors_changed {
|
||||
*handle = materials.add(WireframeMaterial {
|
||||
handle.0 = materials.add(WireframeMaterial {
|
||||
color: wireframe_color.color.into(),
|
||||
});
|
||||
}
|
||||
|
@ -147,27 +149,27 @@ fn apply_wireframe_material(
|
|||
mut materials: ResMut<Assets<WireframeMaterial>>,
|
||||
wireframes: Query<
|
||||
(Entity, Option<&WireframeColor>),
|
||||
(With<Wireframe>, Without<Handle<WireframeMaterial>>),
|
||||
(With<Wireframe>, Without<MeshMaterial3d<WireframeMaterial>>),
|
||||
>,
|
||||
no_wireframes: Query<Entity, (With<NoWireframe>, With<Handle<WireframeMaterial>>)>,
|
||||
no_wireframes: Query<Entity, (With<NoWireframe>, With<MeshMaterial3d<WireframeMaterial>>)>,
|
||||
mut removed_wireframes: RemovedComponents<Wireframe>,
|
||||
global_material: Res<GlobalWireframeMaterial>,
|
||||
) {
|
||||
for e in removed_wireframes.read().chain(no_wireframes.iter()) {
|
||||
if let Some(commands) = commands.get_entity(e) {
|
||||
commands.remove::<Handle<WireframeMaterial>>();
|
||||
commands.remove::<MeshMaterial3d<WireframeMaterial>>();
|
||||
}
|
||||
}
|
||||
|
||||
let mut material_to_spawn = vec![];
|
||||
for (e, maybe_color) in &wireframes {
|
||||
let material = get_wireframe_material(maybe_color, &mut materials, &global_material);
|
||||
material_to_spawn.push((e, material));
|
||||
material_to_spawn.push((e, MeshMaterial3d(material)));
|
||||
}
|
||||
commands.insert_or_spawn_batch(material_to_spawn);
|
||||
}
|
||||
|
||||
type WireframeFilter = (With<Handle<Mesh>>, Without<Wireframe>, Without<NoWireframe>);
|
||||
type WireframeFilter = (With<Mesh3d>, Without<Wireframe>, Without<NoWireframe>);
|
||||
|
||||
/// Applies or removes a wireframe material on any mesh without a [`Wireframe`] or [`NoWireframe`] component.
|
||||
fn apply_global_wireframe_material(
|
||||
|
@ -175,9 +177,12 @@ fn apply_global_wireframe_material(
|
|||
config: Res<WireframeConfig>,
|
||||
meshes_without_material: Query<
|
||||
(Entity, Option<&WireframeColor>),
|
||||
(WireframeFilter, Without<Handle<WireframeMaterial>>),
|
||||
(WireframeFilter, Without<MeshMaterial3d<WireframeMaterial>>),
|
||||
>,
|
||||
meshes_with_global_material: Query<
|
||||
Entity,
|
||||
(WireframeFilter, With<MeshMaterial3d<WireframeMaterial>>),
|
||||
>,
|
||||
meshes_with_global_material: Query<Entity, (WireframeFilter, With<Handle<WireframeMaterial>>)>,
|
||||
global_material: Res<GlobalWireframeMaterial>,
|
||||
mut materials: ResMut<Assets<WireframeMaterial>>,
|
||||
) {
|
||||
|
@ -187,12 +192,14 @@ fn apply_global_wireframe_material(
|
|||
let material = get_wireframe_material(maybe_color, &mut materials, &global_material);
|
||||
// We only add the material handle but not the Wireframe component
|
||||
// This makes it easy to detect which mesh is using the global material and which ones are user specified
|
||||
material_to_spawn.push((e, material));
|
||||
material_to_spawn.push((e, MeshMaterial3d(material)));
|
||||
}
|
||||
commands.insert_or_spawn_batch(material_to_spawn);
|
||||
} else {
|
||||
for e in &meshes_with_global_material {
|
||||
commands.entity(e).remove::<Handle<WireframeMaterial>>();
|
||||
commands
|
||||
.entity(e)
|
||||
.remove::<MeshMaterial3d<WireframeMaterial>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,10 @@ pub mod prelude {
|
|||
Camera, ClearColor, ClearColorConfig, OrthographicProjection, PerspectiveProjection,
|
||||
Projection,
|
||||
},
|
||||
mesh::{morph::MorphWeights, primitives::MeshBuilder, primitives::Meshable, Mesh},
|
||||
mesh::{
|
||||
morph::MorphWeights, primitives::MeshBuilder, primitives::Meshable, Mesh, Mesh2d,
|
||||
Mesh3d,
|
||||
},
|
||||
render_resource::Shader,
|
||||
spatial_bundle::SpatialBundle,
|
||||
texture::{image_texture_conversion::IntoDynamicImageError, Image, ImagePlugin},
|
||||
|
|
115
crates/bevy_render/src/mesh/components.rs
Normal file
115
crates/bevy_render/src/mesh/components.rs
Normal file
|
@ -0,0 +1,115 @@
|
|||
use crate::{mesh::Mesh, view::Visibility};
|
||||
use bevy_asset::{AssetId, Handle};
|
||||
use bevy_derive::{Deref, DerefMut};
|
||||
use bevy_ecs::{component::Component, reflect::ReflectComponent};
|
||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||
use bevy_transform::components::Transform;
|
||||
|
||||
/// A component for rendering 2D meshes, typically with a [`MeshMaterial2d`] using a [`ColorMaterial`].
|
||||
///
|
||||
/// Meshes without a [`MeshMaterial2d`] will be rendered with a [default material].
|
||||
///
|
||||
/// [`MeshMaterial2d`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.MeshMaterial2d.html>
|
||||
/// [`ColorMaterial`]: <https://docs.rs/bevy/latest/bevy/sprite/struct.ColorMaterial.html>
|
||||
/// [default material]: <https://docs.rs/bevy/latest/bevy/sprite/struct.MeshMaterial2d.html#default-material>
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// # use bevy_sprite::{ColorMaterial, Mesh2d, MeshMaterial2d};
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// # use bevy_render::mesh::Mesh;
|
||||
/// # use bevy_color::palettes::basic::RED;
|
||||
/// # use bevy_asset::Assets;
|
||||
/// # use bevy_math::primitives::Circle;
|
||||
/// #
|
||||
/// // Spawn an entity with a mesh using `ColorMaterial`.
|
||||
/// fn setup(
|
||||
/// mut commands: Commands,
|
||||
/// mut meshes: ResMut<Assets<Mesh>>,
|
||||
/// mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
/// ) {
|
||||
/// commands.spawn((
|
||||
/// Mesh2d(meshes.add(Circle::new(50.0))),
|
||||
/// MeshMaterial2d(materials.add(ColorMaterial::from_color(RED))),
|
||||
/// ));
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq)]
|
||||
#[reflect(Component, Default)]
|
||||
#[require(Transform, Visibility)]
|
||||
pub struct Mesh2d(pub Handle<Mesh>);
|
||||
|
||||
impl From<Handle<Mesh>> for Mesh2d {
|
||||
fn from(handle: Handle<Mesh>) -> Self {
|
||||
Self(handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Mesh2d> for AssetId<Mesh> {
|
||||
fn from(mesh: Mesh2d) -> Self {
|
||||
mesh.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Mesh2d> for AssetId<Mesh> {
|
||||
fn from(mesh: &Mesh2d) -> Self {
|
||||
mesh.id()
|
||||
}
|
||||
}
|
||||
|
||||
/// A component for rendering 3D meshes, typically with a [`MeshMaterial3d`] using a [`StandardMaterial`].
|
||||
///
|
||||
/// Meshes without a [`MeshMaterial3d`] will be rendered with a [default material].
|
||||
///
|
||||
/// [`MeshMaterial3d`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.MeshMaterial3d.html>
|
||||
/// [`StandardMaterial`]: <https://docs.rs/bevy/latest/bevy/pbr/struct.StandardMaterial.html>
|
||||
/// [default material]: <https://docs.rs/bevy/latest/bevy/pbr/struct.MeshMaterial3d.html#default-material>
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// # use bevy_pbr::{Material, MeshMaterial3d, StandardMaterial};
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// # use bevy_render::mesh::{Mesh, Mesh3d};
|
||||
/// # use bevy_color::palettes::basic::RED;
|
||||
/// # use bevy_asset::Assets;
|
||||
/// # use bevy_math::primitives::Capsule3d;
|
||||
/// #
|
||||
/// // Spawn an entity with a mesh using `StandardMaterial`.
|
||||
/// fn setup(
|
||||
/// mut commands: Commands,
|
||||
/// mut meshes: ResMut<Assets<Mesh>>,
|
||||
/// mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
/// ) {
|
||||
/// commands.spawn((
|
||||
/// Mesh3d(meshes.add(Capsule3d::default())),
|
||||
/// MeshMaterial3d(materials.add(StandardMaterial {
|
||||
/// base_color: RED.into(),
|
||||
/// ..Default::default()
|
||||
/// })),
|
||||
/// ));
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Component, Clone, Debug, Default, Deref, DerefMut, Reflect, PartialEq, Eq)]
|
||||
#[reflect(Component, Default)]
|
||||
#[require(Transform, Visibility)]
|
||||
pub struct Mesh3d(pub Handle<Mesh>);
|
||||
|
||||
impl From<Handle<Mesh>> for Mesh3d {
|
||||
fn from(handle: Handle<Mesh>) -> Self {
|
||||
Self(handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Mesh3d> for AssetId<Mesh> {
|
||||
fn from(mesh: Mesh3d) -> Self {
|
||||
mesh.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Mesh3d> for AssetId<Mesh> {
|
||||
fn from(mesh: &Mesh3d) -> Self {
|
||||
mesh.id()
|
||||
}
|
||||
}
|
|
@ -36,11 +36,10 @@ pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
|
|||
///
|
||||
/// Meshes can be automatically generated by a bevy `AssetLoader` (generally by loading a `Gltf` file),
|
||||
/// or by converting a [primitive](bevy_math::primitives) using [`into`](Into).
|
||||
/// It is also possible to create one manually.
|
||||
/// They can be edited after creation.
|
||||
/// It is also possible to create one manually. They can be edited after creation.
|
||||
///
|
||||
/// Meshes can be rendered with a `Material`, like `StandardMaterial` in `PbrBundle`
|
||||
/// or `ColorMaterial` in `ColorMesh2dBundle`.
|
||||
/// Meshes can be rendered with a [`Mesh2d`](super::Mesh2d) and `MeshMaterial2d`
|
||||
/// or [`Mesh3d`](super::Mesh3d) and `MeshMaterial3d` for 2D and 3D respectively.
|
||||
///
|
||||
/// A [`Mesh`] in Bevy is equivalent to a "primitive" in the glTF format, for a
|
||||
/// glTF Mesh representation, see `GltfMesh`.
|
||||
|
@ -49,6 +48,7 @@ pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
|
|||
///
|
||||
/// The following function will construct a flat mesh, to be rendered with a
|
||||
/// `StandardMaterial` or `ColorMaterial`:
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_render::mesh::{Mesh, Indices};
|
||||
/// # use bevy_render::render_resource::PrimitiveTopology;
|
||||
|
@ -84,7 +84,7 @@ pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
|
|||
/// ```
|
||||
///
|
||||
/// You can see how it looks like [here](https://github.com/bevyengine/bevy/blob/main/assets/docs/Mesh.png),
|
||||
/// used in a `PbrBundle` with a square bevy logo texture, with added axis, points,
|
||||
/// used in a `Mesh3d` with a square bevy logo texture, with added axis, points,
|
||||
/// lines and text for clarity.
|
||||
///
|
||||
/// ## Other examples
|
||||
|
@ -92,7 +92,7 @@ pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
|
|||
/// For further visualization, explanation, and examples, see the built-in Bevy examples,
|
||||
/// and the [implementation of the built-in shapes](https://github.com/bevyengine/bevy/tree/main/crates/bevy_render/src/mesh/primitives).
|
||||
/// In particular, [generate_custom_mesh](https://github.com/bevyengine/bevy/blob/main/examples/3d/generate_custom_mesh.rs)
|
||||
/// teaches you to access modify a Mesh's attributes after creating it.
|
||||
/// teaches you to access and modify the attributes of a [`Mesh`] after creating it.
|
||||
///
|
||||
/// ## Common points of confusion
|
||||
///
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
mod mesh;
|
||||
|
||||
pub mod allocator;
|
||||
mod components;
|
||||
pub mod morph;
|
||||
pub mod primitives;
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use allocator::MeshAllocatorPlugin;
|
||||
use bevy_utils::HashSet;
|
||||
pub use components::{Mesh2d, Mesh3d};
|
||||
use core::hash::{Hash, Hasher};
|
||||
pub use mesh::*;
|
||||
pub use primitives::*;
|
||||
|
@ -25,6 +27,7 @@ impl Plugin for MeshPlugin {
|
|||
app.init_asset::<Mesh>()
|
||||
.init_asset::<skinning::SkinnedMeshInverseBindposes>()
|
||||
.register_asset_reflect::<Mesh>()
|
||||
.register_type::<Mesh3d>()
|
||||
.register_type::<skinning::SkinnedMesh>()
|
||||
.register_type::<Vec<Entity>>()
|
||||
// 'Mesh' must be prepared after 'Image' as meshes rely on the morph target image being ready
|
||||
|
|
|
@ -14,6 +14,8 @@ use bytemuck::{Pod, Zeroable};
|
|||
use core::iter;
|
||||
use thiserror::Error;
|
||||
|
||||
use super::Mesh3d;
|
||||
|
||||
const MAX_TEXTURE_WIDTH: u32 = 2048;
|
||||
// NOTE: "component" refers to the element count of math objects,
|
||||
// Vec3 has 3 components, Mat2 has 4 components.
|
||||
|
@ -114,7 +116,7 @@ impl MorphTargetImage {
|
|||
}
|
||||
}
|
||||
|
||||
/// Controls the [morph targets] for all child [`Handle<Mesh>`] entities. In most cases, [`MorphWeights`] should be considered
|
||||
/// Controls the [morph targets] for all child [`Mesh3d`] entities. In most cases, [`MorphWeights`] should be considered
|
||||
/// the "source of truth" when writing morph targets for meshes. However you can choose to write child [`MeshMorphWeights`]
|
||||
/// if your situation requires more granularity. Just note that if you set [`MorphWeights`], it will overwrite child
|
||||
/// [`MeshMorphWeights`] values.
|
||||
|
@ -122,9 +124,9 @@ impl MorphTargetImage {
|
|||
/// This exists because Bevy's [`Mesh`] corresponds to a _single_ surface / material, whereas morph targets
|
||||
/// as defined in the GLTF spec exist on "multi-primitive meshes" (where each primitive is its own surface with its own material).
|
||||
/// Therefore in Bevy [`MorphWeights`] an a parent entity are the "canonical weights" from a GLTF perspective, which then
|
||||
/// synchronized to child [`Handle<Mesh>`] / [`MeshMorphWeights`] (which correspond to "primitives" / "surfaces" from a GLTF perspective).
|
||||
/// synchronized to child [`Mesh3d`] / [`MeshMorphWeights`] (which correspond to "primitives" / "surfaces" from a GLTF perspective).
|
||||
///
|
||||
/// Add this to the parent of one or more [`Entities`](`Entity`) with a [`Handle<Mesh>`] with a [`MeshMorphWeights`].
|
||||
/// Add this to the parent of one or more [`Entities`](`Entity`) with a [`Mesh3d`] with a [`MeshMorphWeights`].
|
||||
///
|
||||
/// [morph targets]: https://en.wikipedia.org/wiki/Morph_target_animation
|
||||
#[derive(Reflect, Default, Debug, Clone, Component)]
|
||||
|
@ -148,7 +150,7 @@ impl MorphWeights {
|
|||
first_mesh,
|
||||
})
|
||||
}
|
||||
/// The first child [`Handle<Mesh>`] primitive controlled by these weights.
|
||||
/// The first child [`Mesh3d`] primitive controlled by these weights.
|
||||
/// This can be used to look up metadata information such as [`Mesh::morph_target_names`].
|
||||
pub fn first_mesh(&self) -> Option<&Handle<Mesh>> {
|
||||
self.first_mesh.as_ref()
|
||||
|
@ -168,7 +170,7 @@ impl MorphWeights {
|
|||
///
|
||||
/// See [`MorphWeights`] for more details on Bevy's morph target implementation.
|
||||
///
|
||||
/// Add this to an [`Entity`] with a [`Handle<Mesh>`] with a [`MorphAttributes`] set
|
||||
/// Add this to an [`Entity`] with a [`Mesh3d`] with a [`MorphAttributes`] set
|
||||
/// to control individual weights of each morph target.
|
||||
///
|
||||
/// [morph targets]: https://en.wikipedia.org/wiki/Morph_target_animation
|
||||
|
@ -198,8 +200,8 @@ impl MeshMorphWeights {
|
|||
///
|
||||
/// Only direct children are updated, to fulfill the expectations of glTF spec.
|
||||
pub fn inherit_weights(
|
||||
morph_nodes: Query<(&Children, &MorphWeights), (Without<Handle<Mesh>>, Changed<MorphWeights>)>,
|
||||
mut morph_primitives: Query<&mut MeshMorphWeights, With<Handle<Mesh>>>,
|
||||
morph_nodes: Query<(&Children, &MorphWeights), (Without<Mesh3d>, Changed<MorphWeights>)>,
|
||||
mut morph_primitives: Query<&mut MeshMorphWeights, With<Mesh3d>>,
|
||||
) {
|
||||
for (children, parent_weights) in &morph_nodes {
|
||||
let mut iter = morph_primitives.iter_many_mut(children);
|
||||
|
|
|
@ -17,19 +17,17 @@ use bevy_reflect::prelude::*;
|
|||
/// with the camera's [`Frustum`].
|
||||
///
|
||||
/// It will be added automatically by the systems in [`CalculateBounds`] to entities that:
|
||||
/// - could be subject to frustum culling, for example with a [`Handle<Mesh>`]
|
||||
/// - could be subject to frustum culling, for example with a [`Mesh3d`]
|
||||
/// or `Sprite` component,
|
||||
/// - don't have the [`NoFrustumCulling`] component.
|
||||
///
|
||||
/// It won't be updated automatically if the space occupied by the entity changes,
|
||||
/// for example if the vertex positions of a [`Mesh`] inside a `Handle<Mesh>` are
|
||||
/// updated.
|
||||
/// for example if the vertex positions of a [`Mesh3d`] are updated.
|
||||
///
|
||||
/// [`Camera`]: crate::camera::Camera
|
||||
/// [`NoFrustumCulling`]: crate::view::visibility::NoFrustumCulling
|
||||
/// [`CalculateBounds`]: crate::view::visibility::VisibilitySystems::CalculateBounds
|
||||
/// [`Mesh`]: crate::mesh::Mesh
|
||||
/// [`Handle<Mesh>`]: crate::mesh::Mesh
|
||||
/// [`Mesh3d`]: crate::mesh::Mesh
|
||||
#[derive(Component, Clone, Copy, Debug, Default, Reflect, PartialEq)]
|
||||
#[reflect(Component, Default, Debug, PartialEq)]
|
||||
pub struct Aabb {
|
||||
|
|
|
@ -9,7 +9,7 @@ pub use range::*;
|
|||
pub use render_layers::*;
|
||||
|
||||
use bevy_app::{Plugin, PostUpdate};
|
||||
use bevy_asset::{Assets, Handle};
|
||||
use bevy_asset::Assets;
|
||||
use bevy_derive::Deref;
|
||||
use bevy_ecs::{prelude::*, query::QueryFilter};
|
||||
use bevy_hierarchy::{Children, Parent};
|
||||
|
@ -19,7 +19,7 @@ use bevy_utils::{Parallel, TypeIdMap};
|
|||
|
||||
use crate::{
|
||||
camera::{Camera, CameraProjection},
|
||||
mesh::Mesh,
|
||||
mesh::{Mesh, Mesh3d},
|
||||
primitives::{Aabb, Frustum, Sphere},
|
||||
};
|
||||
|
||||
|
@ -271,10 +271,6 @@ impl VisibleEntities {
|
|||
}
|
||||
}
|
||||
|
||||
/// A convenient alias for `With<Handle<Mesh>>`, for use with
|
||||
/// [`VisibleEntities`].
|
||||
pub type WithMesh = With<Handle<Mesh>>;
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
|
||||
pub enum VisibilitySystems {
|
||||
/// Label for the [`calculate_bounds`], `calculate_bounds_2d` and `calculate_bounds_text2d` systems,
|
||||
|
@ -312,20 +308,20 @@ impl Plugin for VisibilityPlugin {
|
|||
(
|
||||
calculate_bounds.in_set(CalculateBounds),
|
||||
(visibility_propagate_system, reset_view_visibility).in_set(VisibilityPropagate),
|
||||
check_visibility::<WithMesh>.in_set(CheckVisibility),
|
||||
check_visibility::<With<Mesh3d>>.in_set(CheckVisibility),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes and adds an [`Aabb`] component to entities with a
|
||||
/// [`Handle<Mesh>`](Mesh) component and without a [`NoFrustumCulling`] component.
|
||||
/// [`Mesh3d`] component and without a [`NoFrustumCulling`] component.
|
||||
///
|
||||
/// This system is used in system set [`VisibilitySystems::CalculateBounds`].
|
||||
pub fn calculate_bounds(
|
||||
mut commands: Commands,
|
||||
meshes: Res<Assets<Mesh>>,
|
||||
without_aabb: Query<(Entity, &Handle<Mesh>), (Without<Aabb>, Without<NoFrustumCulling>)>,
|
||||
without_aabb: Query<(Entity, &Mesh3d), (Without<Aabb>, Without<NoFrustumCulling>)>,
|
||||
) {
|
||||
for (entity, mesh_handle) in &without_aabb {
|
||||
if let Some(mesh) = meshes.get(mesh_handle) {
|
||||
|
|
|
@ -24,13 +24,14 @@ use wgpu::{BufferBindingType, BufferUsages};
|
|||
|
||||
use crate::{
|
||||
camera::Camera,
|
||||
mesh::Mesh3d,
|
||||
primitives::Aabb,
|
||||
render_resource::BufferVec,
|
||||
renderer::{RenderDevice, RenderQueue},
|
||||
Extract, ExtractSchedule, Render, RenderApp, RenderSet,
|
||||
};
|
||||
|
||||
use super::{check_visibility, VisibilitySystems, WithMesh};
|
||||
use super::{check_visibility, VisibilitySystems};
|
||||
|
||||
/// We need at least 4 storage buffer bindings available to enable the
|
||||
/// visibility range buffer.
|
||||
|
@ -57,7 +58,7 @@ impl Plugin for VisibilityRangePlugin {
|
|||
PostUpdate,
|
||||
check_visibility_ranges
|
||||
.in_set(VisibilitySystems::CheckVisibility)
|
||||
.before(check_visibility::<WithMesh>),
|
||||
.before(check_visibility::<With<Mesh3d>>),
|
||||
);
|
||||
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
|
|
|
@ -25,6 +25,7 @@ mod texture_slice;
|
|||
/// The sprite prelude.
|
||||
///
|
||||
/// This includes the most common types in this crate, re-exported for your convenience.
|
||||
#[expect(deprecated)]
|
||||
pub mod prelude {
|
||||
#[doc(hidden)]
|
||||
pub use crate::{
|
||||
|
@ -32,7 +33,7 @@ pub mod prelude {
|
|||
sprite::{ImageScaleMode, Sprite},
|
||||
texture_atlas::{TextureAtlas, TextureAtlasLayout, TextureAtlasSources},
|
||||
texture_slice::{BorderRect, SliceScaleMode, TextureSlice, TextureSlicer},
|
||||
ColorMaterial, ColorMesh2dBundle, TextureAtlasBuilder,
|
||||
ColorMaterial, ColorMesh2dBundle, MeshMaterial2d, TextureAtlasBuilder,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -52,7 +53,7 @@ use bevy_core_pipeline::core_2d::Transparent2d;
|
|||
use bevy_ecs::{prelude::*, query::QueryItem};
|
||||
use bevy_render::{
|
||||
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
||||
mesh::Mesh,
|
||||
mesh::{Mesh, Mesh2d},
|
||||
primitives::Aabb,
|
||||
render_phase::AddRenderCommand,
|
||||
render_resource::{Shader, SpecializedRenderPipelines},
|
||||
|
@ -84,10 +85,6 @@ pub enum SpriteSystem {
|
|||
#[reflect(Component, Default, Debug)]
|
||||
pub struct SpriteSource;
|
||||
|
||||
/// A convenient alias for `With<Mesh2dHandle>>`, for use with
|
||||
/// [`bevy_render::view::VisibleEntities`].
|
||||
pub type WithMesh2d = With<Mesh2dHandle>;
|
||||
|
||||
/// A convenient alias for `Or<With<Sprite>, With<SpriteSource>>`, for use with
|
||||
/// [`bevy_render::view::VisibleEntities`].
|
||||
pub type WithSprite = Or<(With<Sprite>, With<SpriteSource>)>;
|
||||
|
@ -113,7 +110,7 @@ impl Plugin for SpritePlugin {
|
|||
.register_type::<TextureSlicer>()
|
||||
.register_type::<Anchor>()
|
||||
.register_type::<TextureAtlas>()
|
||||
.register_type::<Mesh2dHandle>()
|
||||
.register_type::<Mesh2d>()
|
||||
.register_type::<SpriteSource>()
|
||||
.add_plugins((
|
||||
Mesh2dRenderPlugin,
|
||||
|
@ -130,7 +127,7 @@ impl Plugin for SpritePlugin {
|
|||
)
|
||||
.in_set(SpriteSystem::ComputeSlices),
|
||||
(
|
||||
check_visibility::<WithMesh2d>,
|
||||
check_visibility::<With<Mesh2d>>,
|
||||
check_visibility::<WithSprite>,
|
||||
)
|
||||
.in_set(VisibilitySystems::CheckVisibility),
|
||||
|
@ -176,7 +173,7 @@ impl Plugin for SpritePlugin {
|
|||
}
|
||||
|
||||
/// System calculating and inserting an [`Aabb`] component to entities with either:
|
||||
/// - a `Mesh2dHandle` component,
|
||||
/// - a `Mesh2d` component,
|
||||
/// - a `Sprite` and `Handle<Image>` components,
|
||||
/// and without a [`NoFrustumCulling`] component.
|
||||
///
|
||||
|
@ -186,7 +183,7 @@ pub fn calculate_bounds_2d(
|
|||
meshes: Res<Assets<Mesh>>,
|
||||
images: Res<Assets<Image>>,
|
||||
atlases: Res<Assets<TextureAtlasLayout>>,
|
||||
meshes_without_aabb: Query<(Entity, &Mesh2dHandle), (Without<Aabb>, Without<NoFrustumCulling>)>,
|
||||
meshes_without_aabb: Query<(Entity, &Mesh2d), (Without<Aabb>, Without<NoFrustumCulling>)>,
|
||||
sprites_to_recalculate_aabb: Query<
|
||||
(Entity, &Sprite, &Handle<Image>, Option<&TextureAtlas>),
|
||||
(
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
use crate::{AlphaMode2d, Material2d, Material2dPlugin, MaterialMesh2dBundle};
|
||||
#![expect(deprecated)]
|
||||
|
||||
use crate::{
|
||||
clear_material_2d_instances, extract_default_materials_2d, AlphaMode2d, Material2d,
|
||||
Material2dPlugin, MaterialMesh2dBundle,
|
||||
};
|
||||
use bevy_app::{App, Plugin};
|
||||
use bevy_asset::{load_internal_asset, Asset, AssetApp, Assets, Handle};
|
||||
use bevy_color::{Alpha, Color, ColorToComponents, LinearRgba};
|
||||
use bevy_ecs::schedule::IntoSystemConfigs;
|
||||
use bevy_math::Vec4;
|
||||
use bevy_reflect::prelude::*;
|
||||
use bevy_render::{
|
||||
render_asset::RenderAssets,
|
||||
render_resource::*,
|
||||
texture::{GpuImage, Image},
|
||||
ExtractSchedule, RenderApp,
|
||||
};
|
||||
|
||||
pub const COLOR_MATERIAL_SHADER_HANDLE: Handle<Shader> =
|
||||
|
@ -28,19 +35,30 @@ impl Plugin for ColorMaterialPlugin {
|
|||
app.add_plugins(Material2dPlugin::<ColorMaterial>::default())
|
||||
.register_asset_reflect::<ColorMaterial>();
|
||||
|
||||
// Initialize the default material.
|
||||
app.world_mut()
|
||||
.resource_mut::<Assets<ColorMaterial>>()
|
||||
.insert(
|
||||
&Handle::<ColorMaterial>::default(),
|
||||
ColorMaterial {
|
||||
color: Color::srgb(1.0, 0.0, 1.0),
|
||||
color: Color::WHITE,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Extract default materials for entities with no material.
|
||||
render_app.add_systems(
|
||||
ExtractSchedule,
|
||||
extract_default_materials_2d.after(clear_material_2d_instances::<ColorMaterial>),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A [2d material](Material2d) that renders [2d meshes](crate::Mesh2dHandle) with a texture tinted by a uniform color
|
||||
/// A [2d material](Material2d) that renders [2d meshes](crate::Mesh2d) with a texture tinted by a uniform color
|
||||
#[derive(Asset, AsBindGroup, Reflect, Debug, Clone)]
|
||||
#[reflect(Default, Debug)]
|
||||
#[uniform(0, ColorMaterialUniform)]
|
||||
|
@ -158,5 +176,9 @@ impl Material2d for ColorMaterial {
|
|||
}
|
||||
}
|
||||
|
||||
/// A component bundle for entities with a [`Mesh2dHandle`](crate::Mesh2dHandle) and a [`ColorMaterial`].
|
||||
/// A component bundle for entities with a [`Mesh2d`](crate::Mesh2d) and a [`ColorMaterial`].
|
||||
#[deprecated(
|
||||
since = "0.15.0",
|
||||
note = "Use the `Mesh3d` and `MeshMaterial3d` components instead. Inserting them will now also insert the other components required by them automatically."
|
||||
)]
|
||||
pub type ColorMesh2dBundle = MaterialMesh2dBundle<ColorMaterial>;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![expect(deprecated)]
|
||||
|
||||
use bevy_app::{App, Plugin};
|
||||
use bevy_asset::{Asset, AssetApp, AssetId, AssetServer, Handle};
|
||||
use bevy_core_pipeline::{
|
||||
|
@ -36,29 +38,34 @@ use bevy_utils::tracing::error;
|
|||
use core::{hash::Hash, marker::PhantomData};
|
||||
|
||||
use crate::{
|
||||
DrawMesh2d, Mesh2dHandle, Mesh2dPipeline, Mesh2dPipelineKey, RenderMesh2dInstances,
|
||||
SetMesh2dBindGroup, SetMesh2dViewBindGroup, WithMesh2d,
|
||||
DrawMesh2d, Mesh2d, Mesh2dPipeline, Mesh2dPipelineKey, RenderMesh2dInstances,
|
||||
SetMesh2dBindGroup, SetMesh2dViewBindGroup,
|
||||
};
|
||||
|
||||
/// Materials are used alongside [`Material2dPlugin`] and [`MaterialMesh2dBundle`]
|
||||
use super::ColorMaterial;
|
||||
|
||||
/// Materials are used alongside [`Material2dPlugin`], [`Mesh2d`], and [`MeshMaterial2d`]
|
||||
/// to spawn entities that are rendered with a specific [`Material2d`] type. They serve as an easy to use high level
|
||||
/// way to render [`Mesh2dHandle`] entities with custom shader logic.
|
||||
/// way to render [`Mesh2d`] entities with custom shader logic.
|
||||
///
|
||||
/// Material2ds must implement [`AsBindGroup`] to define how data will be transferred to the GPU and bound in shaders.
|
||||
/// Materials must implement [`AsBindGroup`] to define how data will be transferred to the GPU and bound in shaders.
|
||||
/// [`AsBindGroup`] can be derived, which makes generating bindings straightforward. See the [`AsBindGroup`] docs for details.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Here is a simple Material2d implementation. The [`AsBindGroup`] derive has many features. To see what else is available,
|
||||
/// Here is a simple [`Material2d`] implementation. The [`AsBindGroup`] derive has many features. To see what else is available,
|
||||
/// check out the [`AsBindGroup`] documentation.
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_sprite::{Material2d, MaterialMesh2dBundle};
|
||||
/// # use bevy_sprite::{Material2d, MeshMaterial2d};
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// # use bevy_reflect::TypePath;
|
||||
/// # use bevy_render::{render_resource::{AsBindGroup, ShaderRef}, texture::Image};
|
||||
/// # use bevy_render::{mesh::{Mesh, Mesh2d}, render_resource::{AsBindGroup, ShaderRef}, texture::Image};
|
||||
/// # use bevy_color::LinearRgba;
|
||||
/// # use bevy_color::palettes::basic::RED;
|
||||
/// # use bevy_asset::{Handle, AssetServer, Assets, Asset};
|
||||
///
|
||||
/// # use bevy_math::primitives::Circle;
|
||||
/// #
|
||||
/// #[derive(AsBindGroup, Debug, Clone, Asset, TypePath)]
|
||||
/// pub struct CustomMaterial {
|
||||
/// // Uniform bindings must implement `ShaderType`, which will be used to convert the value to
|
||||
|
@ -80,17 +87,23 @@ use crate::{
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // Spawn an entity using `CustomMaterial`.
|
||||
/// fn setup(mut commands: Commands, mut materials: ResMut<Assets<CustomMaterial>>, asset_server: Res<AssetServer>) {
|
||||
/// commands.spawn(MaterialMesh2dBundle {
|
||||
/// material: materials.add(CustomMaterial {
|
||||
/// color: LinearRgba::RED,
|
||||
/// // Spawn an entity with a mesh using `CustomMaterial`.
|
||||
/// fn setup(
|
||||
/// mut commands: Commands,
|
||||
/// mut meshes: ResMut<Assets<Mesh>>,
|
||||
/// mut materials: ResMut<Assets<CustomMaterial>>,
|
||||
/// asset_server: Res<AssetServer>,
|
||||
/// ) {
|
||||
/// commands.spawn((
|
||||
/// Mesh2d(meshes.add(Circle::new(50.0))),
|
||||
/// MeshMaterial2d(materials.add(CustomMaterial {
|
||||
/// color: RED.into(),
|
||||
/// color_texture: asset_server.load("some_image.png"),
|
||||
/// }),
|
||||
/// ..Default::default()
|
||||
/// });
|
||||
/// })),
|
||||
/// ));
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// In WGSL shaders, the material's binding would look like this:
|
||||
///
|
||||
/// ```wgsl
|
||||
|
@ -137,8 +150,104 @@ pub trait Material2d: AsBindGroup + Asset + Clone + Sized {
|
|||
}
|
||||
}
|
||||
|
||||
/// A [material](Material2d) for a [`Mesh2d`].
|
||||
///
|
||||
/// See [`Material2d`] for general information about 2D materials and how to implement your own materials.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_sprite::{ColorMaterial, MeshMaterial2d};
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// # use bevy_render::mesh::{Mesh, Mesh2d};
|
||||
/// # use bevy_color::palettes::basic::RED;
|
||||
/// # use bevy_asset::Assets;
|
||||
/// # use bevy_math::primitives::Circle;
|
||||
/// #
|
||||
/// // Spawn an entity with a mesh using `ColorMaterial`.
|
||||
/// fn setup(
|
||||
/// mut commands: Commands,
|
||||
/// mut meshes: ResMut<Assets<Mesh>>,
|
||||
/// mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
/// ) {
|
||||
/// commands.spawn((
|
||||
/// Mesh2d(meshes.add(Circle::new(50.0))),
|
||||
/// MeshMaterial2d(materials.add(ColorMaterial::from_color(RED))),
|
||||
/// ));
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`MeshMaterial2d`]: crate::MeshMaterial2d
|
||||
/// [`ColorMaterial`]: crate::ColorMaterial
|
||||
///
|
||||
/// ## Default Material
|
||||
///
|
||||
/// Meshes without a [`MeshMaterial2d`] are rendered with a default [`ColorMaterial`].
|
||||
/// This material can be overridden by inserting a custom material for the default asset handle.
|
||||
///
|
||||
/// ```
|
||||
/// # use bevy_sprite::ColorMaterial;
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// # use bevy_render::mesh::{Mesh, Mesh2d};
|
||||
/// # use bevy_color::Color;
|
||||
/// # use bevy_asset::{Assets, Handle};
|
||||
/// # use bevy_math::primitives::Circle;
|
||||
/// #
|
||||
/// fn setup(
|
||||
/// mut commands: Commands,
|
||||
/// mut meshes: ResMut<Assets<Mesh>>,
|
||||
/// mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
/// ) {
|
||||
/// // Optional: Insert a custom default material.
|
||||
/// materials.insert(
|
||||
/// &Handle::<ColorMaterial>::default(),
|
||||
/// ColorMaterial::from(Color::srgb(1.0, 0.0, 1.0)),
|
||||
/// );
|
||||
///
|
||||
/// // Spawn a circle with no material.
|
||||
/// // The mesh will be rendered with the default material.
|
||||
/// commands.spawn(Mesh2d(meshes.add(Circle::new(50.0))));
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Component, Clone, Debug, Deref, DerefMut, Reflect, PartialEq, Eq)]
|
||||
#[reflect(Component, Default)]
|
||||
#[require(HasMaterial2d)]
|
||||
pub struct MeshMaterial2d<M: Material2d>(pub Handle<M>);
|
||||
|
||||
impl<M: Material2d> Default for MeshMaterial2d<M> {
|
||||
fn default() -> Self {
|
||||
Self(Handle::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Material2d> From<Handle<M>> for MeshMaterial2d<M> {
|
||||
fn from(handle: Handle<M>) -> Self {
|
||||
Self(handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Material2d> From<MeshMaterial2d<M>> for AssetId<M> {
|
||||
fn from(material: MeshMaterial2d<M>) -> Self {
|
||||
material.id()
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: Material2d> From<&MeshMaterial2d<M>> for AssetId<M> {
|
||||
fn from(material: &MeshMaterial2d<M>) -> Self {
|
||||
material.id()
|
||||
}
|
||||
}
|
||||
|
||||
/// A component that marks an entity as having a [`MeshMaterial2d`].
|
||||
/// [`Mesh2d`] entities without this component are rendered with a [default material].
|
||||
///
|
||||
/// [default material]: crate::MeshMaterial2d#default-material
|
||||
#[derive(Component, Clone, Debug, Default, Reflect)]
|
||||
#[reflect(Component, Default)]
|
||||
pub struct HasMaterial2d;
|
||||
|
||||
/// Sets how a 2d material's base color alpha channel is used for transparency.
|
||||
/// Currently, this only works with [`Mesh2d`](crate::mesh2d::Mesh2d). Sprites are always transparent.
|
||||
/// Currently, this only works with [`Mesh2d`]. Sprites are always transparent.
|
||||
///
|
||||
/// This is very similar to [`AlphaMode`](bevy_render::alpha::AlphaMode) but this only applies to 2d meshes.
|
||||
/// We use a separate type because 2d doesn't support all the transparency modes that 3d does.
|
||||
|
@ -179,6 +288,8 @@ where
|
|||
{
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_asset::<M>()
|
||||
.register_type::<MeshMaterial2d<M>>()
|
||||
.register_type::<HasMaterial2d>()
|
||||
.add_plugins(RenderAssetPlugin::<PreparedMaterial2d<M>>::default());
|
||||
|
||||
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
|
@ -188,7 +299,14 @@ where
|
|||
.add_render_command::<Transparent2d, DrawMaterial2d<M>>()
|
||||
.init_resource::<RenderMaterial2dInstances<M>>()
|
||||
.init_resource::<SpecializedMeshPipelines<Material2dPipeline<M>>>()
|
||||
.add_systems(ExtractSchedule, extract_material_meshes_2d::<M>)
|
||||
.add_systems(
|
||||
ExtractSchedule,
|
||||
(
|
||||
clear_material_2d_instances::<M>,
|
||||
extract_mesh_materials_2d::<M>,
|
||||
)
|
||||
.chain(),
|
||||
)
|
||||
.add_systems(
|
||||
Render,
|
||||
queue_material2d_meshes::<M>
|
||||
|
@ -214,14 +332,33 @@ impl<M: Material2d> Default for RenderMaterial2dInstances<M> {
|
|||
}
|
||||
}
|
||||
|
||||
fn extract_material_meshes_2d<M: Material2d>(
|
||||
pub(crate) fn clear_material_2d_instances<M: Material2d>(
|
||||
mut material_instances: ResMut<RenderMaterial2dInstances<M>>,
|
||||
query: Extract<Query<(Entity, &ViewVisibility, &Handle<M>)>>,
|
||||
) {
|
||||
material_instances.clear();
|
||||
for (entity, view_visibility, handle) in &query {
|
||||
}
|
||||
|
||||
fn extract_mesh_materials_2d<M: Material2d>(
|
||||
mut material_instances: ResMut<RenderMaterial2dInstances<M>>,
|
||||
query: Extract<Query<(Entity, &ViewVisibility, &MeshMaterial2d<M>), With<Mesh2d>>>,
|
||||
) {
|
||||
for (entity, view_visibility, material) in &query {
|
||||
if view_visibility.get() {
|
||||
material_instances.insert(entity, handle.id());
|
||||
material_instances.insert(entity, material.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extracts default materials for 2D meshes with no [`MeshMaterial2d`].
|
||||
pub(crate) fn extract_default_materials_2d(
|
||||
mut material_instances: ResMut<RenderMaterial2dInstances<ColorMaterial>>,
|
||||
query: Extract<Query<(Entity, &ViewVisibility), (With<Mesh2d>, Without<HasMaterial2d>)>>,
|
||||
) {
|
||||
let default_material: AssetId<ColorMaterial> = Handle::<ColorMaterial>::default().id();
|
||||
|
||||
for (entity, view_visibility) in &query {
|
||||
if view_visibility.get() {
|
||||
material_instances.insert(entity, default_material);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -340,7 +477,7 @@ impl<M: Material2d> FromWorld for Material2dPipeline<M> {
|
|||
}
|
||||
}
|
||||
|
||||
type DrawMaterial2d<M> = (
|
||||
pub(super) type DrawMaterial2d<M> = (
|
||||
SetItemPipeline,
|
||||
SetMesh2dViewBindGroup<0>,
|
||||
SetMesh2dBindGroup<1>,
|
||||
|
@ -460,7 +597,7 @@ pub fn queue_material2d_meshes<M: Material2d>(
|
|||
view_key |= Mesh2dPipelineKey::DEBAND_DITHER;
|
||||
}
|
||||
}
|
||||
for visible_entity in visible_entities.iter::<WithMesh2d>() {
|
||||
for visible_entity in visible_entities.iter::<With<Mesh2d>>() {
|
||||
let Some(material_asset_id) = render_material_instances.get(visible_entity) else {
|
||||
continue;
|
||||
};
|
||||
|
@ -609,11 +746,15 @@ impl<M: Material2d> RenderAsset for PreparedMaterial2d<M> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A component bundle for entities with a [`Mesh2dHandle`] and a [`Material2d`].
|
||||
/// A component bundle for entities with a [`Mesh2d`] and a [`MeshMaterial2d`].
|
||||
#[derive(Bundle, Clone)]
|
||||
#[deprecated(
|
||||
since = "0.15.0",
|
||||
note = "Use the `Mesh2d` and `MeshMaterial2d` components instead. Inserting them will now also insert the other components required by them automatically."
|
||||
)]
|
||||
pub struct MaterialMesh2dBundle<M: Material2d> {
|
||||
pub mesh: Mesh2dHandle,
|
||||
pub material: Handle<M>,
|
||||
pub mesh: Mesh2d,
|
||||
pub material: MeshMaterial2d<M>,
|
||||
pub transform: Transform,
|
||||
pub global_transform: GlobalTransform,
|
||||
/// User indication of whether an entity is visible
|
||||
|
|
|
@ -15,7 +15,6 @@ use bevy_ecs::{
|
|||
system::{lifetimeless::*, SystemParamItem, SystemState},
|
||||
};
|
||||
use bevy_math::{Affine3, Vec4};
|
||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||
use bevy_render::{
|
||||
batching::{
|
||||
gpu_preprocessing::IndirectParameters,
|
||||
|
@ -27,7 +26,8 @@ use bevy_render::{
|
|||
},
|
||||
globals::{GlobalsBuffer, GlobalsUniform},
|
||||
mesh::{
|
||||
allocator::MeshAllocator, Mesh, MeshVertexBufferLayoutRef, RenderMesh, RenderMeshBufferInfo,
|
||||
allocator::MeshAllocator, Mesh, Mesh2d, MeshVertexBufferLayoutRef, RenderMesh,
|
||||
RenderMeshBufferInfo,
|
||||
},
|
||||
render_asset::RenderAssets,
|
||||
render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass},
|
||||
|
@ -48,19 +48,6 @@ use nonmax::NonMaxU32;
|
|||
|
||||
use crate::Material2dBindGroupId;
|
||||
|
||||
/// Component for rendering with meshes in the 2d pipeline, usually with a [2d material](crate::Material2d) such as [`ColorMaterial`](crate::ColorMaterial).
|
||||
///
|
||||
/// It wraps a [`Handle<Mesh>`] to differentiate from the 3d pipelines which use the handles directly as components
|
||||
#[derive(Default, Clone, Component, Debug, Reflect, PartialEq, Eq, Deref, DerefMut)]
|
||||
#[reflect(Default, Component, Debug, PartialEq)]
|
||||
pub struct Mesh2dHandle(pub Handle<Mesh>);
|
||||
|
||||
impl From<Handle<Mesh>> for Mesh2dHandle {
|
||||
fn from(handle: Handle<Mesh>) -> Self {
|
||||
Self(handle)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Mesh2dRenderPlugin;
|
||||
|
||||
|
@ -218,7 +205,7 @@ pub struct RenderMesh2dInstance {
|
|||
pub struct RenderMesh2dInstances(EntityHashMap<RenderMesh2dInstance>);
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Mesh2d;
|
||||
pub struct Mesh2dMarker;
|
||||
|
||||
pub fn extract_mesh2d(
|
||||
mut render_mesh_instances: ResMut<RenderMesh2dInstances>,
|
||||
|
@ -227,7 +214,7 @@ pub fn extract_mesh2d(
|
|||
Entity,
|
||||
&ViewVisibility,
|
||||
&GlobalTransform,
|
||||
&Mesh2dHandle,
|
||||
&Mesh2d,
|
||||
Has<NoAutomaticBatching>,
|
||||
)>,
|
||||
>,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Material2d, Material2dKey, Material2dPlugin, Mesh2dHandle};
|
||||
use crate::{Material2d, Material2dKey, Material2dPlugin, Mesh2d};
|
||||
use bevy_app::{Plugin, Startup, Update};
|
||||
use bevy_asset::{load_internal_asset, Asset, Assets, Handle};
|
||||
use bevy_color::{Color, LinearRgba};
|
||||
|
@ -9,6 +9,8 @@ use bevy_render::{
|
|||
render_resource::*,
|
||||
};
|
||||
|
||||
use super::MeshMaterial2d;
|
||||
|
||||
pub const WIREFRAME_2D_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(6920362697190520314);
|
||||
|
||||
/// A [`Plugin`] that draws wireframes for 2D meshes.
|
||||
|
@ -126,12 +128,12 @@ fn global_color_changed(
|
|||
fn wireframe_color_changed(
|
||||
mut materials: ResMut<Assets<Wireframe2dMaterial>>,
|
||||
mut colors_changed: Query<
|
||||
(&mut Handle<Wireframe2dMaterial>, &Wireframe2dColor),
|
||||
(&mut MeshMaterial2d<Wireframe2dMaterial>, &Wireframe2dColor),
|
||||
(With<Wireframe2d>, Changed<Wireframe2dColor>),
|
||||
>,
|
||||
) {
|
||||
for (mut handle, wireframe_color) in &mut colors_changed {
|
||||
*handle = materials.add(Wireframe2dMaterial {
|
||||
handle.0 = materials.add(Wireframe2dMaterial {
|
||||
color: wireframe_color.color.into(),
|
||||
});
|
||||
}
|
||||
|
@ -144,15 +146,24 @@ fn apply_wireframe_material(
|
|||
mut materials: ResMut<Assets<Wireframe2dMaterial>>,
|
||||
wireframes: Query<
|
||||
(Entity, Option<&Wireframe2dColor>),
|
||||
(With<Wireframe2d>, Without<Handle<Wireframe2dMaterial>>),
|
||||
(
|
||||
With<Wireframe2d>,
|
||||
Without<MeshMaterial2d<Wireframe2dMaterial>>,
|
||||
),
|
||||
>,
|
||||
no_wireframes: Query<
|
||||
Entity,
|
||||
(
|
||||
With<NoWireframe2d>,
|
||||
With<MeshMaterial2d<Wireframe2dMaterial>>,
|
||||
),
|
||||
>,
|
||||
no_wireframes: Query<Entity, (With<NoWireframe2d>, With<Handle<Wireframe2dMaterial>>)>,
|
||||
mut removed_wireframes: RemovedComponents<Wireframe2d>,
|
||||
global_material: Res<GlobalWireframe2dMaterial>,
|
||||
) {
|
||||
for e in removed_wireframes.read().chain(no_wireframes.iter()) {
|
||||
if let Some(commands) = commands.get_entity(e) {
|
||||
commands.remove::<Handle<Wireframe2dMaterial>>();
|
||||
commands.remove::<MeshMaterial2d<Wireframe2dMaterial>>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,16 +177,12 @@ fn apply_wireframe_material(
|
|||
// If there's no color specified we can use the global material since it's already set to use the default_color
|
||||
global_material.handle.clone()
|
||||
};
|
||||
wireframes_to_spawn.push((e, material));
|
||||
wireframes_to_spawn.push((e, MeshMaterial2d(material)));
|
||||
}
|
||||
commands.insert_or_spawn_batch(wireframes_to_spawn);
|
||||
}
|
||||
|
||||
type Wireframe2dFilter = (
|
||||
With<Mesh2dHandle>,
|
||||
Without<Wireframe2d>,
|
||||
Without<NoWireframe2d>,
|
||||
);
|
||||
type Wireframe2dFilter = (With<Mesh2d>, Without<Wireframe2d>, Without<NoWireframe2d>);
|
||||
|
||||
/// Applies or removes a wireframe material on any mesh without a [`Wireframe2d`] or [`NoWireframe2d`] component.
|
||||
fn apply_global_wireframe_material(
|
||||
|
@ -183,11 +190,14 @@ fn apply_global_wireframe_material(
|
|||
config: Res<Wireframe2dConfig>,
|
||||
meshes_without_material: Query<
|
||||
Entity,
|
||||
(Wireframe2dFilter, Without<Handle<Wireframe2dMaterial>>),
|
||||
(
|
||||
Wireframe2dFilter,
|
||||
Without<MeshMaterial2d<Wireframe2dMaterial>>,
|
||||
),
|
||||
>,
|
||||
meshes_with_global_material: Query<
|
||||
Entity,
|
||||
(Wireframe2dFilter, With<Handle<Wireframe2dMaterial>>),
|
||||
(Wireframe2dFilter, With<MeshMaterial2d<Wireframe2dMaterial>>),
|
||||
>,
|
||||
global_material: Res<GlobalWireframe2dMaterial>,
|
||||
) {
|
||||
|
@ -196,12 +206,14 @@ fn apply_global_wireframe_material(
|
|||
for e in &meshes_without_material {
|
||||
// We only add the material handle but not the Wireframe component
|
||||
// This makes it easy to detect which mesh is using the global material and which ones are user specified
|
||||
material_to_spawn.push((e, global_material.handle.clone()));
|
||||
material_to_spawn.push((e, MeshMaterial2d(global_material.handle.clone())));
|
||||
}
|
||||
commands.insert_or_spawn_batch(material_to_spawn);
|
||||
} else {
|
||||
for e in &meshes_with_global_material {
|
||||
commands.entity(e).remove::<Handle<Wireframe2dMaterial>>();
|
||||
commands
|
||||
.entity(e)
|
||||
.remove::<MeshMaterial2d<Wireframe2dMaterial>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,12 +32,11 @@ fn setup_cube(
|
|||
.spawn(Transform::default())
|
||||
.with_children(|parent| {
|
||||
// cube
|
||||
parent.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
parent.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::rgb(0.8, 0.7, 0.6))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
});
|
||||
|
||||
// camera
|
||||
|
@ -61,7 +60,8 @@ doesn't have a [`ViewVisibility`] or [`InheritedVisibility`] component.
|
|||
Since the cube is spawned as a child of an entity without the
|
||||
visibility components, it will not be visible at all.
|
||||
|
||||
To fix this, you must use [`SpatialBundle`], as follows:
|
||||
To fix this, you must also add a [`Visibility`] component.
|
||||
It automatically adds the other relevant visibility components for you:
|
||||
|
||||
```rust,no_run
|
||||
use bevy::prelude::*;
|
||||
|
@ -72,18 +72,14 @@ fn setup_cube(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
commands
|
||||
// We use SpatialBundle instead of Transform, it contains the
|
||||
// visibility components needed to display the cube,
|
||||
// In addition to the Transform and GlobalTransform components.
|
||||
.spawn(SpatialBundle::default())
|
||||
.spawn((Transform::default(), Visibility::default()))
|
||||
.with_children(|parent| {
|
||||
// cube
|
||||
parent.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
parent.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::rgb(0.8, 0.7, 0.6))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
});
|
||||
|
||||
// camera
|
||||
|
@ -103,14 +99,14 @@ fn main() {
|
|||
|
||||
A similar problem occurs when the [`GlobalTransform`] component is missing.
|
||||
However, it will be automatically inserted whenever `Transform` is
|
||||
inserted, as it's a required component.
|
||||
inserted, as it is a required component.
|
||||
|
||||
You will most likely encounter this warning when loading a scene
|
||||
as a child of a pre-existing [`Entity`] that does not have the proper components.
|
||||
|
||||
[`InheritedVisibility`]: https://docs.rs/bevy/*/bevy/render/view/struct.InheritedVisibility.html
|
||||
[`ViewVisibility`]: https://docs.rs/bevy/*/bevy/render/view/struct.ViewVisibility.html
|
||||
[`Visibility`]: https://docs.rs/bevy/*/bevy/render/view/struct.Visibility.html
|
||||
[`GlobalTransform`]: https://docs.rs/bevy/*/bevy/transform/components/struct.GlobalTransform.html
|
||||
[`Parent`]: https://docs.rs/bevy/*/bevy/hierarchy/struct.Parent.html
|
||||
[`Entity`]: https://docs.rs/bevy/*/bevy/ecs/entity/struct.Entity.html
|
||||
[`SpatialBundle`]: https://docs.rs/bevy/*/bevy/render/prelude/struct.SpatialBundle.html
|
||||
|
|
|
@ -3,12 +3,9 @@
|
|||
//! You can toggle wireframes with the space bar except on wasm. Wasm does not support
|
||||
//! `POLYGON_MODE_LINE` on the gpu.
|
||||
|
||||
use bevy::prelude::*;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use bevy::sprite::{Wireframe2dConfig, Wireframe2dPlugin};
|
||||
use bevy::{
|
||||
prelude::*,
|
||||
sprite::{MaterialMesh2dBundle, Mesh2dHandle},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let mut app = App::new();
|
||||
|
@ -33,20 +30,20 @@ fn setup(
|
|||
commands.spawn(Camera2dBundle::default());
|
||||
|
||||
let shapes = [
|
||||
Mesh2dHandle(meshes.add(Circle::new(50.0))),
|
||||
Mesh2dHandle(meshes.add(CircularSector::new(50.0, 1.0))),
|
||||
Mesh2dHandle(meshes.add(CircularSegment::new(50.0, 1.25))),
|
||||
Mesh2dHandle(meshes.add(Ellipse::new(25.0, 50.0))),
|
||||
Mesh2dHandle(meshes.add(Annulus::new(25.0, 50.0))),
|
||||
Mesh2dHandle(meshes.add(Capsule2d::new(25.0, 50.0))),
|
||||
Mesh2dHandle(meshes.add(Rhombus::new(75.0, 100.0))),
|
||||
Mesh2dHandle(meshes.add(Rectangle::new(50.0, 100.0))),
|
||||
Mesh2dHandle(meshes.add(RegularPolygon::new(50.0, 6))),
|
||||
Mesh2dHandle(meshes.add(Triangle2d::new(
|
||||
meshes.add(Circle::new(50.0)),
|
||||
meshes.add(CircularSector::new(50.0, 1.0)),
|
||||
meshes.add(CircularSegment::new(50.0, 1.25)),
|
||||
meshes.add(Ellipse::new(25.0, 50.0)),
|
||||
meshes.add(Annulus::new(25.0, 50.0)),
|
||||
meshes.add(Capsule2d::new(25.0, 50.0)),
|
||||
meshes.add(Rhombus::new(75.0, 100.0)),
|
||||
meshes.add(Rectangle::new(50.0, 100.0)),
|
||||
meshes.add(RegularPolygon::new(50.0, 6)),
|
||||
meshes.add(Triangle2d::new(
|
||||
Vec2::Y * 50.0,
|
||||
Vec2::new(-50.0, -50.0),
|
||||
Vec2::new(50.0, -50.0),
|
||||
))),
|
||||
)),
|
||||
];
|
||||
let num_shapes = shapes.len();
|
||||
|
||||
|
@ -54,17 +51,16 @@ fn setup(
|
|||
// Distribute colors evenly across the rainbow.
|
||||
let color = Color::hsl(360. * i as f32 / num_shapes as f32, 0.95, 0.7);
|
||||
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: shape,
|
||||
material: materials.add(color),
|
||||
transform: Transform::from_xyz(
|
||||
commands.spawn((
|
||||
Mesh2d(shape),
|
||||
MeshMaterial2d(materials.add(color)),
|
||||
Transform::from_xyz(
|
||||
// Distribute shapes from -X_EXTENT/2 to +X_EXTENT/2.
|
||||
-X_EXTENT / 2. + i as f32 / (num_shapes - 1) as f32 * X_EXTENT,
|
||||
0.0,
|
||||
0.0,
|
||||
),
|
||||
..default()
|
||||
});
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
|
|
@ -6,7 +6,6 @@ use bevy::{
|
|||
tonemapping::Tonemapping,
|
||||
},
|
||||
prelude::*,
|
||||
sprite::MaterialMesh2dBundle,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
@ -47,22 +46,20 @@ fn setup(
|
|||
});
|
||||
|
||||
// Circle mesh
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: meshes.add(Circle::new(100.)).into(),
|
||||
commands.spawn((
|
||||
Mesh2d(meshes.add(Circle::new(100.))),
|
||||
// 4. Put something bright in a dark environment to see the effect
|
||||
material: materials.add(Color::srgb(7.5, 0.0, 7.5)),
|
||||
transform: Transform::from_translation(Vec3::new(-200., 0., 0.)),
|
||||
..default()
|
||||
});
|
||||
MeshMaterial2d(materials.add(Color::srgb(7.5, 0.0, 7.5))),
|
||||
Transform::from_translation(Vec3::new(-200., 0., 0.)),
|
||||
));
|
||||
|
||||
// Hexagon mesh
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: meshes.add(RegularPolygon::new(100., 6)).into(),
|
||||
commands.spawn((
|
||||
Mesh2d(meshes.add(RegularPolygon::new(100., 6))),
|
||||
// 4. Put something bright in a dark environment to see the effect
|
||||
material: materials.add(Color::srgb(6.25, 9.4, 9.1)),
|
||||
transform: Transform::from_translation(Vec3::new(200., 0., 0.)),
|
||||
..default()
|
||||
});
|
||||
MeshMaterial2d(materials.add(Color::srgb(6.25, 9.4, 9.1))),
|
||||
Transform::from_translation(Vec3::new(200., 0., 0.)),
|
||||
));
|
||||
|
||||
// UI
|
||||
commands.spawn(
|
||||
|
|
|
@ -8,7 +8,7 @@ use bevy::{
|
|||
mesh::{MeshVertexAttribute, MeshVertexBufferLayoutRef},
|
||||
render_resource::*,
|
||||
},
|
||||
sprite::{Material2d, Material2dKey, Material2dPlugin, MaterialMesh2dBundle, Mesh2dHandle},
|
||||
sprite::{Material2d, Material2dKey, Material2dPlugin},
|
||||
};
|
||||
|
||||
/// This example uses a shader source file from the assets subdirectory
|
||||
|
@ -53,12 +53,11 @@ fn setup(
|
|||
}
|
||||
.from_asset("models/barycentric/barycentric.gltf"),
|
||||
);
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: Mesh2dHandle(mesh),
|
||||
material: materials.add(CustomMaterial {}),
|
||||
transform: Transform::from_scale(150.0 * Vec3::ONE),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh2d(mesh),
|
||||
MeshMaterial2d(materials.add(CustomMaterial {})),
|
||||
Transform::from_scale(150.0 * Vec3::ONE),
|
||||
));
|
||||
|
||||
// Add a camera
|
||||
commands.spawn(Camera2dBundle { ..default() });
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Shows how to render a polygonal [`Mesh`], generated from a [`Rectangle`] primitive, in a 2D scene.
|
||||
|
||||
use bevy::{color::palettes::basic::PURPLE, prelude::*, sprite::MaterialMesh2dBundle};
|
||||
use bevy::{color::palettes::basic::PURPLE, prelude::*};
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
|
@ -15,10 +15,9 @@ fn setup(
|
|||
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
) {
|
||||
commands.spawn(Camera2dBundle::default());
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: meshes.add(Rectangle::default()).into(),
|
||||
transform: Transform::default().with_scale(Vec3::splat(128.)),
|
||||
material: materials.add(Color::from(PURPLE)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh2d(meshes.add(Rectangle::default())),
|
||||
MeshMaterial2d(materials.add(Color::from(PURPLE))),
|
||||
Transform::default().with_scale(Vec3::splat(128.)),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//! This example is used to test how transforms interact with alpha modes for [`MaterialMesh2dBundle`] entities.
|
||||
//! This example is used to test how transforms interact with alpha modes for [`Mesh2d`] entities with a [`MeshMaterial2d`].
|
||||
//! This makes sure the depth buffer is correctly being used for opaque and transparent 2d meshes
|
||||
|
||||
use bevy::{
|
||||
color::palettes::css::{BLUE, GREEN, WHITE},
|
||||
prelude::*,
|
||||
sprite::{AlphaMode2d, MaterialMesh2dBundle},
|
||||
sprite::AlphaMode2d,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
@ -28,70 +28,64 @@ fn setup(
|
|||
// opaque
|
||||
// Each sprite should be square with the transparent parts being completely black
|
||||
// The blue sprite should be on top with the white and green one behind it
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: mesh_handle.clone().into(),
|
||||
material: materials.add(ColorMaterial {
|
||||
commands.spawn((
|
||||
Mesh2d(mesh_handle.clone()),
|
||||
MeshMaterial2d(materials.add(ColorMaterial {
|
||||
color: WHITE.into(),
|
||||
alpha_mode: AlphaMode2d::Opaque,
|
||||
texture: Some(texture_handle.clone()),
|
||||
}),
|
||||
transform: Transform::from_xyz(-400.0, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: mesh_handle.clone().into(),
|
||||
material: materials.add(ColorMaterial {
|
||||
})),
|
||||
Transform::from_xyz(-400.0, 0.0, 0.0),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh2d(mesh_handle.clone()),
|
||||
MeshMaterial2d(materials.add(ColorMaterial {
|
||||
color: BLUE.into(),
|
||||
alpha_mode: AlphaMode2d::Opaque,
|
||||
texture: Some(texture_handle.clone()),
|
||||
}),
|
||||
transform: Transform::from_xyz(-300.0, 0.0, 1.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: mesh_handle.clone().into(),
|
||||
material: materials.add(ColorMaterial {
|
||||
})),
|
||||
Transform::from_xyz(-300.0, 0.0, 1.0),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh2d(mesh_handle.clone()),
|
||||
MeshMaterial2d(materials.add(ColorMaterial {
|
||||
color: GREEN.into(),
|
||||
alpha_mode: AlphaMode2d::Opaque,
|
||||
texture: Some(texture_handle.clone()),
|
||||
}),
|
||||
transform: Transform::from_xyz(-200.0, 0.0, -1.0),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(-200.0, 0.0, -1.0),
|
||||
));
|
||||
|
||||
// Test the interaction between opaque/mask and transparent meshes
|
||||
// The white sprite should be:
|
||||
// - only the icon is opaque but background is transparent
|
||||
// - on top of the green sprite
|
||||
// - behind the blue sprite
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: mesh_handle.clone().into(),
|
||||
material: materials.add(ColorMaterial {
|
||||
commands.spawn((
|
||||
Mesh2d(mesh_handle.clone()),
|
||||
MeshMaterial2d(materials.add(ColorMaterial {
|
||||
color: WHITE.into(),
|
||||
alpha_mode: AlphaMode2d::Mask(0.5),
|
||||
texture: Some(texture_handle.clone()),
|
||||
}),
|
||||
transform: Transform::from_xyz(200.0, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: mesh_handle.clone().into(),
|
||||
material: materials.add(ColorMaterial {
|
||||
})),
|
||||
Transform::from_xyz(200.0, 0.0, 0.0),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh2d(mesh_handle.clone()),
|
||||
MeshMaterial2d(materials.add(ColorMaterial {
|
||||
color: BLUE.with_alpha(0.7).into(),
|
||||
alpha_mode: AlphaMode2d::Blend,
|
||||
texture: Some(texture_handle.clone()),
|
||||
}),
|
||||
transform: Transform::from_xyz(300.0, 0.0, 1.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: mesh_handle.clone().into(),
|
||||
material: materials.add(ColorMaterial {
|
||||
})),
|
||||
Transform::from_xyz(300.0, 0.0, 1.0),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh2d(mesh_handle.clone()),
|
||||
MeshMaterial2d(materials.add(ColorMaterial {
|
||||
color: GREEN.with_alpha(0.7).into(),
|
||||
alpha_mode: AlphaMode2d::Blend,
|
||||
texture: Some(texture_handle),
|
||||
}),
|
||||
transform: Transform::from_xyz(400.0, 0.0, -1.0),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(400.0, 0.0, -1.0),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ use bevy::{
|
|||
},
|
||||
prelude::*,
|
||||
render::mesh::{CircularMeshUvMode, CircularSectorMeshBuilder, CircularSegmentMeshBuilder},
|
||||
sprite::MaterialMesh2dBundle,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
@ -68,14 +67,11 @@ fn setup(
|
|||
angle: sector_angle,
|
||||
});
|
||||
commands.spawn((
|
||||
MaterialMesh2dBundle {
|
||||
mesh: meshes.add(sector_mesh).into(),
|
||||
material: material.clone(),
|
||||
transform: Transform {
|
||||
translation: Vec3::new(FIRST_X + OFFSET * i as f32, 2.0 * UPPER_Y, 0.0),
|
||||
rotation: Quat::from_rotation_z(sector_angle),
|
||||
..default()
|
||||
},
|
||||
Mesh2d(meshes.add(sector_mesh)),
|
||||
MeshMaterial2d(material.clone()),
|
||||
Transform {
|
||||
translation: Vec3::new(FIRST_X + OFFSET * i as f32, 2.0 * UPPER_Y, 0.0),
|
||||
rotation: Quat::from_rotation_z(sector_angle),
|
||||
..default()
|
||||
},
|
||||
DrawBounds(sector),
|
||||
|
@ -95,14 +91,11 @@ fn setup(
|
|||
angle: -segment_angle,
|
||||
});
|
||||
commands.spawn((
|
||||
MaterialMesh2dBundle {
|
||||
mesh: meshes.add(segment_mesh).into(),
|
||||
material: material.clone(),
|
||||
transform: Transform {
|
||||
translation: Vec3::new(FIRST_X + OFFSET * i as f32, LOWER_Y, 0.0),
|
||||
rotation: Quat::from_rotation_z(segment_angle),
|
||||
..default()
|
||||
},
|
||||
Mesh2d(meshes.add(segment_mesh)),
|
||||
MeshMaterial2d(material.clone()),
|
||||
Transform {
|
||||
translation: Vec3::new(FIRST_X + OFFSET * i as f32, LOWER_Y, 0.0),
|
||||
rotation: Quat::from_rotation_z(segment_angle),
|
||||
..default()
|
||||
},
|
||||
DrawBounds(segment),
|
||||
|
|
|
@ -12,7 +12,7 @@ use bevy::{
|
|||
math::{ops, FloatOrd},
|
||||
prelude::*,
|
||||
render::{
|
||||
mesh::{Indices, MeshVertexAttribute, RenderMesh},
|
||||
mesh::{Indices, RenderMesh},
|
||||
render_asset::{RenderAssetUsages, RenderAssets},
|
||||
render_phase::{
|
||||
AddRenderCommand, DrawFunctions, PhaseItemExtraIndex, SetItemPipeline,
|
||||
|
@ -30,9 +30,9 @@ use bevy::{
|
|||
Extract, Render, RenderApp, RenderSet,
|
||||
},
|
||||
sprite::{
|
||||
extract_mesh2d, DrawMesh2d, Material2dBindGroupId, Mesh2dHandle, Mesh2dPipeline,
|
||||
extract_mesh2d, DrawMesh2d, HasMaterial2d, Material2dBindGroupId, Mesh2dPipeline,
|
||||
Mesh2dPipelineKey, Mesh2dTransforms, MeshFlags, RenderMesh2dInstance, SetMesh2dBindGroup,
|
||||
SetMesh2dViewBindGroup, WithMesh2d,
|
||||
SetMesh2dViewBindGroup,
|
||||
},
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
|
@ -85,12 +85,9 @@ fn star(
|
|||
// Set the position attribute
|
||||
star.insert_attribute(Mesh::ATTRIBUTE_POSITION, v_pos);
|
||||
// And a RGB color attribute as well
|
||||
let mut v_color: Vec<u32> = vec![LinearRgba::BLACK.as_u32()];
|
||||
v_color.extend_from_slice(&[LinearRgba::from(YELLOW).as_u32(); 10]);
|
||||
star.insert_attribute(
|
||||
MeshVertexAttribute::new("Vertex_Color", 1, VertexFormat::Uint32),
|
||||
v_color,
|
||||
);
|
||||
let mut v_color: Vec<[f32; 4]> = vec![LinearRgba::BLACK.to_f32_array()];
|
||||
v_color.extend_from_slice(&[LinearRgba::from(YELLOW).to_f32_array(); 10]);
|
||||
star.insert_attribute(Mesh::ATTRIBUTE_COLOR, v_color);
|
||||
|
||||
// Now, we specify the indices of the vertex that are going to compose the
|
||||
// triangles in our star. Vertices in triangles have to be specified in CCW
|
||||
|
@ -111,8 +108,8 @@ fn star(
|
|||
commands.spawn((
|
||||
// We use a marker component to identify the custom colored meshes
|
||||
ColoredMesh2d,
|
||||
// The `Handle<Mesh>` needs to be wrapped in a `Mesh2dHandle` to use 2d rendering instead of 3d
|
||||
Mesh2dHandle(meshes.add(star)),
|
||||
// The `Handle<Mesh>` needs to be wrapped in a `Mesh2d` for 2D rendering
|
||||
Mesh2d(meshes.add(star)),
|
||||
// This bundle's components are needed for something to be rendered
|
||||
SpatialBundle::INHERITED_IDENTITY,
|
||||
));
|
||||
|
@ -121,8 +118,10 @@ fn star(
|
|||
commands.spawn(Camera2dBundle::default());
|
||||
}
|
||||
|
||||
// Require `HasMaterial2d` to indicate that no placeholder material should be rendeed.
|
||||
/// A marker component for colored 2d meshes
|
||||
#[derive(Component, Default)]
|
||||
#[require(HasMaterial2d)]
|
||||
pub struct ColoredMesh2d;
|
||||
|
||||
/// Custom pipeline for 2d meshes with vertex colors
|
||||
|
@ -330,7 +329,7 @@ pub fn extract_colored_mesh2d(
|
|||
// When extracting, you must use `Extract` to mark the `SystemParam`s
|
||||
// which should be taken from the main world.
|
||||
query: Extract<
|
||||
Query<(Entity, &ViewVisibility, &GlobalTransform, &Mesh2dHandle), With<ColoredMesh2d>>,
|
||||
Query<(Entity, &ViewVisibility, &GlobalTransform, &Mesh2d), With<ColoredMesh2d>>,
|
||||
>,
|
||||
mut render_mesh_instances: ResMut<RenderColoredMesh2dInstances>,
|
||||
) {
|
||||
|
@ -387,7 +386,7 @@ pub fn queue_colored_mesh2d(
|
|||
| Mesh2dPipelineKey::from_hdr(view.hdr);
|
||||
|
||||
// Queue all entities visible to that view
|
||||
for visible_entity in visible_entities.iter::<WithMesh2d>() {
|
||||
for visible_entity in visible_entities.iter::<With<Mesh2d>>() {
|
||||
if let Some(mesh_instance) = render_mesh_instances.get(visible_entity) {
|
||||
let mesh2d_handle = mesh_instance.mesh_asset_id;
|
||||
let mesh2d_transforms = &mesh_instance.transforms;
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
//! Shows how to render a polygonal [`Mesh`], generated from a [`Rectangle`] primitive, in a 2D scene.
|
||||
//! Adds a texture and colored vertices, giving per-vertex tinting.
|
||||
|
||||
use bevy::{
|
||||
prelude::*,
|
||||
sprite::{MaterialMesh2dBundle, Mesh2dHandle},
|
||||
};
|
||||
use bevy::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
|
@ -33,26 +30,22 @@ fn setup(
|
|||
// Insert the vertex colors as an attribute
|
||||
mesh.insert_attribute(Mesh::ATTRIBUTE_COLOR, vertex_colors);
|
||||
|
||||
let mesh_handle: Mesh2dHandle = meshes.add(mesh).into();
|
||||
let mesh_handle = meshes.add(mesh);
|
||||
|
||||
// Spawn camera
|
||||
commands.spawn(Camera2dBundle::default());
|
||||
|
||||
// Spawn the quad with vertex colors
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: mesh_handle.clone(),
|
||||
transform: Transform::from_translation(Vec3::new(-96., 0., 0.))
|
||||
.with_scale(Vec3::splat(128.)),
|
||||
material: materials.add(ColorMaterial::default()),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh2d(mesh_handle.clone()),
|
||||
MeshMaterial2d(materials.add(ColorMaterial::default())),
|
||||
Transform::from_translation(Vec3::new(-96., 0., 0.)).with_scale(Vec3::splat(128.)),
|
||||
));
|
||||
|
||||
// Spawning the quad with vertex colors and a texture results in tinting
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: mesh_handle,
|
||||
transform: Transform::from_translation(Vec3::new(96., 0., 0.))
|
||||
.with_scale(Vec3::splat(128.)),
|
||||
material: materials.add(texture_handle),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh2d(mesh_handle),
|
||||
MeshMaterial2d(materials.add(texture_handle)),
|
||||
Transform::from_translation(Vec3::new(96., 0., 0.)).with_scale(Vec3::splat(128.)),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use bevy::{
|
|||
},
|
||||
view::RenderLayers,
|
||||
},
|
||||
sprite::MaterialMesh2dBundle,
|
||||
window::WindowResized,
|
||||
};
|
||||
|
||||
|
@ -81,12 +80,9 @@ fn setup_mesh(
|
|||
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
) {
|
||||
commands.spawn((
|
||||
MaterialMesh2dBundle {
|
||||
mesh: meshes.add(Capsule2d::default()).into(),
|
||||
transform: Transform::from_xyz(40., 0., 2.).with_scale(Vec3::splat(32.)),
|
||||
material: materials.add(Color::BLACK),
|
||||
..default()
|
||||
},
|
||||
Mesh2d(meshes.add(Capsule2d::default())),
|
||||
MeshMaterial2d(materials.add(Color::BLACK)),
|
||||
Transform::from_xyz(40., 0., 2.).with_scale(Vec3::splat(32.)),
|
||||
Rotate,
|
||||
PIXEL_PERFECT_LAYERS,
|
||||
));
|
||||
|
|
|
@ -16,10 +16,7 @@ use bevy::{
|
|||
settings::{RenderCreation, WgpuSettings},
|
||||
RenderPlugin,
|
||||
},
|
||||
sprite::{
|
||||
MaterialMesh2dBundle, NoWireframe2d, Wireframe2d, Wireframe2dColor, Wireframe2dConfig,
|
||||
Wireframe2dPlugin,
|
||||
},
|
||||
sprite::{NoWireframe2d, Wireframe2d, Wireframe2dColor, Wireframe2dConfig, Wireframe2dPlugin},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
@ -59,35 +56,26 @@ fn setup(
|
|||
) {
|
||||
// Triangle: Never renders a wireframe
|
||||
commands.spawn((
|
||||
MaterialMesh2dBundle {
|
||||
mesh: meshes
|
||||
.add(Triangle2d::new(
|
||||
Vec2::new(0.0, 50.0),
|
||||
Vec2::new(-50.0, -50.0),
|
||||
Vec2::new(50.0, -50.0),
|
||||
))
|
||||
.into(),
|
||||
material: materials.add(Color::BLACK),
|
||||
transform: Transform::from_xyz(-150.0, 0.0, 0.0),
|
||||
..default()
|
||||
},
|
||||
Mesh2d(meshes.add(Triangle2d::new(
|
||||
Vec2::new(0.0, 50.0),
|
||||
Vec2::new(-50.0, -50.0),
|
||||
Vec2::new(50.0, -50.0),
|
||||
))),
|
||||
MeshMaterial2d(materials.add(Color::BLACK)),
|
||||
Transform::from_xyz(-150.0, 0.0, 0.0),
|
||||
NoWireframe2d,
|
||||
));
|
||||
// Rectangle: Follows global wireframe setting
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: meshes.add(Rectangle::new(100.0, 100.0)).into(),
|
||||
material: materials.add(Color::BLACK),
|
||||
transform: Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh2d(meshes.add(Rectangle::new(100.0, 100.0))),
|
||||
MeshMaterial2d(materials.add(Color::BLACK)),
|
||||
Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
));
|
||||
// Circle: Always renders a wireframe
|
||||
commands.spawn((
|
||||
MaterialMesh2dBundle {
|
||||
mesh: meshes.add(Circle::new(50.0)).into(),
|
||||
material: materials.add(Color::BLACK),
|
||||
transform: Transform::from_xyz(150.0, 0.0, 0.0),
|
||||
..default()
|
||||
},
|
||||
Mesh2d(meshes.add(Circle::new(50.0))),
|
||||
MeshMaterial2d(materials.add(Color::BLACK)),
|
||||
Transform::from_xyz(150.0, 0.0, 0.0),
|
||||
Wireframe2d,
|
||||
// This lets you configure the wireframe color of this entity.
|
||||
// If not set, this will use the color in `WireframeConfig`
|
||||
|
|
|
@ -16,19 +16,17 @@ fn setup(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
// circular base
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Circle::new(4.0)),
|
||||
material: materials.add(Color::WHITE),
|
||||
transform: Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Circle::new(4.0))),
|
||||
MeshMaterial3d(materials.add(Color::WHITE)),
|
||||
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||
));
|
||||
// cube
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
|
||||
material: materials.add(Color::srgb_u8(124, 144, 255)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
// light
|
||||
commands.spawn((
|
||||
PointLight {
|
||||
|
|
|
@ -81,17 +81,14 @@ fn setup(
|
|||
|
||||
for (i, shape) in shapes.into_iter().enumerate() {
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: shape,
|
||||
material: debug_material.clone(),
|
||||
transform: Transform::from_xyz(
|
||||
-SHAPES_X_EXTENT / 2. + i as f32 / (num_shapes - 1) as f32 * SHAPES_X_EXTENT,
|
||||
2.0,
|
||||
Z_EXTENT / 2.,
|
||||
)
|
||||
.with_rotation(Quat::from_rotation_x(-PI / 4.)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(shape),
|
||||
MeshMaterial3d(debug_material.clone()),
|
||||
Transform::from_xyz(
|
||||
-SHAPES_X_EXTENT / 2. + i as f32 / (num_shapes - 1) as f32 * SHAPES_X_EXTENT,
|
||||
2.0,
|
||||
Z_EXTENT / 2.,
|
||||
)
|
||||
.with_rotation(Quat::from_rotation_x(-PI / 4.)),
|
||||
Shape,
|
||||
));
|
||||
}
|
||||
|
@ -100,18 +97,15 @@ fn setup(
|
|||
|
||||
for (i, shape) in extrusions.into_iter().enumerate() {
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: shape,
|
||||
material: debug_material.clone(),
|
||||
transform: Transform::from_xyz(
|
||||
-EXTRUSION_X_EXTENT / 2.
|
||||
+ i as f32 / (num_extrusions - 1) as f32 * EXTRUSION_X_EXTENT,
|
||||
2.0,
|
||||
-Z_EXTENT / 2.,
|
||||
)
|
||||
.with_rotation(Quat::from_rotation_x(-PI / 4.)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(shape),
|
||||
MeshMaterial3d(debug_material.clone()),
|
||||
Transform::from_xyz(
|
||||
-EXTRUSION_X_EXTENT / 2.
|
||||
+ i as f32 / (num_extrusions - 1) as f32 * EXTRUSION_X_EXTENT,
|
||||
2.0,
|
||||
-Z_EXTENT / 2.,
|
||||
)
|
||||
.with_rotation(Quat::from_rotation_x(-PI / 4.)),
|
||||
Shape,
|
||||
));
|
||||
}
|
||||
|
@ -128,11 +122,10 @@ fn setup(
|
|||
));
|
||||
|
||||
// ground plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0).subdivisions(10)),
|
||||
material: materials.add(Color::from(SILVER)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(50.0, 50.0).subdivisions(10))),
|
||||
MeshMaterial3d(materials.add(Color::from(SILVER))),
|
||||
));
|
||||
|
||||
commands.spawn(Camera3dBundle {
|
||||
transform: Transform::from_xyz(0.0, 7., 14.0).looking_at(Vec3::new(0., 1., 0.), Vec3::Y),
|
||||
|
|
|
@ -57,11 +57,8 @@ fn setup(
|
|||
) {
|
||||
// plane
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(20., 20.)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(20., 20.))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
Ground,
|
||||
));
|
||||
|
||||
|
|
|
@ -37,19 +37,18 @@ fn setup(
|
|||
let mut hsla = Hsla::hsl(0.0, 1.0, 0.5);
|
||||
for x in -1..2 {
|
||||
for z in -1..2 {
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: cube.clone(),
|
||||
material: materials.add(Color::from(hsla)),
|
||||
transform: Transform::from_translation(Vec3::new(x as f32, 0.0, z as f32)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(cube.clone()),
|
||||
MeshMaterial3d(materials.add(Color::from(hsla))),
|
||||
Transform::from_translation(Vec3::new(x as f32, 0.0, z as f32)),
|
||||
));
|
||||
hsla = hsla.rotate_hue(GOLDEN_ANGLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn animate_materials(
|
||||
material_handles: Query<&Handle<StandardMaterial>>,
|
||||
material_handles: Query<&MeshMaterial3d<StandardMaterial>>,
|
||||
time: Res<Time>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
|
|
|
@ -104,8 +104,11 @@ fn create_material_variants(
|
|||
mut commands: Commands,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
new_meshes: Query<
|
||||
(Entity, &Handle<StandardMaterial>),
|
||||
(Added<Handle<StandardMaterial>>, Without<MaterialVariants>),
|
||||
(Entity, &MeshMaterial3d<StandardMaterial>),
|
||||
(
|
||||
Added<MeshMaterial3d<StandardMaterial>>,
|
||||
Without<MaterialVariants>,
|
||||
),
|
||||
>,
|
||||
) {
|
||||
for (entity, anisotropic_material_handle) in new_meshes.iter() {
|
||||
|
@ -114,7 +117,7 @@ fn create_material_variants(
|
|||
};
|
||||
|
||||
commands.entity(entity).insert(MaterialVariants {
|
||||
anisotropic: anisotropic_material_handle.clone(),
|
||||
anisotropic: anisotropic_material_handle.0.clone(),
|
||||
isotropic: materials.add(StandardMaterial {
|
||||
anisotropy_texture: None,
|
||||
anisotropy_strength: 0.0,
|
||||
|
@ -163,7 +166,7 @@ fn handle_input(
|
|||
asset_server: Res<AssetServer>,
|
||||
cameras: Query<Entity, With<Camera>>,
|
||||
lights: Query<Entity, Or<(With<DirectionalLight>, With<PointLight>)>>,
|
||||
mut meshes: Query<(&mut Handle<StandardMaterial>, &MaterialVariants)>,
|
||||
mut meshes: Query<(&mut MeshMaterial3d<StandardMaterial>, &MaterialVariants)>,
|
||||
keyboard: Res<ButtonInput<KeyCode>>,
|
||||
mut app_status: ResMut<AppStatus>,
|
||||
) {
|
||||
|
@ -213,7 +216,7 @@ fn handle_input(
|
|||
|
||||
// Go through each mesh and alter its material.
|
||||
for (mut material_handle, material_variants) in meshes.iter_mut() {
|
||||
*material_handle = if app_status.anisotropy_enabled {
|
||||
material_handle.0 = if app_status.anisotropy_enabled {
|
||||
material_variants.anisotropic.clone()
|
||||
} else {
|
||||
material_variants.isotropic.clone()
|
||||
|
|
|
@ -252,11 +252,10 @@ fn setup(
|
|||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
// Plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)),
|
||||
material: materials.add(Color::srgb(0.1, 0.2, 0.1)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(50.0, 50.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.1, 0.2, 0.1))),
|
||||
));
|
||||
|
||||
let cube_material = materials.add(StandardMaterial {
|
||||
base_color_texture: Some(images.add(uv_debug_texture())),
|
||||
|
@ -265,12 +264,11 @@ fn setup(
|
|||
|
||||
// Cubes
|
||||
for i in 0..5 {
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(0.25, 0.25, 0.25)),
|
||||
material: cube_material.clone(),
|
||||
transform: Transform::from_xyz(i as f32 * 0.25 - 1.0, 0.125, -i as f32 * 0.5),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(0.25, 0.25, 0.25))),
|
||||
MeshMaterial3d(cube_material.clone()),
|
||||
Transform::from_xyz(i as f32 * 0.25 - 1.0, 0.125, -i as f32 * 0.5),
|
||||
));
|
||||
}
|
||||
|
||||
// Flight Helmet
|
||||
|
|
|
@ -77,17 +77,14 @@ fn setup_terrain_scene(
|
|||
|
||||
// Sky
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(2.0, 1.0, 1.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("888888").unwrap().into(),
|
||||
unlit: true,
|
||||
cull_mode: None,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_scale(Vec3::splat(20.0)),
|
||||
Mesh3d(meshes.add(Cuboid::new(2.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("888888").unwrap().into(),
|
||||
unlit: true,
|
||||
cull_mode: None,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_scale(Vec3::splat(20.0)),
|
||||
NotShadowCaster,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -88,20 +88,18 @@ fn setup(
|
|||
|
||||
let height = Vec3::Y * level as f32;
|
||||
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: plane.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(plane.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(
|
||||
0.5 + side.x * 0.5,
|
||||
0.75 - level as f32 * 0.25,
|
||||
0.5 + side.z * 0.5,
|
||||
),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_translation(side * 2.0 + height)
|
||||
.looking_at(height, Vec3::Y),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_translation(side * 2.0 + height),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,16 +42,13 @@ fn setup(
|
|||
// Opaque
|
||||
let opaque = commands
|
||||
.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Opaque,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-4.0, 0.0, 0.0),
|
||||
Mesh3d(icosphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Opaque,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(-4.0, 0.0, 0.0),
|
||||
ExampleControls {
|
||||
unlit: true,
|
||||
color: true,
|
||||
|
@ -62,16 +59,13 @@ fn setup(
|
|||
// Blend
|
||||
let blend = commands
|
||||
.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-2.0, 0.0, 0.0),
|
||||
Mesh3d(icosphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(-2.0, 0.0, 0.0),
|
||||
ExampleControls {
|
||||
unlit: true,
|
||||
color: true,
|
||||
|
@ -82,16 +76,13 @@ fn setup(
|
|||
// Premultiplied
|
||||
let premultiplied = commands
|
||||
.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Premultiplied,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
Mesh3d(icosphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Premultiplied,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
ExampleControls {
|
||||
unlit: true,
|
||||
color: true,
|
||||
|
@ -102,16 +93,13 @@ fn setup(
|
|||
// Add
|
||||
let add = commands
|
||||
.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Add,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(2.0, 0.0, 0.0),
|
||||
Mesh3d(icosphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Add,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(2.0, 0.0, 0.0),
|
||||
ExampleControls {
|
||||
unlit: true,
|
||||
color: true,
|
||||
|
@ -122,16 +110,13 @@ fn setup(
|
|||
// Multiply
|
||||
let multiply = commands
|
||||
.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh,
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Multiply,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(4.0, 0.0, 0.0),
|
||||
Mesh3d(icosphere_mesh),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color,
|
||||
alpha_mode: AlphaMode::Multiply,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(4.0, 0.0, 0.0),
|
||||
ExampleControls {
|
||||
unlit: true,
|
||||
color: true,
|
||||
|
@ -148,16 +133,13 @@ fn setup(
|
|||
for x in -3..4 {
|
||||
for z in -3..4 {
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: plane_mesh.clone(),
|
||||
material: if (x + z) % 2 == 0 {
|
||||
black_material.clone()
|
||||
} else {
|
||||
white_material.clone()
|
||||
},
|
||||
transform: Transform::from_xyz(x as f32 * 2.0, -1.0, z as f32 * 2.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(plane_mesh.clone()),
|
||||
MeshMaterial3d(if (x + z) % 2 == 0 {
|
||||
black_material.clone()
|
||||
} else {
|
||||
white_material.clone()
|
||||
}),
|
||||
Transform::from_xyz(x as f32 * 2.0, -1.0, z as f32 * 2.0),
|
||||
ExampleControls {
|
||||
unlit: false,
|
||||
color: true,
|
||||
|
@ -277,7 +259,7 @@ impl Default for ExampleState {
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
fn example_control_system(
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
controllable: Query<(&Handle<StandardMaterial>, &ExampleControls)>,
|
||||
controllable: Query<(&MeshMaterial3d<StandardMaterial>, &ExampleControls)>,
|
||||
mut camera: Query<(&mut Camera, &mut Transform, &GlobalTransform), With<Camera3d>>,
|
||||
mut labels: Query<(&mut Style, &ExampleLabel)>,
|
||||
mut display: Query<&mut Text, With<ExampleDisplay>>,
|
||||
|
|
|
@ -77,12 +77,9 @@ fn setup_scene(
|
|||
};
|
||||
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: mesh.clone(),
|
||||
material,
|
||||
transform: Transform::from_xyz(x as f32 * 2.0, 0.0, z as f32 * 2.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(mesh.clone()),
|
||||
MeshMaterial3d(material),
|
||||
Transform::from_xyz(x as f32 * 2.0, 0.0, z as f32 * 2.0),
|
||||
Bouncing,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -50,19 +50,17 @@ fn setup(
|
|||
let transform = Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y);
|
||||
|
||||
// Plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
));
|
||||
|
||||
// Cube
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::srgb(0.8, 0.7, 0.6)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
|
||||
// Light
|
||||
commands.spawn((
|
||||
|
|
|
@ -97,9 +97,9 @@ fn spawn_car_paint_sphere(
|
|||
sphere: &Handle<Mesh>,
|
||||
) {
|
||||
commands
|
||||
.spawn(PbrBundle {
|
||||
mesh: sphere.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
.spawn((
|
||||
Mesh3d(sphere.clone()),
|
||||
materials.add(StandardMaterial {
|
||||
clearcoat: 1.0,
|
||||
clearcoat_perceptual_roughness: 0.1,
|
||||
normal_map_texture: Some(asset_server.load_with_settings(
|
||||
|
@ -111,9 +111,8 @@ fn spawn_car_paint_sphere(
|
|||
base_color: BLUE.into(),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-1.0, 1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
..default()
|
||||
})
|
||||
Transform::from_xyz(-1.0, 1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
))
|
||||
.insert(ExampleSphere);
|
||||
}
|
||||
|
||||
|
@ -124,9 +123,9 @@ fn spawn_coated_glass_bubble_sphere(
|
|||
sphere: &Handle<Mesh>,
|
||||
) {
|
||||
commands
|
||||
.spawn(PbrBundle {
|
||||
mesh: sphere.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
.spawn((
|
||||
Mesh3d(sphere.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
clearcoat: 1.0,
|
||||
clearcoat_perceptual_roughness: 0.1,
|
||||
metallic: 0.5,
|
||||
|
@ -134,10 +133,9 @@ fn spawn_coated_glass_bubble_sphere(
|
|||
base_color: Color::srgba(0.9, 0.9, 0.9, 0.3),
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-1.0, -1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
..default()
|
||||
})
|
||||
})),
|
||||
Transform::from_xyz(-1.0, -1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
))
|
||||
.insert(ExampleSphere);
|
||||
}
|
||||
|
||||
|
@ -166,9 +164,9 @@ fn spawn_scratched_gold_ball(
|
|||
sphere: &Handle<Mesh>,
|
||||
) {
|
||||
commands
|
||||
.spawn(PbrBundle {
|
||||
mesh: sphere.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
.spawn((
|
||||
Mesh3d(sphere.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
clearcoat: 1.0,
|
||||
clearcoat_perceptual_roughness: 0.3,
|
||||
clearcoat_normal_texture: Some(asset_server.load_with_settings(
|
||||
|
@ -179,10 +177,9 @@ fn spawn_scratched_gold_ball(
|
|||
perceptual_roughness: 0.1,
|
||||
base_color: GOLD.into(),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(1.0, -1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
..default()
|
||||
})
|
||||
})),
|
||||
Transform::from_xyz(1.0, -1.0, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
))
|
||||
.insert(ExampleSphere);
|
||||
}
|
||||
|
||||
|
|
|
@ -100,28 +100,25 @@ fn setup(
|
|||
let forward_mat_h = materials.add(forward_mat);
|
||||
|
||||
// Plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)),
|
||||
material: forward_mat_h.clone(),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(50.0, 50.0))),
|
||||
MeshMaterial3d(forward_mat_h.clone()),
|
||||
));
|
||||
|
||||
let cube_h = meshes.add(Cuboid::new(0.1, 0.1, 0.1));
|
||||
let sphere_h = meshes.add(Sphere::new(0.125).mesh().uv(32, 18));
|
||||
|
||||
// Cubes
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: cube_h.clone(),
|
||||
material: forward_mat_h.clone(),
|
||||
transform: Transform::from_xyz(-0.3, 0.5, -0.2),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: cube_h,
|
||||
material: forward_mat_h,
|
||||
transform: Transform::from_xyz(0.2, 0.5, 0.2),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(cube_h.clone()),
|
||||
MeshMaterial3d(forward_mat_h.clone()),
|
||||
Transform::from_xyz(-0.3, 0.5, -0.2),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh3d(cube_h),
|
||||
MeshMaterial3d(forward_mat_h),
|
||||
Transform::from_xyz(0.2, 0.5, 0.2),
|
||||
));
|
||||
|
||||
let sphere_color = Color::srgb(10.0, 4.0, 1.0);
|
||||
let sphere_pos = Transform::from_xyz(0.4, 0.5, -0.8);
|
||||
|
@ -129,12 +126,9 @@ fn setup(
|
|||
let mut unlit_mat: StandardMaterial = sphere_color.into();
|
||||
unlit_mat.unlit = true;
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: sphere_h.clone(),
|
||||
material: materials.add(unlit_mat),
|
||||
transform: sphere_pos,
|
||||
..default()
|
||||
},
|
||||
Mesh3d(sphere_h.clone()),
|
||||
MeshMaterial3d(materials.add(unlit_mat)),
|
||||
sphere_pos,
|
||||
NotShadowCaster,
|
||||
));
|
||||
// Light
|
||||
|
@ -175,31 +169,27 @@ fn setup(
|
|||
..default()
|
||||
})
|
||||
};
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: sphere_h.clone(),
|
||||
material,
|
||||
transform: Transform::from_xyz(
|
||||
commands.spawn((
|
||||
Mesh3d(sphere_h.clone()),
|
||||
MeshMaterial3d(material),
|
||||
Transform::from_xyz(
|
||||
j as f32 * 0.25 + if i < 3 { -0.15 } else { 0.15 } - 0.4,
|
||||
0.125,
|
||||
-j as f32 * 0.25 + if i < 3 { -0.15 } else { 0.15 } + 0.4,
|
||||
),
|
||||
..default()
|
||||
});
|
||||
));
|
||||
}
|
||||
|
||||
// sky
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(2.0, 1.0, 1.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("888888").unwrap().into(),
|
||||
unlit: true,
|
||||
cull_mode: None,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_scale(Vec3::splat(1_000_000.0)),
|
||||
Mesh3d(meshes.add(Cuboid::new(2.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("888888").unwrap().into(),
|
||||
unlit: true,
|
||||
cull_mode: None,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_scale(Vec3::splat(1_000_000.0)),
|
||||
NotShadowCaster,
|
||||
NotShadowReceiver,
|
||||
));
|
||||
|
@ -266,12 +256,9 @@ fn setup_parallax(
|
|||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(cube),
|
||||
material: parallax_material,
|
||||
transform: Transform::from_xyz(0.4, 0.2, -0.8),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(cube)),
|
||||
MeshMaterial3d(parallax_material),
|
||||
Transform::from_xyz(0.4, 0.2, -0.8),
|
||||
Spin { speed: 0.3 },
|
||||
));
|
||||
}
|
||||
|
|
|
@ -194,8 +194,8 @@ fn tweak_scene(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
mut lights: Query<&mut DirectionalLight, Changed<DirectionalLight>>,
|
||||
mut named_entities: Query<
|
||||
(Entity, &Name, &Handle<StandardMaterial>),
|
||||
(With<Handle<Mesh>>, Without<Lightmap>),
|
||||
(Entity, &Name, &MeshMaterial3d<StandardMaterial>),
|
||||
(With<Mesh3d>, Without<Lightmap>),
|
||||
>,
|
||||
) {
|
||||
// Turn on shadows.
|
||||
|
|
|
@ -59,30 +59,25 @@ fn setup_pyramid_scene(
|
|||
|
||||
// pillars
|
||||
for (x, z) in &[(-1.5, -1.5), (1.5, -1.5), (1.5, 1.5), (-1.5, 1.5)] {
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(1.0, 3.0, 1.0)),
|
||||
material: stone.clone(),
|
||||
transform: Transform::from_xyz(*x, 1.5, *z),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(1.0, 3.0, 1.0))),
|
||||
MeshMaterial3d(stone.clone()),
|
||||
Transform::from_xyz(*x, 1.5, *z),
|
||||
));
|
||||
}
|
||||
|
||||
// orb
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Sphere::default()),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("126212CC").unwrap().into(),
|
||||
reflectance: 1.0,
|
||||
perceptual_roughness: 0.0,
|
||||
metallic: 0.5,
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_scale(Vec3::splat(1.75))
|
||||
.with_translation(Vec3::new(0.0, 4.0, 0.0)),
|
||||
Mesh3d(meshes.add(Sphere::default())),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("126212CC").unwrap().into(),
|
||||
reflectance: 1.0,
|
||||
perceptual_roughness: 0.0,
|
||||
metallic: 0.5,
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_scale(Vec3::splat(1.75)).with_translation(Vec3::new(0.0, 4.0, 0.0)),
|
||||
NotShadowCaster,
|
||||
NotShadowReceiver,
|
||||
));
|
||||
|
@ -91,26 +86,24 @@ fn setup_pyramid_scene(
|
|||
for i in 0..50 {
|
||||
let half_size = i as f32 / 2.0 + 3.0;
|
||||
let y = -i as f32 / 2.0;
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(2.0 * half_size, 0.5, 2.0 * half_size)),
|
||||
material: stone.clone(),
|
||||
transform: Transform::from_xyz(0.0, y + 0.25, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(2.0 * half_size, 0.5, 2.0 * half_size))),
|
||||
MeshMaterial3d(stone.clone()),
|
||||
Transform::from_xyz(0.0, y + 0.25, 0.0),
|
||||
));
|
||||
}
|
||||
|
||||
// sky
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(2.0, 1.0, 1.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(2.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("888888").unwrap().into(),
|
||||
unlit: true,
|
||||
cull_mode: None,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_scale(Vec3::splat(1_000_000.0)),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_scale(Vec3::splat(1_000_000.0)),
|
||||
));
|
||||
|
||||
// light
|
||||
commands.spawn((
|
||||
|
|
|
@ -36,16 +36,13 @@ fn setup(
|
|||
// Create and save a handle to the mesh.
|
||||
let cube_mesh_handle: Handle<Mesh> = meshes.add(create_cube_mesh());
|
||||
|
||||
// Render the mesh with the custom texture using a PbrBundle, add the marker.
|
||||
// Render the mesh with the custom texture, and add the marker.
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: cube_mesh_handle,
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color_texture: Some(custom_texture_handle),
|
||||
..default()
|
||||
}),
|
||||
Mesh3d(cube_mesh_handle),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color_texture: Some(custom_texture_handle),
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
CustomUV,
|
||||
));
|
||||
|
||||
|
@ -81,7 +78,7 @@ fn setup(
|
|||
// check out examples/input/ for more examples about user input.
|
||||
fn input_handler(
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
mesh_query: Query<&Handle<Mesh>, With<CustomUV>>,
|
||||
mesh_query: Query<&Mesh3d, With<CustomUV>>,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut query: Query<&mut Transform, With<CustomUV>>,
|
||||
time: Res<Time>,
|
||||
|
|
|
@ -272,13 +272,11 @@ fn spawn_light(commands: &mut Commands) {
|
|||
|
||||
fn spawn_sphere(commands: &mut Commands, assets: &ExampleAssets) {
|
||||
commands
|
||||
.spawn(PbrBundle {
|
||||
mesh: assets.main_sphere.clone(),
|
||||
material: assets.main_sphere_material.clone(),
|
||||
transform: Transform::from_xyz(0.0, SPHERE_SCALE, 0.0)
|
||||
.with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
..default()
|
||||
})
|
||||
.spawn((
|
||||
Mesh3d(assets.main_sphere.clone()),
|
||||
MeshMaterial3d(assets.main_sphere_material.clone()),
|
||||
Transform::from_xyz(0.0, SPHERE_SCALE, 0.0).with_scale(Vec3::splat(SPHERE_SCALE)),
|
||||
))
|
||||
.insert(MainObject);
|
||||
}
|
||||
|
||||
|
@ -390,7 +388,7 @@ fn change_main_object(
|
|||
mut app_status: ResMut<AppStatus>,
|
||||
mut sphere_query: Query<
|
||||
&mut Visibility,
|
||||
(With<MainObject>, With<Handle<Mesh>>, Without<Handle<Scene>>),
|
||||
(With<MainObject>, With<Mesh3d>, Without<Handle<Scene>>),
|
||||
>,
|
||||
mut fox_query: Query<&mut Visibility, (With<MainObject>, With<Handle<Scene>>)>,
|
||||
) {
|
||||
|
@ -597,13 +595,12 @@ fn create_cubes(
|
|||
let uvw = (uvec3(x, y, z).as_vec3() + 0.5) * scale - 0.5;
|
||||
let pos = global_transform.transform_point(uvw);
|
||||
let voxel_cube = commands
|
||||
.spawn(MaterialMeshBundle {
|
||||
mesh: example_assets.voxel_cube.clone(),
|
||||
material: voxel_cube_material.clone(),
|
||||
transform: Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
|
||||
.spawn((
|
||||
Mesh3d(example_assets.voxel_cube.clone()),
|
||||
MeshMaterial3d(voxel_cube_material.clone()),
|
||||
Transform::from_scale(Vec3::splat(VOXEL_CUBE_SCALE))
|
||||
.with_translation(pos),
|
||||
..default()
|
||||
})
|
||||
))
|
||||
.insert(VoxelCube)
|
||||
.insert(NotShadowCaster)
|
||||
.id();
|
||||
|
|
|
@ -39,86 +39,74 @@ fn setup(
|
|||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
// ground plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(10.0, 10.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(10.0, 10.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::WHITE,
|
||||
perceptual_roughness: 1.0,
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
));
|
||||
|
||||
// left wall
|
||||
let mut transform = Transform::from_xyz(2.5, 2.5, 0.0);
|
||||
transform.rotate_z(PI / 2.);
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(5.0, 0.15, 5.0)),
|
||||
transform,
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(5.0, 0.15, 5.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: INDIGO.into(),
|
||||
perceptual_roughness: 1.0,
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
transform,
|
||||
));
|
||||
// back (right) wall
|
||||
let mut transform = Transform::from_xyz(0.0, 2.5, -2.5);
|
||||
transform.rotate_x(PI / 2.);
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(5.0, 0.15, 5.0)),
|
||||
transform,
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(5.0, 0.15, 5.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: INDIGO.into(),
|
||||
perceptual_roughness: 1.0,
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
transform,
|
||||
));
|
||||
|
||||
// Bevy logo to demonstrate alpha mask shadows
|
||||
let mut transform = Transform::from_xyz(-2.2, 0.5, 1.0);
|
||||
transform.rotate_y(PI / 8.);
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Rectangle::new(2.0, 0.5)),
|
||||
transform,
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color_texture: Some(asset_server.load("branding/bevy_logo_light.png")),
|
||||
perceptual_roughness: 1.0,
|
||||
alpha_mode: AlphaMode::Mask(0.5),
|
||||
cull_mode: None,
|
||||
..default()
|
||||
}),
|
||||
Mesh3d(meshes.add(Rectangle::new(2.0, 0.5))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color_texture: Some(asset_server.load("branding/bevy_logo_light.png")),
|
||||
perceptual_roughness: 1.0,
|
||||
alpha_mode: AlphaMode::Mask(0.5),
|
||||
cull_mode: None,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
transform,
|
||||
Movable,
|
||||
));
|
||||
|
||||
// cube
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: DEEP_PINK.into(),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: DEEP_PINK.into(),
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
Movable,
|
||||
));
|
||||
// sphere
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Sphere::new(0.5).mesh().uv(32, 18)),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: LIMEGREEN.into(),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(1.5, 1.0, 1.5),
|
||||
Mesh3d(meshes.add(Sphere::new(0.5).mesh().uv(32, 18))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: LIMEGREEN.into(),
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(1.5, 1.0, 1.5),
|
||||
Movable,
|
||||
));
|
||||
|
||||
|
@ -140,15 +128,14 @@ fn setup(
|
|||
Transform::from_xyz(1.0, 2.0, 0.0),
|
||||
))
|
||||
.with_children(|builder| {
|
||||
builder.spawn(PbrBundle {
|
||||
mesh: meshes.add(Sphere::new(0.1).mesh().uv(32, 18)),
|
||||
material: materials.add(StandardMaterial {
|
||||
builder.spawn((
|
||||
Mesh3d(meshes.add(Sphere::new(0.1).mesh().uv(32, 18))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: RED.into(),
|
||||
emissive: LinearRgba::new(4.0, 0.0, 0.0, 0.0),
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
));
|
||||
});
|
||||
|
||||
// green spot light
|
||||
|
@ -164,18 +151,15 @@ fn setup(
|
|||
},
|
||||
Transform::from_xyz(-1.0, 2.0, 0.0).looking_at(Vec3::new(-1.0, 0.0, 0.0), Vec3::Z),
|
||||
))
|
||||
.with_children(|builder| {
|
||||
builder.spawn(PbrBundle {
|
||||
transform: Transform::from_rotation(Quat::from_rotation_x(PI / 2.0)),
|
||||
mesh: meshes.add(Capsule3d::new(0.1, 0.125)),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: LIME.into(),
|
||||
emissive: LinearRgba::new(0.0, 4.0, 0.0, 0.0),
|
||||
..default()
|
||||
}),
|
||||
.with_child((
|
||||
Mesh3d(meshes.add(Capsule3d::new(0.1, 0.125))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: LIME.into(),
|
||||
emissive: LinearRgba::new(0.0, 4.0, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
});
|
||||
})),
|
||||
Transform::from_rotation(Quat::from_rotation_x(PI / 2.0)),
|
||||
));
|
||||
|
||||
// blue point light
|
||||
commands
|
||||
|
@ -189,15 +173,14 @@ fn setup(
|
|||
Transform::from_xyz(0.0, 4.0, 0.0),
|
||||
))
|
||||
.with_children(|builder| {
|
||||
builder.spawn(PbrBundle {
|
||||
mesh: meshes.add(Sphere::new(0.1).mesh().uv(32, 18)),
|
||||
material: materials.add(StandardMaterial {
|
||||
builder.spawn((
|
||||
Mesh3d(meshes.add(Sphere::new(0.1).mesh().uv(32, 18))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: BLUE.into(),
|
||||
emissive: LinearRgba::new(0.0, 0.0, 713.0, 0.0),
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
));
|
||||
});
|
||||
|
||||
// directional 'sun' light
|
||||
|
|
|
@ -29,8 +29,8 @@ fn add_lightmaps_to_meshes(
|
|||
asset_server: Res<AssetServer>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
meshes: Query<
|
||||
(Entity, &Name, &Handle<StandardMaterial>),
|
||||
(With<Handle<Mesh>>, Without<Lightmap>),
|
||||
(Entity, &Name, &MeshMaterial3d<StandardMaterial>),
|
||||
(With<Mesh3d>, Without<Lightmap>),
|
||||
>,
|
||||
) {
|
||||
let exposure = 250.0;
|
||||
|
|
|
@ -30,35 +30,33 @@ fn setup(
|
|||
mut materials: ResMut<Assets<LineMaterial>>,
|
||||
) {
|
||||
// Spawn a list of lines with start and end points for each lines
|
||||
commands.spawn(MaterialMeshBundle {
|
||||
mesh: meshes.add(LineList {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(LineList {
|
||||
lines: vec![
|
||||
(Vec3::ZERO, Vec3::new(1.0, 1.0, 0.0)),
|
||||
(Vec3::new(1.0, 1.0, 0.0), Vec3::new(1.0, 0.0, 0.0)),
|
||||
],
|
||||
}),
|
||||
transform: Transform::from_xyz(-1.5, 0.0, 0.0),
|
||||
material: materials.add(LineMaterial {
|
||||
})),
|
||||
MeshMaterial3d(materials.add(LineMaterial {
|
||||
color: LinearRgba::GREEN,
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(-1.5, 0.0, 0.0),
|
||||
));
|
||||
|
||||
// Spawn a line strip that goes from point to point
|
||||
commands.spawn(MaterialMeshBundle {
|
||||
mesh: meshes.add(LineStrip {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(LineStrip {
|
||||
points: vec![
|
||||
Vec3::ZERO,
|
||||
Vec3::new(1.0, 1.0, 0.0),
|
||||
Vec3::new(1.0, 0.0, 0.0),
|
||||
],
|
||||
}),
|
||||
transform: Transform::from_xyz(0.5, 0.0, 0.0),
|
||||
material: materials.add(LineMaterial {
|
||||
})),
|
||||
MeshMaterial3d(materials.add(LineMaterial {
|
||||
color: LinearRgba::BLUE,
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(0.5, 0.0, 0.0),
|
||||
));
|
||||
|
||||
// camera
|
||||
commands.spawn(Camera3dBundle {
|
||||
|
|
|
@ -119,15 +119,14 @@ fn setup(
|
|||
});
|
||||
}
|
||||
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
|
||||
material: standard_materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
|
||||
MeshMaterial3d(standard_materials.add(StandardMaterial {
|
||||
base_color: Color::WHITE,
|
||||
perceptual_roughness: 1.0,
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
));
|
||||
}
|
||||
|
||||
#[derive(Asset, TypePath, AsBindGroup, Clone, Default)]
|
||||
|
|
|
@ -76,32 +76,30 @@ fn setup_scene(
|
|||
Transform::default().looking_to(Vec3::new(-1.0, -0.7, -1.0), Vec3::X),
|
||||
));
|
||||
// Sky
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Sphere::default()),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Sphere::default())),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
unlit: true,
|
||||
base_color: Color::linear_rgb(0.1, 0.6, 1.0),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::default().with_scale(Vec3::splat(-4000.0)),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::default().with_scale(Vec3::splat(-4000.0)),
|
||||
));
|
||||
// Ground
|
||||
let mut plane: Mesh = Plane3d::default().into();
|
||||
let uv_size = 4000.0;
|
||||
let uvs = vec![[uv_size, 0.0], [0.0, 0.0], [0.0, uv_size], [uv_size; 2]];
|
||||
plane.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(plane),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(plane)),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::WHITE,
|
||||
perceptual_roughness: 1.0,
|
||||
base_color_texture: Some(images.add(uv_debug_texture())),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(0.0, -0.65, 0.0).with_scale(Vec3::splat(80.)),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(0.0, -0.65, 0.0).with_scale(Vec3::splat(80.)),
|
||||
));
|
||||
|
||||
spawn_cars(&asset_server, &mut meshes, &mut materials, &mut commands);
|
||||
spawn_trees(&mut meshes, &mut materials, &mut commands);
|
||||
|
@ -146,33 +144,25 @@ fn spawn_cars(
|
|||
let color = colors[i % colors.len()].clone();
|
||||
let mut entity = commands
|
||||
.spawn((
|
||||
PbrBundle {
|
||||
mesh: box_mesh.clone(),
|
||||
material: color.clone(),
|
||||
transform: Transform::from_scale(Vec3::splat(0.5)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(box_mesh.clone()),
|
||||
MeshMaterial3d(color.clone()),
|
||||
Transform::from_scale(Vec3::splat(0.5)),
|
||||
Moves(i as f32 * 2.0),
|
||||
))
|
||||
.insert_if(CameraTracked, || i == 0);
|
||||
entity.with_children(|parent| {
|
||||
parent.spawn(PbrBundle {
|
||||
mesh: box_mesh.clone(),
|
||||
material: color,
|
||||
transform: Transform::from_xyz(0.0, 0.08, 0.03)
|
||||
.with_scale(Vec3::new(1.0, 1.0, 0.5)),
|
||||
..default()
|
||||
});
|
||||
parent.spawn((
|
||||
Mesh3d(box_mesh.clone()),
|
||||
MeshMaterial3d(color),
|
||||
Transform::from_xyz(0.0, 0.08, 0.03).with_scale(Vec3::new(1.0, 1.0, 0.5)),
|
||||
));
|
||||
let mut spawn_wheel = |x: f32, z: f32| {
|
||||
parent.spawn((
|
||||
PbrBundle {
|
||||
mesh: cylinder.clone(),
|
||||
material: wheel_matl.clone(),
|
||||
transform: Transform::from_xyz(0.14 * x, -0.045, 0.15 * z)
|
||||
.with_scale(Vec3::new(0.15, 0.04, 0.15))
|
||||
.with_rotation(Quat::from_rotation_z(std::f32::consts::FRAC_PI_2)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(cylinder.clone()),
|
||||
MeshMaterial3d(wheel_matl.clone()),
|
||||
Transform::from_xyz(0.14 * x, -0.045, 0.15 * z)
|
||||
.with_scale(Vec3::new(0.15, 0.04, 0.15))
|
||||
.with_rotation(Quat::from_rotation_z(std::f32::consts::FRAC_PI_2)),
|
||||
Rotates,
|
||||
));
|
||||
};
|
||||
|
@ -202,12 +192,11 @@ fn spawn_barriers(
|
|||
offset,
|
||||
(i as f32) / (N_CONES as f32) * std::f32::consts::PI * 2.0,
|
||||
);
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: capsule.clone(),
|
||||
material: matl.clone(),
|
||||
transform: Transform::from_xyz(pos.x, -0.65, pos.y).with_scale(Vec3::splat(0.07)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(capsule.clone()),
|
||||
MeshMaterial3d(matl.clone()),
|
||||
Transform::from_xyz(pos.x, -0.65, pos.y).with_scale(Vec3::splat(0.07)),
|
||||
));
|
||||
}
|
||||
};
|
||||
spawn_with_offset(0.04);
|
||||
|
@ -232,18 +221,16 @@ fn spawn_trees(
|
|||
(i as f32) / (N_TREES as f32) * std::f32::consts::PI * 2.0,
|
||||
);
|
||||
let [x, z] = pos.into();
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: sphere.clone(),
|
||||
material: leaves.clone(),
|
||||
transform: Transform::from_xyz(x, -0.3, z).with_scale(Vec3::splat(0.3)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: capsule.clone(),
|
||||
material: trunk.clone(),
|
||||
transform: Transform::from_xyz(x, -0.5, z).with_scale(Vec3::new(0.05, 0.3, 0.05)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(sphere.clone()),
|
||||
MeshMaterial3d(leaves.clone()),
|
||||
Transform::from_xyz(x, -0.3, z).with_scale(Vec3::splat(0.3)),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh3d(capsule.clone()),
|
||||
MeshMaterial3d(trunk.clone()),
|
||||
Transform::from_xyz(x, -0.5, z).with_scale(Vec3::new(0.05, 0.3, 0.05)),
|
||||
));
|
||||
}
|
||||
};
|
||||
spawn_with_offset(0.07);
|
||||
|
|
|
@ -28,36 +28,31 @@ fn setup(
|
|||
});
|
||||
|
||||
// plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
));
|
||||
// cubes
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::srgb(0.8, 0.7, 0.6)),
|
||||
transform: Transform::from_xyz(1.5, 0.5, 1.5),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::srgb(0.8, 0.7, 0.6)),
|
||||
transform: Transform::from_xyz(1.5, 0.5, -1.5),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::srgb(0.8, 0.7, 0.6)),
|
||||
transform: Transform::from_xyz(-1.5, 0.5, 1.5),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::srgb(0.8, 0.7, 0.6)),
|
||||
transform: Transform::from_xyz(-1.5, 0.5, -1.5),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
|
||||
Transform::from_xyz(1.5, 0.5, 1.5),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
|
||||
Transform::from_xyz(1.5, 0.5, -1.5),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
|
||||
Transform::from_xyz(-1.5, 0.5, 1.5),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
|
||||
Transform::from_xyz(-1.5, 0.5, -1.5),
|
||||
));
|
||||
// light
|
||||
commands.spawn((PointLight::default(), Transform::from_xyz(3.0, 8.0, 5.0)));
|
||||
}
|
||||
|
|
|
@ -231,22 +231,21 @@ fn setup(
|
|||
.with_children(|commands| {
|
||||
// represent the light source as a sphere
|
||||
let mesh = meshes.add(Sphere::new(0.05).mesh().ico(3).unwrap());
|
||||
commands.spawn(PbrBundle { mesh, ..default() });
|
||||
commands.spawn((Mesh3d(mesh), MeshMaterial3d(materials.add(Color::WHITE))));
|
||||
});
|
||||
|
||||
// Plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(10.0, 10.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(10.0, 10.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
// standard material derived from dark green, but
|
||||
// with roughness and reflectance set.
|
||||
perceptual_roughness: 0.45,
|
||||
reflectance: 0.18,
|
||||
..Color::srgb_u8(0, 80, 0).into()
|
||||
}),
|
||||
transform: Transform::from_xyz(0.0, -1.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(0.0, -1.0, 0.0),
|
||||
));
|
||||
|
||||
let parallax_depth_scale = TargetDepth::default().0;
|
||||
let max_parallax_layer_count = ops::exp2(TargetLayers::default().0);
|
||||
|
@ -264,17 +263,16 @@ fn setup(
|
|||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(
|
||||
Mesh3d(
|
||||
meshes.add(
|
||||
// NOTE: for normal maps and depth maps to work, the mesh
|
||||
// needs tangents generated.
|
||||
Mesh::from(Cuboid::default())
|
||||
.with_generated_tangents()
|
||||
.unwrap(),
|
||||
),
|
||||
material: parallax_material.clone_weak(),
|
||||
..default()
|
||||
},
|
||||
),
|
||||
MeshMaterial3d(parallax_material.clone()),
|
||||
Spin { speed: 0.3 },
|
||||
));
|
||||
|
||||
|
@ -286,12 +284,9 @@ fn setup(
|
|||
|
||||
let background_cube_bundle = |translation| {
|
||||
(
|
||||
PbrBundle {
|
||||
transform: Transform::from_translation(translation),
|
||||
mesh: background_cube.clone(),
|
||||
material: parallax_material.clone(),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(background_cube.clone()),
|
||||
MeshMaterial3d(parallax_material.clone()),
|
||||
Transform::from_translation(translation),
|
||||
Spin { speed: -0.1 },
|
||||
)
|
||||
};
|
||||
|
|
|
@ -37,22 +37,18 @@ fn setup(
|
|||
// parent cube
|
||||
commands
|
||||
.spawn((
|
||||
PbrBundle {
|
||||
mesh: cube_handle.clone(),
|
||||
material: cube_material_handle.clone(),
|
||||
transform: Transform::from_xyz(0.0, 0.0, 1.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(cube_handle.clone()),
|
||||
MeshMaterial3d(cube_material_handle.clone()),
|
||||
Transform::from_xyz(0.0, 0.0, 1.0),
|
||||
Rotator,
|
||||
))
|
||||
.with_children(|parent| {
|
||||
// child cube
|
||||
parent.spawn(PbrBundle {
|
||||
mesh: cube_handle,
|
||||
material: cube_material_handle,
|
||||
transform: Transform::from_xyz(0.0, 0.0, 3.0),
|
||||
..default()
|
||||
});
|
||||
parent.spawn((
|
||||
Mesh3d(cube_handle),
|
||||
MeshMaterial3d(cube_material_handle),
|
||||
Transform::from_xyz(0.0, 0.0, 3.0),
|
||||
));
|
||||
});
|
||||
// light
|
||||
commands.spawn((PointLight::default(), Transform::from_xyz(4.0, 5.0, -4.0)));
|
||||
|
|
|
@ -24,32 +24,30 @@ fn setup(
|
|||
let x01 = (x + 5) as f32 / 10.0;
|
||||
let y01 = (y + 2) as f32 / 4.0;
|
||||
// sphere
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: sphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(sphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("#ffd891").unwrap().into(),
|
||||
// vary key PBR parameters on a grid of spheres to show the effect
|
||||
metallic: y01,
|
||||
perceptual_roughness: x01,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(x as f32, y as f32 + 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(x as f32, y as f32 + 0.5, 0.0),
|
||||
));
|
||||
}
|
||||
}
|
||||
// unlit sphere
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: sphere_mesh,
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(sphere_mesh),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("#ffd891").unwrap().into(),
|
||||
// vary key PBR parameters on a grid of spheres to show the effect
|
||||
unlit: true,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-5.0, -2.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(-5.0, -2.5, 0.0),
|
||||
));
|
||||
|
||||
commands.spawn((
|
||||
DirectionalLight {
|
||||
|
|
|
@ -124,17 +124,15 @@ fn spawn_sphere(
|
|||
let sphere_mesh = meshes.add(Sphere::new(1.0).mesh().ico(7).unwrap());
|
||||
|
||||
// Create a sphere.
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: sphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(sphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Srgba::hex("#ffd891").unwrap().into(),
|
||||
metallic: 1.0,
|
||||
perceptual_roughness: 0.0,
|
||||
..StandardMaterial::default()
|
||||
}),
|
||||
transform: Transform::default(),
|
||||
..PbrBundle::default()
|
||||
});
|
||||
})),
|
||||
));
|
||||
}
|
||||
|
||||
// Spawns the reflection probe.
|
||||
|
|
|
@ -66,12 +66,9 @@ fn setup(
|
|||
|
||||
// The cube that will be rendered to the texture.
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: cube_handle,
|
||||
material: cube_material_handle,
|
||||
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 1.0)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(cube_handle),
|
||||
MeshMaterial3d(cube_material_handle),
|
||||
Transform::from_translation(Vec3::new(0.0, 0.0, 1.0)),
|
||||
FirstPassCube,
|
||||
first_pass_layer.clone(),
|
||||
));
|
||||
|
@ -113,13 +110,9 @@ fn setup(
|
|||
|
||||
// Main pass cube, with material containing the rendered first pass texture.
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: cube_handle,
|
||||
material: material_handle,
|
||||
transform: Transform::from_xyz(0.0, 0.0, 1.5)
|
||||
.with_rotation(Quat::from_rotation_x(-PI / 5.0)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(cube_handle),
|
||||
MeshMaterial3d(material_handle),
|
||||
Transform::from_xyz(0.0, 0.0, 1.5).with_rotation(Quat::from_rotation_x(-PI / 5.0)),
|
||||
MainPassCube,
|
||||
));
|
||||
|
||||
|
|
|
@ -63,9 +63,9 @@ fn spawn_sphere(
|
|||
asset_server: &AssetServer,
|
||||
sphere_mesh: &Handle<Mesh>,
|
||||
) {
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: sphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(sphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
clearcoat: 1.0,
|
||||
clearcoat_perceptual_roughness: 0.3,
|
||||
clearcoat_normal_texture: Some(asset_server.load_with_settings(
|
||||
|
@ -76,10 +76,9 @@ fn spawn_sphere(
|
|||
perceptual_roughness: 0.1,
|
||||
base_color: GOLD.into(),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(0.0, 0.0, 0.0).with_scale(Vec3::splat(1.25)),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(0.0, 0.0, 0.0).with_scale(Vec3::splat(1.25)),
|
||||
));
|
||||
}
|
||||
|
||||
/// Spawns a light.
|
||||
|
|
|
@ -79,24 +79,22 @@ fn setup(
|
|||
));
|
||||
|
||||
// Spawn ground mesh.
|
||||
commands.spawn(PbrBundle {
|
||||
transform: Transform::from_xyz(0.0, -0.5, 0.0),
|
||||
mesh: meshes.add(Cuboid::new(64.0, 1.0, 64.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(64.0, 1.0, 64.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::BLACK,
|
||||
perceptual_roughness: 1.0,
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(0.0, -0.5, 0.0),
|
||||
));
|
||||
|
||||
// Spawn pillar standing between the camera and the sun.
|
||||
commands.spawn(PbrBundle {
|
||||
transform: Transform::from_xyz(-10.0, 4.5, -11.0),
|
||||
mesh: meshes.add(Cuboid::new(2.0, 9.0, 2.0)),
|
||||
material: materials.add(Color::BLACK),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(2.0, 9.0, 2.0))),
|
||||
MeshMaterial3d(materials.add(Color::BLACK)),
|
||||
Transform::from_xyz(-10.0, 4.5, -11.0),
|
||||
));
|
||||
|
||||
// Load a repeating 3d noise texture. Make sure to set ImageAddressMode to Repeat
|
||||
// so that the texture wraps around as the density texture offset is moved along.
|
||||
|
|
|
@ -83,10 +83,10 @@ fn setup(
|
|||
));
|
||||
|
||||
for z_i32 in (-spawn_plane_depth as i32..=0).step_by(2) {
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: sphere_handle.clone(),
|
||||
material: white_handle.clone(),
|
||||
transform: Transform::from_xyz(
|
||||
commands.spawn((
|
||||
Mesh3d(sphere_handle.clone()),
|
||||
MeshMaterial3d(white_handle.clone()),
|
||||
Transform::from_xyz(
|
||||
0.0,
|
||||
if z_i32 % 4 == 0 {
|
||||
spawn_height
|
||||
|
@ -95,17 +95,15 @@ fn setup(
|
|||
},
|
||||
z_i32 as f32,
|
||||
),
|
||||
..default()
|
||||
});
|
||||
));
|
||||
}
|
||||
|
||||
// ground plane
|
||||
let plane_size = 2.0 * spawn_plane_depth;
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(plane_size, plane_size)),
|
||||
material: white_handle,
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(plane_size, plane_size))),
|
||||
MeshMaterial3d(white_handle),
|
||||
));
|
||||
|
||||
let style = TextStyle::default();
|
||||
|
||||
|
|
|
@ -40,42 +40,34 @@ fn setup(
|
|||
let sphere_handle = meshes.add(Sphere::new(sphere_radius));
|
||||
|
||||
// sphere - initially a caster
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: sphere_handle.clone(),
|
||||
material: materials.add(Color::from(RED)),
|
||||
transform: Transform::from_xyz(-1.0, spawn_height, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(sphere_handle.clone()),
|
||||
MeshMaterial3d(materials.add(Color::from(RED))),
|
||||
Transform::from_xyz(-1.0, spawn_height, 0.0),
|
||||
));
|
||||
|
||||
// sphere - initially not a caster
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: sphere_handle,
|
||||
material: materials.add(Color::from(BLUE)),
|
||||
transform: Transform::from_xyz(1.0, spawn_height, 0.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(sphere_handle),
|
||||
MeshMaterial3d(materials.add(Color::from(BLUE))),
|
||||
Transform::from_xyz(1.0, spawn_height, 0.0),
|
||||
NotShadowCaster,
|
||||
));
|
||||
|
||||
// floating plane - initially not a shadow receiver and not a caster
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(20.0, 20.0)),
|
||||
material: materials.add(Color::from(LIME)),
|
||||
transform: Transform::from_xyz(0.0, 1.0, -10.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(20.0, 20.0))),
|
||||
MeshMaterial3d(materials.add(Color::from(LIME))),
|
||||
Transform::from_xyz(0.0, 1.0, -10.0),
|
||||
NotShadowCaster,
|
||||
NotShadowReceiver,
|
||||
));
|
||||
|
||||
// lower ground plane - initially a shadow receiver
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(20.0, 20.0)),
|
||||
material: white_handle,
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(20.0, 20.0))),
|
||||
MeshMaterial3d(white_handle),
|
||||
));
|
||||
|
||||
println!("Using DirectionalLight");
|
||||
|
||||
|
@ -142,10 +134,10 @@ fn toggle_shadows(
|
|||
mut commands: Commands,
|
||||
input: Res<ButtonInput<KeyCode>>,
|
||||
mut queries: ParamSet<(
|
||||
Query<Entity, (With<Handle<Mesh>>, With<NotShadowCaster>)>,
|
||||
Query<Entity, (With<Handle<Mesh>>, With<NotShadowReceiver>)>,
|
||||
Query<Entity, (With<Handle<Mesh>>, Without<NotShadowCaster>)>,
|
||||
Query<Entity, (With<Handle<Mesh>>, Without<NotShadowReceiver>)>,
|
||||
Query<Entity, (With<Mesh3d>, With<NotShadowCaster>)>,
|
||||
Query<Entity, (With<Mesh3d>, With<NotShadowReceiver>)>,
|
||||
Query<Entity, (With<Mesh3d>, Without<NotShadowCaster>)>,
|
||||
Query<Entity, (With<Mesh3d>, Without<NotShadowReceiver>)>,
|
||||
)>,
|
||||
) {
|
||||
if input.just_pressed(KeyCode::KeyC) {
|
||||
|
|
|
@ -25,15 +25,14 @@ fn setup(
|
|||
});
|
||||
|
||||
// plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(100.0, 100.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.2, 0.2, 0.2),
|
||||
perceptual_roughness: 0.08,
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
));
|
||||
|
||||
const COUNT: usize = 6;
|
||||
let position_range = -2.0..2.0;
|
||||
|
@ -48,17 +47,16 @@ fn setup(
|
|||
|
||||
// sphere light
|
||||
commands
|
||||
.spawn(PbrBundle {
|
||||
mesh: mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
.spawn((
|
||||
Mesh3d(mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.5, 0.5, 1.0),
|
||||
unlit: true,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(position_range.start + percent * pos_len, 0.3, 0.0)
|
||||
})),
|
||||
Transform::from_xyz(position_range.start + percent * pos_len, 0.3, 0.0)
|
||||
.with_scale(Vec3::splat(radius)),
|
||||
..default()
|
||||
})
|
||||
))
|
||||
.with_child(PointLight {
|
||||
radius,
|
||||
color: Color::srgb(0.2, 0.2, 1.0),
|
||||
|
|
|
@ -22,11 +22,10 @@ fn setup(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
// plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(100.0, 100.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
));
|
||||
|
||||
commands.spawn(SceneBundle {
|
||||
scene: asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/animated/Fox.glb")),
|
||||
|
|
|
@ -41,11 +41,8 @@ fn setup(
|
|||
) {
|
||||
// ground plane
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)),
|
||||
material: materials.add(Color::WHITE),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(100.0, 100.0))),
|
||||
MeshMaterial3d(materials.add(Color::WHITE)),
|
||||
Movable,
|
||||
));
|
||||
|
||||
|
@ -64,12 +61,9 @@ fn setup(
|
|||
let z = rng.gen_range(-5.0..5.0);
|
||||
|
||||
(
|
||||
PbrBundle {
|
||||
mesh: cube_mesh.clone(),
|
||||
material: blue.clone(),
|
||||
transform: Transform::from_xyz(x, y, z),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(cube_mesh.clone()),
|
||||
MeshMaterial3d(blue.clone()),
|
||||
Transform::from_xyz(x, y, z),
|
||||
Movable,
|
||||
)
|
||||
})
|
||||
|
@ -108,18 +102,14 @@ fn setup(
|
|||
.looking_at(Vec3::new(1.0 + x, 0.0, z), Vec3::X),
|
||||
))
|
||||
.with_children(|builder| {
|
||||
builder.spawn(PbrBundle {
|
||||
mesh: sphere_mesh.clone(),
|
||||
material: red_emissive.clone(),
|
||||
..default()
|
||||
});
|
||||
builder.spawn((
|
||||
PbrBundle {
|
||||
transform: Transform::from_translation(Vec3::Z * -0.1),
|
||||
mesh: sphere_mesh_direction.clone(),
|
||||
material: maroon_emissive.clone(),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(sphere_mesh.clone()),
|
||||
MeshMaterial3d(red_emissive.clone()),
|
||||
));
|
||||
builder.spawn((
|
||||
Mesh3d(sphere_mesh_direction.clone()),
|
||||
MeshMaterial3d(maroon_emissive.clone()),
|
||||
Transform::from_translation(Vec3::Z * -0.1),
|
||||
NotShadowCaster,
|
||||
));
|
||||
});
|
||||
|
|
|
@ -48,35 +48,29 @@ fn setup(
|
|||
reflectance: 0.0,
|
||||
..default()
|
||||
});
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: material.clone(),
|
||||
transform: Transform::from_xyz(0.0, 0.0, 1.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: material.clone(),
|
||||
transform: Transform::from_xyz(0.0, -1.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material,
|
||||
transform: Transform::from_xyz(1.0, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Sphere::new(0.4).mesh().uv(72, 36)),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.4, 0.4, 0.4),
|
||||
perceptual_roughness: 1.0,
|
||||
reflectance: 0.0,
|
||||
..default()
|
||||
}),
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(material.clone()),
|
||||
Transform::from_xyz(0.0, 0.0, 1.0),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(material.clone()),
|
||||
Transform::from_xyz(0.0, -1.0, 0.0),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(material),
|
||||
Transform::from_xyz(1.0, 0.0, 0.0),
|
||||
));
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Sphere::new(0.4).mesh().uv(72, 36))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.4, 0.4, 0.4),
|
||||
perceptual_roughness: 1.0,
|
||||
reflectance: 0.0,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
SphereMarker,
|
||||
));
|
||||
|
||||
|
|
|
@ -149,16 +149,15 @@ fn spawn_cube(
|
|||
standard_materials: &mut Assets<StandardMaterial>,
|
||||
) {
|
||||
commands
|
||||
.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
|
||||
material: standard_materials.add(StandardMaterial {
|
||||
.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(standard_materials.add(StandardMaterial {
|
||||
base_color: Color::from(WHITE),
|
||||
base_color_texture: Some(asset_server.load("branding/icon.png")),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
})
|
||||
})),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
))
|
||||
.insert(CubeModel);
|
||||
}
|
||||
|
||||
|
@ -182,9 +181,9 @@ fn spawn_water(
|
|||
meshes: &mut Assets<Mesh>,
|
||||
water_materials: &mut Assets<ExtendedMaterial<StandardMaterial, Water>>,
|
||||
) {
|
||||
commands.spawn(MaterialMeshBundle {
|
||||
mesh: meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0))),
|
||||
material: water_materials.add(ExtendedMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(1.0)))),
|
||||
MeshMaterial3d(water_materials.add(ExtendedMaterial {
|
||||
base: StandardMaterial {
|
||||
base_color: BLACK.into(),
|
||||
perceptual_roughness: 0.0,
|
||||
|
@ -215,10 +214,9 @@ fn spawn_water(
|
|||
octave_strengths: vec4(0.16, 0.18, 0.093, 0.044),
|
||||
},
|
||||
},
|
||||
}),
|
||||
transform: Transform::from_scale(Vec3::splat(100.0)),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_scale(Vec3::splat(100.0)),
|
||||
));
|
||||
}
|
||||
|
||||
// Spawns the camera.
|
||||
|
|
|
@ -53,28 +53,23 @@ fn setup(
|
|||
});
|
||||
|
||||
// textured quad - normal
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: quad_handle.clone(),
|
||||
material: material_handle,
|
||||
transform: Transform::from_xyz(0.0, 0.0, 1.5)
|
||||
.with_rotation(Quat::from_rotation_x(-PI / 5.0)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(quad_handle.clone()),
|
||||
MeshMaterial3d(material_handle),
|
||||
Transform::from_xyz(0.0, 0.0, 1.5).with_rotation(Quat::from_rotation_x(-PI / 5.0)),
|
||||
));
|
||||
// textured quad - modulated
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: quad_handle.clone(),
|
||||
material: red_material_handle,
|
||||
transform: Transform::from_rotation(Quat::from_rotation_x(-PI / 5.0)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(quad_handle.clone()),
|
||||
MeshMaterial3d(red_material_handle),
|
||||
Transform::from_rotation(Quat::from_rotation_x(-PI / 5.0)),
|
||||
));
|
||||
// textured quad - modulated
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: quad_handle,
|
||||
material: blue_material_handle,
|
||||
transform: Transform::from_xyz(0.0, 0.0, -1.5)
|
||||
.with_rotation(Quat::from_rotation_x(-PI / 5.0)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(quad_handle),
|
||||
MeshMaterial3d(blue_material_handle),
|
||||
Transform::from_xyz(0.0, 0.0, -1.5).with_rotation(Quat::from_rotation_x(-PI / 5.0)),
|
||||
));
|
||||
// camera
|
||||
commands.spawn(Camera3dBundle {
|
||||
transform: Transform::from_xyz(3.0, 5.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
|
||||
|
|
|
@ -144,13 +144,10 @@ fn setup_color_gradient_scene(
|
|||
transform.translation += *transform.forward();
|
||||
|
||||
commands.spawn((
|
||||
MaterialMeshBundle {
|
||||
mesh: meshes.add(Rectangle::new(0.7, 0.7)),
|
||||
material: materials.add(ColorGradientMaterial {}),
|
||||
transform,
|
||||
visibility: Visibility::Hidden,
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Rectangle::new(0.7, 0.7))),
|
||||
MeshMaterial3d(materials.add(ColorGradientMaterial {})),
|
||||
transform,
|
||||
Visibility::Hidden,
|
||||
SceneNumber(2),
|
||||
));
|
||||
}
|
||||
|
@ -166,17 +163,14 @@ fn setup_image_viewer_scene(
|
|||
|
||||
// exr/hdr viewer (exr requires enabling bevy feature)
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Rectangle::default()),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color_texture: None,
|
||||
unlit: true,
|
||||
..default()
|
||||
}),
|
||||
transform,
|
||||
visibility: Visibility::Hidden,
|
||||
Mesh3d(meshes.add(Rectangle::default())),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color_texture: None,
|
||||
unlit: true,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
transform,
|
||||
Visibility::Hidden,
|
||||
SceneNumber(3),
|
||||
HDRViewer,
|
||||
));
|
||||
|
@ -205,7 +199,7 @@ fn setup_image_viewer_scene(
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
fn drag_drop_image(
|
||||
image_mat: Query<&Handle<StandardMaterial>, With<HDRViewer>>,
|
||||
image_mat: Query<&MeshMaterial3d<StandardMaterial>, With<HDRViewer>>,
|
||||
text: Query<Entity, (With<Text>, With<SceneNumber>)>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
mut drop_events: EventReader<FileDragAndDrop>,
|
||||
|
@ -234,7 +228,7 @@ fn drag_drop_image(
|
|||
}
|
||||
|
||||
fn resize_image(
|
||||
image_mesh: Query<(&Handle<StandardMaterial>, &Handle<Mesh>), With<HDRViewer>>,
|
||||
image_mesh: Query<(&MeshMaterial3d<StandardMaterial>, &Mesh3d), With<HDRViewer>>,
|
||||
materials: Res<Assets<StandardMaterial>>,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
images: Res<Assets<Image>>,
|
||||
|
|
|
@ -77,17 +77,14 @@ fn setup(
|
|||
|
||||
// Cube #1
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: cube_mesh.clone(),
|
||||
material: materials.add(StandardMaterial::default()),
|
||||
transform: Transform::from_xyz(0.25, 0.5, -2.0).with_rotation(Quat::from_euler(
|
||||
EulerRot::XYZ,
|
||||
1.4,
|
||||
3.7,
|
||||
21.3,
|
||||
)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(cube_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial::default())),
|
||||
Transform::from_xyz(0.25, 0.5, -2.0).with_rotation(Quat::from_euler(
|
||||
EulerRot::XYZ,
|
||||
1.4,
|
||||
3.7,
|
||||
21.3,
|
||||
)),
|
||||
ExampleControls {
|
||||
color: true,
|
||||
specular_transmission: false,
|
||||
|
@ -97,17 +94,14 @@ fn setup(
|
|||
|
||||
// Cube #2
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: cube_mesh,
|
||||
material: materials.add(StandardMaterial::default()),
|
||||
transform: Transform::from_xyz(-0.75, 0.7, -2.0).with_rotation(Quat::from_euler(
|
||||
EulerRot::XYZ,
|
||||
0.4,
|
||||
2.3,
|
||||
4.7,
|
||||
)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(cube_mesh),
|
||||
MeshMaterial3d(materials.add(StandardMaterial::default())),
|
||||
Transform::from_xyz(-0.75, 0.7, -2.0).with_rotation(Quat::from_euler(
|
||||
EulerRot::XYZ,
|
||||
0.4,
|
||||
2.3,
|
||||
4.7,
|
||||
)),
|
||||
ExampleControls {
|
||||
color: true,
|
||||
specular_transmission: false,
|
||||
|
@ -117,18 +111,15 @@ fn setup(
|
|||
|
||||
// Candle
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: cylinder_mesh,
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.9, 0.2, 0.3),
|
||||
diffuse_transmission: 0.7,
|
||||
perceptual_roughness: 0.32,
|
||||
thickness: 0.2,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-1.0, 0.0, 0.0),
|
||||
Mesh3d(cylinder_mesh),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.9, 0.2, 0.3),
|
||||
diffuse_transmission: 0.7,
|
||||
perceptual_roughness: 0.32,
|
||||
thickness: 0.2,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(-1.0, 0.0, 0.0),
|
||||
ExampleControls {
|
||||
color: true,
|
||||
specular_transmission: false,
|
||||
|
@ -147,36 +138,30 @@ fn setup(
|
|||
};
|
||||
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
emissive,
|
||||
diffuse_transmission: 1.0,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-1.0, 1.15, 0.0).with_scale(Vec3::new(0.1, 0.2, 0.1)),
|
||||
Mesh3d(icosphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
emissive,
|
||||
diffuse_transmission: 1.0,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(-1.0, 1.15, 0.0).with_scale(Vec3::new(0.1, 0.2, 0.1)),
|
||||
Flicker,
|
||||
NotShadowCaster,
|
||||
));
|
||||
|
||||
// Glass Sphere
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::WHITE,
|
||||
specular_transmission: 0.9,
|
||||
diffuse_transmission: 1.0,
|
||||
thickness: 1.8,
|
||||
ior: 1.5,
|
||||
perceptual_roughness: 0.12,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(1.0, 0.0, 0.0),
|
||||
Mesh3d(icosphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::WHITE,
|
||||
specular_transmission: 0.9,
|
||||
diffuse_transmission: 1.0,
|
||||
thickness: 1.8,
|
||||
ior: 1.5,
|
||||
perceptual_roughness: 0.12,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(1.0, 0.0, 0.0),
|
||||
ExampleControls {
|
||||
color: true,
|
||||
specular_transmission: true,
|
||||
|
@ -186,20 +171,17 @@ fn setup(
|
|||
|
||||
// R Sphere
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: RED.into(),
|
||||
specular_transmission: 0.9,
|
||||
diffuse_transmission: 1.0,
|
||||
thickness: 1.8,
|
||||
ior: 1.5,
|
||||
perceptual_roughness: 0.12,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(1.0, -0.5, 2.0).with_scale(Vec3::splat(0.5)),
|
||||
Mesh3d(icosphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: RED.into(),
|
||||
specular_transmission: 0.9,
|
||||
diffuse_transmission: 1.0,
|
||||
thickness: 1.8,
|
||||
ior: 1.5,
|
||||
perceptual_roughness: 0.12,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(1.0, -0.5, 2.0).with_scale(Vec3::splat(0.5)),
|
||||
ExampleControls {
|
||||
color: true,
|
||||
specular_transmission: true,
|
||||
|
@ -209,20 +191,17 @@ fn setup(
|
|||
|
||||
// G Sphere
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh.clone(),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: LIME.into(),
|
||||
specular_transmission: 0.9,
|
||||
diffuse_transmission: 1.0,
|
||||
thickness: 1.8,
|
||||
ior: 1.5,
|
||||
perceptual_roughness: 0.12,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(0.0, -0.5, 2.0).with_scale(Vec3::splat(0.5)),
|
||||
Mesh3d(icosphere_mesh.clone()),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: LIME.into(),
|
||||
specular_transmission: 0.9,
|
||||
diffuse_transmission: 1.0,
|
||||
thickness: 1.8,
|
||||
ior: 1.5,
|
||||
perceptual_roughness: 0.12,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(0.0, -0.5, 2.0).with_scale(Vec3::splat(0.5)),
|
||||
ExampleControls {
|
||||
color: true,
|
||||
specular_transmission: true,
|
||||
|
@ -232,20 +211,17 @@ fn setup(
|
|||
|
||||
// B Sphere
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: icosphere_mesh,
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: BLUE.into(),
|
||||
specular_transmission: 0.9,
|
||||
diffuse_transmission: 1.0,
|
||||
thickness: 1.8,
|
||||
ior: 1.5,
|
||||
perceptual_roughness: 0.12,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-1.0, -0.5, 2.0).with_scale(Vec3::splat(0.5)),
|
||||
Mesh3d(icosphere_mesh),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: BLUE.into(),
|
||||
specular_transmission: 0.9,
|
||||
diffuse_transmission: 1.0,
|
||||
thickness: 1.8,
|
||||
ior: 1.5,
|
||||
perceptual_roughness: 0.12,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(-1.0, -0.5, 2.0).with_scale(Vec3::splat(0.5)),
|
||||
ExampleControls {
|
||||
color: true,
|
||||
specular_transmission: true,
|
||||
|
@ -271,16 +247,13 @@ fn setup(
|
|||
for x in -3..4 {
|
||||
for z in -3..4 {
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: plane_mesh.clone(),
|
||||
material: if (x + z) % 2 == 0 {
|
||||
black_material.clone()
|
||||
} else {
|
||||
white_material.clone()
|
||||
},
|
||||
transform: Transform::from_xyz(x as f32 * 2.0, -1.0, z as f32 * 2.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(plane_mesh.clone()),
|
||||
MeshMaterial3d(if (x + z) % 2 == 0 {
|
||||
black_material.clone()
|
||||
} else {
|
||||
white_material.clone()
|
||||
}),
|
||||
Transform::from_xyz(x as f32 * 2.0, -1.0, z as f32 * 2.0),
|
||||
ExampleControls {
|
||||
color: true,
|
||||
specular_transmission: false,
|
||||
|
@ -292,22 +265,19 @@ fn setup(
|
|||
|
||||
// Paper
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: plane_mesh,
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::WHITE,
|
||||
diffuse_transmission: 0.6,
|
||||
perceptual_roughness: 0.8,
|
||||
reflectance: 1.0,
|
||||
double_sided: true,
|
||||
cull_mode: None,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(0.0, 0.5, -3.0)
|
||||
.with_scale(Vec3::new(2.0, 1.0, 1.0))
|
||||
.with_rotation(Quat::from_euler(EulerRot::XYZ, PI / 2.0, 0.0, 0.0)),
|
||||
Mesh3d(plane_mesh),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::WHITE,
|
||||
diffuse_transmission: 0.6,
|
||||
perceptual_roughness: 0.8,
|
||||
reflectance: 1.0,
|
||||
double_sided: true,
|
||||
cull_mode: None,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
Transform::from_xyz(0.0, 0.5, -3.0)
|
||||
.with_scale(Vec3::new(2.0, 1.0, 1.0))
|
||||
.with_rotation(Quat::from_euler(EulerRot::XYZ, PI / 2.0, 0.0, 0.0)),
|
||||
TransmittedShadowReceiver,
|
||||
ExampleControls {
|
||||
specular_transmission: false,
|
||||
|
@ -419,7 +389,7 @@ impl Default for ExampleState {
|
|||
fn example_control_system(
|
||||
mut commands: Commands,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
controllable: Query<(&Handle<StandardMaterial>, &ExampleControls)>,
|
||||
controllable: Query<(&MeshMaterial3d<StandardMaterial>, &ExampleControls)>,
|
||||
mut camera: Query<
|
||||
(
|
||||
Entity,
|
||||
|
@ -635,8 +605,8 @@ fn example_control_system(
|
|||
}
|
||||
|
||||
fn flicker_system(
|
||||
mut flame: Query<&mut Transform, (With<Flicker>, With<Handle<Mesh>>)>,
|
||||
mut light: Query<(&mut PointLight, &mut Transform), (With<Flicker>, Without<Handle<Mesh>>)>,
|
||||
mut flame: Query<&mut Transform, (With<Flicker>, With<Mesh3d>)>,
|
||||
mut light: Query<(&mut PointLight, &mut Transform), (With<Flicker>, Without<Mesh3d>)>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let s = time.elapsed_seconds();
|
||||
|
|
|
@ -18,16 +18,15 @@ fn setup(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
// Opaque plane, uses `alpha_mode: Opaque` by default
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(6.0, 6.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(6.0, 6.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
));
|
||||
|
||||
// Transparent sphere, uses `alpha_mode: Mask(f32)`
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap()),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap())),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
// Alpha channel of the color controls transparency.
|
||||
// We set it to 0.0 here, because it will be changed over time in the
|
||||
// `fade_transparency` function.
|
||||
|
@ -37,54 +36,49 @@ fn setup(
|
|||
// alpha values above are fully opaque.
|
||||
alpha_mode: AlphaMode::Mask(0.5),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(1.0, 0.5, -1.5),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(1.0, 0.5, -1.5),
|
||||
));
|
||||
|
||||
// Transparent unlit sphere, uses `alpha_mode: Mask(f32)`
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap()),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap())),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::srgba(0.2, 0.7, 0.1, 0.0),
|
||||
alpha_mode: AlphaMode::Mask(0.5),
|
||||
unlit: true,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-1.0, 0.5, -1.5),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(-1.0, 0.5, -1.5),
|
||||
));
|
||||
|
||||
// Transparent cube, uses `alpha_mode: Blend`
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
// Notice how there is no need to set the `alpha_mode` explicitly here.
|
||||
// When converting a color to a material using `into()`, the alpha mode is
|
||||
// automatically set to `Blend` if the alpha channel is anything lower than 1.0.
|
||||
material: materials.add(Color::srgba(0.5, 0.5, 1.0, 0.0)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
MeshMaterial3d(materials.add(Color::srgba(0.5, 0.5, 1.0, 0.0))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
|
||||
// Transparent cube, uses `alpha_mode: AlphaToCoverage`
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::srgba(0.5, 1.0, 0.5, 0.0),
|
||||
alpha_mode: AlphaMode::AlphaToCoverage,
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-1.5, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(-1.5, 0.5, 0.0),
|
||||
));
|
||||
|
||||
// Opaque sphere
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap()),
|
||||
material: materials.add(Color::srgb(0.7, 0.2, 0.1)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, -1.5),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap())),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.7, 0.2, 0.1))),
|
||||
Transform::from_xyz(0.0, 0.5, -1.5),
|
||||
));
|
||||
|
||||
// Light
|
||||
commands.spawn((
|
||||
|
|
|
@ -16,19 +16,17 @@ fn setup(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
// Plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
));
|
||||
|
||||
// Cube
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::srgb(0.8, 0.7, 0.6)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
|
||||
// Light
|
||||
commands.spawn((
|
||||
|
|
|
@ -16,11 +16,10 @@ fn setup(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
// plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
));
|
||||
// cube
|
||||
// Assign vertex colors based on vertex positions
|
||||
let mut colorful_cube = Mesh::from(Cuboid::default());
|
||||
|
@ -33,15 +32,14 @@ fn setup(
|
|||
.collect();
|
||||
colorful_cube.insert_attribute(Mesh::ATTRIBUTE_COLOR, colors);
|
||||
}
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(colorful_cube),
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(colorful_cube)),
|
||||
// This is the default color, but note that vertex colors are
|
||||
// multiplied by the base color, so you'll likely want this to be
|
||||
// white if using vertex colors.
|
||||
material: materials.add(Color::srgb(1., 1., 1.)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
MeshMaterial3d(materials.add(Color::srgb(1., 1., 1.))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
|
||||
// Light
|
||||
commands.spawn((
|
||||
|
|
|
@ -94,11 +94,10 @@ fn setup(
|
|||
app_status: Res<AppStatus>,
|
||||
) {
|
||||
// Spawn a plane.
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)),
|
||||
material: materials.add(Color::srgb(0.1, 0.2, 0.1)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(50.0, 50.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.1, 0.2, 0.1))),
|
||||
));
|
||||
|
||||
// Spawn the two HLODs.
|
||||
|
||||
|
@ -170,7 +169,7 @@ fn setup(
|
|||
// component as appropriate.
|
||||
fn set_visibility_ranges(
|
||||
mut commands: Commands,
|
||||
mut new_meshes: Query<Entity, Added<Handle<Mesh>>>,
|
||||
mut new_meshes: Query<Entity, Added<Mesh3d>>,
|
||||
parents: Query<(Option<&Parent>, Option<&MainModel>)>,
|
||||
) {
|
||||
// Loop over each newly-added mesh.
|
||||
|
|
|
@ -56,29 +56,22 @@ fn setup(
|
|||
) {
|
||||
// Red cube: Never renders a wireframe
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::from(RED)),
|
||||
transform: Transform::from_xyz(-1.0, 0.5, -1.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::from(RED))),
|
||||
Transform::from_xyz(-1.0, 0.5, -1.0),
|
||||
NoWireframe,
|
||||
));
|
||||
// Orange cube: Follows global wireframe setting
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::from(ORANGE)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::from(ORANGE))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
// Green cube: Always renders a wireframe
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::from(LIME)),
|
||||
transform: Transform::from_xyz(1.0, 0.5, 1.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::from(LIME))),
|
||||
Transform::from_xyz(1.0, 0.5, 1.0),
|
||||
Wireframe,
|
||||
// This lets you configure the wireframe color of this entity.
|
||||
// If not set, this will use the color in `WireframeConfig`
|
||||
|
@ -87,11 +80,8 @@ fn setup(
|
|||
|
||||
// plane
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
|
||||
material: materials.add(Color::from(BLUE)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
|
||||
MeshMaterial3d(materials.add(Color::from(BLUE))),
|
||||
// You can insert this component without the `Wireframe` component
|
||||
// to override the color of the global wireframe for this mesh
|
||||
WireframeColor {
|
||||
|
|
|
@ -59,11 +59,10 @@ fn setup(
|
|||
});
|
||||
|
||||
// Plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(500000.0, 500000.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(500000.0, 500000.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
));
|
||||
|
||||
// Light
|
||||
commands.spawn((
|
||||
|
|
|
@ -134,11 +134,8 @@ fn setup(
|
|||
// First entity is the planet
|
||||
let planet_entity = commands
|
||||
.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Sphere::default()),
|
||||
material: materials.add(Color::srgb(0.8, 0.7, 0.6)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Sphere::default())),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
|
||||
// Add the animation graph and player
|
||||
planet,
|
||||
graphs.add(graph),
|
||||
|
@ -164,12 +161,9 @@ fn setup(
|
|||
.with_children(|p| {
|
||||
// The satellite, placed at a distance of the planet
|
||||
p.spawn((
|
||||
PbrBundle {
|
||||
transform: Transform::from_xyz(1.5, 0.0, 0.0),
|
||||
mesh: meshes.add(Cuboid::new(0.5, 0.5, 0.5)),
|
||||
material: materials.add(Color::srgb(0.3, 0.9, 0.3)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Cuboid::new(0.5, 0.5, 0.5))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.9, 0.3))),
|
||||
Transform::from_xyz(1.5, 0.0, 0.0),
|
||||
AnimationTarget {
|
||||
id: satellite_animation_target_id,
|
||||
player: planet_entity,
|
||||
|
|
|
@ -240,12 +240,11 @@ fn setup_scene(
|
|||
|
||||
// Ground
|
||||
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Circle::new(7.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
transform: Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Circle::new(7.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||
));
|
||||
}
|
||||
|
||||
/// Places the help text at the top left of the window.
|
||||
|
|
|
@ -125,12 +125,11 @@ fn setup_scene(
|
|||
});
|
||||
|
||||
// Spawn the ground.
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Circle::new(7.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
transform: Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Circle::new(7.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||
));
|
||||
}
|
||||
|
||||
// Creates the UI.
|
||||
|
|
|
@ -38,12 +38,9 @@ fn setup(
|
|||
|
||||
// Spawning a cube to experiment on
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::from(ORANGE)),
|
||||
transform: Transform::from_translation(points[0][0]),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::from(ORANGE))),
|
||||
Transform::from_translation(points[0][0]),
|
||||
Curve(bezier),
|
||||
));
|
||||
|
||||
|
@ -59,11 +56,10 @@ fn setup(
|
|||
));
|
||||
|
||||
// ground plane
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50., 50.)),
|
||||
material: materials.add(Color::from(SILVER)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(50., 50.))),
|
||||
MeshMaterial3d(materials.add(Color::from(SILVER))),
|
||||
));
|
||||
|
||||
// The camera
|
||||
commands.spawn(Camera3dBundle {
|
||||
|
|
|
@ -142,15 +142,12 @@ fn setup(
|
|||
|
||||
// Create skinned mesh renderer. Note that its transform doesn't affect the position of the mesh.
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: mesh.clone(),
|
||||
material: materials.add(Color::srgb(
|
||||
rng.gen_range(0.0..1.0),
|
||||
rng.gen_range(0.0..1.0),
|
||||
rng.gen_range(0.0..1.0),
|
||||
)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(mesh.clone()),
|
||||
MeshMaterial3d(materials.add(Color::srgb(
|
||||
rng.gen_range(0.0..1.0),
|
||||
rng.gen_range(0.0..1.0),
|
||||
rng.gen_range(0.0..1.0),
|
||||
))),
|
||||
SkinnedMesh {
|
||||
inverse_bindposes: inverse_bindposes.clone(),
|
||||
joints: joint_entities,
|
||||
|
|
|
@ -37,8 +37,8 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
///
|
||||
/// ```text
|
||||
/// <Parent entity>
|
||||
/// + Mesh node (without `PbrBundle` or `SkinnedMesh` component)
|
||||
/// + Skinned mesh entity (with `PbrBundle` and `SkinnedMesh` component, created by glTF loader)
|
||||
/// + Mesh node (without `Mesh3d` or `SkinnedMesh` component)
|
||||
/// + Skinned mesh entity (with `Mesh3d` and `SkinnedMesh` component, created by glTF loader)
|
||||
/// + First joint
|
||||
/// + Second joint
|
||||
/// ```
|
||||
|
|
|
@ -160,19 +160,17 @@ fn setup(
|
|||
|
||||
// Scene example for non black box picture
|
||||
// circular base
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Circle::new(4.0)),
|
||||
material: materials.add(Color::WHITE),
|
||||
transform: Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Circle::new(4.0))),
|
||||
MeshMaterial3d(materials.add(Color::WHITE)),
|
||||
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
|
||||
));
|
||||
// cube
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
|
||||
material: materials.add(Color::srgb_u8(124, 144, 255)),
|
||||
transform: Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
|
||||
Transform::from_xyz(0.0, 0.5, 0.0),
|
||||
));
|
||||
// light
|
||||
commands.spawn((
|
||||
PointLight {
|
||||
|
|
|
@ -104,23 +104,17 @@ fn setup(
|
|||
commands.spawn((
|
||||
Left,
|
||||
Name::new("Left Shape"),
|
||||
PbrBundle {
|
||||
mesh: left_shape_model,
|
||||
material: material_handle.clone(),
|
||||
transform: Transform::from_xyz(-3.0, 0.0, 0.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(left_shape_model),
|
||||
MeshMaterial3d(material_handle.clone()),
|
||||
Transform::from_xyz(-3.0, 0.0, 0.0),
|
||||
left_shape,
|
||||
));
|
||||
|
||||
commands.spawn((
|
||||
Name::new("Right Shape"),
|
||||
PbrBundle {
|
||||
mesh: right_shape_model,
|
||||
material: material_handle,
|
||||
transform: Transform::from_xyz(3.0, 0.0, 0.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(right_shape_model),
|
||||
MeshMaterial3d(material_handle),
|
||||
Transform::from_xyz(3.0, 0.0, 0.0),
|
||||
right_shape,
|
||||
));
|
||||
|
||||
|
@ -168,11 +162,11 @@ fn spawn_text(mut commands: Commands) {
|
|||
|
||||
fn alter_handle(
|
||||
asset_server: Res<AssetServer>,
|
||||
mut right_shape: Query<(&mut Handle<Mesh>, &mut Shape), Without<Left>>,
|
||||
mut right_shape: Query<(&mut Mesh3d, &mut Shape), Without<Left>>,
|
||||
) {
|
||||
// Mesh handles, like other parts of the ECS, can be queried as mutable and modified at
|
||||
// runtime. We only spawned one shape without the `Left` marker component.
|
||||
let Ok((mut handle, mut shape)) = right_shape.get_single_mut() else {
|
||||
let Ok((mut mesh, mut shape)) = right_shape.get_single_mut() else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -182,7 +176,7 @@ fn alter_handle(
|
|||
// Modify the handle associated with the Shape on the right side. Note that we will only
|
||||
// have to load the same path from storage media once: repeated attempts will re-use the
|
||||
// asset.
|
||||
*handle = asset_server.load(
|
||||
mesh.0 = asset_server.load(
|
||||
GltfAssetLabel::Primitive {
|
||||
mesh: 0,
|
||||
primitive: 0,
|
||||
|
@ -193,7 +187,7 @@ fn alter_handle(
|
|||
|
||||
fn alter_mesh(
|
||||
mut is_mesh_scaled: Local<bool>,
|
||||
left_shape: Query<&Handle<Mesh>, With<Left>>,
|
||||
left_shape: Query<&Mesh3d, With<Left>>,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
) {
|
||||
// It's convenient to retrieve the asset handle stored with the shape on the left. However,
|
||||
|
|
|
@ -73,26 +73,23 @@ fn setup(
|
|||
});
|
||||
|
||||
// torus
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: torus_handle,
|
||||
material: material_handle.clone(),
|
||||
transform: Transform::from_xyz(-3.0, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(torus_handle),
|
||||
MeshMaterial3d(material_handle.clone()),
|
||||
Transform::from_xyz(-3.0, 0.0, 0.0),
|
||||
));
|
||||
// cube
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: cube_handle,
|
||||
material: material_handle.clone(),
|
||||
transform: Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(cube_handle),
|
||||
MeshMaterial3d(material_handle.clone()),
|
||||
Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
));
|
||||
// sphere
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: sphere_handle,
|
||||
material: material_handle,
|
||||
transform: Transform::from_xyz(3.0, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(sphere_handle),
|
||||
MeshMaterial3d(material_handle),
|
||||
Transform::from_xyz(3.0, 0.0, 0.0),
|
||||
));
|
||||
// light
|
||||
commands.spawn((PointLight::default(), Transform::from_xyz(4.0, 5.0, 4.0)));
|
||||
// camera
|
||||
|
|
|
@ -224,11 +224,8 @@ fn setup_scene(
|
|||
|
||||
// Plane
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50000.0, 50000.0)),
|
||||
material: materials.add(Color::srgb(0.7, 0.2, 0.2)),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(50000.0, 50000.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.7, 0.2, 0.2))),
|
||||
Loading,
|
||||
));
|
||||
}
|
||||
|
@ -250,12 +247,11 @@ fn wait_on_load(
|
|||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
// Change color of plane to green
|
||||
commands.spawn((PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(50000.0, 50000.0)),
|
||||
material: materials.add(Color::srgb(0.3, 0.5, 0.3)),
|
||||
transform: Transform::from_translation(Vec3::Z * -0.01),
|
||||
..default()
|
||||
},));
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(50000.0, 50000.0))),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
||||
Transform::from_translation(Vec3::Z * -0.01),
|
||||
));
|
||||
|
||||
// Spawn our scenes.
|
||||
for i in 0..10 {
|
||||
|
|
|
@ -26,20 +26,19 @@ fn setup(
|
|||
asset_server.load("textures/fantasy_ui_borders/panel-border-010.png");
|
||||
|
||||
// central cube with not repeated texture
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color_texture: Some(image_with_default_sampler.clone()),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_translation(Vec3::ZERO),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_translation(Vec3::ZERO),
|
||||
));
|
||||
|
||||
// left cube with repeated texture
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color_texture: Some(asset_server.load_with_settings(
|
||||
"textures/fantasy_ui_borders/panel-border-010-repeated.png",
|
||||
|s: &mut _| {
|
||||
|
@ -59,15 +58,14 @@ fn setup(
|
|||
// that's why you can use rotation and shift also
|
||||
uv_transform: Affine2::from_scale(Vec2::new(2., 3.)),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(-1.5, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(-1.5, 0.0, 0.0),
|
||||
));
|
||||
|
||||
// right cube with scaled texture, because with default sampler
|
||||
commands.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
// there is no sampler set, that's why
|
||||
// by default you see only one small image in a row/column
|
||||
// and other space is filled by image edge
|
||||
|
@ -77,10 +75,9 @@ fn setup(
|
|||
// that's why you can use rotation and shift also
|
||||
uv_transform: Affine2::from_scale(Vec2::new(2., 3.)),
|
||||
..default()
|
||||
}),
|
||||
transform: Transform::from_xyz(1.5, 0.0, 0.0),
|
||||
..default()
|
||||
});
|
||||
})),
|
||||
Transform::from_xyz(1.5, 0.0, 0.0),
|
||||
));
|
||||
|
||||
// light
|
||||
commands.spawn((
|
||||
|
|
|
@ -84,13 +84,12 @@ fn spawn_tasks(mut commands: Commands) {
|
|||
|
||||
world
|
||||
.entity_mut(entity)
|
||||
// Add our new PbrBundle of components to our tagged entity
|
||||
.insert(PbrBundle {
|
||||
mesh: box_mesh_handle,
|
||||
material: box_material_handle,
|
||||
// Add our new `Mesh3d` and `MeshMaterial3d` to our tagged entity
|
||||
.insert((
|
||||
Mesh3d(box_mesh_handle),
|
||||
MeshMaterial3d(box_material_handle),
|
||||
transform,
|
||||
..default()
|
||||
})
|
||||
))
|
||||
// Task is complete, so remove task component from entity
|
||||
.remove::<ComputeTransform>();
|
||||
});
|
||||
|
@ -107,7 +106,7 @@ fn spawn_tasks(mut commands: Commands) {
|
|||
|
||||
/// This system queries for entities that have our Task<Transform> component. It polls the
|
||||
/// tasks to see if they're complete. If the task is complete it takes the result, adds a
|
||||
/// new [`PbrBundle`] of components to the entity using the result from the task's work, and
|
||||
/// new [`Mesh3d`] and [`MeshMaterial3d`] to the entity using the result from the task's work, and
|
||||
/// removes the task component from the entity.
|
||||
fn handle_tasks(mut commands: Commands, mut transform_tasks: Query<&mut ComputeTransform>) {
|
||||
for mut task in &mut transform_tasks {
|
||||
|
|
|
@ -3,7 +3,6 @@ use bevy::{
|
|||
audio::{AudioPlugin, SpatialScale},
|
||||
color::palettes::css::*,
|
||||
prelude::*,
|
||||
sprite::MaterialMesh2dBundle,
|
||||
};
|
||||
|
||||
/// Spatial audio uses the distance to attenuate the sound volume. In 2D with the default camera,
|
||||
|
@ -34,12 +33,9 @@ fn setup(
|
|||
|
||||
// sound emitter
|
||||
commands.spawn((
|
||||
MaterialMesh2dBundle {
|
||||
mesh: meshes.add(Circle::new(15.0)).into(),
|
||||
material: materials.add(Color::from(BLUE)),
|
||||
transform: Transform::from_translation(Vec3::new(0.0, 50.0, 0.0)),
|
||||
..default()
|
||||
},
|
||||
Mesh2d(meshes.add(Circle::new(15.0))),
|
||||
MeshMaterial2d(materials.add(Color::from(BLUE))),
|
||||
Transform::from_translation(Vec3::new(0.0, 50.0, 0.0)),
|
||||
Emitter::default(),
|
||||
AudioBundle {
|
||||
source: asset_server.load("sounds/Windless Slopes.ogg"),
|
||||
|
|
|
@ -24,12 +24,9 @@ fn setup(
|
|||
|
||||
// sound emitter
|
||||
commands.spawn((
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Sphere::new(0.2).mesh().uv(32, 18)),
|
||||
material: materials.add(Color::from(BLUE)),
|
||||
transform: Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Sphere::new(0.2).mesh().uv(32, 18))),
|
||||
MeshMaterial3d(materials.add(Color::from(BLUE))),
|
||||
Transform::from_xyz(0.0, 0.0, 0.0),
|
||||
Emitter::default(),
|
||||
AudioBundle {
|
||||
source: asset_server.load("sounds/Windless Slopes.ogg"),
|
||||
|
@ -42,20 +39,18 @@ fn setup(
|
|||
.spawn((SpatialBundle::default(), listener.clone()))
|
||||
.with_children(|parent| {
|
||||
// left ear indicator
|
||||
parent.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(0.2, 0.2, 0.2)),
|
||||
material: materials.add(Color::from(RED)),
|
||||
transform: Transform::from_translation(listener.left_ear_offset),
|
||||
..default()
|
||||
});
|
||||
parent.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(0.2, 0.2, 0.2))),
|
||||
MeshMaterial3d(materials.add(Color::from(RED))),
|
||||
Transform::from_translation(listener.left_ear_offset),
|
||||
));
|
||||
|
||||
// right ear indicator
|
||||
parent.spawn(PbrBundle {
|
||||
mesh: meshes.add(Cuboid::new(0.2, 0.2, 0.2)),
|
||||
material: materials.add(Color::from(LIME)),
|
||||
transform: Transform::from_translation(listener.right_ear_offset),
|
||||
..default()
|
||||
});
|
||||
parent.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::new(0.2, 0.2, 0.2))),
|
||||
MeshMaterial3d(materials.add(Color::from(LIME))),
|
||||
Transform::from_translation(listener.right_ear_offset),
|
||||
));
|
||||
});
|
||||
|
||||
// light
|
||||
|
|
|
@ -9,12 +9,7 @@
|
|||
//! | `A` | Move left |
|
||||
//! | `D` | Move right |
|
||||
|
||||
use bevy::{
|
||||
core_pipeline::bloom::Bloom,
|
||||
math::vec3,
|
||||
prelude::*,
|
||||
sprite::{MaterialMesh2dBundle, Mesh2dHandle},
|
||||
};
|
||||
use bevy::{core_pipeline::bloom::Bloom, prelude::*};
|
||||
|
||||
/// Player movement speed factor.
|
||||
const PLAYER_SPEED: f32 = 100.;
|
||||
|
@ -39,24 +34,17 @@ fn setup_scene(
|
|||
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||
) {
|
||||
// World where we move the player
|
||||
commands.spawn(MaterialMesh2dBundle {
|
||||
mesh: Mesh2dHandle(meshes.add(Rectangle::new(1000., 700.))),
|
||||
material: materials.add(Color::srgb(0.2, 0.2, 0.3)),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh2d(meshes.add(Rectangle::new(1000., 700.))),
|
||||
MeshMaterial2d(materials.add(Color::srgb(0.2, 0.2, 0.3))),
|
||||
));
|
||||
|
||||
// Player
|
||||
commands.spawn((
|
||||
Player,
|
||||
MaterialMesh2dBundle {
|
||||
mesh: meshes.add(Circle::new(25.)).into(),
|
||||
material: materials.add(Color::srgb(6.25, 9.4, 9.1)), // RGB values exceed 1 to achieve a bright color for the bloom effect
|
||||
transform: Transform {
|
||||
translation: vec3(0., 0., 2.),
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
},
|
||||
Mesh2d(meshes.add(Circle::new(25.))),
|
||||
MeshMaterial2d(materials.add(Color::srgb(6.25, 9.4, 9.1))), // RGB values exceed 1 to achieve a bright color for the bloom effect
|
||||
Transform::from_xyz(0., 0., 2.),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -58,26 +58,20 @@ fn setup(
|
|||
|
||||
commands.spawn((
|
||||
Name::new("Plane"),
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.3, 0.5, 0.3),
|
||||
// Turning off culling keeps the plane visible when viewed from beneath.
|
||||
cull_mode: None,
|
||||
..default()
|
||||
}),
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.3, 0.5, 0.3),
|
||||
// Turning off culling keeps the plane visible when viewed from beneath.
|
||||
cull_mode: None,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
));
|
||||
|
||||
commands.spawn((
|
||||
Name::new("Cube"),
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Cuboid::default()),
|
||||
material: materials.add(Color::srgb(0.8, 0.7, 0.6)),
|
||||
transform: Transform::from_xyz(1.5, 0.51, 1.5),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(meshes.add(Cuboid::default())),
|
||||
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
|
||||
Transform::from_xyz(1.5, 0.51, 1.5),
|
||||
));
|
||||
|
||||
commands.spawn((
|
||||
|
|
|
@ -147,12 +147,9 @@ fn spawn_view_model(
|
|||
|
||||
// Spawn the player's right arm.
|
||||
parent.spawn((
|
||||
MaterialMeshBundle {
|
||||
mesh: arm,
|
||||
material: arm_material,
|
||||
transform: Transform::from_xyz(0.2, -0.1, -0.25),
|
||||
..default()
|
||||
},
|
||||
Mesh3d(arm),
|
||||
MeshMaterial3d(arm_material),
|
||||
Transform::from_xyz(0.2, -0.1, -0.25),
|
||||
// Ensure the arm is only rendered by the view model camera.
|
||||
RenderLayers::layer(VIEW_MODEL_RENDER_LAYER),
|
||||
// The arm is free-floating, so shadows would look weird.
|
||||
|
@ -173,25 +170,19 @@ fn spawn_world_model(
|
|||
// The world model camera will render the floor and the cubes spawned in this system.
|
||||
// Assigning no `RenderLayers` component defaults to layer 0.
|
||||
|
||||
commands.spawn(MaterialMeshBundle {
|
||||
mesh: floor,
|
||||
material: material.clone(),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((Mesh3d(floor), MeshMaterial3d(material.clone())));
|
||||
|
||||
commands.spawn(MaterialMeshBundle {
|
||||
mesh: cube.clone(),
|
||||
material: material.clone(),
|
||||
transform: Transform::from_xyz(0.0, 0.25, -3.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(cube.clone()),
|
||||
MeshMaterial3d(material.clone()),
|
||||
Transform::from_xyz(0.0, 0.25, -3.0),
|
||||
));
|
||||
|
||||
commands.spawn(MaterialMeshBundle {
|
||||
mesh: cube,
|
||||
material,
|
||||
transform: Transform::from_xyz(0.75, 1.75, 0.0),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
Mesh3d(cube),
|
||||
MeshMaterial3d(material),
|
||||
Transform::from_xyz(0.75, 1.75, 0.0),
|
||||
));
|
||||
}
|
||||
|
||||
fn spawn_lights(mut commands: Commands) {
|
||||
|
|
|
@ -67,16 +67,13 @@ fn setup(
|
|||
|
||||
commands.spawn((
|
||||
Name::new("Plane"),
|
||||
PbrBundle {
|
||||
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.3, 0.5, 0.3),
|
||||
// Turning off culling keeps the plane visible when viewed from beneath.
|
||||
cull_mode: None,
|
||||
..default()
|
||||
}),
|
||||
Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
|
||||
MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: Color::srgb(0.3, 0.5, 0.3),
|
||||
// Turning off culling keeps the plane visible when viewed from beneath.
|
||||
cull_mode: None,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
));
|
||||
|
||||
commands.spawn((
|
||||
|
|
|
@ -28,7 +28,8 @@ struct Star;
|
|||
|
||||
#[derive(Bundle, Default)]
|
||||
struct BodyBundle {
|
||||
pbr: PbrBundle,
|
||||
mesh: Mesh3d,
|
||||
material: MeshMaterial3d<StandardMaterial>,
|
||||
mass: Mass,
|
||||
last_pos: LastPos,
|
||||
acceleration: Acceleration,
|
||||
|
@ -61,32 +62,31 @@ fn generate_bodies(
|
|||
* ops::cbrt(rng.gen_range(0.2f32..1.0))
|
||||
* 15.;
|
||||
|
||||
commands.spawn(BodyBundle {
|
||||
pbr: PbrBundle {
|
||||
transform: Transform {
|
||||
translation: position,
|
||||
scale: Vec3::splat(radius),
|
||||
..default()
|
||||
},
|
||||
mesh: mesh.clone(),
|
||||
material: materials.add(Color::srgb(
|
||||
commands.spawn((
|
||||
BodyBundle {
|
||||
mesh: Mesh3d(mesh.clone()),
|
||||
material: MeshMaterial3d(materials.add(Color::srgb(
|
||||
rng.gen_range(color_range.clone()),
|
||||
rng.gen_range(color_range.clone()),
|
||||
rng.gen_range(color_range.clone()),
|
||||
)),
|
||||
))),
|
||||
mass: Mass(mass_value),
|
||||
acceleration: Acceleration(Vec3::ZERO),
|
||||
last_pos: LastPos(
|
||||
position
|
||||
- Vec3::new(
|
||||
rng.gen_range(vel_range.clone()),
|
||||
rng.gen_range(vel_range.clone()),
|
||||
rng.gen_range(vel_range.clone()),
|
||||
) * time.timestep().as_secs_f32(),
|
||||
),
|
||||
},
|
||||
Transform {
|
||||
translation: position,
|
||||
scale: Vec3::splat(radius),
|
||||
..default()
|
||||
},
|
||||
mass: Mass(mass_value),
|
||||
acceleration: Acceleration(Vec3::ZERO),
|
||||
last_pos: LastPos(
|
||||
position
|
||||
- Vec3::new(
|
||||
rng.gen_range(vel_range.clone()),
|
||||
rng.gen_range(vel_range.clone()),
|
||||
rng.gen_range(vel_range.clone()),
|
||||
) * time.timestep().as_secs_f32(),
|
||||
),
|
||||
});
|
||||
));
|
||||
}
|
||||
|
||||
// add bigger "star" body in the center
|
||||
|
@ -94,19 +94,17 @@ fn generate_bodies(
|
|||
commands
|
||||
.spawn((
|
||||
BodyBundle {
|
||||
pbr: PbrBundle {
|
||||
transform: Transform::from_scale(Vec3::splat(star_radius)),
|
||||
mesh: meshes.add(Sphere::new(1.0).mesh().ico(5).unwrap()),
|
||||
material: materials.add(StandardMaterial {
|
||||
base_color: ORANGE_RED.into(),
|
||||
emissive: LinearRgba::from(ORANGE_RED) * 2.,
|
||||
..default()
|
||||
}),
|
||||
mesh: Mesh3d(meshes.add(Sphere::new(1.0).mesh().ico(5).unwrap())),
|
||||
material: MeshMaterial3d(materials.add(StandardMaterial {
|
||||
base_color: ORANGE_RED.into(),
|
||||
emissive: LinearRgba::from(ORANGE_RED) * 2.,
|
||||
..default()
|
||||
},
|
||||
})),
|
||||
|
||||
mass: Mass(500.0),
|
||||
..default()
|
||||
},
|
||||
Transform::from_scale(Vec3::splat(star_radius)),
|
||||
Star,
|
||||
))
|
||||
.with_child(PointLight {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue