Use compute shaders to create water effect in Unity. Now you can simulate ripples of a moving boat!

Поділитися
Вставка
  • Опубліковано 23 жов 2024

КОМЕНТАРІ • 42

  • @HenriquePistelli
    @HenriquePistelli 3 місяці тому +2

    For those who are using recent versions of Unity (I'm using 2023.2.20f1) and the obstaclesTex does not affect the waves, try this:
    - Select your Orthographic camera
    - In the Rendering tab, check the option Custom Frame Settings
    - In the Rendering section, find Post-process
    - Check the left checkbox and uncheck the right checkbox
    This will prevent the camera to use post-processing and use "raw" image. It fixed for me. Hope this helps someone else :)

  • @juleslatu5376
    @juleslatu5376 2 роки тому +2

    I am a students in tech art and you have no idea how much it helped me, i am patiently waiting for the next one, thank you so much

    • @aoiti
      @aoiti  2 роки тому

      I am glad you find them useful :)

  • @random_precision_software
    @random_precision_software Рік тому +2

    Just came across your channel ..Ive subbed and hope to see more Tutorials !

  • @nayuch2358
    @nayuch2358 Рік тому +2

    perfect for beginners!! plz upload more, or may be upload some tutorials about using compute buffer/graphic buffer with vfx graph

    • @aoiti
      @aoiti  Рік тому

      I am happy you liked 'em. I am currently working on the strategy game I started in these tutorials. I hope to continue with compute shaders once I release that game. sorry for the delay.

  • @gutzimmumdo4910
    @gutzimmumdo4910 Рік тому +3

    is the surface always 2D, only creating the illusion of 3D water or does the surface actually change height?

    • @aoiti
      @aoiti  Рік тому

      Not in this video, but in the next video you can see that displacement shaders can be used to extrude the wave in and out. ua-cam.com/video/5EyL0WpjdI8/v-deo.html&ab_channel=SpontaneousSimulations

  • @山田凌-c7t
    @山田凌-c7t 2 роки тому +5

    Thank you for shearing your skills!! I tried your 2 water effect video's code on my unity.
    This time doesn't work correctly. Video's 33:14, wave reflects by block. But my wave doesn't reflects.
    Wave reflects only by the outside of WaterSurface(defined obstaclesTex.width and obstaclesTex.height).
    I think there are errors in my cords of definition of obstacles...
    Would you mind giving some advises?

    • @aoiti
      @aoiti  2 роки тому +1

      There can be several reasons. Because we check the color of the texture for the obstacles, we need to make sure the red color is not tinted. It cud tint, if camera is not ortographic, or the material of the sprites that overlay the objects do not use Unlit shaders.

    • @aoiti
      @aoiti  2 роки тому +1

      I suggest first make sure the obstacleTex is created properly. If then I suggest instead of cheking for red color in the code, check if color is NOT black. that cud remedy the issue

    • @山田凌-c7t
      @山田凌-c7t 2 роки тому

      ​@@aoiti
      I checked both the obstacles camera is orthographic and obstacles(sprites from cube) are red.
      But I checked my code, I can't find red color.
      I don't know how to check obstaclesTex of objects are defined in Wavemanager.cs and waveCompute.

  • @HenriquePistelli
    @HenriquePistelli 3 місяці тому +1

    I was wondering, is there a way to not deform the water around the object when it is not moving?
    Like when a player is stationary, the water is not deformed around him, but it creates the waves when moving

    • @aoiti
      @aoiti  3 місяці тому +1

      you can change the size or transparency of the child capsule depending on the transform speed. goodluck

    • @HenriquePistelli
      @HenriquePistelli 3 місяці тому

      @@aoiti That's a good idea, didn't think about that. Thanks! :D

  • @la-ki5wd
    @la-ki5wd Рік тому +6

    please post this to github if you can. i'm at 20 minutes and not getting the same results as you despite checking for typos multiple times...

  • @werkhaye
    @werkhaye Рік тому

    Hello, very nice tutorial ! just one question, if we want the border conditions to absorb instead of reflect, how would we do that in the compute shader ? It is in 2D, so the formula shown by Haroon Stephen is not so clear to me when converted to 2D.

    • @aoiti
      @aoiti  Рік тому

      If I recall correctly, all you need to do is to zero all the border heights before dispatching to GPU, just like in the cpu-run wave simulation

  • @bdenix1997
    @bdenix1997 Рік тому +2

    a rather irrelevant question: isnt every class passed by referece already? why would you need to put ref when passing it? doesnt it work without it? ( on initializetexture method)

    • @aoiti
      @aoiti  Рік тому

      It's a very good question. I think the reason is you create a copy class when you pass without ref keyword. The question is asked here if you would like to read: stackoverflow.com/questions/186891/why-use-the-ref-keyword-when-passing-an-object

  • @seersdduR
    @seersdduR 6 місяців тому

    Is this possible in Web? I tried on webgl (2023.3.0a14 WebGPU) , but TextureFormat doesn't support Snorm Format. and if No SNorm, Shader's not works

  • @la-ki5wd
    @la-ki5wd Рік тому

    I'm pretty sure I typed everything correctly, yet at 21:25 you get movement while I don't. Could this fail for me because of my system maybe? Running off an Intel UHD Graphics 620.

    • @aoiti
      @aoiti  Рік тому +1

      I am sorry you are having trouble implementing. To find where the problem occur, cud you try to print out the value at the center of the texture to console? Maybe the texture cud not be updated or maybe the compute shader is simply not being initiated.

  • @Justin-sv1if
    @Justin-sv1if Рік тому

    How can I adjust the wave sizes/distortion/length, etc.. I keep changing values within the if statements in the compute shader file but the only thing I can see that truly changes it is the dispersion.

    • @Justin-sv1if
      @Justin-sv1if Рік тому

      Also, this was a great video so thank you no matter what!

  • @GameOver-ol7ku
    @GameOver-ol7ku 2 роки тому

    Hey, I used your Compute shader to get my ripples for a school assignment. I changed it so that I can get a ripple on the mouse position when I click and on the point of collision with an object. The issue now though is that when the collision ripple spawns the ripple based on the mouse position also spawns on the spot where I last clicked. Any clue why or how I could fix this? Clicking doesn't trigger the collision ripple btw.
    My WaveManager code that is of importance is the following:
    void Update()
    {
    Graphics.CopyTexture(NState, Nm1State);
    Graphics.CopyTexture(Np1State, NState);
    waveCompute.SetTexture(0, "NState", NState);
    waveCompute.SetTexture(0, "Nm1State", Nm1State);
    waveCompute.SetTexture(0, "Np1State", Np1State);
    waveCompute.SetVector("resolution", new Vector2(resolution.x, resolution.y));
    waveCompute.SetFloats("dispersion", dispersion);
    Ray ray = cam.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit = new RaycastHit();
    if(Input.GetMouseButtonDown(0)){
    if (Physics.Raycast(ray, out hit)){
    texOrigin = hit.textureCoord;
    }
    effect.z = 2;
    }

    waveCompute.SetVector("effect", effect);
    effect.z = 0;
    waveCompute.SetVector("rippleOrigin", new Vector2(resolution.x * texOrigin.x, resolution.y * texOrigin.y));
    waveCompute.Dispatch(0, resolution.x / 8, resolution.y / 8, 1);
    //Send the main texture of the compute shader to the vertex shader to make the waves in 3D instead of 2D
    waveMat.mainTexture = NState;
    }
    private void OnCollisionEnter(Collision other) {
    RaycastHit colHit = new RaycastHit();

    foreach(ContactPoint contact in other.contacts){
    Ray ray = new Ray(contact.point-contact.normal, contact.normal);
    if(Physics.Raycast(ray, out colHit)){
    Debug.Log(colHit.textureCoord);
    effect.z = 10;
    waveCompute.SetVector("effect", effect);
    waveCompute.SetVector("rippleOrigin", new Vector2(resolution.x * colHit.textureCoord.x, resolution.y * colHit.textureCoord.y));
    waveCompute.Dispatch(0, resolution.x / 8, resolution.y / 8, 1);
    }
    }
    }
    The compute shader is the exact same. I tried making a different kernel for the collision ripple but that didn't work.

    • @aoiti
      @aoiti  Рік тому

      Sorry. I have been busy with the game. I am not sure but I think you need to move the SetVector function into the Raycast check. Goodluck

    • @GameOver-ol7ku
      @GameOver-ol7ku Рік тому +1

      @@aoiti No worries, ended up removing the on click ripple. Found an other bug that might have caused it though. The balls shoot a raycast downwards and sometimes hit themselves with said raycast causing them to default to the last mouse position. I think that was the reason it happened. Having removed the click though I am not certain.

    • @aoiti
      @aoiti  Рік тому +1

      @@GameOver-ol7ku Yes Raycasts can be very confısing. You can set your mesh to ignore outwards raycasts too, but I cant remember how atm.

    • @GameOver-ol7ku
      @GameOver-ol7ku Рік тому +1

      @@aoiti I put the balls on the ignore raycast layer, worked well enough

  • @munyunu
    @munyunu 11 місяців тому

    Is this downloadable? Thank you.

    • @aoiti
      @aoiti  11 місяців тому

      sorry it is not.

  • @AhmedSayed-fj7pu
    @AhmedSayed-fj7pu Рік тому

    Can this used on mobile ?
    sorry i am a beginner

    • @aoiti
      @aoiti  Рік тому

      Sorry. I am not sure because it's quite GPU intensive.

    • @AhmedSayed-fj7pu
      @AhmedSayed-fj7pu Рік тому

      thanks for your replay and could make a one for mobile if i will not annoy you

  • @mehdibashirinejad7798
    @mehdibashirinejad7798 11 місяців тому

    mybe put source?

  • @J4ME5_
    @J4ME5_ 2 роки тому +1

    omg I wish I could download this, its amazing

    • @aoiti
      @aoiti  2 роки тому +1

      Glad you liked it. Once I add a nice shader to it, I will make it available on unity asset store.

  • @claudiosalvatico58
    @claudiosalvatico58 2 роки тому

    Good tutorial works perfect!, one question is it possible to make it work with Time.timeScale?
    i tried "if(frames >=Mathf.RoundToInt(Mathf.Lerp(8, 0, Time.timeScale)))" on Update and it seems to work but is there a better alternative?

    • @aoiti
      @aoiti  2 роки тому +1

      It's a good question. I suggest running a coroutine in the background that calls for the wavecompute dispatch at every certain seconds. So it would look like;
      void Start()
      {
      InitializeTexture(ref NState);
      ...
      StartCoroutine(waveStep(0.1f)); //starts the coroutine with a time step of 100 ms
      }
      void Update() //no need to enter anything in here.
      {
      }
      IEnumerator waveStep(float timeStep)
      {
      while (true) //continues until the coroutine is halted externally.
      {
      Graphics.CopyTexture(NState, Nm1State);
      ...
      waveCompute.SetTexture(0, "NState", NSTate);
      ...
      waveCompute.Dispatch(0, Resolution.x / 8, Resolution.y / 8, 1);
      yield return new WaitForSeconds(timeStep); //wait by certain amount of time.
      }
      }

    • @claudiosalvatico58
      @claudiosalvatico58 2 роки тому +1

      @@aoiti I don't know why that solution didn't cross my mind.
      I just tried it and it works perfect, so thank you very much!👌