|
フラグメントシェーダー 再帰呼び出し tree
https://gam0022.net/blog/2017/03/02/raymarching-fold/
距離関数TREEはループとabs関数で再帰呼び出しの代わりをしています。
※シェーダー言語GLSLは再帰呼び出しができないのでループで代用します。
DIM ST(2),C(3)
ASK BITMAP SIZE XSIZE,YSIZE
SET COLOR MODE "NATIVE"
SET POINT STYLE 1
SET WINDOW -XSIZE/MIN(XSIZE,YSIZE),XSIZE/MIN(XSIZE,YSIZE),-YSIZE/MIN(XSIZE,YSIZE),YSIZE/MIN(XSIZE,YSIZE)
FOR YY=0 TO YSIZE-1
FOR XX=0 TO XSIZE-1
LET X=(XX*2-XSIZE)/MIN(XSIZE,YSIZE)
LET Y=(YY*2-YSIZE)/MIN(XSIZE,YSIZE)
CALL VEC2(ST,X,Y)
IF DISTANCE(ST)>0 THEN
CALL VEC3(C,0,0,0)
ELSE
CALL VEC3(C,1,0,0)
END IF
CALL SETCOLOR(C(1),C(2),C(3))
PLOT POINTS:X,Y
NEXT XX
NEXT YY
END
EXTERNAL FUNCTION BOX(P(),B()) !距離関数 BOX
DIM D(2),DD(2)
FOR I=1 TO 2
LET D(I)=ABS(P(I))-B(I)
NEXT I
FOR I=1 TO 2
LET DD(I)=MAX(D(I),0)
NEXT I
LET BOX=LENGTH(DD)+MIN(MAX(D(1),D(2)),0)
END FUNCTION
EXTERNAL FUNCTION TREE(P()) !距離関数 TREE
DIM Q(2),SIZE(2)
LET SCALE=.8
CALL VEC2(SIZE,.1,.4)
LET D=BOX(P,SIZE)
MAT Q=P
FOR I=1 TO 7
LET Q(1)=ABS(P(1))
LET Q(2)=Q(2)-SIZE(2)
CALL ROTATE(Q,-RAD(45))
LET D=MIN(D,BOX(P,SIZE))
MAT P=Q
MAT SIZE=SCALE*SIZE
NEXT I
LET TREE=D
END FUNCTION
EXTERNAL FUNCTION DISTANCE(P())
LET P(2)=P(2)+.5
LET DISTANCE=TREE(P)
END FUNCTION
EXTERNAL SUB SETCOLOR(R,G,B)
SET COLOR COLORINDEX(CLAMP(R,0,1),CLAMP(G,0,1),CLAMP(B,0,1))
END SUB
EXTERNAL SUB ROTATE(A(),ANGLE)
DIM M(2,2)
LET M(1,1)=COS(ANGLE)
LET M(1,2)=-SIN(ANGLE)
LET M(2,1)=SIN(ANGLE)
LET M(2,2)=COS(ANGLE)
MAT A=A*M
END SUB
EXTERNAL FUNCTION STEP(A,X)
IF X<A THEN LET STEP=0 ELSE LET STEP=1
END FUNCTION
EXTERNAL SUB VEC2(A(),X,Y)
LET A(1)=X
LET A(2)=Y
END SUB
EXTERNAL SUB VEC3(A(),X,Y,Z)
LET A(1)=X
LET A(2)=Y
LET A(3)=Z
END SUB
EXTERNAL FUNCTION CLAMP(X,A,B)
LET CLAMP=MIN(B,MAX(X,A))
END FUNCTION
EXTERNAL FUNCTION LENGTH(A())
LET LENGTH=SQR(A(1)^2+A(2)^2)
END FUNCTION
|
|