xxxxxxxxxx
113
precision mediump float;
varying vec2 vTexCoord;
uniform sampler2D tex;
uniform vec2 normalRes;
vec4 empty = vec4(0.0, 0.0, 0.0, 1.0);
vec4 wallCol = vec4(0.0, 1.0, 0.0, 1.0);
vec4 sandCol = vec4(1.0, 1.0, 0.0, 1.0);
vec4 getCell(float dx, float dy) {
float x = vTexCoord.x + dx * normalRes.x;
float y = (1.0 - vTexCoord.y) + dy * normalRes.y;
return texture2D(tex, vec2(x, y));
}
bool equalFloat(float a, float b){
return abs(a-b) < 0.01;
}
bool eqCol(vec4 color1, vec4 color2){
return equalFloat(color1.x,color2.x) && equalFloat(color1.y,color2.y) && equalFloat(color1.z,color2.z);
}
bool neqCol(vec4 color1, vec4 color2){
return !eqCol(color1,color2);
}
vec4 getCol() {
vec4 c = getCell(0.0, 0.0);
vec4 u = getCell(0.0, -1.0);
vec4 d = getCell(0.0, 1.0);
vec4 ul = getCell(-1.0, -1.0);
vec4 ur = getCell(1.0, -1.0);
vec4 l = getCell(-1.0, 0.0);
vec4 r = getCell(1.0, 0.0);
vec4 dl = getCell(-1.0, 1.0);
vec4 dr = getCell(1.0, 1.0);
// Wall rule
if(eqCol(c, wallCol)) return wallCol;
// Prevent cloning underneath
if(
vTexCoord.y > 1.0-normalRes.y ||
eqCol(u, wallCol)
) {
return empty;
}
// Sand fall rule
if(
eqCol(c, empty) &&
eqCol(u, sandCol)
) return sandCol;
if(
eqCol(c, sandCol) &&
eqCol(u, empty)
) return empty;
// Sand spread rule
if(
eqCol(c, sandCol) &&
(
eqCol(u, sandCol) ||
eqCol(u, wallCol)
)
) {
if(
eqCol(r, empty) &&
eqCol(ur, empty)
) return empty;
if(
eqCol(l, empty) &&
eqCol(ul, empty)
) return empty;
return c;
}
if(
eqCol(c, empty) &&
eqCol(d, empty) &&
eqCol(dl, sandCol) &&
(
eqCol(l, wallCol) ||
eqCol(l, sandCol)
)
) return sandCol;
if(
eqCol(c, empty) &&
eqCol(d, empty) &&
eqCol(dr, sandCol) &&
(
eqCol(r, wallCol) ||
eqCol(r, sandCol)
)
) return sandCol;
return c;
}
void main() {
gl_FragColor = getCol();
}