我正在尝试编写一个 WGSL 着色器来读取存储在存储缓冲区中的八叉树。问题是,编译器不喜欢我正在计算的动态索引来访问存储缓冲区中的叶子。wgpu 产生以下验证错误:
thread 'main' panicked at 'wgpu error: Validation Error
Caused by:
In Device::create_shader_module
Function [1] 'get_voxel' is invalid
Expression [68] is invalid
The expression [67] may only be indexed by a constant
Run Code Online (Sandbox Code Playgroud)
八叉树的结构使得我可以在 GPU 上遍历它。这篇 NVIDIA 论文概述了该结构:https://developer.nvidia.com/gpugems/gpugems2/part-v-image-orient-computing/chapter-37-octree-textures-gpu
本质上,八叉树是一个由IndirectionGrids 组成的数组,每个八叉树在内存中都IndirectionGrid恰好有 8个。GridCell网格单元可以表示指向另一个网格的指针IndirectionGrid,也可以表示一些数据。
假设八叉树最深处代表 16x16x16 网格。我想在 7,7,7 点到达GridCell。我们知道 7,7,7 位于根的单元格 0 中IndirectionGrid,因为坐标的每个分量都小于中点。GridCell如果我们将坐标分量相加,我们就可以获得当前 的索引IndirectionGrid。因为我正在遍历一棵树,所以我在每个级别都执行此操作。下面是演示这一点的不完整代码。
引起问题的行是let cell = grid.cells[grid_index].data;
所以最终我的问题是,是否允许动态索引?有什么我可以改变的东西可以神奇地让它发挥作用吗?或者我需要了解更多关于 WebGPU 所做的权衡的背景信息吗?
thread 'main' …Run Code Online (Sandbox Code Playgroud) 当我尝试制作 wgpu 表面时,出现此错误:
error[E0277]: the trait bound `Window: raw_window_handle::HasRawDisplayHandle` is not satisfied
--> src/lib.rs:34:56
|
34 | let surface = unsafe { instance.create_surface(&window) }.unwrap();
| -------------- ^^^^^^^ the trait `raw_window_handle::HasRawDisplayHandle` is not implemented for `Window`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `raw_window_handle::HasRawDisplayHandle`:
&'a T
raw_window_handle::borrowed::DisplayHandle<'_>
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
let surface = unsafe { instance.create_surface(&window) }.unwrap();
我不知道如何解决这个问题,我尝试修复但一切都是徒劳的。
这几天在学习wgpu,有一点比较困惑。当我浏览 wgpu 示例(https://github.com/gfx-rs/wgpu/tree/master/wgpu/examples)时,他们对其着色器使用以下语法:
struct VertexOutput {
@location(0) color: vec4<f32>,
@builtin(position) position: vec4<f32>,
}
Run Code Online (Sandbox Code Playgroud)
但我必须像这样编写我的着色器:
struct VertexOutput {
[[location(0)]] color: vec4<f32>;
[[builtin(position)]] position: vec4<f32>;
};
Run Code Online (Sandbox Code Playgroud)
@比起语法,我更喜欢[[]]语法。我的猜测是,这是我需要在 Cargo.toml 中启用的功能,但我无法找出这是什么功能。因此,如果有人能告诉我如何@在我的 wgsl 着色器中使用语法,我将不胜感激。
我目前有一个BindGroupandBindGroupLayout看起来像这样:
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: None,
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
multisampled: false,
},
count: None,
}],
});
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: None,
entries: &[wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::TextureView(&target),
}],
layout: &bind_group_layout,
});
Run Code Online (Sandbox Code Playgroud)
并按预期工作。
对于上下文:我在渲染通道中使用它们来进行后处理。
现在我的着色器中还需要一个Sampler。首先我创建了Sampler
let linear_sampler = device.create_sampler(&wgpu::SamplerDescriptor {
mag_filter: wgpu::FilterMode::Nearest,
min_filter: wgpu::FilterMode::Nearest,
mipmap_filter: wgpu::FilterMode::Nearest,
..Default::default()
});
Run Code Online (Sandbox Code Playgroud)
并将其添加到布局和绑定组中,如下所示:
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 wgpu 渲染半透明 png 图像。我遇到一个问题,显示了一些不应该显示的像素。例如,在我的图像左侧有一个灰色 (128, 128, 128) 块,其 alpha 值为 0,这意味着它应该是不可见的,对吗?我已将纹理格式设置为 Rgba8UnormSrgb:
let texture = device.create_texture(
&wgpu::TextureDescriptor {
label,
size,
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::RENDER_ATTACHMENT,
}
);
Run Code Online (Sandbox Code Playgroud)
这是 png 图像和 jpg 等效图像,这是 wgpu 正在渲染的图像。
https://user-images.githubusercontent.com/99501993/169669616-f3386235-73d3-45b8-9415-003c480f686f.png
https://user-images.githubusercontent.com/99501993/169669627-cdabd091-6886-43cd-b6f5 -2c110d7b44d1.png
我有一个用 wgpu/rust 编写的物理模拟器,当我从命令行运行时它可以工作。但是,当我尝试在 chrome v114 上运行(根据我在网上看到的支持)时,我收到以下错误,指出计算工作组的最大数量为零。我打印了适配器功能,得到以下信息:Limits { . . . max_compute_workgroup_storage_size: 0, max_compute_invocations_per_workgroup: 0, max_compute_workgroup_size_x: 0, max_compute_workgroup_size_y: 0, max_compute_workgroup_size_z: 0, max_compute_workgroups_per_dimension: 0, max_push_constant_size: 256 }
此外,抛出错误时控制台会转储以下内容:
Version: WebGL 2.0 (OpenGL ES 3.0 Chromium)
我的适配器设置错误吗?或者 wgpu 还不支持浏览器中的计算着色器?欢迎任何建议。感谢大家。
编辑:以防万一这会破解代码,这些是我在本机运行时的设备功能。
...
max_compute_workgroup_storage_size: 16384,
max_compute_invocations_per_workgroup: 256, max_compute_workgroup_size_x: 256, max_compute_workgroup_size_y: 256, max_compute_workgroup_size_z: 64, max_compute_workgroups_per_dimension: 65535, max_push_constant_size: 0 }```
Run Code Online (Sandbox Code Playgroud) 我试图了解 wgpu 和 Dawn 的一般概念。
据我了解,Khronos 的 WebGPU 标准有两种主要实现:Mozilla 的 wgpu 和 Google 的 Dawn。
我的理解是否正确:
-wgpu:它是一个 C/Rust 库,可以编译成操作系统的可执行文件和浏览器的 WebAssembly 代码吗?
-Dawn:只能为浏览器创建Web Assembly代码。
我还想问:wgpu 可以创建 WebAssembly 代码吗?wgpu 是否只转换其 API 代码或 C/C++ 代码?我想不通。