sync
This commit is contained in:
parent
b83e6d3a0f
commit
36e355335f
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1739,6 +1739,7 @@ dependencies = [
|
|||||||
"pollster",
|
"pollster",
|
||||||
"quick_cache",
|
"quick_cache",
|
||||||
"regex",
|
"regex",
|
||||||
|
"rust-embed",
|
||||||
"wgpu",
|
"wgpu",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -12,5 +12,9 @@ mp_core = { path = "../mp_core", version = "*" }
|
|||||||
flume = "0.11.1"
|
flume = "0.11.1"
|
||||||
pollster = "0.4.0"
|
pollster = "0.4.0"
|
||||||
quick_cache = "0.6.9"
|
quick_cache = "0.6.9"
|
||||||
encase = {version="0.10.0",features=["glam"]}
|
encase = { version = "0.10.0", features = ["glam"] }
|
||||||
image = "0.25.5"
|
image = "0.25.5"
|
||||||
|
rust-embed = "8.5.0"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
regex = "1.11.1"
|
||||||
|
|||||||
122
mp_elements/build.rs
Normal file
122
mp_elements/build.rs
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
use regex::Regex;
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let watch_dir = "shaders/elements";
|
||||||
|
for entry in fs::read_dir(watch_dir).unwrap() {
|
||||||
|
let path = entry.unwrap().path();
|
||||||
|
if path.is_file() {
|
||||||
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let crate_path = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||||
|
|
||||||
|
let shader_path_base = Path::new(&crate_path).join("shaders");
|
||||||
|
|
||||||
|
for entry in fs::read_dir(watch_dir).unwrap() {
|
||||||
|
let path = entry.unwrap().path();
|
||||||
|
if path.is_file() {
|
||||||
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
|
}
|
||||||
|
|
||||||
|
let merged_shader = merge_shader(&path.display().to_string(), &shader_path_base);
|
||||||
|
|
||||||
|
let out_path = Path::new(&crate_path)
|
||||||
|
.join("shaders")
|
||||||
|
.join("elements")
|
||||||
|
.join(format!(
|
||||||
|
"{}_merged.wgsl",
|
||||||
|
path.file_stem().unwrap().to_str().unwrap()
|
||||||
|
));
|
||||||
|
|
||||||
|
fs::write(out_path, merged_shader).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge_shader<'a>(shader: &'a str, base: &std::path::Path) -> String {
|
||||||
|
const TOOLS: &'static str = r#"// This is a tool that merges the shader code with the shader code from the shader module.
|
||||||
|
|
||||||
|
struct UniformCommonTools {
|
||||||
|
model_matrix: mat4x4f,
|
||||||
|
view_matrix: mat4x4f,
|
||||||
|
proj_matrix: mat4x4f,
|
||||||
|
camera_x: f32,
|
||||||
|
camera_y: f32,
|
||||||
|
camera_z: f32,
|
||||||
|
camera_target_x: f32,
|
||||||
|
camera_target_y: f32,
|
||||||
|
camera_target_z: f32,
|
||||||
|
camera_up_x: f32,
|
||||||
|
camera_up_y: f32,
|
||||||
|
camera_up_z: f32,
|
||||||
|
|
||||||
|
// camera_position: vec3f,
|
||||||
|
// camera_front: vec3f,
|
||||||
|
// camera_up: vec3f,
|
||||||
|
}
|
||||||
|
|
||||||
|
@group(0) @binding(0) var<uniform> common_tools: UniformCommonTools;
|
||||||
|
"#;
|
||||||
|
|
||||||
|
let path = std::path::Path::new(shader);
|
||||||
|
|
||||||
|
let mut visited_files = std::collections::HashSet::new();
|
||||||
|
|
||||||
|
let mut result = process_file(&path, &mut visited_files, &base);
|
||||||
|
|
||||||
|
// 将工具代码插入到 shader 代码的开头
|
||||||
|
result.insert_str(0, TOOLS);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_file<'a, P: AsRef<std::path::Path> + 'a, B: AsRef<std::path::Path>>(
|
||||||
|
file_path: P,
|
||||||
|
visited_files: &mut std::collections::HashSet<std::path::PathBuf>,
|
||||||
|
base_path: B,
|
||||||
|
) -> String {
|
||||||
|
let base_path = base_path.as_ref();
|
||||||
|
let file_path = file_path.as_ref();
|
||||||
|
|
||||||
|
// 如果该文件已经处理过,则避免死循环
|
||||||
|
if visited_files.contains(file_path) {
|
||||||
|
return String::new(); // 返回空字符串表示已经处理过
|
||||||
|
}
|
||||||
|
|
||||||
|
visited_files.insert(file_path.to_path_buf());
|
||||||
|
|
||||||
|
let content = std::fs::read_to_string(file_path).unwrap_or_else(|_| {
|
||||||
|
panic!("Failed to read file: {}", file_path.display());
|
||||||
|
});
|
||||||
|
|
||||||
|
let re = Regex::new(r#"#include\s+\"([^\"]+\.wgsl)\";"#).unwrap();
|
||||||
|
|
||||||
|
let result = re.replace_all(&content, |caps: ®ex::Captures| {
|
||||||
|
let included_file = &caps[1]; // 获取文件名
|
||||||
|
|
||||||
|
let included_path = resolve_included_file(included_file, base_path.as_ref());
|
||||||
|
|
||||||
|
let included_content = process_file(
|
||||||
|
&included_path,
|
||||||
|
visited_files,
|
||||||
|
base_path.parent().unwrap_or(base_path),
|
||||||
|
);
|
||||||
|
|
||||||
|
included_content
|
||||||
|
});
|
||||||
|
|
||||||
|
result.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_included_file(included_file: &str, base_path: &std::path::Path) -> std::path::PathBuf {
|
||||||
|
let included_path = std::path::Path::new(included_file);
|
||||||
|
|
||||||
|
if included_path.is_relative() {
|
||||||
|
base_path.join(included_path)
|
||||||
|
} else {
|
||||||
|
included_path.to_path_buf()
|
||||||
|
}
|
||||||
|
}
|
||||||
103
mp_elements/shaders/elements/ppi_merged.wgsl
Normal file
103
mp_elements/shaders/elements/ppi_merged.wgsl
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// This is a tool that merges the shader code with the shader code from the shader module.
|
||||||
|
|
||||||
|
struct UniformCommonTools {
|
||||||
|
model_matrix: mat4x4f,
|
||||||
|
view_matrix: mat4x4f,
|
||||||
|
proj_matrix: mat4x4f,
|
||||||
|
camera_x: f32,
|
||||||
|
camera_y: f32,
|
||||||
|
camera_z: f32,
|
||||||
|
camera_target_x: f32,
|
||||||
|
camera_target_y: f32,
|
||||||
|
camera_target_z: f32,
|
||||||
|
camera_up_x: f32,
|
||||||
|
camera_up_y: f32,
|
||||||
|
camera_up_z: f32,
|
||||||
|
|
||||||
|
// camera_position: vec3f,
|
||||||
|
// camera_front: vec3f,
|
||||||
|
// camera_up: vec3f,
|
||||||
|
}
|
||||||
|
|
||||||
|
@group(0) @binding(0) var<uniform> common_tools: UniformCommonTools;
|
||||||
|
const PI:f32 = 3.14159265358979323846264338327950288;
|
||||||
|
const TWO_PI:f32 = 6.28318530717958647692528676655900576;
|
||||||
|
const HALF_PI:f32 = 1.57079632679489661923132169163975144;
|
||||||
|
const LOG2:f32 = 0.693147180559945309417232121458176568;
|
||||||
|
const LOG10:f32 = 2.30258509299404568401799145468436421;
|
||||||
|
|
||||||
|
// Common Uniforms
|
||||||
|
// common_tools
|
||||||
|
// model_matrix: mat4,
|
||||||
|
// view_matrix: mat4,
|
||||||
|
// proj_matrix: mat4,
|
||||||
|
// camera_position: vec3,
|
||||||
|
// camera_front: vec3,
|
||||||
|
// camera_up: vec3,
|
||||||
|
// light_position: vec3,
|
||||||
|
// light_color: vec3,
|
||||||
|
// light_intensity: float,
|
||||||
|
|
||||||
|
// Uniforms
|
||||||
|
@group(1) @binding(0) var<uniform> params: UniformParams;
|
||||||
|
// Data Buffer
|
||||||
|
@group(1) @binding(1) var<storage> data: array<f32>;
|
||||||
|
|
||||||
|
struct UniformParams {
|
||||||
|
origin: vec4f
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
@builtin(position) position: vec4f,
|
||||||
|
@location(0) r_range: vec4f,
|
||||||
|
@location(1) idx: u32
|
||||||
|
}
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vertex(
|
||||||
|
@location(0) position: vec4f,
|
||||||
|
@location(1) r_range: vec4f,
|
||||||
|
// @location(2) idx: u32
|
||||||
|
) -> VertexOutput {
|
||||||
|
|
||||||
|
var out: VertexOutput;
|
||||||
|
|
||||||
|
// Transform position
|
||||||
|
out.position = common_tools.proj_matrix * common_tools.view_matrix * common_tools.model_matrix * vec4f(position, 1.0);
|
||||||
|
// out.position = vec4(position.xyz, 1.0);
|
||||||
|
out.r_range = r_range;
|
||||||
|
let idx = u32(position.w);
|
||||||
|
out.idx = idx;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn polar_forward(cartesian: vec3f) -> vec3f {
|
||||||
|
let r = length(cartesian.xy - params.origin.xy);
|
||||||
|
let theta = atan2(cartesian.y, cartesian.x);
|
||||||
|
let z = cartesian.z;
|
||||||
|
return vec3f(r, theta, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn fragment(input: VertexOutput) -> @location(0) vec4f {
|
||||||
|
// Sample data texture
|
||||||
|
let value = data[input.idx];
|
||||||
|
let ear = polar_forward(input.position.xyz);
|
||||||
|
// var color = linear_colormap(value);
|
||||||
|
|
||||||
|
var color = clamp(value / 75.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
// let r = ear.x;
|
||||||
|
// Valid range
|
||||||
|
// let r_range = input.r_range;
|
||||||
|
|
||||||
|
// let outside_lower_bound = step(r, r_range.x);
|
||||||
|
// let outside_upper_bound = step(r_range.y, r);
|
||||||
|
// let is_outside = outside_lower_bound + outside_upper_bound;
|
||||||
|
// color.a *= 1.0 - is_outside;
|
||||||
|
|
||||||
|
|
||||||
|
return vec4(color,color,color, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,8 +1,10 @@
|
|||||||
|
use crate::Shaders;
|
||||||
|
use rust_embed::RustEmbed;
|
||||||
use std::{ops::Sub, result, vec};
|
use std::{ops::Sub, result, vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{BufferKey, Ctx, DataBufferPool},
|
app::{BufferKey, Ctx, DataBufferPool},
|
||||||
utils::merge_shader,
|
utils::get_shader,
|
||||||
};
|
};
|
||||||
use bytemuck;
|
use bytemuck;
|
||||||
use glam::{Vec3, Vec4};
|
use glam::{Vec3, Vec4};
|
||||||
@ -259,8 +261,9 @@ impl Element for PPI {
|
|||||||
impl PPI {
|
impl PPI {
|
||||||
fn init_shader(device: &wgpu::Device) -> wgpu::ShaderModule {
|
fn init_shader(device: &wgpu::Device) -> wgpu::ShaderModule {
|
||||||
// let shader_str = merge_shader(r#"/Users/tsuki/projects/mp/mp_elements/shaders/ppi.wgsl"#);
|
// let shader_str = merge_shader(r#"/Users/tsuki/projects/mp/mp_elements/shaders/ppi.wgsl"#);
|
||||||
let shader_str =
|
|
||||||
merge_shader(r#"C:\Users\qwin7\projects\radarmp\mp_elements\shaders\ppi.wgsl"#);
|
let shader_str = get_shader("ppi_merged.wgsl").as_ref();
|
||||||
|
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: Some("PPI Shader Module"),
|
label: Some("PPI Shader Module"),
|
||||||
source: wgpu::ShaderSource::Wgsl(shader_str.into()),
|
source: wgpu::ShaderSource::Wgsl(shader_str.into()),
|
||||||
|
|||||||
@ -5,3 +5,8 @@ pub mod renderer;
|
|||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
pub use app::App;
|
pub use app::App;
|
||||||
|
use rust_embed::RustEmbed;
|
||||||
|
|
||||||
|
#[derive(RustEmbed)]
|
||||||
|
#[folder = "shaders/"]
|
||||||
|
pub struct Shaders;
|
||||||
|
|||||||
@ -1,105 +1,9 @@
|
|||||||
use std::path::PathBuf;
|
use crate::Shaders;
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
use regex::Regex;
|
pub fn get_shader(name: &str) -> Cow<'static, str> {
|
||||||
pub(crate) fn merge_shader<'a>(shader: &'a str) -> String {
|
let file = Shaders::get(name).unwrap();
|
||||||
const TOOLS: &'static str = r#"// This is a tool that merges the shader code with the shader code from the shader module.
|
let string = String::from_utf8_lossy(&file.data);
|
||||||
|
string
|
||||||
struct UniformCommonTools {
|
|
||||||
model_matrix: mat4x4f,
|
|
||||||
view_matrix: mat4x4f,
|
|
||||||
proj_matrix: mat4x4f,
|
|
||||||
camera_x: f32,
|
|
||||||
camera_y: f32,
|
|
||||||
camera_z: f32,
|
|
||||||
camera_target_x: f32,
|
|
||||||
camera_target_y: f32,
|
|
||||||
camera_target_z: f32,
|
|
||||||
camera_up_x: f32,
|
|
||||||
camera_up_y: f32,
|
|
||||||
camera_up_z: f32,
|
|
||||||
|
|
||||||
// camera_position: vec3f,
|
|
||||||
// camera_front: vec3f,
|
|
||||||
// camera_up: vec3f,
|
|
||||||
}
|
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> common_tools: UniformCommonTools;
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let mut visited_files = std::collections::HashSet::new();
|
|
||||||
let path: PathBuf = PathBuf::from(shader);
|
|
||||||
|
|
||||||
let base = match path.canonicalize() {
|
|
||||||
Ok(path) => path.parent().unwrap().to_owned(),
|
|
||||||
Err(e) => {
|
|
||||||
// panic!("Failed to canonicalize path: {}", e);
|
|
||||||
// PathBuf::from(r#"/Users/tsuki/projects/mp/mp_elements/shaders"#)
|
|
||||||
PathBuf::from(r#"C:\Users\qwin7\projects\radarmp\mp_elements\shaders"#)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut result = process_file(&path, &mut visited_files, &base);
|
|
||||||
|
|
||||||
// 将工具代码插入到 shader 代码的开头
|
|
||||||
result.insert_str(0, TOOLS);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn process_file<'a, P: AsRef<std::path::Path> + 'a, B: AsRef<std::path::Path>>(
|
|
||||||
file_path: P,
|
|
||||||
visited_files: &mut std::collections::HashSet<std::path::PathBuf>,
|
|
||||||
base_path: B,
|
|
||||||
) -> String {
|
|
||||||
let base_path = base_path.as_ref();
|
|
||||||
let file_path = file_path.as_ref();
|
|
||||||
|
|
||||||
// 如果该文件已经处理过,则避免死循环
|
|
||||||
if visited_files.contains(file_path) {
|
|
||||||
return String::new(); // 返回空字符串表示已经处理过
|
|
||||||
}
|
|
||||||
|
|
||||||
visited_files.insert(file_path.to_path_buf());
|
|
||||||
|
|
||||||
let content = std::fs::read_to_string(file_path).unwrap_or_else(|_| {
|
|
||||||
panic!("Failed to read file: {}", file_path.display());
|
|
||||||
});
|
|
||||||
|
|
||||||
let re = Regex::new(r#"#include\s+\"([^\"]+\.wgsl)\";"#).unwrap();
|
|
||||||
|
|
||||||
let result = re.replace_all(&content, |caps: ®ex::Captures| {
|
|
||||||
let included_file = &caps[1]; // 获取文件名
|
|
||||||
|
|
||||||
let included_path = resolve_included_file(included_file, base_path.as_ref());
|
|
||||||
|
|
||||||
let included_content = process_file(
|
|
||||||
&included_path,
|
|
||||||
visited_files,
|
|
||||||
base_path.parent().unwrap_or(base_path),
|
|
||||||
);
|
|
||||||
|
|
||||||
included_content
|
|
||||||
});
|
|
||||||
|
|
||||||
result.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_included_file(included_file: &str, base_path: &std::path::Path) -> std::path::PathBuf {
|
|
||||||
let included_path = std::path::Path::new(included_file);
|
|
||||||
|
|
||||||
if included_path.is_relative() {
|
|
||||||
base_path.join(included_path)
|
|
||||||
} else {
|
|
||||||
included_path.to_path_buf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod test {
|
|
||||||
use super::merge_shader;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test() {
|
|
||||||
let merged = merge_shader("/Users/tsuki/projects/mp/mp_elements/shaders/ppi.wgsl");
|
|
||||||
println!("{}", merged);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user