Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by D43DB33F · Feb 08, 2018 at 11:23 AM · shadergpumultithreadingcpuparallel

Using the GPU instead of multiple threads

I have made tiles of water, each of them made of a mesh whose vertices and normals are updated on each frame to generate waves.


This is using a lot of CPU power. So far I managed to make this multi-threaded by performing some calculations in separate threads while the main thread awaits, after what I assign the vertices/normals arrays back into the mesh in the main thread once the other threads have finished updating them.


This is how it works using pseudo code :

 Awake() begin.
     start threads and let them wait
 Awake() end.
 
 Update() begin
     let the threads compute new vertices and normals for each water tile
     wait for the threads to finish their work
     assign the vertices and normals back into the mesh (here, on the main thread)
 Update() end
 
 ... more Update() calls ...
 
 OnDestroy() begin.
     stop threads
 OnDestroy() end.


This multithreading optimisation allowed for a huge performance gain on a quad core CPU. However, it is still very greedy in terms of power, and I have the feeling that I would be able to compute even more stuff in an even faster way if I could use the GPU.


My question is : How can I use the GPU to perform calculations that can be performed in parallel ? I.e the calculations that I currently do in separate threads and only use Vector3, Mathf and other parts of the Unity API which are allowed to be used in another thread than the main one ?


Could I create some kind of "dummy shader" that would not be used to display stuff as its supposed to be, provide it with the arrays of vertices and normals I want to update, and then retreive the resulting values in C# ?


Just a bit of detail about what I actually compute in threads, if it matters : Basically I have, for each water tile, a two dimensional array of "base" points that represent the water when there is no wave at all and a second two dimensional array of directions wich represent the normal of the water at each of these base points. Then, for each "base point", I'm moving the base point along the direction using a Simplex noise function. Something like : vertices[xzIn1D] = basePoints[x,z] + directions[x, z] * GetNoise(something)


Thank you :D

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Pangamini · Feb 08, 2018 at 12:31 PM

How can I use the GPU to perform calculations that can be performed in parallel ?

Well, for your specific thing, waves on the water mesh, you just have to write a vertex shader, assign it to your material and watch it wave. No need to actually modify and update the mesh, CPU does not have to be involved at all. Vertex shader will do exactly what you want, without transferring the data between CPU and GPU (which is super slow). The vertex shader recalculates each displayed vertex in every frame, that's it's purpose. To place the vertex on the screen. Simply write your own vertex shader that will apply some distortion (the waves) to your vertex position, based on time and some other value (world position, wave offset texture, etc)(you might want to recalculate normals as well, but you will live without it) You can find tutorials on how to write shaders on official unity docs
Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image D43DB33F · Feb 08, 2018 at 12:38 PM 0
Share

Thanks for your answer. However I don't want my waves to be only visual. Currently, the shape of the water affects how objects like a boat behave on it. I have other components that compute buoyancy and drag physics which both require access to water level at a given point. I could probably use this approach of yours to get even better graphics, but I want my waves to be physical, not just visual, which is why I want to update the mesh. But maybe that I can provide water levels that take waves into account while having flat meshes and use a vertex shader to let the GPU deform the mesh as you suggest, so that I could have both the physical behaviour and visual apperance of waves. I don't know. Anyway, I'd still like to know how I could use the GPU for that kind of thing, even if, for this particular case your solution might be better, so that I can apply this to other things that could be done in parallel. I just read something about "compute shaders" that seems related to what I'm looking for, so I'll dig further into that.

avatar image Pangamini D43DB33F · Feb 08, 2018 at 01:02 PM 0
Share

Well, do you really need the mesh modified to apply the physics? If it's some sine wave, if you have the function for deformation in your program, can't you just evaluate the water level in location where needed, without using the actual mesh?

avatar image Pangamini D43DB33F · Feb 08, 2018 at 01:04 PM 0
Share

But O$$anonymous$$, for using GPU on such calculations, there are compute shaders but I never used those. Ins$$anonymous$$d, I like to write my input data into texture(s), then use Graphics.Blit to run it through shaders to do my calculations and then download the texture back to the CPU (which is always the slowest operation).

avatar image D43DB33F Pangamini · Feb 08, 2018 at 01:12 PM 0
Share

Yes I can return the right "wavy" water levels even with a flat mesh because i call the same code for both updating the mesh and getting water level. This is what I currently do so I could indeed go for a flat mesh. That Graphics.Blit looks like an interesting way to pass data in my case. I'll have a look into that. Are you talking about the OnRenderObject() unity event ?

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

122 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

RenderTexture.GrabPixels slowdown - How to fix? 0 Answers

how to i off load rendering to my gpu? 0 Answers

Multiple Lighting and DrawCalls Playable Alpha to Help Understand Problem 0 Answers

GPU Instancing and sorting problem 0 Answers

Why are my GPU instanced objects all black? 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges