Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 LiverX! · May 18, 2014 at 05:08 AM · conversioncompute shaderdoubledirectx 11

Compute Shader, replacing floats to double

I made some variant of particle system what independed on particle count, but i hadn't enogth float precision to make system in stabilised state, so i decided to use double instead of float. But functions DoRoutine and DoCoroutine stucks! First function calculates forces (eg gravity "f[pos].p[0].vy += 0.05f;" that don't want to work too), collisions, and normalizes particles. Second function reregistering particles in gridspace, so if it function will not work i'll see only their spawn position, also if first function willn't apply forces i'll see same. If i use floats i can see that particles are falling, colliding, but sticks together, going to the edges, made theirself as big stick forwarded up at the sides of field. Why some double operations don't work? How i permitted to use doubles with uints? Where is the bug? Code: #pragma kernel DoRoutine

 struct Part
 {
     double x,y,vx,vy;
 };
 struct Field
 {
     Part p[4];
 };
 RWStructuredBuffer<Field> f;
 [numthreads(16,16,1)]
 void DoRoutine (uint3 id : SV_DispatchThreadID)
 {
     uint pos = id.x+id.y*512;
     f[pos].p[0].vy += 0.05f;
     f[pos].p[1].vy += 0.05f;
     f[pos].p[2].vy += 0.05f;
     f[pos].p[3].vy += 0.05f;
 /*    f[pos].p[0].vy /= 1.03f;
     f[pos].p[1].vy /= 1.03f;
     f[pos].p[2].vy /= 1.03f;
     f[pos].p[3].vy /= 1.03f;
     f[pos].p[4].vy /= 1.03f;
     f[pos].p[5].vy /= 1.03f;
     f[pos].p[6].vy /= 1.03f;
     f[pos].p[7].vy /= 1.03f;
     f[pos].p[0].vx /= 1.03f;
     f[pos].p[1].vx /= 1.03f;
     f[pos].p[2].vx /= 1.03f;
     f[pos].p[3].vx /= 1.03f;
     f[pos].p[4].vx /= 1.03f;
     f[pos].p[5].vx /= 1.03f;
     f[pos].p[6].vx /= 1.03f;
     f[pos].p[7].vx /= 1.03f;*/
     for(uint i = 0; i < 4; i++)
     {
         if(f[pos].p[i].x >= 0) 
         for(uint j = 0; j < 3; j++)
         {
             for(uint k = 0; k < 3; k++)
             {
                 uint scuko = id.x+k-1+(id.y+j-1)*512;
                 for(uint l = 0; l < 4; l++)
                 {
                     //if(j != 1 && k != 1 && i != l)
                     //{
                         if(f[scuko].p[l].x >= 0)
                         {
                             double x = f[pos].p[i].x - f[scuko].p[l].x;
                             double y = f[pos].p[i].y - f[scuko].p[l].y;
                             double dist = sqrt((float)(x*x+y*y));
                             
                             //double2 midPnt = double2(f[pos].p[i].x+f[scuko].p[l].x/2,f[pos].p[i].y+f[scuko].p[l].y/2);
                             if(dist < 1.0 && dist != 0)
                             {
                                 //if(dist < 0.1) dist = 0.1;
                                 //f[pos].p[i].vx += x/dist/dist*0.2f;
                                 //f[pos].p[i].vy += y/dist/dist*0.2f;
                                 //f[scuko].p[l].vx -= x/dist/dist*0.2f;
                                 //f[scuko].p[l].vy -= y/dist/dist*0.2f;
                                 f[pos].p[i].vx *= 0.8f;
                                 f[pos].p[i].vy *= 0.8f;
                                 f[scuko].p[l].vx *= 0.8f;
                                 f[scuko].p[l].vy *= 0.8f;
                                 f[pos].p[i].x += x/2/dist;
                                 f[pos].p[i].y += y/2/dist;
                                 if(f[pos].p[i].x < 1)
                                 {
                                     f[pos].p[i].vx *= -0.8f;
                                     f[pos].p[i].x = 1;
                                 }
                                 if(f[pos].p[i].y < 1)
                                 {
                                     f[pos].p[i].vy *= -0.8f;
                                     f[pos].p[i].y = 1;
                                 }
                                 if(f[pos].p[i].x > 511)
                                 {
                                     f[pos].p[i].vx *= -0.8f;
                                     f[pos].p[i].x = 511;
                                 }
                                 if(f[pos].p[i].y > 511)
                                 {
                                     f[pos].p[i].vy *= -0.8f;
                                     f[pos].p[i].y = 511;
                                 }
                                 if((uint)(f[pos].p[i].x) != id.x || (uint)(f[pos].p[i].y) != id.y)
                                 {
                                     uint nx = (uint)(f[pos].p[i].x);
                                     uint ny = (uint)(f[pos].p[i].y);    
                                     for(uint place = 0; place < 4; place++)
                                     {
                                         if(f[nx+ny*512].p[place].x < 0)
                                         {    
                                             f[nx+ny*512].p[place] = f[pos].p[i];
                                             f[pos].p[i].x = -100.0;
                                             break;
                                         }
                                     }
                                 }
                             }
                             else if(dist == 0)
                             {
                                 //f[pos].p[i].x -= 0.5f;
                                 f[pos].p[i].y += 0.5f;
                                 //f[pos].p[i].vx *= 0.4f;
                                 //f[pos].p[i].vy *= 0.4f;
                                 if(f[pos].p[i].x < 1)
                                 {
                                     f[pos].p[i].vx *= -0.8f;
                                     f[pos].p[i].x = 1;
                                 }
                                 if(f[pos].p[i].y < 1)
                                 {
                                     f[pos].p[i].vy *= -0.8f;
                                     f[pos].p[i].y = 1;
                                 }
                                 if(f[pos].p[i].x > 511)
                                 {
                                     f[pos].p[i].vx *= -0.8f;
                                     f[pos].p[i].x = 511;
                                 }
                                 if(f[pos].p[i].y > 511)
                                 {
                                     f[pos].p[i].vy *= -0.8f;
                                     f[pos].p[i].y = 511;
                                 }
                                 if((uint)(f[pos].p[i].x) != id.x || (uint)(f[pos].p[i].y) != id.y)
                                 {
                                     uint nx = (uint)(f[pos].p[i].x);
                                     uint ny = (uint)(f[pos].p[i].y);    
                                     for(uint place = 0; place < 4; place++)
                                     {
                                         if(f[nx+ny*512].p[place].x < 0)
                                         {    
                                             f[nx+ny*512].p[place] = f[pos].p[i];
                                             f[pos].p[i].x = -100.0f;
                                             break;
                                         }
                                     }
                                 }
                             }
                         }
                     //}
                 }
             }
         }
     }
     for(uint m = 0; m < 4; m++)
     {
         if(f[pos].p[m].x >= 0)
         {
             f[pos].p[m].x += f[pos].p[m].vx;
             f[pos].p[m].y += f[pos].p[m].vy;
             if(f[pos].p[m].x < 1)
             {
                 f[pos].p[m].vx *= -0.8f;
                 f[pos].p[m].x = 1;
             }
             if(f[pos].p[m].y < 1)
             {
                 f[pos].p[m].vy *= -0.8f;
                 f[pos].p[m].y = 1;
             }
             if(f[pos].p[m].x > 511)
             {
                 f[pos].p[m].vx *= -0.8f;
                 f[pos].p[m].x = 511;
             }
             if(f[pos].p[m].y > 511)
             {
                 f[pos].p[m].vy *= -0.8f;
                 f[pos].p[m].y = 511;
             }
         }
     }
 }
 
 #pragma kernel DoCoroutine
 
 [numthreads(1,1,1)]
 void DoCoroutine(uint3 id : SV_DispatchThreadID)
 {
     uint pos = id.x+id.y*512;
     for(uint m = 0; m < 4; m++)
     {
         if(f[pos].p[m].x >= 0) 
         {
             if((uint)(f[pos].p[m].x) != id.x || (uint)(f[pos].p[m].y) != id.y)
             {
                 uint nx = (uint)(f[pos].p[m].x);
                 uint ny = (uint)(f[pos].p[m].y);    
                 for(uint place = 0; place < 4; place++)
                 {
                     if(f[nx+ny*512].p[place].x < 0)
                     {    
                         f[nx+ny*512].p[place] = f[pos].p[m];
                         f[pos].p[m].x = -100.0;
                         break;
                     }
                 }
             }
         }
     }
 }
 
 #pragma kernel Render
 
 RWTexture2D<float4> Screen;
 
 [numthreads(16,16,1)]
 void Render (uint3 id : SV_DispatchThreadID)
 {
     uint pos = id.x + id.y*512;
     bool empty = false;
     /*for(int i = 0; i < 4; i++) 
     {
         if(f[pos].p[i].x < 0)
         {
             empty = true;
             
         }
         if(f[pos].p[i].x >= 0) Screen[id.xy] = float4(0,0,1,1);
     }*/
     uint i = 0;
     float4 over = float4(.05,.05,.05,1);
     if(f[pos].p[0].x >= 0) over += float4(.25,.25,.25,0);
     else
     { 
         /*if(f[pos].p[0].x == -100.0)
         { 
             over += double4(0,1,0,0);
             f[pos].p[0].x = -1.0;
         }*/
         empty = true;
     }
     if(f[pos].p[1].x >= 0) over += float4(.25,.25,.25,0);
     else
     { 
         /*if(f[pos].p[1].x == -100.0)
         { 
             over += double4(0,1,0,0);
             f[pos].p[1].x = -1.0;
         }*/
         empty = true;
     }
     if(f[pos].p[2].x >= 0) over += float4(.25,.25,.25,0);
     else
     { 
         /*if(f[pos].p[2].x == -100.0)
         { 
             over += double4(0,1,0,0);
             f[pos].p[2].x = -1.0;
         }*/
         empty = true;
     }
     if(f[pos].p[3].x >= 0) over += float4(.25,.25,.25,0);
     else
     { 
         /*if(f[pos].p[3].x == -100.0)
         { 
             over += double4(0,1,0,0);
             f[pos].p[3].x = -1.0;
         }*/
         empty = true;
     }
     Screen[id.xy] = over;
     if(!empty) Screen[id.xy] = float4(1,0,0,1);
 }
 
 #pragma kernel Putis
 int putisi, putisj;
 float pfx, pfy; 
 [numthreads(1,1,1)]
 void Putis(uint3 id : SV_DispatchThreadID)
 {
     f[putisi + putisj*512].p[0].x = pfx +0.5;
 
     f[putisi + putisj*512].p[0].y = pfy +0.5;
 
     f[putisi + putisj*512].p[0].vx = 0;
 
     f[putisi + putisj*512].p[0].vy = 0;
 }
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

0 Replies

· Add your reply
  • Sort: 

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

20 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

Related Questions

Calling Graphics.DrawProcedural multiple times for chunked procedural terrain 2 Answers

Compute Shader crashes when buffer is too big 0 Answers

Convert float in Transform to double 1 Answer

Exclude renderer from compute shader compilation 0 Answers

3D Cellular Automata on the GPU 1 Answer


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