Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions crates/processing_core/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ pub const LAB: &str = "lab";
pub const LCH: &str = "lch";
pub const XYZ: &str = "xyz";

pub const PBR_NEUTRAL: &str = "pbr_neutral"; // tonemapping
pub const AGX: &str = "agx";
pub const ACES: &str = "aces";
pub const TONY_MC_MAPFACE: &str = "tony_mc_mapface";
pub const BLENDER_FILMIC: &str = "blender_filmic";
pub const REINHARD: &str = "reinhard";
pub const REINHARD_LUMINANCE: &str = "reinhard_luminance";
pub const SOMEWHAT_BORING_DISPLAY_TRANSFORM: &str = "somewhat_boring_display_transform";

pub const MAP: &str = "map";
pub const COMBINE: &str = "combine";
pub const MIX: &str = "mix";
Expand Down
24 changes: 22 additions & 2 deletions crates/processing_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3897,13 +3897,33 @@ pub unsafe extern "C" fn processing_graphics_world_from_screen(
#[unsafe(no_mangle)]
pub extern "C" fn processing_graphics_set_bloom(graphics_id: u64, intensity: f32, threshold: f32) {
error::clear_error();
error::check(|| graphics_set_bloom(Entity::from_bits(graphics_id), intensity, threshold));
error::check(|| graphics_bloom(Entity::from_bits(graphics_id), intensity, threshold));
}

#[unsafe(no_mangle)]
pub extern "C" fn processing_graphics_remove_bloom(graphics_id: u64) {
error::clear_error();
error::check(|| graphics_remove_bloom(Entity::from_bits(graphics_id)));
error::check(|| graphics_no_bloom(Entity::from_bits(graphics_id)));
}

#[unsafe(no_mangle)]
pub extern "C" fn processing_graphics_tonemapping(graphics_id: u64, mode: u8) {
error::clear_error();
error::check(|| {
let tonemapping =
processing::prelude::graphics::tonemapping_from_u8(mode).ok_or_else(|| {
processing::prelude::error::ProcessingError::InvalidArgument(format!(
"unknown tonemapping: {mode}"
))
})?;
graphics_tonemapping(Entity::from_bits(graphics_id), tonemapping)
});
}

#[unsafe(no_mangle)]
pub extern "C" fn processing_graphics_no_tonemapping(graphics_id: u64) {
error::clear_error();
error::check(|| graphics_no_tonemapping(Entity::from_bits(graphics_id)));
}

// Mouse buttons
Expand Down
2 changes: 1 addition & 1 deletion crates/processing_pyo3/examples/curves.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def draw():
amp = 30 + sin(i * 0.5) * 20

v = 0.3 + (i / 20.0) * 0.5
stroke(v * 0.6 * 255, v * 255, min(v * 1.2, 1.0) * 255)
stroke(v * 0.6, v, min(v * 1.2, 1.0))

bezier(
0, y_base,
Expand Down
2 changes: 0 additions & 2 deletions crates/processing_pyo3/examples/particles_lissajous.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ def setup():
size(1000, 800)
window_title(f"Lissajous — all points connected — {N:,} pts")
mode_3d()
bloom(0.0)

p = create_particles(capacity=N, attributes=[Attribute.position(), Attribute.color()])
# One line = 2 vertices; up to N*MAX_LINKS lines.
Expand All @@ -52,7 +51,6 @@ def setup():


def draw():
bloom(0.0) # re-assert each frame
background(255, 255, 255)

t = elapsed_time
Expand Down
4 changes: 2 additions & 2 deletions crates/processing_pyo3/examples/primitives_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def draw():
r = 40 + i * 18
offset = t + i * 0.15
v = 0.2 + (i / 12.0) * 0.4
stroke(v * 255, v * 0.8 * 255, v * 0.6 * 255)
stroke(v, v * 0.8, v * 0.6)
arc(cx, cy, r * 2, r * 2, offset, offset + pi * 1.2, OPEN)

no_stroke()
Expand All @@ -29,7 +29,7 @@ def draw():
angle = t + i * 0.15
x = cx + r * cos(angle)
y = cy + r * sin(angle)
fill(217, (0.3 + i / 24.0) * 255, 51)
fill(0.85, 0.3 + i / 24.0, 0.2)
ellipse(x, y, 6, 6)

fill(25, 25, 25, 38)
Expand Down
2 changes: 1 addition & 1 deletion crates/processing_pyo3/examples/style_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def draw():
rotate(spin)

no_stroke()
fill(235, 90 + 130 * pulse, 60)
fill(0.92, 0.35 + 0.51 * pulse, 0.24)
rect_mode(CENTER)
rect(0, 0, cell * (0.3 + 0.15 * pulse), cell * 0.3)

Expand Down
4 changes: 2 additions & 2 deletions crates/processing_pyo3/examples/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def draw():
text("hello, processing", width / 2, height / 2)

# Pulsing subtitle.
pulse = 150 + 105 * sin(frame_count * 0.05)
fill(120, pulse, 255)
pulse = 0.59 + 0.41 * sin(frame_count * 0.05)
fill(0.47, pulse, 1.0)
text_size(20)
text("global text now works", width / 2, height / 2 + 60)

Expand Down
11 changes: 11 additions & 0 deletions crates/processing_pyo3/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ pub fn register(m: &Bound<'_, PyModule>) -> PyResult<()> {
add!(m, WORD, CHAR);
add!(m, NEAREST, CLAMP, REPEAT, MIRROR);
add!(m, SRGB, LINEAR, HSL, HSV, HWB, OKLAB, OKLCH, LAB, LCH, XYZ);
add!(
m,
PBR_NEUTRAL,
AGX,
ACES,
TONY_MC_MAPFACE,
BLENDER_FILMIC,
REINHARD,
REINHARD_LUMINANCE,
SOMEWHAT_BORING_DISPLAY_TRANSFORM
);
add!(
m, PI, TWO_PI, HALF_PI, QUARTER_PI, TAU, DEG_TO_RAD, RAD_TO_DEG
);
Expand Down
26 changes: 19 additions & 7 deletions crates/processing_pyo3/src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2291,14 +2291,26 @@ impl Graphics {
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

#[pyo3(signature = (intensity, threshold=0.0))]
#[pyo3(signature = (intensity=processing_render::graphics::DEFAULT_BLOOM_INTENSITY, threshold=0.0))]
pub fn bloom(&self, intensity: f32, threshold: f32) -> PyResult<()> {
if intensity <= 0.0 {
graphics_remove_bloom(self.entity).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
} else {
graphics_set_bloom(self.entity, intensity, threshold)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}
graphics_bloom(self.entity, intensity, threshold)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn no_bloom(&self) -> PyResult<()> {
graphics_no_bloom(self.entity).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

#[pyo3(signature = (mode=processing::prelude::constants::PBR_NEUTRAL))]
pub fn tonemapping(&self, mode: &str) -> PyResult<()> {
let tonemapping = processing_render::graphics::parse_tonemapping(mode)
.ok_or_else(|| PyValueError::new_err(format!("unknown tonemapping {mode:?}")))?;
graphics_tonemapping(self.entity, tonemapping)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn no_tonemapping(&self) -> PyResult<()> {
graphics_no_tonemapping(self.entity).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

/// Composites a source onto this graphics with a blend mode (Processing
Expand Down
20 changes: 19 additions & 1 deletion crates/processing_pyo3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1485,11 +1485,29 @@ pub mod mewnala {
}

#[pyfunction]
#[pyo3(pass_module, signature = (intensity, threshold=0.0))]
#[pyo3(pass_module, signature = (intensity=processing_render::graphics::DEFAULT_BLOOM_INTENSITY, threshold=0.0))]
fn bloom(module: &Bound<'_, PyModule>, intensity: f32, threshold: f32) -> PyResult<()> {
graphics!(module).bloom(intensity, threshold)
}

#[pyfunction]
#[pyo3(pass_module)]
fn no_bloom(module: &Bound<'_, PyModule>) -> PyResult<()> {
graphics!(module).no_bloom()
}

#[pyfunction]
#[pyo3(pass_module, signature = (mode=processing::prelude::constants::PBR_NEUTRAL))]
fn tonemapping(module: &Bound<'_, PyModule>, mode: &str) -> PyResult<()> {
graphics!(module).tonemapping(mode)
}

#[pyfunction]
#[pyo3(pass_module)]
fn no_tonemapping(module: &Bound<'_, PyModule>) -> PyResult<()> {
graphics!(module).no_tonemapping()
}

#[pyfunction]
#[pyo3(pass_module, signature = (*args))]
fn rect(module: &Bound<'_, PyModule>, args: &Bound<'_, PyTuple>) -> PyResult<()> {
Expand Down
64 changes: 45 additions & 19 deletions crates/processing_render/src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use bevy::{
core_pipeline::tonemapping::Tonemapping,
ecs::query::QueryEntityError,
math::{Mat4, Vec3A},
post_process::bloom::Bloom,
prelude::*,
render::{
RenderApp,
Expand Down Expand Up @@ -210,7 +209,6 @@ pub fn create(
..default()
},
target,
// overridden below for hdr targets
Tonemapping::None,
// we need to be able to write to the texture
CameraMainTextureUsages::default().with(TextureUsages::COPY_DST),
Expand All @@ -229,7 +227,7 @@ pub fn create(
));

if is_hdr {
entity_commands.insert((Hdr, Bloom::NATURAL, Tonemapping::TonyMcMapface));
entity_commands.insert(Hdr);
}

let entity = entity_commands.id();
Expand Down Expand Up @@ -444,10 +442,11 @@ pub fn world_from_screen(
Ok(world)
}

pub fn set_bloom(
pub const DEFAULT_BLOOM_INTENSITY: f32 = bevy::post_process::bloom::Bloom::NATURAL.intensity;

pub fn bloom(
In((entity, intensity, threshold)): In<(Entity, f32, f32)>,
mut commands: Commands,
mut tonemapping_query: Query<&mut Tonemapping>,
) -> Result<()> {
use bevy::post_process::bloom::{Bloom, BloomCompositeMode, BloomPrefilter};

Expand All @@ -462,29 +461,56 @@ pub fn set_bloom(
}

commands.entity(entity).insert((bloom, Hdr));

if let Ok(mut tm) = tonemapping_query.get_mut(entity)
&& *tm == Tonemapping::None
{
*tm = Tonemapping::TonyMcMapface;
}

Ok(())
}

pub fn remove_bloom(
In(entity): In<Entity>,
mut commands: Commands,
mut tonemapping_query: Query<&mut Tonemapping>,
) -> Result<()> {
pub fn no_bloom(In(entity): In<Entity>, mut commands: Commands) -> Result<()> {
use bevy::post_process::bloom::Bloom;

commands.entity(entity).remove::<Bloom>();
Ok(())
}

if let Ok(mut tm) = tonemapping_query.get_mut(entity) {
*tm = Tonemapping::None;
pub fn parse_tonemapping(s: &str) -> Option<Tonemapping> {
use processing_core::constants as consts;
[
(consts::PBR_NEUTRAL, Tonemapping::KhronosPbrNeutral),
(consts::AGX, Tonemapping::AgX),
(consts::ACES, Tonemapping::AcesFitted),
(consts::TONY_MC_MAPFACE, Tonemapping::TonyMcMapface),
(consts::BLENDER_FILMIC, Tonemapping::BlenderFilmic),
(consts::REINHARD, Tonemapping::Reinhard),
(consts::REINHARD_LUMINANCE, Tonemapping::ReinhardLuminance),
(
consts::SOMEWHAT_BORING_DISPLAY_TRANSFORM,
Tonemapping::SomewhatBoringDisplayTransform,
),
]
.into_iter()
.find_map(|(name, tm)| s.eq_ignore_ascii_case(name).then_some(tm))
}

pub fn tonemapping_from_u8(v: u8) -> Option<Tonemapping> {
match v {
0 => Some(Tonemapping::KhronosPbrNeutral),
1 => Some(Tonemapping::AgX),
2 => Some(Tonemapping::AcesFitted),
3 => Some(Tonemapping::TonyMcMapface),
4 => Some(Tonemapping::BlenderFilmic),
5 => Some(Tonemapping::Reinhard),
6 => Some(Tonemapping::ReinhardLuminance),
7 => Some(Tonemapping::SomewhatBoringDisplayTransform),
_ => None,
}
}

pub fn set_tonemapping(
In((entity, tonemapping)): In<(Entity, Tonemapping)>,
mut query: Query<&mut Tonemapping>,
) -> Result<()> {
*query
.get_mut(entity)
.map_err(|_| ProcessingError::GraphicsNotFound)? = tonemapping;
Ok(())
}

Expand Down
26 changes: 22 additions & 4 deletions crates/processing_render/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,26 +948,44 @@ pub fn graphics_world_from_screen(
})
}

pub fn graphics_set_bloom(
pub fn graphics_bloom(
graphics_entity: Entity,
intensity: f32,
threshold: f32,
) -> error::Result<()> {
app_mut(|app| {
app.world_mut()
.run_system_cached_with(graphics::set_bloom, (graphics_entity, intensity, threshold))
.run_system_cached_with(graphics::bloom, (graphics_entity, intensity, threshold))
.unwrap()
})
}

pub fn graphics_remove_bloom(graphics_entity: Entity) -> error::Result<()> {
pub fn graphics_no_bloom(graphics_entity: Entity) -> error::Result<()> {
app_mut(|app| {
app.world_mut()
.run_system_cached_with(graphics::remove_bloom, graphics_entity)
.run_system_cached_with(graphics::no_bloom, graphics_entity)
.unwrap()
})
}

pub fn graphics_tonemapping(
graphics_entity: Entity,
tonemapping: bevy::core_pipeline::tonemapping::Tonemapping,
) -> error::Result<()> {
app_mut(|app| {
app.world_mut()
.run_system_cached_with(graphics::set_tonemapping, (graphics_entity, tonemapping))
.unwrap()
})
}

pub fn graphics_no_tonemapping(graphics_entity: Entity) -> error::Result<()> {
graphics_tonemapping(
graphics_entity,
bevy::core_pipeline::tonemapping::Tonemapping::None,
)
}

pub fn transform_set_position(entity: Entity, position: Vec3) -> error::Result<()> {
app_mut(|app| {
app.world_mut()
Expand Down
Loading