CMH Studio

Add Lights and Tracing Model

Add Lights and Tracing Model


#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 );
}

vec3 phong(vec3 p, vec3 n, vec3 v){
        vec3 final=vec3(0.0);
        vec3 diffuse,specular,ambient;
        ambient=vec3(0.305,0.049,0.049);
            
        vec3 light_pos= vec3(5.000,1.000,2.000);
        vec3 light_col= vec3(0.955,0.819,0.231);
        vec3 l=normalize(light_pos-p); //光線向量
        vec3 r=normalize(reflect(-l,n));
        float ka=0.1, ks=1.0, kd=1.0;
        float shininess=8.0;        
        diffuse=vec3(kd*dot(l, n));
        specular=vec3(ks* pow(max(dot(r, v),0.0), shininess)) ;    
        final+=(diffuse+specular)*light_col;
    
        return final+ambient;
    }

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 sky_color_529295689(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_529295689(e);
}

float sdTorus_0( 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_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));
}

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_1( 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_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));
}

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;
}

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*3.0, -mouse.x);
            vec3 CameraRot=vec3(0.0, -0.8, 0.0);
            vec3 ro= vec3(0.0, 0.0, 2.0)*fromEuler(CameraRot);//CameraPos;
            vec3 ta =vec3(0.0, 0.0, 0.0); //TargetPos; /
            vec3 CameraDir=normalize(ro - ta); //CameraDir;
            // ta =float3(CameraDir.x, CameraDir.z, CameraDir.y);
            //UE座標Z軸在上

            mat3 ca = setCamera( ro, ta, 0.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));
        vec3 bump=triplanarMap(p*1.652,n);
        
        float edge= dot(-RayDir, n);
        //edge = step(0.2, edge);
        edge = smoothstep(-0.272, 0.400, edge);
            
            
                
        //SHADING
            vec3 result=n;
            result = phong(p,n,-RayDir);
                
            
        //HDR環境貼圖
            vec3 BG=getSkyALL(RayDir);	   //或getSkyFBM(RayDir)

        if(t<2.5) gl_FragColor = vec4(vec3(result),1.0); 
        else gl_FragColor = vec4(BG,1.0);
    }