diff --git a/README.md b/README.md index fbee64d..4a112c1 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,26 @@ -# HARFANG® 2.0 Tutorials +# HARFANG® 3.0 Tutorials These **tutorials** demonstrate the usage of the HARFANG 2.0 API in **Python** and **Lua**. -If you want to know more about HARFANG, please visit the [official website](https://www.harfang3d.com). -To **run the tutorials**, please follow the **instructions** here : https://www.harfang3d.com/docs/2.0.111/man.quickstart/ +To run the tutorials: + +1. Download or clone this repository to your computer _(eg. in `d:/tutorials-hg2`)_. +2. Download _assetc_ for your platform from [here](https://harfang3d.com/releases) to compile the tutorial resources. +3. Drag and drop the tutorial resources folder on the assetc executable **-OR-** execute assetc passing it the path to the tutorial resources folder _(eg. `assetc d:/tutorials-hg2/resources`)_. + +![assetc drag & drop](https://github.com/harfang3d/image-storage/raw/main/tutorials/assetc.gif) + +After the compilation process finishes, you will see a `resources_compiled` folder next to the tutorials resources folder. + +You can now execute the tutorials from the folder you unzipped them to. + +```bash +D:\tutorials-hg2>python draw_lines.py +``` + +Alternatively, you can open the tutorial folder using [Visual Studio Code](https://code.visualstudio.com/) and use the provided debug targets to run the tutorials. + +**If you want to know more about HARFANG**, please visit the [official website](https://www.harfang3d.com). ## Screenshots * AAA Rendering Pipeline @@ -34,4 +51,4 @@ To **run the tutorials**, please follow the **instructions** here : https://www. ![Lights priority](screenshots/scene_light_priority.png) * Dear ImGui edition -![Dear ImGui edition](screenshots/imgui_edit.png) +![Dear ImGui edition](screenshots/imgui_edit.png) \ No newline at end of file diff --git a/audio_play_sound_spatialized.lua b/audio_play_sound_spatialized.lua index f60bcbc..7147a75 100644 --- a/audio_play_sound_spatialized.lua +++ b/audio_play_sound_spatialized.lua @@ -3,7 +3,7 @@ hg = require("harfang") hg.InputInit() -hg.WindowSystemInit() +hg.AudioInit() hg.AddAssetsFolder("resources_compiled") diff --git a/draw_model_no_pipeline.lua b/draw_model_no_pipeline.lua index 90aaaad..fe921e0 100644 --- a/draw_model_no_pipeline.lua +++ b/draw_model_no_pipeline.lua @@ -24,7 +24,7 @@ while not hg.ReadKeyboard():Key(hg.K_Escape) do angle = angle + hg.time_to_sec_f(dt) viewpoint = hg.TranslationMat4(hg.Vec3(0, 1, -3)) - hg.SetViewPerspective(0, res_x, res_y, viewpoint) + hg.SetViewPerspective(0, 0, 0, res_x, res_y, viewpoint) hg.DrawModel(0, cube_mdl, shader, {}, {}, hg.TransformationMat4(hg.Vec3(0, 1, 0), hg.Vec3(angle, angle, angle))) hg.DrawModel(0, ground_mdl, shader, {}, {}, hg.TranslationMat4(hg.Vec3(0, 0, 0))) diff --git a/draw_models_no_pipeline.py b/draw_models_no_pipeline.py index c306eb0..34c4429 100644 --- a/draw_models_no_pipeline.py +++ b/draw_models_no_pipeline.py @@ -24,7 +24,7 @@ angle = angle + hg.time_to_sec_f(dt) viewpoint = hg.TranslationMat4(hg.Vec3(0, 1, -3)) - hg.SetViewPerspective(0, res_x, res_y, viewpoint) + hg.SetViewPerspective(0, 0, 0, res_x, res_y, viewpoint) hg.DrawModel(0, cube_mdl, shader, [], [], hg.TransformationMat4(hg.Vec3(0, 1, 0), hg.Vec3(angle, angle, angle))) hg.DrawModel(0, ground_mdl, shader, [], [], hg.TranslationMat4(hg.Vec3(0, 0, 0))) diff --git a/draw_text.lua b/draw_text.lua index d95239d..cba7de4 100644 --- a/draw_text.lua +++ b/draw_text.lua @@ -18,7 +18,7 @@ text_render_state = hg.ComputeRenderState(hg.BM_Alpha, hg.DT_Always, hg.FC_Disab -- main loop while not hg.ReadKeyboard('default'):Key(hg.K_Escape) do - hg.SetView2D(0, res_x, res_y, -1, 1, hg.CF_Color | hg.CF_Depth, hg.ColorI(32, 32, 32), 0, 1) + hg.SetView2D(0, 0, 0, res_x, res_y, -1, 1, hg.CF_Color | hg.CF_Depth, hg.ColorI(32, 32, 32), 0, 1) hg.DrawText(0, font, 'Hello world!', font_prg, 'u_tex', 0, hg.Mat4.Identity, hg.Vec3(res_x / 2, res_y / 2, 0), hg.DTHA_Center, hg.DTVA_Center, text_uniform_values, {}, text_render_state) diff --git a/draw_text.py b/draw_text.py index 5482265..0ee559e 100644 --- a/draw_text.py +++ b/draw_text.py @@ -18,7 +18,7 @@ # main loop while not hg.ReadKeyboard('default').Key(hg.K_Escape): - hg.SetView2D(0, res_x, res_y, -1, 1, hg.CF_Color | hg.CF_Depth, hg.ColorI(32, 32, 32), 0, 1) + hg.SetView2D(0, 0, 0, res_x, res_y, -1, 1, hg.CF_Color | hg.CF_Depth, hg.ColorI(32, 32, 32), 0, 1) hg.DrawText(0, font, 'Hello world!', font_prg, 'u_tex', 0, hg.Mat4.Identity, hg.Vec3(res_x / 2, res_y / 2, 0), hg.DTHA_Center, hg.DTVA_Center, text_uniform_values, [], text_render_state) diff --git a/draw_text_over_models.lua b/draw_text_over_models.lua index e76c706..7c5c053 100644 --- a/draw_text_over_models.lua +++ b/draw_text_over_models.lua @@ -33,13 +33,13 @@ while not hg.ReadKeyboard():Key(hg.K_Escape) do -- 3D view viewpoint = hg.TranslationMat4(hg.Vec3(0, 1, -3)) - hg.SetViewPerspective(0, res_x, res_y, viewpoint, 0.01, 5000) + hg.SetViewPerspective(0, 0, 0, res_x, res_y, viewpoint, 0.01, 5000) hg.DrawModel(0, cube_mdl, shader, {}, {}, hg.TransformationMat4(hg.Vec3(0, 1, 0), hg.Vec3(angle, angle, angle))) hg.DrawModel(0, ground_mdl, shader, {}, {}, hg.TranslationMat4(hg.Vec3(0, 0, 0))) -- 2D view, note that only the depth buffer is cleared - hg.SetView2D(1, res_x, res_y, -1, 1, hg.CF_Depth, hg.ColorI(32, 32, 32), 1, 0) + hg.SetView2D(1, 0, 0, res_x, res_y, -1, 1, hg.CF_Depth, hg.ColorI(32, 32, 32), 1, 0) hg.DrawText(1, font, 'Hello world!', font_prg, 'u_tex', 0, hg.Mat4.Identity, hg.Vec3(res_x / 2, res_y / 2, 0), hg.DTHA_Center, hg.DTVA_Center, text_uniform_values, {}, text_render_state) diff --git a/draw_text_over_models.py b/draw_text_over_models.py index d7b94d8..b4564b6 100644 --- a/draw_text_over_models.py +++ b/draw_text_over_models.py @@ -33,13 +33,13 @@ # 3D view viewpoint = hg.TranslationMat4(hg.Vec3(0, 1, -3)) - hg.SetViewPerspective(0, res_x, res_y, viewpoint, 0.01, 5000) + hg.SetViewPerspective(0, 0, 0, res_x, res_y, viewpoint, 0.01, 5000) hg.DrawModel(0, cube_mdl, shader, [], [], hg.TransformationMat4(hg.Vec3(0, 1, 0), hg.Vec3(angle, angle, angle))) hg.DrawModel(0, ground_mdl, shader, [], [], hg.TranslationMat4(hg.Vec3(0, 0, 0))) # 2D view, note that only the depth buffer is cleared - hg.SetView2D(1, res_x, res_y, -1, 1, hg.CF_Depth, hg.ColorI(32, 32, 32), 1, 0) + hg.SetView2D(1, 0, 0, res_x, res_y, -1, 1, hg.CF_Depth, hg.ColorI(32, 32, 32), 1, 0) hg.DrawText(1, font, 'Hello world!', font_prg, 'u_tex', 0, hg.Mat4.Identity, hg.Vec3(res_x / 2, res_y / 2, 0), hg.DTHA_Center, hg.DTVA_Center, text_uniform_values, [], text_render_state) diff --git a/game_mouse_flight.lua b/game_mouse_flight.lua index 111a398..3fad2e2 100644 --- a/game_mouse_flight.lua +++ b/game_mouse_flight.lua @@ -112,7 +112,7 @@ while not keyboard:Down(hg.K_Escape) do view_id, passes_id = hg.SubmitSceneToPipeline(view_id, scene, hg.IntRect(0, 0, res_x, res_y), true, pipeline, res) -- draw 2D GUI - hg.SetView2D(view_id, res_x, res_y, -1, 1, hg.CF_Depth, hg.Color.Black, 1, 0, true) + hg.SetView2D(view_id, 0, 0, res_x, res_y, -1, 1, hg.CF_Depth, hg.Color.Black, 1, 0, true) draw_circle(view_id, hg.Vec3(mouse_x, mouse_y, 0), 20, hg.Color.White) -- display mouse cursor -- end of frame diff --git a/game_mouse_flight.py b/game_mouse_flight.py index 977d622..50b036a 100644 --- a/game_mouse_flight.py +++ b/game_mouse_flight.py @@ -114,7 +114,7 @@ def update_chase_camera(target_pos): view_id, passes_id = hg.SubmitSceneToPipeline(view_id, scene, hg.IntRect(0, 0, int(res_x), int(res_y)), True, pipeline, res) # draw 2D GUI - hg.SetView2D(view_id, res_x, res_y, -1, 1, hg.CF_Depth, hg.Color.Black, 1, 0, True) + hg.SetView2D(view_id, 0, 0, res_x, res_y, -1, 1, hg.CF_Depth, hg.Color.Black, 1, 0, True) draw_circle(view_id, hg.Vec3(mouse_x, mouse_y, 0), 20, hg.Color.White) # display mouse cursor # end of frame diff --git a/imgui_basic.lua b/imgui_basic.lua index f45e157..973cf51 100644 --- a/imgui_basic.lua +++ b/imgui_basic.lua @@ -25,7 +25,7 @@ while not hg.ReadKeyboard():Key(hg.K_Escape) do end hg.ImGuiEnd() - hg.SetView2D(0, res_x, res_y, -1, 1, hg.CF_Color | hg.CF_Depth, hg.Color.Black, 1, 0) + hg.SetView2D(0, 0, 0, res_x, res_y, -1, 1, hg.CF_Color | hg.CF_Depth, hg.Color.Black, 1, 0) hg.ImGuiEndFrame(0) hg.Frame() diff --git a/imgui_basic.py b/imgui_basic.py index 1b04a20..df84a9e 100644 --- a/imgui_basic.py +++ b/imgui_basic.py @@ -24,7 +24,7 @@ hg.ImGuiText('Hello World!') hg.ImGuiEnd() - hg.SetView2D(0, res_x, res_y, -1, 1, hg.CF_Color | hg.CF_Depth, hg.Color.Black, 1, 0) + hg.SetView2D(0, 0, 0, res_x, res_y, -1, 1, hg.CF_Color | hg.CF_Depth, hg.Color.Black, 1, 0) hg.ImGuiEndFrame(0) hg.Frame() diff --git a/imgui_edit.lua b/imgui_edit.lua index e50c3ac..c2533db 100644 --- a/imgui_edit.lua +++ b/imgui_edit.lua @@ -58,7 +58,7 @@ while not hg.ReadKeyboard():Key(hg.K_Escape) do end hg.ImGuiEnd() - hg.SetView2D(imgui_output_view, res_x, res_y, -1, 0, hg.CF_Color | hg.CF_Depth, imgui_view_clear_color, 1, 0) + hg.SetView2D(imgui_output_view, 0, 0, res_x, res_y, -1, 0, hg.CF_Color | hg.CF_Depth, imgui_view_clear_color, 1, 0) hg.ImGuiEndFrame(imgui_output_view) -- rendering frame diff --git a/imgui_edit.py b/imgui_edit.py index 7136cb5..1f94e32 100644 --- a/imgui_edit.py +++ b/imgui_edit.py @@ -55,7 +55,7 @@ hg.ImGuiEnd() - hg.SetView2D(imgui_output_view, res_x, res_y, -1, 0, hg.CF_Color | hg.CF_Depth, imgui_view_clear_color, 1, 0) + hg.SetView2D(imgui_output_view, 0, 0, res_x, res_y, -1, 0, hg.CF_Color | hg.CF_Depth, imgui_view_clear_color, 1, 0) hg.ImGuiEndFrame(imgui_output_view) # rendering frame diff --git a/imgui_mouse_capture.lua b/imgui_mouse_capture.lua index 83f8925..a0eabec 100644 --- a/imgui_mouse_capture.lua +++ b/imgui_mouse_capture.lua @@ -35,7 +35,7 @@ while not hg.ReadKeyboard():Key(hg.K_Escape) do end end - hg.SetView2D(0, res_x, res_y, -1, 0, hg.CF_Color | hg.CF_Depth, clear_color, 1, 0) + hg.SetView2D(0, 0, 0, res_x, res_y, -1, 0, hg.CF_Color | hg.CF_Depth, clear_color, 1, 0) hg.ImGuiSetNextWindowPosCenter(hg.ImGuiCond_Once) hg.ImGuiSetNextWindowSize(hg.Vec2(700, 96), hg.ImGuiCond_Once) diff --git a/imgui_mouse_capture.py b/imgui_mouse_capture.py index 2a5ca49..78450a5 100644 --- a/imgui_mouse_capture.py +++ b/imgui_mouse_capture.py @@ -30,7 +30,7 @@ else: clear_color = hg.Color.Red if mouse.Down(hg.MB_0) else hg.Color.Black - hg.SetView2D(0, res_x, res_y, -1, 0, hg.CF_Color | hg.CF_Depth, clear_color, 1, 0) + hg.SetView2D(0, 0, 0, res_x, res_y, -1, 0, hg.CF_Color | hg.CF_Depth, clear_color, 1, 0) hg.ImGuiSetNextWindowPosCenter(hg.ImGuiCond_Once) hg.ImGuiSetNextWindowSize(hg.Vec2(700, 96), hg.ImGuiCond_Once) diff --git a/physics_impulse.lua b/physics_impulse.lua index 4041f52..7ff062e 100644 --- a/physics_impulse.lua +++ b/physics_impulse.lua @@ -38,9 +38,9 @@ ground_node = hg.CreatePhysicCube(scene, hg.Vec3(100, 0.02, 100), hg.Translation clocks = hg.SceneClocks() -- scene physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics:SceneCreatePhysicsFromAssets(scene) -physics_step = hg.time_from_sec_f(1 / 30) +physics_step = hg.time_from_sec_f(1 / 60) -- main loop keyboard = hg.Keyboard() @@ -51,15 +51,17 @@ while not keyboard:Down(hg.K_Escape) do dt = hg.TickClock() if keyboard:Pressed(hg.K_I) then + physics:NodeWake(cube_node) world_pos = hg.GetT(cube_node:GetTransform():GetWorld()) - physics:NodeAddImpulse(cube_node, hg.Vec3(0, 2, 0), world_pos, physics_step) + physics:NodeAddImpulse(cube_node, hg.Vec3(0, 8, 0), world_pos) end if keyboard:Pressed(hg.K_F) then + physics:NodeWake(cube_node) world_pos = hg.GetT(cube_node:GetTransform():GetWorld()) - physics:NodeAddForce(cube_node, hg.Vec3(0, 2, 0), world_pos) + physics:NodeAddForce(cube_node, hg.Vec3(0, 8, 0), world_pos) end - hg.SceneUpdateSystems(scene, clocks, dt, physics, physics_step, 1000) + hg.SceneUpdateSystems(scene, clocks, dt, physics, physics_step, 3) hg.SubmitSceneToPipeline(0, scene, hg.IntRect(0, 0, res_x, res_y), true, pipeline, res) hg.Frame() @@ -70,4 +72,4 @@ hg.RenderShutdown() hg.DestroyWindow(win) hg.WindowSystemShutdown() -hg.InputShutdown() \ No newline at end of file +hg.InputShutdown() diff --git a/physics_impulse.py b/physics_impulse.py index 6d37740..5af0637 100644 --- a/physics_impulse.py +++ b/physics_impulse.py @@ -6,7 +6,7 @@ hg.WindowSystemInit() res_x, res_y = 1280, 720 -win = hg.RenderInit('Harfang - Physics Impulse', res_x, res_y, hg.RF_VSync | hg.RF_MSAA4X) +win = hg.RenderInit('Harfang - Physics Force/Impulse (Press space to alternate)', res_x, res_y, hg.RF_VSync | hg.RF_MSAA4X) pipeline = hg.CreateForwardPipeline() res = hg.PipelineResources() @@ -32,32 +32,50 @@ lgt = hg.CreateLinearLight(scene, hg.TransformationMat4(hg.Vec3(0, 0, 0), hg.Vec3(hg.Deg(30), hg.Deg(59), 0)), hg.Color(1, 1, 1), hg.Color(1, 1, 1), 10, hg.LST_Map, 0.002, hg.Vec4(2, 4, 10, 16)) -cube_node = hg.CreatePhysicCube(scene, hg.Vec3(1, 1, 1), hg.TranslationMat4(hg.Vec3(0, 2.5, 0)), cube_ref, [mat], 2) +cube_node = hg.CreatePhysicCube(scene, hg.Vec3(1, 1, 1), hg.TranslationMat4(hg.Vec3(0, 1.5, 0)), cube_ref, [mat], 2) ground_node = hg.CreatePhysicCube(scene, hg.Vec3(100, 0.02, 100), hg.TranslationMat4(hg.Vec3(0, -0.005, 0)), ground_ref, [mat], 0) clocks = hg.SceneClocks() # scene physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics.SceneCreatePhysicsFromAssets(scene) -physics_step = hg.time_from_sec_f(1 / 30) +physics_step = hg.time_from_sec_f(1 / 60) # main loop keyboard = hg.Keyboard() +use_force = True + while not keyboard.Down(hg.K_Escape): keyboard.Update() dt = hg.TickClock() - if keyboard.Pressed(hg.K_I): - world_pos = hg.GetT(cube_node.GetTransform().GetWorld()) - physics.NodeAddImpulse(cube_node, hg.Vec3(0, 2, 0), world_pos, physics_step) - if keyboard.Pressed(hg.K_F): - world_pos = hg.GetT(cube_node.GetTransform().GetWorld()) - physics.NodeAddForce(cube_node, hg.Vec3(0, 2, 0), world_pos) + if keyboard.Pressed(hg.K_Space): + use_force = not use_force + + world_pos = hg.GetT(cube_node.GetTransform().GetWorld()) + dist_to_ground = world_pos.y - 0.5 + + if dist_to_ground < 1.0: + k = -(dist_to_ground - 1.0) + + if use_force: + F = hg.Vec3(0, 1, 0) * k * 80 # apply a force inversely proportional to the distance to the ground + physics.NodeAddForce(cube_node, F, world_pos) + else: + stiffness = 10 + + cur_velocity = physics.NodeGetLinearVelocity(cube_node) + tgt_velocity = hg.Vec3(0, 1, 0) * k * stiffness # compute a velocity that brings us to 1 meter above the ground + + I = tgt_velocity - cur_velocity # an impulse is an instantaneous change in velocity + physics.NodeAddImpulse(cube_node, I, world_pos) + + physics.NodeWake(cube_node) - hg.SceneUpdateSystems(scene, clocks, dt, physics, physics_step, 1000) + hg.SceneUpdateSystems(scene, clocks, dt, physics, physics_step, 3) hg.SubmitSceneToPipeline(0, scene, hg.IntRect(0, 0, res_x, res_y), True, pipeline, res) hg.Frame() @@ -67,4 +85,4 @@ hg.DestroyWindow(win) hg.WindowSystemShutdown() -hg.InputShutdown() \ No newline at end of file +hg.InputShutdown() diff --git a/physics_kapla.lua b/physics_kapla.lua index 41956bb..faf20ec 100644 --- a/physics_kapla.lua +++ b/physics_kapla.lua @@ -89,9 +89,9 @@ cam_pos = hg.Vec3(28.3, 31.8, 26.9) cam_rot = hg.Vec3(0.6, -2.38, 0) -- setup physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics:SceneCreatePhysicsFromAssets(scene) -physics_step = hg.time_from_sec_f(1 / 50) +physics_step = hg.time_from_sec_f(1 / 60) -- main loop while not keyboard:Down(hg.K_Escape) do @@ -114,7 +114,7 @@ while not keyboard:Down(hg.K_Escape) do if keyboard:Pressed(hg.K_Space) then node = hg.CreatePhysicSphere(scene, 0.5, hg.TranslationMat4(cam_pos), sphere_ref, {mat_spheres}, 0.5) physics:NodeCreatePhysicsFromAssets(node) - physics:NodeAddImpulse(node, hg.GetZ(cam:GetTransform():GetWorld()) * 50.0, cam_pos, physics_step) + physics:NodeAddImpulse(node, hg.GetZ(cam:GetTransform():GetWorld()) * 25.0, cam_pos) end hg.SceneUpdateSystems(scene, clocks, dt, physics, physics_step, 1) diff --git a/physics_kapla.py b/physics_kapla.py index 49fd960..a59e6ce 100644 --- a/physics_kapla.py +++ b/physics_kapla.py @@ -87,9 +87,9 @@ def fill_ring(r, ring_y, size, r_adjust, y_off): cam_rot = hg.Vec3(0.6, -2.38, 0) # setup physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics.SceneCreatePhysicsFromAssets(scene) -physics_step = hg.time_from_sec_f(1 / 50) +physics_step = hg.time_from_sec_f(1 / 60) # main loop while not keyboard.Down(hg.K_Escape): @@ -106,7 +106,7 @@ def fill_ring(r, ring_y, size, r_adjust, y_off): if keyboard.Pressed(hg.K_Space): node = hg.CreatePhysicSphere(scene, 0.5, hg.TranslationMat4(cam_pos), sphere_ref, [mat_spheres], 0.5) physics.NodeCreatePhysicsFromAssets(node) - physics.NodeAddImpulse(node, hg.GetZ(cam.GetTransform().GetWorld()) * 50.0, cam_pos, physics_step) + physics.NodeAddImpulse(node, hg.GetZ(cam.GetTransform().GetWorld()) * 25.0, cam_pos) hg.SceneUpdateSystems(scene, clocks, dt, physics, physics_step, 1) hg.SubmitSceneToPipeline(0, scene, hg.IntRect(0, 0, res_x, res_y), True, pipeline, res) diff --git a/physics_manual_setup.lua b/physics_manual_setup.lua index 79dc207..226866b 100644 --- a/physics_manual_setup.lua +++ b/physics_manual_setup.lua @@ -50,7 +50,7 @@ cube_node:SetRigidBody(rb) cube_node:SetCollision(0, collision) -- scene physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics:SceneCreatePhysicsFromAssets(scene) -- main loop diff --git a/physics_manual_setup.py b/physics_manual_setup.py index 49bd5ed..9e3ca12 100644 --- a/physics_manual_setup.py +++ b/physics_manual_setup.py @@ -50,7 +50,7 @@ cube_node.SetCollision(0, collision) # scene physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics.SceneCreatePhysicsFromAssets(scene) # main loop diff --git a/physics_overrides_matrix.lua b/physics_overrides_matrix.lua index 64d092d..5a375fe 100644 --- a/physics_overrides_matrix.lua +++ b/physics_overrides_matrix.lua @@ -41,7 +41,7 @@ ground_node = hg.CreatePhysicCube(scene, hg.Vec3(100, 0.02, 100), hg.Translation clocks = hg.SceneClocks() -- scene physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics:SceneCreatePhysicsFromAssets(scene) -- main loop diff --git a/physics_overrides_matrix.py b/physics_overrides_matrix.py index 1b37a33..027f392 100644 --- a/physics_overrides_matrix.py +++ b/physics_overrides_matrix.py @@ -41,7 +41,7 @@ clocks = hg.SceneClocks() # scene physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics.SceneCreatePhysicsFromAssets(scene) # main loop diff --git a/physics_pool_of_objects.lua b/physics_pool_of_objects.lua index bfd9bb7..3d87c34 100644 --- a/physics_pool_of_objects.lua +++ b/physics_pool_of_objects.lua @@ -59,7 +59,7 @@ hg.CreatePhysicCube(scene, hg.Vec3(32, 11, 1), hg.TranslationMat4(hg.Vec3(0, -0. clocks = hg.SceneClocks() -- setup physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics:SceneCreatePhysicsFromAssets(scene) physic_nodes = {} -- keep track of dynamically created physic nodes @@ -110,11 +110,11 @@ while true do -- update scene and physic system, synchronize physics to scene, submit scene to draw dt = hg.TickClock() - hg.SceneUpdateSystems(scene, clocks, dt, physics, hg.time_from_sec_f(1 / 30), 1) + hg.SceneUpdateSystems(scene, clocks, dt, physics, hg.time_from_sec_f(1 / 60), 4) view_id, pass_id = hg.SubmitSceneToPipeline(0, scene, hg.IntRect(0, 0, res_x, res_y), true, pipeline, res) -- on-screen usage text - hg.SetView2D(view_id, res_x, res_y, -1, 1, hg.CF_Depth, hg.Color.Black, 1, 0) + hg.SetView2D(view_id, 0, 0, res_x, res_y, -1, 1, hg.CF_Depth, hg.Color.Black, 1, 0) hg.DrawText(view_id, font, 'S: Add object - D: Destruct object', font_program, 'u_tex', 0, hg.Mat4.Identity, hg.Vec3(460, res_y - 60, 0), hg.DTHA_Left, hg.DTVA_Bottom, text_uniform_values, {}, text_render_state) hg.DrawText(view_id, font, string.format('%d Object', #physic_nodes), font_program, 'u_tex', 0, hg.Mat4.Identity, hg.Vec3(res_x - 200, res_y - 60, 0), hg.DTHA_Left, hg.DTVA_Bottom, text_uniform_values, {}, text_render_state) diff --git a/physics_pool_of_objects.py b/physics_pool_of_objects.py index 0e1ae79..3b91e81 100644 --- a/physics_pool_of_objects.py +++ b/physics_pool_of_objects.py @@ -59,7 +59,7 @@ def create_material(diffuse, specular, self): clocks = hg.SceneClocks() # setup physics -physics = hg.SceneNewtonPhysics() +physics = hg.SceneBullet3Physics() physics.SceneCreatePhysicsFromAssets(scene) physic_nodes = [] # keep track of dynamically created physic nodes @@ -103,11 +103,11 @@ def create_material(diffuse, specular, self): # update scene and physic system, synchronize physics to scene, submit scene to draw dt = hg.TickClock() - hg.SceneUpdateSystems(scene, clocks, dt, physics, hg.time_from_sec_f(1 / 30), 1) + hg.SceneUpdateSystems(scene, clocks, dt, physics, hg.time_from_sec_f(1 / 60), 4) view_id, pass_id = hg.SubmitSceneToPipeline(0, scene, hg.IntRect(0, 0, res_x, res_y), True, pipeline, res) # on-screen usage text - hg.SetView2D(view_id, res_x, res_y, -1, 1, hg.CF_Depth, hg.Color.Black, 1, 0) + hg.SetView2D(view_id, 0, 0, res_x, res_y, -1, 1, hg.CF_Depth, hg.Color.Black, 1, 0) hg.DrawText(view_id, font, 'S: Add object - D: Destruct object', font_program, 'u_tex', 0, hg.Mat4.Identity, hg.Vec3(460, res_y - 60, 0), hg.DTHA_Left, hg.DTVA_Bottom, text_uniform_values, [], text_render_state) hg.DrawText(view_id, font, '%d Object' % len(physic_nodes), font_program, 'u_tex', 0, hg.Mat4.Identity, hg.Vec3(res_x - 200, res_y - 60, 0), hg.DTHA_Left, hg.DTVA_Bottom, text_uniform_values, [], text_render_state) diff --git a/render_resize_to_window.lua b/render_resize_to_window.lua index 87a3602..b3b51db 100644 --- a/render_resize_to_window.lua +++ b/render_resize_to_window.lua @@ -22,7 +22,7 @@ while not hg.ReadKeyboard():Key(hg.K_Escape) do end viewpoint = hg.TransformationMat4(hg.Vec3(1, 1, -2), hg.Deg3(24, -27, 0)) - hg.SetViewPerspective(0, res_x, res_y, viewpoint, 0.01, 100, 1.8, hg.CF_Color | hg.CF_Depth, hg.ColorI(64, 64, 64), 1, 0) + hg.SetViewPerspective(0, 0, 0, res_x, res_y, viewpoint, 0.01, 100, 1.8, hg.CF_Color | hg.CF_Depth, hg.ColorI(64, 64, 64), 1, 0) hg.DrawModel(0, cube_mdl, cube_prg, {}, {}, hg.TranslationMat4(hg.Vec3(0, 0, 0))) diff --git a/render_resize_to_window.py b/render_resize_to_window.py index 0221754..dc7bb2b 100644 --- a/render_resize_to_window.py +++ b/render_resize_to_window.py @@ -21,7 +21,7 @@ print('Render reset to %dx%d' % (res_x, res_y)) viewpoint = hg.TransformationMat4(hg.Vec3(1, 1, -2), hg.Deg3(24, -27, 0)) - hg.SetViewPerspective(0, res_x, res_y, viewpoint, 0.01, 100, 1.8, hg.CF_Color | hg.CF_Depth, hg.ColorI(64, 64, 64), 1, 0) + hg.SetViewPerspective(0, 0, 0, res_x, res_y, viewpoint, 0.01, 100, 1.8, hg.CF_Color | hg.CF_Depth, hg.ColorI(64, 64, 64), 1, 0) hg.DrawModel(0, cube_mdl, cube_prg, [], [], hg.TranslationMat4(hg.Vec3(0, 0, 0))) diff --git a/resources/car_engine/ORM_1001.png.meta b/resources/car_engine/ORM_1001.png.meta index 48079bc..16888b5 100644 --- a/resources/car_engine/ORM_1001.png.meta +++ b/resources/car_engine/ORM_1001.png.meta @@ -1,7 +1,7 @@ { "profiles": { "default": { - "compression": "BC7", + "compression": "BC3", "mag-filter": "Anisotropic", "min-filter": "Anisotropic" } diff --git a/resources/car_engine/ORM_1002.png.meta b/resources/car_engine/ORM_1002.png.meta index 48079bc..16888b5 100644 --- a/resources/car_engine/ORM_1002.png.meta +++ b/resources/car_engine/ORM_1002.png.meta @@ -1,7 +1,7 @@ { "profiles": { "default": { - "compression": "BC7", + "compression": "BC3", "mag-filter": "Anisotropic", "min-filter": "Anisotropic" } diff --git a/resources/car_engine/ORM_1011.png.meta b/resources/car_engine/ORM_1011.png.meta index 48079bc..16888b5 100644 --- a/resources/car_engine/ORM_1011.png.meta +++ b/resources/car_engine/ORM_1011.png.meta @@ -1,7 +1,7 @@ { "profiles": { "default": { - "compression": "BC7", + "compression": "BC3", "mag-filter": "Anisotropic", "min-filter": "Anisotropic" } diff --git a/resources/car_engine/ORM_1012.png.meta b/resources/car_engine/ORM_1012.png.meta index 48079bc..16888b5 100644 --- a/resources/car_engine/ORM_1012.png.meta +++ b/resources/car_engine/ORM_1012.png.meta @@ -1,7 +1,7 @@ { "profiles": { "default": { - "compression": "BC7", + "compression": "BC3", "mag-filter": "Anisotropic", "min-filter": "Anisotropic" } diff --git a/resources/car_engine/brand_logo.png.meta b/resources/car_engine/brand_logo.png.meta index 48079bc..16888b5 100644 --- a/resources/car_engine/brand_logo.png.meta +++ b/resources/car_engine/brand_logo.png.meta @@ -1,7 +1,7 @@ { "profiles": { "default": { - "compression": "BC7", + "compression": "BC3", "mag-filter": "Anisotropic", "min-filter": "Anisotropic" } diff --git a/resources/car_engine/car_engine_1001_BaseColor.1001.png.meta b/resources/car_engine/car_engine_1001_BaseColor.1001.png.meta index 48079bc..16888b5 100644 --- a/resources/car_engine/car_engine_1001_BaseColor.1001.png.meta +++ b/resources/car_engine/car_engine_1001_BaseColor.1001.png.meta @@ -1,7 +1,7 @@ { "profiles": { "default": { - "compression": "BC7", + "compression": "BC3", "mag-filter": "Anisotropic", "min-filter": "Anisotropic" } diff --git a/resources/car_engine/car_engine_1002_BaseColor.1002.png.meta b/resources/car_engine/car_engine_1002_BaseColor.1002.png.meta index 48079bc..16888b5 100644 --- a/resources/car_engine/car_engine_1002_BaseColor.1002.png.meta +++ b/resources/car_engine/car_engine_1002_BaseColor.1002.png.meta @@ -1,7 +1,7 @@ { "profiles": { "default": { - "compression": "BC7", + "compression": "BC3", "mag-filter": "Anisotropic", "min-filter": "Anisotropic" } diff --git a/resources/car_engine/car_engine_1011_BaseColor.1011.png.meta b/resources/car_engine/car_engine_1011_BaseColor.1011.png.meta index 48079bc..16888b5 100644 --- a/resources/car_engine/car_engine_1011_BaseColor.1011.png.meta +++ b/resources/car_engine/car_engine_1011_BaseColor.1011.png.meta @@ -1,7 +1,7 @@ { "profiles": { "default": { - "compression": "BC7", + "compression": "BC3", "mag-filter": "Anisotropic", "min-filter": "Anisotropic" } diff --git a/resources/car_engine/car_engine_1012_BaseColor.1012.png.meta b/resources/car_engine/car_engine_1012_BaseColor.1012.png.meta index 48079bc..16888b5 100644 --- a/resources/car_engine/car_engine_1012_BaseColor.1012.png.meta +++ b/resources/car_engine/car_engine_1012_BaseColor.1012.png.meta @@ -1,7 +1,7 @@ { "profiles": { "default": { - "compression": "BC7", + "compression": "BC3", "mag-filter": "Anisotropic", "min-filter": "Anisotropic" } diff --git a/resources/core/shader/a_trous_fs.sc b/resources/core/shader/a_trous_fs.sc new file mode 100644 index 0000000..1f5a1d2 --- /dev/null +++ b/resources/core/shader/a_trous_fs.sc @@ -0,0 +1,68 @@ +#include + +SAMPLER2D(u_color, 0); +SAMPLER2D(u_attr0, 1); + +uniform vec4 u_dir; +uniform vec4 u_sigma; // x: pos, y: normal, z: depth, w: depth weight cutoff + +void main() { + const float epsilon = 1.e-6; + + ivec2 p0 = ivec2(gl_FragCoord.xy); + ivec2 offset = ivec2(u_dir.xy); + + vec4 c0 = texelFetch(u_color, p0, 0); + vec4 v0 = texelFetch(u_attr0, p0, 0); + + float w = 3.0 / 8.0; + vec4 c = w * c0; + + float falloff = 1.0 / (sqrt(2.0) * u_sigma.x); + + int i; + float ws; + + ws = 1.0 / 4.0; + for(i=1; i<=2; i++) { + ivec2 p1; + vec4 v1; + float wn, dz, wz, wp, w1, d; + + ivec2 delta = offset * i; + float d2 = dot(vec2(delta), vec2(delta)); + wp = exp(-d2 * falloff); + + // right + p1 = p0 + delta; + v1 = texelFetch(u_attr0, p1, 0); + + dz = abs(v1.w - v0.w); + wz = exp(-dz / u_sigma.z); + wz *= step(u_sigma.w, wz); + + wn = pow(max(0.0, dot(v1.xyz, v0.xyz)), u_sigma.y); + w1 = ws * wn * wz * wp; + + w += w1; + c += w1 * texelFetch(u_color, p1, 0); + + // left + p1 = p0 - delta; + v1 = texelFetch(u_attr0, p1, 0); + + dz = abs(v1.w - v0.w); + wz = exp(-dz / u_sigma.z); + wz *= step(u_sigma.w, wz); + + wn = pow(max(0.0, dot(v1.xyz, v0.xyz)), u_sigma.y); + w1 = ws * wn * wz * wp; + + w += w1; + c += w1 * texelFetch(u_color, p1, 0); + + ws *= ws; + } + + gl_FragColor = c / w; +} \ No newline at end of file diff --git a/resources/core/shader/a_trous_varying.def b/resources/core/shader/a_trous_varying.def new file mode 100644 index 0000000..76522d5 --- /dev/null +++ b/resources/core/shader/a_trous_varying.def @@ -0,0 +1 @@ +vec3 a_position : POSITION; diff --git a/resources/core/shader/a_trous_vs.sc b/resources/core/shader/a_trous_vs.sc new file mode 100644 index 0000000..1b87b56 --- /dev/null +++ b/resources/core/shader/a_trous_vs.sc @@ -0,0 +1,7 @@ +$input a_position + +#include + +void main() { + gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0)); +} diff --git a/resources/core/shader/aaa_utils.sh b/resources/core/shader/aaa_utils.sh index d2607a8..973ed52 100644 --- a/resources/core/shader/aaa_utils.sh +++ b/resources/core/shader/aaa_utils.sh @@ -16,4 +16,23 @@ vec2 GetVelocityVector(in vec2 uv) { return texture2D(u_attr1, uv).xy * offset / (uResolution.xy / u_viewRect.zw); } +vec2 GetAttributeTexCoord(vec2 coord, vec2 size) { +#if BGFX_SHADER_LANGUAGE_GLSL + vec2 uv = vec2(coord.x, 1.0 - coord.y) * u_viewRect.zw / size; + uv.y = 1.0 - uv.y; + return uv; +#else + return coord * u_viewRect.zw / size; +#endif +} + +vec3 GetRayOrigin(mat4 projection, vec3 viewRay, float depth) { +#if BGFX_SHADER_LANGUAGE_GLSL + float z = (depth - projection[3].z) / projection[2].z; +#else + float z = (depth - projection[2].w) / projection[2].z; +#endif + return viewRay * z; +} + #endif // AAA_UTILS_SH_HEADER_GUARD diff --git a/resources/core/shader/hiz_copy_cs.sc b/resources/core/shader/hiz_copy_cs.sc index f5c0097..3083f58 100644 --- a/resources/core/shader/hiz_copy_cs.sc +++ b/resources/core/shader/hiz_copy_cs.sc @@ -5,7 +5,7 @@ SAMPLER2D(u_depth, 0); IMAGE2D_WR(u_depthTexOut, rg32f, 1); // output: level 0 of the min/max depth pyramid -uniform vec4 u_zBounds; // near(x) far(y) unused(z,w) +uniform mat4 u_projection; NUM_THREADS(16, 16, 1) void main() { @@ -22,16 +22,19 @@ void main() { if(all(bvec4(greaterThanEqual(coord, viewport.xy), lessThan(coord, viewport.xy + viewport.zw)))) { z = texelFetch(u_depth, tex_coord, 0).ww; - // [todo] use the backface depth buffer instead - z.y += 0.1; +#if BGFX_SHADER_LANGUAGE_GLSL + vec2 q = vec2(u_projection[2].z, u_projection[3].z); +#else + vec2 q = u_projection[2].zw; +#endif + z.y += 0.1 * q.x; // Store logarithmic depth - z.x = u_zBounds.y * z.x / ((u_zBounds.y - u_zBounds.x) * z.x + u_zBounds.x*u_zBounds.y); - z.y = u_zBounds.y * z.y / ((u_zBounds.y - u_zBounds.x) * z.y + u_zBounds.x*u_zBounds.y); + z.xy = q.x * z.xy / (z.xy - q.yy); } else { // Set pixels outside the viewport to the far clipping distance. z = vec2(1.0, 0.0); } imageStore(u_depthTexOut, coord, vec4(z.x, z.y, 0, 1)); -} \ No newline at end of file +} diff --git a/resources/core/shader/hiz_trace.sh b/resources/core/shader/hiz_trace.sh index de1f89a..791d45f 100644 --- a/resources/core/shader/hiz_trace.sh +++ b/resources/core/shader/hiz_trace.sh @@ -45,7 +45,7 @@ bool hiz_trace(vec3 ray_o, vec3 ray_d, mat4 proj, float z_near, int max_iteratio vec2 cell_count = mip_size(level_min); // clip to the near plane - float ray_len = (ray_o.z + ray_d.z * 1000.0) < z_near ? (z_near - ray_o.z) / ray_d.z : 1000.0; + float ray_len = ((ray_o.z + ray_d.z * 1000.0) < z_near) ? (z_near - ray_o.z) / ray_d.z : 1000.0; vec3 end_point = ray_o + ray_d * ray_len; // project into homogeneous clip space diff --git a/resources/core/shader/pbr_fs.sc b/resources/core/shader/pbr_fs.sc index d69d950..e337cd3 100644 --- a/resources/core/shader/pbr_fs.sc +++ b/resources/core/shader/pbr_fs.sc @@ -91,7 +91,7 @@ vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) { return F0 + (max(vec3_splat(1.0 - roughness), F0) - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0); } -vec3 GGX(vec3 V, vec3 N, float NdotV, vec3 L, vec3 albedo, float roughness, float metalness, vec3 F0) { +vec3 GGX(vec3 V, vec3 N, float NdotV, vec3 L, vec3 albedo, float roughness, float metalness, vec3 F0, vec3 diffuse_color, vec3 specular_color) { vec3 H = normalize(V - L); float NdotH = max(dot(N, H), 0.0); @@ -107,7 +107,7 @@ vec3 GGX(vec3 V, vec3 N, float NdotV, vec3 L, vec3 albedo, float roughness, floa vec3 kD = (vec3_splat(1.0) - F) * (1.0 - metalness); // metallic materials have no diffuse (NOTE: mimics mental ray and 3DX Max ART renderers behavior) vec3 diffuseBRDF = kD * albedo; - return (diffuseBRDF + specularBRDF) * NdotL; + return (diffuse_color * diffuseBRDF + specular_color * specularBRDF) * NdotL; } // @@ -159,7 +159,7 @@ void main() { vec3 T = normalize(vTangent); vec3 B = normalize(vBinormal); - mat3 TBN = MakeMat3(T, B, N); + mat3 TBN = mtxFromRows(T, B, N); N.xy = texture2D(uNormalMap, vTexCoord0).xy * 2.0 - 1.0; N.z = sqrt(1.0 - dot(N.xy, N.xy)); @@ -198,7 +198,7 @@ void main() { # endif } #endif - color += GGX(V, N, NdotV, uLightDir[0].xyz, base_opacity.xyz, occ_rough_metal.g, occ_rough_metal.b, F0) * uLightDiffuse[0].xyz * k_shadow; + color += GGX(V, N, NdotV, uLightDir[0].xyz, base_opacity.xyz, occ_rough_metal.g, occ_rough_metal.b, F0, uLightDiffuse[0].xyz * k_shadow, uLightSpecular[0].xyz * k_shadow); } // SLOT 1: point/spot light (with optional shadows) { @@ -206,12 +206,11 @@ void main() { float distance = length(L); L /= max(distance, 1e-8); float attenuation = LightAttenuation(L, uLightDir[1].xyz, distance, uLightPos[1].w, uLightDir[1].w, uLightDiffuse[1].w); - vec3 radiance = uLightDiffuse[1].xyz * attenuation; #if SLOT1_SHADOWS - radiance *=SampleShadowPCF(uSpotShadowMap, vSpotShadowCoord, uShadowState.y, uShadowState.w, jitter); + attenuation *=SampleShadowPCF(uSpotShadowMap, vSpotShadowCoord, uShadowState.y, uShadowState.w, jitter); #endif - color += GGX(V, N, NdotV, L, base_opacity.xyz, occ_rough_metal.g, occ_rough_metal.b, F0) * radiance; + color += GGX(V, N, NdotV, L, base_opacity.xyz, occ_rough_metal.g, occ_rough_metal.b, F0, uLightDiffuse[1].xyz * attenuation, uLightSpecular[1].xyz * attenuation); } // SLOT 2-N: point/spot light (no shadows) [todo] { @@ -220,9 +219,8 @@ void main() { float distance = length(L); L /= max(distance, 1e-8); float attenuation = LightAttenuation(L, uLightDir[i].xyz, distance, uLightPos[i].w, uLightDir[i].w, uLightDiffuse[i].w); - vec3 radiance = uLightDiffuse[i].xyz * attenuation; - color += GGX(V, N, NdotV, L, base_opacity.xyz, occ_rough_metal.g, occ_rough_metal.b, F0) * radiance; + color += GGX(V, N, NdotV, L, base_opacity.xyz, occ_rough_metal.g, occ_rough_metal.b, F0, uLightDiffuse[i].xyz * attenuation, uLightSpecular[i].xyz * attenuation); } } diff --git a/resources/core/shader/pbr_vs.sc b/resources/core/shader/pbr_vs.sc index 6c73acc..8b9ecc9 100644 --- a/resources/core/shader/pbr_vs.sc +++ b/resources/core/shader/pbr_vs.sc @@ -4,7 +4,17 @@ $output vWorldPos, vNormal, vTexCoord0, vTexCoord1, vTangent, vBinormal, vLinear #include mat3 normal_mat(mat4 m) { - return mat3(normalize(m[0].xyz), normalize(m[1].xyz), normalize(m[2].xyz)); +#if BGFX_SHADER_LANGUAGE_GLSL + vec3 u = normalize(vec3(m[0].x, m[1].x, m[2].x)); + vec3 v = normalize(vec3(m[0].y, m[1].y, m[2].y)); + vec3 w = normalize(vec3(m[0].z, m[1].z, m[2].z)); +#else + vec3 u = normalize(m[0].xyz); + vec3 v = normalize(m[1].xyz); + vec3 w = normalize(m[2].xyz); +#endif + + return mtxFromRows(u, v, w); } void main() { diff --git a/resources/core/shader/sao_compute_vs.sc b/resources/core/shader/sao_compute_vs.sc index 0af310a..3076def 100644 --- a/resources/core/shader/sao_compute_vs.sc +++ b/resources/core/shader/sao_compute_vs.sc @@ -13,5 +13,5 @@ void main() { ndc /= ndc.w; ndc /= ndc.z; - v_viewRay = ndc; + v_viewRay = ndc.xyz; } diff --git a/resources/core/shader/ssgi_fs.sc b/resources/core/shader/ssgi_fs.sc index 4baa58e..48d4e12 100644 --- a/resources/core/shader/ssgi_fs.sc +++ b/resources/core/shader/ssgi_fs.sc @@ -1,4 +1,4 @@ -$input v_viewRay +$input vTexCoord0, v_viewRay #include @@ -21,17 +21,13 @@ void main() { vec4 jitter = texture2D(u_noise, mod(gl_FragCoord.xy, vec2(64, 64)) / vec2(64, 64)); // sample normal/depth - vec2 uv = gl_FragCoord.xy * uv_ratio / uResolution.xy; + vec2 uv = GetAttributeTexCoord(vTexCoord0, textureSize(u_attr0, 0).xy); vec4 attr0 = texture2D(u_attr0, uv); vec3 n = attr0.xyz; // compute ray origin & direction - float near = -uMainProjection[2].w / uMainProjection[2].z; - float far = -near * uMainProjection[2].z / (1.0 - uMainProjection[2].z); - float z = (attr0.w * (far - near) + near*far) / far; - - vec3 ray_o = v_viewRay * z; + vec3 ray_o = GetRayOrigin(uMainProjection, v_viewRay, attr0.w); // spread vec3 right = normalize(cross(n, vec3(1, 0, 0))); @@ -39,6 +35,7 @@ void main() { // vec4 color = vec4_splat(0.); + const float z_min = 0.1; for (int i = 0; i < int(sample_count); ++i) { float r = (float(i) + jitter.y) / sample_count; @@ -52,7 +49,7 @@ void main() { vec2 hit_pixel; vec3 hit_point; - if (TraceScreenRay(ray_o - v_viewRay * 0.05, ray_d_spread, uMainProjection, 0.1, /*jitter.z,*/ 64, hit_pixel, hit_point)) { + if (TraceScreenRay(ray_o - v_viewRay * 0.05, ray_d_spread, uMainProjection, z_min, /*jitter.z,*/ 64, hit_pixel, hit_point)) { // use hit pixel velocity to compensate the fact that we are sampling the previous frame vec2 uv = hit_pixel * uv_ratio / uResolution.xy; vec2 vel = GetVelocityVector(uv); diff --git a/resources/core/shader/ssgi_varying.def b/resources/core/shader/ssgi_varying.def index ff632a3..b42cb63 100644 --- a/resources/core/shader/ssgi_varying.def +++ b/resources/core/shader/ssgi_varying.def @@ -1,4 +1,5 @@ -vec3 v_viewRay : TEXCOORD0 = vec3(0.0, 0.0, 0.0); +vec2 vTexCoord0 : TEXCOORD0; +vec3 v_viewRay : TEXCOORD1 = vec3(0.0, 0.0, 0.0); vec3 a_position : POSITION; vec2 a_texcoord0 : TEXCOORD0; diff --git a/resources/core/shader/ssgi_vs.sc b/resources/core/shader/ssgi_vs.sc index 4ad610f..af73283 100644 --- a/resources/core/shader/ssgi_vs.sc +++ b/resources/core/shader/ssgi_vs.sc @@ -1,8 +1,10 @@ $input a_position, a_texcoord0 -$output v_viewRay +$output vTexCoord0, v_viewRay #include +#define uv_ratio vec2_splat(uAAAParams[0].x) + void main() { gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0)); @@ -14,4 +16,6 @@ void main() { ndc /= ndc.z; v_viewRay = ndc.xyz; + + vTexCoord0 = a_texcoord0; } diff --git a/resources/core/shader/ssr_fs.sc b/resources/core/shader/ssr_fs.sc index a42d649..b8b0808 100644 --- a/resources/core/shader/ssr_fs.sc +++ b/resources/core/shader/ssr_fs.sc @@ -1,4 +1,4 @@ -$input v_viewRay +$input vTexCoord0, v_viewRay #include @@ -21,16 +21,13 @@ void main() { vec4 jitter = texture2D(u_noise, mod(gl_FragCoord.xy, vec2(64, 64)) / vec2(64, 64)); // sample normal/depth - vec2 uv = gl_FragCoord.xy * uv_ratio / uResolution.xy; + vec2 uv = GetAttributeTexCoord(vTexCoord0, textureSize(u_attr0, 0).xy); vec4 attr0 = texture2D(u_attr0, uv); vec3 n = attr0.xyz; // compute ray origin & direction - float near = -uMainProjection[2].w / uMainProjection[2].z; - float far = -near * uMainProjection[2].z / (1.0 - uMainProjection[2].z); - float z = (attr0.w * (far - near) + near*far) / far; - vec3 ray_o = v_viewRay * z; + vec3 ray_o = GetRayOrigin(uMainProjection, v_viewRay, attr0.w); vec3 ray_d = reflect(normalize(ray_o), n); // roughness @@ -38,6 +35,8 @@ void main() { vec3 right = cross(ray_d, vec3(0, 0, 1)); vec3 up = cross(ray_d, right); + + const float z_min = 0.1; // vec4 color = vec4_splat(0.); @@ -52,9 +51,9 @@ void main() { vec2 hit_pixel; vec3 hit_point; - if (TraceScreenRay(ray_o - v_viewRay * 0.05, ray_d_spread, uMainProjection, 0.1, /*jitter.z,*/ 64, hit_pixel, hit_point)) { + if (TraceScreenRay(ray_o - v_viewRay * 0.05, ray_d_spread, uMainProjection, z_min, /*jitter.z,*/ 64, hit_pixel, hit_point)) { // use hit pixel velocity to compensate the fact that we are sampling the previous frame - vec2 uv = hit_pixel * uv_ratio / uResolution.xy; + uv = hit_pixel * uv_ratio / uResolution.xy; vec2 vel = GetVelocityVector(uv); vec4 attr0 = texelFetch(u_attr0, ivec2(hit_pixel), 0); diff --git a/resources/core/shader/ssr_varying.def b/resources/core/shader/ssr_varying.def index ff632a3..b42cb63 100644 --- a/resources/core/shader/ssr_varying.def +++ b/resources/core/shader/ssr_varying.def @@ -1,4 +1,5 @@ -vec3 v_viewRay : TEXCOORD0 = vec3(0.0, 0.0, 0.0); +vec2 vTexCoord0 : TEXCOORD0; +vec3 v_viewRay : TEXCOORD1 = vec3(0.0, 0.0, 0.0); vec3 a_position : POSITION; vec2 a_texcoord0 : TEXCOORD0; diff --git a/resources/core/shader/ssr_vs.sc b/resources/core/shader/ssr_vs.sc index 33fa5ea..1636a1d 100644 --- a/resources/core/shader/ssr_vs.sc +++ b/resources/core/shader/ssr_vs.sc @@ -1,5 +1,5 @@ $input a_position, a_texcoord0 -$output v_viewRay +$output vTexCoord0, v_viewRay #include @@ -14,4 +14,6 @@ void main() { ndc /= ndc.z; v_viewRay = ndc.xyz; -} \ No newline at end of file + + vTexCoord0 = a_texcoord0; +} diff --git a/resources/core/shader/temporal_accumulation_fs.sc b/resources/core/shader/temporal_accumulation_fs.sc index e2832f5..e850fd0 100644 --- a/resources/core/shader/temporal_accumulation_fs.sc +++ b/resources/core/shader/temporal_accumulation_fs.sc @@ -1,9 +1,13 @@ +$input vTexCoord0 + #include SAMPLER2D(u_current, 0); SAMPLER2D(u_previous, 1); SAMPLER2D(u_attr1, 2); +#include + vec2 GetVelocityVector(in vec2 uv, vec2 ratio) { #if BGFX_SHADER_LANGUAGE_GLSL const vec2 offset = vec2(0.5, 0.5); @@ -17,15 +21,16 @@ void main() { ivec2 coord = ivec2(gl_FragCoord.xy); vec2 input_size = vec2(textureSize(u_previous, 0)); - vec2 uv = gl_FragCoord.xy / input_size; + vec2 uv = gl_FragCoord.xy / input_size; vec2 dt = GetVelocityVector(uv, uResolution.xy / input_size.xy); - vec4 current = texelFetch(u_current, coord, 0); - - vec4 c0 = texelFetchOffset(u_current, coord, 0, ivec2( 0, 1)); - vec4 c1 = texelFetchOffset(u_current, coord, 0, ivec2( 0,-1)); - vec4 c2 = texelFetchOffset(u_current, coord, 0, ivec2( 1, 0)); - vec4 c3 = texelFetchOffset(u_current, coord, 0, ivec2(-1, 0)); + vec2 uv_curr = GetAttributeTexCoord(vTexCoord0, textureSize(u_current, 0).xy); + vec4 current = texture2D(u_current, uv_curr); + + vec4 c0 = texture2DLodOffset(u_current, uv_curr, 0, ivec2(0, 1)); + vec4 c1 = texture2DLodOffset(u_current, uv_curr, 0, ivec2(0, -1)); + vec4 c2 = texture2DLodOffset(u_current, uv_curr, 0, ivec2(1, 0)); + vec4 c3 = texture2DLodOffset(u_current, uv_curr, 0, ivec2(-1, 0)); vec4 neighbour_min = min(min(c0, c1), min(c2, c3)); vec4 neighbour_max = max(max(c0, c1), max(c2, c3)); diff --git a/resources/core/shader/temporal_accumulation_varying.def b/resources/core/shader/temporal_accumulation_varying.def index 32f30d1..4aad665 100644 --- a/resources/core/shader/temporal_accumulation_varying.def +++ b/resources/core/shader/temporal_accumulation_varying.def @@ -1 +1,4 @@ -vec3 a_position : POSITION; \ No newline at end of file +vec2 vTexCoord0 : TEXCOORD0; + +vec3 a_position : POSITION; +vec2 a_texcoord0 : TEXCOORD0; diff --git a/resources/core/shader/temporal_accumulation_vs.sc b/resources/core/shader/temporal_accumulation_vs.sc index 1b87b56..9e87523 100644 --- a/resources/core/shader/temporal_accumulation_vs.sc +++ b/resources/core/shader/temporal_accumulation_vs.sc @@ -1,7 +1,9 @@ -$input a_position +$input a_position, a_texcoord0 +$output vTexCoord0, #include void main() { gl_Position = mul(u_viewProj, vec4(a_position.xy, 0.0, 1.0)); + vTexCoord0 = a_texcoord0; } diff --git a/scene_draw_to_texture.lua b/scene_draw_to_texture.lua index 488d76b..dcf56d0 100644 --- a/scene_draw_to_texture.lua +++ b/scene_draw_to_texture.lua @@ -46,7 +46,7 @@ while not hg.ReadKeyboard():Key(hg.K_Escape) do view_id, pass_ids = hg.SubmitSceneToPipeline(view_id, scene, hg.IntRect(0, 0, 512, 512), true, pipeline, res, frame_buffer.handle) -- draw a rotating cube in immediate mode using the texture the scene was rendered to - hg.SetViewPerspective(view_id, res_x, res_y, hg.TranslationMat4(hg.Vec3(0, 0, -1.8))) + hg.SetViewPerspective(view_id, 0, 0, res_x, res_y, hg.TranslationMat4(hg.Vec3(0, 0, -1.8))) val_uniforms = {hg.MakeUniformSetValue('color', hg.Vec4(1, 1, 1, 1))} -- note: these could be moved out of the main loop but are kept here for readability tex_uniforms = {hg.MakeUniformSetTexture('s_tex', res:GetTexture(frame_buffer.color), 0)} diff --git a/scene_draw_to_texture.py b/scene_draw_to_texture.py index 91d12ac..4926f84 100644 --- a/scene_draw_to_texture.py +++ b/scene_draw_to_texture.py @@ -47,7 +47,7 @@ view_id, pass_ids = hg.SubmitSceneToPipeline(view_id, scene, hg.IntRect(0, 0, 512, 512), True, pipeline, res, frame_buffer.handle) # draw a rotating cube in immediate mode using the texture the scene was rendered to - hg.SetViewPerspective(view_id, res_x, res_y, hg.TranslationMat4(hg.Vec3(0, 0, -1.8))) + hg.SetViewPerspective(view_id, 0, 0, res_x, res_y, hg.TranslationMat4(hg.Vec3(0, 0, -1.8))) val_uniforms = [hg.MakeUniformSetValue('color', hg.Vec4(1, 1, 1, 1))] # note: these could be moved out of the main loop but are kept here for readability tex_uniforms = [hg.MakeUniformSetTexture('s_tex', res.GetTexture(frame_buffer.color), 0)] diff --git a/scene_lua_script.lua b/scene_lua_script.lua new file mode 100644 index 0000000..477940e --- /dev/null +++ b/scene_lua_script.lua @@ -0,0 +1,36 @@ +-- Creating a Lua script VM for a scene object and communicating with a Script component + +hg = require("harfang") + +scene = hg.Scene() +script = scene:CreateScript('example') + +lua_vm = hg.SceneLuaVM() +lua_vm:CreateScriptFromSource(scene, script, "\ +a = 4\ +\ +function CallToPrintA() print('CallToPrintA: '..a) end\ +function CallToPrintV(v) print('CallToPrint: '..v) end\ +function CallToPrintScriptPath(s) print('CallToPrintScriptPath: '..s:GetPath()) end\ +\ +function CallToReturnValue() return 'String returned from scene VM to host VM' end\ +") + +a = lua_vm:GetScriptValue(script, 'a') +print('GetScriptValue returned a='..a) + +lua_vm:SetScriptValue(script, 'a', 24) + +a = lua_vm:GetScriptValue(script, 'a') +print('GetScriptValue returned a='..a) + +assert(lua_vm:Call(script, 'CallToPrintA', hg.LuaObjectList()) == true) +assert(lua_vm:Call(script, 'CallToPrintV', {8}) == true) +assert(lua_vm:Call(script, 'CallToPrintScriptPath', {script}) == true) + +assert(lua_vm:Call(script, 'InvalidCall', {}) == false) + +success, rvalues = lua_vm:Call(script, 'CallToReturnValue', {}) +assert(success == true) + +print('CallToReturnValue return value='..rvalues[1]) diff --git a/scene_lua_script.py b/scene_lua_script.py new file mode 100644 index 0000000..ce2bf92 --- /dev/null +++ b/scene_lua_script.py @@ -0,0 +1,36 @@ +# Creating a Lua script VM for a scene object and communicating with a Script component + +import harfang as hg + +scene = hg.Scene() +script = scene.CreateScript('example') + +lua_vm = hg.SceneLuaVM() +lua_vm.CreateScriptFromSource(scene, script, """ +a = 4 + +function CallToPrintA() print('CallToPrintA: '..a) end +function CallToPrintV(v) print('CallToPrint: '..v) end +function CallToPrintScriptPath(s) print('CallToPrintScriptPath: '..s:GetPath()) end + +function CallToReturnValue() return 'String returned from scene VM to host VM' end +""") + +a = lua_vm.GetScriptValue(script, 'a') +print('GetScriptValue returned a=' + str(lua_vm.Unpack(a))) + +lua_vm.SetScriptValue(script, 'a', lua_vm.Pack(24)) + +a = lua_vm.GetScriptValue(script, 'a') +print('GetScriptValue returned a=' + str(lua_vm.Unpack(a))) + +assert lua_vm.Call(script, 'CallToPrintA', [])[0] == True +assert lua_vm.Call(script, 'CallToPrintV', [lua_vm.Pack(8)])[0] == True +assert lua_vm.Call(script, 'CallToPrintScriptPath', [lua_vm.Pack(script)])[0] == True + +assert lua_vm.Call(script, 'InvalidCall', [])[0] == False + +success, rvalues = lua_vm.Call(script, 'CallToReturnValue', []) +assert success == True + +print('CallToReturnValue return value=' + str(lua_vm.Unpack(rvalues[0]))) diff --git a/scene_many_nodes.lua b/scene_many_nodes.lua index 54a2c7e..3202f56 100644 --- a/scene_many_nodes.lua +++ b/scene_many_nodes.lua @@ -69,6 +69,9 @@ while not hg.ReadKeyboard():Key(hg.K_Escape) do hg.Frame() hg.UpdateWindow(win) + + -- prevent GC bottleneck + collectgarbage() end hg.RenderShutdown() hg.DestroyWindow(win) diff --git a/scene_vr.py b/scene_vr.py index 2d5a29c..db3a210 100644 --- a/scene_vr.py +++ b/scene_vr.py @@ -88,17 +88,18 @@ def create_material(ubc, orm): left, right = hg.OpenVRStateToViewState(vr_state) vid = 0 # keep track of the next free view id + passId = hg.SceneForwardPipelinePassViewId() # Prepare view-independent render data once - vid, passId = hg.PrepareSceneForwardPipelineCommonRenderData(vid, scene, render_data, pipeline, res) + vid, passId = hg.PrepareSceneForwardPipelineCommonRenderData(vid, scene, render_data, pipeline, res, passId) vr_eye_rect = hg.IntRect(0, 0, vr_state.width, vr_state.height) # Prepare the left eye render data then draw to its framebuffer - vid, passId = hg.PrepareSceneForwardPipelineViewDependentRenderData(vid, left, scene, render_data, pipeline, res) + vid, passId = hg.PrepareSceneForwardPipelineViewDependentRenderData(vid, left, scene, render_data, pipeline, res, passId) vid, passId = hg.SubmitSceneToForwardPipeline(vid, scene, vr_eye_rect, left, pipeline, render_data, res, vr_left_fb.GetHandle()) # Prepare the right eye render data then draw to its framebuffer - vid, passId = hg.PrepareSceneForwardPipelineViewDependentRenderData(vid, right, scene, render_data, pipeline, res) + vid, passId = hg.PrepareSceneForwardPipelineViewDependentRenderData(vid, right, scene, render_data, pipeline, res, passId) vid, passId = hg.SubmitSceneToForwardPipeline(vid, scene, vr_eye_rect, right, pipeline, render_data, res, vr_right_fb.GetHandle()) # Display the VR eyes texture to the backbuffer