Multiple Models
Multiple Models
#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
float sdPlane_1(vec3 p){
float plane_y = -0.948;
float dPlane = abs(p.y-plane_y);
return dPlane;
}
float sdSphere_0( vec3 p, float s )
{
return length(p)-s;
}
float getDist_0(vec3 p){
//SDF中,模型要擺在同一個場景要用min,
//取最短距離,因為較近的距離一定在畫面前方,
//遠的就會被遮擋。
return min(sdPlane_1(p),sdSphere_0(p, 0.0));
}
float rayMarching(vec3 ro,vec3 rd){
float dO = 0.;
for(int i = 0 ; i < 64 ; i++){
vec3 p_0 = ro+rd*dO;
float ds = getDist_0(p_0);
dO += ds;
if(ds<0.01 || dO>100.)
break;
}
return dO;
}
float sdPlane_0(vec3 p){
float plane_y = -0.948;
float dPlane = abs(p.y-plane_y);
return dPlane;
}
float sdSphere_1( vec3 p, float s )
{
return length(p)-s;
}
float getDist_1(vec3 p){
//SDF中,模型要擺在同一個場景要用min,
//取最短距離,因為較近的距離一定在畫面前方,
//遠的就會被遮擋。
return min(sdPlane_0(p),sdSphere_1(p, 0.0));
}
//燈光的模板
struct Light{
vec3 p; // position
vec3 id; // diffuse color
vec3 is; // specular color
};
struct Mat{
float ka; // factor of abient
float kd; // factor of diffuse
float ks; // factor of specular
float s; // shiness
};
vec3 CalLight(Light l,Mat m,vec3 p, vec3 n,vec3 rd){
vec3 diffuse,specular;
vec3 ld =normalize(l.p - p); //Light Dir
vec3 vr =reflect(rd,n); //View Reflect
diffuse = m.kd*max(dot(ld,n),0.)*l.id;
specular = m.ks*pow(max(dot(vr,ld),0.),m.s)*l.is;
// shadow
float d = rayMarching(p+n*0.03,ld);
if(d < length(l.p - p)) diffuse *= 0.1;
return diffuse + specular;
}
vec3 lighting(vec3 p ,vec3 n , vec3 v,vec3 rd){
// Define Lights
//左到右的input分別是,position , diffuse color , specular color ,可以參照上方struct Light
Light l1 = Light(vec3(5.,0.,0.),vec3(1.000,0.216,0.292),vec3(1.,1.,1.));
Light l2 = Light(vec3(-5.,1.,-5.),vec3(0.029,0.119,0.805),vec3(1.,1.,1.));
Light l3 = Light(vec3(-1.5,1.5,3.),vec3(0.855,0.756,0.273),vec3(1.,1.,1.));
// Material Properties
vec3 ambient,final;
float ka = 0.5;
Mat mat = Mat(1.,1.,1.,150.); // 設定material的參數,ka, kd, ks, s的數值大小
ambient = ka*vec3(0.095,0.037,0.012); // 決定底色
final = ambient;
final += CalLight(l1,mat,p,n,rd); // 加上第一盞燈光的渲染
final += CalLight(l2,mat,p,n,rd); // 加上第二盞燈光的渲染
final += CalLight(l3,mat,p,n,rd); // 加上第三盞燈光的渲染
return final;
}
vec3 GetNormal(vec3 p){
vec2 e = vec2(0.01,0.0);
vec3 n = vec3(
getDist_1(p+e.xyy),
getDist_1(p+e.yxy),
getDist_1(p+e.yyx))-getDist_1(p);
return normalize(n);
}
// main step by step
void main() {
vec2 st = (gl_FragCoord.xy/u_resolution.xy)*2.-1.;
// ro -> ray origin
vec3 ro = vec3(0.,-0.2,0.);
// rd -> ray direction
vec3 rd = normalize(vec3(st.xy,1.));
// t -> distance
float t = rayMarching(ro,rd);
// p -> vertex pos
vec3 p = ro+rd*t;
// n -> normal dir
vec3 n = GetNormal(p);
//calculate lighting
vec3 color = lighting(p,n,ro,rd);
gl_FragColor = vec4(color,1.0);
}