From 090cde5f89d40d2279c3835f34f7547b5f22674d Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Mon, 6 Feb 2023 15:00:11 +0100 Subject: [PATCH] Included face area value in tessellation LOD level calculation. Could probably use some more finetuning in practice, but this is already pretty good. --- n64start.ps1bsp | Bin 631339 -> 631339 bytes world.c | 61 ++++++++++++++++-------------------------------- 2 files changed, 20 insertions(+), 41 deletions(-) diff --git a/n64start.ps1bsp b/n64start.ps1bsp index 63275cc2de7096ece7055513a77151f0b312473c..130f0da597d207ca1e455d3e530f3fa5f7a17584 100755 GIT binary patch delta 12635 zcmai43wRaPwch)jGv^$VoD-7p2!WDJgs8}?Jc3#!GiWJI!RrH&`hW}~Rf{jMR;?vx z5MR`*R*TDOOEcWo?@B+duM(>k&sfAqz1FsXsBJxCwYSx4>!Z?YA>4oMy-zYH(XaVF z{j=7;*4k_By=Lz{6Mnp-?Z-RX3LE5x#D?UC)CTL}bm@M1Bt`e9J7go-52Tv`?gQ!N zvXg=bpajRzM)rf6dk|bB1q^K@AA%CxLy+c>&(K8CLvWZ$_QUBXpo|_?O82Kw&LID% z>DS=yZBxN~hGq&hgxg@!PO?|IyS?ddNFhrdBp-ogo@@=S22X?k2u2t|(Ic=NLH5t! zH-dtn!J(eQpDCq$RDr9(*AOzyAo&<9=aBsvq{-y5gghTp6-AFBSQ~kdBkMf5KUYb3 z8vLKbAy1(Oxm|I#23Lc}&_O=K3<|cxp`9YFluszmWS}SGmN7^L&$(Wd=8cv=$DW_N3I5s z!6sir@Jl=zBglImN|eHII0etcuZ<#>@+AKUP}OTQz|?&KB~?-If+9nP4vHA&ko*J2lL8Il zZ&ehz3)Sbz-vtiK!*B$JyTD<7cc+^xmUcE)d37qA-C$+0w4!?H$d=?Ba(ANx7R!MS zXg9y!Wo0rc@oH{DgRrKPzdPNK-x5~|dVP0#nUv)2!LV2YKw`R}^?TBDQBt@Em0>4( zNhRuO2pGmu^b)vsa`&c}x5kIALG$rXbGiyc@5wD3SxhaK^yFR@QN9eXS>(Np;hKAW z2JVAbptVW9ipVy(8vIv5+7xIAwNn00oBU339>W;&H3ZC|RahEL^7nvgWNUDL4{kL1 zEY(w>A!I;vXi5G-aW(@MT!W{<*AOr?QOGcjA`S92rL-B^$bAh1;bCJ*P{4rw_BFKT zVdR%kCN^(|W^yAX1rbcJ;0$=?B3QOj@H#l01b>7QyXYUGJc1&Y(8Ohu6S!&QYVb7p8UlvV6e_7VV&K&N3`A@E zIem~b{0pQb$Yq#A-e1t|XpOhP;oy54$}!}XJqrtY7Rn#ukrq*n46u<)#GrBFkpL4E`dv-A--JeC@K25e{_VM1n+`!TYf zMZw2Vwo%B^Y_k6aX*Rk4f;*OjB`hifOjy}Wa=+r-{ZKZOw;x&KSz~~707`7q2htt( zOv`LmfN$WxOR`ovs7~WRJ6hgYwNIWx5nHby*{2Hk`w(|Ng?(zdyo2Col7En;O?IYP zPT%Ba&}o|j{NBDP%rqyC6`Nkq%*E)o%y7D%1ckYlu**;+Gu?bgNw61%44AqkAfa~5 z>i?=qVkg^L`&PZ6<$Ka2r`+AIaIE;b+k))thDmu(O%gS+gL5!XQ8Lr)7E<8MPq*12 ze_At)<7RhP7t?XRVC=Tnq`-@WQ(a2eQg~dZA@`(F6>3W9Dza;!+No8w+DfUOGb(Kr zRb?9TFDO+ZD{`guHG-Z@W&VJzGO$o(70EQ_Ly*mY9W0Icz&Xa!Qi{@;viW3ZV2Nu; z21@MLEMX7GLc*cUP)lwWmL244WuTQID+S46nI|w%I1GLms7m>{0QctD#FS61?YTM> z{-a#eaAC#y^2GcqXQ_$#Zp~inSmOF}yOiqggviac1cf{RE*pTv_#`E&vHCcttD!xX z&$xyuALaO9d?$B9ty3|?)mWPySVECcVF?S#u9^18MDSSEpRl1NQ z3QbsxRPj^%0bND$H(<;UQNgvkf<&oiu7$f(ExHU>A%?Tb9*#D_{xe*)UNk)O1N59< z2jv0^8Sn;EuX@g_$8=97p8@wOR)TAQ2|8DU-vF+if(CFnE=NGZOU?*L*q2#C12fE} zP(!3ScckJxhR>0&As7iiT>D2si49~_<~45T(U5Rzj#im@3^-I6swiUUAiEJJGs$g) zG=coa%t3}RP)?vgLpVlpvPmgz4Xy@HgRddb5Ne2;5Nt9k@EaxOh*!Z**X^=-?#ak&l0)DMzPX^@4o2*k~m`UCg__dOpie&*z zL$HZtPXmWnscCQ+O_5g0>B=&g&cS-4=`i70n*qdn&VY7uuRT*I?9Kur?^!zUSs<}m zv!TT0M1#wKiPGRRoK3-OSk9$LD`mSfu{F3Fymn<0v}4@4WY2-gQRHgy<{(A9{u~Jt zT;Yzy=vYt&%Yh0_pfh&0I0!4EGp$G`-gdW5|77Z;f8xW9^^a)pT`W0AUPjOO!<6Bcm%%ym`L6i-~f{^V6NK9UZ7^j zWk91XP?q5Wn4s&w2qiYgFG8v(kD-YIfPGDFAg{gn_4?sb{$?~E)IBMYyf}fhI$@2g zXeUBQ@))Yf2PDP`+R}+*4X-ktnQr^}*h}eN94=cCYGh*yM^;abNS>I4*Oyd`;7gfq zc5YpmS;lv>g%|)Q?n1<9iN$!?WVWo4*ZBBqk-8%No?5R(D;jxmiuswDz1EtT%XP-( zEB}UH-I!MXh0MdLH*^cEsZ??AT;9khYcXG+*`GB1);&~ptxB($cdYRi7K0r(4prS` zGFp{-!otf8t^v8*hN|u`j%QiZQ-|tU->X!yV~`F_-E;+AY zL0?24z0t@|N+~bWr4&BCorsRXaeoq^id+r;Nhsi9lBZ(OVPp6jzq{H=%}EuUKPKfZ#ec_*WTac4YPb#TNmp6pWq zcmhvBKDb7+gzjcZQpA8u#bO0E0}9ZR$8a3^i?xI1A}!gcDhF4Cr@?2y$}wP481RzF zP$aoTfz2>Nzfe3dMqi~@WnWI?7O)62ux*Tb?MRALDUHiLs~%OVt`w`V&`{;KE7kEC zR?Wr>#S%R8sNpp1;@GE7!$y-OcPX;QXWyk5?ct=DCE6OUJ_aZ>N6 zQhE_a3{^EM$F*3h{b)@4%Ls|DRtz|-czF+12CHCjYRaf4H}NN^=c^n%6HigJ6jtp+ zREwM@Zh}pglbUUfjP%HqOVUYgwsz`_yDC(w z`&KH|S+L?~o$Jb<8&_eXPtUBgcbe1~%IC{f%Fao&SUi9_k_t`S@lHZyCZ%8c1edET zc-nG?TEplJ)ob>dm|N@-8a#mA5{t1JoB5(TDSy<&5247lr1&8W*c#oA4w-VVN~n+% z*h=s&)&H{&o+s2L5)UZPTj04mh40a4!851Z?J+guomr6@Zrw-060BROR1P|DwzXJW zJ*^h}#e`6;r26!ErTP#_|c{Bwo#=tv*Tfy40%pU3v$A7n~!2Jv^2Q?}=Z-ax5Cl%h8e$YEQI1 znAOF4x(a5O)yc%tvAiN<6VGBoah-)(;!u3`^)QsBAJo-j)h>|G2SEf2%!gc|z+Qp* z!25)TXa%ks2y!+!+|C$|qu^{P(FiM%HMYH#P-5F-$)Rv1+#Rydfi#@Fb8w3}isUMo z97XmjNW&>)slGQ_g(&QQF2q{$&xHpzE|&0}mmy2?JOI9hoQI&ehO&g$1O{B?&w~Tj z_Iw1zUHp7(PB8hZdK+?A!vx>m7;xWUz^1L0AwvyCT9Owi&b|O6)R51B6}SK~krFwkUj85+sI2o8A3WN9r$7pctLi`M>~ewU~y5i7y1 zQDCpp+#0y!CcaiXFyO3Uz+Y&z($`X;xlk*kwMZ9#WVjTTDDzT`fET7qRWSE!kT5R{ z__+Nw4&56upg{R`Af}fA->kn58+=OsI-=nt+2zX7V?f#r_}q0lg5p8C0uJbkE0jaP z5}qf9rrziZm~gajsG#0ARA~`Q_-=m{VlSrPDmdbn&w#h-Z-T=M{x>1v%E*A@la+Yk zX23kH!|G!Abt;(G4S>|G{A2+!CsI&=G?BsrI4qVA3AZ1H5#%#q1M|UQy!DVe$kpI! z@YjRGMf++18vSY{k)`lzH5J|lNceNp27Wc~4X)t=N0Gb^h<7**;dQV%jO6u5^hk=X z#}G*S1}O0X_67vSN4^`Ntfh!0d?noo3D4O^m|$U80=E${F?ZjBg!W~?)}$d|z~5)T z1qbXfH!9B7;NA!&+V@7dqkUP4UH3l$cza^NjA+SYz_1zu&4n5w2K4()+V3U=L+3D{ znOTX7Zr0q*7!NhD1QQLx%_@0$3zX=eTQFOIZ$oM#mjQo0{I>E7v=lO+=x@Uhf33V# zn=l~3TUD7M10IRnFlQL(HgH%+2F%%Q;IILFhv&1`{|+RWhMN=_ZBmZ*?T}FX?Mm`* zhp9u70BCdu#J)qN?cJfG1$QVD`@8US$o(!F0A0vZ9mzYvb&!82Bz!Yx2@lU*%FnwC zN<4!a0u3QU2Ss+`y4apyYkprmfiEyl>aE26 z$v9vBOWf&-FJ#|J6jP@OTJinNx^6FaC^X?C{<+o+(1if;Z=feAR)~#;?-|6G3%E)1 z*-tCr)_%UbvVtXMfZLTp2>~iAIMq~er{Y_N@Z|zFn*lzpfGvja>Hd@o?p6jp$xo|b zYd>FEz&WOX`xGxyg9}(`3V2ZQPV)1E4aya4GXs2D1&Y~tQuKc>2LUMu}cLgR+Z|C z2Pee_SZd~BuL@8|4-Qb~|DgN}>B0V?@qc}Sg#`YTSyj%!8JYc^+R>DFdgL4Jy{qJnZ>$fSN&TX!!cFKlr%+ zV#AM8d{?!Tuk;76#urV-pokubH(6w+bG+hvY6k}>^R0#->|b7@HpRE(ibHy!ThGxX zW8h#7hc<~2Qx)&ja)3|jffqW1m-2K9g$UmV?^z#s#ipP1X9z$f>>y#53# z`59&g=TGE!ghIABs*vC}i}FwRXU${MIba~-2BQssg5m`SkR!_8z$Wwi$(kQFn4f9< zmzelH@IPt5zgwJYDm>j7lqwCx0ux}Fs<0>7GO~CuesmsVf~^?fWt?AY_*IH8q~I?G z3PArYF!iD@ZZuTr2aBEB}Jz zEvZcvq5rqs{9aW4MQgCX;k(676`*Jh4p83Ho|~x7wZxbqdzzliUzw74OIl^-m&Y#q z|5o|0wb(ztWoaILvDeH12UuvbW+?Azzw1xnlees>KY>z30%iX<`xB_#vJ}sK`Br}d zrHTa3GfVJS&1XyX&Vl$7-@;kq=lub`qFqNC|9y%tWZ>U7PI>76aV!<@V`bnBQwH1> zQ~OLv(cttw6?3`QgiN%lqc~ec$fxix_U_4S#=C{T6)y*P#Q=1FCFXUeS(aAiC2F1Q zi89WgW%xG5pHurv<{2?P=8u03sH91XzcbJLpJP1U9@WoO*%vbUknIY#J zzLYB+c*qRHu)_Fv_VX=$aekk+?G`5}gO6or)~T4(v(2QP+|N%J@kw8423Vr_uEd*} zM=Ivz9K)Zk_)YTuY$dOswP`{uGXVx0e8nWN!UW&}Ug73w=w78%h3qpej<91zpKHcE zzn>S0IA1=`E;PJ@Kg7+A`JZQoTx0kXTPpeUHQy~RQwGD4K#M#s7T~KUfh!gN?ht;p z8DO2_g;hxPh(gT&0^`44@x|)F{Cmn45B;^;AYHV2M0{Db0p2SW-%`c=-D2S9LX*Hv z#@|U+`j`1zjX(2ofAwCxLX+%u&arK@mKeY&4aPEpD!GU^W_)g`xIZ|U9oQr2Q)wB7vl$Y0z-J1 n-B!Ebn!3%z=PfS2?U%Q>M-9(g+(L2PmY-yLxBMh~!~6da3?c0> delta 13657 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 diff --git a/world.c b/world.c index 86f506c..b3f5f83 100644 --- a/world.c +++ b/world.c @@ -64,59 +64,38 @@ static INLINE short world_pointPlaneDist(const VECTOR *point, const ps1bsp_plane return (short)m_pointPlaneDist2(point, &plane->normal, plane->dist); } -static INLINE short world_planeDot(const SVECTOR *dir, const ps1bsp_plane_t *plane) -{ - // Make use of axis-aligned planes to skip the need for a dot product - if (plane->type < 3) - return ((short*)dir)[plane->type]; - - return (short)m_dot12(dir, &plane->normal); -} - static INLINE short world_cull_backface(const world_t *world, const ps1bsp_face_t *face) { // Backface culling using the face's plane and center point // This eliminates the need for normal clipping per polygon - SVECTOR cam_vec; - cam_vec.vx = face->center.vx - cam_pos.vx; - cam_vec.vy = face->center.vy - cam_pos.vy; - cam_vec.vz = face->center.vz - cam_pos.vz; + VECTOR cam_vec; + cam_vec.vx = (int)face->center.vx - cam_pos.vx; + cam_vec.vy = (int)face->center.vy - cam_pos.vy; + cam_vec.vz = (int)face->center.vz - cam_pos.vz; // Check if the face's plane points towards the camera const ps1bsp_plane_t *plane = &world->planes[face->planeId]; - int planeDot = world_planeDot(&cam_vec, plane); + int planeDot = m_dot12(&cam_vec, &plane->normal); if ((planeDot >= 0) ^ face->side) return 0; - - // Check if the face is behind the camera - // TODO: this may cull faces close to the camera, use VectorNormalS to normalize and check for angles < -60 degrees - // TODO: or, just check against all corners of the face... - // const ps1bsp_facevertex_t *faceVertices = &world->faceVertices[face->firstFaceVertex]; - // for (int vertIdx = 0; vertIdx < face->numFaceVertices; ++vertIdx) - // { - // const ps1bsp_vertex_t *vert = &world->vertices[faceVertices[vertIdx].index]; - // cam_vec.vx = vert->x - cam_pos.vx; - // cam_vec.vy = vert->y - cam_pos.vy; - // cam_vec.vz = vert->z - cam_pos.vz; - // if (m_dot12(cam_vec, cam_dir) >= 0) - // return 0; - // } + // Check if the face is behind the camera // NOTE: disabling the behind-the-camera check does *not* actually solve the problem of polygons disappearing when too close to the camera! // This means that the GPU probably already clips polygons that stretch too far outside the drawing area. Tessellation should solve this. int camDot = m_dot12(&cam_vec, &cam_dir); if (camDot < 0) return 0; - int vecLenSqr = m_dot12(&cam_vec, &cam_vec); - // Flip angle for faces that are on the opposite side of their plane char flip = 2 * face->side - 1; planeDot = planeDot * flip; - int foo = (planeDot * vecLenSqr) / (camDot + 1); - // TODO: include face area - return (short)foo; + // Calculate an LOD value for this face, based on camera position & direction, face normal & area and distance. + // This is used to determine how many tessellation subdivisions are necessary to prevent texture warping. + int vecLenSqr = m_dot12(&cam_vec, &cam_vec); + int lod = (planeDot * vecLenSqr) / (camDot + 1); + lod = (lod << 6) / (face->center.pad + 1); + return (short)lod; } static u_short world_leafAtPoint(const world_t *world, const VECTOR *point) @@ -235,19 +214,19 @@ static ps1bsp_face_t *world_sortFaces(const world_t *world, const ps1bsp_leaf_t face->drawFrame = frameNum; - // NOTE: this value could be REALLY useful for determining the tessellation subdivisions. It has camera distance *and* angle in it. - // Just include the face size/area for an approximate screen size. Maybe also separate x/y/z for angle-dependent tessellation. - short dot = world_cull_backface(world, face); - if (!dot) + // Cull faces that are facing away from the camera + // This also returns an LOD value used to determine tessellation level + short lod = world_cull_backface(world, face); + if (!lod) continue; face->flags &= ~3; - if (dot < 64) + if (lod < 64) face->flags |= 1; - else if (dot < 128) + else if (lod < 128) face->flags |= 2; - else if (dot < 256) - face->flags |= 3; + // else if (lod < 256) + // face->flags |= 3; // Sort the faces to draw in front-to-back order face->nextFace = firstFace;