# ... from scipy.spatial.transform import Rotation class App: # ... def __init__(self): # ... self.instance_count = 10 # ... instance_data = b"" for _ in range(self.instance_count): trans = np.eye(4) trans[:3, 3] = np.random.uniform(-5, 5, 3) rot = np.eye(4) rot[:3, :3] = Rotation.random().as_matrix() instance_data += (trans @ rot).T.astype(np.float32).tobytes() self.instance_buffer = self.device.create_buffer_with_data( data=instance_data, usage=wgpu.BufferUsage.VERTEX ) # ... instance_buffer_descriptor = { "array_stride": 4 * 4 * 4, "step_mode": wgpu.VertexStepMode.instance, "attributes": [ { "format": wgpu.VertexFormat.float32x4, "offset": 0, "shader_location": 3, }, { "format": wgpu.VertexFormat.float32x4, "offset": 4 * 4, "shader_location": 4, }, { "format": wgpu.VertexFormat.float32x4, "offset": 8 * 4, "shader_location": 5, }, { "format": wgpu.VertexFormat.float32x4, "offset": 12 * 4, "shader_location": 6, }, ], } self.pipeline = self.device.create_render_pipeline( # ... vertex={ "module": shader_module, "entry_point": "vs_main", "buffers": [vertex_buffer_descriptor, instance_buffer_descriptor], }, # ... ) def loop(self): # ... render_pass.set_vertex_buffer(1, self.instance_buffer) # ... render_pass.draw_indexed(36, self.instance_count)
struct RenderParams { light: vec4<f32>, view: mat4x4<f32>, proj: mat4x4<f32>, }; @group(0) @binding(0) var<uniform> params: RenderParams; @group(0) @binding(1) var texture: texture_2d<f32>; @group(0) @binding(2) var samplr: sampler; struct VertexInput { @location(0) position: vec3<f32>, @location(1) normal: vec3<f32>, @location(2) uv: vec2<f32>, }; struct InstanceInput { @location(3) c0: vec4<f32>, @location(4) c1: vec4<f32>, @location(5) c2: vec4<f32>, @location(6) c3: vec4<f32>, } struct VertexOutput { @builtin(position) clip: vec4<f32>, @location(0) position: vec3<f32>, @location(1) normal: vec3<f32>, @location(2) uv: vec2<f32>, }; @vertex fn vs_main(in: VertexInput, instance: InstanceInput) -> VertexOutput { let model = mat4x4<f32>(instance.c0, instance.c1, instance.c2, instance.c3); let rot = mat3x3<f32>(instance.c0.xyz, instance.c1.xyz, instance.c2.xyz); var out: VertexOutput; let world_pos = model * vec4<f32>(in.position, 1.0); out.clip = params.proj * params.view * world_pos; out.position = world_pos.xyz / world_pos.w; out.normal = rot * in.normal; out.uv = in.uv; return out; } @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { let light_dir = normalize(params.light.xyz - in.position); let shading = clamp(dot(light_dir, normalize(in.normal)), 0.1, 1.0); let color = textureSample(texture, samplr, in.uv); return vec4<f32>(color.xyz * shading, 1.0); }
# ... import random from imgui_bundle import imgui # Before rendercanvas from rendercanvas.auto import RenderCanvas, loop from wgpu.utils.imgui import ImguiRenderer class App: # ... def __init__(self): # ... self.imgui_renderer = ImguiRenderer(self.device, self.canvas) def loop(self): # ... self.imgui_renderer.render() def update_gui(self): imgui.begin("Window", None) imgui.text("Example Text") if imgui.button("Hello"): print("World") imgui.end() def run(self): self.canvas.request_draw(self.loop) self.imgui_renderer.set_gui(self.update_gui) loop.run()