testing shader fragments

This commit is contained in:
2024-05-28 22:10:25 +03:00
parent 42ab16309c
commit 063624d7bb
9 changed files with 1260 additions and 335 deletions

View File

@ -1,265 +1,233 @@
#version 120
uniform float time;
uniform vec2 resolution;
uniform sampler2D texture_sampler;
uniform sampler2D texts;
#define MAX_STEPS 100
#define MAX_DIST 20.
#define SURF_DIST .001
#define TAU 6.283185
#define PI 3.141592
float zoom = 1.;
float gTime = 0.;
#define FOG_DENSITY 0.01
float getBeat(void) {
return floor(abs(time*4.) / (60./145.) );
}
float getBar(void) {
return floor(abs(time) / (60./145.));
struct Obj {
float distance; // distance map
int material; // material Id
};
mat2 Rot(float a) {
float s=sin(a), c=cos(a);
return mat2(c, -s, s, c);
}
vec2 csqr(vec2 a) {
return vec2(a.x * a.x - a.y * a.y, 2. * a.x * a.y);
}
mat2 rot(float a) {
return mat2(cos(a), sin(a), -sin(a), cos(a));
}
vec2 iSphere(in vec3 ro, in vec3 rd, in vec4 sph)//from iq
{
vec3 oc = ro - sph.xyz;
float b = dot(oc, rd);
float c = dot(oc, oc) - sph.w * sph.w;
float h = b * b - c;
if(h < 0.0)
return vec2(-1.0);
h = sqrt(h);
return vec2(-b - h, -b + h);
}
float map(in vec3 p) {
float res = 0.;
vec3 c = p;
for(int i = 0; i < 10; ++i) {
p = .7 * abs(p) / dot(p, p) - .7;
p.yz = csqr(p.yz);
p = p.zxy;
res += exp(-19. * abs(dot(p, c)));
}
return res / 2.;
}
vec3 raymarch(in vec3 ro, vec3 rd, vec2 tminmax) {
float t = tminmax.x;
float dt = .02;
//float dt = .2 - .195*cos(time*.05);//animated
vec3 col = vec3(0.);
float c = 0.;
for(int i = 0; i < 64; i++) {
t += dt * exp(-2. * c);
if(t > tminmax.y)
break;
c = map(ro + t * rd);
col = .99 * col + .08 * vec3(c * c, c, c * c * c);//green
//col = .99*col+ .08*vec3(c*c*c, c*c, c);//blue
}
return col;
}
void CoolSphere(out vec4 fragColor, in vec2 fragCoord) {
float time = time;
vec2 q = fragCoord.xy / resolution.xy;
vec2 p = -1.0 + 2.0 * q;
p.x *= resolution.x / resolution.y;
vec2 m = vec2(0.);
m -= .5;
// camera
vec3 ro = zoom * vec3(4.);
ro.yz *= rot(m.y);
ro.xz *= rot(m.x + 0.1 * time);
vec3 ta = vec3(0.0, 0.0, 0.0);
vec3 ww = normalize(ta - ro);
vec3 uu = normalize(cross(ww, vec3(0.0, 1.0, 0.0)));
vec3 vv = normalize(cross(uu, ww));
vec3 rd = normalize(p.x * uu + p.y * vv + 4.0 * ww);
vec2 tmm = iSphere(ro, rd, vec4(0., 0., 0., 2.));
// raymarch
vec3 col = raymarch(ro, rd, tmm);
if(tmm.x < 0.)
col = texture2D(texture_sampler, rd.xy).rgb;
else {
vec3 nor = (ro + tmm.x * rd) / 2.;
nor = reflect(rd, nor);
float fre = pow(.5 + clamp(dot(nor, rd), 0.0, 1.0), 3.) * 1.3;
col += texture2D(texture_sampler, nor.xy).rgb * fre;
}
// shade
col = .5 * (log(1. + col));
col = clamp(col, 0., 1.);
fragColor = vec4(col, 1.0);
}
float sdBox(vec3 p, vec3 b) {
vec3 q = abs(p) - b;
return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
}
float box(vec3 pos, float scale) {
pos *= scale;
float base = sdBox(pos, vec3(.4, .4, .1)) / 1.5;
pos.xy *= 5.;
pos.y -= 3.5;
pos.xy *= rot(.75);
float result = -base;
return result;
}
float box_set(vec3 pos, float time) {
vec3 pos_origin = pos;
pos = pos_origin;
pos.y += sin(gTime * 0.4) * 2.5;
pos.xy *= rot(.8);
float box1 = box(pos, 2. - abs(sin(gTime * 0.4)) * 1.5);
pos = pos_origin;
pos.y -= sin(gTime * 0.4) * 2.5;
pos.xy *= rot(.8);
float box2 = box(pos, 2. - abs(sin(gTime * 0.4)) * 1.5);
pos = pos_origin;
pos.x += sin(gTime * 0.4) * 2.5;
pos.xy *= rot(.8);
float box3 = box(pos, 2. - abs(sin(gTime * 0.4)) * 1.5);
pos = pos_origin;
pos.x -= sin(gTime * 0.4) * 2.5;
pos.xy *= rot(.8);
float box4 = box(pos, 2. - abs(sin(gTime * 0.4)) * 1.5);
pos = pos_origin;
pos.xy *= rot(.8);
float box5 = box(pos, .5) * 6.;
pos = pos_origin;
float box6 = box(pos, .5) * 6.;
float result = max(max(max(max(max(box1, box2), box3), box4), box5), box6);
return result;
}
float map(vec3 pos, float time) {
vec3 pos_origin = pos;
float box_set1 = box_set(pos, time);
return box_set1;
}
vec4 mainImage2(vec2 fragCoord) {
vec2 p = (fragCoord.xy * 2. - resolution.xy) / min(resolution.x, resolution.y);
vec3 ro = vec3(0., -0.2, time * 4.);
vec3 ray = normalize(vec3(p, 1.5));
ray.xy = ray.xy * rot(sin(time * .03) * 5.);
ray.yz = ray.yz * rot(sin(time * .05) * .2);
float t = 0.1;
vec3 col = vec3(0.);
float ac = 0.0;
for(int i = 0; i < 99; i++) {
vec3 pos = ro + ray * t;
pos = mod(pos - 2., 4.) - 2.;
gTime = time - float(i) * 0.01;
float d = map(pos, time);
d = max(abs(d), 0.01);
ac += exp(-d * 23.);
t += d * 0.55;
}
col = vec3(ac * 0.02);
col += vec3(0., 0.2 * abs(sin(time)), 0.5 + sin(time) * 0.2);
return vec4(col, 1.0 - t * (0.02 + 0.02 * sin(time)));
}
vec3 palette(float t) {
vec3 a = vec3(0.5, 0.5, 0.5);
vec3 b = vec3(1.0, 1.0, 1.0);
vec3 c = vec3(1.0, 1.0, 1.0);
vec3 d = vec3(0.0, 0.6666, 0.3333);
return a + b * cos(6.28318 * (c*t+d));
}
float rand(vec2 co) {
float a = 12.9898;
float b = 78.233;
float c = 43758.5453;
float dt= dot(co.xy ,vec2(a,b));
float sn= mod(dt,3.14);
return fract(sin(sn) * c);
}
vec3 random(vec2 uv) {
float rng = rand(vec2(uv.x+time, uv.y));
vec3 col = vec3(0.0+rng*0.1, 0.2+rng*0.1, 0.4+rng*0.1);
col.x += sin(uv.x+time*0.2)*0.1;
col.y += sin(uv.y+time*0.2)*0.1;
col.z += sin(uv.y+time*0.2)*0.1;
return col;
vec3 applyFog(in vec3 color, in float distance) {
float fogAmount = 1.0 - exp(-distance*FOG_DENSITY);
vec3 fogColor = vec3(0.17, 0.16, 0.24);
return mix( color, fogColor, fogAmount );
}
vec3 wave(vec2 uv, float phase, float _offset, float height, float waveLenght, float color) {
float val = -(sin(phase+uv.x*waveLenght+time) + (uv.y*6.+height)+_offset)*0.055;
val *= 1. + sin(phase + uv.x*waveLenght+time) + (uv.y*6.-height+_offset);
//return smoothstep(0.0, 1.0, val) * palette(color/360.);
return clamp(val, 0., .9) * palette(color/360.);
}
float gStartTime = 0.;
float gPrevTime = -0.1;
vec4 waveTexture(vec2 uv) {
uv.y = sin(uv.x*16. + time)/32. + uv.y-0.03;
uv.x -= (time-gStartTime)*0.2;
vec4 tex = texture2D(texts, uv);
if (tex.y > 0. && (gPrevTime != gStartTime)) {
gStartTime = time;
gPrevTime = gStartTime;
}
return vec4(tex.rgb, 1.0);
}
void TextScroller(out vec4 fragColor, in vec2 fragCoord)
float opExtrusion( in vec3 p, in float sdf, in float h )
{
// Normalized pixel coordinates (from -1 to 1, origo at 0,0)
vec2 uv = (fragCoord.xy * 2. - resolution.xy) / min(resolution.x, resolution.y);
vec3 col = vec3(0., 0.4, 0.6);
col += wave(uv, 0., 1., 3., 1., sin(time+0.3)*90.);
col += wave(uv, sin(time), 0., 3., -1., sin(time-1.2)*120.);
col += wave(uv, -3., 0., 3., 1., sin(time+0.5)*90.);
vec4 outBuf = waveTexture(uv * 0.1);
fragColor = max(mainImage2(gl_FragCoord.xy)*0.2, vec4(col*outBuf.xyz, 1.0)); // + vec4(random(uv*2.), 1.0);
vec2 w = vec2( sdf, abs(p.z) - h);
return min(max(w.x,w.y),0.0) + length(max(w,0.0));
}
void main(void) {
TextScroller(gl_FragColor, gl_FragCoord.xy);
/*else
float sdCog2d(vec2 pos) {
float r = length(pos)*2.;
float a = atan(pos.y,pos.x);
float f = 1. - smoothstep(-0.2, .8, sin(a * 12.))*0.14;
f = smoothstep(f,f + 2.,r);
return f;
}
float opSmoothSubtraction( float d1, float d2, float k )
{
float h = max(k-abs(-d1-d2),0.0);
return max(-d1, d2) + h*h*0.25/k;
}
float sdCapsule( vec3 p, vec3 a, vec3 b, float r )
{
vec3 pa = p - a, ba = b - a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
return length( pa - ba*h ) - r;
}
float sdCog(vec3 pos, float angle) {
pos.xy *= Rot(angle);
float d1 = opExtrusion(pos, sdCog2d(pos.xy), 0.15);
float d2 = sdCapsule(pos - vec3(0.,0., -0.5), vec3(0., 0.0, 0.), vec3(0., 0., 1.), 0.2);
return 0.8 * opSmoothSubtraction(d2,d1,0.02)-0.001;
}
// Scene
Obj mapScene(in vec3 p) {
float d = 1e10;
float dGround = p.y +1.5 + sin(p.z*0.6)*.2 + sin(p.x*1.3)*.1;
Obj ground = Obj(dGround, 0);
{
mainImage2(gl_FragColor, gl_FragCoord.xy);
vec4 l;
vec2 texttop = vec2(0., -.35), pt = (gl_FragCoord.xy / resolution) - texttop;
if(pt.y > 0.) {
l = gl_FragColor + texture2D(texts, pt);
}
float d1 = sdCog(p+vec3(1., 0., 0.), time);
d = min(d, d1);
}
{
float d1 = sdCog(p+vec3(0.5, -.87, 0.), -time);
d = min(d, d1);
}
{
float d1 = sdCog(p+vec3(0.5, .87, 0.), -time);
d = min(d, d1);
}
Obj ob1 = Obj(d, 1);
gl_FragColor = l;
} */
}
if (ground.distance > ob1.distance) return ob1;
return ground;
}
Obj castRay(vec3 ro, vec3 rd) {
float t = 0.0;
Obj res = Obj(-1., -1);
for(int i=0; i<MAX_STEPS; i++) {
vec3 p = ro + rd * t;
res = mapScene(p);
t += res.distance;
if (t > MAX_DIST || res.distance < abs(SURF_DIST*t) ) break;
}
if (t > MAX_DIST) t = -1.0;
res.distance = t;
return res;
}
float castShadow(vec3 ro, vec3 rd) {
float res = 1.0;
float t = 0.001;
for(int i = 0; i < MAX_STEPS; i++) {
vec3 pos = ro + t* rd;
float h = mapScene(pos).distance;
res = min(res, 10.0*h/t);
if (abs(h) < (0.001*t) ) break;
t += h;
if (t > 20.) break;
}
return clamp(res,0., 1.);
}
vec3 calcNormal(vec3 pos) {
vec2 e = vec2(.001, 0.);
vec3 n = vec3( mapScene(pos+e.xyy).distance - mapScene(pos-e.xyy).distance,
mapScene(pos+e.yxy).distance - mapScene(pos-e.yxy).distance,
mapScene(pos+e.yyx).distance - mapScene(pos-e.yyx).distance
);
return normalize(n);
}
vec3 fresnel( vec3 F0, vec3 h, vec3 l ) {
return F0 + ( 1.0 - F0 ) * pow( clamp( 1.0 - dot( h, l ), 0.0, 1.0 ), 5.0 );
}
vec3 shading(vec3 v, vec3 n, vec3 dir, int material) {
float shininess = 1.;
vec3 final = vec3( 0.0 );
vec3 ref = reflect( dir, n );
vec3 Ks = vec3( 0.5 );
vec3 Kd = vec3( 1.0 );
vec3 outMaterial = vec3(0.1255, 0.1255, 0.1255);
if (material == 0) {
outMaterial = vec3(0.1412, 0.1412, 0.1412);
shininess = 3.1;
} else if (material == 1) {
outMaterial = vec3(0.1765, 0.1961, 0.2275);
shininess = 21.;
}
// light 0
{
vec3 light_pos = vec3( -2.,.3, 10. );
vec3 light_color = vec3(0.71, 0.51, 0.72) * 5.;
vec3 vl = normalize( light_pos - v );
vec3 diffuse = Kd * vec3( max( 0.0, dot( vl, n ) ) );
vec3 specular = vec3( max( 0.0, dot( vl, ref ) ) );
vec3 F = fresnel( Ks, normalize( vl - dir ), vl );
specular = pow( specular, vec3( shininess ) );
final += outMaterial * specular * light_color * mix( diffuse, specular, F );
}
// light 1
{
vec3 light_pos = vec3( 5.0, 5.0, -20.0 );
vec3 light_color = vec3(0.14, 0.36, 0.83)* 7.;
vec3 vl = normalize( light_pos - v );
vec3 diffuse = Kd * vec3( max( 0.0, dot( vl, n ) ) );
vec3 specular = vec3( max( 0.0, dot( vl, ref ) ) );
vec3 F = fresnel( Ks, normalize( vl - dir ), vl );
specular = pow( specular, vec3( shininess ) );
final += outMaterial * specular * light_color * mix( diffuse, specular, F );
}
{
vec3 SUN_DIR = vec3(0. , .4, 1.);
float sun_dif = clamp(dot(n, SUN_DIR), 0., 1.);
float shadow = castShadow(v + n*0.02, SUN_DIR);
final += outMaterial * vec3(1.1,1.2, 1.5) * sun_dif * sun_dif * shadow;
}
{
vec3 SUN_DIR = vec3(0. , .6, -1.);
float sun_dif = clamp(dot(n, SUN_DIR), 0., 1.);
final += outMaterial * vec3(0.0353, 0.2667, 0.4784) * sun_dif;
}
// final += texture( iChannel0, ref ).rgb * fresnel( Ks, n, -dir );
// vec3 col = vec3(0.4)* ref.x;
//vec3 col = vec3(0.0588, 0.0588, 0.1216);// - vec3(0.149, 0.0863, 0.2314) * v.x;
//final += col * fresnel( vec3(.5), ref, -dir );
return final;
}
void main()
{
vec2 p = (2.0 * gl_FragCoord.xy - resolution.xy) / resolution.y;
float angle = time*0.4;
// angle = 2.0; // comment to rotate
// gl_FragColor = vec4(vec3(sdCog2d(p)), 1.);
// return;
// camera
vec3 ta = vec3(0.0, 0., 0.0);
vec3 ro = ta + vec3(4.*sin(angle), cos(angle), 4.*cos(angle)); // *cos(angle))
vec3 ww = normalize(ta-ro);
vec3 uu = normalize(cross(ww, vec3(0,1,0)));
vec3 vv = normalize(cross(uu,ww));
vec3 rd = normalize(p.x * uu + p.y*vv + 1.4*ww); // camera
// global light
vec3 col = vec3(0.1451, 0.1098, 0.1608) - vec3(0.9725, 0.5176, 0.0) *rd.y;
Obj t = castRay(ro, rd);
if (t.distance > 0.) {
vec3 pos = ro + rd * t.distance;
vec3 nor = calcNormal(pos);
col = shading(pos, nor, rd , t.material);
// apply fog
col = applyFog(col, t.distance);
}
gl_FragColor = vec4( pow( col, vec3(1.0/1.3) ), 1.0 );
}