❄️🎁⛄ The Winter Games Tournament is Live! 🎄🎅❄️
Jump to content

Josh

Staff
  • Posts

    26,812
  • Joined

  • Last visited

Profile Information

  • Location
    USA

Recent Profile Visitors

1,527,872 profile views

Josh's Achievements

Grand Master

Grand Master (14/14)

  • Well Followed
  • Dedicated
  • Conversation Starter
  • Reacting Well
  • Problem Solver

Recent Badges

17.2k

Reputation

1.2k

Community Answers

  1. You will need to find the driver that corresponds to the GPU you have. The name of your GPU will appear in the program console when the editor starts. I tried searching for your card but can't identify it without the exact name.
  2. I have not heard of this problem before. I could only test it by getting the same computer as you. Are the drivers for your GPU discontinued? When were they last updated?
  3. AMD had some pretty bad driver bugs last year that would cause behavior like this. Make sure you have the latest drivers installed for your card: https://www.amd.com/en/support/download/drivers.html
  4. Here is is: https://www.leadwerks.com/community/topic/61318-release-notes/page/37/#findComment-320732 Assuming your game is written in C++, I recommend these settings: world->Update(window->display->GetRefreshRate()); world->Render(framebuffer, true, 1); And multiply all your time-dependent values by world->GetSpeed().
  5. What graphics card do you have?
  6. 5.0.2 beta Added Display:GetRefreshRate method. Added Hmd:GetRefreshRate method. Fixed player physics to work the same at any update frequency. Improved timing and thread sychronization. This is experimental. If you don't want your workflow interupted, switch to the default branch now. In this build, timing works differently. The third command argument for World:Render has been replaced with a new value, syncedframes: World::Render(framebuffer, bool vsync = true, int syncedframes = -1) This value allows you to specify how many frames the rendering thread should draw before it waits for a new update from the main thread. The max framerate value this command previously supported will no longer be used, because this value is now calculated from the world update frequency and number of synced frames. Emulating 5.0.1 Standard Behavior The standard behavior previous builds use is a 60 hz game loop, and the rendering thread is allowed to go as fast as it wants. This will work with any display or VR headset refresh rate: world->Update(60); world->Render(framebuffer, true, 0); Or if you want to test the maximum framerate set VSync to false: world->Update(60); world->Render(framebuffer, false, 0); Improved Synchronization at 60 hz If you set syncedframes to 1, and the world update rate is 60, then for every one iteration of the game loop, one frame will be rendered. The main and rendering threads will still be running at the same time, but they will be more closely synchronized, for lower-latency input: world->Update(60); world->Render(framebuffer, true, 1); However, on high-frequency displays this will give you a framerate lower than the max refresh rate. Competitive E-Sports Games If want to adjust the game speed to support any display with minimal latency, you can do this: world->Update(window->display->GetRefreshRate()); world->Render(framebuffer, true, 1); This is the best setting for minimal latency for twitch shooters written in C++. Note that if a frequency other than 60 is used, you will need to multiply all the time-dependent values in your code by world->GetSpeed(). Velocity does not need to be modulated with this, because it is already in units of distance over time. If you want your game to run at a speed faster than the screen refresh rate, you can set vsync to false: world->Update(200); world->Render(framebuffer, false, 1); I believe this is how the timing in the newer Doom games works, and it explains why the game cannot run at a framerate faster than 200. Anything higher than that would probably start to affect how physics and other game code works, causing erratic behavior. Tight Synchronization with Varying Game and Rendering Frequencies The problem with perfectly synced timing on high-frequency displays is it decreases the amount of time your code has to run in the main thread. At 60 hz your game code has 16.667 milliseconds to run. If the screen refresh rate is 240 hz, that only allows 4.16 milliseconds for your game code to run. If there are a lot of enemies with complex code or if the game is written with Lua, this will probably cause the game to slow down. You might also want to always make the game update at 60 hz so that you don't have to multiply everything by world->GetSpeed(). You can combine a higher rendering frequency with a lower game frequency, by specifying more than one synced frames: world->Update(60); world->Render(framebuffer, false, 2); This will update the game at 60 hz, but render the world at 120 hz, drawing two frames for every game loop. The previous two orientations of each entity will be interpolated, so you have smooth motion even though two frames are rendered for every one iteration of the game loop. If you wanted the game to render at 180 hz, you could set the third argument to 3. To support any display frequency with close synchronization of frames, you might wish to do something like this: float refreshrate = window->display->GetRefreshRate(); int syncedframes = Floor(refreshrate / 60.0f); int updatespeed = Round(refreshrate / syncedframes); world->Update(updatespeed); world->Render(framebuffer, true, syncedframes); The above code will give you these values: Display refresh rate: 90 hz Update speed: 90 Synced frames: 1 Display refresh rate: 120 hz Update speed: 60 Synced frames: 2 Display refresh rate: 144 hz Update speed: 72 Synced frames: 2 Display refresh rate: 240 hz Update speed: 60 Synced frames: 4 If you are rendering at a faster speed than the game loop, you may wish to use the Camera::SetMouseLook feature to handle camera looking in the rendering thread. This will give you low-latency camera movement, with a few caveats: The player movement will still be updating at a lower frequency and might feel slightly mushier, but since player movement has inertia anyways it might not be very noticable. The camera rotation will be fed back to the main loop, so it will always be a few milliseconds behind. This could matter in E-sports type hyper-competitive shooters, but probably doesn't matter for regular FPS games. On the other hand, someone with a 240 hz display is likely to also have a top-of-the-line CPU, so maybe it all balances out. It's up to you. Default Behavior If you don't understand any of this, or don't care, then you can just not specify any parameter, and the engine will choose settings for you based on the display refresh rate. For 75% of players this will be 60 hz, so if your game loop is running at 60 hz and vsync is enabled, the engine will choose 1 for the number of synced frames, otherwise it will be set to 0. Visualizing the Technique This code provides a dramatic example that shows how varying game and rendering frequencies works. Here the game updates at just one update per second, but the renderer displays smooth motion at 120 frames per second, using just the inputted information! (Don't actually do this in your own games, this is just for learning.) #include "Leadwerks.h" using namespace Leadwerks; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Leadwerks", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); auto world = CreateWorld(); auto framebuffer = CreateFramebuffer(window); auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetPosition(0, 0, -2); auto light = CreateBoxLight(world); light->SetRotation(45, 35, 0); light->SetRange(-10, 10); light->SetColor(2); auto A = CreateBox(world); A->SetPosition(-1,0,0); A->SetColor(0, 0, 1); auto B = CreateBox(world); B->SetPosition(1, 0, 0); B->SetColor(0, 0, 1); while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { // The box on the left will show smoothed motion A->Turn(0, 0, 22.5); // The box on the right will show the true state of the game B->Turn(0, 0, 22.5); B->Sync(); // Game updates once per second world->Update(1); // Game renders 120 frames, evenly spaced, for every one game loop iteration world->Render(framebuffer, false, 120); } return 0; }
  7. Note to self...
      • 1
      • Confused
  8. I'll have some more stuff for you after Christmas. I did some work on the timing and found a way to run the logic and rendering thread in sync at any frequency. It feels like playing new Doom games at 200 FPS. I think you will like it.
  9. @vega I have added an experimental mouse look feature in 5.0.2 on the beta branch that gets run in the rendering thread. This operates in a manner similar to how the VR headset orientation updates, right before a frame is rendered: https://www.leadwerks.com/community/topic/61318-release-notes/page/37/#findComment-320702 This will provide very low-latency mouse input controls.
  10. What GPU do you have?
  11. 5.0.2 beta Added experimental Camera:SetMouseLook command. This handles mouse looking in the rendering thread, right before a frame is drawn, in the same way that our VR orientation updating code operates. This will provide you with very low-latency mouse feedback, ideal for fast-paced games. The arguments are mode, speed, and smoothness and it should be called like this: camera:SetMouseLook(true, 0.1, 0.5)-- 0.1 degree / pixel moved, 0.5 smoothness Speed (second value) should be greater than zero. Smoothness (last value) should be less than 1.0, 0.0 for no smoothing. You only need to call this command once. You should not mix this with your own mouse look code. The camera rotation will be retrieved back from the rendering thread automatically. Note this does not yet handle objects parented to the camera, like a weapon view model. Here is a version of the CameraControls.lua script, adjusted to use this feature. Since the looking behavior is controlled in the rendering thread, you need to disable it before switching to the menu, or is it keep control of the mouse. Hit Alt + F4 to close the window if you get stuck. ---@class CameraControls : Entity CameraControls = {} CameraControls.mousesmoothing = 0.5--"Mouse smoothing" CameraControls.mouselookspeed = 1.0--"Look speed" CameraControls.movespeed = 4.0--"Move speed" ---@param self CameraControls function CameraControls:Start() local camera = Camera(self) if camera ~= nil then camera:SetMouseLook(true, self.mouselookspeed * 0.1, self.mousesmoothing) end self:ListenEvent(EVENT_WORLDPAUSE, self.world) self:ListenEvent(EVENT_WORLDRESUME, self.world) end ---@param self CameraControls ---@param event Event function CameraControls:ProcessEvent(event) local camera = Camera(self) if event.id == EVENT_WORLDPAUSE then if camera ~= nil then camera:SetMouseLook(false, self.mouselookspeed * 0.1, self.mousesmoothing) end elseif event.id == EVENT_WORLDRESUME then if camera ~= nil then camera:SetMouseLook(true, self.mouselookspeed * 0.1, self.mousesmoothing) end end end ---@param self CameraControls function CameraControls:Update() local window = ActiveWindow() if window == nil then return end local speed = self.movespeed / 60.0 if window:KeyDown(KEY_SHIFT) then speed = speed * 10.0 elseif window:KeyDown(KEY_CONTROL) then speed = speed * 0.25 end if window:KeyDown(KEY_E) then self:Translate(0, speed, 0) end if window:KeyDown(KEY_Q) then self:Translate(0, -speed, 0) end if window:KeyDown(KEY_D) then self:Move(speed, 0, 0) end if window:KeyDown(KEY_A) then self:Move(-speed, 0, 0) end if window:KeyDown(KEY_W) then self:Move(0, 0, speed) end if window:KeyDown(KEY_S) then self:Move(0, 0, -speed) end end
  12. Is this still occuring? Can it be reproduced reliably?
  13. @Vladimir Sabantsev I really appreciate your in-depth feedback. I am planning to fix all bugs that can be fixed right now (a few things depend on internal refactoring) before I proceed with a new deep dive into modifications to the renderer for 5.1. The plan is to move lighting shader code into a deferred step (as Leadwerks 4 does) which I think will probably provide better optimization for low-end hardware and simpler shader code.
  14. Carving a 32-sided cylinder out of another one, at a 90 degree angle...this may be as good as it gets. Every other CSG program I've ever seen has simi;ar issues when the geometry gets complex. The crash is fixed on the beta branch, so I will call this finished for now.
  15. 5.0.2 beta Several bugs fixed.
×
×
  • Create New...