sync
This commit is contained in:
parent
b83e6d3a0f
commit
36e355335f
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1739,6 +1739,7 @@ dependencies = [
|
||||
"pollster",
|
||||
"quick_cache",
|
||||
"regex",
|
||||
"rust-embed",
|
||||
"wgpu",
|
||||
]
|
||||
|
||||
|
||||
@ -12,5 +12,9 @@ mp_core = { path = "../mp_core", version = "*" }
|
||||
flume = "0.11.1"
|
||||
pollster = "0.4.0"
|
||||
quick_cache = "0.6.9"
|
||||
encase = {version="0.10.0",features=["glam"]}
|
||||
encase = { version = "0.10.0", features = ["glam"] }
|
||||
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 crate::{
|
||||
app::{BufferKey, Ctx, DataBufferPool},
|
||||
utils::merge_shader,
|
||||
utils::get_shader,
|
||||
};
|
||||
use bytemuck;
|
||||
use glam::{Vec3, Vec4};
|
||||
@ -259,8 +261,9 @@ impl Element for PPI {
|
||||
impl PPI {
|
||||
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#"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 {
|
||||
label: Some("PPI Shader Module"),
|
||||
source: wgpu::ShaderSource::Wgsl(shader_str.into()),
|
||||
|
||||
@ -5,3 +5,8 @@ pub mod renderer;
|
||||
mod utils;
|
||||
|
||||
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(crate) fn merge_shader<'a>(shader: &'a str) -> 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 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);
|
||||
}
|
||||
pub fn get_shader(name: &str) -> Cow<'static, str> {
|
||||
let file = Shaders::get(name).unwrap();
|
||||
let string = String::from_utf8_lossy(&file.data);
|
||||
string
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user