Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Screen Tearing In Window Mode #2216

Closed
jhimes144 opened this issue Apr 5, 2024 · 13 comments
Closed

Screen Tearing In Window Mode #2216

jhimes144 opened this issue Apr 5, 2024 · 13 comments
Labels
bug Something isn't working

Comments

@jhimes144
Copy link

Release Type: Official Release

Version: 4.2.0.2122

Platform(s): Windows 11

Describe the bug
When running the fps template in window mode, screen tearing occurs (tested on a 100hz monitor, and 60hz monitor)

Per @Doprez, I tried the following code:

            WindowMinimumUpdateRate.MinimumElapsedTime = TimeSpan.FromMilliseconds(100f / 60f);
            MinimizedMinimumUpdateRate.MinimumElapsedTime = TimeSpan.FromMilliseconds(100f / 60f);

I've also tried changing PresenterInterval options. Having two selected still creates screen tearing, but its more, how do I say... steppy.

To Reproduce
Steps to reproduce the behavior:

  1. Create an empty project based off the FPS template.
  2. Create a TestGame with the following code
    public class TestGame : Game
    {
        protected override void BeginRun()
        {
            base.BeginRun();


            WindowMinimumUpdateRate.MinimumElapsedTime = TimeSpan.FromMilliseconds(1000f / 100f); // set to screen refresh rate
            MinimizedMinimumUpdateRate.MinimumElapsedTime = TimeSpan.FromMilliseconds(1000f / 100f); // set to screen refresh rate

            Window.IsBorderLess = true;
            Window.Position = new Stride.Core.Mathematics.Int2(0, 0);

            Settings.Configurations.Get<RenderingSettings>().DefaultBackBufferHeight = 1440; // set to screen res
            Settings.Configurations.Get<RenderingSettings>().DefaultBackBufferHeight = 3440; // set to screen res
        }
    }
  1. Observe screen tearing when running game.

Expected behavior
No screen tearing occurs, like when in exclusive full screen.

Additional context
I've also tried setting 0 for throttle limits on window update rate. I've also tried WindowMinimumUpdateRate.SetToPreciseAuto(), no dice.

@jhimes144 jhimes144 added the bug Something isn't working label Apr 5, 2024
@Doprez
Copy link
Contributor

Doprez commented Apr 5, 2024

Oh, its it the bad jitter in the FPS tempalte? whenever you move around and look at something it looks like bad FPS?

@jhimes144
Copy link
Author

jhimes144 commented Apr 5, 2024

So I'm new to stride so I haven't use any other template, but yes - especially when you strafe right or left and move your mouse to keep looking at an object - you get horrible screen tearing. In fullscreen mode, you don't get it at all.

EDIT: Just pulled up the third person template - also get the screen tearing. Although, its less noticeable because of how the camera moves.

@Doprez
Copy link
Contributor

Doprez commented Apr 5, 2024

Ok, assuming I understand what the problem is this time lol I have dealt with the same issue. It had to do with the Camera being directly attached in some way to the Physics body and updating its transforms based on that update interval.

The way I fixed it was the below steps:

What I had to do was create a SmoothFollowAndRotate script that just lerped between 2 entities at a certain speed.

[ComponentCategory("Utils")]
[DataContract("SmoothFollowAndRotate")]
public class SmoothFollowAndRotate : SyncScript
{
	public Entity EntityToFollow { get; set; }
	public float Speed { get; set; } = 1;

	public override void Update()
	{
		var deltaTime = (float)this.Game.UpdateTime.Elapsed.TotalSeconds;
		var currentPosition = Entity.Transform.Position;
		var currentRotation = Entity.Transform.Rotation;

		EntityToFollow.Transform.GetWorldTransformation(out var otherPosition, out var otherRotation, out var _);

		var newPosition = Vector3.Lerp(currentPosition, otherPosition, Speed * deltaTime);
		Entity.Transform.Position = newPosition;

		Quaternion.Slerp(ref currentRotation, ref otherRotation, Speed * deltaTime, out var newRotation);
		Entity.Transform.Rotation = newRotation;
	}
}

Then in your scene you have to unparent the camera from the player controller and add that smooth follow and rotate component to follow a new pivot point on your character controller.
image

This will break things in certain scripts since they use direct references to a CameraComponent but I will list the fixes below.

PlayerInput.cs

change
public CameraComponent Camera { get; set; }
to
public Entity Camera { get; set; }

Utils.cs

change
CameraComponent camera
to
Entity camera,
and change

camera.Update();
var inverseView = Matrix.Invert(camera.ViewMatrix);

to
var inverseView = camera.Transform.WorldMatrix;

FpsCamera.cs

Remove


        /// <summary>
        /// Gets the camera component used to visualized the scene.
        /// </summary>
        private Entity Component;

and change

        private void UpdateViewMatrix()
        {
            var camera = Component;
            if (camera == null) return;
            var rotation = Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0);

            Entity.Transform.Rotation = rotation;
        }

to

private void UpdateViewMatrix()
{
    var rotation = Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0);

    Entity.Transform.Rotation = rotation;
}

@jhimes144
Copy link
Author

@Doprez

Thank you for all of this, looks like you accidently copied and paste twice here, mind if you correct it? I got the rest of the changes in.

and change

    private void UpdateViewMatrix()
    {
        var camera = Component;
        if (camera == null) return;
        var rotation = Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0);

        Entity.Transform.Rotation = rotation;
    }

to

    private void UpdateViewMatrix()
    {
        var camera = Entity;
        if (camera == null) return;
        var rotation = Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0);

        Entity.Transform.Rotation = rotation;

}

@Doprez
Copy link
Contributor

Doprez commented Apr 5, 2024

Ah yep, fixed!

Also worth mentioning that my best speed for for the follow script is 25, seems to be the smoothest without falling behind.

@jhimes144
Copy link
Author

jhimes144 commented Apr 5, 2024

Whoa. Well, I think I definitely screwed it up somewhere because I'm getting wild behavior.

I'm going to come back tonight and just rewrite the camera and movement system, while taking in your smooth lerping technique into account. For me, I think the player control and camera should all be in one script. Thanks a ton for the help! If you have a sample project with these changes let me know as well.

Sounds like this is probably not a v-sync issue.

@Doprez
Copy link
Contributor

Doprez commented Apr 5, 2024

Here is the project with the fixes included: https://github.com/Doprez/smooth-fps-template/tree/main

It also had a change with some light shafts that cause an initial lag on loading the game but it should clear up after 2-3 seconds.

@jhimes144
Copy link
Author

jhimes144 commented Apr 5, 2024

@Doprez You are a saint! That fixed it. It was a bit laggy at first, but then when I also set the MinimumElapsedTime to Zero - it became butter smooth, and the experience is now identical to fullscreen mode. This really should be the new FPS 1st person template too, its much much smoother.

Its full steam ahead for my wpf/avalonia overlay. I think I definitely will open source it. The other wpf/avalonia solutions involve the attempt of rendering the UI framework in Stride, mine just uses win32 apis to get it to work.

EDIT: The only thing not working in this code is that gun shots do not hit when you are moving the character, I'm sure i can figure out a fix to that though.

@VaclavElias
Copy link
Contributor

@Doprez, do we need to document this?

@Doprez
Copy link
Contributor

Doprez commented Apr 6, 2024

@Doprez, do we need to document this?

Probably wouldnt hurt, I know this isnt the first time I have seen someone with this issue and even when I first started this drove me nuts because I didnt know why lol.

@VaclavElias
Copy link
Contributor

Let's do it. Do we have a relevant section in the manual? Should it go to UI section? Wouldn't you mind creating a PR, maybe just simply summarising the subject?

@Doprez
Copy link
Contributor

Doprez commented Apr 6, 2024

Yep, I can take some time later to do this. I am not sure where would be the right spot though.. maybe Physics?

@VaclavElias
Copy link
Contributor

VaclavElias commented Apr 6, 2024

Thank you. Let's put it under Physics. I will assist with the rest, I can check with others if it is the right location. Also, you can just dump content to the new docs page, and I can align and format further, just to save your time :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants