rendauksen hienosäätöä

This commit is contained in:
2025-07-28 00:54:38 +03:00
parent 17d1ab8651
commit 84d9dbaa93
2 changed files with 145 additions and 131 deletions

View File

@ -57,18 +57,69 @@ float noise(vec2 p, float scale, int a)
hash( i + vec2(1.), a), u.x), u.y); hash( i + vec2(1.), a), u.x), u.y);
} }
// Hexagonal prism, circumcircle variant float sdHexPrism( vec3 p, vec2 h )
{
const vec3 k = vec3(-0.8660254, 0.5, 0.57735);
p = abs(p);
p.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy;
vec2 d = vec2(
length(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x),
p.z-h.y );
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
float fHexagonCircumcircle(vec3 p, vec2 h) { float fHexagonCircumcircle(vec3 p, vec2 h) {
vec3 q = abs(p); vec3 q = abs(p);
return max(q.y - h.y, max(q.x * sqrt(3.) * 0.5 + q.z * 0.5, q.z) - h.x); return max(q.y - h.y, max(q.x * sqrt(3.) * 0.5 + q.z * 0.5, q.z) - h.x);
//this is mathematically equivalent to this line, but less efficient:
//return max(q.y - h.y, max(dot(vec2(cos(PI/3), sin(PI/3)), q.zx), q.z) - h.x);
} }
float sdHex(vec3 pos, vec2 id, float angle) { float hexPylon(vec3 p, vec2 h) {//float r, float ht){
pos.xz *= rot2D(0.1);
float d1 = fHexagonCircumcircle(pos, vec2(0.86, 1.)); //vec3 p = vec3(p.x, p.z, p2.y);
return d1; vec3 b = vec3(h.x, h.y, h.x);
// Hexagon.
p.xz = abs(p.xz);
p.xz = vec2(p.x*.866025 + p.z*.5, p.z);
// The ".015" is a subtle rounding factor. Zero gives sharp edges,
// and larger numbers give a more rounded look.
return length(max(abs(p) - b + .015, 0.)) - .015;
}
#define zclamp(a) max(a,0.0) //Clamp negative values at zero
float DF_RoundedHex( vec3 p, vec2 h) //float width, float height)
{
float width = h.x;
float height = h.y;
//Modified version (smooth edges) of the exagon prism found here:
//https://iquilezles.org/articles/distfunctions
float smoothRadius = 0.05;
width -= smoothRadius*2.0;
//Hexagon prism constructed using X,Y,Z symmetry.
//Only quadrant 1 needs to be solved, but the joining diagonal to quadrant IV is also
//required for distance blending (see db).
p = abs(p);
//Hexagonal edge distances :
//Note : [.8666,0.5] = [sin(PI/3,cos(PI/3)] -> Hexagon edges rotation coeff (60 degrees).
float da = (p.x*0.866025+p.z*0.5)-width; //quadrant I diagonal edge distance
float db = (p.x*0.866025-p.z*0.5)-width; //quadrant IV diagonal edge distance (needed for blending)
float dc = p.z-width; //upper distance
vec3 d = zclamp(vec3(da,db,dc));
//Note: this is not an euclidian length, therefore this operation slightly distorts our distance field.
//Yet, it is harmless to convergence, and does the smoothing job quite well.
float dw = length(d)-smoothRadius; //hexagonal part smoothness (blending at 60 deg)
float dh = p.y-height;
//Now that we have xz distance(dw) and y distance (dh), we can compute the distance
//for the given isovalue (the smoothing radius).
//Note : internal distance (maxX,maxY,maxZ) is also used to genereate internal signed dist,
// helping convergence when overstepping (very frequent with domain repetition).
float externalDistance = length(zclamp(vec2(dh,dw)))-smoothRadius; //Smoothed, unsigned
float internalDistance = max(max(da,dc),dh); //Sharp, signed.
return min(externalDistance,internalDistance);
} }
float getScaledFFT(int index, float scale, float offset) { float getScaledFFT(int index, float scale, float offset) {
@ -135,16 +186,17 @@ vec3 mapScene(vec3 p) {
// Use axial coordinates as a stable hex ID // Use axial coordinates as a stable hex ID
float distFromCenter = hexDistance(hex.axial); float distFromCenter = hexDistance(hex.axial);
int fftIndex = int(clamp(distFromCenter * 1.0, 0.0, 511.0)); // tweak 15.0 to taste int fftIndex = int(clamp(distFromCenter +1.0, 0.0, 511.0)); // tweak 15.0 to taste
float fftVal = fft_output[fftIndex]; float fftVal = fft_output[fftIndex];
float hexHeight = 1.0 + fftVal * 1.0; float hexHeight = 1.0 + fftVal * 1.0;
// Rotate individual hex tiles if needed // Rotate individual hex tiles if needed
vec3 r = hex.local; vec3 r = hex.local;
//r.yz *= rot2D(1.0);
r.xz *= rot2D(0.5); r.xz *= rot2D(0.5);
float d1 = fHexagonCircumcircle(r, vec2(hexRadius, hexHeight)); float d1 = fHexagonCircumcircle(vec3(r.x,(r.y-hexHeight/2),r.z), vec2(hexRadius, hexHeight/2));
d = min(d,d1); d = min(d,d1);
return vec3(d, 0.0, 0.0); return vec3(d, 0.0, 0.0);
@ -156,13 +208,27 @@ vec3 mapScene(vec3 p) {
float rayMarch(vec3 ro, vec3 rd, int a) { float rayMarch(vec3 ro, vec3 rd, int a) {
vec3 d; vec3 d;
float t = 0.; // total distance travelled float t = 0.,ad,tmax=100.; // total distance travelled
const float tolerance = 0.00001;
const float Z_REPEAT_DIST = 1.;
// Raymarching // Raymarching
for (int i = 0; i < 100; i++) { for (int i = 0; i < 80; i++) {
d = mapScene(ro + rd * t); // Get distance to objects d = mapScene(ro + rd * t); // Get distance to objects
ad = abs(d.x);
if (ad < tolerance*(t*0.125 + 1.0) || t > tmax) break;
t += d.x; // "march" the ray t += d.x; // "march" the ray
if (d.x < 1e-3 || t > 500.) break;
} }
t -= Z_REPEAT_DIST*15.;
for( int i=0; i<80; i++ )
{
d = mapScene(ro + rd * t); // get distance to objects
ad = abs(d.x);
if (ad < tolerance*(t*0.00125) || t > tmax) break;
t += min(d.x, Z_REPEAT_DIST/5.0); // "march" the ray
}
if (ad >= tmax) t= - 1.0;
return t; return t;
} }
@ -179,7 +245,7 @@ float getLight(vec3 p, vec3 lightPos, float intensity, float shadow, vec3 n, flo
vec3 l = no(lightPos - p); vec3 l = no(lightPos - p);
float len = length( lightPos - p ); // Distance from the light to the surface point. float len = length( lightPos - p ); // Distance from the light to the surface point.
float dif = cl(dot(n, l)*intensity, 0., intensity) * 1.0 / (1.0 + atte*len), float dif = cl(dot(n, l)*intensity, 0., intensity) * 1.0 / (1.0 + atte*len),
d = rayMarch(p+n*.0025, l, 1); d = rayMarch(p+n*.025, l, 1);
if(d<length(lightPos-p)) dif *= shadow; if(d<length(lightPos-p)) dif *= shadow;
return dif; return dif;
} }
@ -194,14 +260,6 @@ float specular(vec3 normal,vec3 lightPos,vec3 rayOrigin,float specular) {
return pow(max(dot(reflect(rayOrigin,normal),lightPos),0.0),specular) * nrm; return pow(max(dot(reflect(rayOrigin,normal),lightPos),0.0),specular) * nrm;
} }
vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye) {
vec3 color = vec3(0.0, 0.1, 0.3) + diffuse(n,l,60.0) * vec3(0.11, 0.16, 0.18) * 0.3;
color -= vec3(0.73, 0.15, 0.66) * pow(cl(1.-dot(n, -eye), 0., 1.), .7);
color += vec3(specular(n,l,eye,60.0))*0.2;
return color;
}
vec3 applyFog(vec3 col, float t, vec3 rd, vec3 lightDir, float b ) { vec3 applyFog(vec3 col, float t, vec3 rd, vec3 lightDir, float b ) {
vec3 fogColor = mix( vec3(0.34, 0.11, 0.34), // blue vec3 fogColor = mix( vec3(0.34, 0.11, 0.34), // blue
@ -280,37 +338,10 @@ vec3 sceneGate(vec2 uv)
if(mat==0.) if(mat==0.)
col *= vec3(0.2, 0.3, 0.3) + addSpecular(n,rd,.5, 2.); col *= vec3(0.2, 0.3, 0.3) + addSpecular(n,rd,.5, 2.);
if(mat==1.)
col *= getSeaColor(p, n, no(vec3(0.0,0.3,0.8)),no(rd));
if(mat==2.)
col *= vec3(0.7, 0.7, 0.4) + noise (p.xz*3.+1.5, 0.1,0);
if(mat==3.)
col *= vec3(.8, .8, .5) + noise(p.xz*500.+1e5, .3,0);
if(mat==4.)
col *= vec3(0.0, 0.08, 0.11) + addSpecular(n,rd,0.3,0.7);
if(mat ==5.)
col = vec3(0.0, 0.08, 0.11);// * pow(cl(1. -dot(n, -rd), 0., 1.), .3);
if(mat == 6.)
col *= vec3(0.01, 0.04, 0.06) + addSpecular(n,rd,.1, 2.5);
} }
return postProcess(applyFog(col, d, rd, vec3(0., -.1, -1.), .01)); return postProcess(applyFog(col, d, rd, vec3(0., -.1, -1.), .01));
} }
void main() { void main() {
// Determine FFT bin index for current x position
// vec2 uv = (gl_FragCoord.xy * 2. - u_resolution.xy) / u_resolution.y;
// int index = int(floor((1.0+uv.x)*128.0));
// index = clamp(index, 0, 255);
//
// // Get the FFT energy (clamped to avoid NaNs or overflow)
// float energy = clamp(texture(u_fft_texture, vec2(index/255., 0.0)).r, 0.0, 1.0);
//
// float bar_height = energy;
// float fade = smoothstep(bar_height, bar_height + 0.02, 1.0 - uv.y);
//
// vec3 color = vec3(fade);
//
// o = vec4(color, 1.0);
o = vec4(sceneGate( (gl_FragCoord.xy * 2. - u_resolution.xy) / u_resolution.y), 1.); o = vec4(sceneGate( (gl_FragCoord.xy * 2. - u_resolution.xy) / u_resolution.y), 1.);
} }

View File

@ -2,15 +2,15 @@
#ifndef FRAGMENT_INL_ #ifndef FRAGMENT_INL_
# define FRAGMENT_INL_ # define FRAGMENT_INL_
# define VAR_fft_output "H" # define VAR_fft_output "H"
# define VAR_o "v" # define VAR_o "f"
# define VAR_syncs "a" # define VAR_syncs "a"
# define VAR_u_hexGridTex "l" # define VAR_u_hexGridTex "l"
const char *fragment_frag = const char *fragment_frag =
"#version 460\n" "#version 460\n"
"precision mediump float;" "precision mediump float;"
"out vec4 v;" "out vec4 f;"
"const float f=2.*acos(-1.),m=sqrt(5.)*.5+.5;" "const float m=2.*acos(-1.),v=sqrt(5.)*.5+.5;"
"layout(location=0)uniform float a[7];" "layout(location=0)uniform float a[7];"
"layout(location=8)uniform float H[512];" "layout(location=8)uniform float H[512];"
"uniform sampler2D l;" "uniform sampler2D l;"
@ -29,128 +29,111 @@ const char *fragment_frag =
"float v=sin(.5),f=cos(.5);" "float v=sin(.5),f=cos(.5);"
"return mat2(f,-v,v,f);" "return mat2(f,-v,v,f);"
"}" "}"
"float s(vec2 v)" "float s(vec3 v,vec2 m)"
"{"
"v=50.*fract(v*.3183099);"
"return fract(v.x*v.y*(v.x+v.y));"
"}"
"float s(vec2 v,float x)"
"{"
"vec2 f=floor(v);"
"v=fract(v);"
"v=v*v*(3.-2.*v);"
"return-x+x*mix(mix(s(f+vec2(0)),s(f+vec2(1,0)),v.x),mix(s(f+vec2(0,1)),s(f+vec2(1)),v.x),v.y);"
"}"
"float s(vec3 v,vec2 f)"
"{" "{"
"v=abs(v);" "v=abs(v);"
"return max(v.y-f.y,max(v.x*sqrt(3.)*.5+v.z*.5,v.z)-f.x);" "return max(v.y-m.y,max(v.x*sqrt(3.)*.5+v.z*.5,v.z)-m.x);"
"}" "}\n"
"#define zclamp(a)max(a,0.0)\n"
"struct HexData{vec3 local;vec2 axial;};" "struct HexData{vec3 local;vec2 axial;};"
"HexData t(vec3 v)" "HexData t(vec3 v)"
"{" "{"
"float f=sqrt(3.)/3.*v.x-1./3.*v.z,i=2./3.*v.z,x=round(f),m=round(i),l=round(-f-i),d=abs(x-f),s=abs(m-i);" "float f=sqrt(3.)/3.*v.x-1./3.*v.z,m=2./3.*v.z,x=round(f),l=round(m),a=round(-f-m),d=abs(x-f),p=abs(l-m);"
"f=abs(l+f+i);" "f=abs(a+f+m);"
"if(d>s&&d>f)" "if(d>p&&d>f)"
"x=-m-l;" "x=-l-a;"
"else if(s>f)" "else if(p>f)"
"m=-x-l;" "l=-x-a;"
"f=sqrt(3.)*(x+m*.5);" "f=sqrt(3.)*(x+l*.5);"
"i=1.5*m;" "m=1.5*l;"
"HexData r;" "HexData r;"
"r.local=v-vec3(f,0,i);" "r.local=v-vec3(f,0,m);"
"r.axial=vec2(x,m);" "r.axial=vec2(x,l);"
"return r;" "return r;"
"}" "}"
"struct HexData{vec3 local;vec2 axial;};" "struct HexData{vec3 local;vec2 axial;};"
"float t(vec2 v)" "float s(vec2 v)"
"{" "{"
"float f=v.x,m=v.y;" "float m=v.x,f=v.y;"
"return max(abs(f),max(abs(m),abs(-f-m)));" "return max(abs(m),max(abs(f),abs(-m-f)));"
"}" "}"
"vec3 x(vec3 v)" "vec3 p(vec3 v)"
"{" "{"
"float f=1e9;" "float f=1e9;"
"HexData m=t(vec3(v.x,v.y-10.,v.z));" "HexData m=t(vec3(v.x,v.y-10.,v.z));"
"float l=1.+H[int(clamp(s(m.axial)+1.,0.,511.))];"
"v=m.local;" "v=m.local;"
"v.xz*=s();" "v.xz*=s();"
"float x=s(v,vec2(.83,1.+H[int(clamp(t(m.axial),0.,511.))]));" "l=s(vec3(v.x,v.y-l/2,v.z),vec2(.83,l/2));"
"f=min(f,x);" "f=min(f,l);"
"return vec3(f,0,0);" "return vec3(f,0,0);"
"}" "}"
"float s(vec3 v,vec3 f,int m)" "float p(vec3 v,vec3 f,int m)"
"{" "{"
"vec3 l;" "vec3 l;"
"float i=0.;" "float x=0.,r;"
"for(int r=0;r<100;r++)" "for(int m=0;m<80;m++)"
"{" "{"
"l=x(v+f*i);" "l=p(v+f*x);"
"i+=l.x;" "r=abs(l.x);"
"if(l.x<.001||i>5e2)" "if(r<1e-5*(x*.125+1.)||x>1e2)"
"break;" "break;"
"x+=l.x;"
"}" "}"
"return i;" "x-=15.;"
"for(int m=0;m<80;m++)"
"{"
"l=p(v+f*x);"
"r=abs(l.x);"
"if(r<x*.00125*1e-5||x>1e2)"
"break;"
"x+=min(l.x,.2);"
"}"
"if(r>=1e2)"
"x=-1.;"
"return x;"
"}" "}"
"vec3 w(vec3 v)" "vec3 x(vec3 v)"
"{" "{"
"vec2 f=vec2(.01,0);" "vec2 m=vec2(.01,0);"
"return s(x(v).x-vec3(x(v-f.xyy).x,x(v-f.yxy).x,x(v-f.yyx)));" "return s(p(v).x-vec3(p(v-m.xyy).x,p(v-m.yxy).x,p(v-m.yyx)));"
"}" "}"
"float s(vec3 v,vec3 f,float m,float l,vec3 x,float i)" "float p(vec3 v,vec3 f,float m,float l,vec3 x,float y)"
"{" "{"
"vec3 y=s(f-v);" "vec3 a=s(f-v);"
"m=s(dot(x,y)*m,0.,m)/(1.+i*length(f-v));" "m=s(dot(x,a)*m,0.,m)/(1.+y*length(f-v));"
"if(s(v+x*.0025,y,1)<length(f-v))" "if(p(v+x*.025,a,1)<length(f-v))"
"m*=l;" "m*=l;"
"return m;" "return m;"
"}" "}"
"float s(vec3 v,vec3 f,vec3 m,float x)" "float p(vec3 v,vec3 m,vec3 f)"
"{" "{"
"return pow(max(dot(reflect(m,v),f),0.),x)*((x+8.)/(acos(-1.)*8.));" "float l=pow(10.,2.);"
"return pow(max(dot(reflect(f,v),m),0.),l)*((l+8.)/(acos(-1.)*8.));"
"}" "}"
"vec3 s(vec3 v,vec3 f,vec3 m,vec3 x)" "vec3 p(vec2 v,vec3 f,float m)"
"{"
"return vec3(0,.1,.3)+pow(dot(f,m)*.4+.6,60.)*vec3(.11,.16,.18)*.3-vec3(.73,.15,.66)*pow(s(1.-dot(f,-x),0.,1.),.7)+vec3(s(f,m,x,60.))*.2;"
"}"
"vec3 s(vec2 v,vec3 f,float m)"
"{" "{"
"f=s(vec3(0,0,-5)-f);" "f=s(vec3(0,0,-5)-f);"
"vec3 x=s(cross(vec3(0,1,0),f));" "vec3 l=s(cross(vec3(0,1,0),f));"
"return s(f*m+v.x*x+v.y*cross(f,x));" "return s(f*m+v.x*l+v.y*cross(f,l));"
"}" "}"
"vec3 s(vec3 v,vec3 f,float m,float x)" "vec3 p(vec2 v)"
"{" "{"
"return vec3(s(v,s(vec3(0,.3,.8)),s(f),pow(10.,x)))*m;" "vec3 f=vec3(0,25,25),m=p(v,f,s(1.,2.,25.)),l=vec3(0);"
"}" "float a=p(f,m,0),r=0.;"
"vec3 w(vec2 v)" "if(a<5e2)"
"{"
"vec3 f=vec3(0,25,25),m=s(v,f,s(1.,2.,25.)),i=vec3(0);"
"float l=s(f,m,0),r=0.;"
"if(l<5e2)"
"{" "{"
"vec3 v=f+m*l,y=w(v);" "vec3 v=f+m*a,i=x(v);"
"r=x(v).y;" "r=p(v).y;"
"i=i+vec3(.82,.5,.9)*s(v,vec3(10,15,25),1.,.2,y,1e-10)+vec3(.79,.66,.43)*s(v,vec3(4,2,-15),1.,1.,y,1e-10)+vec3(0,.06,.7)*s(v,vec3(0,0,5),s((d-29.)*1e2,0.,50.),0.,y,3.1)+vec3(.29,.28,.33)*s(dot(y,s(vec3(0,1,10))),0.,1.);" "l=l+vec3(.82,.5,.9)*p(v,vec3(10,15,25),1.,.2,i,1e-10)+vec3(.79,.66,.43)*p(v,vec3(4,2,-15),1.,1.,i,1e-10)+vec3(0,.06,.7)*p(v,vec3(0,0,5),s((d-29.)*1e2,0.,50.),0.,i,3.1)+vec3(.29,.28,.33)*s(dot(i,s(vec3(0,1,10))),0.,1.);"
"if(r==0.)" "if(r==0.)"
"i*=vec3(.2,.3,.3)+s(y,m,.5,2.);" "l*=vec3(.2,.3,.3)+vec3(p(i,s(vec3(0,.3,.8)),s(m)))*.5;"
"if(r==1.)"
"i*=s(v,y,s(vec3(0,.3,.8)),s(m));"
"if(r==2.)"
"i*=vec3(.7,.7,.4)+s(v.xz*3.+1.5,.1);"
"if(r==3.)"
"i*=vec3(.8,.8,.5)+s(v.xz*5e2+1e5,.3);"
"if(r==4.)"
"i*=vec3(0,.08,.11)+s(y,m,.3,.7);"
"if(r==5.)"
"i=vec3(0,.08,.11);"
"if(r==6.)"
"i*=vec3(.01,.04,.06)+s(y,m,.1,2.5);"
"}" "}"
"return smoothstep(0.,1.,pow(mix(i,mix(vec3(.34,.11,.34),vec3(.93,.37,.16),pow(max(dot(m,vec3(0,-.1,-1)),0.),8.)),1.-exp(-l*.01))*vec3(.9,.8,.7),vec3(.45)));" "return smoothstep(0.,1.,pow(mix(l,mix(vec3(.34,.11,.34),vec3(.93,.37,.16),pow(max(dot(m,vec3(0,-.1,-1)),0.),8.)),1.-exp(-a*.01))*vec3(.9,.8,.7),vec3(.45)));"
"}" "}"
"void main()" "void main()"
"{" "{"
"v=vec4(w((gl_FragCoord.xy*2.-n.xy)/n.y),1);" "f=vec4(p((gl_FragCoord.xy*2.-n.xy)/n.y),1);"
"}"; "}";
#endif // FRAGMENT_INL_ #endif // FRAGMENT_INL_