Recorder Writting Exr Files With Time Based Shader Are Wrong

Hi everyone,

I initially posted this thread elsewhere but I think it is more accurate to post it here as it is more a shader issue than a Recorder/Timeline one.

I’m working on a film project done with unity and I’m investigating into the Unity recorder to do EXR exports and I noticed that my time based water shader was way too fast than it should be.

In my test I’m rendering an image sequence at 4K 24fps 16:9, which gives me 0.5 fps in the Game View because of the time to write the exr files.

I assume the rendered water shader is too fast because the game clock is running even if i’m stuck at 0.5 fps. So is there a way to render something like this without a time node but with something that takes in account the framerate I’m rendering at?

What would be great is that the recorder records the result I get when I’m running the sequence in Game Mode without recording.

@jasonm_unity3d answered me with this

Now my problem is that I don’t code at all and that I’ve done the shader with shadergraph. Sadly it seems like there’s only the Time node with the following values:
Yesterday I fake fixed my issue by reducing the speed of the water but it isn’t a good way to work as I must guess the speed. Plus it means I would have to change the value each time I want to switch between render or preview in real time.

So now I’ve been trying to research and understand what these do but I can’t find a way to replicate it and fix my problem.

Thanks

Have you tried driving it with Delta time instead of Time? That’s my first guess that might help, otherwise this is something we’d need an official bug reported for to test and fix.

Instead of time (defined in the shader by that node) you can set an variable in the shader, call it FunctionalTime or something (up to you) and then manually set it by shader.setfloat or shader.setglobalfloat with a c# script.

That allows you to integrate it with any other time scripting you’ve got going on that works at 0.5fps.

IE if you’re going for 24fps, then after each frame is rendered it would increase the FunctionalTime value by (1/24).

I already tried with delta time (and smoothed) and the movement of the water goes back and forth in position in a very laggy way. I might be doing something wrong as I’m pretty new at using the shader graph.
Every tutorials I’ve looked at use the following technique to animate. Is changing the Time node to Delta Time requires to do something more? As it only counts the seconds between each frame.
4438714--406099--upload_2019-4-17_9-58-16.png

(Also I noticed I haven’t said which version of Unity I’m working with; 2018.3.2 with HDRP 4.6.0 so it may be the reason of it not working correctly. I’m going to try with a newer version of Unity and see if I get the same result).

I think I get what you’re telling me but I’m sorry I’m not a tech artist and I have no knowledge of c# to do what you proposed, I will see with my team if someone has some time to try and do this.

Alright the issue can be recreated in 2019.1 Delta Time doesn’t offset the texture and Time makes the water go crazy fast when rendering 4k exr files

[edit] I tried also with the visual effect graph and I’m glad it doesn’t have the same issue, it renders correctly
I suppose the vfx graph is clocked with another timer than the shader graph which is puzzling me. Is it because one is calculated on GPU and not the other?

Here’s some more info on setglobalfloat:

https://docs.unity3d.com/ScriptReference/Shader.SetGlobalFloat.html

In your shader graph, you create a variable like any other, a vector1. Then you make it a property that moves it to the blackboard. The exposed button, you want to UN-TICK that. Also note the internal shader name (forget what they call it, but it’s not the main name of the value, usually it’ll be FLOAT+01231324 or something).

I’m out of date with the Unity recorder, but if you can access the script, then you want to add a new float called FunctionalTime or ManualTime or something you can remember.

Then you want to add to the value on pre or post-render.

Thanks a lot for your help! Combined to some tutorials on YT I managed to write a super basic c# script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FunctionRenderTime : MonoBehaviour
{
    public Material waterOffset;
    public float timingValue;
    public float timer;
    // Start is called before the first frame update
    void Start()
    {
        waterOffset.SetFloat("Vector1_3236E2C5", timer);
    }

    // Update is called once per frame
    void Update()
    {
        timer += timingValue * Time.deltaTime;
        waterOffset.SetFloat("Vector1_3236E2C5", timer);
    }
}

Now it renders at the same speed in both Game Mode and in the exr render

[edit] the naming is very specific but it is very easy to make this script flexible

@kFreezer would you mind elaborating on how you connected your script to shader graph.
I’m getting the following error:
UnassignedReferenceException: The variable waterOffset of FunctionRenderTime has not been assigned. You probably need to assign the waterOffset variable of the FunctionRenderTime script in the inspector.
I’ve updated the code to reflect Vector1_4A80CB37.
See attached image for SG workflow.
I’m using Unity 2019.1.3f1 and Shader Graph 5.13.0.
Any suggestions would be awesome!

In this case waterOffset is a material, you have to assign it to its slot in the script, wherever that is in your Scene.

And since you can, you should change Vector1_13123087r1 to an actual name, both in the script and the shader graph. Click the field called Reference in SGE and call it something descriptive, usually the same as the variable (or WaterOffsetVector). You might end up expanding on things later, so keeping hings readable can help.

1 Like

@Jesus !! Amazing thanks so much, just missed that last bit.
I’ve attached as screenshot and SGE for others to reference.

4585777--427204--Screen Shot 2019-05-27 at 2.06.22 pm.jpg

Worked for me too. Thank you so much !