diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 8126d5b1..3fbf11e5 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -894,12 +894,17 @@ void V_TickForever(WaveLaneCtx *lane) frame->draw_cursor = MulXformV2(frame->xf.ui_to_draw, frame->ui_cursor); frame->world_cursor = MulXformV2(frame->xf.ui_to_world, frame->ui_cursor); + b32 show_editor_ui = TweakBool("Show editor UI", 0); + frame->world_selection_start = frame->world_cursor; if (frame->is_editing) { b32 m1_held = frame->held_buttons[Button_M1]; b32 m2_held = frame->held_buttons[Button_M2]; - // frame->selection_mode = V_SelectionMode_Tile; + if (show_editor_ui) + { + frame->selection_mode = V_SelectionMode_Tile; + } if (m1_held) { frame->is_selecting = 1; @@ -1073,7 +1078,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Build panels - if (TweakBool("Show editor UI", 0) && frame->is_editing) + if (show_editor_ui && frame->is_editing) { Struct(PanelDfsNode) { PanelDfsNode *next; b32 visited; V_Panel *panel; UI_Checkpoint cp; }; PanelDfsNode *first_panel_dfs = PushStruct(frame->arena, PanelDfsNode); @@ -2682,12 +2687,14 @@ void V_TickForever(WaveLaneCtx *lane) emitter->pos = frame->world_cursor; emitter->angle = AngleFromVec2(dir); - emitter->count = 1000; + emitter->count = 100; emitter->speed = 10; emitter->seed = RandU64FromState(&frame->rand); emitter->speed_spread = 1; - emitter->angle_spread = 1; + // emitter->angle_spread = 1; + // emitter->angle_spread = 0.5; + emitter->angle_spread = Tau / 4; } // Flatten emitters list @@ -2736,7 +2743,6 @@ void V_TickForever(WaveLaneCtx *lane) params.target_rw = draw_target_rw; params.xf = frame->xf; params.seed = RandU64FromState(&frame->rand); - params.noise = G_BasicNoiseTexture(); params.selection_mode = frame->selection_mode; params.equipped_tile = frame->equipped_tile; @@ -2770,6 +2776,7 @@ void V_TickForever(WaveLaneCtx *lane) // Constants G_SetConstant(frame->cl, V_ShaderConst_State, gpu_state_ref); G_SetConstant(frame->cl, V_ShaderConst_Params, gpu_params_ref); + G_SetConstant(frame->cl, V_ShaderConst_NoiseTex, G_BasicNoiseTexture()); // Sync G_DumbGlobalMemorySync(frame->cl); @@ -2795,6 +2802,19 @@ void V_TickForever(WaveLaneCtx *lane) G_DiscardRenderTarget(frame->cl, draw_target); + ////////////////////////////// + //- Particle simulation pass + + { + // Emit particles + G_Compute(frame->cl, V_EmitParticlesCS, V_ThreadGroupSizeFromBufferSize(emitters_count)); + + G_DumbMemorySync(frame->cl, gpu_particles); + + // Simulate particles + G_Compute(frame->cl, V_SimParticlesCS, V_ThreadGroupSizeFromBufferSize(max_particles)); + } + ////////////////////////////// //- Backdrop pass @@ -2820,19 +2840,6 @@ void V_TickForever(WaveLaneCtx *lane) ); } - ////////////////////////////// - //- Particle simulation pass - - { - // Emit particles - G_Compute(frame->cl, V_EmitParticlesCS, V_ThreadGroupSizeFromBufferSize(emitters_count)); - - G_DumbMemorySync(frame->cl, gpu_particles); - - // Simulate particles - G_Compute(frame->cl, V_SimParticlesCS, V_ThreadGroupSizeFromBufferSize(max_particles)); - } - ////////////////////////////// //- Overlay pass diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index 85db275a..24d09c9a 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -144,6 +144,25 @@ ComputeShader2D(V_BackdropCS, 8, 8) result = bounds_color; } } + + + + + // TODO: Remove this + // Decals test + { + RWTexture2D decals = G_Dereference(params.decals); + Vec2 decal_pos = mul(params.xf.world_to_decal, Vec3(world_pos, 1)); + // Vec2 decal_uv = decal_pos / countof(decals); + V_ParticleKind decal = decals.Load(decal_pos); + + if (decal == V_ParticleKind_Test) + { + result = Color_Yellow; + // result = LinearFromSrgb(Vec4(0.5, 0.1, 0.1, 1)); + } + } + } target[SV_DispatchThreadID] = result; @@ -235,6 +254,7 @@ ComputeShader(V_SimParticlesCS, 64) V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; RWStructuredBuffer particles = G_Dereference(params.particles); RWTexture2D decals = G_Dereference(params.decals); + Texture2D tiles = G_Dereference(params.tiles); u32 particle_idx = SV_DispatchThreadID; if (particle_idx < params.max_particles) @@ -247,17 +267,14 @@ ComputeShader(V_SimParticlesCS, 64) { V_Emitter emitter = G_Dereference(params.emitters)[particle.emitter_init_num - 1]; - // TODO: Faster mix u64 seed = MixU64(emitter.seed + particle.idx_in_emitter); - - // TODO: Blue noise u32 speed_noise = ((u32)seed >> 0) & 0xFFFF; u32 angle_noise = ((u32)seed >> 16) & 0xFFFF; f32 speed_rand = speed_noise / (f32)0xFFFF; f32 angle_rand = angle_noise / (f32)0xFFFF; - f32 speed = emitter.speed + ((speed_rand * 2 - 1) * emitter.speed_spread); - f32 angle = emitter.angle + ((angle_rand * 2 - 1) * emitter.angle_spread); + f32 speed = emitter.speed + ((speed_rand - 0.5) * emitter.speed_spread); + f32 angle = emitter.angle + ((angle_rand - 0.5) * emitter.angle_spread); particle.pos = emitter.pos; particle.velocity = Vec2(cos(angle), sin(angle)) * speed; @@ -268,7 +285,100 @@ ComputeShader(V_SimParticlesCS, 64) // Simulate { f32 dt = params.dt; - particle.pos += particle.velocity * dt; + + Vec2 pos_a = particle.pos; + Vec2 pos_b = pos_a + particle.velocity * dt; + + // TODO: Don't query tiles + Vec2I32 tile_pos_a = S_TilePosFromWorldPos(pos_a); + S_TileKind tile_a = tiles.Load(Vec3I32(tile_pos_a, 0)); + b32 is_blocked_a = tile_a == S_TileKind_Wall; + + Vec2 pos_a_decal = mul(params.xf.world_to_decal, Vec3(pos_a, 1)); + Vec2 pos_b_decal = mul(params.xf.world_to_decal, Vec3(pos_b, 1)); + + Vec2 step_a = pos_a_decal; + Vec2 step_b = pos_b_decal; + Vec2 step_vab = step_b - step_a; + + f32 slope = step_vab.y / step_vab.x; + i32 x_dir = (step_vab.x >= 0) - (step_vab.x < 0); + + if (!is_blocked_a) + { + i32 step_x = step_a.x; + for (;;) + { + f32 step_y = step_a.y + slope * (step_x - step_a.x); + Vec2 step = Vec2(step_x, step_y); + + // TODO: Don't query tiles + Vec2 world_step = mul(params.xf.decal_to_world, Vec3(step, 1)); + Vec2I32 tile_pos = S_TilePosFromWorldPos(world_step); + S_TileKind tile = tiles.Load(Vec3I32(tile_pos, 0)); + + b32 is_blocked = tile == S_TileKind_Wall; + if (is_blocked) + { + // particle.velocity *= -1; + particle.velocity.y *= -1; + // particle.velocity.x *= -1; + break; + } + + step_x += x_dir; + if (x_dir > 0) + { + if (step_x > (step_b.x + x_dir)) + { + break; + } + } + else + { + if (step_x < (step_b.x + x_dir)) + { + break; + } + } + } + } + + // // Line walk + // // FIXME: Real line walk, not aabb check + // b32 is_blocked = 0; + // for (u32 step_y = step_a.y; step_y <= step_b.y; ++step_y) + // { + // for (u32 step_x = step_a.x; step_x <= step_b.x; ++step_x) + // { + // // TODO: Don't query tiles + // Vec2 world_step = mul(params.xf.decal_to_world, Vec3(step_x, step_y, 1)); + // Vec2I32 tile_pos = S_TilePosFromWorldPos(world_step); + // S_TileKind tile = tiles.Load(Vec3I32(tile_pos, 0)); + + // if (tile == S_TileKind_Wall) + // { + // if (is_blocked) + // { + // // particle.velocity *= -1; + // particle.velocity.x *= -1; + // break; + // } + // is_blocked = 1; + // } + // } + // } + + + + + // Vec2I32 tile_pos = S_TilePosFromWorldPos(pos_a); + // S_TileKind tile = tiles.Load(Vec3I32(tile_pos, 0)); + + + particle.pos = pos_a + particle.velocity * dt; + particle.velocity = lerp(particle.velocity, 0, 4 * params.dt); + Vec2 decal_pos = mul(params.xf.world_to_decal, Vec3(particle.pos, 1)); if (decal_pos.x >= 0 && decal_pos.y >= 0 && decal_pos.x < countof(decals).x && decal_pos.y < countof(decals).y) @@ -393,20 +503,20 @@ PixelShader(V_OverlayPS, V_OverlayPSOutput, V_OverlayPSInput input) } } - // TODO: Remove this - // Decals test - { - RWTexture2D decals = G_Dereference(params.decals); - Vec2 decal_pos = mul(params.xf.world_to_decal, Vec3(world_pos, 1)); - // Vec2 decal_uv = decal_pos / countof(decals); - V_ParticleKind decal = decals.Load(floor(decal_pos)); + // // TODO: Remove this + // // Decals test + // { + // RWTexture2D decals = G_Dereference(params.decals); + // Vec2 decal_pos = mul(params.xf.world_to_decal, Vec3(world_pos, 1)); + // // Vec2 decal_uv = decal_pos / countof(decals); + // V_ParticleKind decal = decals.Load(decal_pos); - if (decal == V_ParticleKind_Test) - { - result = Color_Yellow; - // result = LinearFromSrgb(Vec4(0.5, 0.1, 0.1, 1)); - } - } + // if (decal == V_ParticleKind_Test) + // { + // result = Color_Yellow; + // // result = LinearFromSrgb(Vec4(0.5, 0.1, 0.1, 1)); + // } + // } V_OverlayPSOutput output; diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index bbab70da..c6bed00d 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -6,6 +6,7 @@ G_DeclConstant(G_RWStructuredBufferRef, V_ShaderConst_State, 0); G_DeclConstant(G_StructuredBufferRef, V_ShaderConst_Params, 1); +G_DeclConstant(G_Texture3DRef, V_ShaderConst_NoiseTex, 2); Enum(V_SelectionMode) { @@ -48,7 +49,6 @@ Struct(V_GpuParams) V_Xforms xf; u64 seed; - G_Texture3DRef noise; V_SelectionMode selection_mode; S_TileKind equipped_tile;