Minecraft
Minecraft
#ifdef GL_ES
precision mediump float;
#define GLSLIFY 1
#endif
uniform vec2 u_resolution;
uniform float u_time;
uniform vec2 u_mouse;
#define GLSLIFY 1
vec2 hash2( vec2 x ) //亂數範圍 [-1,1]
{
const vec2 k = vec2( 0.3183099, 0.3678794 );
x = x*k + k.yx;
return -1.0 + 2.0*fract( 16.0 * k*fract( x.x*x.y*(x.x+x.y)) );
}
float gnoise( in vec2 p ) //亂數範圍 [-1,1]
{
vec2 i = floor( p );
vec2 f = fract( p );
vec2 u = f*f*(3.0-2.0*f);
return mix( mix( dot( hash2( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
dot( hash2( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
mix( dot( hash2( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
dot( hash2( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
}
float fbm(in vec2 uv) //亂數範圍 [-1,1]
{
float f; //fbm - fractal noise (4 octaves)
mat2 m = mat2( 1.6, 1.2, -1.2, 1.6 );
f = 0.5000*gnoise( uv );
uv = m*uv;
f += 0.2500*gnoise( uv );
uv = m*uv;
f += 0.1250*gnoise( uv );
uv = m*uv;
f += 0.0625*gnoise( uv );
uv = m*uv;
return f;
}
mat3 fromEuler(vec3 ang) {
vec2 a1 = vec2(sin(ang.x),cos(ang.x));
vec2 a2 = vec2(sin(ang.y),cos(ang.y));
vec2 a3 = vec2(sin(ang.z),cos(ang.z));
vec3 m0 = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,
a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);
vec3 m1 = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);
vec3 m2 = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,
a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);
return mat3(m0, m1, m2);
}
mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
{
vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) );
vec3 cv = normalize( cross(cu,cw) );
return mat3( cu, cv, cw );
}
float sdTorus_1( vec3 p, vec2 t )
{
vec2 q = vec2(length(p.xy)-t.x,p.z);
return length(q)-t.y;
}
float map_1(in vec3 p)
{
//return sdSphere(p+vec3(0.,0.,1.0), 0.4);
return sdTorus_1(p+vec3(0.,0.,0.0),vec2(0.4,0.1));
//return sdBox(p+vec3(0.0,0.0,1.0), vec3(0.2, 0.2, 0.2));
//方形中挖掉圓形
// return max(boxSDF(p+vec3(0.0,0.0,1.0), vec3(0.3, 0.3, 0.3)), -sphereSDF(p+vec3(0.,0.,1.0), 0.5));
}
vec2 pixel(vec2 p, float scale){
return floor(p*scale)/scale;
//floor : 無條件捨去
}
vec3 pixel(vec3 p, float scale){
return floor(p*scale)/scale;
}
float trace(vec3 o, vec3 r, out vec3 p)
{
float t=0.0;
for (int i=0; i<32; ++i)
{
p= o+r*t;
float d= map_1(p);
t += d*0.3;
}
return t;
}
// Pixel effect
float trace(vec3 o, vec3 r, out vec3 p, out float d)
{
float t=0.0;
for (int i=0; i<32; ++i)
{
p = o+r*t;
p = pixel(p, 10.);//格化
d = map_1(p);
if(d<0.0){
break;
}
t += d*0.5; //影響輪廓精準程度
}
return t;
}
float sdTorus_0( vec3 p, vec2 t )
{
vec2 q = vec2(length(p.xy)-t.x,p.z);
return length(q)-t.y;
}
float map_0(in vec3 p)
{
//return sdSphere(p+vec3(0.,0.,1.0), 0.4);
return sdTorus_0(p+vec3(0.,0.,0.0),vec2(0.4,0.1));
//return sdBox(p+vec3(0.0,0.0,1.0), vec3(0.2, 0.2, 0.2));
//方形中挖掉圓形
// return max(boxSDF(p+vec3(0.0,0.0,1.0), vec3(0.3, 0.3, 0.3)), -sphereSDF(p+vec3(0.,0.,1.0), 0.5));
}
vec3 gradient( in vec3 p ) //尚未normalize
{
const float d = 0.001;
vec3 grad = vec3(map_0(p+vec3(d,0,0))-map_0(p-vec3(d,0,0)),
map_0(p+vec3(0,d,0))-map_0(p-vec3(0,d,0)),
map_0(p+vec3(0,0,d))-map_0(p-vec3(0,0,d)));
return grad;
}
vec3 sky_color_2315452051(vec3 e) { //漸層藍天空色
e.y = max(e.y,0.0);
vec3 ret;
ret.x = pow(1.0-e.y,3.0);
ret.y = pow(1.0-e.y, 1.2);
ret.z = 0.8+(1.0-e.y)*0.3;
return ret;
}
vec3 getSkyALL(vec3 e)
{
return sky_color_2315452051(e);
}
void main(){
vec2 uv = gl_FragCoord.xy/u_resolution.xy;
uv = uv*2.0-1.0;
uv.x*= u_resolution.x/u_resolution.y;
uv.y*=1.0;//校正 預設值uv v軸朝下,轉成v軸朝上相同於y軸朝上為正
vec2 mouse=(u_mouse.xy/u_resolution.xy)*2.0-1.0;
// camera option1 (模型應在原點,適用於物件)
vec3 CameraRot=vec3(0.0, mouse.y, mouse.x);
vec3 ro= vec3(0.0, 0.0, 1.0)*fromEuler(CameraRot); //CameraPos;
vec3 ta =vec3(0.0, 0.0, 0.0); //TargetPos;
//vec3 ta =float3(CameraDir.x, CameraDir.z, CameraDir.y);
//UE座標Z軸在上
mat3 ca = setCamera( ro, ta, 0.0 );
vec3 RayDir = ca*normalize(vec3(uv, 1.0));
//z值越大則zoom in,可替換成iMouse.z
vec3 RayOri = ro;
// camera option2 (攝影機在原點,適用於場景)
/*
vec3 CameraRot=vec3(0.0, -iMouse.y, -iMouse.x);
vec3 RayOri= vec3(0.0, 0.0, 0.0);//CameraPos;
vec3 RayDir = normalize(vec3(uv, -1.))*fromEuler(CameraRot);
*/
vec3 p,n;
float d;
float t = trace(RayOri, RayDir, p, d); //position
n=normalize(gradient(p)); //normal
//SHADING
vec3 result;
result=(p);
// result=(n);
//HDR環境貼圖
vec3 BG=getSkyALL(RayDir); //或getSkyFBM(RayDir)
gl_FragColor = vec4(vec3(result),1.0);
if(t<3.5) gl_FragColor = vec4(vec3(result),1.0);
else gl_FragColor = vec4(BG,1.0);
}