|
ネット上のサンプルを基にレイマーチング法で球?をレンダリングしています。
二進モードで実行してください。
PUBLIC NUMERIC EPS,OFFSET
DIM POS(3),CPOS(3),CDIR(3),CUP(3),CSIDE(3),RAY(3),R1(3),R2(3),R3(3),LIGHTDIR(3)
DIM NORMAL(3),COL(3),C(3),V(3),R(3),CC(3),CAMERA(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)
CALL VEC3(CDIR,0,0,1)
CALL VEC3(CUP,0,1,0)
CALL VEC3(CAMERA,0,1,0)
MAT CSIDE=CROSS(CDIR,CUP)
LET EPS=.01
LET TARGETDEPTH=1.3
LET OFFSET = EPS * 100
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)
MAT R1=X*CSIDE
MAT R2=Y*CUP
MAT R3=TARGETDEPTH*CDIR
MAT RAY=R1
MAT RAY=RAY+R2
MAT RAY=RAY+R3
MAT CPOS=CAMERA
CALL NORMALIZE(RAY)
LET ALPHA=1
MAT COL=ZER
FOR I=0 TO 2
CALL GETRAYCOLOR(CPOS, RAY, POS, NORMAL, HIT,CC)
MAT C=ALPHA*CC
MAT COL=COL+C
LET ALPHA=ALPHA*.3
CALL REFLECT(RAY, NORMAL ,R)
CALL NORMALIZE(R)
MAT RAY=R
MAT CPOS=OFFSET*NORMAL
MAT CPOS=CPOS+POS
IF HIT=0 THEN EXIT FOR
NEXT I
CALL SETCOLOR(COL(1),COL(2),COL(3))
PLOT POINTS:X,Y
NEXT XX
NEXT YY
END
EXTERNAL SUB ONREP(P(), INTERVAL,PP())
DIM Q(2)
LET Q(1)=MOD(P(1),INTERVAL)- INTERVAL * 0.5
LET Q(2)=MOD(P(3),INTERVAL)- INTERVAL * 0.5
CALL VEC3(PP,Q(1),P(2),Q(2))
END SUB
EXTERNAL FUNCTION SPHEREDIST(P(),R)
DIM PP(3)
CALL ONREP(P,3,PP)
LET SPHEREDIST=LENGTH(PP)-R
END FUNCTION
EXTERNAL FUNCTION FLOORDIST(P())
DIM V(3)
CALL VEC3(V,0,1,0)
LET FLOORDIST=DOT(P,V)+1
END FUNCTION
EXTERNAL SUB MINVEC4(A(),B(),C())
IF A(4)<B(4) THEN MAT C=A ELSE MAT C=B
END SUB
EXTERNAL FUNCTION CHECKEREDPATTERN(P())
LET U=1-IP(MOD(P(1),2))
LET V=1-IP(MOD(P(3),2))
IF U=1 AND V<1 OR U<1 AND V=1 THEN LET CHECKEREDPATTERN=.2 ELSE LET CHECKEREDPATTERN=1
END FUNCTION
EXTERNAL SUB HSV2RGB(C(),RGB())
DIM K(4),P(3)
CALL VEC4(K,1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0)
FOR I=1 TO 3
LET P(I)=ABS(FRACT(C(1)+K(I))*6-K(4))
NEXT I
FOR I=1 TO 3
LET RGB(I)=C(3)*MIX(K(1),CLAMP(P(I)-K(1),0,1),C(2))
NEXT I
END SUB
EXTERNAL FUNCTION SCENEDIST(P())
LET SCENEDIST=MIN(SPHEREDIST(P,1),FLOORDIST(P))
END FUNCTION
EXTERNAL SUB SCENECOLOR(P(),PP())
DIM A(4),B(4),C(3),COL(3)
CALL VEC3(C,(P(3) + P(1)) / 9.0, 1.0, 1.0 )
CALL HSV2RGB(C,COL)
CALL VEC4(A,COL(1),COL(2),COL(3), SPHEREDIST(P,1.0))
LET L=CHECKEREDPATTERN(P)
CALL VEC4(B,.5*L,.5*L,.5*L,FLOORDIST(P))
CALL MINVEC4(A,B,PP)
END SUB
EXTERNAL SUB GETNORMAL(P(),N())
DIM X1(3),X2(3),Y1(3),Y2(3),Z1(3),Z2(3),PX1(3),PX2(3),PY1(3),PY2(3),PZ1(3),PZ2(3)
CALL VEC3(X1,EPS,0,0)
CALL VEC3(X2,-EPS,0,0)
MAT PX1=P+X1
MAT PX2=P+X2
CALL VEC3(Y1,0,EPS,0)
CALL VEC3(Y2,0,-EPS,0)
MAT PY1=P+Y1
MAT PY2=P+Y2
CALL VEC3(Z1,0,0,EPS)
CALL VEC3(Z2,0,0,-EPS)
MAT PZ1=P+Z1
MAT PZ2=P+Z2
CALL VEC3(N,SCENEDIST(PX1)-SCENEDIST(PX2),SCENEDIST(PY1)-SCENEDIST(PY2),SCENEDIST(PZ1)-SCENEDIST(PZ2))
CALL NORMALIZE(N)
END SUB
EXTERNAL FUNCTION GETSHADOW(RO(),RD())
DIM RAY(3),DMY(3)
LET R=1
LET SHADOWCOEF=.5
FOR T=0 TO 49
MAT RAY=C*RD
MAT RAY=RAY+RO
LET H=SCENEDIST(RAY)
IF H<EPS THEN
LET GETSHADOW=SHADOWCOEF
EXIT FUNCTION
END IF
IF C<>0 THEN LET R=MIN(R,H*16/C)
LET C=C+H
NEXT T
LET GETSHADOW=1-SHADOWCOEF+R*SHADOWCOEF
END FUNCTION
EXTERNAL SUB GETRAYCOLOR(ORIGIN(),RAY(),POS(),NORMAL(),HIT,COL())
DIM P(3),S(3),V(3),LIGHTDIR(3),CL(4)
MAT POS=ORIGIN
CALL VEC3(LIGHTDIR,-0.48666426339228763, 0.8111071056538127, -0.3244428422615251)
FOR I=0 TO 63
LET DIST = SCENEDIST(POS)
LET DEPTH =DEPTH+ DIST
MAT POS=DEPTH*RAY
MAT POS=POS+ORIGIN
IF ABS(DIST)<EPS THEN EXIT FOR
NEXT I
IF ABS(DIST)<EPS THEN
CALL GETNORMAL(POS,NORMAL)
LET DIFFUSE = CLAMP(DOT(LIGHTDIR, NORMAL), 0.1, 1.0 )
CALL REFLECT(LIGHTDIR, NORMAL,V)
LET SPECULAR = CLAMP(DOT(V,RAY),0, 1)^10
CALL VEC3(S,SPECULAR*.8,SPECULAR*.8,SPECULAR*.8)
MAT P=OFFSET*NORMAL
MAT P=P+POS
LET SHADOW = GETSHADOW(P, LIGHTDIR)
CALL SCENECOLOR(POS ,CL)
FOR I=1 TO 3
LET COL(I)=CL(I)
NEXT I
MAT COL=DIFFUSE*COL
MAT COL=COL+S
MAT COL=(MAX(0.5,SHADOW))*COL
LET HIT = 1
ELSE
MAT COL=ZER
LET HIT=0
END IF
LET K= CLAMP(.05 * DEPTH, 0, .6)^2
FOR I=1 TO 3
LET COL(I)=COL(I)-K
NEXT I
END SUB
EXTERNAL SUB REFLECT(I(),N(),V())
DIM C(3),VV(3)
LET K=2*DOT(N,I)
MAT C=K*N
MAT VV=I-C
MAT V=VV
END SUB
EXTERNAL SUB NORMALIZE(RAY())
LET S=LENGTH(RAY)
IF S<>0 THEN
MAT RAY=(1/S)*RAY
ELSE
MAT RAY=ZER
END IF
END SUB
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 VEC2(V(),X,Y)
LET V(1)=X
LET V(2)=Y
END SUB
EXTERNAL SUB VEC3(V(),X,Y,Z)
LET V(1)=X
LET V(2)=Y
LET V(3)=Z
END SUB
EXTERNAL SUB VEC4(V(),X,Y,Z,W)
LET V(1)=X
LET V(2)=Y
LET V(3)=Z
LET V(4)=W
END SUB
EXTERNAL FUNCTION LENGTH(A())
FOR I=1 TO UBOUND(A,1)
LET S=S+A(I)^2
NEXT I
LET LENGTH=SQR(S)
END FUNCTION
EXTERNAL FUNCTION CLAMP(X,A,B)
LET CLAMP=MIN(B,MAX(X,A))
END FUNCTION
EXTERNAL FUNCTION FRACT(X)
LET FRACT=FP(X)
END FUNCTION
EXTERNAL FUNCTION MIX(X,Y,A)
LET MIX=X*(1-A)+Y*A
END FUNCTION
上記プログラムの原版はこちら(※マウスでいじれます)
GLSL言語でのGPUによるレンダリングです(WebGL)
※凄すぎるので上記BASICプログラム実行前のアクセス禁止です(笑)
|
|