Make Bumping
Make Bumping
#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
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;
}
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);
}
vec3 smoothSampling2(vec2 uv)
{
const float T_RES = 32.0;
return vec3(gnoise(uv*T_RES)); //讀取亂數函式
}
float triplanarSampling(vec3 p, vec3 n)
{
float fTotal = abs(n.x)+abs(n.y)+abs(n.z);
return (abs(n.x)*smoothSampling2(p.yz).x
+abs(n.y)*smoothSampling2(p.xz).x
+abs(n.z)*smoothSampling2(p.xy).x)/fTotal;
}
const mat2 m2_0 = mat2(0.90,0.44,-0.44,0.90);
float triplanarNoise(vec3 p, vec3 n)
{
const float BUMP_MAP_UV_SCALE = 0.2;
float fTotal = abs(n.x)+abs(n.y)+abs(n.z);
float f1 = triplanarSampling(p*BUMP_MAP_UV_SCALE,n);
p.xy = m2_0*p.xy;
p.xz = m2_0*p.xz;
p *= 2.1;
float f2 = triplanarSampling(p*BUMP_MAP_UV_SCALE,n);
p.yx = m2_0*p.yx;
p.yz = m2_0*p.yz;
p *= 2.3;
float f3 = triplanarSampling(p*BUMP_MAP_UV_SCALE,n);
return f1+0.5*f2+0.25*f3;
}
vec3 triplanarMap(vec3 p, vec3 n)
{
float d = 0.005;
float po = triplanarNoise(p,n);
float px = triplanarNoise(p+vec3(d,0,0),n);
float py = triplanarNoise(p+vec3(0,d,0),n);
float pz = triplanarNoise(p+vec3(0,0,d),n);
return normalize(vec3((px-po)/d,
(py-po)/d,
(pz-po)/d));
}
vec3 hsv2rgb_smooth_2315452051( in vec3 c )
{
vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 );
rgb = rgb*rgb*(3.0-2.0*rgb); // cubic smoothing
return c.z * mix( vec3(1.0), rgb, c.y);
}
vec3 flameColour(float f)
{
return hsv2rgb_smooth_2315452051(vec3((f-(2.25/6.))*(1.25/6.),f*1.25+.2,f*.95));
}
vec3 sky_color_1535977339(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_1535977339(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*2., -mouse.x);
vec3 ro= vec3(0.0, 0.0, 2.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, 01.0 );
vec3 RayDir = ca*normalize(vec3(uv, 2.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 t = trace(RayOri, RayDir, p);
n=normalize(gradient(p));
//sol2
/*
float displacement = 10. * (noise_3(p*10.0)*2.0-1.0);
p += n*displacement;
n=normalize(gradient(p));
*/
//sol3
vec3 bump = triplanarMap(p*1.6,n);//調整bumping密度
// n += bump*2.; // ⚠️ 這個數值會讓圖形渲染超出 canvas ,甚至超過 browser 範圍,讓整個螢幕看起來像是壞掉 ⚠️
float edge = dot(-RayDir,n);
//RayDir : 相機看出去的方向
//-RayDir : 看向攝影機的方向
//edge*=-1.;
edge = smoothstep(.2,.4,edge);
//smoothstep產生一點灰階 vs. step單純畫邊緣
//SHADING
vec3 result=n;
result = vec3(edge)*flameColour(edge);
//HDR環境貼圖
vec3 BG=getSkyALL(RayDir); //或getSkyFBM(RayDir)
//亂數作用雲霧(二維)
//float fog= fbm(0.6*uv+vec2(-0.2*u_time, -0.02*u_time))*0.5+0.3;
//vec3 fogFBM=getSkyFBM(reflect(RayDir,n));
if(t<2.5) gl_FragColor = vec4(vec3(result),1.0);
else gl_FragColor = vec4(BG,1.0);
}