10作目です。
このコードだけでこの動画のようになります。
#define PI 3.14159265359
#define lightDir normalize(vec3(1.0, 1.0, -1.0))
#define sphereRadius .1
float sdSphere(vec3 p, float r) //球
{
return length(p) - r;
}
float sdCappedCylinder( vec3 p, vec2 h ) //円柱
{
vec2 d = abs(vec2(length(p.xz),p.y)) - h;
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
float sdTorus( vec3 p, vec2 t ) //トーラス(ドーナツ)
{
vec2 q = vec2(length(p.xz)-t.x,p.y);
return length(q)-t.y;
}
float map(vec3 p){
float d = 3.0;
vec3 q = p;
//torus
d = min(d, sdTorus(q - vec3(0.0, 1.0, 0.0), vec2((2.0 + 0.5 * sin(iTime * PI)), .1)));
//cylinder
for (int i = 0; i < 10; i++) {
float radius = 2.0 - float(i) * (0.1 * sin(iTime) + 0.15);
float delta = 0.05 * (0.8 + 0.2 * sin(iTime * PI));
float height = .1;
if (i % 2 == 0) {
float cylinder = sdCappedCylinder(q - vec3(0.0, -2.0, 0.0), vec2(radius, height));
d = min(d, cylinder);
} else {
float cylinder = sdCappedCylinder(q - vec3(0.0, -2.0, 0.0) - vec3(0.0,0.1,0.0), vec2(radius, height));
d = max(d, -cylinder);
}
}
return d;
}
vec3 calcNormal( in vec3 pos )
{
const float ep = 0.0001;
vec2 e = vec2(1.0,-1.0)*0.5773;
return normalize( e.xyy*map( pos + e.xyy*ep ) +
e.yyx*map( pos + e.yyx*ep ) +
e.yxy*map( pos + e.yxy*ep ) +
e.xxx*map( pos + e.xxx*ep ) );
}
float calcSoftshadow( in vec3 ro, in vec3 rd, float tmin, float tmax, const float k )
{
float res = 1.0;
float t = tmin;
for( int i=0; i<50; i++ )
{
float h = map( ro + rd*t );
res = min( res, k*h/t );
t += clamp( h, 0.02, 0.20 );
if( res<0.005 || t>tmax ) break;
}
return clamp( res, 0.0, 1.0 );
}
mat2 rot(float a)
{
return mat2(cos(a), -sin(a), sin(a), cos(a));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord){
vec2 uv = fragCoord/iResolution.xy;
uv = uv * 2.0 - 1.0;
uv.x *= iResolution.x/iResolution.y;
vec2 m = (iMouse.xy * 2.0 - iResolution.xy)/iResolution.xy;
vec3 ro = vec3(0.0, 0.0, 4.);
vec3 rd = normalize(vec3(uv, -1.0));
vec3 col = vec3(0.0);
vec3 totalCol = vec3(0.0);
// 球の表面にカメラを配置
vec3 spherePos = vec3(sin(iTime), 2. * cos((iTime + .5)) + 1., cos(iTime));
ro.xz *= rot(iTime * PI / 4.);
rd.xz *= rot(iTime * PI / 4.);
ro.xz *= rot(-m.x);
rd.xz *= rot(-m.x);
ro.yz *= rot(-m.y);
rd.yz *= rot(-m.y);
float t = 0.0;
for(int i = 0; i < 64; i++){
vec3 p = ro + rd * t;
float sphere = sdSphere(p - spherePos, sphereRadius);
float d = map(p);
d = min(d, sphere);
if(d < 0.01 || t > 20.0) {
vec3 pos = ro + t*rd;
vec3 nor = calcNormal(pos); //法線
vec3 lig = lightDir; //光源の方向
float dif = clamp(dot(nor,lig),0.0,1.0); //拡散反射
float sha = calcSoftshadow( pos, lig, 0.001, 1.0, 32.0 ); //影
float amb = 0.5 + 0.5*nor.y; //環境光
if(d == sphere){
col = vec3(t * .05);
col += (
vec3(0.05,0.1,0.15)*amb +
vec3(1.00,0.9,0.0)*dif*sha
);
col = sqrt(col);
col *= vec3(1.0, 0.8, 0.6);
}
else{
col = vec3(t * .05);
col += vec3(0.05,0.1,0.15)*amb +
vec3(1.00,0.9,0.80)*dif*sha;
col = sqrt(col);
}
totalCol += col;
break;
}
t += d;
}
fragColor = vec4(totalCol, 1.0);
}
制作を続けていきます。では。
#デジタルアート #デモシーン #3DCG #シェーダーコーディング #レイマーチング #SF #demoscene
Please follow and like us:
コメント