Waterflow
Visualize water in terrain
|
00001 00002 00003 00004 00005 #version 430 00006 00007 layout(local_size_x = 16, local_size_y = 16) in; 00008 00009 layout (std430,binding = 4) readonly buffer height0 00010 { 00011 float water0[]; 00012 00013 }; 00014 00015 layout (std430, binding = 5) readonly buffer height1 00016 { 00017 float water1[]; 00018 }; 00019 00020 //Since in previous step, (advectVelocity) we used this as inbuffer and vxout as out. Now we are interested in the new data and want to save it to a out buffer. vin cotains nothing of value anymore. use it as out data. DO NOT SWAP IN CPP. 00021 00022 layout (std430,binding = 6) writeonly buffer velocityX 00023 { 00024 float vxin[]; 00025 00026 }; 00027 00028 layout (std430,binding = 7) readonly buffer velocityXout 00029 { 00030 float vxout[]; 00031 00032 }; 00033 00034 00035 layout (std430,binding = 8) writeonly buffer velocityY 00036 { 00037 float vyin[]; 00038 00039 }; 00040 00041 00042 layout (std430,binding = 9) readonly buffer velocityYout 00043 { 00044 float vyout[]; 00045 00046 }; 00047 00048 layout (std430,binding = 10) readonly buffer Terrain 00049 { 00050 float terr[]; 00051 00052 }; 00053 00054 00055 uniform ivec2 size; 00056 uniform float dt; 00057 00058 void main(){ 00059 00060 float GRAVITY = -9.81f; 00061 float C = dt*GRAVITY; 00062 ivec2 storePos = ivec2(gl_GlobalInvocationID.xy); 00063 int i = storePos.x; 00064 int j = storePos.y; 00065 int offset = (i + j*size.x); 00066 00067 00068 int ipos= clamp(i+1,0,size.x-1); 00069 int jpos = clamp(j+1,0,size.y-1); 00070 int imin = clamp(i-1,0,size.x-1); 00071 int jmin = clamp(j-1,0,size.y-1); 00072 00073 //Coordinate system HERE! < is to the right and up. 00074 00075 int offsetright = ipos+j*size.x; 00076 int offsetleft = imin+j*size.x; 00077 int offsetup = i+jpos*size.x; 00078 int offsetdown = i+jmin*size.x; 00079 int offsettopright = ipos+jpos*size.x; 00080 int sampX,sampY; 00081 00082 00083 float ourWater = water0[offset]; 00084 float ourTot = ourWater+terr[offset]; 00085 00086 if(i > 1 && i < size.x-1 && j < size.y-1) { 00087 float neighWater = water0[offsetleft]; 00088 float neighTot = neighWater + terr[offsetleft]; 00089 /* 00090 float change = clamp(ourTot - neighTot,-ourWater/2.0f,neighWater/.0f); 00091 00092 */ 00093 00094 float change = ourTot-neighTot; 00095 //vxin[offset] = clamp((vxout[offset] + C*change),-10.0f,10.0f); 00096 vxin[offset] = vxout[offset] + C*change; 00097 00098 } 00099 if(j > 1 && i < size.x-1 && j < size.y-1) { 00100 00101 float neighWater = water0[offsetdown]; 00102 float neighTot = neighWater +terr[offsetdown]; 00103 /* So this ensures that the velocities do not exceed too large values and tries to compensate for topology 00104 float change = clamp(ourTot-neighTot,-ourWater,neighWater); 00105 00106 */ 00107 00108 float change = ourTot-neighTot; 00109 //vyin[offset] = clamp((vyout[offset] + C*change),-10.0f,10.0f); 00110 vyin[offset] = vyout[offset] + C*change; 00111 } 00112 00113 if(i == 0 || i ==size.x -1){ 00114 vyin[offset] = 0.0f; 00115 } 00116 if(j == 0 || j ==size.y -1){ 00117 vxin[offset] = 0.0f; 00118 } 00119 00120 00121 00122 }