Skip to content

Instantly share code, notes, and snippets.

@Pentan
Last active July 11, 2017 08:30
Show Gist options
  • Save Pentan/d3fd67228aadeedaf3b7a6faa85399cc to your computer and use it in GitHub Desktop.
Save Pentan/d3fd67228aadeedaf3b7a6faa85399cc to your computer and use it in GitHub Desktop.
#define PI05 1.570796326795
#define PI 3.1415926535898
#define kNumVertX 15.0
#define kNumVertY 15.0
//#define kNumVertZ
#define kScale 0.2
#define kTranslate vec3(-1.5)
vec3 hash3(vec3 v) {
return fract(sin(v) * vec3(43758.5453123, 12345.6789012,76543.2109876));
}
vec3 rotX(vec3 p, float rad) {
vec2 sc = sin(vec2(rad, rad + PI05));
vec3 rp = p;
rp.y = p.y * sc.y + p.z * -sc.x;
rp.z = p.y * sc.x + p.z * sc.y;
return rp;
}
vec3 rotY(vec3 p, float rad) {
vec2 sc = sin(vec2(rad, rad + PI05));
vec3 rp = p;
rp.x = p.x * sc.y + p.z * sc.x;
rp.z = p.x * -sc.x + p.z * sc.y;
return rp;
}
vec3 rotZ(vec3 p, float rad) {
vec2 sc = sin(vec2(rad, rad + PI05));
vec3 rp = p;
rp.x = p.x * sc.x + p.y * sc.y;
rp.y = p.x * -sc.y + p.y * sc.x;
return rp;
}
vec4 perspective(vec3 p, float fov, float near, float far) {
vec4 pp = vec4(p, -p.z);
pp.xy *= vec2(resolution.y / resolution.x, 1.0) / tan(radians(fov * 0.5));
pp.z = (-p.z * (far + near) - 2.0 * far * near) / (far - near);
return pp;
}
mat4 lookat(vec3 eye, vec3 look, vec3 up) {
vec3 z = normalize(eye - look);
vec3 x = normalize(cross(up, z));
vec3 y = cross(z, x);
return mat4(x.x, y.x, z.x, 0.0, x.y, y.y, z.y, 0.0, x.z, y.z, z.z, 0.0, 0.0, 0.0, 0.0, 1.0) *
mat4(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -eye.x, -eye.y, -eye.z, 1.0);
}
vec3 voxelPosToWorld(vec3 vxlp) {
return vxlp * kScale + kTranslate;
}
float blobSphere(vec3 p, float r) {
return 1.0 / (1.0 + pow(length(p / r), 2.0));
}
float scene(vec3 p) {
const float kThreshould = 0.5;
float d = 0.0;
d += blobSphere(p + sin(time * vec3(1.5, 2.1, 0.5)) * vec3(0.5, 0.6, 0.3), 0.4);
d += blobSphere(p + sin(time * vec3(2.3, 1.2, 1.7)) * vec3(0.6, 0.5, 0.8), 0.2);
d += blobSphere(p + sin(time * vec3(0.3, 1.2, 2.7)) * vec3(0.5, 0.4, 0.5), 0.3);
//d += 1.0 / (1.0 + pow(length(p * 2.0), 2.0));
return kThreshould - d;
}
vec3 sceneNormal(vec3 p) {
vec3 EPS = vec3(0.01, 0.0, 0.0);
vec3 n;
n.x = scene(p + EPS.xyz) - scene(p - EPS.xyz);
n.y = scene(p + EPS.zxy) - scene(p - EPS.zxy);
n.z = scene(p + EPS.yzx) - scene(p - EPS.yzx);
return normalize(n);
}
vec3 smoothVertex(vec3 ip) {
vec3 p = ip;
vec3 n = sceneNormal(p);
for(int i = 0; i < 8; i++) {
float d = scene(p);
p -= n * d;
if(abs(d) < 0.01) { break; }
}
return p;
}
vec4 shading(vec3 p, vec3 n) {
vec3 kDc = vec3(0.6, 0.05, 0.15);
vec3 kSp = vec3(1.0, 1.0, 1.0) * 0.2;
vec3 kFc = vec3(0.3,0.1,0.15);
vec3 L = normalize(vec3(1.0, 1.0, 1.0));
float d = dot(L, n);
float s = 0.0;
if(d > 0.0) {
vec3 h = (normalize(-p) + L) * 0.5;
s = pow(max(0.0, dot(h, n)), 4.0);
}
float kR0 = 0.02;
float F = kR0 + (1.0 - kR0) * pow(1.0 - max(0.0, dot(normalize(-p), n)), 5.0);
return vec4((max(0.0, d) * 0.6 + 0.2) * kDc + s * kSp + F * kFc, 1.0);
}
void main() {
// vertex index in quad face (2 triangles: 0-5)
float faceVertId = mod(vertexId, 6.0);
// face index
float faceId = floor(vertexId / 6.0);
// fece index in corner
float cornerFaceId = mod(faceId, 3.0);
// edge index in corner
float cornerEdgeId = mod(faceId, 3.0);
// corner index (1 corner = 3 faces = 3 * 6 verts)
float cornerId = floor(vertexId / 18.0);
// corner position
vec3 cornerPos;
cornerPos.x = mod(cornerId, kNumVertX);
cornerPos.y = mod(floor(cornerId / kNumVertX), kNumVertY);
cornerPos.z = mod(floor(cornerId / (kNumVertX * kNumVertY)), kNumVertY);
vec3 faceNormal;
vec3 faceTangent;
vec3 faceCotangent;
vec3 faceColor;
if(cornerEdgeId == 0.0) {
faceNormal = vec3(1.0, 0.0, 0.0);
faceTangent = vec3(0.0, 0.0, -1.0);
faceCotangent = vec3(0.0, 1.0, 0.0);
} else if(cornerEdgeId == 1.0) {
faceNormal = vec3(0.0, 1.0, 0.0);
faceTangent = vec3(1.0, 0.0, 0.0);
faceCotangent = vec3(0.0, 0.0, -1.0);
} else {
faceNormal = vec3(0.0, 0.0, 1.0);
faceTangent = vec3(1.0, 0.0, 0.0);
faceCotangent = vec3(0.0, 1.0, 0.0);
}
vec3 anotherPos = cornerPos + faceNormal;
// sampling points
vec3 p0 = voxelPosToWorld(cornerPos);
vec3 p1 = voxelPosToWorld(anotherPos);
// field value
float d0 = scene(p0);
float d1 = scene(p1);
vec3 p;
vec3 vertNorm;
if(d0 * d1 > 0.0) {
// no face
p = p0;
vertNorm = vec3(1.0, 1.0, 1.0);
} else {
// have a face
if(d1 < d0) {
// 0->1 is standard normal.
// otherwise flip triangle
if(faceVertId == 0.0) {
faceVertId = 2.0;
} else if(faceVertId == 2.0) {
faceVertId = 0.0;
} else if(faceVertId == 3.0) {
faceVertId = 5.0;
} else if(faceVertId == 5.0) {
faceVertId = 3.0;
}
faceNormal *= -1.0;
}
/*
face
2 4-5
|\ \|
0-1 3
*/
float kFaceSize = mix(0.45, 0.5, clamp(cos(time * 1.5) * 4.0 + 0.5, 0.0, 1.0));
vec3 edgeMidPos = (cornerPos + anotherPos) * 0.5;
vec3 faceVertPos;
if(faceVertId == 0.0) {
faceVertPos = edgeMidPos + faceTangent * -kFaceSize + faceCotangent * -kFaceSize;
} else if(faceVertId == 1.0) {
faceVertPos = edgeMidPos + faceTangent * kFaceSize + faceCotangent * -kFaceSize;
} else if(faceVertId == 2.0) {
faceVertPos = edgeMidPos + faceTangent * -kFaceSize + faceCotangent * kFaceSize;
} else if(faceVertId == 3.0) {
faceVertPos = edgeMidPos + faceTangent * kFaceSize + faceCotangent * -kFaceSize;
} else if(faceVertId == 4.0) {
faceVertPos = edgeMidPos + faceTangent * -kFaceSize + faceCotangent * kFaceSize;
} else if(faceVertId == 5.0) {
faceVertPos = edgeMidPos + faceTangent * 0.5 + faceCotangent * 0.5;
}
p = voxelPosToWorld(faceVertPos);
// smoothing
vec3 sp = smoothVertex(p);
vertNorm = sceneNormal(p);
float vmix = clamp(sin(time * 0.35) * 2.0 + 0.5, 0.0, 1.0);
p = mix(p, sp, vmix);
vertNorm = mix(faceNormal, vertNorm, vmix);
}
vec3 eye = rotX(rotY(vec3(0.0, 0.0, 3.5), -mouse.x * 2.0), mouse.y);
//vec3 eye = vec3(0.0, 0.0, 3.0);
mat4 viewMat = lookat(eye, vec3(0.0), vec3(0.0, 1.0, 0.0));
vec3 viewPos = (viewMat * vec4(p, 1.0)).xyz;
vec3 viewNorm = normalize((viewMat * vec4(vertNorm, 0.0)).xyz);
gl_Position = perspective(viewPos, 60.0, 0.1, 10.0);
gl_PointSize = 2.0;
//v_color = vec4(abs(faceNormal), 1.0);
//v_color = vec4(vertNorm * 0.5 + 0.5, 1.0);
//v_color = vec4(viewNorm * 0.5 + 0.5, 1.0);
v_color = shading(viewPos, viewNorm);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment