turn material into resource, removed SharedMaterial

This commit is contained in:
Dmitry Stepanov
2023-11-14 18:26:46 +03:00
parent 5648235afe
commit eca96ae7ed
26 changed files with 523 additions and 480 deletions
+2 -2
View File
@@ -47,7 +47,7 @@ use fyrox::{
BuildContext, HorizontalAlignment, Orientation, RcUiNodeHandle, Thickness, UiNode,
UserInterface, VerticalAlignment, BRUSH_DARK,
},
material::{Material, PropertyValue, SharedMaterial},
material::{Material, MaterialResource, PropertyValue},
resource::texture::Texture,
scene::{
base::BaseBuilder,
@@ -518,7 +518,7 @@ impl AssetBrowser {
fallback: Default::default(),
},
));
let material = SharedMaterial::new(material);
let material = MaterialResource::new(material);
let graph = &mut engine.scenes[self.preview.scene()].graph;
let quad = MeshBuilder::new(BaseBuilder::new())
+9 -9
View File
@@ -21,7 +21,7 @@ use fyrox::{
widget::{Widget, WidgetBuilder},
BuildContext, Control, Thickness, UiNode, UserInterface, VerticalAlignment,
},
material::SharedMaterial,
material::MaterialResource,
};
use std::{
any::{Any, TypeId},
@@ -31,11 +31,11 @@ use std::{
#[derive(Debug, Clone, PartialEq)]
pub enum MaterialFieldMessage {
Material(SharedMaterial),
Material(MaterialResource),
}
impl MaterialFieldMessage {
define_constructor!(MaterialFieldMessage:Material => fn material(SharedMaterial), layout: false);
define_constructor!(MaterialFieldMessage:Material => fn material(MaterialResource), layout: false);
}
#[derive(Clone, Visit, Reflect)]
@@ -47,7 +47,7 @@ pub struct MaterialFieldEditor {
text: Handle<UiNode>,
edit: Handle<UiNode>,
make_unique: Handle<UiNode>,
material: SharedMaterial,
material: MaterialResource,
}
impl Debug for MaterialFieldEditor {
@@ -116,7 +116,7 @@ pub struct MaterialFieldEditorBuilder {
widget_builder: WidgetBuilder,
}
fn make_name(material: &SharedMaterial) -> String {
fn make_name(material: &MaterialResource) -> String {
let name = material.lock().shader().data_ref().definition.name.clone();
format!("{} - {} uses", name, material.use_count())
}
@@ -130,7 +130,7 @@ impl MaterialFieldEditorBuilder {
self,
ctx: &mut BuildContext,
sender: MessageSender,
material: SharedMaterial,
material: MaterialResource,
) -> Handle<UiNode> {
let edit;
let text;
@@ -212,14 +212,14 @@ pub struct MaterialPropertyEditorDefinition {
impl PropertyEditorDefinition for MaterialPropertyEditorDefinition {
fn value_type_id(&self) -> TypeId {
TypeId::of::<SharedMaterial>()
TypeId::of::<MaterialResource>()
}
fn create_instance(
&self,
ctx: PropertyEditorBuildContext,
) -> Result<PropertyEditorInstance, InspectorError> {
let value = ctx.property_info.cast_value::<SharedMaterial>()?;
let value = ctx.property_info.cast_value::<MaterialResource>()?;
Ok(PropertyEditorInstance::Simple {
editor: MaterialFieldEditorBuilder::new(WidgetBuilder::new()).build(
ctx.build_context,
@@ -233,7 +233,7 @@ impl PropertyEditorDefinition for MaterialPropertyEditorDefinition {
&self,
ctx: PropertyEditorMessageContext,
) -> Result<Option<UiMessage>, InspectorError> {
let value = ctx.property_info.cast_value::<SharedMaterial>()?;
let value = ctx.property_info.cast_value::<MaterialResource>()?;
Ok(Some(MaterialFieldMessage::material(
ctx.instance,
MessageDirection::ToWidget,
+2 -2
View File
@@ -42,7 +42,7 @@ use fyrox::{
},
material::{
shader::{Shader, ShaderResource},
SharedMaterial,
MaterialResource,
},
renderer::framework::state::PolygonFillMode,
resource::{
@@ -140,7 +140,7 @@ pub fn make_property_editors_container(sender: MessageSender) -> PropertyEditorD
container.insert(MaterialPropertyEditorDefinition {
sender: Mutex::new(sender.clone()),
});
container.insert(InheritablePropertyEditorDefinition::<SharedMaterial>::new());
container.insert(InheritablePropertyEditorDefinition::<MaterialResource>::new());
container.register_inheritable_vec_collection::<Handle<Node>>();
container.insert(NodeHandlePropertyEditorDefinition::new(sender.clone()));
+6 -6
View File
@@ -119,7 +119,7 @@ use fyrox::{
},
material::{
shader::{ShaderResource, ShaderResourceExtension},
Material, PropertyValue, SharedMaterial,
Material, MaterialResource, PropertyValue,
},
plugin::PluginConstructor,
resource::texture::{
@@ -179,7 +179,7 @@ lazy_static! {
};
}
pub fn make_color_material(color: Color) -> SharedMaterial {
pub fn make_color_material(color: Color) -> MaterialResource {
let mut material = Material::from_shader(GIZMO_SHADER.clone(), None);
material
.set_property(
@@ -187,7 +187,7 @@ pub fn make_color_material(color: Color) -> SharedMaterial {
PropertyValue::Color(color),
)
.unwrap();
SharedMaterial::new(material)
MaterialResource::new(material)
}
pub fn set_mesh_diffuse_color(mesh: &mut Mesh, color: Color) {
@@ -203,7 +203,7 @@ pub fn set_mesh_diffuse_color(mesh: &mut Mesh, color: Color) {
}
}
pub fn create_terrain_layer_material() -> SharedMaterial {
pub fn create_terrain_layer_material() -> MaterialResource {
let mut material = Material::standard_terrain();
material
.set_property(
@@ -211,7 +211,7 @@ pub fn create_terrain_layer_material() -> SharedMaterial {
PropertyValue::Vector2(Vector2::new(10.0, 10.0)),
)
.unwrap();
SharedMaterial::new(material)
MaterialResource::new(material)
}
#[derive(Debug)]
@@ -2032,7 +2032,7 @@ impl Editor {
}
}
fn open_material_editor(&mut self, material: SharedMaterial) {
fn open_material_editor(&mut self, material: MaterialResource) {
let engine = &mut self.engine;
self.material_editor.set_material(Some(material), engine);
+3 -3
View File
@@ -39,7 +39,7 @@ use fyrox::{
window::{WindowBuilder, WindowTitle},
BuildContext, RcUiNodeHandle, Thickness, UiNode, UserInterface, VerticalAlignment,
},
material::{shader::Shader, PropertyValue, SharedMaterial},
material::{shader::Shader, MaterialResource, PropertyValue},
resource::texture::Texture,
scene::{
base::BaseBuilder,
@@ -87,7 +87,7 @@ pub struct MaterialEditor {
properties_panel: Handle<UiNode>,
properties: BiDirHashMap<ImmutableString, Handle<UiNode>>,
preview: PreviewPanel,
material: Option<SharedMaterial>,
material: Option<MaterialResource>,
shader: Handle<UiNode>,
texture_context_menu: TextureContextMenu,
}
@@ -323,7 +323,7 @@ impl MaterialEditor {
}
}
pub fn set_material(&mut self, material: Option<SharedMaterial>, engine: &mut Engine) {
pub fn set_material(&mut self, material: Option<MaterialResource>, engine: &mut Engine) {
self.material = material;
if let Some(material) = self.material.clone() {
+2 -2
View File
@@ -8,7 +8,7 @@ use fyrox::{
pool::{ErasedHandle, Handle},
},
gui::UiNode,
material::SharedMaterial,
material::MaterialResource,
scene::{camera::Projection, node::Node, Scene},
};
use std::{any::TypeId, path::PathBuf, sync::mpsc::Sender};
@@ -39,7 +39,7 @@ pub enum Message {
OpenSettings,
OpenAnimationEditor,
OpenAbsmEditor,
OpenMaterialEditor(SharedMaterial),
OpenMaterialEditor(MaterialResource),
OpenNodeRemovalDialog,
ShowInAssetBrowser(PathBuf),
SetWorldViewerFilter(String),
+5 -5
View File
@@ -1,18 +1,18 @@
use crate::{command::Command, scene::commands::SceneContext};
use fyrox::{
core::sstorage::ImmutableString,
material::{shader::ShaderResource, Material, PropertyValue, SharedMaterial},
material::{shader::ShaderResource, Material, MaterialResource, PropertyValue},
};
#[derive(Debug)]
pub struct SetMaterialPropertyValueCommand {
material: SharedMaterial,
material: MaterialResource,
name: ImmutableString,
value: PropertyValue,
}
impl SetMaterialPropertyValueCommand {
pub fn new(material: SharedMaterial, name: ImmutableString, value: PropertyValue) -> Self {
pub fn new(material: MaterialResource, name: ImmutableString, value: PropertyValue) -> Self {
Self {
material,
name,
@@ -55,12 +55,12 @@ enum SetMaterialShaderCommandState {
#[derive(Debug)]
pub struct SetMaterialShaderCommand {
material: SharedMaterial,
material: MaterialResource,
state: SetMaterialShaderCommandState,
}
impl SetMaterialShaderCommand {
pub fn new(material: SharedMaterial, shader: ShaderResource) -> Self {
pub fn new(material: MaterialResource, shader: ShaderResource) -> Self {
Self {
material,
state: SetMaterialShaderCommandState::NonExecuted { new_shader: shader },
+2 -2
View File
@@ -7,7 +7,7 @@ use fyrox::{
sstorage::ImmutableString,
},
engine::Engine,
material::{Material, PropertyValue, SharedMaterial},
material::{Material, MaterialResource, PropertyValue},
resource::texture::{TextureResource, TextureResourceExtension},
scene::{
base::BaseBuilder,
@@ -64,7 +64,7 @@ fn make_cone(transform: Matrix4<f32>, color: Color, graph: &mut Graph) -> Handle
.with_surfaces(vec![SurfaceBuilder::new(SurfaceSharedData::new(
SurfaceData::make_cone(16, 0.3, 1.0, &transform),
))
.with_material(SharedMaterial::new(material))
.with_material(MaterialResource::new(material))
.build()])
.build(graph)
}
+2 -2
View File
@@ -14,7 +14,7 @@ use fyrox::{
engine::{executor::Executor, GraphicsContextParams},
event::{ElementState, Event, WindowEvent},
event_loop::EventLoop,
material::{Material, PropertyValue, SharedMaterial},
material::{Material, MaterialResource, PropertyValue},
plugin::{Plugin, PluginConstructor, PluginContext},
resource::texture::Texture,
scene::{
@@ -58,7 +58,7 @@ impl SceneLoader {
},
)
.unwrap();
let material = SharedMaterial::new(material);
let material = MaterialResource::new(material);
// Add some sprites.
for y in 0..10 {
+3 -3
View File
@@ -12,7 +12,7 @@ use fyrox::{
event::{ElementState, Event, WindowEvent},
event_loop::EventLoop,
keyboard::KeyCode,
material::{Material, PropertyValue, SharedMaterial},
material::{Material, MaterialResource, PropertyValue},
plugin::{Plugin, PluginConstructor, PluginContext},
resource::model::{Model, ModelResourceExtension},
scene::{
@@ -77,7 +77,7 @@ async fn create_scene(resource_manager: ResourceManager) -> GameScene {
.with_surfaces(vec![SurfaceBuilder::new(SurfaceSharedData::new(
SurfaceData::make_sphere(10, 10, 0.1, &Matrix4::identity()),
))
.with_material(SharedMaterial::new(cursor_material))
.with_material(MaterialResource::new(cursor_material))
.build()])
.build(&mut scene.graph);
@@ -99,7 +99,7 @@ async fn create_scene(resource_manager: ResourceManager) -> GameScene {
.with_surfaces(vec![SurfaceBuilder::new(SurfaceSharedData::new(
SurfaceData::make_sphere(10, 10, 0.2, &Matrix4::identity()),
))
.with_material(SharedMaterial::new(agent_material))
.with_material(MaterialResource::new(agent_material))
.build()])
.build(&mut scene.graph);
+61 -58
View File
@@ -5,25 +5,27 @@
#![warn(missing_docs)]
use crate::{
asset::{manager::ResourceManager, ResourceStateRef},
asset::{manager::ResourceManager, Resource, ResourceData, ResourceStateRef},
core::{
algebra::{Matrix2, Matrix3, Matrix4, Vector2, Vector3, Vector4},
color::Color,
log::Log,
parking_lot::{Mutex, MutexGuard},
reflect::prelude::*,
sstorage::ImmutableString,
uuid::{uuid, Uuid},
visitor::prelude::*,
TypeUuidProvider,
},
material::shader::{PropertyKind, SamplerFallback, ShaderResource, ShaderResourceExtension},
resource::texture::{Texture, TextureResource},
};
use fxhash::FxHashMap;
use std::{
any::Any,
borrow::Cow,
fmt::{Display, Formatter},
hash::{Hash, Hasher},
ops::Deref,
sync::Arc,
path::{Path, PathBuf},
};
pub mod shader;
@@ -387,12 +389,52 @@ impl Default for PropertyValue {
/// As you can see it is only a bit more hard that with the standard shader. The main difference here is
/// that we using resource manager to get shader instance and the we just use the instance to create
/// material instance. Then we populate properties as usual.
#[derive(Default, Debug, Visit, Clone, Reflect)]
#[derive(Debug, Visit, Clone, Reflect)]
pub struct Material {
#[visit(optional)]
path: PathBuf,
shader: ShaderResource,
properties: FxHashMap<ImmutableString, PropertyValue>,
}
impl Default for Material {
fn default() -> Self {
Material::standard()
}
}
impl TypeUuidProvider for Material {
fn type_uuid() -> Uuid {
uuid!("0e54fe44-0c58-4108-a681-d6eefc88c234")
}
}
impl ResourceData for Material {
fn path(&self) -> Cow<Path> {
Cow::Borrowed(&self.path)
}
fn set_path(&mut self, path: PathBuf) {
self.path = path;
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn type_uuid(&self) -> Uuid {
<Self as TypeUuidProvider>::type_uuid()
}
fn is_procedural(&self) -> bool {
false
}
}
/// A set of possible errors that can occur when working with materials.
#[derive(Clone, Debug)]
pub enum MaterialError {
@@ -540,6 +582,7 @@ impl Material {
drop(data);
Self {
path: Default::default(),
shader,
properties: property_values,
}
@@ -767,61 +810,21 @@ impl Material {
/// Shared material is also tells a renderer that this material can be used for efficient rendering -
/// the renderer will be able to optimize rendering when it knows that multiple objects share the
/// same material.
#[derive(Reflect, Clone, Debug)]
pub struct SharedMaterial(Arc<Mutex<Material>>);
pub type MaterialResource = Resource<Material>;
impl Default for SharedMaterial {
fn default() -> Self {
Self::new(Material::standard())
}
pub trait MaterialResourceExtension {
fn deep_copy(&self) -> MaterialResource;
}
impl PartialEq for SharedMaterial {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.0, &other.0)
}
}
impl Eq for SharedMaterial {}
impl Hash for SharedMaterial {
fn hash<H: Hasher>(&self, state: &mut H) {
let ptr_num = &*self.0 as *const _ as u64;
ptr_num.hash(state);
}
}
impl Visit for SharedMaterial {
fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
self.0.visit(name, visitor)
}
}
impl SharedMaterial {
/// Creates new shared material from a material instance.
pub fn new(material: Material) -> Self {
Self(Arc::new(Mutex::new(material)))
}
/// Provides access to inner material.
pub fn lock(&self) -> MutexGuard<'_, Material> {
self.0.lock()
}
/// Returns unique id of the material. The id is not stable across multiple runs of an application!
pub fn key(&self) -> u64 {
&*self.0 as *const _ as u64
}
/// Returns total use count of the material.
pub fn use_count(&self) -> usize {
Arc::strong_count(&self.0)
}
/// Creates a deep copy of shared material, making "unique" clone of the underlying material.
/// It is useful when you need to create unique version of a material and set its properties
/// to some specific values and assign it to an object.
pub fn deep_copy(&self) -> Self {
Self::new(self.0.lock().clone())
impl MaterialResourceExtension for MaterialResource {
fn deep_copy(&self) -> MaterialResource {
let material_state = self.state();
match material_state.get() {
ResourceStateRef::Pending { path, .. } => MaterialResource::new_pending(path.clone()),
ResourceStateRef::LoadError { path, error, .. } => {
MaterialResource::new_load_error(path.clone(), error.clone())
}
ResourceStateRef::Ok(material) => MaterialResource::new_ok(material.clone()),
}
}
}
+6 -6
View File
@@ -7,7 +7,7 @@ use crate::{
pool::Handle,
sstorage::ImmutableString,
},
material::SharedMaterial,
material::MaterialResource,
renderer::{cache::geometry::TimeToLive, framework::geometry_buffer::ElementRange},
scene::{
graph::Graph,
@@ -119,7 +119,7 @@ pub struct RenderDataBatch {
/// A set of instances.
pub instances: Vec<SurfaceInstanceData>,
/// A material that is shared across all instances.
pub material: SharedMaterial,
pub material: MaterialResource,
/// Whether the batch is using GPU skinning or not.
pub is_skinned: bool,
/// A render path of the batch.
@@ -239,7 +239,7 @@ impl RenderDataBatchStorage {
&mut self,
vertices: impl Iterator<Item = T>,
local_triangles: impl Iterator<Item = TriangleDefinition>,
material: &SharedMaterial,
material: &MaterialResource,
render_path: RenderPath,
decal_layer_index: u8,
sort_index: u64,
@@ -249,7 +249,7 @@ impl RenderDataBatchStorage {
T: VertexTrait,
{
let mut hasher = FxHasher::default();
hasher.write_u64(material.key());
hasher.write_u64(material.key() as u64);
TypeId::of::<T>().hash(&mut hasher);
hasher.write_u8(if is_skinned { 1 } else { 0 });
hasher.write_u8(decal_layer_index);
@@ -320,7 +320,7 @@ impl RenderDataBatchStorage {
pub fn push(
&mut self,
data: &SurfaceSharedData,
material: &SharedMaterial,
material: &MaterialResource,
render_path: RenderPath,
decal_layer_index: u8,
sort_index: u64,
@@ -329,7 +329,7 @@ impl RenderDataBatchStorage {
let is_skinned = !instance_data.bone_matrices.is_empty();
let mut hasher = FxHasher::default();
hasher.write_u64(material.key());
hasher.write_u64(material.key() as u64);
hasher.write_u64(data.key());
hasher.write_u8(if is_skinned { 1 } else { 0 });
hasher.write_u8(decal_layer_index);
+61 -58
View File
@@ -33,6 +33,7 @@ use crate::{
},
};
use fyrox_core::math::Matrix4Ext;
use fyrox_resource::ResourceStateRef;
use std::{cell::RefCell, rc::Rc};
pub(crate) struct ForwardRenderer {
@@ -155,66 +156,68 @@ impl ForwardRenderer {
.iter()
.filter(|b| b.render_path == RenderPath::Forward)
{
let material = batch.material.lock();
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
let material_state = batch.material.state();
if let ResourceStateRef::Ok(material) = material_state.get() {
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
if let Some(render_pass) = shader_cache
.get(state, material.shader())
.and_then(|shader_set| shader_set.render_passes.get(&self.render_pass_name))
{
for instance in batch.instances.iter() {
let view_projection = if instance.depth_offset != 0.0 {
let mut projection = camera.projection_matrix();
projection[14] -= instance.depth_offset;
projection * camera.view_matrix()
} else {
initial_view_projection
};
if let Some(render_pass) = shader_cache
.get(state, material.shader())
.and_then(|shader_set| shader_set.render_passes.get(&self.render_pass_name))
{
for instance in batch.instances.iter() {
let view_projection = if instance.depth_offset != 0.0 {
let mut projection = camera.projection_matrix();
projection[14] -= instance.depth_offset;
projection * camera.view_matrix()
} else {
initial_view_projection
};
statistics += framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&render_pass.draw_params,
instance.element_range,
|mut program_binding| {
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
world_matrix: &instance.world_transform,
view_projection_matrix: &view_projection,
wvp_matrix: &(view_projection * instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &camera.global_position(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near: camera.projection().z_near(),
z_far: camera.projection().z_far(),
use_pom: quality_settings.use_parallax_mapping,
light_position: &Default::default(),
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
matrix_storage,
persistent_identifier: instance.persistent_identifier,
light_data: Some(&light_data),
ambient_light,
scene_depth: Some(&scene_depth),
});
},
)?;
statistics += framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&render_pass.draw_params,
instance.element_range,
|mut program_binding| {
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
world_matrix: &instance.world_transform,
view_projection_matrix: &view_projection,
wvp_matrix: &(view_projection * instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &camera.global_position(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near: camera.projection().z_near(),
z_far: camera.projection().z_far(),
use_pom: quality_settings.use_parallax_mapping,
light_position: &Default::default(),
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
matrix_storage,
persistent_identifier: instance.persistent_identifier,
light_data: Some(&light_data),
ambient_light,
scene_depth: Some(&scene_depth),
});
},
)?;
}
}
}
}
+62 -59
View File
@@ -46,6 +46,7 @@ use crate::{
},
};
use fyrox_core::math::Matrix4Ext;
use fyrox_resource::ResourceStateRef;
use std::{cell::RefCell, rc::Rc};
mod decal;
@@ -308,68 +309,70 @@ impl GBuffer {
.iter()
.filter(|b| b.render_path == RenderPath::Deferred)
{
let material = batch.material.lock();
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
let material_state = batch.material.state();
if let ResourceStateRef::Ok(material) = material_state.get() {
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
if let Some(render_pass) = shader_cache
.get(state, material.shader())
.and_then(|shader_set| shader_set.render_passes.get(&self.render_pass_name))
{
for instance in batch.instances.iter() {
let apply_uniforms = |mut program_binding: GpuProgramBinding| {
let view_projection = if instance.depth_offset != 0.0 {
let mut projection = camera.projection_matrix();
projection[14] -= instance.depth_offset;
projection * camera.view_matrix()
} else {
initial_view_projection
if let Some(render_pass) = shader_cache
.get(state, material.shader())
.and_then(|shader_set| shader_set.render_passes.get(&self.render_pass_name))
{
for instance in batch.instances.iter() {
let apply_uniforms = |mut program_binding: GpuProgramBinding| {
let view_projection = if instance.depth_offset != 0.0 {
let mut projection = camera.projection_matrix();
projection[14] -= instance.depth_offset;
projection * camera.view_matrix()
} else {
initial_view_projection
};
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
matrix_storage,
world_matrix: &instance.world_transform,
view_projection_matrix: &view_projection,
wvp_matrix: &(view_projection * instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &camera.global_position(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near: camera.projection().z_near(),
use_pom: use_parallax_mapping,
light_position: &Default::default(),
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
persistent_identifier: instance.persistent_identifier,
light_data: None,
ambient_light: Color::WHITE, // TODO
scene_depth: None, // TODO. Add z-pre-pass.
z_far: camera.projection().z_far(),
});
};
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
matrix_storage,
world_matrix: &instance.world_transform,
view_projection_matrix: &view_projection,
wvp_matrix: &(view_projection * instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &camera.global_position(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near: camera.projection().z_near(),
use_pom: use_parallax_mapping,
light_position: &Default::default(),
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
persistent_identifier: instance.persistent_identifier,
light_data: None,
ambient_light: Color::WHITE, // TODO
scene_depth: None, // TODO. Add z-pre-pass.
z_far: camera.projection().z_far(),
});
};
statistics += self.framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&render_pass.draw_params,
instance.element_range,
apply_uniforms,
)?;
statistics += self.framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&render_pass.draw_params,
instance.element_range,
apply_uniforms,
)?;
}
}
}
}
+66 -62
View File
@@ -27,6 +27,7 @@ use crate::{
};
use fyrox_core::color::Color;
use fyrox_core::math::Matrix4Ext;
use fyrox_resource::ResourceStateRef;
use std::{cell::RefCell, rc::Rc};
pub struct Cascade {
@@ -261,69 +262,72 @@ impl CsmRenderer {
framebuffer.clear(state, viewport, None, Some(1.0), None);
for batch in batches.batches.iter() {
let material = batch.material.lock();
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
let material_state = batch.material.state();
if let ResourceStateRef::Ok(material) = material_state.get() {
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
if let Some(render_pass) =
shader_cache
.get(state, material.shader())
.and_then(|shader_set| {
shader_set.render_passes.get(&DIRECTIONAL_SHADOW_PASS_NAME)
})
{
for instance in batch.instances.iter() {
stats += framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&DrawParameters {
cull_face: Some(CullFace::Back),
color_write: ColorMask::all(false),
depth_write: true,
stencil_test: None,
depth_test: true,
blend: None,
stencil_op: Default::default(),
},
instance.element_range,
|mut program_binding| {
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
matrix_storage,
world_matrix: &instance.world_transform,
view_projection_matrix: &light_view_projection,
wvp_matrix: &(light_view_projection * instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &camera.global_position(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near,
use_pom: false,
light_position: &Default::default(),
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
persistent_identifier: instance.persistent_identifier,
light_data: None, // TODO
ambient_light: Color::WHITE, // TODO
scene_depth: None,
z_far,
});
},
)?;
if let Some(render_pass) =
shader_cache
.get(state, material.shader())
.and_then(|shader_set| {
shader_set.render_passes.get(&DIRECTIONAL_SHADOW_PASS_NAME)
})
{
for instance in batch.instances.iter() {
stats += framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&DrawParameters {
cull_face: Some(CullFace::Back),
color_write: ColorMask::all(false),
depth_write: true,
stencil_test: None,
depth_test: true,
blend: None,
stencil_op: Default::default(),
},
instance.element_range,
|mut program_binding| {
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
matrix_storage,
world_matrix: &instance.world_transform,
view_projection_matrix: &light_view_projection,
wvp_matrix: &(light_view_projection
* instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &camera.global_position(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near,
use_pom: false,
light_position: &Default::default(),
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
persistent_identifier: instance.persistent_identifier,
light_data: None, // TODO
ambient_light: Color::WHITE, // TODO
scene_depth: None,
z_far,
});
},
)?;
}
}
}
}
+58 -52
View File
@@ -26,6 +26,7 @@ use crate::{
scene::graph::Graph,
};
use fyrox_core::math::Matrix4Ext;
use fyrox_resource::ResourceStateRef;
use std::{cell::RefCell, rc::Rc};
pub struct PointShadowMapRenderer {
@@ -254,59 +255,64 @@ impl PointShadowMapRenderer {
);
for batch in batches.batches.iter() {
let material = batch.material.lock();
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
let material_state = batch.material.state();
if let ResourceStateRef::Ok(material) = material_state.get() {
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
if let Some(render_pass) = shader_cache
.get(state, material.shader())
.and_then(|shader_set| shader_set.render_passes.get(&POINT_SHADOW_PASS_NAME))
{
for instance in batch.instances.iter() {
statistics += framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&render_pass.draw_params,
instance.element_range,
|mut program_binding| {
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
matrix_storage,
world_matrix: &instance.world_transform,
view_projection_matrix: &light_view_projection_matrix,
wvp_matrix: &(light_view_projection_matrix
* instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &Default::default(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near,
use_pom: false,
light_position: &light_pos,
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
persistent_identifier: instance.persistent_identifier,
light_data: None, // TODO
ambient_light: Color::WHITE, // TODO
scene_depth: None,
z_far,
});
},
)?;
if let Some(render_pass) =
shader_cache
.get(state, material.shader())
.and_then(|shader_set| {
shader_set.render_passes.get(&POINT_SHADOW_PASS_NAME)
})
{
for instance in batch.instances.iter() {
statistics += framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&render_pass.draw_params,
instance.element_range,
|mut program_binding| {
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
matrix_storage,
world_matrix: &instance.world_transform,
view_projection_matrix: &light_view_projection_matrix,
wvp_matrix: &(light_view_projection_matrix
* instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &Default::default(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near,
use_pom: false,
light_position: &light_pos,
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
persistent_identifier: instance.persistent_identifier,
light_data: None, // TODO
ambient_light: Color::WHITE, // TODO
scene_depth: None,
z_far,
});
},
)?;
}
}
}
}
+62 -59
View File
@@ -26,6 +26,7 @@ use crate::{
scene::graph::Graph,
};
use fyrox_core::math::Matrix4Ext;
use fyrox_resource::ResourceStateRef;
use std::{cell::RefCell, rc::Rc};
pub struct SpotShadowMapRenderer {
@@ -164,66 +165,68 @@ impl SpotShadowMapRenderer {
let camera_side = inv_view.side();
for batch in batches.batches.iter() {
let material = batch.material.lock();
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
let material_state = batch.material.state();
if let ResourceStateRef::Ok(material) = material_state.get() {
let geometry = geom_cache.get(state, &batch.data, batch.time_to_live);
let blend_shapes_storage = batch
.data
.lock()
.blend_shapes_container
.as_ref()
.and_then(|c| c.blend_shape_storage.clone());
if let Some(render_pass) = shader_cache
.get(state, material.shader())
.and_then(|shader_set| shader_set.render_passes.get(&SPOT_SHADOW_PASS_NAME))
{
for instance in batch.instances.iter() {
statistics += framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&DrawParameters {
cull_face: Some(CullFace::Back),
color_write: ColorMask::all(false),
depth_write: true,
stencil_test: None,
depth_test: true,
blend: None,
stencil_op: Default::default(),
},
instance.element_range,
|mut program_binding| {
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
matrix_storage,
world_matrix: &instance.world_transform,
view_projection_matrix: &light_view_projection,
wvp_matrix: &(light_view_projection * instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &Default::default(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near,
use_pom: false,
light_position: &Default::default(),
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
persistent_identifier: instance.persistent_identifier,
light_data: None, // TODO
ambient_light: Color::WHITE, // TODO
scene_depth: None,
z_far,
});
},
)?;
if let Some(render_pass) = shader_cache
.get(state, material.shader())
.and_then(|shader_set| shader_set.render_passes.get(&SPOT_SHADOW_PASS_NAME))
{
for instance in batch.instances.iter() {
statistics += framebuffer.draw(
geometry,
state,
viewport,
&render_pass.program,
&DrawParameters {
cull_face: Some(CullFace::Back),
color_write: ColorMask::all(false),
depth_write: true,
stencil_test: None,
depth_test: true,
blend: None,
stencil_op: Default::default(),
},
instance.element_range,
|mut program_binding| {
apply_material(MaterialContext {
material: &material,
program_binding: &mut program_binding,
texture_cache,
matrix_storage,
world_matrix: &instance.world_transform,
view_projection_matrix: &light_view_projection,
wvp_matrix: &(light_view_projection * instance.world_transform),
bone_matrices: &instance.bone_matrices,
use_skeletal_animation: batch.is_skinned,
camera_position: &Default::default(),
camera_up_vector: &camera_up,
camera_side_vector: &camera_side,
z_near,
use_pom: false,
light_position: &Default::default(),
blend_shapes_storage: blend_shapes_storage.as_ref(),
blend_shapes_weights: &instance.blend_shapes_weights,
normal_dummy: normal_dummy.clone(),
white_dummy: white_dummy.clone(),
black_dummy: black_dummy.clone(),
volume_dummy: volume_dummy.clone(),
persistent_identifier: instance.persistent_identifier,
light_data: None, // TODO
ambient_light: Color::WHITE, // TODO
scene_depth: None,
z_far,
});
},
)?;
}
}
}
}
+2 -2
View File
@@ -294,7 +294,7 @@ async fn create_surfaces(
let mut surface = Surface::new(SurfaceSharedData::new(surface_data));
surface.vertex_weights = data.skin_data;
let material = fbx_scene.get(material_handle).as_material()?;
if let Err(e) = surface.material().lock().set_property(
if let Err(e) = surface.material().data_ref().set_property(
&ImmutableString::new("diffuseColor"),
PropertyValue::Color(material.diffuse_color),
) {
@@ -394,7 +394,7 @@ async fn create_surfaces(
};
if let Some((property_name, usage)) = name_usage {
if let Err(e) = surface.material().lock().set_property(
if let Err(e) = surface.material().data_ref().set_property(
&ImmutableString::new(property_name),
PropertyValue::Sampler {
value: Some(texture),
+9 -9
View File
@@ -17,7 +17,7 @@ use crate::{
visitor::prelude::*,
TypeUuidProvider,
},
material::{shader::SamplerFallback, Material, PropertyValue, SharedMaterial},
material::{shader::SamplerFallback, Material, MaterialResource, PropertyValue},
renderer::{self, batch::RenderContext},
resource::texture::TextureResource,
scene::{
@@ -161,7 +161,7 @@ pub struct Rectangle {
#[reflect(setter = "set_uv_rect")]
uv_rect: InheritableVariable<Rect<f32>>,
material: InheritableVariable<SharedMaterial>,
material: InheritableVariable<MaterialResource>,
}
impl Visit for Rectangle {
@@ -180,7 +180,7 @@ impl Visit for Rectangle {
fallback: SamplerFallback::White,
},
));
self.material = SharedMaterial::new(material).into();
self.material = MaterialResource::new_ok(material).into();
} else {
self.material.visit("Material", &mut region)?;
}
@@ -202,7 +202,7 @@ impl Default for Rectangle {
base: Default::default(),
color: Default::default(),
uv_rect: InheritableVariable::new_modified(Rect::new(0.0, 0.0, 1.0, 1.0)),
material: InheritableVariable::new_modified(SharedMaterial::new(
material: InheritableVariable::new_modified(MaterialResource::new_ok(
Material::standard_2d(),
)),
}
@@ -236,12 +236,12 @@ impl Rectangle {
}
/// Returns a reference to the current material used by the rectangle.
pub fn material(&self) -> &InheritableVariable<SharedMaterial> {
pub fn material(&self) -> &InheritableVariable<MaterialResource> {
&self.material
}
/// Returns a reference to the current material used by the rectangle.
pub fn material_mut(&mut self) -> &mut InheritableVariable<SharedMaterial> {
pub fn material_mut(&mut self) -> &mut InheritableVariable<MaterialResource> {
&mut self.material
}
@@ -351,7 +351,7 @@ pub struct RectangleBuilder {
base_builder: BaseBuilder,
color: Color,
uv_rect: Rect<f32>,
material: SharedMaterial,
material: MaterialResource,
}
impl RectangleBuilder {
@@ -361,7 +361,7 @@ impl RectangleBuilder {
base_builder,
color: Color::WHITE,
uv_rect: Rect::new(0.0, 0.0, 1.0, 1.0),
material: SharedMaterial::new(Material::standard_2d()),
material: MaterialResource::new_ok(Material::standard_2d()),
}
}
@@ -379,7 +379,7 @@ impl RectangleBuilder {
}
/// Sets the desired material of the rectangle.
pub fn with_material(mut self, material: SharedMaterial) -> Self {
pub fn with_material(mut self, material: MaterialResource) -> Self {
self.material = material;
self
}
+39 -29
View File
@@ -36,7 +36,7 @@ use crate::{
variable::try_inherit_properties,
visitor::{Visit, VisitResult, Visitor},
},
material::{shader::SamplerFallback, PropertyValue, SharedMaterial},
material::{shader::SamplerFallback, MaterialResource, PropertyValue},
resource::model::{ModelResource, ModelResourceExtension, NodeMapping},
scene::mesh::buffer::{
VertexAttributeDataType, VertexAttributeDescriptor, VertexAttributeUsage, VertexWriteTrait,
@@ -62,6 +62,7 @@ use crate::{
};
use fxhash::{FxHashMap, FxHashSet};
use fyrox_core::variable;
use fyrox_resource::ResourceStateRefMut;
use rapier3d::geometry::ColliderHandle;
use std::{
any::Any,
@@ -950,7 +951,7 @@ impl Graph {
node_reflect,
resource_node_reflect,
// Do not try to inspect materials, because it most likely cause a deadlock.
&[std::any::TypeId::of::<SharedMaterial>()],
&[std::any::TypeId::of::<MaterialResource>()],
));
})
})
@@ -1203,7 +1204,7 @@ impl Graph {
let mut materials = FxHashSet::default();
for node in self.linear_iter_mut() {
(node as &mut dyn Reflect).enumerate_fields_recursively(&mut |_, _, v| {
v.downcast_ref::<SharedMaterial>(&mut |material| {
v.downcast_ref::<MaterialResource>(&mut |material| {
if let Some(material) = material {
materials.insert(material.clone());
}
@@ -1212,7 +1213,10 @@ impl Graph {
}
for material in materials {
material.lock().sync_to_shader(resource_manager);
let mut material_state = material.state();
if let ResourceStateRefMut::Ok(material) = material_state.get_mut() {
material.sync_to_shader(resource_manager);
}
}
self.apply_lightmap();
@@ -1233,20 +1237,23 @@ impl Graph {
// This unwrap() call must never panic in normal conditions, because texture wrapped in Option
// only to implement Default trait to be serializable.
let texture = entry.texture.clone().unwrap();
if let Err(e) = surface.material().lock().set_property(
&ImmutableString::new("lightmapTexture"),
PropertyValue::Sampler {
value: Some(texture),
fallback: SamplerFallback::Black,
},
) {
Log::writeln(
MessageKind::Error,
format!(
"Failed to apply light map texture to material. Reason {:?}",
e
),
)
let mut material_state = surface.material().state();
if let ResourceStateRefMut::Ok(material) = material_state.get_mut() {
if let Err(e) = material.set_property(
&ImmutableString::new("lightmapTexture"),
PropertyValue::Sampler {
value: Some(texture),
fallback: SamplerFallback::Black,
},
) {
Log::writeln(
MessageKind::Error,
format!(
"Failed to apply light map texture to material. Reason {:?}",
e
),
)
}
}
}
}
@@ -1331,20 +1338,23 @@ impl Graph {
for (&handle, entries) in lightmap.map.iter_mut() {
if let Some(mesh) = self.pool[handle].cast_mut::<Mesh>() {
for (entry, surface) in entries.iter_mut().zip(mesh.surfaces_mut()) {
if let Err(e) = surface.material().lock().set_property(
&ImmutableString::new("lightmapTexture"),
PropertyValue::Sampler {
value: entry.texture.clone(),
fallback: SamplerFallback::Black,
},
) {
Log::writeln(
MessageKind::Error,
format!(
let mut material_state = surface.material().state();
if let ResourceStateRefMut::Ok(material) = material_state.get_mut() {
if let Err(e) = material.set_property(
&ImmutableString::new("lightmapTexture"),
PropertyValue::Sampler {
value: entry.texture.clone(),
fallback: SamplerFallback::Black,
},
) {
Log::writeln(
MessageKind::Error,
format!(
"Failed to apply light map texture to material. Reason {:?}",
e
),
)
)
}
}
}
}
+1 -1
View File
@@ -393,7 +393,7 @@ impl NodeTrait for Mesh {
surface.material(),
self.render_path(),
self.decal_layer_index(),
surface.material().key(),
surface.material().key() as u64,
SurfaceInstanceData {
world_transform: world,
bone_matrices: surface
+10 -9
View File
@@ -1,6 +1,7 @@
//! Surface is a set of triangles with a single material. Such arrangement makes GPU rendering very efficient.
//! See [`Surface`] docs for more info and usage examples.
use crate::material::MaterialResourceExtension;
use crate::{
core::{
algebra::{Matrix4, Point3, Vector2, Vector3, Vector4},
@@ -13,7 +14,7 @@ use crate::{
variable::InheritableVariable,
visitor::{Visit, VisitResult, Visitor},
},
material::{Material, SharedMaterial},
material::{Material, MaterialResource},
resource::texture::{TextureKind, TexturePixelKind, TextureResource, TextureResourceExtension},
scene::{
mesh::{
@@ -1241,7 +1242,7 @@ impl SurfaceSharedData {
pub struct Surface {
pub(crate) data: InheritableVariable<SurfaceSharedData>,
pub(crate) material: InheritableVariable<SharedMaterial>,
pub(crate) material: InheritableVariable<MaterialResource>,
/// Array of handles to scene nodes which are used as bones.
pub bones: InheritableVariable<Vec<Handle<Node>>>,
@@ -1299,7 +1300,7 @@ impl Default for Surface {
fn default() -> Self {
Self {
data: SurfaceSharedData::new(SurfaceData::make_cube(Matrix4::identity())).into(),
material: SharedMaterial::new(Material::standard()).into(),
material: MaterialResource::new_ok(Material::standard()).into(),
vertex_weights: Default::default(),
bones: Default::default(),
unique_material: Default::default(),
@@ -1319,7 +1320,7 @@ impl Surface {
/// Calculates material id.
pub fn material_id(&self) -> u64 {
self.material.key()
self.material.key() as u64
}
/// Calculates batch id.
@@ -1343,12 +1344,12 @@ impl Surface {
}
/// Returns current material of the surface.
pub fn material(&self) -> &SharedMaterial {
pub fn material(&self) -> &MaterialResource {
&self.material
}
/// Sets new material for the surface.
pub fn set_material(&mut self, material: SharedMaterial) {
pub fn set_material(&mut self, material: MaterialResource) {
self.material.set_value_and_mark_modified(material);
}
@@ -1372,7 +1373,7 @@ impl Surface {
/// Surface builder allows you to create surfaces in declarative manner.
pub struct SurfaceBuilder {
data: SurfaceSharedData,
material: Option<SharedMaterial>,
material: Option<MaterialResource>,
bones: Vec<Handle<Node>>,
unique_material: bool,
}
@@ -1389,7 +1390,7 @@ impl SurfaceBuilder {
}
/// Sets desired diffuse texture.
pub fn with_material(mut self, material: SharedMaterial) -> Self {
pub fn with_material(mut self, material: MaterialResource) -> Self {
self.material = Some(material);
self
}
@@ -1412,7 +1413,7 @@ impl SurfaceBuilder {
data: self.data.into(),
material: self
.material
.unwrap_or_else(|| SharedMaterial::new(Material::standard()))
.unwrap_or_else(|| MaterialResource::new_ok(Material::standard()))
.into(),
vertex_weights: Default::default(),
bones: self.bones.into(),
+12 -12
View File
@@ -14,7 +14,7 @@ use crate::{
visitor::prelude::*,
TypeUuidProvider,
},
material::{shader::SamplerFallback, Material, PropertyValue, SharedMaterial},
material::{shader::SamplerFallback, Material, MaterialResource, PropertyValue},
rand::{prelude::StdRng, Error, RngCore, SeedableRng},
renderer::{self, batch::RenderContext},
resource::texture::TextureResource,
@@ -142,7 +142,7 @@ impl Visit for ParticleSystemRng {
/// # color_gradient::{ColorGradient, GradientPoint},
/// # sstorage::ImmutableString,
/// # },
/// # material::{Material, PropertyValue, SharedMaterial},
/// # material::{Material, PropertyValue, MaterialResource},
/// # resource::texture::Texture,
/// # scene::{
/// # base::BaseBuilder,
@@ -201,7 +201,7 @@ impl Visit for ParticleSystemRng {
/// )
/// .with_radius(0.01)
/// .build()])
/// .with_material(SharedMaterial::new(material))
/// .with_material(MaterialResource::new(material))
/// .build(graph);
/// }
/// ```
@@ -213,7 +213,7 @@ pub struct ParticleSystem {
pub emitters: InheritableVariable<Vec<Emitter>>,
#[reflect(setter = "set_material")]
material: InheritableVariable<SharedMaterial>,
material: InheritableVariable<MaterialResource>,
#[reflect(setter = "set_acceleration")]
acceleration: InheritableVariable<Vector3<f32>>,
@@ -260,7 +260,7 @@ impl Visit for ParticleSystem {
},
)
.unwrap();
self.material = SharedMaterial::new(material).into();
self.material = MaterialResource::new_ok(material).into();
} else {
self.material.visit(name, &mut region)?;
}
@@ -271,7 +271,7 @@ impl Visit for ParticleSystem {
.is_ok()
{
self.material
.lock()
.data_ref()
.set_property(
&ImmutableString::new("softBoundarySharpnessFactor"),
PropertyValue::Float(soft_boundary_sharpness_factor),
@@ -355,17 +355,17 @@ impl ParticleSystem {
}
/// Sets the new material for the particle system.
pub fn set_material(&mut self, material: SharedMaterial) -> SharedMaterial {
pub fn set_material(&mut self, material: MaterialResource) -> MaterialResource {
self.material.set_value_and_mark_modified(material)
}
/// Returns current material used by particle system.
pub fn texture(&self) -> SharedMaterial {
pub fn texture(&self) -> MaterialResource {
(*self.material).clone()
}
/// Returns current material used by particle system by ref.
pub fn texture_ref(&self) -> &SharedMaterial {
pub fn texture_ref(&self) -> &MaterialResource {
&self.material
}
@@ -576,7 +576,7 @@ impl NodeTrait for ParticleSystem {
pub struct ParticleSystemBuilder {
base_builder: BaseBuilder,
emitters: Vec<Emitter>,
material: SharedMaterial,
material: MaterialResource,
acceleration: Vector3<f32>,
particles: Vec<Particle>,
color_over_lifetime: ColorGradient,
@@ -590,7 +590,7 @@ impl ParticleSystemBuilder {
Self {
base_builder,
emitters: Default::default(),
material: SharedMaterial::new(Material::standard_particle_system()),
material: MaterialResource::new_ok(Material::standard_particle_system()),
particles: Default::default(),
acceleration: Vector3::new(0.0, -9.81, 0.0),
color_over_lifetime: Default::default(),
@@ -606,7 +606,7 @@ impl ParticleSystemBuilder {
}
/// Sets desired material for particle system.
pub fn with_material(mut self, material: SharedMaterial) -> Self {
pub fn with_material(mut self, material: MaterialResource) -> Self {
self.material = material;
self
}
+10 -10
View File
@@ -16,7 +16,7 @@ use crate::{
visitor::{Visit, VisitResult, Visitor},
TypeUuidProvider,
},
material::{shader::SamplerFallback, Material, PropertyValue, SharedMaterial},
material::{shader::SamplerFallback, Material, MaterialResource, PropertyValue},
renderer::{self, batch::RenderContext},
resource::texture::TextureResource,
scene::{
@@ -111,7 +111,7 @@ impl VertexTrait for SpriteVertex {
/// # use fyrox::{
/// # asset::manager::ResourceManager,
/// # core::pool::Handle,
/// # material::{Material, SharedMaterial},
/// # material::{Material, MaterialResource},
/// # resource::texture::Texture,
/// # scene::{base::BaseBuilder, graph::Graph, node::Node, sprite::SpriteBuilder},
/// # };
@@ -127,7 +127,7 @@ impl VertexTrait for SpriteVertex {
/// .unwrap();
///
/// SpriteBuilder::new(BaseBuilder::new())
/// .with_material(SharedMaterial::new(material))
/// .with_material(MaterialResource::new(material))
/// .build(graph)
/// }
/// ```
@@ -143,7 +143,7 @@ pub struct Sprite {
#[reflect(setter = "set_uv_rect")]
uv_rect: InheritableVariable<Rect<f32>>,
material: InheritableVariable<SharedMaterial>,
material: InheritableVariable<MaterialResource>,
#[reflect(setter = "set_color")]
color: InheritableVariable<Color>,
@@ -172,7 +172,7 @@ impl Visit for Sprite {
fallback: SamplerFallback::White,
},
));
self.material = SharedMaterial::new(material).into();
self.material = MaterialResource::new_ok(material).into();
} else {
self.material.visit("Material", &mut region)?;
}
@@ -253,12 +253,12 @@ impl Sprite {
}
/// Returns a reference to the current material used by the sprite.
pub fn material(&self) -> &InheritableVariable<SharedMaterial> {
pub fn material(&self) -> &InheritableVariable<MaterialResource> {
&self.material
}
/// Returns a reference to the current material used by the sprite.
pub fn material_mut(&mut self) -> &mut InheritableVariable<SharedMaterial> {
pub fn material_mut(&mut self) -> &mut InheritableVariable<MaterialResource> {
&mut self.material
}
@@ -359,7 +359,7 @@ impl NodeTrait for Sprite {
pub struct SpriteBuilder {
base_builder: BaseBuilder,
uv_rect: Rect<f32>,
material: SharedMaterial,
material: MaterialResource,
color: Color,
size: f32,
rotation: f32,
@@ -370,7 +370,7 @@ impl SpriteBuilder {
pub fn new(base_builder: BaseBuilder) -> Self {
Self {
base_builder,
material: SharedMaterial::new(Material::standard_sprite()),
material: MaterialResource::new_ok(Material::standard_sprite()),
uv_rect: Rect::new(0.0, 0.0, 1.0, 1.0),
color: Color::WHITE,
size: 0.2,
@@ -386,7 +386,7 @@ impl SpriteBuilder {
}
/// Sets the desired material of the sprite.
pub fn with_material(mut self, material: SharedMaterial) -> Self {
pub fn with_material(mut self, material: MaterialResource) -> Self {
self.material = material;
self
}
+16 -10
View File
@@ -1,5 +1,6 @@
//! Everything related to terrains. See [`Terrain`] docs for more info.
use crate::material::MaterialResourceExtension;
use crate::renderer::batch::PersistentIdentifier;
use crate::{
asset::{Resource, ResourceStateRef},
@@ -16,7 +17,7 @@ use crate::{
visitor::{prelude::*, PodVecView},
TypeUuidProvider,
},
material::{Material, PropertyValue, SharedMaterial},
material::{Material, MaterialResource, PropertyValue},
renderer::{
self,
batch::{RenderContext, SurfaceInstanceData},
@@ -36,6 +37,7 @@ use crate::{
},
utils::{self},
};
use fyrox_resource::ResourceStateRefMut;
use half::f16;
use image::{imageops::FilterType, ImageBuffer, Luma};
use std::{
@@ -57,7 +59,7 @@ pub const VERSION: u8 = 1;
#[derive(Debug, Clone, Visit, Reflect, PartialEq)]
pub struct Layer {
/// Material of the layer.
pub material: SharedMaterial,
pub material: MaterialResource,
/// Name of the mask sampler property in the material.
pub mask_property_name: String,
@@ -74,7 +76,7 @@ pub struct Layer {
impl Default for Layer {
fn default() -> Self {
Self {
material: SharedMaterial::new(Material::standard_terrain()),
material: MaterialResource::new_ok(Material::standard_terrain()),
mask_property_name: "maskTexture".to_string(),
height_map_property_name: "heightMapTexture".to_string(),
node_uv_offsets_property_name: "nodeUvOffsets".to_string(),
@@ -654,7 +656,7 @@ impl Default for Terrain {
#[derive(Visit)]
struct OldLayer {
pub material: SharedMaterial,
pub material: MaterialResource,
pub mask_property_name: String,
pub chunk_masks: Vec<TextureResource>,
}
@@ -662,7 +664,7 @@ struct OldLayer {
impl Default for OldLayer {
fn default() -> Self {
Self {
material: SharedMaterial::new(Material::standard_terrain()),
material: MaterialResource::new_ok(Material::standard_terrain()),
mask_property_name: "maskTexture".to_string(),
chunk_masks: Default::default(),
}
@@ -737,12 +739,16 @@ impl Visit for Terrain {
// so here we must re-create the material and put every property from the old material
// to the new.
let mut new_material = Material::standard_terrain();
for (name, value) in layer.material.lock().properties() {
Log::verify(new_material.set_property(name, value.clone()));
let mut material_state = layer.material.state();
if let ResourceStateRefMut::Ok(material) = material_state.get_mut() {
for (name, value) in material.properties() {
Log::verify(new_material.set_property(name, value.clone()));
}
}
self.layers.push(Layer {
material: SharedMaterial::new(new_material),
material: MaterialResource::new_ok(new_material),
mask_property_name: layer.mask_property_name,
..Default::default()
});
@@ -1476,7 +1482,7 @@ impl NodeTrait for Terrain {
&mut selection,
);
let mut material = (*layer.material.lock()).clone();
let mut material = layer.material.deep_copy().data_ref().clone();
Log::verify_message(
material.set_property(
@@ -1515,7 +1521,7 @@ impl NodeTrait for Terrain {
"Unable to set node uv offsets for terrain material.",
);
let material = SharedMaterial::new(material.clone());
let material = MaterialResource::new_ok(material.clone());
let node_transform = chunk_transform
* Matrix4::new_translation(&Vector3::new(
+12 -8
View File
@@ -39,6 +39,7 @@ use crate::{
utils::{uvgen, uvgen::SurfaceDataPatch},
};
use fxhash::FxHashMap;
use fyrox_resource::ResourceStateRef;
use rayon::prelude::*;
use std::{
fmt::{Display, Formatter},
@@ -360,14 +361,17 @@ impl LightmapInputData {
let global_transform = mesh.global_transform();
'surface_loop: for surface in mesh.surfaces() {
// Check material for compatibility.
let material = surface.material().lock();
if !material
.properties()
.get(&ImmutableString::new("lightmapTexture"))
.map(|v| matches!(v, PropertyValue::Sampler { .. }))
.unwrap_or_default()
{
continue 'surface_loop;
let material_state = surface.material().state();
if let ResourceStateRef::Ok(material) = material_state.get() {
if !material
.properties()
.get(&ImmutableString::new("lightmapTexture"))
.map(|v| matches!(v, PropertyValue::Sampler { .. }))
.unwrap_or_default()
{
continue 'surface_loop;
}
}
// Gather unique "list" of surface data to generate UVs for.