Skip to content

Instantly share code, notes, and snippets.

@Gitmoko
Created December 16, 2017 09:10
Show Gist options
  • Save Gitmoko/7f20ca810b529f58c087d6f1071e4c2e to your computer and use it in GitHub Desktop.
Save Gitmoko/7f20ca810b529f58c087d6f1071e4c2e to your computer and use it in GitHub Desktop.
#ifdef GL_ES
precision mediump float;
#endif
#extension GL_OES_standard_derivatives : enable
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
//反復回数(constで書く方も多い)
#define ITE_MAX 190
#define DIST_COEFF .36
//打ち切り係数
#define DIST_MIN 0.01
//t最大
#define DIST_MAX 10000.0
#define inf 100000
#define PI 3.14159276
#define UnitWindow_Size 50.0
float hash(float n) { return fract(sin(n) * 1e4); }
float noise(vec3 x) {
const vec3 step = vec3(110, 241, 171);
vec3 i = floor(x);
vec3 f = fract(x);
// For performance, compute the base input to a 1D hash from the integer part of the argument and the
// incremental change to the 1D based on the 3D -> 1D wrapping
float n = dot(i, step);
vec3 u = f * f * (3.0 - 2.0 * f);
return mix(mix(mix( hash(n + dot(step, vec3(0, 0, 0))), hash(n + dot(step, vec3(1, 0, 0))), u.x),
mix( hash(n + dot(step, vec3(0, 1, 0))), hash(n + dot(step, vec3(1, 1, 0))), u.x), u.y),
mix(mix( hash(n + dot(step, vec3(0, 0, 1))), hash(n + dot(step, vec3(1, 0, 1))), u.x),
mix( hash(n + dot(step, vec3(0, 1, 1))), hash(n + dot(step, vec3(1, 1, 1))), u.x), u.y), u.z);
}
float sphIntersect( vec3 ro, vec3 rd, vec4 sph )
{
vec3 oc = ro - sph.xyz;
float b = dot( oc, rd );
float c = dot( oc, oc ) - sph.w*sph.w;
float h = b*b - c;
if( h<0.0 ) return -1.0;
h = sqrt( h );
return -b - h;
}
mat3 rotM(vec3 axis,float angle){
axis = normalize(axis);
float s = sin(angle);
float c = cos(angle);
float oc = 1.0 - c;
return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c);}
vec3 GenRay(vec3 dir,vec3 up,float angle){
vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);
p.x += p.x + (2.*noise(vec3(p*10.,time*10.))-1.)*.5/pow(20.*(mod(time,1.))+1.,2.);
vec3 u = normalize(cross(up, dir));
vec3 v = normalize(cross(dir, u));
float fov = angle * PI * 0.5 / 180.;
return normalize(sin(fov) * u * p.x + sin(fov) * v * p.y + cos(fov) * dir);}
float sdBox( vec3 p, vec3 b )
{
vec3 d = abs(p) - b;
return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}
float map(vec3 p){
float d = 0.;
//p = mod(p,12.) - vec3(6);//d = length(max(abs(p)-vec3(1.,2.,1.),0.0));
d = max(p.z + 2.,-sdBox(p-vec3(0.,0.,-2.),vec3(1.,1.,1.)));
d =min(d,length(p-vec3(0.,0.,-2.))-.2);//d = hivemap(p);
return d;
}
vec3 getnormal(vec3 p){
float d = 0.01;
return normalize(vec3(
map(p + vec3(d, 0.0, 0.0)) - map(p + vec3(-d, 0.0, 0.0)),
map(p + vec3(0.0, d, 0.0)) - map(p + vec3(0.0, -d, 0.0)),
map(p + vec3(0.0, 0.0, d)) - map(p + vec3(0.0, 0.0, -d))
));
}
void main( void) {
vec3 l = normalize(vec3(.0, -.99, .99));
//eye座標
vec3 pos = vec3(0.+.7*cos(time*0.2),0.+1.7*sin(time*0.2),-1.);
vec3 target = vec3(0.,0., -2.);
vec3 center_dir = (target - pos);
vec3 dir;
vec3 up = vec3(.0, 0., 1.);
dir = GenRay(normalize(center_dir), up, 120.);
if(sphIntersect(pos,normalize(dir),vec4(0.,0.,-1.5,.2)) > 0.){
//return;
}
float t = 0.0;
float dist = 0.;
//SphereTracing。ここintersectって名前で別に作る人も多いです
for(int i = 0 ; i < ITE_MAX; i++) {
//形状表現した陰関数を反復しながら解く
//0(DIST_MIN)に近くなったら解に近いので打ち切り
dist = map((t * dir + pos));
if(dist < DIST_MIN) {
break;
}
//tを更新。DIST_COEFFは複雑な形状を描画する際に小さく為につけています。
//ちょっとずつレイを進める事ができます。
t += dist * DIST_COEFF;
if(t > DIST_MAX){
break;
}
}
//option形状の近くの位置を出しておく
vec3 ip = pos + dir * t;
//色を作ります。ここでは進めたtの位置(深度)をただ出力するだけ
vec3 point = vec3(0.,0.,-1.5+sin(time));
vec3 color = vec3(0.);
vec3 n = getnormal(ip);
if(dist < DIST_MIN){
float diff = dot(normalize(point-ip),n);
color = 1.9*normalize(vec3(0.2,0.2,0.2)) * clamp(pow(diff,9.),0.1,1.);
if(sphIntersect(ip,normalize(-dir),vec4(point.xyz,.05)) > 0.){
color += vec3(1.,1.,1.);
}
color += vec3(.5) * clamp(dot(n,normalize(dir+l)),0.,1.);
//color += ip.z*vec3(2.0,1.,0.);
}else if(sphIntersect(pos,normalize(dir),vec4(point.xyz,.05)) > 0.){
color += vec3(1.,1.,1.);
}
color += clamp((1.-20./t),0.,1.)*vec3(.2,.2,.2);
vec2 r = gl_FragCoord.xy/resolution.xy;
vec3 no;
no.x = noise(vec3(r.x,r.y+time*100.,0.0));
no.y = noise(vec3(r.x,r.y+time*200.,0.1));
no.z = noise(vec3(r.x,r.y+time*300.,0.2));
no *= 0.6;
color = mix(color,no,1./(40.*(mod(time,1.))+1.));
gl_FragColor = vec4(color, 1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment