投稿者:しばっち
投稿日:2018年 4月 9日(月)20時11分57秒
|
|
|
ネット上のサンプルを基にしてレイマーチング法(ray marching)で箱(box)をレンダリングしています。
レイ・マーチング法はレイ・トレーシング法(ray tracing)の一種です。
※厳密にはレイマーチング法の中のスフィアトレーシング法(sphere tracing)です。
二進モードで実行してください。
DIM P(2),V(2),CPOS(3),CDIR(3),CUP(3),CSIDE(3),RAY(3),R1(3),R2(3),R3(3),LIGHTDIR(3),RPOS(3)
DIM NORMAL(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(CPOS,0,0,2)
CALL VEC3(LIGHTDIR,-.577,.577,.577)
LET ANG=60 !'視野角
LET FOV=ANG*.5*PI/180
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 VEC3(RAY,SIN(FOV)*X,SIN(FOV)*Y,-COS(FOV))
CALL NORMALIZE(RAY)
LET DISTANCE=0
LET RLEN=0
MAT RPOS=CPOS
FOR I=0 TO 127
LET DISTANCE=DISTANCEFUNC(RPOS)
LET RLEN=RLEN+DISTANCE
MAT RPOS=RLEN*RAY
MAT RPOS=RPOS+CPOS
IF ABS(DISTANCE)<.001 THEN EXIT FOR
NEXT I
IF ABS(DISTANCE)<.001 THEN
CALL GETNORMAL(RPOS,NORMAL)
LET DIFF=CLAMP(DOT(LIGHTDIR,NORMAL),.1,1)
CALL SETCOLOR(DIFF,DIFF,DIFF)
ELSE
CALL SETCOLOR(0,0,0)
END IF
PLOT POINTS:X,Y
NEXT XX
NEXT YY
END
EXTERNAL SUB TRANS(P())
FOR I=1 TO 3
LET P(I)=MOD(P(I),4)-2
NEXT I
END SUB
EXTERNAL FUNCTION DISTANCEFUNC(PP())
DIM V(3),A(3),B(3),P(3)
CALL VEC3(B,.5,.5,.5)
MAT P=PP
CALL TRANS(P)
CALL VABS(V,P)
MAT V=V-B
CALL NMAX(A,V,0)
LET DISTANCEFUNC=LENGTH(A)-.5
END FUNCTION
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)
LET D=.0001
CALL VEC3(X1,D,0,0)
CALL VEC3(X2,-D,0,0)
MAT PX1=P+X1
MAT PX2=P+X2
CALL VEC3(Y1,0,D,0)
CALL VEC3(Y2,0,-D,0)
MAT PY1=P+Y1
MAT PY2=P+Y2
CALL VEC3(Z1,0,0,D)
CALL VEC3(Z2,0,0,-D)
MAT PZ1=P+Z1
MAT PZ2=P+Z2
CALL VEC3(N,DISTANCEFUNC(PX1)-DISTANCEFUNC(PX2),DISTANCEFUNC(PY1)-DISTANCEFUNC(PY2),DISTANCEFUNC(PZ1)-DISTANCEFUNC(PZ2))
CALL NORMALIZE(N)
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 VEC3(V(),X,Y,Z)
LET V(1)=X
LET V(2)=Y
LET V(3)=Z
END SUB
EXTERNAL FUNCTION LENGTH(A())
LET LENGTH=SQR(A(1)^2+A(2)^2+A(3)^2)
END FUNCTION
EXTERNAL FUNCTION CLAMP(X,A,B)
LET CLAMP=MIN(B,MAX(X,A))
END FUNCTION
EXTERNAL SUB VABS(A(),B())
FOR I=1 TO 3
LET A(I)=ABS(B(I))
NEXT I
END SUB
EXTERNAL SUB NMAX(A(),B(),N)
FOR I=1 TO 3
LET A(I)=MAX(B(I),N)
NEXT I
END SUB
|
|
|
投稿者:しばっち
投稿日:2018年 4月 9日(月)20時12分42秒
|
|
|
ネット上のサンプルを基にレイマーチング法によりトーラス(ドーナツ型)をレンダリングしています。
二進モードで実行してください。
DIM CPOS(3),CDIR(3),CUP(3),CSIDE(3),RAY(3),R1(3),R2(3),R3(3),LIGHTDIR(3),RPOS(3),HALF(3)
DIM NORMAL(3),DPOS(3),COL(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(CPOS,0,5,5) !'カメラ
CALL VEC3(CDIR,0,-.707,-.707) !'カメラの向き(視線)
CALL VEC3(CUP,0,.707,-.707) !'カメラの上方向
CALL VEC3(LIGHTDIR,-.577,.577,.577)
MAT CSIDE=CROSS(CDIR,CUP) !'横方向
LET TARGETDEPTH=1 !'フォーカス深度
CALL NORMALIZE(LIGHTDIR)
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
CALL NORMALIZE(RAY) !'レイの定義
LET DIST=0
LET RLEN=0
MAT RPOS=CPOS
LET SHADOW=1
FOR I=0 TO 255 !'マーチングループ(marching loop)
CALL DISTANCE(RPOS,DIST,COL)
LET RLEN=RLEN+DIST
MAT RPOS=RLEN*RAY
MAT RPOS=RPOS+CPOS
IF DIST<.001 THEN EXIT FOR
NEXT I
IF ABS(DIST)<.001 THEN !'レイとの距離
CALL GETNORMAL(RPOS,NORMAL)
MAT HALF=LIGHTDIR-RAY
CALL NORMALIZE(HALF)
LET DIFF=CLAMP(DOT(LIGHTDIR,NORMAL),.1,1)
LET SPEC=CLAMP(DOT(HALF,NORMAL),0,1)^50
MAT DPOS=(1/1000)*NORMAL
MAT DPOS=DPOS+RPOS
LET SHADOW=GENSHADOW(DPOS,LIGHTDIR) !'シャドウ
FOR I=1 TO 3
LET COL(I)=COL(I)*DIFF+SPEC
NEXT I
ELSE
CALL VEC3(COL,0,0,0)
END IF
FOR I=1 TO 3
LET COL(I)=COL(I)*MAX(.5,SHADOW)
NEXT I
CALL SETCOLOR(COL(1),COL(2),COL(3))
PLOT POINTS:X,Y
NEXT XX
NEXT YY
END
EXTERNAL FUNCTION TORUS(P()) !'距離関数(トーラス)
DIM T(3),R(3)
CALL VEC2(T,3,1)
CALL VEC2(R,LENGTH2(P(1),P(3),0)-T(1),P(2))
LET TORUS=LENGTH(R)-T(2)
END FUNCTION
EXTERNAL FUNCTION FLOOR(P()) !'距離関数(床)
DIM V(3)
CALL VEC3(V,0,1,0)
LET FLOOR=DOT(P,V)+1
END FUNCTION
EXTERNAL SUB DISTANCE(P(),DIST,COL())
LET D1=TORUS(P)
LET D2=FLOOR(P)
IF D1<D2 THEN
LET DIST=D1
CALL VEC3(COL,1,1,.25) !'色
ELSE
LET DIST=D2
LET U=1-IP(MOD(P(1),2))
LET V=1-IP(MOD(P(3),2))
IF U+V=1 THEN CALL VEC3(COL,.7,.7,.7) ELSE CALL VEC3(COL,1,1,1) !'色(市松模様)
END IF
END SUB
EXTERNAL SUB NMAX(A(),B(),N)
FOR I=1 TO 3
LET A(I)=MAX(B(I),N)
NEXT I
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),DMY(3)
LET D=.0001
CALL VEC3(X1,D,0,0)
CALL VEC3(X2,-D,0,0)
MAT PX1=P+X1
MAT PX2=P+X2
CALL VEC3(Y1,0,D,0)
CALL VEC3(Y2,0,-D,0)
MAT PY1=P+Y1
MAT PY2=P+Y2
CALL VEC3(Z1,0,0,D)
CALL VEC3(Z2,0,0,-D)
MAT PZ1=P+Z1
MAT PZ2=P+Z2
CALL DISTANCE(PX1,XS,DMY)
CALL DISTANCE(PX2,XE,DMY)
CALL DISTANCE(PY1,YS,DMY)
CALL DISTANCE(PY2,YE,DMY)
CALL DISTANCE(PZ1,ZS,DMY)
CALL DISTANCE(PZ2,ZE,DMY)
CALL VEC3(N,XS-XE,YS-YE,ZS-ZE)
CALL NORMALIZE(N)
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 VABS(A(),B())
FOR I=1 TO 3
LET A(I)=ABS(B(I))
NEXT I
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 VEC3(V(),X,Y,Z)
LET V(1)=X
LET V(2)=Y
LET V(3)=Z
END SUB
EXTERNAL SUB VEC2(A(),X,Y)
LET A(1)=X
LET A(2)=Y
END SUB
EXTERNAL FUNCTION LENGTH(A()) !'長さ
LET LENGTH=SQR(A(1)^2+A(2)^2+A(3)^2)
END FUNCTION
EXTERNAL FUNCTION LENGTH2(X,Y,Z)
LET LENGTH2=SQR(X^2+Y^2+Z^2)
END FUNCTION
EXTERNAL FUNCTION CLAMP(X,A,B)
LET CLAMP=MIN(B,MAX(X,A))
END FUNCTION
EXTERNAL FUNCTION GENSHADOW(RO(),RD()) !'シャドウ
DIM RAY(3),DMY(3)
LET R=1
LET C=.001
LET SHADOWCOEF=.5
FOR T=0 TO 49
MAT RAY=C*RD
MAT RAY=RAY+RO
CALL DISTANCE(RAY,H,DMY)
IF H<.001 THEN
LET GENSHADOW=SHADOWCOEF
EXIT FUNCTION
END IF
LET R=MIN(R,H*32/C)
LET C=C+H
NEXT T
LET GENSHADOW=1-SHADOWCOEF+R*SHADOWCOEF
END FUNCTION
|
|
|
投稿者:しばっち
投稿日:2018年 4月 9日(月)20時13分32秒
|
|
|
ネット上のサンプルを基にレイマーチング法で鉄骨?をレンダリングしています。
二進モードで実行してください。
DIM P(2),V(2),CPOS(3),CDIR(3),CUP(3),CSIDE(3),RAY(3),R1(3),R2(3),R3(3),LIGHTDIR(3),DPOS(3)
DIM NORMAL(3),COL(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(CPOS,5,5,.5)
CALL VEC3(CUP,.1,.4,0)
CALL NORMALIZE(CUP)
CALL VEC3(CDIR,-1,0,0)
MAT CDIR=CROSS(CUP,CDIR)
CALL VEC3(LIGHTDIR,1,1,-2)
CALL NORMALIZE(LIGHTDIR)
MAT CSIDE=CROSS(CDIR,CUP)
LET TARGETDEPTH=1
LET EPS=.001
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
CALL NORMALIZE(RAY)
LET DEPTH=0
MAT DPOS=CPOS
FOR I=0 TO 63
LET DIST=DISTANCEFUNC(DPOS)
LET DEPTH=DEPTH+DIST
MAT DPOS=DEPTH*RAY
MAT DPOS=DPOS+CPOS
IF ABS(DIST)<EPS THEN EXIT FOR
NEXT I
IF ABS(DIST)<EPS THEN
CALL GETNORMAL(DPOS,NORMAL)
LET DIFFUSE=CLAMP(DOT(LIGHTDIR,NORMAL),.1,1)
CALL VEC3(COL,1,.1,.1)
MAT COL=DIFFUSE*COL
CALL SETCOLOR(COL(1)+.05*DEPTH,COL(2)+.05*DEPTH,COL(3)+.05*DEPTH)
ELSE
CALL SETCOLOR(.05*DEPTH,.05*DEPTH,.05*DEPTH)
END IF
PLOT POINTS:X,Y
NEXT XX
NEXT YY
END
EXTERNAL SUB ONREP(P(), INTERVAL,PP())
FOR I=1 TO UBOUND(P,1)
LET PP(I)=MOD(P(I),INTERVAL)- INTERVAL * 0.5
NEXT I
END SUB
EXTERNAL FUNCTION BARDIST(X,Y,INTERVAL,WIDTH)
DIM PP(2),P(2)
CALL VEC2(P,X,Y)
CALL ONREP(P, INTERVAL,PP)
CALL VABS(PP)
FOR I=1 TO 2
LET PP(I)=PP(I)-WIDTH
NEXT I
CALL VMAX(PP,0)
LET BARDIST=LENGTH(PP)
END FUNCTION
EXTERNAL FUNCTION TUBEDIST(X,Y, INTERVAL, WIDTH)
DIM PP(2),P(2)
CALL VEC2(P,X,Y)
CALL ONREP(P, INTERVAL,PP)
LET TUBEDIST=LENGTH(PP) - WIDTH
END FUNCTION
EXTERNAL FUNCTION DISTANCEFUNC(P())
LET BARX=BARDIST(P(2),P(3),1,.1)
LET BARY=BARDIST(P(1),P(3),1,.1)
LET BARZ=BARDIST(P(1),P(2),1,.1)
LET TUBEX=TUBEDIST(P(2),P(3),.1,.025)
LET TUBEY=TUBEDIST(P(1),P(3),.1,.025)
LET TUBEZ=TUBEDIST(P(1),P(2),.1,.025)
LET DISTANCEFUNC=MAX(MAX(MAX(MIN(MIN(BARX, BARY),BARZ), -TUBEX), -TUBEY), -TUBEZ)
END FUNCTION
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)
LET D=.001
CALL VEC3(X1,D,0,0)
CALL VEC3(X2,-D,0,0)
MAT PX1=P+X1
MAT PX2=P+X2
CALL VEC3(Y1,0,D,0)
CALL VEC3(Y2,0,-D,0)
MAT PY1=P+Y1
MAT PY2=P+Y2
CALL VEC3(Z1,0,0,D)
CALL VEC3(Z2,0,0,-D)
MAT PZ1=P+Z1
MAT PZ2=P+Z2
CALL VEC3(N,DISTANCEFUNC(PX1)-DISTANCEFUNC(PX2),DISTANCEFUNC(PY1)-DISTANCEFUNC(PY2),DISTANCEFUNC(PZ1)-DISTANCEFUNC(PZ2))
CALL NORMALIZE(N)
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 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 SUB VABS(A())
FOR I=1 TO UBOUND(A,1)
LET A(I)=ABS(A(I))
NEXT I
END SUB
EXTERNAL SUB VMAX(A(),N)
FOR I=1 TO UBOUND(A,1)
LET A(I)=MAX(A(I),N)
NEXT I
END SUB
このプログラムの原版はこちら(※マウスでいじれます)
GLSL言語でのGPUによるレンダリングです(WebGL)
※凄すぎるので上記BASICプログラム実行前のアクセス禁止です(笑)
|
|
|
投稿者:しばっち
投稿日:2018年 4月 9日(月)20時14分28秒
|
|
|
ネット上のサンプルを基にレイマーチング法で球?をレンダリングしています。
二進モードで実行してください。
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プログラム実行前のアクセス禁止です(笑)
|
|
|
戻る