Skip to content

Instantly share code, notes, and snippets.

@muripoLife
Last active December 19, 2019 05:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muripoLife/8efbb3f9412ed97397234e5dba5eb569 to your computer and use it in GitHub Desktop.
Save muripoLife/8efbb3f9412ed97397234e5dba5eb569 to your computer and use it in GitHub Desktop.
GLSLレイマーチング研究_距離関数について勉強してみた24(smooth minimum functionでメタボールを作ってみた。) ref: http://qiita.com/muripo_life/items/3983b26bac039b9f803e
// 球
float dSphere(vec3 p, float r){
// ここに図形の距離関数を書く
return sqrt(p.x*p.x+p.y*p.y+p.z*p.z) - r;
}
// 球を4つ重ねる
float instanceSpherer(vec3 p){
p = mat3(cos(time),-sin(time),0, sin(time),cos(time),0 ,0,0,1)*p;
p = mat3(1,0,0, 0,cos(time),-sin(time), 0,sin(time),cos(time))*p;
vec3 p1 = vec3(p.x+1.0*sin(time), p.y, p.z);
vec3 p2 = vec3(p.x-1.0*sin(time), p.y, p.z);
vec3 p3 = vec3(p.x+2.0*sin(time), p.y, p.z);
vec3 p4 = vec3(p.x-2.0*sin(time), p.y, p.z);
float spherer01 = dSphere(p1, 1.3+0.3*sin(time));
float spherer02 = dSphere(p2, 1.3+0.3*cos(time));
float spherer03 = dSphere(p3, 1.3+0.3*cos(time));
float spherer04 = dSphere(p4, 1.3+0.3*cos(time));
return min(min(min(spherer01, spherer02), spherer03), spherer04);
}
vec3 doColor(vec3 p){
float e = 0.001;
if (instanceSpherer(p)<e){
vec3 normal = genNormal(p);
vec3 light = normalize(vec3(1.0, 1.0, 1.0));
float diff = max(dot(normal, light), 0.1);
float spec = pow(diff*diff, 15.0);
return vec3(diff*0.3+spec, diff+spec, diff+spec);
}
return vec3(0.0);
}
float smin( float a, float b, float k )
{
float res = exp( -k*a ) + exp( -k*b );
return -log( res )/k;
}
\begin{align}
y &= x \\
y &= -(-x) \\
y &= - \log(\exp(-x)) \\
\end{align}
{\hat {f}}(\xi ):=\int _{{-\infty }}^{{\infty }}f(x)\ e^{{-2\pi ix\xi }}\,dx
\exp(x) = 1 + \frac{1}{1!} \cdot x^1 + \frac{1}{2!} \cdot x^2 + \cdots + \frac{1}{n!} \cdot x^n + \cdots + \cdots
// ============================================================================
// メタボールの距離関数
// ============================================================================
precision mediump float;
uniform vec2 resolution;
uniform vec2 mouse;
uniform float time;
uniform sampler2D prevScene;
float dSphere(vec3 p, float r){
return sqrt(p.x*p.x+p.y*p.y+p.z*p.z) - r;
}
// 接合部分を滑らかにする
float smin( float a, float b, float k )
{
float res = exp( -k*a ) +exp( -k*b );
return -log( res )/k;
}
float instanceSpherer(vec3 p){
p = mat3(cos(time),-sin(time),0, sin(time),cos(time),0 ,0,0,1)*p;
p = mat3(1,0,0, 0,cos(time),-sin(time), 0,sin(time),cos(time))*p;
vec3 p1 = vec3(p.x+1.0*sin(time), p.y, p.z);
vec3 p2 = vec3(p.x-1.0*sin(time), p.y, p.z);
vec3 p3 = vec3(p.x+2.0*sin(time), p.y, p.z);
vec3 p4 = vec3(p.x-2.0*sin(time), p.y, p.z);
float spherer01 = dSphere(p1, 1.3+0.3*sin(time));
float spherer02 = dSphere(p2, 1.3+0.3*cos(time));
float spherer03 = dSphere(p3, 1.3+0.3*cos(time));
float spherer04 = dSphere(p4, 1.3+0.3*cos(time));
// return smin(spherer01, spherer02, 32.0);
// return min(min(min(spherer01, spherer02), spherer03), spherer04);
return smin(smin(smin(spherer01, spherer02, 32.0), spherer03, 32.0), spherer03, 32.0);
}
float distanceHub(vec3 p){
return instanceSpherer(p);
}
vec3 genNormal(vec3 p){
float d = 0.001;
return normalize(vec3(
distanceHub(p + vec3( d, 0.0, 0.0)) - distanceHub(p + vec3( -d, 0.0, 0.0)),
distanceHub(p + vec3(0.0, d, 0.0)) - distanceHub(p + vec3(0.0, -d, 0.0)),
distanceHub(p + vec3(0.0, 0.0, d)) - distanceHub(p + vec3(0.0, 0.0, -d))
));
}
vec3 doColor(vec3 p){
float e = 0.001;
if (instanceSpherer(p)<e){
vec3 normal = genNormal(p);
vec3 light = normalize(vec3(1.0, 1.0, 1.0));
float diff = max(dot(normal, light), 0.1);
float spec = pow(diff*diff, 15.0);
return vec3(diff*0.3+spec, diff+spec, diff+spec);
}
return vec3(0.0);
}
void main(){
vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);
vec3 cPos = vec3(0.0, 0.0, 3.0);
vec3 cDir = vec3(0.0, 0.0, -1.0);
vec3 cUp = vec3(0.0, 1.0, 0.0);
vec3 cSide = cross(cDir, cUp);
float targetDepth = 1.0;
vec3 ray = normalize(cSide * p.x + cUp * p.y + cDir * targetDepth);
float dist = 0.0;
float rLen = 0.0;
vec3 rPos = cPos;
for(int i = 0; i < 32; ++i){
dist = distanceHub(rPos);
rLen += dist;
rPos = cPos + ray * rLen;
}
vec3 color = doColor(rPos);
gl_FragColor = vec4(color, 1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment