Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
OBI Assets do not work with Octane Render
#11
I know. Totally understand. I tried explaining that to them but they just don't get it.
Anyway all good on that topic. Its a small code change anyway.

Now however I have a different problem. When rendering with timeline and Octane offline renderer the timescale of OBI gets out of whack. Obviously with an offline renderer the frame rate is like one frame every few seconds.

When rendered the OBI simulation runs at hyper speed with ropes flying around in all directions

OBI seems to be using actual real time rather than game time. How can I fix this ?

I noticed that in OBIFixedUpdate you are using BeginStep(Time.fixedDeltaTime);

When I check ObiLateUpdater it says:
/// Updater class that will perform simulation during LateUpdate(). This is highly unphysical and should be avoided whenever possible.
    /// This updater does not make any accuracy guarantees when it comes to two-way coupling with rigidbodies.
    /// It is only provided for the odd case when there's no way to perform simulation with a fixed timestep.
    /// If in doubt, use the ObiFixedUpdater component instead.

What is my best strategy. Is it to switch OBIFixedUpdate to use time.deltatime ? or to switch to OBILateUpdater
Or to create an updater that runs during update ?

Note: This is going to be a common issue for anyone using Timeline with offline render mode.
Reply
#12
(13-08-2021, 01:01 PM)tcwicks Wrote: I know. Totally understand. I tried explaining that to them but they just don't get it.
Anyway all good on that topic. Its a small code change anyway.

If you use some kind of version control (git, svn) it might be a good idea to keep a patch with your changes around. That way every time you update Obi, applying your changes should be a matter of just clicking a button (and you minimize potential human error when copying/pasting code).

(13-08-2021, 01:01 PM)tcwicks Wrote: Now however I have a different problem. When rendering with timeline and Octane offline renderer the timescale of OBI gets out of whack. Obviously with an offline renderer the frame rate is like one frame every few seconds.OBI seems to be using actual real time rather than game time. How can I fix this ?

However, the way Obi is updated is controlled by the ObiUpdater family of components, of which there are a few (and you can write your own if needed).

By default Obi uses ObiFixedUpdater, which hooks up to Unity's standard FixedUpdate() call, using Unity's Time.fixedDeltaTime. This would be "game" time, which is the correct thing to do for physics. You can also use ObiLateUpdater, which would use a variable time stepping scheme (Time.deltaTime, or "wall" time). Since these are all Unity's standard callbacks/time deltas, things like Time.timeScale for bullet-time effects and the like are accounted for. See:

http://obi.virtualmethodstudio.com/manua...cture.html
http://obi.virtualmethodstudio.com/manua...aters.html

As to why time gets out of whack when using timeline+Octane, I have no idea. Do regular physics (ie, rigidbodies) work?
Reply
#13
Found this:

https://forum.unity.com/threads/is-it-po...y.1000794/

Quote:Timeline doesn't play well with Physics because there is no fixed update option in the playable director.
You can try a manual evaluation in FixedUpdate using either

playableDirector.time += Time.fixedDeltaTime;
playableDirector.Evaluate()

or

playableDirector.playableGraph.Evaluate(Time.fixedDeltaTime).

However, Timeline updated in this manner won't play audio correctly. Signals are not fired in the former, and might work in the latter (I believe they should, but I am not 100% sure).

Not sure about the validity of these statements, but they're quite recent (Nov 2020). Seems like timeline and physics don't work well with each other. Will do some testing of my own and report back.

Edit: Off the top of my head, I get it that scrubbing trough the timeline won't work (since physics can't be simulated "backwards"), but just playing forwards from the top should work as long as correct deltaTimes are being passed to FixedUpdate(). Another possible workaround would be simulating in realtime and recording particle data to a timeline track (not sure of how flexible the timeline API is, but I'd bet a finger it allows you to store your own data on tracks).
Reply
#14
Thanks so much for this. To answer your comment yes rigid body physics works with Timeline.

I will give it a try using
playableDirector.time += Time.fixedDeltaTime;
playableDirector.Evaluate()

Will report back in a bit.

Thanks so much for the pointer.
Reply
#15
Found the root of the problem
So with time.captureframerate set to say 30. FixedUpdate will run on a fixeddeltatime of 0.02 while the standard update loop will run on a deltatime of 0.0333

Which means obiFixedUpdater will be running the simulation approximately twice for some frames and once for some frames.

However when using the slow octane offline renderer fixedupdate effectively was getting run 333 times per update with fixeddeltatime for some reason being set all the way down to 0.0001

Of course if the simulation is running 333 times per frame floating point error etc.. is going to kick in.
So what I did was I fixed the number of times the simulation runs to a fixed number of twice per frame.

This fixes the issue.


Code:
[color=#333333][size=small][font=Tahoma, Verdana, Arial, sans-serif]        [/font][/size][/color]public bool UseCustomTime = false;
        public float CustomTimeSteps = 2f;
        public int LastNumItterations = 0;
        public float LastAccumulatedTime = 0f;
        public float LastDeltaTime = 0f;
        private int NumItterations = 0;

        private void FixedUpdate()
        {
            float TimeStepDelta;
            if (UseCustomTime)
            {
                TimeStepDelta = (1f / Time.captureFramerate) / CustomTimeSteps;
            }
            else
            {
                TimeStepDelta = Time.fixedDeltaTime;
            }

            if (accumulatedTime > 0f)
            {
                ObiProfiler.EnableProfiler();
                float substepDelta;

                BeginStep(TimeStepDelta);
                substepDelta = TimeStepDelta / (float)substeps;


                // Divide the step into multiple smaller substeps:
                for (int i = 0; i < substeps; ++i)
                {
                    Substep(TimeStepDelta, substepDelta, substeps - i);
                }

                EndStep(substepDelta);

                ObiProfiler.DisableProfiler();

                accumulatedTime -= TimeStepDelta;
                NumItterations += 1;
            }
        }

        private void Update()
        {
            ObiProfiler.EnableProfiler();
            Interpolate(Time.fixedDeltaTime, accumulatedTime);
            ObiProfiler.DisableProfiler();

            accumulatedTime += Time.deltaTime;
            LastNumItterations = NumItterations;
            LastAccumulatedTime = accumulatedTime;
            LastDeltaTime = Time.deltaTime;
            NumItterations = 0;
        }
Reply
#16
Hi there,

Glad you found a workaround! Not sure why running Octane would cause the fixed delta to get set to 0.0001, but that is indeed bound to cause some issues. Add to this the fact that Obi generally uses substepping (4 substeps by default) and that would yield a delta of 0.000025 seconds per substep.

I took a look at your code, looks ok except for one line in the Update() method:

Code:
Interpolate(Time.fixedDeltaTime, accumulatedTime);

this should be:

Code:
Interpolate(TimeStepDelta, accumulatedTime);

You should pass the duration of the last timestep as the first argument, and the amount of "unsimulated" time left as the second one.

Otherwise physics state interpolation won't work well (if you're using it, can be enabled/disabled in the ObiSolver component).
Reply