Skip to content

Commit

Permalink
Fix #354 Performance issues (#366)
Browse files Browse the repository at this point in the history
* Lights id

* Material id

* Optimised working

* Split Material::fragment_shader into source ant attributes

* Use u64 instead of Vec<u32> as program key

* Shared Mesh::id function

* Particles use program2

* Use byte array for key

* program_cache

* Internal name fix

* render_with_material

* impl draw, vertex_shader_source and id for Geometry types

* impl new Geometry for Particles

* Remove program_cache

* impl new Geometry

* Simplify Axes

* Compile

* use macro rules to impl Geometry

* Use macro rules to impl more geometries

* Use more macro rules to impl geometry and object

* todo

* More impl Object with macro

* Fix mandelbrot example

* impl id for skybox and terrain

* Clean-up in instanced shapes example

* Geometry id

* macro rule for material body

* macro rule for post material body

* PostMaterial impl basic methods

* Use 16 bit for Geometry

* use render_with_post_material

* Remove fragment_shader method

* Fix instanced mesh

* InstancedMesh is working

* Material ids

* Fix examples implementing material

* Fix warnings

* Docs

* Docs

* Remove unused function

* light macro impl

* Light unique id

* use u16 for geometry and material id

* Docs

* Remove InstancedMesh::set_instance_count

* Update instance buffers at set_instances

* impl animate for mutable Geometry

* Instanced mesh clean-up

* Fix animation

* Avoid Geometry::render_with_material

* Avoid using apply_effect in core

* full_screen_id

* Rename and clean-up

* render fullscreen functions

* impl PostMaterial for fog and fxaa

* Update examples

* Internal LightingPassMaterial (improve performance)

* Rename

* Move effect functionality to effect folder

* Rename PostMaterial -> Effect

* Rename

* Render target impl apply_screen_effect and material

* Move LightingPass to effects

* Rename

* Use apply_screen_effect for lighting pass

* Avoid use of apply_effect

* Avoid use of apply_effect in logo example

* Full screen id

* Fix id of water geometry

* Fix core ids

* Avoid apply_cube_effect

* Avoid cube effect in core

* IrradianceMaterial

* PrefilterMaterial

* Deprecate apply_effect and apply_cube_effect

* Deprecate Context::program

* Rename

* Expose Context::programs

* Docs

* Remove Effect::material_type

* Docs

* Fix docs

* Docs

* Move ColorTexture and DepthTexture impl to core

* Remove redundant resolution methods

* fmt
  • Loading branch information
asny committed Jun 2, 2023
1 parent ee5230c commit afba8c4
Show file tree
Hide file tree
Showing 60 changed files with 2,136 additions and 2,030 deletions.
20 changes: 12 additions & 8 deletions examples/fireworks/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ struct FireworksMaterial {
}

impl Material for FireworksMaterial {
fn fragment_shader(&self, _lights: &[&dyn Light]) -> FragmentShader {
FragmentShader {
source: include_str!("particles.frag").to_string(),
attributes: FragmentAttributes {
uv: true,
color: true,
..FragmentAttributes::NONE
},
fn fragment_shader_source(&self, _lights: &[&dyn Light]) -> String {
include_str!("particles.frag").to_string()
}
fn fragment_attributes(&self) -> FragmentAttributes {
FragmentAttributes {
uv: true,
color: true,
..FragmentAttributes::NONE
}
}
fn use_uniforms(&self, program: &Program, _camera: &Camera, _lights: &[&dyn Light]) {
Expand All @@ -42,6 +42,10 @@ impl Material for FireworksMaterial {
fn material_type(&self) -> MaterialType {
MaterialType::Transparent
}

fn id(&self) -> u16 {
0b1u16
}
}
// Entry point for non-wasm
#[cfg(not(target_arch = "wasm32"))]
Expand Down
18 changes: 9 additions & 9 deletions examples/fog/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ pub async fn run() {
let fog_effect = FogEffect {
color: Color::new_opaque(200, 200, 200),
density: 0.2,
animation: 0.1,
animation: 0.2,
..Default::default()
};
let mut fog_enabled = true;

Expand Down Expand Up @@ -114,14 +115,13 @@ pub async fn run() {
frame_input.viewport,
WriteMask::default(),
)
.write(|| {
fog_effect.apply(
&context,
frame_input.accumulated_time,
&camera,
DepthTexture::Single(&depth_texture),
)
});
.apply_screen_effect(
&fog_effect,
&camera,
&[],
None,
Some(DepthTexture::Single(&depth_texture)),
);
} else if change {
// If a change has happened and no fog is applied, copy the result to the screen
frame_input.screen().copy_from_color(
Expand Down
39 changes: 17 additions & 22 deletions examples/image/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub async fn run() {
.await
.expect("failed to download the necessary assets, to enable running this example offline, place the relevant assets in a folder called 'assets' next to the three-d source")
};
let image = Texture2D::new(&context, &loaded.deserialize("").unwrap());
let image = std::sync::Arc::new(Texture2D::new(&context, &loaded.deserialize("").unwrap()));

let mut gui = GUI::new(&context);

Expand Down Expand Up @@ -72,27 +72,22 @@ pub async fn run() {
frame_input.viewport.height,
);

frame_input.screen().clear(ClearState::default()).write(|| {
apply_effect(
&context,
include_str!("shader.frag"),
RenderStates::default(),
viewport,
|program| {
program.use_texture("image", &image);
program.use_uniform("parameter", tone_mapping);
program.use_uniform(
"textureTransform",
Mat3::from_scale(texture_transform_scale)
* Mat3::from_translation(vec2(
texture_transform_x,
texture_transform_y,
)),
)
},
);
gui.render();
});
let material = ColorMaterial {
texture: Some(Texture2DRef {
texture: image.clone(),
transformation: Mat3::from_scale(texture_transform_scale)
* Mat3::from_translation(vec2(texture_transform_x, texture_transform_y)),
}),
..Default::default()
};

frame_input
.screen()
.clear(ClearState::default())
.apply_screen_material(&material, &camera2d(viewport), &[])
.write(|| {
gui.render();
});

FrameOutput::default()
});
Expand Down
30 changes: 0 additions & 30 deletions examples/image/src/shader.frag

This file was deleted.

4 changes: 1 addition & 3 deletions examples/instanced_draw_order/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ pub fn main() {
)
.unwrap();

let mut opaque_meshes_opaque_instances = Gm::new(
let opaque_meshes_opaque_instances = Gm::new(
InstancedMesh::new(&context, &opaque_instances, &thin_cube_right),
PhysicalMaterial::new_opaque(
&context,
Expand All @@ -119,8 +119,6 @@ pub fn main() {
},
),
);
// Testing that changing the instance count still works as expected, blue should disappear.
opaque_meshes_opaque_instances.set_instance_count(3);

let light0 = DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, -0.5, -0.5));
let ambient_light = three_d::renderer::light::AmbientLight::new(&context, 0.1, Color::WHITE);
Expand Down
17 changes: 6 additions & 11 deletions examples/instanced_shapes/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,20 +146,15 @@ pub fn main() {

// Then, based on whether or not we render the instanced cubes, collect the renderable
// objects.
let render_objects: Vec<&dyn Object> = if is_instanced {
instanced_mesh.into_iter().collect()
let screen = frame_input.screen();
screen.clear(ClearState::color_and_depth(0.8, 0.8, 0.8, 1.0, 1.0));
if is_instanced {
screen.render(&camera, &instanced_mesh, &[&light0, &light1]);
} else {
non_instanced_meshes
.iter()
.map(|x| x as &dyn Object)
.collect()
screen.render(&camera, &non_instanced_meshes, &[&light0, &light1]);
};

frame_input
.screen()
.clear(ClearState::color_and_depth(0.8, 0.8, 0.8, 1.0, 1.0))
.render(&camera, render_objects, &[&light0, &light1])
.write(|| gui.render());
screen.write(|| gui.render());

FrameOutput::default()
});
Expand Down
53 changes: 38 additions & 15 deletions examples/logo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,46 @@ pub async fn run() {
frame_input
.screen()
.clear(ClearState::color_and_depth(1.0, 1.0, 1.0, 1.0, 1.0))
.write(|| {
apply_effect(
&context,
include_str!("shader.frag"),
RenderStates {
write_mask: WriteMask::COLOR,
blend: Blend::TRANSPARENCY,
..Default::default()
},
frame_input.viewport,
|program| {
program.use_texture("image", &image);
},
);
})
.apply_screen_material(&LogoMaterial { image: &image }, &camera, &[])
.render(&camera, &model, &[]);

FrameOutput::default()
});
}

struct LogoMaterial<'a> {
image: &'a Texture2D,
}

impl Material for LogoMaterial<'_> {
fn fragment_shader_source(&self, _lights: &[&dyn Light]) -> String {
include_str!("shader.frag").to_string()
}

fn id(&self) -> u16 {
0b1u16
}

fn fragment_attributes(&self) -> FragmentAttributes {
FragmentAttributes {
uv: true,
..FragmentAttributes::NONE
}
}

fn use_uniforms(&self, program: &Program, _camera: &Camera, _lights: &[&dyn Light]) {
program.use_texture("image", &self.image);
}

fn render_states(&self) -> RenderStates {
RenderStates {
write_mask: WriteMask::COLOR,
blend: Blend::TRANSPARENCY,
..Default::default()
}
}

fn material_type(&self) -> MaterialType {
MaterialType::Transparent
}
}
20 changes: 13 additions & 7 deletions examples/mandelbrot/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ use three_d::*;
struct MandelbrotMaterial {}

impl Material for MandelbrotMaterial {
fn fragment_shader(&self, _lights: &[&dyn Light]) -> FragmentShader {
FragmentShader {
source: include_str!("mandelbrot.frag").to_string(),
attributes: FragmentAttributes {
position: true,
..FragmentAttributes::NONE
},
fn fragment_shader_source(&self, _lights: &[&dyn Light]) -> String {
include_str!("mandelbrot.frag").to_string()
}

fn fragment_attributes(&self) -> FragmentAttributes {
FragmentAttributes {
position: true,
..FragmentAttributes::NONE
}
}

fn use_uniforms(&self, _program: &Program, _camera: &Camera, _lights: &[&dyn Light]) {}
fn render_states(&self) -> RenderStates {
RenderStates {
Expand All @@ -24,6 +26,10 @@ impl Material for MandelbrotMaterial {
fn material_type(&self) -> MaterialType {
MaterialType::Opaque
}

fn id(&self) -> u16 {
0b11u16
}
}

pub fn main() {
Expand Down
2 changes: 1 addition & 1 deletion examples/terrain/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ pub async fn run() {
camera.viewport(),
WriteMask::default(),
)
.render_with_post_material(
.render_with_effect(
&water_material,
&camera,
&water,
Expand Down
53 changes: 48 additions & 5 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,23 @@ pub enum CoreError {
/// The fragment shader get the uv coordinates of the viewport (specified by `in vec2 uvs;`),
/// where uv coordinates of `(0, 0)` corresponds to the bottom left corner of the viewport and `(1, 1)` to the top right corner.
///
#[deprecated = "Use apply_screen_material or apply_screen_effect in the renderer module"]
pub fn apply_effect(
context: &Context,
fragment_shader_source: &str,
render_states: RenderStates,
viewport: Viewport,
use_uniforms: impl FnOnce(&Program),
) {
let position_buffer = full_screen_buffer(context);
let position_buffer = VertexBuffer::new_with_data(
context,
&[
vec3(-3.0, -1.0, 0.0),
vec3(3.0, -1.0, 0.0),
vec3(0.0, 2.0, 0.0),
],
);
#[allow(deprecated)]
context
.program(
"
Expand All @@ -100,6 +109,7 @@ pub fn apply_effect(
/// Applies a 2D/screen space effect to the given viewport of the given side of a cube map.
/// The fragment shader get the 3D position (specified by `in vec3 pos;`) of the fragment on the cube with minimum position `(-1, -1, -1)` and maximum position `(1, 1, 1)`.
///
#[deprecated = "Use apply_screen_material or apply_screen_effect in the renderer module"]
pub fn apply_cube_effect(
context: &Context,
side: CubeMapSide,
Expand All @@ -108,7 +118,15 @@ pub fn apply_cube_effect(
viewport: Viewport,
use_uniforms: impl FnOnce(&Program),
) {
let position_buffer = full_screen_buffer(context);
let position_buffer = VertexBuffer::new_with_data(
context,
&[
vec3(-3.0, -1.0, 0.0),
vec3(3.0, -1.0, 0.0),
vec3(0.0, 2.0, 0.0),
],
);
#[allow(deprecated)]
context
.program(
"
Expand Down Expand Up @@ -136,15 +154,40 @@ pub fn apply_cube_effect(
.expect("Failed compiling shader");
}

fn full_screen_buffer(context: &Context) -> VertexBuffer {
VertexBuffer::new_with_data(
pub(crate) fn full_screen_id() -> u16 {
0b1u16 << 15
}

pub(crate) fn full_screen_draw(
context: &Context,
program: &Program,
render_states: RenderStates,
viewport: Viewport,
) {
let position_buffer = VertexBuffer::new_with_data(
context,
&[
vec3(-3.0, -1.0, 0.0),
vec3(3.0, -1.0, 0.0),
vec3(0.0, 2.0, 0.0),
],
)
);
program.use_vertex_attribute("position", &position_buffer);
program.draw_arrays(render_states, viewport, 3);
}

pub(crate) fn full_screen_vertex_shader_source() -> &'static str {
"
in vec3 position;
out vec2 uvs;
out vec4 col;
void main()
{
uvs = 0.5 * position.xy + 0.5;
col = vec4(1.0);
gl_Position = vec4(position, 1.0);
}
"
}

mod data_type;
Expand Down
Loading

0 comments on commit afba8c4

Please sign in to comment.