Compare commits

...

8 Commits

Author SHA1 Message Date
c6efe1498b ignore this error; it doesn't affect us
Some checks failed
book / deploy (push) Has been cancelled
CI / test (macos-latest) (push) Has been cancelled
CI / test (ubuntu-latest) (push) Has been cancelled
CI / test (windows-latest) (push) Has been cancelled
CI / all-doc-tests (push) Has been cancelled
CI / lint (push) Has been cancelled
2026-02-23 22:14:05 +01:00
e43a22931c updated shader for better mixing of overlay
Some checks failed
book / deploy (push) Has been cancelled
CI / test (macos-latest) (push) Has been cancelled
CI / test (ubuntu-latest) (push) Has been cancelled
CI / test (windows-latest) (push) Has been cancelled
CI / all-doc-tests (push) Has been cancelled
CI / lint (push) Has been cancelled
2026-02-23 00:53:46 +01:00
530fac29dc allow overlay texture 2026-02-22 20:39:13 +01:00
0bdc962e2c need to expose meshaabb for head lookat move mouse test
Some checks failed
book / deploy (push) Has been cancelled
CI / test (macos-latest) (push) Has been cancelled
CI / test (ubuntu-latest) (push) Has been cancelled
CI / test (windows-latest) (push) Has been cancelled
CI / all-doc-tests (push) Has been cancelled
CI / lint (push) Has been cancelled
2026-02-21 19:08:59 +01:00
0e629b98af faster scroll
Some checks failed
book / deploy (push) Has been cancelled
CI / test (macos-latest) (push) Has been cancelled
CI / test (ubuntu-latest) (push) Has been cancelled
CI / test (windows-latest) (push) Has been cancelled
CI / all-doc-tests (push) Has been cancelled
CI / lint (push) Has been cancelled
2026-02-21 14:34:34 +01:00
ac07af581e fix: x mouse pos on mesh
Some checks failed
book / deploy (push) Has been cancelled
CI / test (macos-latest) (push) Has been cancelled
CI / test (ubuntu-latest) (push) Has been cancelled
CI / test (windows-latest) (push) Has been cancelled
CI / all-doc-tests (push) Has been cancelled
CI / lint (push) Has been cancelled
2026-02-21 13:54:14 +01:00
a1152ca759 update readme
Some checks failed
book / deploy (push) Has been cancelled
CI / test (windows-latest) (push) Has been cancelled
CI / all-doc-tests (push) Has been cancelled
CI / test (macos-latest) (push) Has been cancelled
CI / test (ubuntu-latest) (push) Has been cancelled
CI / lint (push) Has been cancelled
2026-02-20 22:07:53 +01:00
d39602eb0e Stuff
Some checks failed
book / deploy (push) Has been cancelled
CI / test (macos-latest) (push) Has been cancelled
CI / test (ubuntu-latest) (push) Has been cancelled
CI / test (windows-latest) (push) Has been cancelled
CI / all-doc-tests (push) Has been cancelled
CI / lint (push) Has been cancelled
2026-02-20 22:06:28 +01:00
21 changed files with 77 additions and 271 deletions

View File

@@ -1,13 +0,0 @@
---
allowed-tools: Bash(cargo test:*),
description: Create new tests
---
1. Reading $ARGUMENTS and understanding the implementation details.
2. Creating new tests for $ARGUMENTS in `tests` module in the same file.
3. Run `cargo test --workspace --all-features` to ensure all tests pass.
4. If any tests fail, fix the issues and re-run the tests.
## Contracts
- You have to write the rust-doc that describes the test case for each test function.

View File

@@ -1,37 +0,0 @@
# Repository Guidelines
## Project Structure & Module Organization
- `src/`: Public `bevy_cef` crate API surface.
- `crates/bevy_cef_core`: Core CEF integration and IPC.
- `crates/bevy_cef_debug_render_process`: Debug render-process tool.
- `examples/`: Runnable samples (e.g., `simple.rs`, `js_emit.rs`, `brp.rs`).
- `assets/`: Local HTML/CSS/JS served via `cef://localhost/`.
- `docs/`: Supporting documentation.
## Build, Test, and Development Commands
- `cargo build --features debug`: Build with macOS debug tooling enabled.
- `cargo run --example simple --features debug`: Run a basic webview example.
- `cargo test --workspace --all-features`: Run tests (currently no automated tests; validates compilation).
- `make fix`: Run `cargo clippy --fix` and `cargo fmt --all`.
- `make install`: Install and copy the debug render process into the CEF framework (macOS).
## Coding Style & Naming Conventions
- Rust 2024 edition; format with `cargo fmt` before committing.
- Lint with `cargo clippy` (see `make fix`).
- Naming: `snake_case` for modules/functions/files, `CamelCase` for types/traits, `SCREAMING_SNAKE_CASE` for constants.
- Prefer small, focused modules; keep public API in `src/` and implementation in `crates/`.
## Testing Guidelines
- No dedicated test suite yet; rely on examples for manual verification.
- Use `examples/` to validate features (IPC, navigation, zoom, devtools).
- If adding tests, keep names descriptive (e.g., `test_ipc_roundtrip`) and run with `cargo test --workspace --all-features`.
## Commit & Pull Request Guidelines
- Commit subjects are short, imperative; common prefixes include `add:`, `fix:`, `update:`, `remove:`.
- Include PR or issue references when relevant (e.g., `Support Bevy 0.17 (#11)`).
- PRs should describe changes, testing performed, and target platform (macOS/Windows/Linux).
- For webview or UI changes, include screenshots or short clips when possible.
## Platform & Configuration Notes
- Primary development target is macOS; CEF framework should exist at `$HOME/.local/share/cef`.
- Local assets are served as `cef://localhost/<file>`; prefer `CefWebviewUri::local("file.html")`.

View File

@@ -1,96 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is `bevy_cef`, a Bevy plugin that integrates the Chromium Embedded Framework (CEF) into Bevy applications, allowing webviews to be rendered as 3D objects in the game world or as UI overlays.
## Architecture
### Multi-Process Design
- **Browser Process**: Main application process running Bevy (`bevy_cef_core::browser_process`)
- **Render Process**: Separate CEF render process (`bevy_cef_core::render_process`)
- Communication through IPC channels and Bevy Remote Protocol (BRP)
### Core Components
- `CefWebviewUri`: URL specification (`CefWebviewUri::new("url")` or `CefWebviewUri::local("file.html")`)
- `WebviewSize`: Rendering dimensions (default 800x800), controls texture resolution not 3D size
- `WebviewExtendStandardMaterial`: Primary material for 3D mesh rendering
- `WebviewSpriteMaterial`: Material for 2D sprite rendering
- `HostWindow`: Optional parent window (defaults to PrimaryWindow)
- `ZoomLevel`: f64 zoom control (0.0 = default)
- `AudioMuted`: bool for audio control
- `PreloadScripts`: Vec<String> of scripts to execute before page scripts
- `CefExtensions`: Custom JS extensions via `register_extension` (global to all webviews)
### Plugin Architecture
The main `CefPlugin` accepts `CommandLineConfig` for CEF command-line switches and `CefExtensions` for custom JavaScript APIs. Sub-plugins:
- `LocalHostPlugin`: Serves local assets via `cef://localhost/` scheme
- `MessageLoopPlugin`: CEF message loop integration (macOS uses `CefDoMessageLoopWork()`)
- `WebviewCoreComponentsPlugin`: Core component registration
- `WebviewPlugin`: Webview lifecycle and DevTools
- `IpcPlugin`: IPC containing `IpcRawEventPlugin` and `HostEmitPlugin`
- `KeyboardPlugin`, `SystemCursorIconPlugin`, `NavigationPlugin`, `ZoomPlugin`, `AudioMutePlugin`
- `RemotePlugin`: Auto-added for BRP support if not present
### IPC System
Three communication patterns:
1. **JS Emit**: Webview → Bevy via `JsEmitEventPlugin<E>` where E: `DeserializeOwned + Send + Sync + 'static`
- Events wrapped in `Receive<E>` EntityEvent
- JavaScript: `window.cef.emit('event_name', data)`
2. **Host Emit**: Bevy → Webview via `HostEmitEvent` (EntityEvent)
- JavaScript: `window.cef.listen('event_name', callback)`
3. **BRP**: Bidirectional RPC via `bevy_remote`
- JavaScript: `await window.cef.brp({ method: 'method_name', params: {...} })`
### EntityEvent Pattern
Navigation and DevTools events are `EntityEvent` types requiring explicit `webview: Entity` field:
- `HostEmitEvent`, `RequestGoBack`, `RequestGoForward`, `RequestShowDevTool`, `RequestCloseDevtool`
## Development Commands
```bash
# Fix and format code
make fix
# Run examples (macOS requires debug feature)
cargo run --example simple --features debug
# Install debug render process tool
make install
```
### Debug Tools Setup (macOS)
Manual installation required before running with `debug` feature:
```bash
cargo install export-cef-dir
export-cef-dir --force $HOME/.local/share
cargo install bevy_cef_debug_render_process
mv $HOME/.cargo/bin/bevy_cef_debug_render_process "$HOME/.local/share/Chromium Embedded Framework.framework/Libraries/bevy_cef_debug_render_process"
```
## Local Asset Loading
Local HTML/assets served via `cef://localhost/` scheme:
- Place assets in `assets/` directory
- Reference as `CefWebviewUri::local("filename.html")`
## Testing
No automated tests. Testing done through examples:
- `cargo test --workspace --all-features` (for any future tests)
- Examples: simple, js_emit, host_emit, brp, navigation, zoom_level, sprite, devtool, custom_material, preload_scripts, extensions
## Platform Notes
- Primary platform: macOS (uses `objc` crate for window handling)
- CEF framework location: `$HOME/.local/share/Chromium Embedded Framework.framework`
- Windows/Linux: Infrastructure ready but needs testing
- Key resources (`Browsers`, library loaders) are `NonSend` - CEF is not thread-safe
## Workspace Structure
- Root crate: `bevy_cef` (public API)
- `crates/bevy_cef_core`: Core CEF integration logic
- `crates/bevy_cef_debug_render_process`: Debug render process executable

10
Cargo.lock generated
View File

@@ -1930,9 +1930,7 @@ dependencies = [
[[package]] [[package]]
name = "cef" name = "cef"
version = "144.4.0+144.0.13" version = "145.3.0+145.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42320c2356f3fe4ed3f875b8fc93cbbabd1be3c59fcc0a8eb1e5b5c25616ac28"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cargo_metadata", "cargo_metadata",
@@ -1950,9 +1948,7 @@ dependencies = [
[[package]] [[package]]
name = "cef-dll-sys" name = "cef-dll-sys"
version = "144.4.0+144.0.13" version = "145.3.0+145.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d802abd4ac0b8c12be11b6af24100c6e21543c265867ad53067268048bc7e3a"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cmake", "cmake",
@@ -2469,8 +2465,6 @@ checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc"
[[package]] [[package]]
name = "download-cef" name = "download-cef"
version = "2.3.0" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6002a6b95f9f3bbe5693ac02a03221a8e3af6c9f5f4539f5734a8d6cde1a3616"
dependencies = [ dependencies = [
"bzip2", "bzip2",
"clap", "clap",

View File

@@ -13,9 +13,7 @@ exclude = ["assets/"]
[workspace] [workspace]
resolver = "2" resolver = "2"
members = [ members = ["crates/*"]
"crates/*",
]
[workspace.package] [workspace.package]
version = "0.2.0-dev" version = "0.2.0-dev"
@@ -38,9 +36,9 @@ bevy = { version = "0.18", default-features = false, features = [
"picking", "picking",
] } ] }
bevy_remote = "0.18" bevy_remote = "0.18"
cef = { version = "144.4.0" } cef = { path = "../../cef-rs/cef" }
cef-dll-sys = { version = "144.4.0", features = ["sandbox"] } cef-dll-sys = { path = "../../cef-rs/sys" }
bevy_cef = { path = "." , version = "0.2.0-dev" } bevy_cef = { path = ".", version = "0.2.0-dev" }
bevy_cef_core = { path = "crates/bevy_cef_core", version = "0.2.0-dev" } bevy_cef_core = { path = "crates/bevy_cef_core", version = "0.2.0-dev" }
async-channel = { version = "2.5" } async-channel = { version = "2.5" }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
@@ -58,14 +56,18 @@ serde_json = { workspace = true }
raw-window-handle = "0.6" raw-window-handle = "0.6"
[dev-dependencies] [dev-dependencies]
bevy = { workspace = true, default-features = true, features = ["file_watcher"]} bevy = { workspace = true, default-features = true, features = [
"file_watcher",
] }
bevy_cef = { workspace = true, features = ["debug"] } bevy_cef = { workspace = true, features = ["debug"] }
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
objc = { version = "0.2" } objc = { version = "0.2" }
[lints.rust] [lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(feature, values("cargo-clippy"))'] } unexpected_cfgs = { level = "warn", check-cfg = [
'cfg(feature, values("cargo-clippy"))',
] }
[features] [features]
default = [] default = []

View File

@@ -1,19 +0,0 @@
.PHONY: fix install
BIN := bevy_cef_debug_render_process
CEF_LIB := $(HOME)/.local/share/Chromium Embedded Framework.framework/Libraries
.PHONY: fix install
BIN := bevy_cef_debug_render_process
CEF_LIB := $(HOME)/.local/share/Chromium Embedded Framework.framework/Libraries
CARGO_BIN := $(HOME)/.cargo/bin
fix:
cargo clippy --fix --allow-dirty --allow-staged --workspace --all --all-features
cargo fmt --all
install:
cargo install --path ./crates/bevy_cef_debug_render_process --force
mv "$(CARGO_BIN)/$(BIN)" "$(CEF_LIB)/$(BIN)"

View File

@@ -1,3 +1,5 @@
# Not my own repo, but since its the only thing out there that does what i need, i'll have to deal with it, had to fix it's shit first tho cuz ofc....
# bevy_cef # bevy_cef
A powerful Bevy plugin for embedding web content using the Chromium Embedded Framework (CEF). A powerful Bevy plugin for embedding web content using the Chromium Embedded Framework (CEF).

View File

@@ -69,7 +69,7 @@ impl Browsers {
let browser = browser_host_create_browser_sync( let browser = browser_host_create_browser_sync(
Some(&WindowInfo { Some(&WindowInfo {
windowless_rendering_enabled: true as _, windowless_rendering_enabled: true as _,
external_begin_frame_enabled: false as _, external_begin_frame_enabled: true as _,
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
parent_view: match _window_handle { parent_view: match _window_handle {
Some(RawWindowHandle::AppKit(handle)) => handle.ns_view.as_ptr(), Some(RawWindowHandle::AppKit(handle)) => handle.ns_view.as_ptr(),
@@ -78,7 +78,7 @@ impl Browsers {
Some(RawWindowHandle::Wayland(handle)) => handle.surface.as_ptr(), Some(RawWindowHandle::Wayland(handle)) => handle.surface.as_ptr(),
_ => std::ptr::null_mut(), _ => std::ptr::null_mut(),
}, },
// shared_texture_enabled: true as _, shared_texture_enabled: false as _,
..Default::default() ..Default::default()
}), }),
Some(&mut self.client_handler( Some(&mut self.client_handler(

View File

@@ -43,7 +43,7 @@ pub fn create_cef_key_event(
// ButtonState::Pressed if input.just_pressed(key_event.key_code) => { // ButtonState::Pressed if input.just_pressed(key_event.key_code) => {
// cef_key_event_type_t::KEYEVENT_RAWKEYDOWN // cef_key_event_type_t::KEYEVENT_RAWKEYDOWN
// } // }
ButtonState::Pressed => cef_key_event_type_t::KEYEVENT_CHAR, ButtonState::Pressed => cef_key_event_type_t::KEYEVENT_RAWKEYDOWN,
ButtonState::Released => cef_key_event_type_t::KEYEVENT_KEYUP, ButtonState::Released => cef_key_event_type_t::KEYEVENT_KEYUP,
}; };
let windows_key_code = keycode_to_windows_vk(key_event.key_code); let windows_key_code = keycode_to_windows_vk(key_event.key_code);

View File

@@ -41,7 +41,8 @@ pub fn debug_chromium_embedded_framework_dir_path() -> PathBuf {
.unwrap() .unwrap()
.join(".local") .join(".local")
.join("share") .join("share")
.join("Chromium Embedded Framework.framework") .join("avii")
.join("cef")
} }
pub fn debug_render_process_path() -> PathBuf { pub fn debug_render_process_path() -> PathBuf {

View File

@@ -12,7 +12,13 @@ fn main() {
App::new() App::new()
.add_plugins(( .add_plugins((
DefaultPlugins, DefaultPlugins,
CefPlugin::default(), CefPlugin {
command_line_config: CommandLineConfig {
switches: ["--in-process-gpu", "--no-sandbox"].to_vec(),
..Default::default()
},
..Default::default()
},
WebviewExtendMaterialPlugin::<CustomExtension>::default(), WebviewExtendMaterialPlugin::<CustomExtension>::default(),
)) ))
.add_systems(Startup, (spawn_camera, spawn_webview)) .add_systems(Startup, (spawn_camera, spawn_webview))

View File

@@ -10,7 +10,16 @@ use bevy_cef::prelude::*;
fn main() { fn main() {
App::new() App::new()
.add_plugins((DefaultPlugins, CefPlugin::default())) .add_plugins((
DefaultPlugins,
CefPlugin {
command_line_config: CommandLineConfig {
switches: ["--in-process-gpu"].to_vec(),
..Default::default()
},
..Default::default()
},
))
.add_systems( .add_systems(
Startup, Startup,
(spawn_camera, spawn_directional_light, spawn_webview), (spawn_camera, spawn_directional_light, spawn_webview),

View File

@@ -5,7 +5,14 @@ use bevy_cef::prelude::*;
fn main() { fn main() {
App::new() App::new()
.add_plugins((DefaultPlugins, CefPlugin::default())) .add_plugins(DefaultPlugins)
.add_plugins(CefPlugin {
command_line_config: CommandLineConfig {
switches: ["--no-zygote", "--no-sandbox"].to_vec(),
..Default::default()
},
..Default::default()
})
.add_systems( .add_systems(
Startup, Startup,
(spawn_camera, spawn_directional_light, spawn_webview), (spawn_camera, spawn_directional_light, spawn_webview),

View File

@@ -74,7 +74,7 @@ pub struct WebviewSize(pub Vec2);
impl Default for WebviewSize { impl Default for WebviewSize {
fn default() -> Self { fn default() -> Self {
Self(Vec2::splat(800.0)) Self(Vec2::new(768.0, 1024.0))
} }
} }

View File

@@ -24,12 +24,12 @@ impl Plugin for MessageLoopPlugin {
let mut cef_app = let mut cef_app =
BrowserProcessAppBuilder::build(tx, self.config.clone(), self.extensions.clone()); BrowserProcessAppBuilder::build(tx, self.config.clone(), self.extensions.clone());
let ret = execute_process( let _ = execute_process(
Some(args.as_main_args()), Some(args.as_main_args()),
Some(&mut cef_app), Some(&mut cef_app),
std::ptr::null_mut(), std::ptr::null_mut(),
); );
assert_eq!(ret, -1, "cannot execute browser process"); // assert_eq!(ret, -1, "cannot execute browser process");
cef_initialize(&args, &mut cef_app); cef_initialize(&args, &mut cef_app);
@@ -54,20 +54,10 @@ fn load_cef_library(app: &mut App) {
fn cef_initialize(args: &Args, cef_app: &mut cef::App) { fn cef_initialize(args: &Args, cef_app: &mut cef::App) {
let settings = Settings { let settings = Settings {
#[cfg(all(target_os = "macos", feature = "debug"))] root_cache_path: debug_chromium_embedded_framework_dir_path()
framework_dir_path: debug_chromium_embedded_framework_dir_path()
.to_str() .to_str()
.unwrap() .unwrap()
.into(), .into(),
#[cfg(all(target_os = "macos", feature = "debug"))]
browser_subprocess_path: debug_render_process_path().to_str().unwrap().into(),
#[cfg(all(target_os = "macos", feature = "debug"))]
no_sandbox: true as _,
windowless_rendering_enabled: true as _,
// #[cfg(any(target_os = "windows", target_os = "linux"))]
// multi_threaded_message_loop: true as _,
multi_threaded_message_loop: false as _,
external_message_pump: true as _,
..Default::default() ..Default::default()
}; };
assert_eq!( assert_eq!(
@@ -86,6 +76,7 @@ fn cef_do_message_loop_work(
mut timer: Local<Option<MessageLoopTimer>>, mut timer: Local<Option<MessageLoopTimer>>,
mut max_delay_timer: Local<MessageLoopWorkingMaxDelayTimer>, mut max_delay_timer: Local<MessageLoopWorkingMaxDelayTimer>,
) { ) {
// cef::do_message_loop_work();
while let Ok(t) = receiver.try_recv() { while let Ok(t) = receiver.try_recv() {
timer.replace(t); timer.replace(t);
} }
@@ -99,58 +90,3 @@ fn cef_do_message_loop_work(
fn cef_shutdown(_: NonSend<RunOnMainThread>) { fn cef_shutdown(_: NonSend<RunOnMainThread>) {
shutdown(); shutdown();
} }
#[cfg(target_os = "macos")]
mod macos {
use core::sync::atomic::AtomicBool;
use objc::runtime::{Class, Object, Sel};
use objc::{sel, sel_impl};
use std::os::raw::c_char;
use std::os::raw::c_void;
use std::sync::atomic::Ordering;
unsafe extern "C" {
fn class_addMethod(
cls: *const Class,
name: Sel,
imp: *const c_void,
types: *const c_char,
) -> bool;
}
static IS_HANDLING_SEND_EVENT: AtomicBool = AtomicBool::new(false);
extern "C" fn is_handling_send_event(_: &Object, _: Sel) -> bool {
IS_HANDLING_SEND_EVENT.load(Ordering::Relaxed)
}
extern "C" fn set_handling_send_event(_: &Object, _: Sel, flag: bool) {
IS_HANDLING_SEND_EVENT.swap(flag, Ordering::Relaxed);
}
pub fn install_cef_app_protocol() {
unsafe {
let cls = Class::get("NSApplication").expect("NSApplication クラスが見つかりません");
let sel_name = sel!(isHandlingSendEvent);
let success = class_addMethod(
cls as *const _,
sel_name,
is_handling_send_event as *const c_void,
c"c@:".as_ptr() as *const c_char,
);
assert!(success, "メソッド追加に失敗しました");
let sel_set = sel!(setHandlingSendEvent:);
let success2 = class_addMethod(
cls as *const _,
sel_set,
set_handling_send_event as *const c_void,
c"v@:c".as_ptr() as *const c_char,
);
assert!(
success2,
"Failed to add setHandlingSendEvent: to NSApplication"
);
}
}
}

View File

@@ -20,8 +20,13 @@ use bevy_cef_core::prelude::{CefExtensions, CommandLineConfig};
use bevy_remote::RemotePlugin; use bevy_remote::RemotePlugin;
pub mod prelude { pub mod prelude {
pub use crate::{CefPlugin, RunOnMainThread, common::*, navigation::*, webview::prelude::*}; pub use crate::{
pub use bevy_cef_core::prelude::{CefExtensions, CommandLineConfig}; CefPlugin, RunOnMainThread, common::*, navigation::*, system_param::mesh_aabb::*,
webview::prelude::*,
};
pub use bevy_cef_core::prelude::{
Browsers, CefExtensions, CommandLineConfig, create_cef_key_event,
};
} }
pub struct RunOnMainThread; pub struct RunOnMainThread;

View File

@@ -120,7 +120,7 @@ fn pointer_to_webview_uv(
// outside plane bounds // outside plane bounds
return None; return None;
} }
let px = u * tex_size.x; let px = (1.0 - u) * tex_size.x;
let py = (1.0 - v) * tex_size.y; let py = (1.0 - v) * tex_size.y;
Some(Vec2::new(px, py)) Some(Vec2::new(px, py))
} }

View File

@@ -98,7 +98,7 @@ fn on_mouse_wheel(
let Some(pos) = pointer.pointer_pos(webview, cursor_pos) else { let Some(pos) = pointer.pointer_pos(webview, cursor_pos) else {
continue; continue;
}; };
browsers.send_mouse_wheel(&webview, pos, Vec2::new(event.x, event.y)); browsers.send_mouse_wheel(&webview, pos, Vec2::new(event.x, event.y) * 40.0);
} }
} }
} }

View File

@@ -11,6 +11,7 @@
} }
#import webview::util::{ #import webview::util::{
surface_color, surface_color,
overlay_color,
} }
@fragment @fragment
@@ -18,15 +19,13 @@ fn fragment(
in: VertexOutput, in: VertexOutput,
@builtin(front_facing) is_front: bool, @builtin(front_facing) is_front: bool,
) -> FragmentOutput { ) -> FragmentOutput {
var pbr_input = pbr_input_from_standard_material(in, is_front);
pbr_input.material.base_color *= surface_color(in.uv);
pbr_input.material.base_color = alpha_discard(pbr_input.material, pbr_input.material.base_color);
var out: FragmentOutput; var out: FragmentOutput;
if (material.flags & STANDARD_MATERIAL_FLAGS_UNLIT_BIT) == 0u {
out.color = apply_pbr_lighting(pbr_input); var surface = surface_color(in.uv);
out.color = main_pass_post_lighting_processing(pbr_input, out.color); var overlay = overlay_color(in.uv);
}else{ var result_rgb = mix(surface.rgb, overlay.rgb, overlay.a);
out.color = pbr_input.material.base_color;
} out.color = vec4(result_rgb, 1.0);
return out; return out;
} }

View File

@@ -22,7 +22,7 @@ impl Plugin for WebviewMaterialPlugin {
} }
} }
#[derive(Asset, TypePath, AsBindGroup, Debug, Clone, PartialEq, Eq, Hash, Default)] #[derive(Asset, TypePath, AsBindGroup, Debug, Clone, PartialEq, Default)]
pub struct WebviewMaterial { pub struct WebviewMaterial {
/// Holds the texture handle for the webview. /// Holds the texture handle for the webview.
/// ///
@@ -30,6 +30,9 @@ pub struct WebviewMaterial {
#[texture(101)] #[texture(101)]
#[sampler(102)] #[sampler(102)]
pub surface: Option<Handle<Image>>, pub surface: Option<Handle<Image>>,
#[texture(103)]
#[sampler(104)]
pub overlay: Option<Handle<Image>>,
} }
impl Material for WebviewMaterial {} impl Material for WebviewMaterial {}

View File

@@ -8,6 +8,13 @@
@group(#{MATERIAL_BIND_GROUP}) @binding(101) var surface_texture: texture_2d<f32>; @group(#{MATERIAL_BIND_GROUP}) @binding(101) var surface_texture: texture_2d<f32>;
@group(#{MATERIAL_BIND_GROUP}) @binding(102) var surface_sampler: sampler; @group(#{MATERIAL_BIND_GROUP}) @binding(102) var surface_sampler: sampler;
@group(#{MATERIAL_BIND_GROUP}) @binding(103) var overlay_texture: texture_2d<f32>;
@group(#{MATERIAL_BIND_GROUP}) @binding(104) var overlay_sampler: sampler;
fn surface_color(uv: vec2<f32>) -> vec4<f32> { fn surface_color(uv: vec2<f32>) -> vec4<f32> {
return textureSampleBias(surface_texture, surface_sampler, uv, view.mip_bias); return textureSampleBias(surface_texture, surface_sampler, uv, view.mip_bias);
}
fn overlay_color(uv: vec2<f32>) -> vec4<f32> {
return textureSampleBias(overlay_texture, overlay_sampler, uv, view.mip_bias);
} }