シェーディング

 投稿者:しばっち  投稿日:2019年 3月 3日(日)21時29分49秒
  シェーディングによる陰(shade)をつけます。但し、影(shadow) は付きません。全く別物です。
ランバートによるシェーディングで球(円...じゃないもん!!)を描画します。

sampleフォルダの3DVIEW2.BAS内にある setBrightness サブルーチンと
実質的には同じ(パラメーターが違うだけ)です。

明るさ E ∝ cosθ ランバートシェーディングモデル


SET COLOR MODE "NATIVE"
CLEAR
SET POINT STYLE 1
ASK BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE,0,YSIZE
DIM LIGHT(3),N(3),COL(3),KD(3),LA(3)
LET RR=.7
MAT READ LIGHT !'光線ベクトル
DATA 1,1,1
MAT READ KD !'拡散反射光
DATA .7,.7,.2
MAT READ LA !'環境光
DATA .3,.3,.3
FOR Y=0 TO YSIZE
   LET YY=(Y*2-YSIZE)/YSIZE
   FOR X=0 TO XSIZE
      LET XX=(X*2-XSIZE)/XSIZE
      LET D=RR*RR-XX*XX-YY*YY
      IF D>0 THEN
         LET ZZ=SQR(D)
         LET N(1)=XX
         LET N(2)=YY
         LET N(3)=ZZ
         CALL SHADE(COL,N,LIGHT,LA,KD)
         CALL PSET(X,Y,COL)
      END IF
   NEXT X
NEXT Y
END

EXTERNAL  SUB SHADE(COL(),N(),LIGHT(),LA(),KD()) !'lambertシェーディングモデル
MAT N=(1/SQR(DOT(N,N)))*N
MAT LIGHT=(1/SQR(DOT(LIGHT,LIGHT)))*LIGHT
LET C=DOT(N,LIGHT)
MAT COL=(MAX(C,0))*KD
MAT COL=COL+LA
END SUB

EXTERNAL SUB PSET(X,Y,COL())
FOR I=1 TO 3
   LET COL(I)=MIN(1,MAX(0,COL(I)))
NEXT I
SET COLOR COLORINDEX(COL(1),COL(2),COL(3))
PLOT POINTS:X,Y
END SUB
 

シェーディング

 投稿者:しばっち  投稿日:2019年 3月 3日(日)21時31分16秒
  フォンによるシェーディングモデルです。
パラメーターは適当です。

鏡面反射によるハイライトがつきます。
いろいろいじるとそれらしく見えてくるかもしれません。

拡散反射光 Ed ∝ COSθ
鏡面反射光 Es ∝ COSα^n
背景光 Ea
明るさ E = Ed + Es + Ea フォンシェーディングモデル

SET COLOR MODE "NATIVE"
CLEAR
SET POINT STYLE 1
ASK BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE,0,YSIZE
LET RR=.7
DIM LA(3),N(3),LIGHT(3),COL(3),KS(3)
DIM VIEW(3),LS(3),KD(3)
MAT READ LA !'環境光
DATA .7,.2,.1
MAT READ KD !'拡散反射光
DATA .9,.5,.3
MAT READ LIGHT !'光線ベクトル
DATA 1,1,1
MAT READ KS !'鏡面反射光
DATA .9,.6,.6
MAT READ VIEW !'視線ベクトル
DATA 0,0,1
LET SHININESS=32
FOR Y=0 TO YSIZE
   LET YY=(Y*2-YSIZE)/YSIZE
   FOR X=0 TO XSIZE
      LET XX=(X*2-XSIZE)/XSIZE
      LET D=RR*RR-XX*XX-YY*YY
      IF D>0 THEN
         LET ZZ=SQR(D)
         LET N(1)=XX
         LET N(2)=YY
         LET N(3)=ZZ
         CALL SHADE(COL,N,LIGHT,VIEW,LA,KD,KS,SHININESS)
         CALL PSET(X,Y,COL)
      END IF
   NEXT X
NEXT Y
END

EXTERNAL  SUB SHADE(COL(),N(),LIGHT(),VIEW(),LA(),KD(),KS(),SHININESS) !'phongシェーディングモデル
DIM LD(3),LS(3),R(3)
MAT N=(1/SQR(DOT(N,N)))*N
MAT LIGHT=(1/SQR(DOT(LIGHT,LIGHT)))*LIGHT
MAT VIEW=(1/SQR(DOT(VIEW,VIEW)))*VIEW
LET C=DOT(N,LIGHT)
MAT LD=(MAX(C,0))*KD
LET MODE=0
SELECT CASE MODE
CASE 0
   CALL REFLECT(R,N,LIGHT) !'反射ベクトル phong鏡面反射
   LET C=DOT(VIEW,R)
CASE 1
   CALL HALF(R,LIGHT,VIEW) !'ハーフベクトル Bllinn-phong鏡面反射
   LET C=DOT(R,N)
END SELECT
MAT LS=(MAX(C,0)^SHININESS)*KS
MAT COL=LA+LD
MAT COL=COL+LS
END SUB

EXTERNAL SUB PSET(X,Y,COL())
FOR I=1 TO 3
   LET COL(I)=MIN(1,MAX(0,COL(I)))
NEXT I
SET COLOR COLORINDEX(COL(1),COL(2),COL(3))
PLOT POINTS:X,Y
END SUB

EXTERNAL  SUB REFLECT(R(),NORMAL(),LIGHT()) !'反射ベクトル
LET C=DOT(NORMAL,LIGHT)
MAT R=(MAX(2*C,0))*NORMAL
MAT R=R-LIGHT
MAT R=SQR(1/SQR(DOT(R,R)))*R
END SUB

EXTERNAL  SUB HALF(H(),LIGHT(),VIEW()) !'ハーフベクトル
MAT H=LIGHT+VIEW
MAT H=(1/SQR(DOT(H,H)))*H
END SUB
 

シェーディング

 投稿者:しばっち  投稿日:2019年 3月 3日(日)21時32分54秒
  金属の質感を表現できるクックトランスによるシェーディングです。

残念ながら、金属風には見えませんが...(-_-;)
どこか間違っているのかもしれません。パラメーターも適当なのであしからず


D(α)=1/(4m^2cosα^4)exp{-(tanα/m)^2}
G=min{1,2(N・H)(N・E)/2(E・H),2(N・H)(N・L)/(E・H)}
F={.5(g-c)^2/(g+c)^2}[1+{c(g+c)-1}^2/{c(g-c)+1}^2]
鏡面反射光 Es ∝ DGF/(N・E) クックトランスシェーディングモデル

SET COLOR MODE "NATIVE"
SET POINT STYLE 1
DIM COL(3),LIGHT(3),N(3),VIEW(3),DIFFUSE(3),AMBIENT(3),SPECULAR(3)
ASK BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE,0,YSIZE
LET RR=.7
MAT READ LIGHT !'光線ベクトル
DATA 1,1,1
MAT READ VIEW !'視線ベクトル
DATA 0,0,1
MAT READ DIFFUSE !'拡散反射係数
DATA .3,.5,.1
MAT READ AMBIENT !'環境光
DATA .6,.6,0
MAT READ SPECULAR
DATA .5,.2,.3
LET MICROFACET=.2 !' 面の粗さ
FOR Y=0 TO YSIZE
   LET YY=(Y*2-YSIZE)/YSIZE
   FOR X=0 TO XSIZE
      LET XX=(X*2-XSIZE)/XSIZE
      LET D=RR*RR-XX*XX-YY*YY
      IF D>0 THEN
         LET ZZ=SQR(D)
         LET N(1)=XX
         LET N(2)=YY
         LET N(3)=ZZ
         CALL SHADE(COL,N,LIGHT,VIEW,SPECULAR,DIFFUSE,AMBIENT,MICROFACET)
         CALL PSET(X,Y,COL)
      END IF
   NEXT X
NEXT Y
END

EXTERNAL  SUB SHADE(COL(),NORMAL(),LIGHT(),VIEW(),SPECULAR(),DIFFUSE(),AMBIENT(),MICROFACET) !' Cook-Torranceシェーディングモデル
DIM L(3),N(3),V(3),H(3),SPE(3),DIF(3),F(3),VR(3)
MAT N=(1/SQR(DOT(NORMAL,NORMAL)))*NORMAL
MAT L=(1/SQR(DOT(LIGHT,LIGHT)))*LIGHT
MAT V=(1/SQR(DOT(VIEW,VIEW)))*VIEW
MAT H = L+V
MAT H = (1/SQR(DOT(H,H)))*H
LET HN = DOT(H, N)
LET LN = DOT(L, N)
LET LH = DOT(L, H)
LET VN = DOT(V, N)
LET VH = DOT(V, H)
LET D = BECHMANNDISTRIBUTION(MICROFACET,HN)
LET T = 2 * HN / VH
LET G = MIN(1, MIN(T * VN, T * LN))
LET M = PI * VN * LN
FOR I=1 TO 3
   LET F(I)=FRESNEL(LH,SPECULAR(I))
NEXT I
MAT SPE = (MAX(D*G/M,0)) * F
MAT DIF = (MAX(LN,0)) * DIFFUSE
MAT COL = SPE + DIF
MAT COL = COL + AMBIENT
END SUB

EXTERNAL  FUNCTION BECHMANNDISTRIBUTION(M, NH) !' Beckman分布
LET ALPHA=ACOS(NH)
LET BECHMANNDISTRIBUTION=EXP(-TAN(ALPHA)^2/M^2) / (4*M^2 * COS(ALPHA)^4)
END FUNCTION

EXTERNAL  FUNCTION FRESNEL(C, F0) !' フレネル項
LET SF = SQR(F0)
LET N = (1 + SF) / (1 - SF)
LET G = SQR(N * N + C * C - 1)
LET GA = (C * (G + C) - 1)^2
LET GB = (C * (G - C) + 1)^2
LET FRESNEL=(G - C)^2 / (2 * (G + C)^2) * (1 + GA / GB)
END FUNCTION

EXTERNAL SUB PSET(X,Y,COL())
FOR I=1 TO 3
   LET COL(I)=MIN(1,MAX(0,COL(I)))
NEXT I
SET COLOR COLORINDEX(COL(1),COL(2),COL(3))
PLOT POINTS:X,Y
END SUB
 

戻る