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) writeonly buffer height1 00016 { 00017 float water1[]; 00018 }; 00019 00020 layout (std430,binding = 6) readonly buffer velocityX 00021 { 00022 float vxin[]; 00023 00024 }; 00025 00026 layout (std430,binding = 7) readonly buffer velocityXout 00027 { 00028 float vxout[]; 00029 00030 }; 00031 00032 00033 layout (std430,binding = 8) readonly buffer velocityY 00034 { 00035 float vyin[]; 00036 00037 }; 00038 00039 00040 layout (std430,binding = 9) readonly buffer velocityYout 00041 { 00042 float vyout[]; 00043 00044 }; 00045 00046 layout (std430,binding = 10) readonly buffer Terrain 00047 { 00048 float terr[]; 00049 00050 }; 00051 00052 00053 uniform ivec2 size; 00054 uniform float dt; 00055 00056 00057 00058 float average(int i, int j){ 00059 i = clamp(i,0,size.x-1); 00060 j = clamp(j,0,size.y-1); 00061 int ipos = clamp(i+1,0,size.x-1); 00062 int jpos = clamp(j+1,0,size.y-1); 00063 int imin = clamp(i-1,0,size.x-1); 00064 int jmin = clamp(j-1,0,size.y-1); 00065 00066 int offset = i+ j*size.x; 00067 int offsete = ipos+j*size.x; 00068 int offsetw = imin+j*size.x; 00069 int offsetn = i+jpos*size.x; 00070 int offsets = i+jmin*size.x; 00071 00072 return 0.2f*(water0[offset] +water0[offsete] +water0[offsetw] +water0[offsetn] +water0[offsets]); 00073 00074 } 00078 float bilinjearInterpolation(float point_x, float point_y) 00079 { 00080 //picking out the nearby points 00081 int x = int(point_x); 00082 int y = int(point_y); 00083 00084 //picking out the distances to the point from nearby points 00085 float s1 = point_x - float(x); 00086 float s0 = 1.0f - s1; 00087 00088 float t1 = point_y - float(y); 00089 float t0 = 1.0f - t1; 00090 00091 int ypos = clamp(y+1,0,size.y-1); 00092 int xpos = clamp(x+1,0,size.x-1); 00093 00094 int offset0 = x +y*size.x; 00095 int offset1 = x +(ypos)*size.x; 00096 int offset2 = xpos +y*size.x; 00097 int offset3 = xpos +(ypos)*size.x; 00098 float totalWater0 = water0[offset0];// + terr[offset0]; 00099 float totalWater1 = water0[offset1];// + terr[offset1]; 00100 float totalWater2 = water0[offset2];// + terr[offset2]; 00101 float totalWater3 = water0[offset3];// + terr[offset3]; 00102 00103 00104 return s0*(t0*totalWater0 + t1*totalWater1) + 00105 s1*(t0*totalWater2 + t1*totalWater3); 00106 00107 } 00108 00109 00110 void main(){ 00111 //determine where to sample 00112 ivec2 storePos = ivec2(gl_GlobalInvocationID.xy); 00113 int i = storePos.x; 00114 int j = storePos.y; 00115 int offset = (i + j*size.x); 00116 00117 //Change these to clamps. 00118 if(i < size.x && j < size.y ) { 00119 int ipos = clamp(i+1,0,size.x-1); 00120 int jpos = clamp(j+1,0,size.y-1); 00121 int imin = clamp(i-1,0,size.x-1); 00122 int jmin = clamp(j-1,0,size.y-1); 00123 00124 float u = 0.0f; // Temporary velocity in x 00125 float v = 0.0f; // Temporary velocity in y 00126 00127 //Coordinate system HERE! < is to the right and up. 00128 00129 int offsetright = ipos+j*size.x; 00130 int offsetleft = imin+j*size.x; 00131 int offsetup = i+jpos*size.x; 00132 int offsetdown = i+jmin*size.x; 00133 int offsettopright = ipos+jpos*size.x; 00134 int sampX,sampY; 00135 00136 u = (vxin[offsetleft]+ vxin[offset] +vxin[offsetright])*0.33f; 00137 v = (vyin[offsetdown] + vyin[offset] +vyin[offsetup])*0.33f; 00138 00139 float source_point_x = clamp(float(i)-u*dt,0.0f,float(size.x)-1.0f);// clamp(float(i)-u*dt, float(i)-1.0f,float(i)+1.0f); // 00140 float source_point_y =clamp(float(j)-v*dt,0.0f,float(size.y)-1.0f); // clamp(float(j)-v*dt, float(j)-1.0f,float(j)+1.0f); // 00141 00142 water1[offset] =bilinjearInterpolation(source_point_x, source_point_y); 00143 //water1[offset] =average(int(source_point_x), int(source_point_y)); 00144 } 00145 }