new effect, occulusion etc... softshadows...

This commit is contained in:
2024-05-30 22:32:17 +03:00
parent 3d7a859ac1
commit 4c7c2e863b

View File

@ -4,8 +4,13 @@ uniform float u_time;
uniform sampler2D texture_sampler;
uniform sampler2D texts;
struct Ray {
vec3 rd;
vec3 dir;
};
mat2 scale(vec2 scale){
return mat2(scale.x, 0.0, 0.0, scale.y);
return mat2(1. / scale.x, 0.0, 0.0, 1./scale.y);
}
////////////////////////////////////////////////////////////////
@ -595,12 +600,6 @@ mat2 Rot(float a) {
return mat2(c, -s, s, c);
}
vec3 applyFog(in vec3 color, in float distance) {
float fogAmount = 1.0 - exp(-distance * 0.01);
vec3 fogColor = vec3(0.14, 0.13, 0.31);
return mix( color, fogColor, fogAmount );
}
float opExtrusion( in vec3 p, in float sdf, in float h )
{
vec2 w = vec2( sdf, abs(p.z) - h);
@ -617,90 +616,123 @@ float sdCog2d(vec2 pos) {
float sdCog(vec3 pos, float angle) {
pos.xy *= Rot(angle);
float d1 = opExtrusion(pos, sdCog2d(pos.xy), 0.15);
float d2 = fCapsule(pos - vec3(0.,0., -0.5), vec3(0., 0.0, 0.), vec3(0., 0., 1.), 0.2);
return 0.8 * fOpDifferenceRound(d1,d2,0.1)-0.02;}
float d1 = opExtrusion(pos, sdCog2d(pos.xy), 0.05);
float d2 = fCapsule(pos, vec3(0., 0.0, 0.), vec3(0., 0., 1.), 0.2);
return 0.8 * fOpDifferenceRound(d1,d2,0.05)-0.003;}
float sdHex(vec3 pos, float i, float angle) {
vec3 po = pos;
//po.xy *= Rot(angle);
pR(po.yz, PI/2.);
//float d1 = opExtrusion(pos, sdCog2d(pos.xy), 0.01);
float d1 = fHexagonIncircle(po, vec2(0.5+i, .1));
float d2 = fHexagonIncircle(po, vec2(0.2+i, .05));
return 0.9 * fOpGroove(d1,d2, 0.2,0.2);
po.xz *= Rot(angle);
po.yz *= Rot(angle);
pR(po.yz, PI/2.);
float d1 = fHexagonCircumcircle(po, vec2(0.5+i, .1));
float d2 = fHexagonCircumcircle(po, vec2(0.2+i, .1));
return fOpDifferenceRound(d1,d2,0.1);
}
float model(vec3 pos, float angle) {
float d = 1e10;
for (float i = 1.; i < 5.; i++) {
vec3 po = pos;
// pos.z += i*.1;
float a = sdHex(po, i*0.2, angle);
d = min(d,a);
}
return d;
}
// Scene
vec2 mapScene(in vec3 p) {
float mat = 0.;
float d = 1e10;
float dGround = p.y + 1.5;
d = min(d, dGround);
//float dGround = p.y + 2.5;
//d = min(d, dGround);
vec3 po = p;
//po.y += sin(u_time);
// pMod3(po, vec3(3.));
float c1 = model(po, u_time);
d = min(d, c1);
po.xy *= scale(vec2(1.3, 1.3));
/*float c2 = sdCog(p+vec3(0.5, -.87, 0.), -u_time);
const float num = 6.;
for (float i = 1.; i <= num; i++) {
// pos.z += i*.1;
float a = sdHex(po,i*0.35, u_time + abs( 2. + 0.4 * sin(u_time)) * i*3.1415/num);
d = min(d,a);
if (d == a) mat = 1. + mod(i,3.);
}
/*float c2 = sdCog(p, u_time);
d = min(d, c2);
float c3 = sdCog(p+vec3(0.5, .87, 0.), -u_time);
d = min(d, c3);
*/
float mat = 0.;
if ( d == c1) mat = 1.;
//if ( d == c2) mat = 2.;
if ( d == c2) mat = 4.;
*/
// float c3 = fBox(p+vec3(0.5, .87, 0.), vec3(1., 1.,1.));
// d = min(d, c3);
// if ( d == c1) mat = 1.;
//if ( d == c3) mat = 3.;
return vec2(d, mat);
}
vec3 castRay(vec3 ro, vec3 rd) {
vec3 castRay(vec3 ro, vec3 rd, inout vec3 pos) {
float t = 0.0;
float mat = 0.;
float count = 0.;
for(int i=0; i < 100; i++) {
vec3 p = ro + rd * t;
vec2 res = mapScene(p);
float hit = 0.;
for(int i=0; i < 150; i++) {
pos = ro + rd * t;
vec2 res = mapScene(pos);
t += res.x;
mat = res.y;
count = float(i);
if (t > 40. || res.x < abs(0.001*t) ) break;
if (t > 80.) break;
if (res.x < abs(0.001*t) ) {
hit = 1.;
break;
}
}
if (t > 80.) t = -1.0;
return vec3(t, mat, hit);
}
vec3 castReflectedRay(vec3 ro, vec3 rd, vec3 pos) {
float t = 0.0;
float mat = 0.;
float hit = 0.;
for(int i=0; i < 50; i++) {
pos = ro + rd * t;
vec2 res = mapScene(pos);
t += res.x;
mat = res.y;
if (t > 40.) break;
if (res.x < abs(0.001*t) ) {
hit = 1.;
break;
}
}
if (t > 40.) t = -1.0;
return vec3(t, mat, count);
return vec3(t, mat, hit);
}
float softshadow( in vec3 ro, in vec3 rd, float mint, float maxt, float w )
{
float res = 1.0;
float t = mint;
for( int i=0; i<40; i++ )
{
if (t > maxt) break;
float h = mapScene(ro + t*rd).x;
res = min( res, h/(w*t) );
t += clamp(h, 0.005, 0.50);
if( res < -1.0 || t>maxt ) break;
}
res = max(res,-1.0);
return 0.25*(1.0+res)*(1.0+res)*(2.0-res);
}
float castShadow(vec3 ro, vec3 rd) {
float res = 1.0;
float t = 0.001;
for(int i = 0; i < 100; i++) {
vec3 pos = ro + t* rd;
float h = mapScene(pos).x;
for(int i = 0; i < 40; i++) {
float h = mapScene(ro + t* rd).x;
res = min(res, 10.0*h/t);
if (abs(h) < (0.001*t) ) break;
t += h;
@ -722,67 +754,81 @@ 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 addPointLight(vec3 light_pos, vec3 light_color, float shininess, vec3 v, vec3 dir, vec3 n) {
// https://suricrasia.online/blog/shader-functions/
vec3 eRot(vec3 p, vec3 ax, float ro) {
return mix(dot(ax,p)*ax, p, cos(ro)) + sin(ro)*cross(ax,p);
}
vec3 addPointLight(vec3 light_pos, vec3 light_color, float shininess, vec3 v, vec3 dir, vec3 n, float occ) {
vec3 Ks = vec3( .5454 );
vec3 Kd = vec3( 1. );
vec3 ref = reflect( dir, n );
vec3 vl = normalize( 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 ) );
float shadow = castShadow(v + n*0.02, light_pos);
vec3 F = fresnel( Ks, normalize( vl - dir ), vl )*occ;
float shadow = softshadow(v+n*0.01,light_pos, .01, 30., 18.);
//float shadow = castShadow(v + n*0.02, light_pos);
specular = pow( specular, vec3( shininess ) )*occ;
return light_color * mix( diffuse, specular, F ) * shadow;
return light_color * mix( diffuse, specular, F );
}
float getAmbientOcc(vec3 p, vec3 n) {
float occ = 0.;
float weight = 1.;
for (int i = 0; i < 8; i++) {
float len = 0.01 + 0.02 * float(i*i);
float dist = mapScene(p+n*len).x;
occ += (len - dist) * weight;
weight *=0.85;
}
return 1.0 - clamp(0.6 * occ, 0., 1.);
}
vec3 shading(vec3 v, vec3 n, vec3 dir, float material) {
float shininess = 1.;
vec3 ref = reflect( dir, n );
vec3 outMaterial = vec3(0.1529, 0.1529, 0.1529);
float occ = getAmbientOcc(v,n);
vec3 outMaterial = vec3(0.1529, 0.1529, 0.1529);
if (material == 0.) {
outMaterial = vec3(0.4, 0.2235, 0.3608);
outMaterial = vec3(0.2863, 0.1059, 0.2431);
shininess = 1.5;
} else if (material == 1.) {
outMaterial = vec3(0.8784, 0.8784, 0.8784);
shininess = 15.;
outMaterial = vec3(0.3294, 0.0941, 0.6);
shininess = 0.6;
} else if (material == 2.) {
outMaterial = vec3(0.0431, 0.2118, 0.4588);
outMaterial = vec3(0.5804, 0.9647, 1.0);
shininess = 1.;
} else if (material == 3.) {
outMaterial = vec3(0.1569, 0.1922, 0.2549);
shininess = 16.;
outMaterial = vec3(0.0, 0.0, 0.0);
shininess = 100.;
} else if (material == 4.) {
outMaterial = vec3(0.9961, 1.0, 0.9922);
shininess = .3;
}
vec3 lights = vec3(0.);
lights += addPointLight(vec3( 0.,20., 10. ),vec3(0.38, .54, .54)*2., shininess, v, dir, n);
lights += addPointLight(vec3( 2.0, .0, -10.0 ),vec3(0.22, 0.14, 0.57)*3., shininess, v,dir,n );
lights += addPointLight(vec3( 0., -40., -1. ),vec3(0.56, 0.44, 0.18)*2., shininess, v, dir, n, occ);
lights += addPointLight(vec3( -20.,4., 10. ),vec3(0.04, 0.2, 0.71)*2., shininess, v, dir, n, occ);
// lights += addPointLight(vec3( 2., -1.0, -1.0 ),vec3(0.12, 0.51, 0.63)*2., shininess, v,dir,n,occ );
vec3 lightDir = vec3(-2. , 3., -1.);
vec3 lightDir = vec3(0. , 4., 2.);
float sun_dif = clamp(dot(n, lightDir), 0., 1.);
float shadow = castShadow(v + n*0.02, lightDir);
lights += vec3(0.0863, 0.102, 0.1059) *sun_dif* shadow; //* mix( vec3(sun_dif), specular, F )
float shadow = softshadow(v+n*0.01,lightDir, .01, 30., 18.);
lights += vec3(0.6627, 0.7098, 0.8863) * sun_dif*shadow*occ; //* shadow; //* mix( vec3(sun_dif), specular, F )
{
vec3 lightDir = vec3(0. , .6, -1.);
float sun_dif = clamp(dot(n, lightDir), 0., 1.);
//lights += vec3(0.1804, 0.3686, 0.5451) * sun_dif;
}
//vec3 col = mix(vec3(0.051, 0.0118, 0.1216), vec3(0.2471, 0.3216, 0.0471), v.y);
//lights += col * fresnel(vec3(.5),dir, n);
// 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;
// lights += col * fresnel( vec3(.5), ref, -dir );
float ind = clamp( dot( n, normalize(lightDir*vec3(-1.0,.0,-1.0)) ), 0.0, 1.0 );
lights += vec3(0.1333, 0.1333, 0.1216) * ind *occ;
//float ind = clamp( dot( n, normalize(lightDir*vec3(-1.0,.0,-1.0)) ), 0.0, 1.0 );
//lights += vec3(0.2196, 0.2196, 0.2196) * ind;
return outMaterial * lights;
return outMaterial * max(vec3(0.), lights);
}
vec3 postProcess(vec3 col) {
@ -794,17 +840,17 @@ vec3 postProcess(vec3 col) {
vec2 screenCoord = gl_FragCoord.xy/u_resolution.xy;
// Vignette
float radius = 0.9;
float radius = 0.8;
float d = smoothstep(radius, radius-0.4, length(screenCoord-vec2(0.5)));
col = mix(col, col * d, 0.6);
col = mix(col, col * d, .9);
// Contrast
float constrast = .3;
float constrast = .5;
col = mix(col, smoothstep(0.0, 1.0, col), constrast);
// Colour mapping
col *= vec3(0.9412, 0.8392, 1.0);
col *= vec3(1.0, 1.0, 1.0);
col = pow( col, vec3(1.0/2.2) ); // gamma
@ -820,78 +866,124 @@ vec3 postProcess(vec3 col) {
vec3 getCameraRayDir(vec2 uv, vec3 camPos, vec3 camTarget)
{
// Calculate camera's "orthonormal basis", i.e. its transform matrix components
vec3 camForward = normalize(camTarget - camPos);
vec3 camRight = normalize(cross(vec3(0.0, 1.0, 0.0), camForward));
vec3 camForward = normalize(camTarget-camPos );
vec3 camRight = normalize(cross(vec3(.0, 1.0, 0.0), camForward));
vec3 camUp = normalize(cross(camForward, camRight));
float fov = 1.1;
float fov = 0.7;
vec3 vDir = normalize(uv.x * camRight + uv.y * camUp + camForward * fov);
return vDir;
}
vec3 getCameraFov(vec2 uv, vec3 camPos,vec3 camTarget) {
vec3 getCameraRayDir2(vec2 uv, vec3 camPos, vec3 lookAt, float zoom){
vec3 f = normalize(lookAt - camPos);
vec3 r = cross(vec3(0.0,1.0,0.0),f);
vec3 u = cross(f,r);
vec3 c=camPos+f*zoom;
vec3 i=c+uv.x*r+uv.y*u;
return normalize(i-camPos);
}
vec3 getCameraFov(vec2 uv, vec3 camPos, vec3 camTarget) {
vec3 camForward = normalize(camTarget-camPos);
vec3 camRight = normalize(cross(vec3(0.0, 1.0, 0.0), camForward));
vec3 camUp = normalize(cross(camForward,camRight));
float fov = 1.1;
float fov = 1.7;
// Depth of field
float dof = .1;
vec2 h = vec2( noise(gl_FragCoord.xy, .11), noise(gl_FragCoord.xy, .4));
float dof = .25;
vec2 h = vec2( noise(gl_FragCoord.xy, .13), noise(gl_FragCoord.xy, .4));
//vec3 h= rnd23(gl_FragCoord.xy);
vec3 voff = sqrt(h.x)*(camRight*sin(h.y*6.283)+camUp*cos(h.y*6.283))*dof;
camTarget -=voff;
float focusdistance = 40.2;
// camTarget -=voff;
float focusdistance = 150.2;
return normalize(uv.x * camRight + uv.y * camUp + fov * camForward + voff * fov/focusdistance);
}
vec3 getSceneColor(vec2 fragCoord) {
vec3 applyFog(vec3 col, float t, vec3 rd, vec3 lightDir, float b ) {
float fogAmount = 1.0 - exp(-t*b);
float sunAmount = max( dot(rd, lightDir), 0.0 );
vec3 fogColor = mix( vec3(0.3686, 0.2431, 0.4392), // blue
vec3(0.4, 0.7294, 0.9216), // yellow
pow(sunAmount,8.0) );
return mix( col, fogColor, fogAmount );
}
vec3 render(vec2 uv) {
bool useDof = !true;
//vec2 uv = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y;
vec2 uv = 2.0 * (fragCoord.xy/u_resolution.xy - 0.5);
uv.x *= u_resolution.x/u_resolution.y; // Correct for aspect ratio
//vec2 uv = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y;
float angle = -2.4 +u_time*0.4;
//angle = 0.;
// camera
vec3 camPos = vec3(2.*sin(angle), 1.,-2.*cos(angle));
vec3 camTarget = vec3(0., 0.0, 0.);
vec3 rayDir;
vec3 camPos = vec3(0., 3., -4.);
vec3 camTarget = vec3(0., 0., 0.);
vec3 rayDir;
if (useDof) {
rayDir = getCameraFov(uv, camPos, camTarget);
} else {
rayDir = getCameraRayDir(uv, camPos, camTarget);
}
vec3 col = mix(vec3(0.0824, 0.0275, 0.1882), vec3(0.2471, 0.3216, 0.0471), rayDir.y);
rayDir = getCameraRayDir2(uv, camPos, camTarget, 1.0);
}
vec3 col = vec3(0.051, 0.0667, 0.1529);
//vec3 col = vec3(0.0314, 0.0118, 0.1255) + rayDir.y * 0.4;
vec3 t = castRay(camPos, rayDir);
vec3 hitPos = vec3(0.);
vec3 t = castRay(camPos, rayDir, hitPos);
vec3 rd = rayDir;
if (t.z > 0.) {
vec3 nor = calcNormal(hitPos);
col = shading(hitPos, nor, rayDir , t.y);
float fogAmount = 0.04;
col = col*exp(-t.x*fogAmount) + applyFog(col, t.x, rd, vec3(0., .3, -1.), fogAmount) * (1.0-exp(-t.x*fogAmount));
rayDir = normalize(reflect(rayDir, nor));
vec3 rayOrigin = hitPos + (rayDir * 0.01);
vec3 t2 = castReflectedRay(rayOrigin, rayDir, hitPos);
vec3 pos = camPos + rayDir * t.x;
if (t.x > 0.) {
vec3 nor = calcNormal(pos);
col = shading(pos, nor, rayDir , t.y);
// apply fog
col = applyFog(col, t.x);
if (t2.z > 0.) {
hitPos = rayOrigin + rayDir * t2.x;
nor = calcNormal(hitPos);
col += 0.1 * shading(hitPos, nor, rayDir , t2.y);
/* rayDir = normalize(reflect(rayDir, nor));
rayOrigin = hitPos + (rayDir * 0.01);
vec3 t3 = castReflectedRay(rayOrigin, rayDir, hitPos);
if (t3.z > 0.) {
hitPos = rayOrigin + rayDir * t3.x;
nor = calcNormal(hitPos);
col += 0.025 * shading(hitPos, nor, rayDir , t3.y);
} */
}
}
// pixelColor*exp(-distance*b) + fogColor*(1.0-exp(-distance*b));
return col;
}
vec2 getUV(vec2 offset) {
vec2 uv = 2.0 *((gl_FragCoord.xy + offset*0.5)/u_resolution.xy - 0.5);
uv.x *= u_resolution.x/u_resolution.y; // Correct for aspect ratio
return uv;
}
void main()
{
vec2 uv = gl_FragCoord.xy;
vec3 finalColor = vec3(0.);
const float AA_SIZE = 4.;
const float AA_SIZE = 1.;
float count = 0.0;
/*
for (float aaY = 0.0; aaY < AA_SIZE; aaY++) {
for (float aaX = 0.0; aaX < AA_SIZE; aaX++) {
finalColor += getSceneColor(uv + vec2(aaX, aaY) / AA_SIZE);
for (float aaX = 0.0; aaX < AA_SIZE; aaX++) {
finalColor += render(getUV(vec2( aaX, aaY)));
count += 1.0;
}
}
finalColor /= count;
}
finalColor /= count; */
finalColor += render(getUV(vec2( 0.,0.)));
finalColor = postProcess(finalColor);