import {BAKED_SHAPE_GLSL} from './baked.glsl'; /** 원본 좌표의 무지개 색을 실제 입체와 공통 재질에서 함께 쓴다. */ export const ENDLESS_RAINBOW_GLSL=/* glsl */` vec3 endlessRainbow(vec3 p) { float t=clamp((p.x/1.2+1.0)*.5+p.y*.10+sin(p.z*2.4)*.025,0.0,1.0)*6.0; vec3 c0=vec3(1.0,.16,.32),c1=vec3(1.0,.49,.12),c2=vec3(1.0,.88,.19); vec3 c3=vec3(.30,.89,.45),c4=vec3(.13,.80,.98),c5=vec3(.27,.40,1.0),c6=vec3(.69,.22,.95); float f=smoothstep(0.0,1.0,fract(t)); if(t<1.0)return mix(c0,c1,f); if(t<2.0)return mix(c1,c2,f); if(t<3.0)return mix(c2,c3,f); if(t<4.0)return mix(c3,c4,f); if(t<5.0)return mix(c4,c5,f); return mix(c5,c6,smoothstep(0.0,1.0,t-5.0)); } `; /** 원본 입체 좌표에 고정한 별 홀로그램. 확대/회전/재절단에도 무늬가 미끄러지지 않는다. */ export const ENDLESS_CUT_GLSL=/* glsl */` vec3 endlessGrainHash(vec3 p) { p=fract(p*vec3(.1031,.1030,.0973)); p+=dot(p,p.yxz+33.33); return fract((p.xxy+p.yxx)*p.zyx); } // 면의 원본 좌표에서 별을 찾는다. 이웃 셀 전체의 자유 위치를 검사해 줄무늬를 피한다. vec3 endlessHologram(vec3 p,float projection) { vec2 plane=projection<1.5?p.yz:(projection<2.5?p.xz:p.xy); float depth=projection<1.5?p.x:(projection<2.5?p.y:p.z); // 깊이를 연속 이동으로 섞어 평행 단면의 별도 같은 열로 겹치지 않게 한다. vec2 q=plane*6.5+depth*vec2(2.17,-1.39),base=floor(q); float aa=max(length(fwidth(q))*.65,.003); float resolved=1.0-smoothstep(.45,1.0,length(fwidth(q))); vec3 result=vec3(0.0); for(int y=-1;y<=1;y++)for(int x=-1;x<=1;x++) { vec2 cell=base+vec2(float(x),float(y)); vec3 seed=endlessGrainHash(vec3(cell,7.31)); if(seed.z<.38)continue; vec2 delta=q-cell-seed.xy; float radius=mix(.19,.36,endlessGrainHash(vec3(cell,19.7)).x); float distanceToCenter=length(delta); if(distanceToCenter>radius+aa)continue; // 바깥 꼭짓점과 안쪽 꼭짓점을 잇는 직선의 극좌표 교차로 별 다섯 꼭짓점을 만든다. float angle=abs(mod(atan(delta.y,delta.x+1e-7)+seed.z*6.2831853+.6283185,1.2566371)-.6283185); float inner=.46,s=.5877853,c=.8090170; float edge=radius*inner*s/(inner*s*cos(angle)+(1.0-inner*c)*sin(angle)); float mask=(1.0-smoothstep(-aa,aa,distanceToCenter-edge))*resolved; if(mask>result.x)result=vec3(mask,seed.z,seed.x); } return result; } vec3 endlessFoil(float phase) { return mix(vec3(.82,.92,1.0),.5+.5*cos(phase+vec3(0.0,2.0943951,4.1887902)),.72); } vec3 endlessCutColor(vec3 rainbow) { return vec3(.012,.018,.042)+(vec3(1.0)-rainbow)*.16; } `; export const ENDLESS_GLSL=/* glsl */` ${BAKED_SHAPE_GLSL} ${ENDLESS_RAINBOW_GLSL} void jField(vec3 p,out vec3 sigma,out float scat,out vec3 albedo,out vec4 incl) { albedo=endlessRainbow(p); sigma=(1.0-albedo)*1.7+.08;scat=.6;incl=vec4(0.); } `;