Main.cpp 157 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859
  1. /******************************************************************************/
  2. #include "!Header.h"
  3. #include "Ambient Occlusion.h"
  4. #include "Sky.h"
  5. #include "Layered Clouds.h"
  6. #include "Hdr.h"
  7. #include "Water.h"
  8. #include "Overlay.h"
  9. #include "Simple.h"
  10. #include "Volumetric.h"
  11. #include "Vertex Fog.h"
  12. #include "Fog.h"
  13. #include "Fur.h"
  14. /******************************************************************************/
  15. ImageCube Cub;
  16. /******************************************************************************/
  17. VecH4 TexCubicFast(Vec2 inTex)
  18. {
  19. #if 0 // original
  20. Vec2 tex =inTex*ColSize.zw-0.5f,
  21. texi=Floor(tex),
  22. texf=tex-texi;
  23. texi-=0.5f; texi*=ColSize.xy;
  24. Vec4 c00=TexPoint(Col, texi+ColSize.xy*Vec2(0, 0)), c10=TexPoint(Col, texi+ColSize.xy*Vec2(1, 0)), c20=TexPoint(Col, texi+ColSize.xy*Vec2(2, 0)), c30=TexPoint(Col, texi+ColSize.xy*Vec2(3, 0)),
  25. c01=TexPoint(Col, texi+ColSize.xy*Vec2(0, 1)), c11=TexPoint(Col, texi+ColSize.xy*Vec2(1, 1)), c21=TexPoint(Col, texi+ColSize.xy*Vec2(2, 1)), c31=TexPoint(Col, texi+ColSize.xy*Vec2(3, 1)),
  26. c02=TexPoint(Col, texi+ColSize.xy*Vec2(0, 2)), c12=TexPoint(Col, texi+ColSize.xy*Vec2(1, 2)), c22=TexPoint(Col, texi+ColSize.xy*Vec2(2, 2)), c32=TexPoint(Col, texi+ColSize.xy*Vec2(3, 2)),
  27. c03=TexPoint(Col, texi+ColSize.xy*Vec2(0, 3)), c13=TexPoint(Col, texi+ColSize.xy*Vec2(1, 3)), c23=TexPoint(Col, texi+ColSize.xy*Vec2(2, 3)), c33=TexPoint(Col, texi+ColSize.xy*Vec2(3, 3));
  28. Vec4 c0=Lerp4(c00, c10, c20, c30, texf.x),
  29. c1=Lerp4(c01, c11, c21, c31, texf.x),
  30. c2=Lerp4(c02, c12, c22, c32, texf.x),
  31. c3=Lerp4(c03, c13, c23, c33, texf.x);
  32. return Lerp4(c0, c1, c2, c3, texf.y);
  33. #else // optimized
  34. inTex*=ColSize.zw;
  35. Vec2 tc=Floor(inTex-0.5f)+0.5f,
  36. f=inTex-tc, f2=f*f, f3=f2*f,
  37. w0=f2-0.5f*(f3+f), w1=1.5f*f3-2.5f*f2+1.0f,
  38. #if 0
  39. w2=-1.5f*f3+2*f2+0.5f*f, w3=0.5f*(f3-f2);
  40. #else
  41. w3=0.5f*(f3-f2), w2=1.0f-w0-w1-w3;
  42. #endif
  43. tc*=ColSize.xy;
  44. Vec2 tc0=tc-ColSize.xy, tc3=tc+ColSize.xy*2;
  45. #if 0 // 16 tex reads
  46. Vec2 tc2=tc+ColSize.xy;
  47. /*Flt w[4][4]={(w0.x*w0.y), (w1.x*w0.y), (w2.x*w0.y), (w3.x*w0.y),
  48. (w0.x*w1.y), (w1.x*w1.y), (w2.x*w1.y), (w3.x*w1.y),
  49. (w0.x*w2.y), (w1.x*w2.y), (w2.x*w2.y), (w3.x*w2.y),
  50. (w0.x*w3.y), (w1.x*w3.y), (w2.x*w3.y), (w3.x*w3.y)};*/
  51. return TexPoint(Col, Vec2(tc0.x, tc0.y))*(w0.x*w0.y)
  52. +TexPoint(Col, Vec2(tc .x, tc0.y))*(w1.x*w0.y)
  53. +TexPoint(Col, Vec2(tc0.x, tc .y))*(w0.x*w1.y)
  54. +TexPoint(Col, Vec2(tc .x, tc .y))*(w1.x*w1.y)
  55. +TexPoint(Col, Vec2(tc2.x, tc0.y))*(w2.x*w0.y)
  56. +TexPoint(Col, Vec2(tc3.x, tc0.y))*(w3.x*w0.y)
  57. +TexPoint(Col, Vec2(tc2.x, tc .y))*(w2.x*w1.y)
  58. +TexPoint(Col, Vec2(tc3.x, tc .y))*(w3.x*w1.y)
  59. +TexPoint(Col, Vec2(tc0.x, tc2.y))*(w0.x*w2.y)
  60. +TexPoint(Col, Vec2(tc .x, tc2.y))*(w1.x*w2.y)
  61. +TexPoint(Col, Vec2(tc0.x, tc3.y))*(w0.x*w3.y)
  62. +TexPoint(Col, Vec2(tc .x, tc3.y))*(w1.x*w3.y)
  63. +TexPoint(Col, Vec2(tc2.x, tc2.y))*(w2.x*w2.y)
  64. +TexPoint(Col, Vec2(tc3.x, tc2.y))*(w3.x*w2.y)
  65. +TexPoint(Col, Vec2(tc2.x, tc3.y))*(w2.x*w3.y)
  66. +TexPoint(Col, Vec2(tc3.x, tc3.y))*(w3.x*w3.y);
  67. #else // 5 tex reads, corners are ignored because they're insignificant,
  68. Vec2 w12=w1+w2, p=tc+(w2/w12)*ColSize.xy;
  69. Flt wu=w12.x*w0.y, wd=w12.x*w3.y, wl=w12.y*w0.x, wr=w12.y*w3.x, wc=w12.x*w12.y;
  70. // keep 'Tex' in case we need LOD's (for example stretching in 1 dimension but shrinking in another)
  71. return(Tex(Col, Vec2( p.x, tc0.y))*wu // sample upper edge (2 texels), both weights are negative
  72. +Tex(Col, Vec2( p.x, tc3.y))*wd // sample lower edge (2 texels), both weights are negative
  73. +Tex(Col, Vec2(tc0.x, p.y))*wl // sample left edge (2 texels), both weights are negative
  74. +Tex(Col, Vec2(tc3.x, p.y))*wr // sample right edge (2 texels), both weights are negative
  75. +Tex(Col, Vec2( p.x, p.y))*wc // sample center (4 texels), all weights are positive
  76. )/(wu+wd+wl+wr+wc);
  77. #endif
  78. #endif
  79. }
  80. VecH TexCubicFastRGB(Vec2 inTex) // ignores alpha channel
  81. {
  82. inTex*=ColSize.zw;
  83. Vec2 tc=Floor(inTex-0.5f)+0.5f,
  84. f=inTex-tc, f2=f*f, f3=f2*f,
  85. w0=f2-0.5f*(f3+f), w1=1.5f*f3-2.5f*f2+1.0f,
  86. w3=0.5f*(f3-f2), w2=1.0f-w0-w1-w3;
  87. tc*=ColSize.xy;
  88. Vec2 tc0=tc-ColSize.xy, tc3=tc+ColSize.xy*2,
  89. w12=w1 +w2 , p =tc+(w2/w12)*ColSize.xy;
  90. Flt wu =w12.x*w0.y , wd =w12.x*w3.y, wl=w12.y*w0.x, wr=w12.y*w3.x, wc=w12.x*w12.y;
  91. // keep 'Tex' in case we need LOD's (for example stretching in 1 dimension but shrinking in another)
  92. return(Tex(Col, Vec2( p.x, tc0.y)).rgb*wu
  93. +Tex(Col, Vec2( p.x, tc3.y)).rgb*wd
  94. +Tex(Col, Vec2(tc0.x, p.y)).rgb*wl
  95. +Tex(Col, Vec2(tc3.x, p.y)).rgb*wr
  96. +Tex(Col, Vec2( p.x, p.y)).rgb*wc)/(wu+wd+wl+wr+wc);
  97. }
  98. /******************************************************************************/
  99. #define CUBIC_SAMPLES 3
  100. #define CUBIC_RANGE 2
  101. #define CUBIC_SHARPNESS (2/2.5f)
  102. #define CUBIC_QUALITY 2 // 0..2, 0=3.748 fps, 1=3.242 fps, 2=3.075 fps (however when using CUBIC_SKIP_SAMPLE it's now much faster)
  103. #if MODEL!=SM_GL
  104. #define CUBIC_SKIP_SAMPLE (1 && CUBIC_QUALITY==2) // because the actual range is 2.5 then it means we need to process 5x5 samples (and not 6x6), this optimization can work only if actual range <= 2.5, also we can enable this only for CUBIC_QUALITY==2 because only this mode operates on single 1x1 pixels and not 2x2 blocks)
  105. #else
  106. #define CUBIC_SKIP_SAMPLE 1 // otherwise fails to compile
  107. #endif
  108. inline Flt Cubic(Flt x, uniform Flt blur, uniform Flt sharpen)
  109. {
  110. Flt x2=x*x,
  111. x3=x*x*x;
  112. return (x<=1) ? ((12-9*blur-6*sharpen)/6*x3 + (-18+12*blur+6*sharpen)/6*x2 + (6-2*blur )/6)
  113. : ((-blur-6*sharpen )/6*x3 + (6*blur+30*sharpen )/6*x2 + (-12*blur-48*sharpen)/6*x + (8*blur+24*sharpen)/6);
  114. }
  115. Flt CubicMed(Flt x) {return Cubic(x, 0.0f, 0.375f);}
  116. VecH4 TexLerp(Flt x0, Flt x1, Flt y, Flt l, Flt r)
  117. {
  118. Flt w=l+r;
  119. // keep 'Tex' in case we need LOD's (for example stretching in 1 dimension but shrinking in another)
  120. return Tex(Col, Vec2((x0*l + x1*r)/w, y))*Half(w);
  121. }
  122. VecH TexLerpRGB(Flt x0, Flt x1, Flt y, Flt l, Flt r) // ignores alpha channel
  123. {
  124. Flt w=l+r;
  125. // keep 'Tex' in case we need LOD's (for example stretching in 1 dimension but shrinking in another)
  126. return Tex(Col, Vec2((x0*l + x1*r)/w, y)).rgb*Half(w);
  127. }
  128. VecH4 TexLerp(Vec2 t0, Vec2 t1, Flt lu, Flt ru, Flt lb, Flt rb)
  129. {
  130. #if 0 // slower
  131. return TexPoint(Col, Vec2(t0.x, t0.y))*lu
  132. +TexPoint(Col, Vec2(t1.x, t0.y))*ru
  133. +TexPoint(Col, Vec2(t0.x, t1.y))*lb
  134. +TexPoint(Col, Vec2(t1.x, t1.y))*rb;
  135. #else
  136. Vec2 t=Vec2(t0.x, t0.y)*lu
  137. +Vec2(t1.x, t0.y)*ru
  138. +Vec2(t0.x, t1.y)*lb
  139. +Vec2(t1.x, t1.y)*rb;
  140. Flt w=lu+ru+lb+rb;
  141. // keep 'Tex' in case we need LOD's (for example stretching in 1 dimension but shrinking in another)
  142. return Tex(Col, t/w)*Half(w);
  143. #endif
  144. }
  145. VecH TexLerpRGB(Vec2 t0, Vec2 t1, Flt lu, Flt ru, Flt lb, Flt rb) // ignores alpha channel
  146. {
  147. Vec2 t=Vec2(t0.x, t0.y)*lu
  148. +Vec2(t1.x, t0.y)*ru
  149. +Vec2(t0.x, t1.y)*lb
  150. +Vec2(t1.x, t1.y)*rb;
  151. Flt w=lu+ru+lb+rb;
  152. // keep 'Tex' in case we need LOD's (for example stretching in 1 dimension but shrinking in another)
  153. return Tex(Col, t/w).rgb*Half(w);
  154. }
  155. VecH4 TexCubic(Vec2 inTex)
  156. {
  157. Vec2 pixel =inTex*ColSize.zw-0.5f,
  158. pixeli=Floor(pixel),
  159. offset [CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE],
  160. offset_weight[CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE];
  161. #if CUBIC_SKIP_SAMPLE
  162. pixeli+=(pixel-pixeli>=CUBIC_RANGE/CUBIC_SHARPNESS-(CUBIC_SAMPLES-1)); // if the left/top coordinate is completely out of range, then process the next pixel (the >= returns Vec2, so it modifies X and Y independently)
  163. #endif
  164. UNROLL for(int i=0; i<CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE; i++)
  165. {
  166. offset [i]= pixeli+(i-(CUBIC_SAMPLES-1));
  167. offset_weight[i]=Sqr((pixel -offset[i])*CUBIC_SHARPNESS);
  168. offset [i]= (offset[i]+0.5f)*ColSize.xy;
  169. }
  170. Vec4 color =0;
  171. Flt weight=0;
  172. #if CUBIC_QUALITY>=2
  173. UNROLL for(int y=0; y<CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE; y++)
  174. UNROLL for(int x=0; x<CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE; x++)
  175. {
  176. Flt w=offset_weight[x].x+offset_weight[y].y; if(w<Sqr(CUBIC_RANGE))
  177. {
  178. w=CubicMed(Sqrt(w));
  179. color +=w*TexPoint(Col, Vec2(offset[x].x, offset[y].y)); // don't use "color+=w*Col.Load(VecI(offset[x].x without scale, offset[y].y without scale, 0)); because it is slower and doesn't support wrap/clamp
  180. weight+=w;
  181. }
  182. }
  183. #else
  184. Flt weights[CUBIC_SAMPLES*2][CUBIC_SAMPLES*2]; // [y][x]
  185. UNROLL for(int y=0; y<CUBIC_SAMPLES*2; y++)
  186. UNROLL for(int x=0; x<CUBIC_SAMPLES*2; x++)
  187. {
  188. Flt w=offset_weight[x].x+offset_weight[y].y;
  189. w=(w<Sqr(CUBIC_RANGE) ? CubicMed(Sqrt(w)) : 0);
  190. weights[y][x]=w;
  191. weight +=w;
  192. }
  193. #if CUBIC_QUALITY>=1 // medium quality
  194. UNROLL for(int y=0; y<CUBIC_SAMPLES*2; y++ )
  195. UNROLL for(int x=0; x<CUBIC_SAMPLES*2; x+=2)color+=TexLerp(offset[x].x, offset[x+1].x, offset[y].y, weights[y][x], weights[y][x+1]);
  196. #else // low quality
  197. UNROLL for(int y=0; y<CUBIC_SAMPLES*2; y+=2)
  198. UNROLL for(int x=0; x<CUBIC_SAMPLES*2; x+=2)color+=TexLerp(Vec2(offset[x].x, offset[y].y), Vec2(offset[x+1].x, offset[y+1].y), weights[y][x], weights[y][x+1], weights[y+1][x], weights[y+1][x+1]);
  199. #endif
  200. #endif
  201. return color/weight;
  202. }
  203. VecH TexCubicRGB(Vec2 inTex) // ignores alpha channel
  204. {
  205. Vec2 pixel =inTex*ColSize.zw-0.5f,
  206. pixeli=Floor(pixel),
  207. offset [CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE],
  208. offset_weight[CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE];
  209. #if CUBIC_SKIP_SAMPLE
  210. pixeli+=(pixel-pixeli>=CUBIC_RANGE/CUBIC_SHARPNESS-(CUBIC_SAMPLES-1)); // if the left/top coordinate is completely out of range, then process the next pixel (the >= returns Vec2, so it modifies X and Y independently)
  211. #endif
  212. UNROLL for(int i=0; i<CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE; i++)
  213. {
  214. offset [i]= pixeli+(i-(CUBIC_SAMPLES-1));
  215. offset_weight[i]=Sqr((pixel -offset[i])*CUBIC_SHARPNESS);
  216. offset [i]= (offset[i]+0.5f)*ColSize.xy;
  217. }
  218. Vec color =0;
  219. Flt weight=0;
  220. #if CUBIC_QUALITY>=2 // high quality
  221. UNROLL for(int y=0; y<CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE; y++)
  222. UNROLL for(int x=0; x<CUBIC_SAMPLES*2-CUBIC_SKIP_SAMPLE; x++)
  223. {
  224. Flt w=offset_weight[x].x+offset_weight[y].y; if(w<Sqr(CUBIC_RANGE))
  225. {
  226. w=CubicMed(Sqrt(w));
  227. color +=w*TexPoint(Col, Vec2(offset[x].x, offset[y].y)).rgb; // don't use "color+=w*Col.Load(VecI(offset[x].x without scale, offset[y].y without scale, 0)).rgb; because it is slower and doesn't support wrap/clamp
  228. weight+=w;
  229. }
  230. }
  231. #else
  232. Flt weights[CUBIC_SAMPLES*2][CUBIC_SAMPLES*2]; // [y][x]
  233. UNROLL for(int y=0; y<CUBIC_SAMPLES*2; y++)
  234. UNROLL for(int x=0; x<CUBIC_SAMPLES*2; x++)
  235. {
  236. Flt w=offset_weight[x].x+offset_weight[y].y;
  237. w=(w<Sqr(CUBIC_RANGE) ? CubicMed(Sqrt(w)) : 0);
  238. weights[y][x]=w;
  239. weight +=w;
  240. }
  241. #if CUBIC_QUALITY>=1 // medium quality
  242. UNROLL for(int y=0; y<CUBIC_SAMPLES*2; y++ )
  243. UNROLL for(int x=0; x<CUBIC_SAMPLES*2; x+=2)color+=TexLerpRGB(offset[x].x, offset[x+1].x, offset[y].y, weights[y][x], weights[y][x+1]);
  244. #else // low quality
  245. UNROLL for(int y=0; y<CUBIC_SAMPLES*2; y+=2)
  246. UNROLL for(int x=0; x<CUBIC_SAMPLES*2; x+=2)color+=TexLerpRGB(Vec2(offset[x].x, offset[y].y), Vec2(offset[x+1].x, offset[y+1].y), weights[y][x], weights[y][x+1], weights[y+1][x], weights[y+1][x+1]);
  247. #endif
  248. #endif
  249. return color/weight;
  250. }
  251. /******************************************************************************/
  252. // SHADERS
  253. /******************************************************************************/
  254. Vec4 Draw2DFlat_VS(VtxInput vtx):POSITION {return Vec4(vtx.pos2()*Coords.xy+Coords.zw, REVERSE_DEPTH, 1);}
  255. Vec4 Draw3DFlat_VS(VtxInput vtx):POSITION {return Project(TransformPos(vtx.pos()));}
  256. Vec4 DrawFlat_PS():COLOR {return Color[0];}
  257. TECHNIQUE(Draw2DFlat, Draw2DFlat_VS(), DrawFlat_PS());
  258. TECHNIQUE(Draw3DFlat, Draw3DFlat_VS(), DrawFlat_PS());
  259. #if !DX11 // THERE IS A BUG ON NVIDIA GEFORCE DX10+ when trying to clear normal render target using SetCol "Bool clear_nrm=(_nrm && !NRM_CLEAR_START && ClearNrm());", with D.depth2DOn(true) entire RT is cleared instead of background pixels only, this was verified on Windows 10 GeForce 650m, drivers 381, TODO: check again in the future
  260. TECHNIQUE(SetCol , Draw_VS (), DrawFlat_PS());
  261. #else // this version works OK
  262. void SetCol_VS(VtxInput vtx,
  263. out Vec4 outCol:COLOR ,
  264. out Vec4 outVtx:POSITION)
  265. {
  266. outCol=Color[0];
  267. outVtx=Vec4(vtx.pos2(), !REVERSE_DEPTH, 1); // set Z to be at the end of the viewport, this enables optimizations by optional applying lighting only on solid pixels (no sky/background)
  268. }
  269. Vec4 SetCol_PS(NOPERSP Vec4 inCol:COLOR):COLOR {return inCol;}
  270. TECHNIQUE(SetCol, SetCol_VS(), SetCol_PS());
  271. #endif
  272. /******************************************************************************/
  273. void Draw2DCol_VS(VtxInput vtx,
  274. out VecH4 outCol:COLOR ,
  275. out Vec4 outVtx:POSITION)
  276. {
  277. outCol= vtx.color();
  278. outVtx=Vec4(vtx.pos ().xy*Coords.xy+Coords.zw, REVERSE_DEPTH, 1);
  279. }
  280. Vec4 Draw2DCol_PS(NOPERSP Vec4 inCol:COLOR):COLOR {return inCol;}
  281. TECHNIQUE(Draw2DCol, Draw2DCol_VS(), Draw2DCol_PS());
  282. /******************************************************************************/
  283. void Draw3DCol_VS(VtxInput vtx,
  284. out VecH4 outCol:COLOR ,
  285. out Vec4 outVtx:POSITION)
  286. {
  287. outCol=vtx.color();
  288. outVtx=Project(TransformPos(vtx.pos()));
  289. }
  290. Vec4 Draw3DCol_PS(Vec4 inCol:COLOR):COLOR {return inCol;}
  291. TECHNIQUE(Draw3DCol, Draw3DCol_VS(), Draw3DCol_PS());
  292. /******************************************************************************/
  293. void Draw2DTex_VS(VtxInput vtx,
  294. out Vec2 outTex:TEXCOORD,
  295. out Vec4 outVtx:POSITION)
  296. {
  297. outTex=vtx.tex();
  298. outVtx=Vec4(vtx.pos2()*Coords.xy+Coords.zw, REVERSE_DEPTH, 1);
  299. }
  300. Vec4 Draw2DTex_PS (NOPERSP Vec2 inTex:TEXCOORD):COLOR {return Tex(Col, inTex);}
  301. Vec4 Draw2DTexC_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR {return Tex(Col, inTex)*Color[0]+Color[1];}
  302. Vec4 Draw2DTexA_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR {return Vec4(Tex(Col, inTex).rgb, Step);}
  303. Vec4 DrawTexX_PS (NOPERSP Vec2 inTex:TEXCOORD):COLOR {return Vec4(Tex(Col, inTex).xxx, 1);}
  304. Vec4 DrawTexY_PS (NOPERSP Vec2 inTex:TEXCOORD):COLOR {return Vec4(Tex(Col, inTex).yyy, 1);}
  305. Vec4 DrawTexZ_PS (NOPERSP Vec2 inTex:TEXCOORD):COLOR {return Vec4(Tex(Col, inTex).zzz, 1);}
  306. Vec4 DrawTexW_PS (NOPERSP Vec2 inTex:TEXCOORD):COLOR {return Vec4(Tex(Col, inTex).www, 1);}
  307. Vec4 DrawTexNrm_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  308. {
  309. Vec nrm; nrm.xy=Tex(Col, inTex).xy*2-1; // #MaterialTextureChannelOrder
  310. nrm.z =CalcZ(nrm.xy);
  311. nrm =Normalize(nrm)*0.5f+0.5f;
  312. return Vec4(nrm, 1);
  313. }
  314. TECHNIQUE(Draw2DTex , Draw2DTex_VS(), Draw2DTex_PS());
  315. TECHNIQUE(Draw2DTexC, Draw2DTex_VS(), Draw2DTexC_PS());
  316. TECHNIQUE(DrawTexX , Draw2DTex_VS(), DrawTexX_PS());
  317. TECHNIQUE(DrawTexY , Draw2DTex_VS(), DrawTexY_PS());
  318. TECHNIQUE(DrawTexZ , Draw2DTex_VS(), DrawTexZ_PS());
  319. TECHNIQUE(DrawTexW , Draw2DTex_VS(), DrawTexW_PS());
  320. TECHNIQUE(DrawTexNrm, Draw2DTex_VS(), DrawTexNrm_PS());
  321. TECHNIQUE(Draw , Draw_VS(), Draw2DTex_PS());
  322. TECHNIQUE(DrawC , Draw_VS(), Draw2DTexC_PS());
  323. TECHNIQUE(DrawA , Draw_VS(), Draw2DTexA_PS());
  324. Vec4 DrawTexPoint_PS (NOPERSP Vec2 inTex:TEXCOORD):COLOR {return TexPoint(Col, inTex);}
  325. Vec4 DrawTexPointC_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR {return TexPoint(Col, inTex)*Color[0]+Color[1];}
  326. TECHNIQUE(DrawTexPoint , Draw2DTex_VS(), DrawTexPoint_PS ());
  327. TECHNIQUE(DrawTexPointC, Draw2DTex_VS(), DrawTexPointC_PS());
  328. /******************************************************************************/
  329. void Draw2DTexCol_VS(VtxInput vtx,
  330. out Vec2 outTex:TEXCOORD,
  331. out VecH4 outCol:COLOR ,
  332. out Vec4 outVtx:POSITION)
  333. {
  334. outTex= vtx.tex ();
  335. outCol= vtx.color();
  336. outVtx=Vec4(vtx.pos ().xy*Coords.xy+Coords.zw, REVERSE_DEPTH, 1);
  337. }
  338. Vec4 Draw2DTexCol_PS(NOPERSP Vec2 inTex:TEXCOORD,
  339. NOPERSP VecH4 inCol:COLOR ):COLOR
  340. {
  341. VecH4 col=Tex(Col, inTex);
  342. return col*inCol;
  343. }
  344. TECHNIQUE(Draw2DTexCol, Draw2DTexCol_VS(), Draw2DTexCol_PS());
  345. /******************************************************************************/
  346. void Draw3DTex_VS(VtxInput vtx,
  347. out Vec2 outTex:TEXCOORD,
  348. out VecH4 outFog:COLOR ,
  349. out Vec4 outVtx:POSITION,
  350. uniform Bool fog=false)
  351. {
  352. Vec pos=TransformPos(vtx.pos());
  353. outTex=vtx.tex();
  354. if(fog)outFog=Vec4(FogColor(), AccumulatedDensity(FogDensity(), Length(pos)));
  355. outVtx=Project(pos);
  356. }
  357. Vec4 Draw3DTex_PS(Vec2 inTex:TEXCOORD,
  358. VecH4 inFog:COLOR ,
  359. uniform Bool alpha_test ,
  360. uniform Bool fog ):COLOR
  361. {
  362. VecH4 col=Tex(Col, inTex);
  363. if(alpha_test)clip(col.a-0.5f);
  364. if(fog)col.rgb=Lerp(col.rgb, inFog.rgb, inFog.a);
  365. return col;
  366. }
  367. TECHNIQUE(Draw3DTex , Draw3DTex_VS(false), Draw3DTex_PS(false, false));
  368. TECHNIQUE(Draw3DTexAT , Draw3DTex_VS(false), Draw3DTex_PS(true , false));
  369. TECHNIQUE(Draw3DTexF , Draw3DTex_VS(true ), Draw3DTex_PS(false, true ));
  370. TECHNIQUE(Draw3DTexATF, Draw3DTex_VS(true ), Draw3DTex_PS(true , true ));
  371. /******************************************************************************/
  372. void Draw3DTexCol_VS(VtxInput vtx,
  373. out Vec2 outTex:TEXCOORD,
  374. out VecH4 outCol:COLOR ,
  375. out VecH4 outFog:COLOR1 ,
  376. out Vec4 outVtx:POSITION,
  377. uniform Bool fog=false)
  378. {
  379. Vec pos=TransformPos(vtx.pos());
  380. outTex=vtx.tex ();
  381. outCol=vtx.color();
  382. if(fog)outFog=Vec4(FogColor(), AccumulatedDensity(FogDensity(), Length(pos)));
  383. outVtx=Project(pos);
  384. }
  385. Vec4 Draw3DTexCol_PS(Vec2 inTex:TEXCOORD,
  386. VecH4 inCol:COLOR ,
  387. VecH4 inFog:COLOR1 ,
  388. uniform Bool alpha_test ,
  389. uniform Bool fog ):COLOR
  390. {
  391. VecH4 col=Tex(Col, inTex);
  392. if(alpha_test)clip(col.a-0.5f);
  393. col*=inCol;
  394. if(fog)col.rgb=Lerp(col.rgb, inFog.rgb, inFog.a);
  395. return col;
  396. }
  397. TECHNIQUE(Draw3DTexCol , Draw3DTexCol_VS(false), Draw3DTexCol_PS(false, false));
  398. TECHNIQUE(Draw3DTexColAT , Draw3DTexCol_VS(false), Draw3DTexCol_PS(true , false));
  399. TECHNIQUE(Draw3DTexColF , Draw3DTexCol_VS(true ), Draw3DTexCol_PS(false, true ));
  400. TECHNIQUE(Draw3DTexColATF, Draw3DTexCol_VS(true ), Draw3DTexCol_PS(true , true ));
  401. /******************************************************************************/
  402. Vec4 DrawTexXC_PS(NOPERSP Vec2 inTex:TEXCOORD,
  403. NOPERSP PIXEL,
  404. uniform Bool dither=false):COLOR
  405. {
  406. VecH4 col=Tex(Col, inTex).x*Color[0]+Color[1];
  407. if(dither)col.rgb+=DitherValueColor(pixel);
  408. return col;
  409. }
  410. Vec4 DrawTexWC_PS(NOPERSP Vec2 inTex:TEXCOORD,
  411. NOPERSP PIXEL,
  412. uniform Bool dither=false):COLOR
  413. {
  414. VecH4 col=Tex(Col, inTex).w*Color[0]+Color[1];
  415. if(dither)col.rgb+=DitherValueColor(pixel);
  416. return col;
  417. }
  418. TECHNIQUE(DrawTexXC , Draw_VS(), DrawTexXC_PS());
  419. TECHNIQUE(DrawTexWC , Draw_VS(), DrawTexWC_PS());
  420. TECHNIQUE(DrawTexXCD, Draw_VS(), DrawTexXC_PS(true));
  421. TECHNIQUE(DrawTexWCD, Draw_VS(), DrawTexWC_PS(true));
  422. /******************************************************************************/
  423. Vec4 DrawTexCubicFast_PS(NOPERSP Vec2 inTex:TEXCOORD,
  424. NOPERSP PIXEL,
  425. uniform Bool color,
  426. uniform Bool dither):COLOR
  427. {
  428. VecH4 col=TexCubicFast(inTex);
  429. if(color)col=col*Color[0]+Color[1];
  430. if(dither)col.rgb+=DitherValueColor(pixel);
  431. return col;
  432. }
  433. Vec4 DrawTexCubicFastRGB_PS(NOPERSP Vec2 inTex:TEXCOORD,
  434. NOPERSP PIXEL,
  435. uniform Bool dither=false):COLOR
  436. {
  437. VecH col=TexCubicFastRGB(inTex);
  438. if(dither)col.rgb+=DitherValueColor(pixel);
  439. return Vec4(col, 1);
  440. }
  441. TECHNIQUE(DrawTexCubicFast , Draw2DTex_VS(), DrawTexCubicFast_PS(false, false));
  442. TECHNIQUE(DrawTexCubicFastC , Draw2DTex_VS(), DrawTexCubicFast_PS(true , false));
  443. TECHNIQUE(DrawTexCubicFast1 , Draw_VS(), DrawTexCubicFast_PS(false, false));
  444. TECHNIQUE(DrawTexCubicFastD , Draw_VS(), DrawTexCubicFast_PS(false, true ));
  445. TECHNIQUE(DrawTexCubicFastRGB , Draw_VS(), DrawTexCubicFastRGB_PS());
  446. TECHNIQUE(DrawTexCubicFastRGBD, Draw_VS(), DrawTexCubicFastRGB_PS(true));
  447. /******************************************************************************/
  448. Vec4 DrawTexCubic_PS(NOPERSP Vec2 inTex:TEXCOORD,
  449. NOPERSP PIXEL ,
  450. uniform Bool color ,
  451. uniform Bool dither ):COLOR
  452. {
  453. VecH4 col=TexCubic(inTex);
  454. if(color)col=col*Color[0]+Color[1];
  455. if(dither)col.rgb+=DitherValueColor(pixel);
  456. return col;
  457. }
  458. Vec4 DrawTexCubicRGB_PS(NOPERSP Vec2 inTex:TEXCOORD,
  459. NOPERSP PIXEL ,
  460. uniform Bool dither=false ):COLOR
  461. {
  462. VecH col=TexCubicRGB(inTex);
  463. if(dither)col.rgb+=DitherValueColor(pixel);
  464. return Vec4(col, 1);
  465. }
  466. TECHNIQUE(DrawTexCubic , Draw2DTex_VS(), DrawTexCubic_PS(false, false));
  467. TECHNIQUE(DrawTexCubicC , Draw2DTex_VS(), DrawTexCubic_PS(true , false));
  468. TECHNIQUE(DrawTexCubic1 , Draw_VS(), DrawTexCubic_PS(false, false));
  469. TECHNIQUE(DrawTexCubicD , Draw_VS(), DrawTexCubic_PS(false, true ));
  470. TECHNIQUE(DrawTexCubicRGB , Draw_VS(), DrawTexCubicRGB_PS());
  471. TECHNIQUE(DrawTexCubicRGBD, Draw_VS(), DrawTexCubicRGB_PS(true));
  472. /******************************************************************************/
  473. #if MODEL>=SM_4
  474. Vec4 DrawMs1_PS(NOPERSP PIXEL):COLOR {return TexSample(ColMS, pixel.xy, 0);}
  475. Vec4 DrawMsN_PS(NOPERSP PIXEL):COLOR
  476. {
  477. Vec4 color =TexSample(ColMS, pixel.xy, 0);
  478. UNROLL for(Int i=1; i<MS_SAMPLES; i++)color+=TexSample(ColMS, pixel.xy, i);
  479. return color/MS_SAMPLES;
  480. }
  481. Vec4 DrawMsM_PS(NOPERSP PIXEL,
  482. UInt index:SV_SampleIndex):COLOR
  483. {
  484. return TexSample(ColMS, pixel.xy, index);
  485. }
  486. TECHNIQUE (DrawMs1, DrawPixel_VS(), DrawMs1_PS());
  487. TECHNIQUE (DrawMsN, DrawPixel_VS(), DrawMsN_PS());
  488. TECHNIQUE_4_1(DrawMsM, DrawPixel_VS(), DrawMsM_PS());
  489. #endif
  490. /******************************************************************************/
  491. void DrawMask_VS(VtxInput vtx,
  492. out Vec2 outTexC:TEXCOORD0,
  493. out Vec2 outTexM:TEXCOORD1,
  494. out Vec4 outVtx :POSITION )
  495. {
  496. outTexC=vtx.tex ();
  497. outTexM=vtx.tex1();
  498. outVtx =Vec4(vtx.pos2()*Coords.xy+Coords.zw, REVERSE_DEPTH, 1);
  499. }
  500. Vec4 DrawMask_PS(NOPERSP Vec2 inTexC:TEXCOORD0,
  501. NOPERSP Vec2 inTexM:TEXCOORD1):COLOR
  502. {
  503. VecH4 col =Tex(Col , inTexC)*Color[0]+Color[1];
  504. col.a*=Tex(Col1, inTexM).a;
  505. return col;
  506. }
  507. TECHNIQUE(DrawMask, DrawMask_VS(), DrawMask_PS());
  508. /******************************************************************************/
  509. void DrawCubeFace_VS(VtxInput vtx,
  510. out Vec outTex:TEXCOORD,
  511. out Vec4 outVtx:POSITION)
  512. {
  513. outTex=Vec (vtx.tex(), vtx.size());
  514. outVtx=Vec4(vtx.pos2()*Coords.xy+Coords.zw, REVERSE_DEPTH, 1);
  515. }
  516. Vec4 DrawCubeFace_PS(NOPERSP Vec inTex:TEXCOORD):COLOR {return TexCube(Rfl, inTex)*Color[0]+Color[1];}
  517. TECHNIQUE(DrawCubeFace, DrawCubeFace_VS(), DrawCubeFace_PS());
  518. /******************************************************************************/
  519. BUFFER(Font)
  520. Flt FontShadow,
  521. FontContrast=1,
  522. FontShade,
  523. FontDepth;
  524. BUFFER_END
  525. void Font_VS(VtxInput vtx,
  526. out Vec2 outTex :TEXCOORD0,
  527. out Flt outShade:TEXCOORD1,
  528. out Vec4 outVtx :POSITION ,
  529. uniform Bool custom_depth)
  530. {
  531. outTex = vtx.tex ();
  532. outShade= vtx.size();
  533. if(custom_depth)outVtx =Vec4(vtx.pos ().xy*Coords.xy+Coords.zw, DelinearizeDepth(FontDepth), 1);
  534. else outVtx =Vec4(vtx.pos ().xy*Coords.xy+Coords.zw, REVERSE_DEPTH, 1);
  535. }
  536. Vec4 Font_PS
  537. (
  538. NOPERSP Vec2 inTex :TEXCOORD0,
  539. NOPERSP Flt inShade:TEXCOORD1
  540. ):COLOR
  541. {
  542. // c=color, s=shadow, a=alpha
  543. // final=dest *(1-s) + 0*s; -> background after applying shadow
  544. // final=final*(1-a) + c*a; -> background after applying shadow after applying color
  545. // final=(dest*(1-s) + 0*s)*(1-a) + c*a;
  546. // final=dest*(1-s)*(1-a) + c*a;
  547. #if DX11
  548. Vec2 as=Col.Sample(SamplerFont, inTex).ga;
  549. #else
  550. Vec2 as=Tex(Col, inTex).ga;
  551. #endif
  552. Flt a =Sat(as.x*FontContrast), // font opacity, "Min(as.x*FontContrast, 1)", scale up by 'FontContrast' to improve quality when font is very small
  553. s = as.y*FontShadow ; // font shadow
  554. // Flt final_alpha=1-(1-s)*(1-a);
  555. // 1-(1-s)*(1-a)
  556. // 1-(1-a-s+sa)
  557. // 1-1+a+s-sa
  558. // a + s - s*a
  559. Flt final_alpha=a+s-s*a;
  560. #if 1 // use for ALPHA_BLEND (this option is better because we don't need to set blend state specificaly for drawing fonts)
  561. return Vec4(Color[0].rgb*(Lerp(FontShade, 1, Sat(inShade))*a/(final_alpha+EPS)), Color[0].a*final_alpha); // NaN, division by 'final_alpha' is required because of the hardware ALPHA_BLEND formula, without it we would get dark borders around the font
  562. #else // use for ALPHA_MERGE
  563. return Vec4(Color[0].rgb*(Lerp(FontShade, 1, Sat(inShade))*a*Color[0].a), Color[0].a*final_alpha);
  564. #endif
  565. }
  566. TECHNIQUE(Font , Font_VS(false), Font_PS());
  567. TECHNIQUE(FontD, Font_VS(true ), Font_PS());
  568. /******************************************************************************/
  569. void Laser_VS(VtxInput vtx,
  570. out Vec outPos:TEXCOORD0,
  571. out Vec outNrm:TEXCOORD1,
  572. out Vec4 outVtx:POSITION ,
  573. uniform Bool normals )
  574. {
  575. if(normals)outNrm=TransformDir(vtx.nrm());
  576. outVtx=Project(outPos=TransformPos(vtx.pos()));
  577. }
  578. void Laser_PS(Vec inPos:TEXCOORD0,
  579. Vec inNrm:TEXCOORD1,
  580. out DeferredSolidOutput output ,
  581. uniform Bool normals )
  582. {
  583. if(normals)
  584. {
  585. inNrm=Normalize(inNrm);
  586. Flt stp=Max (-Dot(inNrm, Normalize(inPos)), -inNrm.z);
  587. stp=Sat (stp);
  588. stp=Pow (stp, Half(Step));
  589. Vec4 col=Lerp(Color[0], Color[1], stp);
  590. output.color(col.rgb);
  591. output.glow (col.a );
  592. }else
  593. {
  594. output.color(Color[0].rgb);
  595. output.glow (Color[0].a );
  596. }
  597. output.normal (0);
  598. output.specular(0);
  599. output.velocity(0, inPos);
  600. }
  601. TECHNIQUE(Laser , Laser_VS(false), Laser_PS(false));
  602. TECHNIQUE(LaserN, Laser_VS(true ), Laser_PS(true ));
  603. /******************************************************************************/
  604. void Simple_VS(VtxInput vtx,
  605. out Vec2 outTex:TEXCOORD,
  606. out VecH4 outCol:COLOR ,
  607. out Vec4 outVtx:POSITION)
  608. {
  609. outTex=vtx.tex();
  610. outCol=vtx.color();
  611. outVtx=Project(TransformPos(vtx.pos()));
  612. }
  613. Vec4 Simple_PS(Vec2 inTex:TEXCOORD,
  614. VecH4 inCol:COLOR ):COLOR
  615. {
  616. return Tex(Col, inTex)*inCol;
  617. }
  618. TECHNIQUE(Simple, Simple_VS(), Simple_PS());
  619. /******************************************************************************/
  620. BUFFER(LocalFog)
  621. Vec4 LocalFogColor_Density; // rgb=color, a=density
  622. Vec LocalFogInside;
  623. BUFFER_END
  624. inline Vec LocalFogColor () {return LocalFogColor_Density.rgb;}
  625. inline Flt LocalFogDensity() {return LocalFogColor_Density.a ;}
  626. /******************************************************************************/
  627. // TODO: optimize fog shaders
  628. void FogBox_VS(VtxInput vtx,
  629. out Vec4 outVtx :POSITION ,
  630. out Vec outPos :TEXCOORD0,
  631. out Vec outTex :TEXCOORD1,
  632. out Vec4 outSize:TEXCOORD2,
  633. out Matrix3 outMat :TEXCOORD3)
  634. {
  635. outMat[0]=Normalize(MatrixX(ViewMatrix[0])); outSize.x=Length(MatrixX(ViewMatrix[0]));
  636. outMat[1]=Normalize(MatrixY(ViewMatrix[0])); outSize.y=Length(MatrixY(ViewMatrix[0]));
  637. outMat[2]=Normalize(MatrixZ(ViewMatrix[0])); outSize.z=Length(MatrixZ(ViewMatrix[0]));
  638. outSize.w=Max(outSize.xyz);
  639. // convert to texture space (0..1)
  640. outTex=vtx.pos()*0.5f+0.5f;
  641. outVtx=Project(outPos=TransformPos(vtx.pos()));
  642. }
  643. void FogBox_PS
  644. (
  645. PIXEL,
  646. Vec inPos :TEXCOORD0,
  647. Vec inTex :TEXCOORD1,
  648. Vec4 inSize:TEXCOORD2,
  649. Matrix3 inMat :TEXCOORD3,
  650. out Vec4 color:COLOR0,
  651. out Vec4 alpha:COLOR1,
  652. uniform Bool height
  653. )
  654. {
  655. Flt z =TexDepthPoint(PIXEL_TO_SCREEN);
  656. Vec pos=inTex,
  657. dir=Normalize(inPos); dir*=Min((SQRT3*2)*inSize.w, (z-inPos.z)/dir.z);
  658. dir=mul(inMat, dir); // convert to box space
  659. // convert to texture space (0..1)
  660. dir=dir/(2*inSize.xyz);
  661. Vec end=pos+dir;
  662. if(end.x<0)end+=(0-end.x)/dir.x*dir;
  663. if(end.x>1)end+=(1-end.x)/dir.x*dir;
  664. if(end.y<0)end+=(0-end.y)/dir.y*dir;
  665. if(end.y>1)end+=(1-end.y)/dir.y*dir;
  666. if(end.z<0)end+=(0-end.z)/dir.z*dir;
  667. if(end.z>1)end+=(1-end.z)/dir.z*dir;
  668. dir =end-pos;
  669. dir*=inSize.xyz;
  670. Flt len =Length(dir)/inSize.w;
  671. Flt dns=LocalFogDensity();
  672. if(height){dns*=1-Avg(pos.y, end.y); len*=3;}
  673. color.rgb=LocalFogColor();
  674. color.a =AccumulatedDensity(dns, len);
  675. alpha =color.a;
  676. }
  677. void FogBoxI_VS(VtxInput vtx,
  678. out Vec2 outTex :TEXCOORD0,
  679. out Vec2 outPosXY:TEXCOORD1,
  680. out Vec4 outSize :TEXCOORD2,
  681. out Matrix3 outMat :TEXCOORD3,
  682. out Vec4 outVtx :POSITION )
  683. {
  684. outMat[0]=Normalize(MatrixX(ViewMatrix[0])); outSize.x=Length(MatrixX(ViewMatrix[0]));
  685. outMat[1]=Normalize(MatrixY(ViewMatrix[0])); outSize.y=Length(MatrixY(ViewMatrix[0]));
  686. outMat[2]=Normalize(MatrixZ(ViewMatrix[0])); outSize.z=Length(MatrixZ(ViewMatrix[0]));
  687. outSize.w=Max(outSize.xyz);
  688. outVtx =Vec4(vtx.pos2(), !REVERSE_DEPTH, 1); AdjustPixelCenter(outVtx); // set Z to be at the end of the viewport, this enables optimizations by optional applying lighting only on solid pixels (no sky/background)
  689. outTex =vtx.tex();
  690. outPosXY=ScreenToPosXY(outTex);
  691. }
  692. void FogBoxI_PS
  693. (
  694. NOPERSP Vec2 inTex :TEXCOORD0,
  695. NOPERSP Vec2 inPosXY:TEXCOORD1,
  696. NOPERSP Vec4 inSize :TEXCOORD2,
  697. NOPERSP Matrix3 inMat :TEXCOORD3,
  698. out Vec4 color:COLOR0,
  699. out Vec4 alpha:COLOR1,
  700. uniform Int inside,
  701. uniform Bool height
  702. )
  703. {
  704. Vec pos=GetPosPoint(inTex, inPosXY),
  705. dir=Normalize(pos); dir*=Min((SQRT3*2)*inSize.w, (pos.z-Viewport.from)/dir.z);
  706. dir=mul(inMat, dir); // convert to box space
  707. // convert to texture space (0..1)
  708. pos=LocalFogInside/(2*inSize.xyz)+0.5f;
  709. dir=dir /(2*inSize.xyz);
  710. if(inside==0)
  711. {
  712. if(pos.x<0)pos+=(0-pos.x)/dir.x*dir;
  713. if(pos.x>1)pos+=(1-pos.x)/dir.x*dir;
  714. if(pos.y<0)pos+=(0-pos.y)/dir.y*dir;
  715. if(pos.y>1)pos+=(1-pos.y)/dir.y*dir;
  716. if(pos.z<0)pos+=(0-pos.z)/dir.z*dir;
  717. if(pos.z>1)pos+=(1-pos.z)/dir.z*dir;
  718. }
  719. Vec end=pos+dir;
  720. if(end.x<0)end+=(0-end.x)/dir.x*dir;
  721. if(end.x>1)end+=(1-end.x)/dir.x*dir;
  722. if(end.y<0)end+=(0-end.y)/dir.y*dir;
  723. if(end.y>1)end+=(1-end.y)/dir.y*dir;
  724. if(end.z<0)end+=(0-end.z)/dir.z*dir;
  725. if(end.z>1)end+=(1-end.z)/dir.z*dir;
  726. dir =end-pos;
  727. dir*=inSize.xyz;
  728. Flt len =Length(dir)/inSize.w;
  729. Flt dns=LocalFogDensity();
  730. if(height){dns*=1-Avg(pos.y, end.y); len*=3;}
  731. color.rgb=LocalFogColor();
  732. color.a =AccumulatedDensity(dns, len);
  733. alpha =color.a;
  734. }
  735. void FogBall_VS(VtxInput vtx,
  736. out Vec4 outVtx :POSITION ,
  737. out Vec outPos :TEXCOORD0,
  738. out Vec outTex :TEXCOORD1,
  739. out Flt outSize:TEXCOORD2)
  740. {
  741. outTex =vtx.pos();
  742. outSize=Length(MatrixX(ViewMatrix[0]));
  743. outVtx =Project(outPos=TransformPos(vtx.pos()));
  744. }
  745. void FogBall_PS
  746. (
  747. PIXEL,
  748. Vec inPos :TEXCOORD0,
  749. Vec inTex :TEXCOORD1,
  750. Flt inSize:TEXCOORD2,
  751. out Vec4 color:COLOR0,
  752. out Vec4 alpha:COLOR1
  753. )
  754. {
  755. Flt z =TexDepthPoint(PIXEL_TO_SCREEN);
  756. Vec pos=Normalize (inTex),
  757. dir=Normalize (inPos); Flt max_length=(z-inPos.z)/(dir.z*inSize);
  758. dir=Transform3 (dir, CamMatrix); // convert to ball space
  759. // collision detection
  760. Vec p =PointOnPlane(pos, dir);
  761. Flt s =Length (p );
  762. s =Sat (1-s*s );
  763. Vec end=p+Sqrt(s)*dir;
  764. Flt len=Min(Dist(pos, end), max_length);
  765. Flt dns=LocalFogDensity()*s;
  766. color.rgb=LocalFogColor();
  767. color.a =AccumulatedDensity(dns, len);
  768. alpha =color.a;
  769. }
  770. void FogBallI_VS(VtxInput vtx,
  771. out Vec2 outTex :TEXCOORD0,
  772. out Vec2 outPosXY:TEXCOORD1,
  773. out Flt outSize :TEXCOORD2,
  774. out Vec4 outVtx :POSITION )
  775. {
  776. outVtx =Vec4(vtx.pos2(), !REVERSE_DEPTH, 1); AdjustPixelCenter(outVtx); // set Z to be at the end of the viewport, this enables optimizations by optional applying lighting only on solid pixels (no sky/background)
  777. outTex =vtx.tex();
  778. outPosXY=ScreenToPosXY(outTex);
  779. outSize =Length(MatrixX(ViewMatrix[0]));
  780. }
  781. void FogBallI_PS
  782. (
  783. NOPERSP Vec2 inTex :TEXCOORD0,
  784. NOPERSP Vec2 inPosXY:TEXCOORD1,
  785. NOPERSP Flt inSize :TEXCOORD2,
  786. out Vec4 color:COLOR0,
  787. out Vec4 alpha:COLOR1,
  788. uniform Int inside
  789. )
  790. {
  791. Vec pos=GetPosPoint(inTex, inPosXY),
  792. dir=Normalize (pos); Flt max_length=(pos.z-Viewport.from)/(dir.z*inSize);
  793. dir=Transform3(dir, CamMatrix); // convert to ball space
  794. pos=LocalFogInside/inSize;
  795. // collision detection
  796. Vec p =PointOnPlane(pos, dir);
  797. Flt s =Length (p );
  798. s =Sat (1-s*s );
  799. Vec end=p+dir*Sqrt(s);
  800. Flt len=Min(Dist(pos, end), max_length);
  801. Flt dns=LocalFogDensity()*s;
  802. color.rgb=LocalFogColor();
  803. color.a =AccumulatedDensity(dns, len);
  804. alpha =color.a;
  805. }
  806. TECHNIQUE(FogBox , FogBox_VS(), FogBox_PS( false));
  807. TECHNIQUE(FogBox0, FogBoxI_VS(), FogBoxI_PS(0, false));
  808. TECHNIQUE(FogBox1, FogBoxI_VS(), FogBoxI_PS(1, false));
  809. TECHNIQUE(FogHgt , FogBox_VS(), FogBox_PS( true));
  810. TECHNIQUE(FogHgt0, FogBoxI_VS(), FogBoxI_PS(0, true));
  811. TECHNIQUE(FogHgt1, FogBoxI_VS(), FogBoxI_PS(1, true));
  812. TECHNIQUE(FogBall , FogBall_VS(), FogBall_PS( ));
  813. TECHNIQUE(FogBall0, FogBallI_VS(), FogBallI_PS(0));
  814. TECHNIQUE(FogBall1, FogBallI_VS(), FogBallI_PS(1));
  815. /******************************************************************************/
  816. struct VolumeClass
  817. {
  818. Flt min_steps,
  819. max_steps,
  820. density_factor,
  821. precision;
  822. Vec size ,
  823. pixels,
  824. inside;
  825. };
  826. BUFFER(Volume)
  827. VolumeClass Volume;
  828. BUFFER_END
  829. void Volume_VS(VtxInput vtx,
  830. out Vec4 outVtx:POSITION ,
  831. out Vec outPos:TEXCOORD0,
  832. out Vec outTex:TEXCOORD1,
  833. out Matrix3 outMat:TEXCOORD2,
  834. uniform Int inside )
  835. {
  836. outMat[0]=Normalize(MatrixX(ViewMatrix[0]));
  837. outMat[1]=Normalize(MatrixY(ViewMatrix[0]));
  838. outMat[2]=Normalize(MatrixZ(ViewMatrix[0]));
  839. // convert to texture space (0..1)
  840. if(inside)outTex=Volume.inside/(2*Volume.size)+0.5f;
  841. else outTex=vtx.pos()*0.5f+0.5f;
  842. outVtx=Project(outPos=TransformPos(vtx.pos()));
  843. }
  844. void Volume_PS
  845. (
  846. PIXEL,
  847. Vec inPos:TEXCOORD0,
  848. Vec inTex:TEXCOORD1,
  849. Matrix3 inMat:TEXCOORD2,
  850. out Vec4 color:COLOR0,
  851. out Vec4 alpha:COLOR1,
  852. uniform Int inside,
  853. uniform Bool LA=false
  854. )
  855. {
  856. Flt z =TexDepthPoint(PIXEL_TO_SCREEN);
  857. Vec pos=inTex;
  858. Vec dir=Normalize(inPos); dir*=Min((SQRT3*2)*Max(Volume.size), (z-(inside ? Viewport.from : inPos.z))/dir.z);
  859. dir=mul(inMat, dir); // convert to box space
  860. // convert to texture space (0..1)
  861. dir=dir/(2*Volume.size);
  862. if(inside==1)
  863. {
  864. if(pos.x<0)pos+=(0-pos.x)/dir.x*dir;
  865. if(pos.x>1)pos+=(1-pos.x)/dir.x*dir;
  866. if(pos.y<0)pos+=(0-pos.y)/dir.y*dir;
  867. if(pos.y>1)pos+=(1-pos.y)/dir.y*dir;
  868. if(pos.z<0)pos+=(0-pos.z)/dir.z*dir;
  869. if(pos.z>1)pos+=(1-pos.z)/dir.z*dir;
  870. }
  871. Vec end=pos+dir;
  872. if(end.x<0)end+=(0-end.x)/dir.x*dir;
  873. if(end.x>1)end+=(1-end.x)/dir.x*dir;
  874. if(end.y<0)end+=(0-end.y)/dir.y*dir;
  875. if(end.y>1)end+=(1-end.y)/dir.y*dir;
  876. if(end.z<0)end+=(0-end.z)/dir.z*dir;
  877. if(end.z>1)end+=(1-end.z)/dir.z*dir;
  878. dir =end-pos;
  879. Flt pixels =Length(dir *Volume.pixels);
  880. Int steps =Mid (pixels*Volume.precision, Volume.min_steps, Volume.max_steps);
  881. Flt steps_speed= pixels/steps;
  882. Flt density_factor=Volume.density_factor;
  883. density_factor=1-Pow(1-density_factor, steps_speed); // modify by steps speed
  884. dir/=steps;
  885. if(LA)
  886. {
  887. Vec2 col=0;
  888. LOOP for(Int i=0; i<steps; i++)
  889. {
  890. Vec2 sample=Tex3DLod(Vol, pos).rg;
  891. Flt alpha =sample.g*density_factor*(1-col.g);
  892. col.r+=alpha*sample.r;
  893. col.g+=alpha;
  894. pos+=dir;
  895. }
  896. col.r/=col.g+EPS; // NaN
  897. color=col.rrrg*Color[0]+Color[1];
  898. alpha=color.a;
  899. }else
  900. {
  901. Vec4 col=0;
  902. LOOP for(Int i=0; i<steps; i++)
  903. {
  904. Vec4 sample=Tex3DLod(Vol, pos);
  905. Flt alpha =sample.a*density_factor*(1-col.a);
  906. col.rgb+=alpha*sample.rgb;
  907. col.a +=alpha;
  908. pos+=dir;
  909. }
  910. col.rgb/=col.a+EPS; // NaN
  911. color=col*Color[0]+Color[1];
  912. alpha=color.a;
  913. }
  914. }
  915. TECHNIQUE(Volume0, Volume_VS(0), Volume_PS(0));
  916. TECHNIQUE(Volume1, Volume_VS(1), Volume_PS(1));
  917. TECHNIQUE(Volume2, Volume_VS(2), Volume_PS(2));
  918. TECHNIQUE(Volume0LA, Volume_VS(0), Volume_PS(0, true));
  919. TECHNIQUE(Volume1LA, Volume_VS(1), Volume_PS(1, true));
  920. TECHNIQUE(Volume2LA, Volume_VS(2), Volume_PS(2, true));
  921. /******************************************************************************/
  922. inline VecH TexYUV(Vec2 inTex)
  923. {
  924. /*Flt y=Tex(Col , inTex).x,
  925. u=Tex(Col1, inTex).x,
  926. v=Tex(Col2, inTex).x;
  927. Flt r=1.1643f*(y-0.0625f) + 1.5958f*(v-0.5f),
  928. g=1.1643f*(y-0.0625f) - 0.39173f*(u-0.5f) - 0.8129f*(v-0.5f),
  929. b=1.1643f*(y-0.0625f) + 2.017f *(u-0.5f) ;*/
  930. // keep 'Tex' in case images have LOD's (however unlikely)
  931. Half y=Tex(Col , inTex).x*1.1643-0.07276875,
  932. u=Tex(Col1, inTex).x -0.5,
  933. v=Tex(Col2, inTex).x -0.5;
  934. return VecH(y + 1.5958*v,
  935. y - 0.39173*u - 0.8129*v,
  936. y + 2.017 *u );
  937. }
  938. VecH4 YUV_PS (NOPERSP Vec2 inTex:TEXCOORD):COLOR {return VecH4(TexYUV(inTex), 1);}
  939. VecH4 YUVA_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR {return VecH4(TexYUV(inTex), Tex(Col3, inTex).x*1.1643-0.07276875);} // need to MulAdd because alpha image assumes to come from another YUV video
  940. TECHNIQUE(YUV , Draw2DTex_VS(), YUV_PS ());
  941. TECHNIQUE(YUVA, Draw2DTex_VS(), YUVA_PS());
  942. /******************************************************************************/
  943. // BLUR
  944. /******************************************************************************/
  945. #define WEIGHT4_0 0.250000000f
  946. #define WEIGHT4_1 0.213388354f
  947. #define WEIGHT4_2 0.124999993f
  948. #define WEIGHT4_3 0.036611654f
  949. // WEIGHT4_0 + WEIGHT4_1*2 + WEIGHT4_2*2 + WEIGHT4_3*2 = 1
  950. #define WEIGHT5_0 0.200000014f
  951. #define WEIGHT5_1 0.180901707f
  952. #define WEIGHT5_2 0.130901704f
  953. #define WEIGHT5_3 0.069098287f
  954. #define WEIGHT5_4 0.019098295f
  955. // WEIGHT5_0 + WEIGHT5_1*2 + WEIGHT5_2*2 + WEIGHT5_3*2 + WEIGHT5_4*2 = 1
  956. #define WEIGHT6_0 0.166666668f
  957. #define WEIGHT6_1 0.155502122f
  958. #define WEIGHT6_2 0.125000001f
  959. #define WEIGHT6_3 0.083333329f
  960. #define WEIGHT6_4 0.041666662f
  961. #define WEIGHT6_5 0.011164551f
  962. // WEIGHT6_0 + WEIGHT6_1*2 + WEIGHT6_2*2 + WEIGHT6_3*2 + WEIGHT6_4*2 + WEIGHT6_5*2 = 1
  963. // !!
  964. // !! If changing number of samples then change also SHADER_BLUR_RANGE !!
  965. // !!
  966. #define TEST_BLUR 0
  967. #if TEST_BLUR
  968. Flt Test, Samples, Mode;
  969. Flt Weight(Int i, Int s)
  970. {
  971. return Mode ? Gaussian(Mode*i/Flt(s+1)) : BlendSmoothSin(i/Flt(s+1));
  972. }
  973. #endif
  974. Vec4 BlurX_PS(NOPERSP Vec2 inTex:TEXCOORD,
  975. uniform Int samples ):COLOR
  976. {
  977. #if TEST_BLUR
  978. if(Test){Int s=Round(Samples); Vec4 color=0; Flt weight=0; for(Int i=-s; i<=s; i++){Flt w=Weight(Abs(i), s); weight+=w; color.rgb+=w*TexPoint(Col, inTex+ColSize.xy*Vec2(i, 0)).rgb;} color.rgb/=weight; return color;}
  979. #endif
  980. // use linear filtering because texcoords aren't rounded
  981. if(samples==4) // -3 .. 3
  982. return Vec4(TexLod(Col, inTex+ColSize.xy*Vec2( 0+WEIGHT4_1/(WEIGHT4_0/2+WEIGHT4_1), 0)).rgb*(WEIGHT4_0/2+WEIGHT4_1) // 0th sample is divided by 2 because it's obtained here and line below to preserve symmetry
  983. +TexLod(Col, inTex+ColSize.xy*Vec2(-0-WEIGHT4_1/(WEIGHT4_0/2+WEIGHT4_1), 0)).rgb*(WEIGHT4_0/2+WEIGHT4_1)
  984. +TexLod(Col, inTex+ColSize.xy*Vec2( 2+WEIGHT4_3/(WEIGHT4_2 +WEIGHT4_3), 0)).rgb*(WEIGHT4_2 +WEIGHT4_3)
  985. +TexLod(Col, inTex+ColSize.xy*Vec2(-2-WEIGHT4_3/(WEIGHT4_2 +WEIGHT4_3), 0)).rgb*(WEIGHT4_2 +WEIGHT4_3), 0);
  986. if(samples==5) // -4 .. 4
  987. return Vec4(TexLod(Col, inTex ).rgb* WEIGHT5_0
  988. +TexLod(Col, inTex+ColSize.xy*Vec2( 1+WEIGHT5_2/(WEIGHT5_1+WEIGHT5_2), 0)).rgb*(WEIGHT5_1+WEIGHT5_2)
  989. +TexLod(Col, inTex+ColSize.xy*Vec2(-1-WEIGHT5_2/(WEIGHT5_1+WEIGHT5_2), 0)).rgb*(WEIGHT5_1+WEIGHT5_2)
  990. +TexLod(Col, inTex+ColSize.xy*Vec2( 3+WEIGHT5_4/(WEIGHT5_3+WEIGHT5_4), 0)).rgb*(WEIGHT5_3+WEIGHT5_4)
  991. +TexLod(Col, inTex+ColSize.xy*Vec2(-3-WEIGHT5_4/(WEIGHT5_3+WEIGHT5_4), 0)).rgb*(WEIGHT5_3+WEIGHT5_4), 0);
  992. if(samples==6) // -5 .. 5
  993. return Vec4(TexLod(Col, inTex+ColSize.xy*Vec2( 0+WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1), 0)).rgb*(WEIGHT6_0/2+WEIGHT6_1) // 0th sample is divided by 2 because it's obtained here and line below to preserve symmetry
  994. +TexLod(Col, inTex+ColSize.xy*Vec2(-0-WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1), 0)).rgb*(WEIGHT6_0/2+WEIGHT6_1)
  995. +TexLod(Col, inTex+ColSize.xy*Vec2( 2+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3), 0)).rgb*(WEIGHT6_2 +WEIGHT6_3)
  996. +TexLod(Col, inTex+ColSize.xy*Vec2(-2-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3), 0)).rgb*(WEIGHT6_2 +WEIGHT6_3)
  997. +TexLod(Col, inTex+ColSize.xy*Vec2( 4+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5), 0)).rgb*(WEIGHT6_4 +WEIGHT6_5)
  998. +TexLod(Col, inTex+ColSize.xy*Vec2(-4-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5), 0)).rgb*(WEIGHT6_4 +WEIGHT6_5), 0);
  999. }
  1000. Vec4 BlurY_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1001. uniform Int samples ):COLOR
  1002. {
  1003. #if TEST_BLUR
  1004. if(Test){Int s=Round(Samples); Vec4 color=0; Flt weight=0; for(Int i=-s; i<=s; i++){Flt w=Weight(Abs(i), s); weight+=w; color.rgb+=w*TexPoint(Col, inTex+ColSize.xy*Vec2(0, i)).rgb;} color.rgb/=weight; return color;}
  1005. #endif
  1006. // use linear filtering because texcoords aren't rounded
  1007. if(samples==4) // -3 .. 3
  1008. return Vec4(TexLod(Col, inTex+ColSize.xy*Vec2(0, 0+WEIGHT4_1/(WEIGHT4_0/2+WEIGHT4_1))).rgb*(WEIGHT4_0/2+WEIGHT4_1) // 0th sample is divided by 2 because it's obtained here and line below to preserve symmetry
  1009. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -0-WEIGHT4_1/(WEIGHT4_0/2+WEIGHT4_1))).rgb*(WEIGHT4_0/2+WEIGHT4_1)
  1010. +TexLod(Col, inTex+ColSize.xy*Vec2(0, 2+WEIGHT4_3/(WEIGHT4_2 +WEIGHT4_3))).rgb*(WEIGHT4_2 +WEIGHT4_3)
  1011. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -2-WEIGHT4_3/(WEIGHT4_2 +WEIGHT4_3))).rgb*(WEIGHT4_2 +WEIGHT4_3), 0);
  1012. if(samples==5) // -4 .. 4
  1013. return Vec4(TexLod(Col, inTex ).rgb* WEIGHT5_0
  1014. +TexLod(Col, inTex+ColSize.xy*Vec2(0, 1+WEIGHT5_2/(WEIGHT5_1+WEIGHT5_2))).rgb*(WEIGHT5_1+WEIGHT5_2)
  1015. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -1-WEIGHT5_2/(WEIGHT5_1+WEIGHT5_2))).rgb*(WEIGHT5_1+WEIGHT5_2)
  1016. +TexLod(Col, inTex+ColSize.xy*Vec2(0, 3+WEIGHT5_4/(WEIGHT5_3+WEIGHT5_4))).rgb*(WEIGHT5_3+WEIGHT5_4)
  1017. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -3-WEIGHT5_4/(WEIGHT5_3+WEIGHT5_4))).rgb*(WEIGHT5_3+WEIGHT5_4), 0);
  1018. if(samples==6) // -5 .. 5
  1019. return Vec4(TexLod(Col, inTex+ColSize.xy*Vec2(0, 0+WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1))).rgb*(WEIGHT6_0/2+WEIGHT6_1) // 0th sample is divided by 2 because it's obtained here and line below to preserve symmetry
  1020. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -0-WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1))).rgb*(WEIGHT6_0/2+WEIGHT6_1)
  1021. +TexLod(Col, inTex+ColSize.xy*Vec2(0, 2+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3))).rgb*(WEIGHT6_2 +WEIGHT6_3)
  1022. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -2-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3))).rgb*(WEIGHT6_2 +WEIGHT6_3)
  1023. +TexLod(Col, inTex+ColSize.xy*Vec2(0, 4+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5))).rgb*(WEIGHT6_4 +WEIGHT6_5)
  1024. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -4-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5))).rgb*(WEIGHT6_4 +WEIGHT6_5), 0);
  1025. }
  1026. Vec4 BlurX_X_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1027. {
  1028. // use linear filtering because texcoords aren't rounded
  1029. return TexLod(Col, inTex+ColSize.xy*Vec2( 0+WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1), 0)).x*(WEIGHT6_0/2+WEIGHT6_1)
  1030. +TexLod(Col, inTex+ColSize.xy*Vec2(-0-WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1), 0)).x*(WEIGHT6_0/2+WEIGHT6_1)
  1031. +TexLod(Col, inTex+ColSize.xy*Vec2( 2+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3), 0)).x*(WEIGHT6_2 +WEIGHT6_3)
  1032. +TexLod(Col, inTex+ColSize.xy*Vec2(-2-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3), 0)).x*(WEIGHT6_2 +WEIGHT6_3)
  1033. +TexLod(Col, inTex+ColSize.xy*Vec2( 4+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5), 0)).x*(WEIGHT6_4 +WEIGHT6_5)
  1034. +TexLod(Col, inTex+ColSize.xy*Vec2(-4-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5), 0)).x*(WEIGHT6_4 +WEIGHT6_5);
  1035. }
  1036. Vec4 BlurX_W_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1037. {
  1038. // use linear filtering because texcoords aren't rounded
  1039. return TexLod(Col, inTex+ColSize.xy*Vec2( 0+WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1), 0)).w*(WEIGHT6_0/2+WEIGHT6_1)
  1040. +TexLod(Col, inTex+ColSize.xy*Vec2(-0-WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1), 0)).w*(WEIGHT6_0/2+WEIGHT6_1)
  1041. +TexLod(Col, inTex+ColSize.xy*Vec2( 2+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3), 0)).w*(WEIGHT6_2 +WEIGHT6_3)
  1042. +TexLod(Col, inTex+ColSize.xy*Vec2(-2-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3), 0)).w*(WEIGHT6_2 +WEIGHT6_3)
  1043. +TexLod(Col, inTex+ColSize.xy*Vec2( 4+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5), 0)).w*(WEIGHT6_4 +WEIGHT6_5)
  1044. +TexLod(Col, inTex+ColSize.xy*Vec2(-4-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5), 0)).w*(WEIGHT6_4 +WEIGHT6_5);
  1045. }
  1046. Vec4 BlurY_X_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1047. {
  1048. // use linear filtering because texcoords aren't rounded
  1049. return TexLod(Col, inTex+ColSize.xy*Vec2(0, 0+WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1))).x*(WEIGHT6_0/2+WEIGHT6_1)
  1050. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -0-WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1))).x*(WEIGHT6_0/2+WEIGHT6_1)
  1051. +TexLod(Col, inTex+ColSize.xy*Vec2(0, 2+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3))).x*(WEIGHT6_2 +WEIGHT6_3)
  1052. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -2-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3))).x*(WEIGHT6_2 +WEIGHT6_3)
  1053. +TexLod(Col, inTex+ColSize.xy*Vec2(0, 4+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5))).x*(WEIGHT6_4 +WEIGHT6_5)
  1054. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -4-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5))).x*(WEIGHT6_4 +WEIGHT6_5);
  1055. }
  1056. Vec4 BlurY_W_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1057. {
  1058. // use linear filtering because texcoords aren't rounded
  1059. return TexLod(Col, inTex+ColSize.xy*Vec2(0, 0+WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1))).w*(WEIGHT6_0/2+WEIGHT6_1)
  1060. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -0-WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1))).w*(WEIGHT6_0/2+WEIGHT6_1)
  1061. +TexLod(Col, inTex+ColSize.xy*Vec2(0, 2+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3))).w*(WEIGHT6_2 +WEIGHT6_3)
  1062. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -2-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3))).w*(WEIGHT6_2 +WEIGHT6_3)
  1063. +TexLod(Col, inTex+ColSize.xy*Vec2(0, 4+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5))).w*(WEIGHT6_4 +WEIGHT6_5)
  1064. +TexLod(Col, inTex+ColSize.xy*Vec2(0, -4-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5))).w*(WEIGHT6_4 +WEIGHT6_5);
  1065. }
  1066. TECHNIQUE(BlurX , Draw_VS(), BlurX_PS(4));
  1067. TECHNIQUE(BlurXH, Draw_VS(), BlurX_PS(6));
  1068. TECHNIQUE(BlurY , Draw_VS(), BlurY_PS(4));
  1069. TECHNIQUE(BlurYH, Draw_VS(), BlurY_PS(6));
  1070. TECHNIQUE(BlurX_X, Draw_VS(), BlurX_X_PS());
  1071. TECHNIQUE(BlurX_W, Draw_VS(), BlurX_W_PS());
  1072. TECHNIQUE(BlurY_X, Draw_VS(), BlurY_X_PS());
  1073. TECHNIQUE(BlurY_W, Draw_VS(), BlurY_W_PS());
  1074. /******************************************************************************/
  1075. // MAX
  1076. /******************************************************************************/
  1077. Vec4 MaxX_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1078. {
  1079. VecH color; // color=0; for(Int i=0; i<11; i++)color=Max(color, TexPoint(Col, inTex+ColSize.xy*Vec2(i-5, 0)).rgb*(BlendWeight[i]/BlendWeight[5])); original slower version
  1080. // use linear filtering because texcoords aren't rounded
  1081. color= TexLod(Col, inTex+ColSize.xy*Vec2( 0+WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1), 0)).rgb ;
  1082. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2(-0-WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1), 0)).rgb);
  1083. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2( 2+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3), 0)).rgb*((WEIGHT6_2+WEIGHT6_3)/(WEIGHT6_0+WEIGHT6_1)));
  1084. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2(-2-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3), 0)).rgb*((WEIGHT6_2+WEIGHT6_3)/(WEIGHT6_0+WEIGHT6_1)));
  1085. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2( 4+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5), 0)).rgb*((WEIGHT6_4+WEIGHT6_5)/(WEIGHT6_0+WEIGHT6_1)));
  1086. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2(-4-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5), 0)).rgb*((WEIGHT6_4+WEIGHT6_5)/(WEIGHT6_0+WEIGHT6_1)));
  1087. return Vec4(color, 0);
  1088. }
  1089. Vec4 MaxY_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1090. {
  1091. VecH color; // color=0; for(Int i=0; i<11; i++)color=Max(color, TexPoint(Col, inTex+ColSize.xy*Vec2(0, i-5)).rgb*(BlendWeight[i]/BlendWeight[5])); original slower version
  1092. // use linear filtering because texcoords aren't rounded
  1093. color= TexLod(Col, inTex+ColSize.xy*Vec2(0, 0+WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1))).rgb ;
  1094. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2(0, -0-WEIGHT6_1/(WEIGHT6_0/2+WEIGHT6_1))).rgb);
  1095. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2(0, 2+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3))).rgb*((WEIGHT6_2+WEIGHT6_3)/(WEIGHT6_0+WEIGHT6_1)));
  1096. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2(0, -2-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3))).rgb*((WEIGHT6_2+WEIGHT6_3)/(WEIGHT6_0+WEIGHT6_1)));
  1097. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2(0, 4+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5))).rgb*((WEIGHT6_4+WEIGHT6_5)/(WEIGHT6_0+WEIGHT6_1)));
  1098. color=Max(color, TexLod(Col, inTex+ColSize.xy*Vec2(0, -4-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5))).rgb*((WEIGHT6_4+WEIGHT6_5)/(WEIGHT6_0+WEIGHT6_1)));
  1099. return Vec4(color, 0);
  1100. }
  1101. TECHNIQUE(MaxX, Draw_VS(), MaxX_PS());
  1102. TECHNIQUE(MaxY, Draw_VS(), MaxY_PS());
  1103. /******************************************************************************/
  1104. // 2D FX
  1105. /******************************************************************************/
  1106. BUFFER(ColTrans)
  1107. Matrix ColTransMatrix;
  1108. Vec ColTransHsb;
  1109. BUFFER_END
  1110. Vec4 ColTrans_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1111. {
  1112. return Vec4(Transform(Tex(Col, inTex).rgb, ColTransMatrix), Step);
  1113. }
  1114. Vec4 ColTransHB_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1115. {
  1116. Vec color =Tex(Col, inTex).rgb;
  1117. Flt brightness=Max(color); color=Transform(color, ColTransMatrix);
  1118. Flt max =Max(color);
  1119. if( max)color*=ColTransHsb.z*brightness/max;
  1120. return Vec4(color, Step);
  1121. }
  1122. Vec4 ColTransHSB_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1123. {
  1124. Vec hsb=RgbToHsb(Tex(Col, inTex).rgb);
  1125. return Vec4(HsbToRgb(Vec(hsb.x+ColTransHsb.x, hsb.y*ColTransHsb.y, hsb.z*ColTransHsb.z)), Step);
  1126. }
  1127. TECHNIQUE(ColTrans , Draw_VS(), ColTrans_PS());
  1128. TECHNIQUE(ColTransHB , Draw_VS(), ColTransHB_PS());
  1129. TECHNIQUE(ColTransHSB, Draw_VS(), ColTransHSB_PS());
  1130. /******************************************************************************/
  1131. struct RippleClass
  1132. {
  1133. Flt xx, xy,
  1134. yx, yy,
  1135. stp,
  1136. power,
  1137. alpha_scale,
  1138. alpha_add;
  1139. Vec2 center;
  1140. };
  1141. BUFFER(Ripple)
  1142. RippleClass Rppl;
  1143. BUFFER_END
  1144. Vec4 Ripple_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1145. {
  1146. inTex+=Vec2(Sin(inTex.x*Rppl.xx + inTex.y*Rppl.xy + Rppl.stp),
  1147. Sin(inTex.x*Rppl.yx + inTex.y*Rppl.yy + Rppl.stp))*Rppl.power;
  1148. VecH4 c=Tex(Col, inTex); c.a*=Sat((Rppl.alpha_scale*2)*Length(inTex-Rppl.center)+Rppl.alpha_add);
  1149. return c;
  1150. }
  1151. TECHNIQUE(Ripple, Draw2DTex_VS(), Ripple_PS());
  1152. /******************************************************************************/
  1153. struct TitlesClass
  1154. {
  1155. Flt stp,
  1156. center,
  1157. range,
  1158. smooth,
  1159. swirl;
  1160. };
  1161. BUFFER(Titles)
  1162. TitlesClass Ttls;
  1163. BUFFER_END
  1164. Vec4 Titles_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1165. {
  1166. Flt s=Sat((Abs(inTex.y-Ttls.center)-Ttls.range)/Ttls.smooth);
  1167. inTex.x+=Sin(s*s*s*s*(PI*6)+Ttls.stp)*s*s*Ttls.swirl;
  1168. Vec4 color=0; UNROLL for(Int i=-4; i<=4; i++)color+=Tex(Col, inTex+s*ColSize.xy*Vec2(i, 0));
  1169. color/=9;
  1170. color.a*=Pow(1-s, 0.6f);
  1171. return color;
  1172. }
  1173. TECHNIQUE(Titles, Draw_VS(), Titles_PS());
  1174. /******************************************************************************/
  1175. Vec4 Fade_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1176. {
  1177. VecH4 c=Tex(Col, inTex); c.a*=Sat(Step*3+(inTex.x+inTex.y)*0.5f-1-Tex(Col1, inTex).a);
  1178. return c;
  1179. }
  1180. TECHNIQUE(Fade, Draw_VS(), Fade_PS());
  1181. /******************************************************************************/
  1182. void Wave_VS(VtxInput vtx,
  1183. out Vec2 outTex:TEXCOORD,
  1184. out Vec4 outVtx:POSITION)
  1185. {
  1186. outTex.x=vtx.tex().x*Color[0].x + vtx.tex().y*Color[0].y + Color[0].z;
  1187. outTex.y=vtx.tex().x*Color[1].x + vtx.tex().y*Color[1].y + Color[1].z;
  1188. outVtx =vtx.pos4(); AdjustPixelCenter(outVtx);
  1189. }
  1190. TECHNIQUE(Wave, Wave_VS(), Draw2DTex_PS());
  1191. /******************************************************************************/
  1192. Vec4 RadialBlur_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1193. {
  1194. Vec2 tex =inTex/Color[0].z + (Color[0].xy-Color[0].xy/Color[0].z); // (inTex-RadialBlurPos)/step+RadialBlurPos
  1195. Vec color=0;
  1196. const Int steps=32;
  1197. for(Int i=0; i<steps; i++)color+=Tex(Col, Lerp(inTex, tex, i/Flt(steps-1))).rgb;
  1198. return Vec4(color/steps, Color[0].w);
  1199. }
  1200. TECHNIQUE(RadialBlur, Draw_VS(), RadialBlur_PS());
  1201. /******************************************************************************/
  1202. Vec4 Outline_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1203. uniform Bool clip_do ,
  1204. uniform Bool down_sample=false):COLOR
  1205. {
  1206. if(down_sample)inTex=(Floor(inTex*ColSize.zw)+0.5f)*ColSize.xy; // we're rendering to a smaller RT, so inTex is located in the center between multiple texels, we need to align it so it's located at the center of the nearest one
  1207. Vec4 col=TexLod(Col, inTex); // use linear filtering because 'Col' can be of different size
  1208. Vec2 t0=inTex+ColSize.xy*(down_sample ? 2.5f : 0.5f), // 2.5 scale was the min value that worked OK with 2.0 density
  1209. t1=inTex-ColSize.xy*(down_sample ? 2.5f : 0.5f);
  1210. // use linear filtering because texcoords aren't rounded
  1211. #if 0
  1212. if(Dist2(col.rgb, TexLod(Col, Vec2(t0.x, t0.y)).rgb)
  1213. +Dist2(col.rgb, TexLod(Col, Vec2(t0.x, t1.y)).rgb)
  1214. +Dist2(col.rgb, TexLod(Col, Vec2(t1.x, t0.y)).rgb)
  1215. +Dist2(col.rgb, TexLod(Col, Vec2(t1.x, t1.y)).rgb)<=EPS_COL)col.a=0; // if all neighbors are the same then make this pixel transparent
  1216. #else // faster approximate
  1217. if(Length2(col.rgb*4-TexLod(Col, Vec2(t0.x, t0.y)).rgb
  1218. -TexLod(Col, Vec2(t0.x, t1.y)).rgb
  1219. -TexLod(Col, Vec2(t1.x, t0.y)).rgb
  1220. -TexLod(Col, Vec2(t1.x, t1.y)).rgb)<=EPS_COL)col.a=0; // if all neighbors are the same then make this pixel transparent
  1221. #endif
  1222. /* old code used for super sampling
  1223. {
  1224. Flt pos=TexDepthPoint(inTex);
  1225. if(Dist2(col, TexLod(Col, inTex+ColSize.xy*Vec2(-1, 0)))*(TexDepthPoint(inTex+ColSize.xy*Vec2(-1, 0))>=pos)
  1226. +Dist2(col, TexLod(Col, inTex+ColSize.xy*Vec2( 1, 0)))*(TexDepthPoint(inTex+ColSize.xy*Vec2( 1, 0))>=pos)
  1227. +Dist2(col, TexLod(Col, inTex+ColSize.xy*Vec2( 0, -1)))*(TexDepthPoint(inTex+ColSize.xy*Vec2( 0, -1))>=pos)
  1228. +Dist2(col, TexLod(Col, inTex+ColSize.xy*Vec2( 0, 1)))*(TexDepthPoint(inTex+ColSize.xy*Vec2( 0, 1))>=pos)<=EPS_COL)col.a=0;
  1229. }*/
  1230. if(clip_do)clip(col.a-EPS);
  1231. return col;
  1232. }
  1233. Vec4 OutlineApply_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1234. {
  1235. Vec4 color=TexLod(Col, inTex); // use linear filtering because 'Col' can be of different size
  1236. for(Int i=0; i<6; i++)
  1237. {
  1238. Vec2 t=inTex+BlendOfs6[i]*ColSize.xy;
  1239. Vec4 c=TexLod(Col, t); // use linear filtering because texcoords aren't rounded
  1240. if(c.a>color.a)color=c;
  1241. }
  1242. return color;
  1243. }
  1244. TECHNIQUE(Outline , Draw_VS(), Outline_PS(false));
  1245. TECHNIQUE(OutlineDS , Draw_VS(), Outline_PS(false, true));
  1246. TECHNIQUE(OutlineClip , Draw_VS(), Outline_PS(true ));
  1247. TECHNIQUE(OutlineApply, Draw_VS(), OutlineApply_PS());
  1248. /******************************************************************************/
  1249. Vec4 EdgeDetect_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1250. {
  1251. Flt z =TexDepthPoint(inTex),
  1252. zl=TexDepthPoint(inTex+ColSize.xy*Vec2(-1, 0)),
  1253. zr=TexDepthPoint(inTex+ColSize.xy*Vec2( 1, 0)),
  1254. zd=TexDepthPoint(inTex+ColSize.xy*Vec2( 0,-1)),
  1255. zu=TexDepthPoint(inTex+ColSize.xy*Vec2( 0, 1)), soft=0.1f+z/50;
  1256. Flt px =Abs(zr-((z-zl)+z))/soft-0.5f, //cx=Sat(Max(Abs(zl-z), Abs(zr-z))/soft-0.5f), cx, cy doesn't work well in lower screen resolutions and with flat terrain
  1257. py =Abs(zu-((z-zd)+z))/soft-0.5f, //cy=Sat(Max(Abs(zu-z), Abs(zd-z))/soft-0.5f),
  1258. edge=px+py;
  1259. return Sat(1-edge); // saturate because this can be directly multiplied to dest using ALPHA_MUL
  1260. }
  1261. Vec4 EdgeDetectApply_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1262. {
  1263. const Int samples=6;
  1264. Flt color =TexPoint(Col, inTex).API(a, r, r); // DX9 uses A8 while others use R8 RT
  1265. for(Int i=0; i<samples; i++)
  1266. {
  1267. Vec2 t=inTex+BlendOfs6[i]*ColSize.xy;
  1268. color+=TexLod(Col, t).API(a, r, r); // DX9 uses A8 while others use R8 RT, use linear filtering because texcoords aren't rounded
  1269. }
  1270. return color/(samples+1);
  1271. }
  1272. TECHNIQUE(EdgeDetect , Draw_VS(), EdgeDetect_PS());
  1273. TECHNIQUE(EdgeDetectApply, Draw_VS(), EdgeDetectApply_PS());
  1274. /******************************************************************************/
  1275. Vec4 Dither_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1276. NOPERSP PIXEL):COLOR
  1277. {
  1278. Vec4 col=Vec4(TexLod(Col, inTex).rgb, 1); // force full alpha so back buffer effects can work ok, can't use 'TexPoint' because 'Col' can be of different size
  1279. col.rgb+=DitherValueColor(pixel);
  1280. return col;
  1281. }
  1282. TECHNIQUE(Dither, Draw_VS(), Dither_PS());
  1283. /******************************************************************************/
  1284. Vec4 CombineSSAlpha_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1285. {
  1286. return DEPTH_FOREGROUND(TexDepthRawPoint(inTex));
  1287. }
  1288. Vec4 Combine_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1289. NOPERSP PIXEL,
  1290. uniform Int sample ):COLOR
  1291. {
  1292. Vec4 col=TexLod(Col, inTex); // use linear filtering because Col can be of different size
  1293. #if MODEL>=SM_4
  1294. if(sample==2) // multi sample
  1295. {
  1296. col.w =0; UNROLL for(Int i=0; i<MS_SAMPLES; i++)col.w+=DEPTH_FOREGROUND(TexDepthMSRaw(pixel.xy, i));
  1297. col.w/=MS_SAMPLES;
  1298. // here col.rgb is not premultiplied by alpha (it is at full scale), which means that it will not work as smooth when doing the blended support below
  1299. // if any of the neighbor pixels are transparent then assume that there's no blended graphics in the area, and then return just the solid pixel to keep AA
  1300. // use linear filtering because Col can be of different size
  1301. if(Max(TexLod(Col, inTex+ColSize.xy*Vec2( 0, SQRT2)).rgb)<=0.15f
  1302. || Max(TexLod(Col, inTex+ColSize.xy*Vec2(-1, -1)).rgb)<=0.15f
  1303. || Max(TexLod(Col, inTex+ColSize.xy*Vec2( 1, -1)).rgb)<=0.15f)return col; // there can be bloom around solid pixels, so allow some tolerance
  1304. }else
  1305. #endif
  1306. if(sample==1)col.w=TexLod(Col1, inTex).API(a, r, r); // super sample, DX9 uses A8 while others use R8 RT, use linear filtering because Col can be of different size
  1307. else col.w=DEPTH_FOREGROUND(TexDepthRawPoint(inTex)); // single sample
  1308. // support blended graphics (pixels with colors but without depth)
  1309. col.w=Max(col); // treat luminance as opacity
  1310. if(col.w>0)col.rgb/=col.w;
  1311. return col;
  1312. }
  1313. TECHNIQUE(CombineSSAlpha, Draw_VS(), CombineSSAlpha_PS( ));
  1314. TECHNIQUE(Combine , Draw_VS(), Combine_PS(0));
  1315. TECHNIQUE(CombineSS , Draw_VS(), Combine_PS(1));
  1316. #if MODEL>=SM_4
  1317. TECHNIQUE(CombineMS , Draw_VS(), Combine_PS(2));
  1318. #endif
  1319. /******************************************************************************/
  1320. #if MODEL>=SM_4
  1321. void ResolveDepth_PS(NOPERSP PIXEL,
  1322. out Flt depth:DEPTH)
  1323. {
  1324. // return the smallest of all samples
  1325. depth= TexSample(ColMS, pixel.xy, 0).x;
  1326. UNROLL for(Int i=1; i<MS_SAMPLES; i++)depth=DEPTH_MIN(depth, TexSample(ColMS, pixel.xy, i).x); // have to use minimum of depth samples to avoid shadow artifacts, by picking the samples that are closer to the camera, similar effect to what we do with view space bias (if Max is used, then shadow acne can occur for local lights)
  1327. }
  1328. TECHNIQUE(ResolveDepth, DrawPixel_VS(), ResolveDepth_PS());
  1329. // 'Depth' can't be used because it's 1-sample
  1330. // 'DepthMs' can't be used because it's always multi-sampled (all samples are different)
  1331. void DetectMSCol_PS(NOPERSP PIXEL)
  1332. {
  1333. Vec cols[4]={TexSample(ColMS, pixel.xy, 0).rgb, TexSample(ColMS, pixel.xy, 1).rgb, TexSample(ColMS, pixel.xy, 2).rgb, TexSample(ColMS, pixel.xy, 3).rgb}; // load 4-multi-samples of texel
  1334. //if(all((cols[0]==cols[1])*(cols[0]==cols[2])*(cols[0]==cols[3])))discard;
  1335. clip(Length2(cols[0].rgb*3-cols[1].rgb-cols[2].rgb-cols[3].rgb) - Sqr(2.0f/256)); // simplified and approximate version of testing if samples are identical, (cols[0].rgb-cols[1].rgb) + (cols[0].rgb-cols[2].rgb) + (cols[0].rgb-cols[3].rgb)
  1336. }
  1337. TECHNIQUE(DetectMSCol, DrawPixel_VS(), DetectMSCol_PS());
  1338. /*void DetectMSNrm_PS(NOPERSP PIXEL)
  1339. {
  1340. Vec2 nrms[4]={TexSample(ColMS, pixel.xy, 0).xy, TexSample(ColMS, pixel.xy, 1).xy, TexSample(ColMS, pixel.xy, 2).xy, TexSample(ColMS, pixel.xy, 3).xy}; // load 4-multi-samples of texel
  1341. //if(all((nrms[0]==nrms[1])*(nrms[0]==nrms[2])*(nrms[0]==nrms[3])))discard;
  1342. clip(Length2(nrms[0].xy*3-nrms[1].xy-nrms[2].xy-nrms[3].xy) - Sqr(2.0f/256*(SIGNED_NRM_RT ? 2 : 1))); // simplified and approximate version of testing if samples are identical, (nrms[0].xy-nrms[1].xy) + (nrms[0].xy-nrms[2].xy) + (nrms[0].xy-nrms[3].xy), for SIGNED_NRM_RT we have to use bigger epsilon because we have 2x bigger value range (-1..1 instead of 0..1)
  1343. }
  1344. TECHNIQUE(DetectMSNrm, DrawPixel_VS(), DetectMSNrm_PS());*/
  1345. #endif
  1346. void SetDepth_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1347. #if MODEL==SM_3
  1348. out Vec4 ret :COLOR ,
  1349. #endif
  1350. out Flt depth:DEPTH )
  1351. {
  1352. #if MODEL==SM_3
  1353. ret=0;
  1354. #endif
  1355. depth=TexLod(Col, inTex).x; // use linear filtering because this can be used for different size RT
  1356. }
  1357. TECHNIQUE(SetDepth, Draw_VS(), SetDepth_PS());
  1358. /*void RebuildDepth_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1359. out Flt depth:DEPTH ,
  1360. uniform Bool perspective )
  1361. {
  1362. depth=DelinearizeDepth(TexLod(Col, inTex).x, perspective); // use linear filtering because this can be used for different size RT
  1363. }
  1364. TECHNIQUE(RebuildDepth , Draw_VS(), RebuildDepth_PS(false));
  1365. TECHNIQUE(RebuildDepthP, Draw_VS(), RebuildDepth_PS(true ));*/
  1366. Vec4 LinearizeDepth_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1367. uniform Bool perspective ):COLOR
  1368. {
  1369. return LinearizeDepth(TexLod(Col, inTex).x, perspective); // use linear filtering because this can be used for different size RT
  1370. }
  1371. TECHNIQUE(LinearizeDepth0 , Draw_VS(), LinearizeDepth_PS(false));
  1372. TECHNIQUE(LinearizeDepthP0, Draw_VS(), LinearizeDepth_PS(true ));
  1373. #if MODEL>=SM_4
  1374. Vec4 LinearizeDepth1_PS(NOPERSP PIXEL,
  1375. uniform Bool perspective):COLOR
  1376. {
  1377. return LinearizeDepth(TexSample(ColMS, pixel.xy, 0).x, perspective);
  1378. }
  1379. Vec4 LinearizeDepth2_PS(NOPERSP PIXEL,
  1380. UInt index:SV_SampleIndex,
  1381. uniform Bool perspective ):COLOR
  1382. {
  1383. return LinearizeDepth(TexSample(ColMS, pixel.xy, index).x, perspective);
  1384. }
  1385. TECHNIQUE (LinearizeDepth1 , DrawPixel_VS(), LinearizeDepth1_PS(false));
  1386. TECHNIQUE (LinearizeDepthP1, DrawPixel_VS(), LinearizeDepth1_PS(true ));
  1387. TECHNIQUE_4_1(LinearizeDepth2 , DrawPixel_VS(), LinearizeDepth2_PS(false));
  1388. TECHNIQUE_4_1(LinearizeDepthP2, DrawPixel_VS(), LinearizeDepth2_PS(true ));
  1389. #endif
  1390. #if DX9
  1391. Vec4 LinearizeDepthRAWZ_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1392. uniform Bool perspective ):COLOR
  1393. {
  1394. Vec rawval=Floor(255.0f*TexPoint(Col, inTex).arg+0.5f);
  1395. Flt w =Dot (rawval, Vec(0.996093809371817670572857294849, 0.0038909914428586627756752238080039, 1.5199185323666651467481343000015e-5)/255.0);
  1396. return LinearizeDepth(w, perspective);
  1397. }
  1398. TECHNIQUE(LinearizeDepthRAWZ , Draw_VS(), LinearizeDepthRAWZ_PS(false));
  1399. TECHNIQUE(LinearizeDepthRAWZP, Draw_VS(), LinearizeDepthRAWZ_PS(true ));
  1400. #endif
  1401. Vec4 DrawDepth_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1402. {
  1403. Flt frac=LinearizeDepth(TexLod(Col, inTex).x)/Viewport.range; // use linear filtering because this can be used for different size RT
  1404. return Vec4(HsbToRgb(Vec(frac*2.57f, 1, 1)), 1); // the scale is set so the full range equals to blue color, to imitate sky color
  1405. }
  1406. TECHNIQUE(DrawDepth, Draw_VS(), DrawDepth_PS());
  1407. /******************************************************************************/
  1408. // SKY
  1409. /******************************************************************************/
  1410. inline Vec4 SkyColor(Vec inTex)
  1411. {
  1412. Flt hor=Pow(1-Sat(inTex.y), SkyHorExp);
  1413. return Lerp(SkySkyCol, SkyHorCol, hor);
  1414. }
  1415. inline VecH4 SkyTex(Vec inTex, Vec inTexStar, VecH4 inCol, Flt alpha, uniform Bool per_vertex, uniform Bool density, uniform Int textures, uniform Bool stars)
  1416. {
  1417. if(density)alpha=Pow(SkyDnsExp, alpha)*SkyDnsMulAdd.x+SkyDnsMulAdd.y; // here 'alpha' means opacity of the sky which is used as the distance from start to end point, this function matches 'AccumulatedDensity'
  1418. if(textures==2)return VecH4(Lerp(TexCube(Rfl, inTex).rgb, TexCube(Cub, inTex).rgb, SkyBoxBlend), alpha);else
  1419. if(textures==1)return VecH4( TexCube(Rfl, inTex).rgb, alpha);else
  1420. {
  1421. if(!per_vertex)
  1422. {
  1423. inTex=Normalize(inTex);
  1424. inCol=SkyColor (inTex);
  1425. Flt cos =Dot(SkySunPos, inTex),
  1426. highlight=1+Sqr(cos)*((cos>0) ? SkySunHighlight.x : SkySunHighlight.y); // rayleigh
  1427. inCol.rgb*=highlight;
  1428. }
  1429. if(stars)inCol.rgb=Lerp(TexCube(Rfl, inTexStar).rgb, inCol.rgb, inCol.a);
  1430. return VecH4(inCol.rgb, alpha);
  1431. }
  1432. }
  1433. void Sky_VS(VtxInput vtx,
  1434. out Vec4 outVtx :POSITION ,
  1435. out Vec outPos :TEXCOORD0,
  1436. out Vec outTex :TEXCOORD1,
  1437. out Vec outTexStar :TEXCOORD2,
  1438. out Vec outTexCloud:TEXCOORD3,
  1439. out VecH4 outCol :COLOR0 ,
  1440. out VecH4 outColCloud:COLOR1 ,
  1441. uniform Bool per_vertex ,
  1442. uniform Bool stars ,
  1443. uniform Bool clouds )
  1444. {
  1445. outTex = vtx.pos();
  1446. if(stars ) outTexStar=Transform (vtx.pos(), SkyStarOrn);
  1447. outVtx=Project(outPos =TransformPos(vtx.pos() ));
  1448. if(per_vertex)outCol= SkyColor (vtx.pos());
  1449. if(clouds)
  1450. {
  1451. outTexCloud=vtx.pos()*Vec(LCScale, 1, LCScale);
  1452. outColCloud=CL[0].color; outColCloud.a*=Sat(CloudAlpha(vtx.pos().y));
  1453. }
  1454. }
  1455. Vec4 Sky_PS(PIXEL,
  1456. Vec inPos :TEXCOORD0,
  1457. Vec inTex :TEXCOORD1,
  1458. Vec inTexStar :TEXCOORD2,
  1459. Vec inTexCloud:TEXCOORD3,
  1460. VecH4 inCol :COLOR0 ,
  1461. VecH4 inColCloud:COLOR1 ,
  1462. uniform Bool per_vertex ,
  1463. uniform Bool flat ,
  1464. uniform Bool density ,
  1465. uniform Int textures ,
  1466. uniform Bool stars ,
  1467. uniform Bool clouds ,
  1468. uniform Bool dither ):COLOR
  1469. {
  1470. Flt alpha; if(flat)alpha=0;else // flat uses ALPHA_NONE
  1471. {
  1472. alpha=TexDepthPoint(PIXEL_TO_SCREEN)/Normalize(inPos).z;
  1473. alpha=Sat(alpha*SkyFracMulAdd.x + SkyFracMulAdd.y);
  1474. }
  1475. VecH4 col=SkyTex(inTex, inTexStar, inCol, alpha, per_vertex, density, textures, stars);
  1476. if(clouds)
  1477. {
  1478. Vec2 uv =Normalize(inTexCloud).xz;
  1479. VecH4 tex=Tex(Col, uv*CL[0].scale + CL[0].position)*inColCloud;
  1480. col.rgb=Lerp(col.rgb, tex.rgb, tex.a);
  1481. }
  1482. if(dither)col.rgb+=DitherValueColor(pixel);
  1483. return col;
  1484. }
  1485. #if MODEL>=SM_4
  1486. Vec4 Sky1_PS(PIXEL,
  1487. Vec inPos :TEXCOORD0,
  1488. Vec inTex :TEXCOORD1,
  1489. Vec inTexStar :TEXCOORD2,
  1490. Vec inTexCloud:TEXCOORD3,
  1491. Vec4 inCol :COLOR ,
  1492. uniform Bool per_vertex ,
  1493. uniform Bool density ,
  1494. uniform Int textures ,
  1495. uniform Bool stars ,
  1496. uniform Bool dither ):COLOR
  1497. {
  1498. Flt pos_scale=Normalize(inPos).z, alpha=0;
  1499. UNROLL for(Int i=0; i<MS_SAMPLES; i++){Flt dist=TexDepthMS(pixel.xy, i)/pos_scale; alpha+=Sat(dist*SkyFracMulAdd.x + SkyFracMulAdd.y);}
  1500. alpha/=MS_SAMPLES;
  1501. VecH4 col=SkyTex(inTex, inTexStar, inCol, alpha, per_vertex, density, textures, stars);
  1502. if(dither)col.rgb+=DitherValueColor(pixel);
  1503. return col;
  1504. }
  1505. Vec4 Sky2_PS(PIXEL,
  1506. Vec inPos :TEXCOORD0 ,
  1507. Vec inTex :TEXCOORD1 ,
  1508. Vec inTexStar :TEXCOORD2 ,
  1509. Vec inTexCloud:TEXCOORD3 ,
  1510. Vec4 inCol :COLOR ,
  1511. UInt index :SV_SampleIndex,
  1512. uniform Bool per_vertex ,
  1513. uniform Bool density ,
  1514. uniform Int textures ,
  1515. uniform Bool stars ,
  1516. uniform Bool dither ):COLOR
  1517. {
  1518. Flt pos_scale=Normalize(inPos).z,
  1519. alpha =Sat(TexDepthMS(pixel.xy, index)/pos_scale*SkyFracMulAdd.x + SkyFracMulAdd.y);
  1520. VecH4 col=SkyTex(inTex, inTexStar, inCol, alpha, per_vertex, density, textures, stars);
  1521. // skip dither for MS because it won't be noticeable
  1522. return col;
  1523. }
  1524. #endif
  1525. // Textures Flat
  1526. TECHNIQUE (SkyTF1 , Sky_VS(false, false, false), Sky_PS (false, true , false, 1, false, false, false));
  1527. TECHNIQUE (SkyTF2 , Sky_VS(false, false, false), Sky_PS (false, true , false, 2, false, false, false));
  1528. TECHNIQUE (SkyTF1C , Sky_VS(false, false, true ), Sky_PS (false, true , false, 1, false, true , false));
  1529. TECHNIQUE (SkyTF2C , Sky_VS(false, false, true ), Sky_PS (false, true , false, 2, false, true , false));
  1530. TECHNIQUE (SkyTF1D , Sky_VS(false, false, false), Sky_PS (false, true , false, 1, false, false, true ));
  1531. TECHNIQUE (SkyTF2D , Sky_VS(false, false, false), Sky_PS (false, true , false, 2, false, false, true ));
  1532. TECHNIQUE (SkyTF1CD , Sky_VS(false, false, true ), Sky_PS (false, true , false, 1, false, true , true ));
  1533. TECHNIQUE (SkyTF2CD , Sky_VS(false, false, true ), Sky_PS (false, true , false, 2, false, true , true ));
  1534. // Textures
  1535. TECHNIQUE (SkyT10 , Sky_VS(false, false, false), Sky_PS (false, false, false, 1, false, false, false));
  1536. TECHNIQUE (SkyT20 , Sky_VS(false, false, false), Sky_PS (false, false, false, 2, false, false, false));
  1537. TECHNIQUE (SkyT10D , Sky_VS(false, false, false), Sky_PS (false, false, false, 1, false, false, true ));
  1538. TECHNIQUE (SkyT20D , Sky_VS(false, false, false), Sky_PS (false, false, false, 2, false, false, true ));
  1539. #if MODEL>=SM_4 // Multi Sample
  1540. TECHNIQUE (SkyT11 , Sky_VS(false, false, false), Sky1_PS(false, false, 1, false, false));
  1541. TECHNIQUE (SkyT21 , Sky_VS(false, false, false), Sky1_PS(false, false, 2, false, false));
  1542. TECHNIQUE_4_1(SkyT12 , Sky_VS(false, false, false), Sky2_PS(false, false, 1, false, false));
  1543. TECHNIQUE_4_1(SkyT22 , Sky_VS(false, false, false), Sky2_PS(false, false, 2, false, false));
  1544. TECHNIQUE (SkyT11D , Sky_VS(false, false, false), Sky1_PS(false, false, 1, false, true ));
  1545. TECHNIQUE (SkyT21D , Sky_VS(false, false, false), Sky1_PS(false, false, 2, false, true ));
  1546. TECHNIQUE_4_1(SkyT12D , Sky_VS(false, false, false), Sky2_PS(false, false, 1, false, true ));
  1547. TECHNIQUE_4_1(SkyT22D , Sky_VS(false, false, false), Sky2_PS(false, false, 2, false, true ));
  1548. #endif
  1549. // Atmospheric Flat
  1550. TECHNIQUE (SkyAF , Sky_VS(false, false, false), Sky_PS(false, true ,false, 0, false, false, false));
  1551. TECHNIQUE (SkyAFV , Sky_VS(true , false, false), Sky_PS(true , true ,false, 0, false, false, false));
  1552. TECHNIQUE (SkyAFS , Sky_VS(false, true , false), Sky_PS(false, true ,false, 0, true , false, false));
  1553. TECHNIQUE (SkyAFVS , Sky_VS(true , true , false), Sky_PS(true , true ,false, 0, true , false, false));
  1554. TECHNIQUE (SkyAFC , Sky_VS(false, false, true ), Sky_PS(false, true ,false, 0, false, true , false));
  1555. TECHNIQUE (SkyAFVC , Sky_VS(true , false, true ), Sky_PS(true , true ,false, 0, false, true , false));
  1556. TECHNIQUE (SkyAFSC , Sky_VS(false, true , true ), Sky_PS(false, true ,false, 0, true , true , false));
  1557. TECHNIQUE (SkyAFVSC , Sky_VS(true , true , true ), Sky_PS(true , true ,false, 0, true , true , false));
  1558. TECHNIQUE (SkyAFD , Sky_VS(false, false, false), Sky_PS(false, true ,false, 0, false, false, true ));
  1559. TECHNIQUE (SkyAFVD , Sky_VS(true , false, false), Sky_PS(true , true ,false, 0, false, false, true ));
  1560. TECHNIQUE (SkyAFSD , Sky_VS(false, true , false), Sky_PS(false, true ,false, 0, true , false, true ));
  1561. TECHNIQUE (SkyAFVSD , Sky_VS(true , true , false), Sky_PS(true , true ,false, 0, true , false, true ));
  1562. TECHNIQUE (SkyAFCD , Sky_VS(false, false, true ), Sky_PS(false, true ,false, 0, false, true , true ));
  1563. TECHNIQUE (SkyAFVCD , Sky_VS(true , false, true ), Sky_PS(true , true ,false, 0, false, true , true ));
  1564. TECHNIQUE (SkyAFSCD , Sky_VS(false, true , true ), Sky_PS(false, true ,false, 0, true , true , true ));
  1565. TECHNIQUE (SkyAFVSCD, Sky_VS(true , true , true ), Sky_PS(true , true ,false, 0, true , true , true ));
  1566. // Atmospheric
  1567. TECHNIQUE (SkyA0 , Sky_VS(false, false, false), Sky_PS(false, false, false, 0, false, false, false));
  1568. TECHNIQUE (SkyAV0 , Sky_VS(true , false, false), Sky_PS(true , false, false, 0, false, false, false));
  1569. TECHNIQUE (SkyAS0 , Sky_VS(false, true , false), Sky_PS(false, false, false, 0, true , false, false));
  1570. TECHNIQUE (SkyAVS0 , Sky_VS(true , true , false), Sky_PS(true , false, false, 0, true , false, false));
  1571. TECHNIQUE (SkyAP0 , Sky_VS(false, false, false), Sky_PS(false, false, true , 0, false, false, false));
  1572. TECHNIQUE (SkyAVP0 , Sky_VS(true , false, false), Sky_PS(true , false, true , 0, false, false, false));
  1573. TECHNIQUE (SkyASP0 , Sky_VS(false, true , false), Sky_PS(false, false, true , 0, true , false, false));
  1574. TECHNIQUE (SkyAVSP0 , Sky_VS(true , true , false), Sky_PS(true , false, true , 0, true , false, false));
  1575. TECHNIQUE (SkyA0D , Sky_VS(false, false, false), Sky_PS(false, false, false, 0, false, false, true ));
  1576. TECHNIQUE (SkyAV0D , Sky_VS(true , false, false), Sky_PS(true , false, false, 0, false, false, true ));
  1577. TECHNIQUE (SkyAS0D , Sky_VS(false, true , false), Sky_PS(false, false, false, 0, true , false, true ));
  1578. TECHNIQUE (SkyAVS0D , Sky_VS(true , true , false), Sky_PS(true , false, false, 0, true , false, true ));
  1579. TECHNIQUE (SkyAP0D , Sky_VS(false, false, false), Sky_PS(false, false, true , 0, false, false, true ));
  1580. TECHNIQUE (SkyAVP0D , Sky_VS(true , false, false), Sky_PS(true , false, true , 0, false, false, true ));
  1581. TECHNIQUE (SkyASP0D , Sky_VS(false, true , false), Sky_PS(false, false, true , 0, true , false, true ));
  1582. TECHNIQUE (SkyAVSP0D, Sky_VS(true , true , false), Sky_PS(true , false, true , 0, true , false, true ));
  1583. #if MODEL>=SM_4 // Multi Sample
  1584. TECHNIQUE (SkyA1 , Sky_VS(false, false, false), Sky1_PS(false, false, 0, false, false));
  1585. TECHNIQUE (SkyAV1 , Sky_VS(true , false, false), Sky1_PS(true , false, 0, false, false));
  1586. TECHNIQUE (SkyAS1 , Sky_VS(false, true , false), Sky1_PS(false, false, 0, true , false));
  1587. TECHNIQUE (SkyAVS1 , Sky_VS(true , true , false), Sky1_PS(true , false, 0, true , false));
  1588. TECHNIQUE (SkyAP1 , Sky_VS(false, false, false), Sky1_PS(false, true , 0, false, false));
  1589. TECHNIQUE (SkyAVP1 , Sky_VS(true , false, false), Sky1_PS(true , true , 0, false, false));
  1590. TECHNIQUE (SkyASP1 , Sky_VS(false, true , false), Sky1_PS(false, true , 0, true , false));
  1591. TECHNIQUE (SkyAVSP1 , Sky_VS(true , true , false), Sky1_PS(true , true , 0, true , false));
  1592. TECHNIQUE (SkyA1D , Sky_VS(false, false, false), Sky1_PS(false, false, 0, false, true ));
  1593. TECHNIQUE (SkyAV1D , Sky_VS(true , false, false), Sky1_PS(true , false, 0, false, true ));
  1594. TECHNIQUE (SkyAS1D , Sky_VS(false, true , false), Sky1_PS(false, false, 0, true , true ));
  1595. TECHNIQUE (SkyAVS1D , Sky_VS(true , true , false), Sky1_PS(true , false, 0, true , true ));
  1596. TECHNIQUE (SkyAP1D , Sky_VS(false, false, false), Sky1_PS(false, true , 0, false, true ));
  1597. TECHNIQUE (SkyAVP1D , Sky_VS(true , false, false), Sky1_PS(true , true , 0, false, true ));
  1598. TECHNIQUE (SkyASP1D , Sky_VS(false, true , false), Sky1_PS(false, true , 0, true , true ));
  1599. TECHNIQUE (SkyAVSP1D, Sky_VS(true , true , false), Sky1_PS(true , true , 0, true , true ));
  1600. TECHNIQUE_4_1(SkyA2 , Sky_VS(false, false, false), Sky2_PS(false, false, 0, false, false));
  1601. TECHNIQUE_4_1(SkyAV2 , Sky_VS(true , false, false), Sky2_PS(true , false, 0, false, false));
  1602. TECHNIQUE_4_1(SkyAS2 , Sky_VS(false, true , false), Sky2_PS(false, false, 0, true , false));
  1603. TECHNIQUE_4_1(SkyAVS2 , Sky_VS(true , true , false), Sky2_PS(true , false, 0, true , false));
  1604. TECHNIQUE_4_1(SkyAP2 , Sky_VS(false, false, false), Sky2_PS(false, true , 0, false, false));
  1605. TECHNIQUE_4_1(SkyAVP2 , Sky_VS(true , false, false), Sky2_PS(true , true , 0, false, false));
  1606. TECHNIQUE_4_1(SkyASP2 , Sky_VS(false, true , false), Sky2_PS(false, true , 0, true , false));
  1607. TECHNIQUE_4_1(SkyAVSP2 , Sky_VS(true , true , false), Sky2_PS(true , true , 0, true , false));
  1608. TECHNIQUE_4_1(SkyA2D , Sky_VS(false, false, false), Sky2_PS(false, false, 0, false, true ));
  1609. TECHNIQUE_4_1(SkyAV2D , Sky_VS(true , false, false), Sky2_PS(true , false, 0, false, true ));
  1610. TECHNIQUE_4_1(SkyAS2D , Sky_VS(false, true , false), Sky2_PS(false, false, 0, true , true ));
  1611. TECHNIQUE_4_1(SkyAVS2D , Sky_VS(true , true , false), Sky2_PS(true , false, 0, true , true ));
  1612. TECHNIQUE_4_1(SkyAP2D , Sky_VS(false, false, false), Sky2_PS(false, true , 0, false, true ));
  1613. TECHNIQUE_4_1(SkyAVP2D , Sky_VS(true , false, false), Sky2_PS(true , true , 0, false, true ));
  1614. TECHNIQUE_4_1(SkyASP2D , Sky_VS(false, true , false), Sky2_PS(false, true , 0, true , true ));
  1615. TECHNIQUE_4_1(SkyAVSP2D, Sky_VS(true , true , false), Sky2_PS(true , true , 0, true , true ));
  1616. #endif
  1617. /******************************************************************************/
  1618. // FOG
  1619. /******************************************************************************/
  1620. Vec4 Fog_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1621. NOPERSP Vec2 inPosXY:TEXCOORD1):COLOR
  1622. {
  1623. Vec pos=GetPosPoint(inTex, inPosXY);
  1624. Flt dns=AccumulatedDensity(FogDensity(), Length(pos));
  1625. return Vec4(FogColor(), dns);
  1626. }
  1627. #if MODEL>=SM_4
  1628. Vec4 FogN_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1629. NOPERSP Vec2 inPosXY:TEXCOORD1,
  1630. NOPERSP PIXEL ):COLOR
  1631. {
  1632. Flt valid=EPS, dns=0;
  1633. UNROLL for(Int i=0; i<MS_SAMPLES; i++)
  1634. {
  1635. Flt depth=TexDepthMSRaw(pixel.xy, i); if(DEPTH_FOREGROUND(depth))
  1636. {
  1637. Vec pos =GetPos(LinearizeDepth(depth), inPosXY);
  1638. dns+=AccumulatedDensity(FogDensity(), Length(pos));
  1639. valid++;
  1640. }
  1641. }
  1642. return Vec4(FogColor(), dns/valid);
  1643. }
  1644. Vec4 FogM_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1645. NOPERSP Vec2 inPosXY:TEXCOORD1,
  1646. NOPERSP PIXEL ,
  1647. UInt index :SV_SampleIndex):COLOR
  1648. {
  1649. Vec pos=GetPosMS(pixel.xy, index, inPosXY);
  1650. return Vec4(FogColor(), AccumulatedDensity(FogDensity(), Length(pos)));
  1651. }
  1652. #endif
  1653. TECHNIQUE (Fog , DrawPosXY_VS(), Fog_PS ());
  1654. #if MODEL>=SM_4 // multi sample
  1655. TECHNIQUE (FogN, DrawPosXY_VS(), FogN_PS());
  1656. TECHNIQUE_4_1(FogM, DrawPosXY_VS(), FogM_PS());
  1657. #endif
  1658. /******************************************************************************/
  1659. // SUN
  1660. /******************************************************************************/
  1661. struct SunClass
  1662. {
  1663. Vec2 pos2;
  1664. Vec pos, color;
  1665. };
  1666. BUFFER(Sun)
  1667. SunClass Sun;
  1668. BUFFER_END
  1669. Vec4 SunRaysMask_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1670. NOPERSP Vec2 inPosXY:TEXCOORD1,
  1671. uniform Bool mask ):COLOR
  1672. {
  1673. if(mask) // for this version we have to use linear depth filtering, because RT is of different size, and otherwise too much artifacts/flickering is generated
  1674. {
  1675. #if REVERSE_DEPTH // we can use the simple version for REVERSE_DEPTH
  1676. Half m=(Length2(GetPosLinear(inTex, inPosXY))>=Sqr(Viewport.range));
  1677. #else // need safer
  1678. Flt z=TexDepthRawLinear(inTex);
  1679. Half m=(DEPTH_BACKGROUND(z) || Length2(GetPos(LinearizeDepth(z), inPosXY))>=Sqr(Viewport.range));
  1680. #endif
  1681. return m*TexLod(Col, inTex).API(a, r, r); // DX9 uses A8 while others use R8 RT, use linear filtering because Col can be of different size
  1682. }else // can use point filtering here
  1683. {
  1684. #if REVERSE_DEPTH // we can use the simple version for REVERSE_DEPTH
  1685. return Length2(GetPosPoint(inTex, inPosXY))>=Sqr(Viewport.range);
  1686. #else // need safer
  1687. Flt z=TexDepthRawPoint(inTex);
  1688. return DEPTH_BACKGROUND(z) || Length2(GetPos(LinearizeDepth(z), inPosXY))>=Sqr(Viewport.range);
  1689. #endif
  1690. }
  1691. }
  1692. TECHNIQUE(SunRaysMask , DrawPosXY_VS(), SunRaysMask_PS(false));
  1693. TECHNIQUE(SunRaysMask1, DrawPosXY_VS(), SunRaysMask_PS(true ));
  1694. /*Vec4 SunRaysSoft_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  1695. {
  1696. const Int samples=6;
  1697. Flt color =TexLod(Col, inTex).API(a, r, r); // DX9 uses A8 while others use R8 RT, use linear filtering because Col can be of different size
  1698. for(Int i=0; i<samples; i++)
  1699. {
  1700. Vec2 t=inTex+BlendOfs6[i]*ColSize.xy;
  1701. color+=TexLod(Col, t).API(a, r, r); // DX9 uses A8 while others use R8 RT, use linear filtering because texcoords aren't rounded
  1702. }
  1703. return Vec4(color/(samples+1)*Color[0].rgb, 0);
  1704. }
  1705. TECHNIQUE(SunRaysSoft, Draw_VS(), SunRaysSoft_PS());*/
  1706. Vec4 SunRays_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1707. NOPERSP Vec2 inPosXY:TEXCOORD1,
  1708. NOPERSP PIXEL ,
  1709. uniform Bool high ,
  1710. uniform Bool jitter ):COLOR
  1711. {
  1712. Vec pos =Normalize(Vec(inPosXY, 1));
  1713. Flt cos =Dot(Sun.pos, pos),
  1714. power=((cos>0) ? cos*cos : 0);
  1715. Vec4 col =0;
  1716. #if 0 // can't use 'clip' because we always have to set output (to 0 if no rays)
  1717. clip(power-EPS_COL);
  1718. #else
  1719. BRANCH if(power>EPS_COL)
  1720. #endif
  1721. {
  1722. const Int steps =40;
  1723. Flt light =0;
  1724. Vec2 sun_pos=Sun.pos2;
  1725. // limit sun position
  1726. #if 0
  1727. if(sun_pos.x>1)
  1728. {
  1729. Flt frac=(1-inTex.x)/(sun_pos.x-inTex.x);
  1730. sun_pos.x =1;
  1731. sun_pos.y-=(1-frac)*(sun_pos.y-inTex.y);
  1732. //power *=frac;
  1733. }else
  1734. if(sun_pos.x<0)
  1735. {
  1736. Flt frac=(inTex.x)/(inTex.x-sun_pos.x);
  1737. sun_pos.x =0;
  1738. sun_pos.y-=(1-frac)*(sun_pos.y-inTex.y);
  1739. //power *=frac;
  1740. }
  1741. if(sun_pos.y>1)
  1742. {
  1743. Flt frac=(1-inTex.y)/(sun_pos.y-inTex.y);
  1744. sun_pos.y =1;
  1745. sun_pos.x-=(1-frac)*(sun_pos.x-inTex.x);
  1746. //power *=frac;
  1747. }else
  1748. if(sun_pos.y<0)
  1749. {
  1750. Flt frac=(inTex.y)/(inTex.y-sun_pos.y);
  1751. sun_pos.y =0;
  1752. sun_pos.x-=(1-frac)*(sun_pos.x-inTex.x);
  1753. //power *=frac;
  1754. }
  1755. #else
  1756. //Flt frac=Max(Max(Vec2(0,0), Abs(sun_pos-0.5f)-0.5f)/Abs(sun_pos-inTex)); // Max(Max(0, Abs(sun_pos.x-0.5)-0.5)/Abs(sun_pos.x-inTex.x), Max(0, Abs(sun_pos.y-0.5)-0.5)/Abs(sun_pos.y-inTex.y));
  1757. Flt frac=Max(Max(Vec2(0,0), Abs(sun_pos-Viewport.center)-Viewport.size/2)/Abs(sun_pos-inTex)); // Max(Max(0, Abs(sun_pos.x-0.5)-0.5)/Abs(sun_pos.x-inTex.x), Max(0, Abs(sun_pos.y-0.5)-0.5)/Abs(sun_pos.y-inTex.y));
  1758. sun_pos-=( frac)*(sun_pos-inTex);
  1759. //power *=(1-frac);
  1760. #endif
  1761. if(jitter)inTex+=(sun_pos-inTex)*(DitherValue(pixel)*(3.0f/steps)); // a good value is 2.5 or 3.0 (3.0 was slightly better)
  1762. UNROLL for(Int i=0; i<steps; i++)
  1763. {
  1764. Vec2 t=Lerp(inTex, sun_pos, i/Flt(steps)); // /(steps) worked better than /(steps-1)
  1765. if(high)light+=TexLod(Col, t).API(a, r, r); // pos and clouds combined together, DX9 uses A8 while others use R8 RT, use linear filtering because texcoords aren't rounded
  1766. else light+=DEPTH_BACKGROUND(TexDepthRawPoint(t)); // use simpler version here unlike in 'SunRaysPre_PS' because this one is called for each step for each pixel
  1767. }
  1768. col.rgb=(light*power/steps)*Sun.color;
  1769. }
  1770. return col;
  1771. }
  1772. TECHNIQUE(SunRays , DrawPosXY_VS(), SunRays_PS(false, false));
  1773. TECHNIQUE(SunRaysH , DrawPosXY_VS(), SunRays_PS(true , false));
  1774. TECHNIQUE(SunRaysJ , DrawPosXY_VS(), SunRays_PS(false, true ));
  1775. TECHNIQUE(SunRaysHJ, DrawPosXY_VS(), SunRays_PS(true , true ));
  1776. /******************************************************************************/
  1777. // SHADOW MAP
  1778. /******************************************************************************/
  1779. Vec4 ShdDir_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1780. NOPERSP Vec2 inPosXY:TEXCOORD1,
  1781. NOPERSP PIXEL ,
  1782. uniform Int num ,
  1783. uniform Bool cloud ):COLOR
  1784. {
  1785. return ShadowDirValue(GetPosPoint(inTex, inPosXY), ShadowJitter(pixel.xy), true, num, cloud);
  1786. }
  1787. #if MODEL>=SM_4
  1788. Vec4 ShdDirM_PS(NOPERSP Vec2 inTex :TEXCOORD0 ,
  1789. NOPERSP Vec2 inPosXY:TEXCOORD1 ,
  1790. NOPERSP PIXEL ,
  1791. UInt index :SV_SampleIndex,
  1792. uniform Int num ,
  1793. uniform Bool cloud ):COLOR
  1794. {
  1795. return ShadowDirValue(GetPosMS(pixel.xy, index, inPosXY), ShadowJitter(pixel.xy), true, num, cloud);
  1796. }
  1797. #endif
  1798. TECHNIQUE(ShdDir1, DrawPosXY_VS(), ShdDir_PS(1, false)); TECHNIQUE(ShdDir1C, DrawPosXY_VS(), ShdDir_PS(1, true));
  1799. TECHNIQUE(ShdDir2, DrawPosXY_VS(), ShdDir_PS(2, false)); TECHNIQUE(ShdDir2C, DrawPosXY_VS(), ShdDir_PS(2, true));
  1800. TECHNIQUE(ShdDir3, DrawPosXY_VS(), ShdDir_PS(3, false)); TECHNIQUE(ShdDir3C, DrawPosXY_VS(), ShdDir_PS(3, true));
  1801. TECHNIQUE(ShdDir4, DrawPosXY_VS(), ShdDir_PS(4, false)); TECHNIQUE(ShdDir4C, DrawPosXY_VS(), ShdDir_PS(4, true));
  1802. TECHNIQUE(ShdDir5, DrawPosXY_VS(), ShdDir_PS(5, false)); TECHNIQUE(ShdDir5C, DrawPosXY_VS(), ShdDir_PS(5, true));
  1803. TECHNIQUE(ShdDir6, DrawPosXY_VS(), ShdDir_PS(6, false)); TECHNIQUE(ShdDir6C, DrawPosXY_VS(), ShdDir_PS(6, true));
  1804. TECHNIQUE_4_1(ShdDir1M, DrawPosXY_VS(), ShdDirM_PS(1, false)); TECHNIQUE_4_1(ShdDir1CM, DrawPosXY_VS(), ShdDirM_PS(1, true));
  1805. TECHNIQUE_4_1(ShdDir2M, DrawPosXY_VS(), ShdDirM_PS(2, false)); TECHNIQUE_4_1(ShdDir2CM, DrawPosXY_VS(), ShdDirM_PS(2, true));
  1806. TECHNIQUE_4_1(ShdDir3M, DrawPosXY_VS(), ShdDirM_PS(3, false)); TECHNIQUE_4_1(ShdDir3CM, DrawPosXY_VS(), ShdDirM_PS(3, true));
  1807. TECHNIQUE_4_1(ShdDir4M, DrawPosXY_VS(), ShdDirM_PS(4, false)); TECHNIQUE_4_1(ShdDir4CM, DrawPosXY_VS(), ShdDirM_PS(4, true));
  1808. TECHNIQUE_4_1(ShdDir5M, DrawPosXY_VS(), ShdDirM_PS(5, false)); TECHNIQUE_4_1(ShdDir5CM, DrawPosXY_VS(), ShdDirM_PS(5, true));
  1809. TECHNIQUE_4_1(ShdDir6M, DrawPosXY_VS(), ShdDirM_PS(6, false)); TECHNIQUE_4_1(ShdDir6CM, DrawPosXY_VS(), ShdDirM_PS(6, true));
  1810. /******************************************************************************/
  1811. Vec4 ShdPnt_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1812. NOPERSP Vec2 inPosXY:TEXCOORD1,
  1813. NOPERSP PIXEL):COLOR
  1814. {
  1815. return ShadowPointValue(GetPosPoint(inTex, inPosXY), ShadowJitter(pixel.xy), true);
  1816. }
  1817. #if MODEL>=SM_4
  1818. Vec4 ShdPntM_PS(NOPERSP Vec2 inTex :TEXCOORD0 ,
  1819. NOPERSP Vec2 inPosXY:TEXCOORD1 ,
  1820. NOPERSP PIXEL,
  1821. UInt index :SV_SampleIndex):COLOR
  1822. {
  1823. return ShadowPointValue(GetPosMS(pixel.xy, index, inPosXY), ShadowJitter(pixel.xy), true);
  1824. }
  1825. #endif
  1826. TECHNIQUE (ShdPnt , DrawPosXY_VS(), ShdPnt_PS ());
  1827. TECHNIQUE_4_1(ShdPntM, DrawPosXY_VS(), ShdPntM_PS());
  1828. /******************************************************************************/
  1829. Vec4 ShdCone_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1830. NOPERSP Vec2 inPosXY:TEXCOORD1,
  1831. NOPERSP PIXEL):COLOR
  1832. {
  1833. return ShadowConeValue(GetPosPoint(inTex, inPosXY), ShadowJitter(pixel.xy), true);
  1834. }
  1835. #if MODEL>=SM_4
  1836. Vec4 ShdConeM_PS(NOPERSP Vec2 inTex :TEXCOORD0 ,
  1837. NOPERSP Vec2 inPosXY:TEXCOORD1 ,
  1838. NOPERSP PIXEL,
  1839. UInt index :SV_SampleIndex):COLOR
  1840. {
  1841. return ShadowConeValue(GetPosMS(pixel.xy, index, inPosXY), ShadowJitter(pixel.xy), true);
  1842. }
  1843. #endif
  1844. TECHNIQUE (ShdCone , DrawPosXY_VS(), ShdCone_PS());
  1845. TECHNIQUE_4_1(ShdConeM, DrawPosXY_VS(), ShdConeM_PS());
  1846. /******************************************************************************/
  1847. Vec4 ShdBlur_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1848. uniform Int samples ):COLOR
  1849. {
  1850. Flt weight=0.25f,
  1851. color =TexPoint(Col, inTex).API(a, r, r)*weight, // DX9 uses A8 while others use R8 RT
  1852. z =TexDepthPoint(inTex);
  1853. Vec2 dw_mad=DepthWeightMAD(z);
  1854. UNROLL for(Int i=0; i<samples; i++)
  1855. {
  1856. Vec2 t;
  1857. if(samples== 4)t=ColSize.xy*BlendOfs4 [i]+inTex;
  1858. //if(samples== 5)t=ColSize.xy*BlendOfs5 [i]+inTex;
  1859. if(samples== 6)t=ColSize.xy*BlendOfs6 [i]+inTex;
  1860. if(samples== 8)t=ColSize.xy*BlendOfs8 [i]+inTex;
  1861. //if(samples== 9)t=ColSize.xy*BlendOfs9 [i]+inTex;
  1862. if(samples==12)t=ColSize.xy*BlendOfs12[i]+inTex;
  1863. //if(samples==13)t=ColSize.xy*BlendOfs13[i]+inTex;
  1864. // use linear filtering because texcoords are not rounded
  1865. Flt w=DepthWeight(z-TexDepthLinear(t), dw_mad);
  1866. color +=w*TexLod(Col, t).API(a, r, r); // DX9 uses A8 while others use R8 RT, use linear filtering because texcoords aren't rounded
  1867. weight+=w;
  1868. }
  1869. return color/weight;
  1870. }
  1871. Vec4 ShdBlurX_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1872. uniform Int range ):COLOR
  1873. {
  1874. Flt weight=0.5f,
  1875. color =TexPoint(Col, inTex).API(a, r, r)*weight, // DX9 uses A8 while others use R8 RT
  1876. z =TexDepthPoint(inTex);
  1877. Vec2 dw_mad=DepthWeightMAD(z), t; t.y=inTex.y;
  1878. UNROLL for(Int i=-range; i<=range; i++)if(i)
  1879. {
  1880. // use linear filtering because texcoords are not rounded
  1881. t.x=ColSize.x*(2*i+((i>0) ? -0.5f : 0.5f))+inTex.x;
  1882. Flt w=DepthWeight(z-TexDepthLinear(t), dw_mad);
  1883. color +=w*TexLod(Col, t).API(a, r, r); // DX9 uses A8 while others use R8 RT, use linear filtering because texcoords aren't rounded
  1884. weight+=w;
  1885. }
  1886. return color/weight;
  1887. }
  1888. Vec4 ShdBlurY_PS(NOPERSP Vec2 inTex:TEXCOORD,
  1889. uniform Int range ):COLOR
  1890. {
  1891. Flt weight=0.5f,
  1892. color =TexPoint(Col, inTex).API(a, r, r)*weight, // DX9 uses A8 while others use R8 RT
  1893. z =TexDepthPoint(inTex);
  1894. Vec2 dw_mad=DepthWeightMAD(z), t; t.x=inTex.x;
  1895. UNROLL for(Int i=-range; i<=range; i++)if(i)
  1896. {
  1897. // use linear filtering because texcoords are not rounded
  1898. t.y=ColSize.y*(2*i+((i>0) ? -0.5f : 0.5f))+inTex.y;
  1899. Flt w=DepthWeight(z-TexDepthLinear(t), dw_mad);
  1900. color +=w*TexLod(Col, t).API(a, r, r); // DX9 uses A8 while others use R8 RT, use linear filtering because texcoords aren't rounded
  1901. weight+=w;
  1902. }
  1903. return color/weight;
  1904. }
  1905. TECHNIQUE(ShdBlur4 , Draw_VS(), ShdBlur_PS(4));
  1906. //TECHNIQUE(ShdBlur5 , Draw_VS(), ShdBlur_PS(5));
  1907. TECHNIQUE(ShdBlur6 , Draw_VS(), ShdBlur_PS(6));
  1908. TECHNIQUE(ShdBlur8 , Draw_VS(), ShdBlur_PS(8));
  1909. //TECHNIQUE(ShdBlur9 , Draw_VS(), ShdBlur_PS(9));
  1910. TECHNIQUE(ShdBlur12, Draw_VS(), ShdBlur_PS(12));
  1911. //TECHNIQUE(ShdBlur13, Draw_VS(), ShdBlur_PS(13));
  1912. //TECHNIQUE(ShdBlurX1, Draw_VS(), ShdBlurX_PS(1));
  1913. //TECHNIQUE(ShdBlurY1, Draw_VS(), ShdBlurY_PS(1));
  1914. TECHNIQUE(ShdBlurX2, Draw_VS(), ShdBlurX_PS(2));
  1915. TECHNIQUE(ShdBlurY2, Draw_VS(), ShdBlurY_PS(2));
  1916. /******************************************************************************/
  1917. // LIGHT
  1918. /******************************************************************************/
  1919. BUFFER(LightMap)
  1920. Flt LightMapScale =1,
  1921. LightMapSpecular;
  1922. Vec LightMapColAdd ;
  1923. BUFFER_END
  1924. Vec4 LightDir_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1925. NOPERSP Vec2 inPosXY:TEXCOORD1,
  1926. uniform Int shadow ,
  1927. uniform Bool quality ):COLOR
  1928. {
  1929. // shadow
  1930. Half shd; if(shadow)shd=TexPoint(Col, inTex).API(a, r, r); // DX9 uses A8 while others use R8 RT
  1931. // diffuse
  1932. VecH4 nrm=GetNormal (inTex, quality);
  1933. Half lum=LightDiffuse(nrm.xyz, Light_dir.dir); if(shadow)lum*=shd; clip(lum-EPS_COL);
  1934. // specular
  1935. VecH eye_dir =Normalize (-Vec(inPosXY, 1));
  1936. Half specular=LightSpecular(nrm.xyz, nrm.w, Light_dir.dir, eye_dir); if(shadow)specular*=shd;
  1937. return Vec4(Light_dir.color.rgb*lum, Light_dir.color.a*specular);
  1938. }
  1939. #if MODEL>=SM_4
  1940. Vec4 LightDirM_PS(NOPERSP Vec2 inTex :TEXCOORD0 ,
  1941. NOPERSP Vec2 inPosXY:TEXCOORD1 ,
  1942. NOPERSP PIXEL ,
  1943. UInt index :SV_SampleIndex,
  1944. uniform Bool shadow ,
  1945. uniform Bool quality ):COLOR
  1946. {
  1947. // shadow
  1948. Half shd; if(shadow)shd=TexSample(ColMS, pixel.xy, index).x;
  1949. // diffuse
  1950. VecH4 nrm=GetNormalMS(pixel.xy, index, quality);
  1951. Half lum=LightDiffuse(nrm.xyz, Light_dir.dir); if(shadow)lum*=shd; clip(lum-EPS_COL);
  1952. // specular
  1953. VecH eye_dir =Normalize (-Vec(inPosXY, 1));
  1954. Half specular=LightSpecular(nrm.xyz, nrm.w, Light_dir.dir, eye_dir); if(shadow)specular*=shd;
  1955. return Vec4(Light_dir.color.rgb*lum, Light_dir.color.a*specular);
  1956. }
  1957. #endif
  1958. TECHNIQUE (LightDir , DrawPosXY_VS(), LightDir_PS (false, false));
  1959. TECHNIQUE (LightDirS , DrawPosXY_VS(), LightDir_PS (true , false));
  1960. TECHNIQUE (LightDirQ , DrawPosXY_VS(), LightDir_PS (false, true ));
  1961. TECHNIQUE (LightDirSQ, DrawPosXY_VS(), LightDir_PS (true , true ));
  1962. TECHNIQUE_4_1(LightDirM , DrawPosXY_VS(), LightDirM_PS(false, false));
  1963. TECHNIQUE_4_1(LightDirSM, DrawPosXY_VS(), LightDirM_PS(true , false));
  1964. // no Quality version for MSAA
  1965. /******************************************************************************/
  1966. Vec4 LightPnt_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  1967. NOPERSP Vec2 inPosXY:TEXCOORD1,
  1968. uniform Int shadow ,
  1969. uniform Bool quality ):COLOR
  1970. {
  1971. // shadow
  1972. Half shd; if(shadow)
  1973. {
  1974. shd=ShadowFinal(TexPoint(Col, inTex).API(a, r, r)); // DX9 uses A8 while others use R8 RT
  1975. clip(shd-EPS_COL);
  1976. }
  1977. // distance
  1978. Vec pos =GetPosPoint(inTex, inPosXY),
  1979. light_dir=Light_point.pos-pos;
  1980. Half power =LightPointDist(light_dir); if(shadow)power*=shd; clip(power-EPS_COL);
  1981. // diffuse
  1982. light_dir=Normalize (light_dir);
  1983. VecH4 nrm =GetNormal (inTex, quality);
  1984. Half lum =LightDiffuse(nrm.xyz, light_dir)*power;
  1985. // specular
  1986. VecH eye_dir =Normalize (-pos);
  1987. Half specular=LightSpecular( nrm.xyz, nrm.w, light_dir, eye_dir)*power;
  1988. return Vec4(Light_point.color.rgb*lum, Light_point.color.a*specular);
  1989. }
  1990. #if MODEL>=SM_4
  1991. Vec4 LightPntM_PS(NOPERSP Vec2 inTex :TEXCOORD0 ,
  1992. NOPERSP Vec2 inPosXY:TEXCOORD1 ,
  1993. NOPERSP PIXEL ,
  1994. UInt index :SV_SampleIndex,
  1995. uniform Bool shadow ,
  1996. uniform Bool quality ):COLOR
  1997. {
  1998. // shadow
  1999. Half shd; if(shadow){shd=ShadowFinal(TexSample(ColMS, pixel.xy, index).x); clip(shd-EPS_COL);}
  2000. // distance
  2001. Vec pos =GetPosMS(pixel.xy, index, inPosXY),
  2002. light_dir=Light_point.pos-pos;
  2003. Half power =LightPointDist(light_dir); if(shadow)power*=shd; clip(power-EPS_COL);
  2004. // diffuse
  2005. light_dir=Normalize (light_dir);
  2006. VecH4 nrm =GetNormalMS (pixel.xy, index, quality);
  2007. Half lum =LightDiffuse(nrm.xyz, light_dir)*power;
  2008. // specular
  2009. VecH eye_dir =Normalize (-pos);
  2010. Half specular=LightSpecular( nrm.xyz, nrm.w, light_dir, eye_dir)*power;
  2011. return Vec4(Light_point.color.rgb*lum, Light_point.color.a*specular);
  2012. }
  2013. #endif
  2014. TECHNIQUE (LightPnt , DrawPosXY_VS(), LightPnt_PS (false, false));
  2015. TECHNIQUE (LightPntS , DrawPosXY_VS(), LightPnt_PS (true , false));
  2016. TECHNIQUE (LightPntQ , DrawPosXY_VS(), LightPnt_PS (false, true ));
  2017. TECHNIQUE (LightPntSQ, DrawPosXY_VS(), LightPnt_PS (true , true ));
  2018. TECHNIQUE_4_1(LightPntM , DrawPosXY_VS(), LightPntM_PS(false, false));
  2019. TECHNIQUE_4_1(LightPntSM, DrawPosXY_VS(), LightPntM_PS(true , false));
  2020. // no Quality version for MSAA
  2021. /******************************************************************************/
  2022. Vec4 LightSqr_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  2023. NOPERSP Vec2 inPosXY:TEXCOORD1,
  2024. uniform Int shadow ,
  2025. uniform Bool quality ):COLOR
  2026. {
  2027. // shadow
  2028. Half shd; if(shadow)
  2029. {
  2030. shd=ShadowFinal(TexPoint(Col, inTex).API(a, r, r)); // DX9 uses A8 while others use R8 RT
  2031. clip(shd-EPS_COL);
  2032. }
  2033. // distance
  2034. Vec pos =GetPosPoint(inTex, inPosXY),
  2035. light_dir=Light_sqr.pos-pos;
  2036. Half power =LightSqrDist(light_dir); if(shadow)power*=shd; clip(power-EPS_COL);
  2037. // diffuse
  2038. light_dir=Normalize (light_dir);
  2039. VecH4 nrm =GetNormal (inTex, quality);
  2040. Half lum =LightDiffuse(nrm.xyz, light_dir)*power;
  2041. // specular
  2042. VecH eye_dir =Normalize (-pos);
  2043. Half specular=LightSpecular( nrm.xyz, nrm.w, light_dir, eye_dir)*power;
  2044. return Vec4(Light_sqr.color.rgb*lum, Light_sqr.color.a*specular);
  2045. }
  2046. #if MODEL>=SM_4
  2047. Vec4 LightSqrM_PS(NOPERSP Vec2 inTex :TEXCOORD0 ,
  2048. NOPERSP Vec2 inPosXY:TEXCOORD1 ,
  2049. NOPERSP PIXEL ,
  2050. UInt index :SV_SampleIndex,
  2051. uniform Bool shadow ,
  2052. uniform Bool quality ):COLOR
  2053. {
  2054. // shadow
  2055. Half shd; if(shadow){shd=ShadowFinal(TexSample(ColMS, pixel.xy, index).x); clip(shd-EPS_COL);}
  2056. // distance
  2057. Vec pos =GetPosMS(pixel.xy, index, inPosXY),
  2058. light_dir=Light_sqr.pos-pos;
  2059. Half power =LightSqrDist(light_dir); if(shadow)power*=shd; clip(power-EPS_COL);
  2060. // diffuse
  2061. light_dir=Normalize (light_dir);
  2062. VecH4 nrm =GetNormalMS (pixel.xy, index, quality);
  2063. Half lum =LightDiffuse(nrm.xyz, light_dir)*power;
  2064. // specular
  2065. VecH eye_dir =Normalize (-pos);
  2066. Half specular=LightSpecular( nrm.xyz, nrm.w, light_dir, eye_dir)*power;
  2067. return Vec4(Light_sqr.color.rgb*lum, Light_sqr.color.a*specular);
  2068. }
  2069. #endif
  2070. TECHNIQUE (LightSqr , DrawPosXY_VS(), LightSqr_PS (false, false));
  2071. TECHNIQUE (LightSqrS , DrawPosXY_VS(), LightSqr_PS (true , false));
  2072. TECHNIQUE (LightSqrQ , DrawPosXY_VS(), LightSqr_PS (false, true ));
  2073. TECHNIQUE (LightSqrSQ, DrawPosXY_VS(), LightSqr_PS (true , true ));
  2074. TECHNIQUE_4_1(LightSqrM , DrawPosXY_VS(), LightSqrM_PS(false, false));
  2075. TECHNIQUE_4_1(LightSqrSM, DrawPosXY_VS(), LightSqrM_PS(true , false));
  2076. // no Quality version for MSAA
  2077. /******************************************************************************/
  2078. Vec4 LightCone_PS(NOPERSP Vec2 inTex :TEXCOORD0,
  2079. NOPERSP Vec2 inPosXY:TEXCOORD1,
  2080. uniform Int shadow ,
  2081. uniform Bool quality ,
  2082. uniform Bool image ):COLOR
  2083. {
  2084. // shadow
  2085. Half shd; if(shadow)
  2086. {
  2087. shd=ShadowFinal(TexPoint(Col, inTex).API(a, r, r)); // DX9 uses A8 while others use R8 RT
  2088. clip(shd-EPS_COL);
  2089. }
  2090. // distance & angle
  2091. Vec pos =GetPosPoint(inTex, inPosXY),
  2092. light_dir=Light_cone.pos-pos,
  2093. dir =mul(Light_cone.mtrx, light_dir); dir.xy/=dir.z; clip(Vec(1-Abs(dir.xy), dir.z));
  2094. Half power =LightConeAngle(dir.xy)*LightConeDist(light_dir); if(shadow)power*=shd; clip(power-EPS_COL);
  2095. // diffuse
  2096. light_dir=Normalize (light_dir);
  2097. VecH4 nrm =GetNormal (inTex, quality);
  2098. Half lum =LightDiffuse(nrm.xyz, light_dir)*power;
  2099. // specular
  2100. VecH eye_dir =Normalize (-pos);
  2101. Half specular=LightSpecular( nrm.xyz, nrm.w, light_dir, eye_dir)*power;
  2102. if(image)
  2103. {
  2104. VecH map_col=Tex(Col1, dir.xy*(LightMapScale*0.5f)+0.5f).rgb;
  2105. return Vec4(Light_cone.color.rgb*lum*(map_col+LightMapColAdd), Light_cone.color.a*specular + LightMapSpecular*Max(map_col.rgb)*power);
  2106. }else
  2107. {
  2108. return Vec4(Light_cone.color.rgb*lum, Light_cone.color.a*specular);
  2109. }
  2110. }
  2111. #if MODEL>=SM_4
  2112. Vec4 LightConeM_PS(NOPERSP Vec2 inTex :TEXCOORD0 ,
  2113. NOPERSP Vec2 inPosXY:TEXCOORD1 ,
  2114. NOPERSP PIXEL ,
  2115. UInt index :SV_SampleIndex,
  2116. uniform Bool shadow ,
  2117. uniform Bool quality ,
  2118. uniform Bool image ):COLOR
  2119. {
  2120. // shadow
  2121. Half shd; if(shadow){shd=ShadowFinal(TexSample(ColMS, pixel.xy, index).x); clip(shd-EPS_COL);}
  2122. // distance & angle
  2123. Vec pos =GetPosMS(pixel.xy, index, inPosXY),
  2124. light_dir=Light_cone.pos-pos,
  2125. dir =mul(Light_cone.mtrx, light_dir); dir.xy/=dir.z; clip(Vec(1-Abs(dir.xy), dir.z));
  2126. Half power =LightConeAngle(dir.xy)*LightConeDist(light_dir); if(shadow)power*=shd; clip(power-EPS_COL);
  2127. // diffuse
  2128. light_dir=Normalize (light_dir);
  2129. VecH4 nrm =GetNormalMS (pixel.xy, index, quality);
  2130. Half lum =LightDiffuse(nrm.xyz, light_dir)*power;
  2131. // specular
  2132. VecH eye_dir =Normalize (-pos);
  2133. Half specular=LightSpecular( nrm.xyz, nrm.w, light_dir, eye_dir)*power;
  2134. if(image)
  2135. {
  2136. VecH map_col=Tex(Col1, dir.xy*(LightMapScale*0.5f)+0.5f).rgb;
  2137. return Vec4(Light_cone.color.rgb*lum*(map_col+LightMapColAdd), Light_cone.color.a*specular + LightMapSpecular*Max(map_col.rgb)*power);
  2138. }else
  2139. {
  2140. return Vec4(Light_cone.color.rgb*lum, Light_cone.color.a*specular);
  2141. }
  2142. }
  2143. #endif
  2144. TECHNIQUE (LightCone , DrawPosXY_VS(), LightCone_PS (false, false, false));
  2145. TECHNIQUE (LightConeS , DrawPosXY_VS(), LightCone_PS (true , false, false));
  2146. TECHNIQUE (LightConeQ , DrawPosXY_VS(), LightCone_PS (false, true , false));
  2147. TECHNIQUE (LightConeSQ , DrawPosXY_VS(), LightCone_PS (true , true , false));
  2148. TECHNIQUE (LightConeI , DrawPosXY_VS(), LightCone_PS (false, false, true ));
  2149. TECHNIQUE (LightConeSI , DrawPosXY_VS(), LightCone_PS (true , false, true ));
  2150. TECHNIQUE (LightConeQI , DrawPosXY_VS(), LightCone_PS (false, true , true ));
  2151. TECHNIQUE (LightConeSQI, DrawPosXY_VS(), LightCone_PS (true , true , true ));
  2152. TECHNIQUE_4_1(LightConeM , DrawPosXY_VS(), LightConeM_PS(false, false, false));
  2153. TECHNIQUE_4_1(LightConeSM , DrawPosXY_VS(), LightConeM_PS(true , false, false));
  2154. TECHNIQUE_4_1(LightConeIM , DrawPosXY_VS(), LightConeM_PS(false, false, true ));
  2155. TECHNIQUE_4_1(LightConeSIM, DrawPosXY_VS(), LightConeM_PS(true , false, true ));
  2156. // no Quality version for MSAA
  2157. /******************************************************************************/
  2158. // COL LIGHT
  2159. /******************************************************************************/
  2160. BUFFER(ColLight)
  2161. VecH NightShadeColor;
  2162. BUFFER_END
  2163. Flt CelShade(Flt lum) {return TexLod(Det1, Vec2(lum, 0.5f)).x;} // have to use linear filtering
  2164. Vec ColLight(Vec4 color, Vec4 lum, Flt ao, Vec night_shade_col,
  2165. uniform Bool ao_do ,
  2166. uniform Bool cel_shade,
  2167. uniform Bool night_shade)
  2168. {
  2169. // treat glow as if it's a light source, this will have 2 effects: 1) pixels will have color even without any lights 2) this will disable night shade effects and retain original color (not covered by night shade), this is because 'night_shade_intensity' is multiplied by "Sat(1-max_lum)"
  2170. #if 0 // simply adding doesn't provide good results
  2171. lum.rgb+=color.w;
  2172. #else // instead lerp to 1, to avoid glow pixels getting too bright, because if color is mostly red (255, 40, 20), but if too much light is applied, then it could become more white 10*(255, 40, 20)=(2550, 400, 200), and we want pixels to glow with exact color as on the texture
  2173. #if 0 // slower
  2174. lum.rgb=Lerp(lum.rgb, 1, color.w);
  2175. #else // faster
  2176. lum.rgb=lum.rgb*(1-color.w) + color.w;
  2177. #endif
  2178. #endif
  2179. Flt max_lum=Max(lum.rgb);
  2180. if(cel_shade)
  2181. {
  2182. max_lum=CelShade(max_lum);
  2183. lum.rgb=max_lum;
  2184. }
  2185. Flt spec =lum.w/Max(max_lum, EPS);
  2186. Vec col_lit=(color.rgb+spec)*lum.rgb;
  2187. if(night_shade)
  2188. {
  2189. Flt night_shade_intensity=Sat(1-max_lum) // only for low light
  2190. *SRGBLumOfSRGBColor(color.rgb); // set based on unlit color luminance
  2191. if(ao_do)night_shade_intensity*=ao;
  2192. col_lit+=night_shade_intensity*night_shade_col;
  2193. }
  2194. return col_lit;
  2195. }
  2196. Vec4 ColLight_PS(NOPERSP Vec2 inTex:TEXCOORD ,
  2197. NOPERSP PIXEL,
  2198. uniform Int multi_sample ,
  2199. uniform Bool ao_do =false,
  2200. uniform Bool cel_shade=false,
  2201. uniform Bool night_shade=false):COLOR
  2202. {
  2203. Flt ao; Vec ambient; if(ao_do){ao=TexLod(Det, inTex).API(a, r, r); ambient=AmbColor*ao;} // use 'TexLod' because AO can be of different size and we need to use tex filtering, DX9 uses A8 while others use R8 RT
  2204. #if MODEL>=SM_4
  2205. VecI p=VecI(pixel.xy, 0);
  2206. if(multi_sample)
  2207. {
  2208. if(multi_sample==1) // 1 sample
  2209. {
  2210. Vec4 color=TexSample(ColMS, pixel.xy, 0),
  2211. lum =TexSample(LumMS, pixel.xy, 0), // needed because Mesh Ambient is stored only in Multi Sampled Lum
  2212. lum1s= Lum .Load(p);
  2213. lum +=lum1s ;
  2214. if(ao_do)lum .rgb+=ambient;
  2215. color.rgb =ColLight(color, lum, ao, NightShadeColor, ao_do, cel_shade, night_shade);
  2216. return color;
  2217. }else // n samples
  2218. {
  2219. Vec4 color_sum=0;
  2220. Flt valid_samples=EPS;
  2221. Vec night_shade_col=NightShadeColor; if(night_shade && ao_do)night_shade_col*=ao; // compute it once, and not inside 'ColLight'
  2222. UNROLL for(Int i=0; i<MS_SAMPLES; i++)if(DEPTH_FOREGROUND(TexDepthMSRaw(pixel.xy, i))) // valid sample
  2223. {
  2224. Vec4 color=TexSample(ColMS, pixel.xy, i),
  2225. lum =TexSample(LumMS, pixel.xy, i);
  2226. if(ao_do)lum .rgb+=ambient;
  2227. color.rgb =ColLight(color, lum, ao, night_shade_col, false, cel_shade, night_shade); // we've already adjusted 'night_shade_col' by 'ao', so set 'ao_do' as false
  2228. color_sum+=color;
  2229. valid_samples++;
  2230. }
  2231. return color_sum/valid_samples; // MS_SAMPLES
  2232. }
  2233. }else
  2234. {
  2235. Vec4 color=Col.Load(p),
  2236. lum =Lum.Load(p);
  2237. if(ao_do)lum .rgb+=ambient;
  2238. color.rgb =ColLight(color, lum, ao, NightShadeColor, ao_do, cel_shade, night_shade);
  2239. return color;
  2240. }
  2241. #else
  2242. Vec4 color=TexPoint(Col, inTex),
  2243. lum =TexPoint(Lum, inTex);
  2244. if(ao_do)lum .rgb+=ambient;
  2245. color.rgb =ColLight(color, lum, ao, NightShadeColor, ao_do, cel_shade, night_shade);
  2246. return color;
  2247. #endif
  2248. }
  2249. TECHNIQUE(ColLight0 , Draw_VS(), ColLight_PS(0));
  2250. TECHNIQUE(ColLight0A , Draw_VS(), ColLight_PS(0, true));
  2251. TECHNIQUE(ColLight0C , Draw_VS(), ColLight_PS(0, false, true));
  2252. TECHNIQUE(ColLight0AC , Draw_VS(), ColLight_PS(0, true , true));
  2253. TECHNIQUE(ColLight0N , Draw_VS(), ColLight_PS(0, false, false, true));
  2254. TECHNIQUE(ColLight0AN , Draw_VS(), ColLight_PS(0, true , false, true));
  2255. TECHNIQUE(ColLight0CN , Draw_VS(), ColLight_PS(0, false, true , true));
  2256. TECHNIQUE(ColLight0ACN, Draw_VS(), ColLight_PS(0, true , true , true));
  2257. #if MODEL>=SM_4 // multi sample
  2258. TECHNIQUE(ColLight1 , Draw_VS(), ColLight_PS(1));
  2259. TECHNIQUE(ColLight1A , Draw_VS(), ColLight_PS(1, true));
  2260. TECHNIQUE(ColLight1C , Draw_VS(), ColLight_PS(1, false, true));
  2261. TECHNIQUE(ColLight1AC , Draw_VS(), ColLight_PS(1, true , true));
  2262. TECHNIQUE(ColLight1N , Draw_VS(), ColLight_PS(1, false, false, true));
  2263. TECHNIQUE(ColLight1AN , Draw_VS(), ColLight_PS(1, true , false, true));
  2264. TECHNIQUE(ColLight1CN , Draw_VS(), ColLight_PS(1, false, true , true));
  2265. TECHNIQUE(ColLight1ACN, Draw_VS(), ColLight_PS(1, true , true , true));
  2266. TECHNIQUE(ColLight2 , Draw_VS(), ColLight_PS(2));
  2267. TECHNIQUE(ColLight2A , Draw_VS(), ColLight_PS(2, true));
  2268. TECHNIQUE(ColLight2C , Draw_VS(), ColLight_PS(2, false, true));
  2269. TECHNIQUE(ColLight2AC , Draw_VS(), ColLight_PS(2, true , true));
  2270. TECHNIQUE(ColLight2N , Draw_VS(), ColLight_PS(2, false, false, true));
  2271. TECHNIQUE(ColLight2AN , Draw_VS(), ColLight_PS(2, true , false, true));
  2272. TECHNIQUE(ColLight2CN , Draw_VS(), ColLight_PS(2, false, true , true));
  2273. TECHNIQUE(ColLight2ACN, Draw_VS(), ColLight_PS(2, true , true , true));
  2274. #endif
  2275. /******************************************************************************/
  2276. // PARTICLE
  2277. /******************************************************************************/
  2278. #define ANIM_NONE 0
  2279. #define ANIM_YES 1
  2280. #define ANIM_SMOOTH 2
  2281. BUFFER(Particle)
  2282. Vec2 ParticleFrames=Vec2(1, 1);
  2283. BUFFER_END
  2284. void Particle_VS(VtxInput vtx,
  2285. out Vec4 outVtx :POSITION ,
  2286. out VecH4 outCol :COLOR ,
  2287. out Vec2 outTex :TEXCOORD0,
  2288. out Vec2 outZS :TEXCOORD1,
  2289. out Vec outAnim:TEXCOORD2,
  2290. uniform Bool palette ,
  2291. uniform Bool soft ,
  2292. uniform Int anim ,
  2293. uniform Bool motion_stretch ,
  2294. uniform Bool stretch_alpha )
  2295. {
  2296. outTex=vtx.tex();
  2297. outCol=vtx.color();
  2298. Flt size =vtx.size(),
  2299. angle =vtx._tan.w;
  2300. Vec pos =TransformPos(vtx.pos());
  2301. Vec2 offset=outTex*Vec2(2, -2)+Vec2(-1, 1), cos_sin; CosSin(cos_sin.x, cos_sin.y, angle); offset=Rotate(offset, cos_sin);
  2302. if(motion_stretch)
  2303. if(pos.z>0)
  2304. {
  2305. #define PARTICLE_PROJECT 100
  2306. Vec vel =TransformDir(vtx.tan()); if(vel.z<0)vel=-vel; // view space velocity, always make it along the camera direction, so we won't have a situation where the 'pos1' is behind the camera
  2307. Vec pos1=pos+vel/PARTICLE_PROJECT;
  2308. Vec2 vel2=(pos1.xy/pos1.z - pos.xy/pos.z)*PARTICLE_PROJECT; // 2D velocity
  2309. Flt len =Length(vel2)+EPS;
  2310. //if(len>0) // instead of using "if", add EPS line above - it's faster
  2311. {
  2312. //Flt max_stretch=5; if(len>max_stretch){vel2*=max_stretch/len; len=max_stretch;} // NaN
  2313. Vec2 x=vel2*(vel2.x/len),
  2314. y=vel2*(vel2.y/len);
  2315. offset=Vec2(offset.x*(x.x+1) + offset.y*y.x, offset.x*x.y + offset.y*(y.y+1));
  2316. if(stretch_alpha)
  2317. {
  2318. if(palette)outCol /=1+len; // in RM_PALETTE each component
  2319. else outCol.a/=1+len; // in RM_BLEND only alpha
  2320. }
  2321. }
  2322. }
  2323. pos.xy+=offset*size;
  2324. // sky
  2325. Flt d=Length(pos), opacity=Sat(d*SkyFracMulAdd.x + SkyFracMulAdd.y);
  2326. if(palette)outCol *=opacity; // in RM_PALETTE each component
  2327. else outCol.a*=opacity; // in RM_BLEND only alpha
  2328. if(soft)
  2329. {
  2330. outZS.x=pos.z;
  2331. outZS.y=size;
  2332. if(pos.z >= -size)
  2333. {
  2334. Flt wanted_z=Max(Viewport.from+EPS, pos.z-size),
  2335. scale =wanted_z;
  2336. if(pos.z)scale /=pos .z; // NaN
  2337. pos.xyz*=scale;
  2338. }
  2339. }
  2340. if(anim!=ANIM_NONE)
  2341. {
  2342. Flt frame=vtx.tex1().x;
  2343. #if 0 // integer version
  2344. #if MODEL>=SM_4
  2345. #define INT UInt
  2346. #else
  2347. #define INT Int
  2348. #endif
  2349. INT frames=ParticleFrames.x*ParticleFrames.y;
  2350. INT f =INT(frame)%frames; // Trunc(frame)%frames; don't know why but doesn't work correctly
  2351. if(anim==ANIM_SMOOTH) // frame blending
  2352. {
  2353. INT f1=(f+1)%frames;
  2354. outAnim.xy =outTex;
  2355. outAnim.z =Frac(frame);
  2356. outAnim.x +=f1%INT(ParticleFrames.x);
  2357. outAnim.y +=f1/INT(ParticleFrames.x);
  2358. outAnim.xy/= ParticleFrames ;
  2359. }
  2360. outTex.x+=f%INT(ParticleFrames.x);
  2361. outTex.y+=f/INT(ParticleFrames.x);
  2362. outTex /= ParticleFrames ;
  2363. #undef INT
  2364. #else // float version
  2365. Flt frames=ParticleFrames.x*ParticleFrames.y; frame=Frac(frame/frames)*frames; // frame=[0..frames)
  2366. Flt f; frame=modf(frame, f);
  2367. if(anim==ANIM_SMOOTH) // frame blending
  2368. {
  2369. Flt f1=f+1; if(f1+0.5f>=frames)f1=0; // f1=(f+1)%frames;
  2370. outAnim.xy =outTex;
  2371. outAnim.z =frame ; // frame step [0..1)
  2372. Flt y; outAnim.x +=ParticleFrames.x*modf(f1/ParticleFrames.x, y); // outAnim.x+=f1%INT(ParticleFrames.x);
  2373. outAnim.y +=y ; // outAnim.y+=f1/INT(ParticleFrames.x);
  2374. outAnim.xy/=ParticleFrames ;
  2375. }
  2376. Flt y; outTex.x+=ParticleFrames.x*modf(f/ParticleFrames.x, y); // outTex.x+=f%INT(ParticleFrames.x);
  2377. outTex.y+=y ; // outTex.y+=f/INT(ParticleFrames.x);
  2378. outTex /=ParticleFrames ;
  2379. #endif
  2380. }
  2381. #if DX9 || GL // DX10+ should support all sizes, Image.partial
  2382. outTex *=ColSize.xy;
  2383. if(anim==ANIM_SMOOTH)outAnim.xy*=ColSize.xy;
  2384. #endif
  2385. outVtx=Project(pos);
  2386. }
  2387. /******************************************************************************/
  2388. Vec4 Particle_PS(PIXEL,
  2389. VecH4 inCol :COLOR ,
  2390. Vec2 inTex :TEXCOORD0,
  2391. Vec2 inZS :TEXCOORD1,
  2392. Vec inAnim:TEXCOORD2,
  2393. uniform Bool palette ,
  2394. uniform Bool soft ,
  2395. uniform Int anim ):COLOR
  2396. {
  2397. VecH4 tex= Tex(Col, inTex ) ;
  2398. if(anim==ANIM_SMOOTH)tex=Lerp(tex, Tex(Col, inAnim.xy), inAnim.z);
  2399. if(soft)
  2400. {
  2401. Flt z0 =inZS.x-tex.a*inZS.y,
  2402. z1 =inZS.x+tex.a*inZS.y;
  2403. tex.a*=Sat((TexDepthPoint(PIXEL_TO_SCREEN)-z0)/inZS.y); // fade out at occluder
  2404. tex.a*=Sat(z1/(z1-z0+EPS)); // smooth visibility fraction when particle near (or behind) camera, NaN
  2405. }
  2406. if(palette)return inCol*tex.a;
  2407. else return inCol*tex ;
  2408. }
  2409. /******************************************************************************/
  2410. TECHNIQUE(Bilb , Particle_VS(false, false, ANIM_NONE , false, false), Particle_PS(false, false, ANIM_NONE ));
  2411. TECHNIQUE(ParticleTex , Particle_VS(false, false, ANIM_NONE , true , false), Particle_PS(false, false, ANIM_NONE ));
  2412. TECHNIQUE(ParticleTexP , Particle_VS(true , false, ANIM_NONE , true , false), Particle_PS(true , false, ANIM_NONE ));
  2413. TECHNIQUE(ParticleTexS , Particle_VS(false, true , ANIM_NONE , true , false), Particle_PS(false, true , ANIM_NONE ));
  2414. TECHNIQUE(ParticleTexPS , Particle_VS(true , true , ANIM_NONE , true , false), Particle_PS(true , true , ANIM_NONE ));
  2415. TECHNIQUE(ParticleTexA , Particle_VS(false, false, ANIM_YES , true , false), Particle_PS(false, false, ANIM_YES ));
  2416. TECHNIQUE(ParticleTexPA , Particle_VS(true , false, ANIM_YES , true , false), Particle_PS(true , false, ANIM_YES ));
  2417. TECHNIQUE(ParticleTexSA , Particle_VS(false, true , ANIM_YES , true , false), Particle_PS(false, true , ANIM_YES ));
  2418. TECHNIQUE(ParticleTexPSA , Particle_VS(true , true , ANIM_YES , true , false), Particle_PS(true , true , ANIM_YES ));
  2419. TECHNIQUE(ParticleTexAA , Particle_VS(false, false, ANIM_SMOOTH, true , false), Particle_PS(false, false, ANIM_SMOOTH));
  2420. TECHNIQUE(ParticleTexPAA , Particle_VS(true , false, ANIM_SMOOTH, true , false), Particle_PS(true , false, ANIM_SMOOTH));
  2421. TECHNIQUE(ParticleTexSAA , Particle_VS(false, true , ANIM_SMOOTH, true , false), Particle_PS(false, true , ANIM_SMOOTH));
  2422. TECHNIQUE(ParticleTexPSAA , Particle_VS(true , true , ANIM_SMOOTH, true , false), Particle_PS(true , true , ANIM_SMOOTH));
  2423. TECHNIQUE(ParticleTexM , Particle_VS(false, false, ANIM_NONE , true , true ), Particle_PS(false, false, ANIM_NONE ));
  2424. TECHNIQUE(ParticleTexPM , Particle_VS(true , false, ANIM_NONE , true , true ), Particle_PS(true , false, ANIM_NONE ));
  2425. TECHNIQUE(ParticleTexSM , Particle_VS(false, true , ANIM_NONE , true , true ), Particle_PS(false, true , ANIM_NONE ));
  2426. TECHNIQUE(ParticleTexPSM , Particle_VS(true , true , ANIM_NONE , true , true ), Particle_PS(true , true , ANIM_NONE ));
  2427. TECHNIQUE(ParticleTexAM , Particle_VS(false, false, ANIM_YES , true , true ), Particle_PS(false, false, ANIM_YES ));
  2428. TECHNIQUE(ParticleTexPAM , Particle_VS(true , false, ANIM_YES , true , true ), Particle_PS(true , false, ANIM_YES ));
  2429. TECHNIQUE(ParticleTexSAM , Particle_VS(false, true , ANIM_YES , true , true ), Particle_PS(false, true , ANIM_YES ));
  2430. TECHNIQUE(ParticleTexPSAM , Particle_VS(true , true , ANIM_YES , true , true ), Particle_PS(true , true , ANIM_YES ));
  2431. TECHNIQUE(ParticleTexAAM , Particle_VS(false, false, ANIM_SMOOTH, true , true ), Particle_PS(false, false, ANIM_SMOOTH));
  2432. TECHNIQUE(ParticleTexPAAM , Particle_VS(true , false, ANIM_SMOOTH, true , true ), Particle_PS(true , false, ANIM_SMOOTH));
  2433. TECHNIQUE(ParticleTexSAAM , Particle_VS(false, true , ANIM_SMOOTH, true , true ), Particle_PS(false, true , ANIM_SMOOTH));
  2434. TECHNIQUE(ParticleTexPSAAM, Particle_VS(true , true , ANIM_SMOOTH, true , true ), Particle_PS(true , true , ANIM_SMOOTH));
  2435. /******************************************************************************/
  2436. Vec4 PaletteDraw_PS(NOPERSP Vec2 inTex:TEXCOORD):COLOR
  2437. {
  2438. Vec4 particle=TexLod(Col, inTex); // use linear filtering in case in the future we support downsized palette intensities (for faster fill-rate)
  2439. clip(Length2(particle)-Sqr(EPS_COL)); // 'clip' is faster than "BRANCH if(Length2(particle)>Sqr(EPS_COL))" (branch is however slightly faster when entire majority of pixels have some effect, however in most cases majority of pixels doesn't have anything so stick with 'clip')
  2440. // have to use linear filtering because this is palette image
  2441. Vec4 c0=TexLod(Col1, Vec2(particle.x, 0.5f/4)),
  2442. c1=TexLod(Col1, Vec2(particle.y, 1.5f/4)),
  2443. c2=TexLod(Col1, Vec2(particle.z, 2.5f/4)),
  2444. c3=TexLod(Col1, Vec2(particle.w, 3.5f/4));
  2445. Flt a =Max(c0.a, c1.a, c2.a, c3.a);
  2446. return Vec4((c0.rgb*c0.a
  2447. +c1.rgb*c1.a
  2448. +c2.rgb*c2.a
  2449. +c3.rgb*c3.a)/(a+EPS), a); // NaN
  2450. }
  2451. TECHNIQUE(PaletteDraw, Draw_VS(), PaletteDraw_PS());
  2452. /******************************************************************************/
  2453. // DECAL
  2454. /******************************************************************************/
  2455. BUFFER(Decal)
  2456. Vec DecalParams; // x=OpaqueFracMul, y=OpaqueFracAdd, z=alpha
  2457. BUFFER_END
  2458. inline Flt DecalOpaqueFracMul() {return DecalParams.x;}
  2459. inline Flt DecalOpaqueFracAdd() {return DecalParams.y;}
  2460. inline Flt DecalAlpha () {return DecalParams.z;}
  2461. void Decal_VS(VtxInput vtx,
  2462. out Vec4 outVtx :POSITION ,
  2463. out Matrix outMatrix :TEXCOORD0,
  2464. out Matrix3 outMatrixN:TEXCOORD3,
  2465. uniform Bool fullscreen ,
  2466. uniform Bool normal ,
  2467. uniform Bool palette )
  2468. {
  2469. outMatrix=ViewMatrix[0];
  2470. outMatrix[0]/=Length2(outMatrix[0]);
  2471. outMatrix[1]/=Length2(outMatrix[1]);
  2472. outMatrix[2]/=Length2(outMatrix[2]);
  2473. if(!palette && normal)
  2474. {
  2475. outMatrixN[0]=Normalize(outMatrix[0]);
  2476. outMatrixN[1]=Normalize(outMatrix[1]);
  2477. outMatrixN[2]=Normalize(outMatrix[2]);
  2478. }
  2479. if(fullscreen)
  2480. {
  2481. outVtx=Vec4(vtx.pos2(), !REVERSE_DEPTH, 1); AdjustPixelCenter(outVtx); // set Z to be at the end of the viewport, this enables optimizations by optional applying lighting only on solid pixels (no sky/background)
  2482. }else
  2483. {
  2484. outVtx=Project(TransformPos(vtx.pos()));
  2485. }
  2486. }
  2487. Vec4 Decal_PS(PIXEL,
  2488. Matrix inMatrix :TEXCOORD0,
  2489. Matrix3 inMatrixN:TEXCOORD3,
  2490. out Vec4 outNrm :COLOR1 ,
  2491. uniform Bool normal ,
  2492. uniform Bool palette ):COLOR
  2493. {
  2494. Vec pos =GetPosPoint(PIXEL_TO_SCREEN);
  2495. pos =mul((Matrix3)inMatrix, pos-inMatrix[3]);
  2496. Flt alpha=Sat(Abs(pos.z)*DecalOpaqueFracMul()+DecalOpaqueFracAdd());
  2497. clip(Vec(1-Abs(pos.xy), alpha-EPS_COL));
  2498. alpha*=DecalAlpha();
  2499. pos.xy=pos.xy*0.5f+0.5f;
  2500. Vec4 col=Tex(Col, pos.xy);
  2501. if(palette)
  2502. {
  2503. return col.a*(Color[0]*MaterialColor())*alpha;
  2504. }else
  2505. {
  2506. if(normal)
  2507. {
  2508. Vec4 tex_nrm =Tex(Nrm, pos.xy); // #MaterialTextureChannelOrder
  2509. Flt specular=tex_nrm.z*MaterialSpecular(); // specular is in 'nrm.z'
  2510. Vec nrm;
  2511. nrm.xy =(tex_nrm.xy*2-1)*MaterialRough(); // normal is in 'nrm.xy'
  2512. //if(detail)nrm.xy+=det.xy;
  2513. nrm.z =CalcZ(nrm.xy);
  2514. nrm =Transform(nrm, inMatrixN);
  2515. col.a =tex_nrm.w; // alpha is in 'nrm.w'
  2516. col *=Color[0]*MaterialColor();
  2517. col.a*=alpha;
  2518. #if SIGNED_NRM_RT
  2519. outNrm.xyz=nrm;
  2520. #else
  2521. outNrm.xyz=nrm*0.5f+0.5f;
  2522. #endif
  2523. outNrm.w=col.a; // alpha
  2524. }else
  2525. {
  2526. col *=Color[0]*MaterialColor();
  2527. col.a*=alpha;
  2528. }
  2529. return col;
  2530. }
  2531. }
  2532. TECHNIQUE(Decal , Decal_VS(false, false, false), Decal_PS(false, false));
  2533. TECHNIQUE(DecalN , Decal_VS(false, true , false), Decal_PS(true , false));
  2534. TECHNIQUE(DecalP , Decal_VS(false, false, true ), Decal_PS(false, true ));
  2535. TECHNIQUE(DecalF , Decal_VS(true , false, false), Decal_PS(false, false));
  2536. TECHNIQUE(DecalFN, Decal_VS(true , true , false), Decal_PS(true , false));
  2537. TECHNIQUE(DecalFP, Decal_VS(true , false, true ), Decal_PS(false, true ));
  2538. /******************************************************************************/
  2539. // BLOOM
  2540. /******************************************************************************/
  2541. BUFFER(Bloom)
  2542. VecH BloomParams; // x=original, y=scale, z=cut
  2543. BUFFER_END
  2544. void BloomDS_VS(VtxInput vtx,
  2545. out Vec2 outTex:TEXCOORD,
  2546. out Vec4 outVtx:POSITION,
  2547. uniform Bool glow ,
  2548. uniform Bool do_clamp ,
  2549. uniform Bool half )
  2550. {
  2551. outTex=vtx.tex (); if(glow)outTex-=ColSize.xy*Vec2(half ? 0.5f : 1.5f, half ? 0.5f : 1.5f);
  2552. outVtx=vtx.pos4(); AdjustPixelCenter(outVtx);
  2553. }
  2554. inline VecH BloomColor(VecH color, uniform Bool saturate)
  2555. {
  2556. if(saturate)
  2557. {
  2558. return color*BloomParams.y+BloomParams.z;
  2559. }else
  2560. {
  2561. Half col_lum=Max(color), lum=col_lum*BloomParams.y+BloomParams.z;
  2562. return (lum>0) ? color*(lum/col_lum) : VecH(0, 0, 0);
  2563. }
  2564. }
  2565. Vec4 BloomDS_PS(NOPERSP Vec2 inTex:TEXCOORD,
  2566. uniform Bool glow ,
  2567. uniform Bool do_clamp ,
  2568. uniform Bool half ,
  2569. uniform Bool saturate ):COLOR // "Max(0, " of the result is not needed because we're rendering to 1 byte per channel RT
  2570. {
  2571. if(glow)
  2572. {
  2573. const Int res=(half ? 2 : 4);
  2574. Vec color=0;
  2575. Vec4 glow =0;
  2576. UNROLL for(Int y=0; y<res; y++)
  2577. UNROLL for(Int x=0; x<res; x++)
  2578. {
  2579. Vec4 c=TexLod(Col, UVClamp(inTex+ColSize.xy*Vec2(x, y), do_clamp)); // can't use 'TexPoint' because 'Col' can be supersampled
  2580. color +=c.rgb;
  2581. glow.rgb+=c.rgb*c.a;
  2582. glow.a =Max(glow.a, c.a);
  2583. }
  2584. glow.rgb*=2*glow.a/Max(Vec4(glow.rgb, EPS)); // NaN (increase by 2 because normally it's too small)
  2585. return Vec4(Max(BloomColor(color, saturate), glow.rgb), 0);
  2586. }else
  2587. {
  2588. if(half)
  2589. {
  2590. return Vec4(BloomColor(TexLod(Col, UVClamp(inTex, do_clamp)).rgb, saturate), 0);
  2591. }else
  2592. {
  2593. Vec2 tex_min=UVClamp(inTex-ColSize.xy, do_clamp),
  2594. tex_max=UVClamp(inTex+ColSize.xy, do_clamp);
  2595. return Vec4(BloomColor(TexLod(Col, Vec2(tex_min.x, tex_min.y)).rgb
  2596. +TexLod(Col, Vec2(tex_max.x, tex_min.y)).rgb
  2597. +TexLod(Col, Vec2(tex_min.x, tex_max.y)).rgb
  2598. +TexLod(Col, Vec2(tex_max.x, tex_max.y)).rgb, saturate), 0);
  2599. }
  2600. }
  2601. }
  2602. TECHNIQUE(BloomDS , BloomDS_VS(false, false, false), BloomDS_PS(false, false, false, false));
  2603. TECHNIQUE(BloomDSC , BloomDS_VS(false, true , false), BloomDS_PS(false, true , false, false));
  2604. TECHNIQUE(BloomDSH , BloomDS_VS(false, false, true ), BloomDS_PS(false, false, true , false));
  2605. TECHNIQUE(BloomDSCH , BloomDS_VS(false, true , true ), BloomDS_PS(false, true , true , false));
  2606. TECHNIQUE(BloomGDS , BloomDS_VS(true , false, false), BloomDS_PS(true , false, false, false));
  2607. TECHNIQUE(BloomGDSC , BloomDS_VS(true , true , false), BloomDS_PS(true , true , false, false));
  2608. TECHNIQUE(BloomGDSH , BloomDS_VS(true , false, true ), BloomDS_PS(true , false, true , false));
  2609. TECHNIQUE(BloomGDSCH , BloomDS_VS(true , true , true ), BloomDS_PS(true , true , true , false));
  2610. TECHNIQUE(BloomDSS , BloomDS_VS(false, false, false), BloomDS_PS(false, false, false, true ));
  2611. TECHNIQUE(BloomDSCS , BloomDS_VS(false, true , false), BloomDS_PS(false, true , false, true ));
  2612. TECHNIQUE(BloomDSHS , BloomDS_VS(false, false, true ), BloomDS_PS(false, false, true , true ));
  2613. TECHNIQUE(BloomDSCHS , BloomDS_VS(false, true , true ), BloomDS_PS(false, true , true , true ));
  2614. TECHNIQUE(BloomGDSS , BloomDS_VS(true , false, false), BloomDS_PS(true , false, false, true ));
  2615. TECHNIQUE(BloomGDSCS , BloomDS_VS(true , true , false), BloomDS_PS(true , true , false, true ));
  2616. TECHNIQUE(BloomGDSHS , BloomDS_VS(true , false, true ), BloomDS_PS(true , false, true , true ));
  2617. TECHNIQUE(BloomGDSCHS, BloomDS_VS(true , true , true ), BloomDS_PS(true , true , true , true ));
  2618. /******************************************************************************/
  2619. Vec4 Bloom_PS(NOPERSP Vec2 inTex:TEXCOORD,
  2620. NOPERSP PIXEL ,
  2621. uniform Bool dither ):COLOR // Saturation of the result is not needed because we're rendering to 1 byte per channel RT
  2622. {
  2623. // final=src*original + Sat((src-cut)*scale)
  2624. VecH col=TexLod(Col , inTex).rgb*BloomParams.x // can't use 'TexPoint' because 'Col' can be supersampled
  2625. +TexLod(Col1, inTex).rgb; // can't use 'TexPoint' because 'Col1' can be smaller
  2626. if(dither)col+=DitherValueColor(pixel);
  2627. return Vec4(col, 1); // force full alpha so back buffer effects can work ok
  2628. }
  2629. TECHNIQUE(Bloom , Draw_VS(), Bloom_PS(false));
  2630. TECHNIQUE(BloomD, Draw_VS(), Bloom_PS(true ));
  2631. /******************************************************************************/
  2632. // FXAA
  2633. /******************************************************************************/
  2634. #define FxaaTex Image
  2635. #if MODEL>=SM_4
  2636. #define FxaaInt2 VecI2
  2637. #define FxaaTexTop(t, p ) t.SampleLevel(SamplerLinearClamp, p, 0)
  2638. #define FxaaTexOff(t, p, o, r) t.SampleLevel(SamplerLinearClamp, p, 0, o)
  2639. #else
  2640. #define FxaaInt2 Vec2
  2641. #define FxaaTexTop(t, p ) TexLod(t, p)
  2642. #define FxaaTexOff(t, p, o, r) TexLod(t, p+o*ColSize.xy)
  2643. #endif
  2644. #include "FXAA_config.h"
  2645. #include "FXAA.h"
  2646. Vec4 FXAA_PS(NOPERSP Vec2 pos:TEXCOORD):COLOR
  2647. {
  2648. return FxaaPixelShader(pos, 0, Col, Col, Col, ColSize.xy, 0, 0, 0, 0.475f, 0.15f, 0.0833f, 8.0, 0.125, 0.05, Vec4(1.0, -1.0, 0.25, -0.25));
  2649. }
  2650. TECHNIQUE(FXAA, Draw_VS(), FXAA_PS());
  2651. /******************************************************************************
  2652. // MLAA
  2653. Copyright (C) 2011 Jorge Jimenez ([email protected])
  2654. Copyright (C) 2011 Belen Masia ([email protected])
  2655. Copyright (C) 2011 Jose I. Echevarria ([email protected])
  2656. Copyright (C) 2011 Fernando Navarro ([email protected])
  2657. Copyright (C) 2011 Diego Gutierrez ([email protected])
  2658. All rights reserved.
  2659. /******************************************************************************
  2660. #define MLAA_MAX_SEARCH_STEPS 6
  2661. #define MLAA_MAX_DISTANCE 32
  2662. #define MLAA_THRESHOLD 0.1f
  2663. Vec2 MLAAArea(Vec2 distance, Flt e1, Flt e2)
  2664. {
  2665. Flt areaSize=MLAA_MAX_DISTANCE*5;
  2666. Vec2 pixcoord=MLAA_MAX_DISTANCE*Round(4*Vec2(e1, e2))+distance;
  2667. Vec2 texcoord=pixcoord/(areaSize-1);
  2668. return TexLod(Col1, texcoord).rg; // AreaMap
  2669. }
  2670. void MLAA_VS(VtxInput vtx,
  2671. out Vec2 outTex :TEXCOORD0,
  2672. out Vec4 outTexOffset[2]:TEXCOORD1,
  2673. out Vec4 outVtx :POSITION )
  2674. {
  2675. outVtx =Vec4(vtx.pos2(), !REVERSE_DEPTH, 1); AdjustPixelCenter(outVtx); // set Z to be at the end of the viewport, this enables optimizations by optional applying lighting only on solid pixels (no sky/background)
  2676. outTex =vtx.tex();
  2677. outTexOffset[0]=ColSize.xyxy*Vec4(-1, 0, 0,-1)+outTex.xyxy;
  2678. outTexOffset[1]=ColSize.xyxy*Vec4( 1, 0, 0, 1)+outTex.xyxy;
  2679. }
  2680. Vec4 MLAAEdge_PS(NOPERSP Vec2 texcoord :TEXCOORD0,
  2681. NOPERSP Vec4 offset[2]:TEXCOORD1):COLOR
  2682. {
  2683. Flt L =Dot(TexPoint(Col, texcoord ).rgb, ColorLumWeight2);
  2684. Flt Lleft =Dot(TexPoint(Col, offset[0].xy).rgb, ColorLumWeight2);
  2685. Flt Ltop =Dot(TexPoint(Col, offset[0].zw).rgb, ColorLumWeight2);
  2686. Flt Lright =Dot(TexPoint(Col, offset[1].xy).rgb, ColorLumWeight2);
  2687. Flt Lbottom=Dot(TexPoint(Col, offset[1].zw).rgb, ColorLumWeight2);
  2688. Vec4 delta=Abs(L.xxxx-Vec4(Lleft, Ltop, Lright, Lbottom));
  2689. Vec4 edges=step(Vec4(MLAA_THRESHOLD, MLAA_THRESHOLD, MLAA_THRESHOLD, MLAA_THRESHOLD), delta);
  2690. if(Dot(edges, 1)==0)discard;
  2691. return edges;
  2692. }
  2693. #if MODEL!=SM_GL
  2694. Flt MLAASearchXLeft (Vec2 texcoord) {Flt i, e=0; for(i=-1.5f; i>-2*MLAA_MAX_SEARCH_STEPS; i-=2){e=TexLod(Col, texcoord+ColSize.xy*Vec2(i, 0)).g; FLATTEN if(e<0.9f)break;} return Max(i+1.5f-2*e, -2*MLAA_MAX_SEARCH_STEPS);}
  2695. Flt MLAASearchXRight(Vec2 texcoord) {Flt i, e=0; for(i= 1.5f; i< 2*MLAA_MAX_SEARCH_STEPS; i+=2){e=TexLod(Col, texcoord+ColSize.xy*Vec2(i, 0)).g; FLATTEN if(e<0.9f)break;} return Min(i-1.5f+2*e, 2*MLAA_MAX_SEARCH_STEPS);}
  2696. Flt MLAASearchYUp (Vec2 texcoord) {Flt i, e=0; for(i=-1.5f; i>-2*MLAA_MAX_SEARCH_STEPS; i-=2){e=TexLod(Col, texcoord+ColSize.xy*Vec2(0, i)).r; FLATTEN if(e<0.9f)break;} return Max(i+1.5f-2*e, -2*MLAA_MAX_SEARCH_STEPS);}
  2697. Flt MLAASearchYDown (Vec2 texcoord) {Flt i, e=0; for(i= 1.5f; i< 2*MLAA_MAX_SEARCH_STEPS; i+=2){e=TexLod(Col, texcoord+ColSize.xy*Vec2(0, i)).r; FLATTEN if(e<0.9f)break;} return Min(i-1.5f+2*e, 2*MLAA_MAX_SEARCH_STEPS);}
  2698. #else // CG doesn't properly compile "break"
  2699. Flt MLAASearchXLeft (Vec2 texcoord) {Flt i, e=0; for(i=-1.5f; i>-2*MLAA_MAX_SEARCH_STEPS; i-=2){e=TexLod(Col, texcoord+ColSize.xy*Vec2(i, 0)).g; if(e<0.9f)return Max(i+1.5f-2*e, -2*MLAA_MAX_SEARCH_STEPS);} return Max(i+1.5f-2*e, -2*MLAA_MAX_SEARCH_STEPS);}
  2700. Flt MLAASearchXRight(Vec2 texcoord) {Flt i, e=0; for(i= 1.5f; i< 2*MLAA_MAX_SEARCH_STEPS; i+=2){e=TexLod(Col, texcoord+ColSize.xy*Vec2(i, 0)).g; if(e<0.9f)return Min(i-1.5f+2*e, 2*MLAA_MAX_SEARCH_STEPS);} return Min(i-1.5f+2*e, 2*MLAA_MAX_SEARCH_STEPS);}
  2701. Flt MLAASearchYUp (Vec2 texcoord) {Flt i, e=0; for(i=-1.5f; i>-2*MLAA_MAX_SEARCH_STEPS; i-=2){e=TexLod(Col, texcoord+ColSize.xy*Vec2(0, i)).r; if(e<0.9f)return Max(i+1.5f-2*e, -2*MLAA_MAX_SEARCH_STEPS);} return Max(i+1.5f-2*e, -2*MLAA_MAX_SEARCH_STEPS);}
  2702. Flt MLAASearchYDown (Vec2 texcoord) {Flt i, e=0; for(i= 1.5f; i< 2*MLAA_MAX_SEARCH_STEPS; i+=2){e=TexLod(Col, texcoord+ColSize.xy*Vec2(0, i)).r; if(e<0.9f)return Min(i-1.5f+2*e, 2*MLAA_MAX_SEARCH_STEPS);} return Min(i-1.5f+2*e, 2*MLAA_MAX_SEARCH_STEPS);}
  2703. #endif
  2704. Vec4 MLAABlend_PS(NOPERSP Vec2 texcoord:TEXCOORD):COLOR
  2705. {
  2706. Vec4 areas=0;
  2707. Vec2 e=TexPoint(Col, texcoord).rg;
  2708. BRANCH if(e.g) // Edge at north
  2709. {
  2710. Vec2 d =Vec2(MLAASearchXLeft(texcoord), MLAASearchXRight(texcoord)); // Search distances to the left and to the right
  2711. Vec4 coords=Vec4(d.x, -0.25f, d.y+1, -0.25f)*ColSize.xyxy+texcoord.xyxy; // Now fetch the crossing edges. Instead of sampling between edgels, we sample at -0.25, to be able to discern what value has each edge
  2712. Flt e1=TexLod(Col, coords.xy).r,
  2713. e2=TexLod(Col, coords.zw).r;
  2714. areas.rg=MLAAArea(Abs(d), e1, e2); // Ok, we know how this pattern looks like, now it is time for getting the actual area
  2715. }
  2716. BRANCH if(e.r) // Edge at west
  2717. {
  2718. Vec2 d =Vec2(MLAASearchYUp(texcoord), MLAASearchYDown(texcoord)); // Search distances to the top and to the bottom
  2719. Vec4 coords=Vec4(-0.25f, d.x, -0.25f, d.y+1)*ColSize.xyxy+texcoord.xyxy; // Now fetch the crossing edges (yet again)
  2720. Flt e1=TexLod(Col, coords.xy).g,
  2721. e2=TexLod(Col, coords.zw).g;
  2722. areas.ba=MLAAArea(Abs(d), e1, e2); // Get the area for this direction
  2723. }
  2724. return areas;
  2725. }
  2726. Vec4 MLAA_PS(NOPERSP Vec2 texcoord :TEXCOORD0,
  2727. NOPERSP Vec4 offset[2]:TEXCOORD1):COLOR
  2728. {
  2729. // Fetch the blending weights for current pixel:
  2730. Vec4 topLeft=TexPoint(Col1, texcoord);
  2731. Flt bottom =TexPoint(Col1, offset[1].zw).g,
  2732. right =TexPoint(Col1, offset[1].xy).a;
  2733. Vec4 a =Vec4(topLeft.r, bottom, topLeft.b, right),
  2734. w =a*a*a; // Up to 4 lines can be crossing a pixel (one in each edge). So, we perform a weighted average, where the weight of each line is 'a' cubed, which favors blending and works well in practice.
  2735. Flt sum=Dot(w, 1); // There is some blending weight with a value greater than 0?
  2736. if( sum<1e-5)discard;
  2737. // Add the contributions of the possible 4 lines that can cross this pixel:
  2738. #if 1 // use Bilinear Filtering to speedup calculations
  2739. Vec4 color=TexLod(Col, texcoord-Vec2(0, a.r*ColSize.y))*w.r
  2740. +TexLod(Col, texcoord+Vec2(0, a.g*ColSize.y))*w.g
  2741. +TexLod(Col, texcoord-Vec2(a.b*ColSize.x, 0))*w.b
  2742. +TexLod(Col, texcoord+Vec2(a.a*ColSize.x, 0))*w.a;
  2743. #else
  2744. Vec4 C =TexPoint(Col, texcoord ),
  2745. Cleft =TexPoint(Col, offset[0].xy),
  2746. Ctop =TexPoint(Col, offset[0].zw),
  2747. Cright =TexPoint(Col, offset[1].xy),
  2748. Cbottom=TexPoint(Col, offset[1].zw),
  2749. color =Lerp(C, Ctop , a.r)*w.r;
  2750. color +=Lerp(C, Cbottom, a.g)*w.g;
  2751. color +=Lerp(C, Cleft , a.b)*w.b;
  2752. color +=Lerp(C, Cright , a.a)*w.a;
  2753. #endif
  2754. return color/sum; // Normalize the resulting color
  2755. }
  2756. TECHNIQUE(MLAAEdge , MLAA_VS(), MLAAEdge_PS ());
  2757. TECHNIQUE(MLAABlend, MLAA_VS(), MLAABlend_PS());
  2758. TECHNIQUE(MLAA , MLAA_VS(), MLAA_PS ());
  2759. /******************************************************************************/
  2760. #define SMAA_FLATTEN FLATTEN
  2761. #define SMAA_BRANCH BRANCH
  2762. #if DX11
  2763. #define SMAA_HLSL_4 1 // TODO: using SMAA_HLSL_4_1 would be faster, but it's not easy to mix SMAA 4.0 and 4.1 together in one shader, however it's only used for predication and SMAADepthEdgeDetectionPS which are not used
  2764. #define PointSampler SamplerPoint
  2765. #define LinearSampler SamplerLinearClamp
  2766. #else
  2767. #define SMAA_HLSL_3 1
  2768. #endif
  2769. #if GL
  2770. #define mad(a, b, c) ((a)*(b) + (c))
  2771. #endif
  2772. BUFFER(SMAA)
  2773. Flt SMAAThreshold=0.05f;
  2774. BUFFER_END
  2775. #include "SMAA_config.h"
  2776. #include "SMAA.h"
  2777. void SMAAEdge_VS(VtxInput vtx,
  2778. out Vec2 texcoord :TEXCOORD0,
  2779. out Vec4 offset[3]:TEXCOORD1,
  2780. out Vec4 position :POSITION )
  2781. {
  2782. position=Vec4(vtx.pos2(), !REVERSE_DEPTH, 1); AdjustPixelCenter(position); // set Z to be at the end of the viewport, this enables optimizations by optional applying lighting only on solid pixels (no sky/background)
  2783. texcoord=vtx.tex();
  2784. SMAAEdgeDetectionVS(texcoord, offset);
  2785. }
  2786. void SMAABlend_VS(VtxInput vtx,
  2787. out Vec2 texcoord :TEXCOORD0,
  2788. out Vec2 pixcoord :TEXCOORD1,
  2789. out Vec4 offset[3]:TEXCOORD2,
  2790. out Vec4 position :POSITION )
  2791. {
  2792. position=Vec4(vtx.pos2(), !REVERSE_DEPTH, 1); AdjustPixelCenter(position); // set Z to be at the end of the viewport, this enables optimizations by optional applying lighting only on solid pixels (no sky/background)
  2793. texcoord=vtx.tex();
  2794. SMAABlendingWeightCalculationVS(texcoord, pixcoord, offset);
  2795. }
  2796. void SMAA_VS(VtxInput vtx,
  2797. out Vec2 texcoord:TEXCOORD0,
  2798. out Vec4 offset :TEXCOORD1,
  2799. out Vec4 position:POSITION )
  2800. {
  2801. position=Vec4(vtx.pos2(), !REVERSE_DEPTH, 1); AdjustPixelCenter(position); // set Z to be at the end of the viewport, this enables optimizations by optional applying lighting only on solid pixels (no sky/background)
  2802. texcoord=vtx.tex();
  2803. SMAANeighborhoodBlendingVS(texcoord, offset);
  2804. }
  2805. Vec4 SMAAEdgeLuma_PS(NOPERSP Vec2 texcoord :TEXCOORD0,
  2806. NOPERSP Vec4 offset[3]:TEXCOORD1):COLOR
  2807. {
  2808. return Vec4(SMAALumaEdgeDetectionPS(texcoord, offset, Col), 0, 1);
  2809. }
  2810. Vec4 SMAAEdgeColor_PS(NOPERSP Vec2 texcoord :TEXCOORD0,
  2811. NOPERSP Vec4 offset[3]:TEXCOORD1):COLOR
  2812. {
  2813. return Vec4(SMAAColorEdgeDetectionPS(texcoord, offset, Col), 0, 1);
  2814. }
  2815. Vec4 SMAABlend_PS(NOPERSP Vec2 texcoord :TEXCOORD0,
  2816. NOPERSP Vec2 pixcoord :TEXCOORD1,
  2817. NOPERSP Vec4 offset[3]:TEXCOORD2):COLOR
  2818. {
  2819. return SMAABlendingWeightCalculationPS(texcoord, pixcoord, offset, Col, Col1, Col2, 0);
  2820. }
  2821. Vec4 SMAA_PS(NOPERSP Vec2 texcoord:TEXCOORD0,
  2822. NOPERSP Vec4 offset :TEXCOORD1):COLOR
  2823. {
  2824. return SMAANeighborhoodBlendingPS(texcoord, offset, Col, Col1);
  2825. }
  2826. //TECHNIQUE(SMAAEdgeLuma , SMAAEdge_VS (), SMAAEdgeLuma_PS ());
  2827. TECHNIQUE(SMAAEdgeColor, SMAAEdge_VS (), SMAAEdgeColor_PS());
  2828. TECHNIQUE(SMAABlend , SMAABlend_VS(), SMAABlend_PS ());
  2829. TECHNIQUE(SMAA , SMAA_VS (), SMAA_PS ());
  2830. /******************************************************************************/
  2831. #if 0
  2832. @GROUP "Draw3DTex" // params: COLOR, alpha_test
  2833. @SHARED
  2834. #include "Glsl.h"
  2835. VAR HP Vec2 IO_tex;
  2836. #if COLOR!=0
  2837. VAR LP Vec4 IO_col;
  2838. #endif
  2839. @SHARED_END
  2840. @VS
  2841. #include "Glsl VS.h"
  2842. #include "Glsl VS 3D.h"
  2843. void main()
  2844. {
  2845. O_vtx=Project(TransformPos(vtx_pos()));
  2846. IO_tex=vtx_tex();
  2847. #if COLOR!=0
  2848. IO_col=vtx_color();
  2849. #endif
  2850. }
  2851. @VS_END
  2852. @PS
  2853. #include "Glsl PS.h"
  2854. void main()
  2855. {
  2856. LP Vec4 col=Tex(Col, IO_tex);
  2857. #if alpha_test!=0
  2858. if(col.a<0.5)discard;
  2859. #endif
  2860. #if COLOR!=0
  2861. col*=IO_col;
  2862. #endif
  2863. gl_FragColor=col;
  2864. }
  2865. @PS_END
  2866. @GROUP_END
  2867. @GROUP "Draw2DTex" // params: COLOR
  2868. @SHARED
  2869. #include "Glsl.h"
  2870. VAR HP Vec2 IO_tex;
  2871. @SHARED_END
  2872. @VS
  2873. #include "Glsl VS.h"
  2874. #include "Glsl VS 2D.h"
  2875. void main()
  2876. {
  2877. O_vtx=Vec4(vtx_pos2()*Coords.xy+Coords.zw, Flt(REVERSE_DEPTH), 1.0);
  2878. IO_tex=vtx_tex();
  2879. }
  2880. @VS_END
  2881. @PS
  2882. #include "Glsl PS.h"
  2883. #include "Glsl PS 2D.h"
  2884. void main()
  2885. {
  2886. #if COLOR!=0
  2887. gl_FragColor=Tex(Col, IO_tex)*Color[0]+Color[1];
  2888. #else
  2889. gl_FragColor=Tex(Col, IO_tex);
  2890. #endif
  2891. }
  2892. @PS_END
  2893. @GROUP_END
  2894. @GROUP "Font"
  2895. @SHARED
  2896. #include "Glsl.h"
  2897. VAR HP Vec2 IO_tex;
  2898. VAR MP Flt IO_shade;
  2899. @SHARED_END
  2900. @VS
  2901. #include "Glsl VS.h"
  2902. #include "Glsl VS 2D.h"
  2903. void main()
  2904. {
  2905. O_vtx =Vec4(vtx_pos2()*Coords.xy+Coords.zw, Flt(REVERSE_DEPTH), 1.0);
  2906. IO_tex =vtx_tex ();
  2907. IO_shade=vtx_size();
  2908. }
  2909. @VS_END
  2910. @PS
  2911. #include "Glsl PS.h"
  2912. #include "Glsl PS 2D.h"
  2913. PAR MP Flt FontShadow, FontShade;
  2914. void main()
  2915. {
  2916. LP Vec4 tex=Tex(Col, IO_tex);
  2917. MP Flt a =tex.g,
  2918. s =tex.a*FontShadow,
  2919. final_alpha=a+s-s*a;
  2920. LP Flt final_color=Lerp(FontShade, 1.0, Sat(IO_shade))*a/(final_alpha+EPS);
  2921. gl_FragColor.rgb=Color[0].rgb*final_color;
  2922. gl_FragColor.a =Color[0].a *final_alpha;
  2923. }
  2924. @PS_END
  2925. @GROUP_END
  2926. @GROUP "Blur" // params: axis, high
  2927. @SHARED
  2928. #include "Glsl.h"
  2929. #define WEIGHT4_0 0.250000000
  2930. #define WEIGHT4_1 0.213388354
  2931. #define WEIGHT4_2 0.124999993
  2932. #define WEIGHT4_3 0.036611654
  2933. // WEIGHT4_0 + WEIGHT4_1*2 + WEIGHT4_2*2 + WEIGHT4_3*2 = 1
  2934. #define WEIGHT6_0 0.166666668
  2935. #define WEIGHT6_1 0.155502122
  2936. #define WEIGHT6_2 0.125000001
  2937. #define WEIGHT6_3 0.083333329
  2938. #define WEIGHT6_4 0.041666662
  2939. #define WEIGHT6_5 0.011164551
  2940. // WEIGHT6_0 + WEIGHT6_1*2 + WEIGHT6_2*2 + WEIGHT6_3*2 + WEIGHT6_4*2 + WEIGHT6_5*2 = 1
  2941. VAR HP Vec2 IO_tex0, IO_tex1, IO_tex2, IO_tex3;
  2942. #if high!=0
  2943. VAR HP Vec2 IO_tex4, IO_tex5;
  2944. #endif
  2945. @SHARED_END
  2946. @VS
  2947. #include "Glsl VS.h"
  2948. #include "Glsl VS 2D.h"
  2949. void main()
  2950. {
  2951. O_vtx=vtx_pos4();
  2952. HP Vec2 tex=vtx_tex();
  2953. #if high==0
  2954. #if axis==0 // X
  2955. IO_tex0.y=tex.y; IO_tex0.x=tex.x+ColSize.x*( 0.0+WEIGHT4_1/(WEIGHT4_0/2.0+WEIGHT4_1));
  2956. IO_tex1.y=tex.y; IO_tex1.x=tex.x+ColSize.x*(-0.0-WEIGHT4_1/(WEIGHT4_0/2.0+WEIGHT4_1));
  2957. IO_tex2.y=tex.y; IO_tex2.x=tex.x+ColSize.x*( 2.0+WEIGHT4_3/(WEIGHT4_2 +WEIGHT4_3));
  2958. IO_tex3.y=tex.y; IO_tex3.x=tex.x+ColSize.x*(-2.0-WEIGHT4_3/(WEIGHT4_2 +WEIGHT4_3));
  2959. #else
  2960. IO_tex0.x=tex.x; IO_tex0.y=tex.y+ColSize.y*( 0.0+WEIGHT4_1/(WEIGHT4_0/2.0+WEIGHT4_1));
  2961. IO_tex1.x=tex.x; IO_tex1.y=tex.y+ColSize.y*(-0.0-WEIGHT4_1/(WEIGHT4_0/2.0+WEIGHT4_1));
  2962. IO_tex2.x=tex.x; IO_tex2.y=tex.y+ColSize.y*( 2.0+WEIGHT4_3/(WEIGHT4_2 +WEIGHT4_3));
  2963. IO_tex3.x=tex.x; IO_tex3.y=tex.y+ColSize.y*(-2.0-WEIGHT4_3/(WEIGHT4_2 +WEIGHT4_3));
  2964. #endif
  2965. #else
  2966. #if axis==0 // X
  2967. IO_tex0.y=tex.y; IO_tex0.x=tex.x+ColSize.x*( 0.0+WEIGHT6_1/(WEIGHT6_0/2.0+WEIGHT6_1));
  2968. IO_tex1.y=tex.y; IO_tex1.x=tex.x+ColSize.x*(-0.0-WEIGHT6_1/(WEIGHT6_0/2.0+WEIGHT6_1));
  2969. IO_tex2.y=tex.y; IO_tex2.x=tex.x+ColSize.x*( 2.0+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3));
  2970. IO_tex3.y=tex.y; IO_tex3.x=tex.x+ColSize.x*(-2.0-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3));
  2971. IO_tex4.y=tex.y; IO_tex4.x=tex.x+ColSize.x*( 4.0+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5));
  2972. IO_tex5.y=tex.y; IO_tex5.x=tex.x+ColSize.x*(-4.0-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5));
  2973. #else
  2974. IO_tex0.x=tex.x; IO_tex0.y=tex.y+ColSize.y*( 0.0+WEIGHT6_1/(WEIGHT6_0/2.0+WEIGHT6_1));
  2975. IO_tex1.x=tex.x; IO_tex1.y=tex.y+ColSize.y*(-0.0-WEIGHT6_1/(WEIGHT6_0/2.0+WEIGHT6_1));
  2976. IO_tex2.x=tex.x; IO_tex2.y=tex.y+ColSize.y*( 2.0+WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3));
  2977. IO_tex3.x=tex.x; IO_tex3.y=tex.y+ColSize.y*(-2.0-WEIGHT6_3/(WEIGHT6_2 +WEIGHT6_3));
  2978. IO_tex4.x=tex.x; IO_tex4.y=tex.y+ColSize.y*( 4.0+WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5));
  2979. IO_tex5.x=tex.x; IO_tex5.y=tex.y+ColSize.y*(-4.0-WEIGHT6_5/(WEIGHT6_4 +WEIGHT6_5));
  2980. #endif
  2981. #endif
  2982. }
  2983. @VS_END
  2984. @PS
  2985. #include "Glsl PS.h"
  2986. void main()
  2987. {
  2988. #if high==0
  2989. gl_FragColor.rgb=texture2DLod(Col, IO_tex0, 0.0).rgb*(WEIGHT4_0/2.0+WEIGHT4_1)
  2990. +texture2DLod(Col, IO_tex1, 0.0).rgb*(WEIGHT4_0/2.0+WEIGHT4_1)
  2991. +texture2DLod(Col, IO_tex2, 0.0).rgb*(WEIGHT4_2 +WEIGHT4_3)
  2992. +texture2DLod(Col, IO_tex3, 0.0).rgb*(WEIGHT4_2 +WEIGHT4_3);
  2993. #else
  2994. gl_FragColor.rgb=texture2DLod(Col, IO_tex0, 0.0).rgb*(WEIGHT6_0/2.0+WEIGHT6_1)
  2995. +texture2DLod(Col, IO_tex1, 0.0).rgb*(WEIGHT6_0/2.0+WEIGHT6_1)
  2996. +texture2DLod(Col, IO_tex2, 0.0).rgb*(WEIGHT6_2 +WEIGHT6_3)
  2997. +texture2DLod(Col, IO_tex3, 0.0).rgb*(WEIGHT6_2 +WEIGHT6_3)
  2998. +texture2DLod(Col, IO_tex4, 0.0).rgb*(WEIGHT6_4 +WEIGHT6_5)
  2999. +texture2DLod(Col, IO_tex5, 0.0).rgb*(WEIGHT6_4 +WEIGHT6_5);
  3000. #endif
  3001. gl_FragColor.a=0.0;
  3002. }
  3003. @PS_END
  3004. @GROUP_END
  3005. @GROUP "BloomDS" // params: DoGlow, DoClamp, half, saturate
  3006. @SHARED
  3007. #include "Glsl.h"
  3008. PAR MP Vec BloomParams;
  3009. #if DoGlow!=0
  3010. #define res ((half!=0) ? 2 : 4)
  3011. VAR HP Vec2 IO_tex;
  3012. #elif half!=0
  3013. VAR HP Vec2 IO_tex;
  3014. #else
  3015. VAR HP Vec2 IO_tex0, IO_tex1, IO_tex2, IO_tex3;
  3016. #endif
  3017. @SHARED_END
  3018. @VS
  3019. #include "Glsl VS.h"
  3020. #include "Glsl VS 2D.h"
  3021. void main()
  3022. {
  3023. O_vtx=vtx_pos4();
  3024. HP Vec2 tex=vtx_tex();
  3025. #if DoGlow!=0
  3026. IO_tex=tex-ColSize.xy*Vec2((half!=0) ? 0.5 : 1.5, (half!=0) ? 0.5 : 1.5);
  3027. #elif half!=0
  3028. IO_tex=tex;
  3029. #else
  3030. #if DoClamp!=0
  3031. IO_tex0=tex-ColSize.xy;
  3032. IO_tex1=tex+ColSize.xy;
  3033. #else
  3034. IO_tex0=tex+ColSize.xy*Vec2( 1.0, 1.0);
  3035. IO_tex1=tex+ColSize.xy*Vec2(-1.0, 1.0);
  3036. IO_tex2=tex+ColSize.xy*Vec2( 1.0, -1.0);
  3037. IO_tex3=tex+ColSize.xy*Vec2(-1.0, -1.0);
  3038. #endif
  3039. #endif
  3040. }
  3041. @VS_END
  3042. @PS
  3043. #include "Glsl PS.h"
  3044. #include "Glsl PS 2D.h"
  3045. #include "Glsl VS 2D.h"
  3046. MP Vec BloomColor(MP Vec color)
  3047. {
  3048. #if saturate!=0
  3049. return color*BloomParams.y+BloomParams.z;
  3050. #else
  3051. MP Flt col_lum=Max(Max(color.r, color.g), color.b), lum=col_lum*BloomParams.y+BloomParams.z;
  3052. return (lum>0.0) ? color*(lum/col_lum) : Vec(0.0, 0.0, 0.0);
  3053. #endif
  3054. }
  3055. void main()
  3056. {
  3057. #if DoGlow!=0
  3058. MP Vec color=Vec (0.0, 0.0, 0.0);
  3059. MP Vec4 glow =Vec4(0.0, 0.0, 0.0, 0.0);
  3060. for(Int y=0; y<res; y++)
  3061. for(Int x=0; x<res; x++)
  3062. {
  3063. MP Vec4 c=texture2DLod(Col, UVClamp(IO_tex+ColSize.xy*Vec2(x, y), DoClamp!=0), 0.0);
  3064. color +=c.rgb;
  3065. glow.rgb+=c.rgb*c.a;
  3066. glow.a =Max(glow.a, c.a);
  3067. }
  3068. MP Flt eps=EPS;
  3069. glow.rgb*=2.0*glow.a/Max(glow.rgb, eps); // NaN (increase by 2 because normally it's too small)
  3070. gl_FragColor.rgb=Max(BloomColor(color), glow.rgb);
  3071. #elif half!=0
  3072. gl_FragColor.rgb=BloomColor(texture2DLod(Col, UVClamp(IO_tex, DoClamp!=0), 0.0).rgb);
  3073. #else
  3074. #if DoClamp!=0
  3075. HP Vec2 tex_min=UVClamp(IO_tex0, true),
  3076. tex_max=UVClamp(IO_tex1, true);
  3077. MP Vec col=texture2DLod(Col, Vec2(tex_min.x, tex_min.y), 0.0).rgb // keep this outside of Sat(..) if used, because compilation will fail on Galaxy Tab 2 and some others
  3078. +texture2DLod(Col, Vec2(tex_max.x, tex_min.y), 0.0).rgb
  3079. +texture2DLod(Col, Vec2(tex_min.x, tex_max.y), 0.0).rgb
  3080. +texture2DLod(Col, Vec2(tex_max.x, tex_max.y), 0.0).rgb;
  3081. #else
  3082. MP Vec col=texture2DLod(Col, IO_tex0, 0.0).rgb
  3083. +texture2DLod(Col, IO_tex1, 0.0).rgb
  3084. +texture2DLod(Col, IO_tex2, 0.0).rgb
  3085. +texture2DLod(Col, IO_tex3, 0.0).rgb;
  3086. #endif
  3087. gl_FragColor.rgb=BloomColor(col);
  3088. #endif
  3089. gl_FragColor.a=0.0;
  3090. }
  3091. @PS_END
  3092. @GROUP_END
  3093. @GROUP "Bloom"
  3094. @SHARED
  3095. #include "Glsl.h"
  3096. VAR HP Vec2 IO_tex;
  3097. @SHARED_END
  3098. @VS
  3099. #include "Glsl VS.h"
  3100. void main()
  3101. {
  3102. O_vtx=vtx_pos4();
  3103. IO_tex=vtx_tex ();
  3104. }
  3105. @VS_END
  3106. @PS
  3107. #include "Glsl PS.h"
  3108. PAR LP Vec BloomParams;
  3109. void main()
  3110. {
  3111. gl_FragColor.rgb=texture2DLod(Col, IO_tex, 0.0).rgb*BloomParams.x + texture2DLod(Col1, IO_tex, 0.0).rgb;
  3112. gl_FragColor.a =1.0; // force full alpha so back buffer effects can work ok
  3113. }
  3114. @PS_END
  3115. @GROUP_END
  3116. @GROUP "ShdBlurX" // params: range
  3117. @SHARED
  3118. #include "Glsl.h"
  3119. VAR HP Vec2 IO_tex;
  3120. @SHARED_END
  3121. @VS
  3122. #include "Glsl VS.h"
  3123. void main()
  3124. {
  3125. O_vtx=Vec4(vtx_pos2(), Flt(!REVERSE_DEPTH), 1.0);
  3126. IO_tex=vtx_tex();
  3127. }
  3128. @VS_END
  3129. @PS
  3130. #include "Glsl PS.h"
  3131. #include "Glsl Matrix.h"
  3132. PAR HP Matrix4(ProjMatrix);
  3133. #include "Glsl Depth.h"
  3134. PAR HP Flt DepthWeightScale;
  3135. PAR HP Vec4 ColSize;
  3136. inline HP Vec2 DepthWeightMAD(HP Flt depth) {return Vec2(-1.0/(depth*DepthWeightScale+0.004), 2.0);}
  3137. inline MP Flt DepthWeight (MP Flt delta, HP Vec2 dw_mad) {return Sat(Abs(delta)*dw_mad.x + dw_mad.y);}
  3138. void main()
  3139. {
  3140. MP Flt weight=0.5,
  3141. color = texture2DLod(Col , IO_tex, 0.0).x*weight;
  3142. HP Flt z =LinearizeDepth(texture2DLod(Depth, IO_tex, 0.0).x, true);
  3143. HP Vec2 dw_mad=DepthWeightMAD(z), t; t.y=IO_tex.y;
  3144. for(MP Int i=-range; i<=range; i++)if(i!=0)
  3145. {
  3146. t.x=ColSize.x*(Flt(2*i)+((i>0) ? -0.5 : 0.5))+IO_tex.x;
  3147. MP Flt w=DepthWeight(z-LinearizeDepth(texture2DLod(Depth, t, 0.0).x, true), dw_mad);
  3148. color +=w*texture2DLod(Col, t, 0.0).x;
  3149. weight+=w;
  3150. }
  3151. gl_FragColor=Vec4(color/weight, 0.0, 0.0, 0.0);
  3152. }
  3153. @PS_END
  3154. @GROUP_END
  3155. @GROUP "ShdBlurY" // params: range
  3156. @SHARED
  3157. #include "Glsl.h"
  3158. VAR HP Vec2 IO_tex;
  3159. @SHARED_END
  3160. @VS
  3161. #include "Glsl VS.h"
  3162. void main()
  3163. {
  3164. O_vtx=Vec4(vtx_pos2(), Flt(!REVERSE_DEPTH), 1.0);
  3165. IO_tex=vtx_tex();
  3166. }
  3167. @VS_END
  3168. @PS
  3169. #include "Glsl PS.h"
  3170. #include "Glsl Matrix.h"
  3171. PAR HP Matrix4(ProjMatrix);
  3172. #include "Glsl Depth.h"
  3173. PAR HP Flt DepthWeightScale;
  3174. PAR HP Vec4 ColSize;
  3175. inline HP Vec2 DepthWeightMAD(HP Flt depth) {return Vec2(-1.0/(depth*DepthWeightScale+0.004), 2.0);}
  3176. inline MP Flt DepthWeight (MP Flt delta, HP Vec2 dw_mad) {return Sat(Abs(delta)*dw_mad.x + dw_mad.y);}
  3177. void main()
  3178. {
  3179. MP Flt weight=0.5,
  3180. color = texture2DLod(Col , IO_tex, 0.0).x*weight;
  3181. HP Flt z =LinearizeDepth(texture2DLod(Depth, IO_tex, 0.0).x, true);
  3182. HP Vec2 dw_mad=DepthWeightMAD(z), t; t.x=IO_tex.x;
  3183. for(MP Int i=-range; i<=range; i++)if(i!=0)
  3184. {
  3185. t.y=ColSize.y*(Flt(2*i)+((i>0) ? -0.5 : 0.5))+IO_tex.y;
  3186. MP Flt w=DepthWeight(z-LinearizeDepth(texture2DLod(Depth, t, 0.0).x, true), dw_mad);
  3187. color +=w*texture2DLod(Col, t, 0.0).x;
  3188. weight+=w;
  3189. }
  3190. gl_FragColor=Vec4(color/weight, 0.0, 0.0, 0.0);
  3191. }
  3192. @PS_END
  3193. @GROUP_END
  3194. @GROUP "Particle" // params: palette, anim, motion_stretch, stretch_alpha
  3195. @SHARED
  3196. #include "Glsl.h"
  3197. #define ANIM_NONE 0
  3198. #define ANIM_YES 1
  3199. #define ANIM_SMOOTH 2
  3200. VAR LP Vec4 IO_col;
  3201. VAR HP Vec2 IO_tex;
  3202. #if anim==ANIM_SMOOTH
  3203. VAR HP Vec2 IO_tex1;
  3204. VAR LP Flt IO_tex_blend;
  3205. #endif
  3206. @SHARED_END
  3207. @VS
  3208. #include "Glsl VS.h"
  3209. #include "Glsl VS 2D.h"
  3210. #include "Glsl VS 3D.h"
  3211. PAR MP Vec2 ParticleFrames;
  3212. void main()
  3213. {
  3214. IO_tex=vtx_tex ();
  3215. IO_col=vtx_color();
  3216. MP Flt size =vtx_size(),
  3217. angle =vtx_tanW();
  3218. HP Vec pos =TransformPos(vtx_pos());
  3219. MP Vec2 offset=IO_tex; offset=offset*Vec2(2.0, -2.0)+Vec2(-1.0, 1.0); offset=Rotate(offset, Vec2(Cos(angle), Sin(angle)));
  3220. #if motion_stretch!=0
  3221. if(pos.z>0.0)
  3222. {
  3223. #define PARTICLE_PROJECT 100.0
  3224. MP Vec vel =TransformDir(vtx_tan()); if(vel.z<0.0)vel=-vel;
  3225. HP Vec pos1=pos+vel/PARTICLE_PROJECT;
  3226. MP Vec2 vel2=(pos1.xy/pos1.z - pos.xy/pos.z)*PARTICLE_PROJECT;
  3227. MP Flt len =Length(vel2)+EPS;
  3228. {
  3229. MP Vec2 x=vel2*(vel2.x/len),
  3230. y=vel2*(vel2.y/len);
  3231. offset=Vec2(offset.x*(x.x+1.0) + offset.y*y.x, offset.x*x.y + offset.y*(y.y+1.0));
  3232. if(stretch_alpha!=0)
  3233. {
  3234. if(palette!=0)IO_col /=1.0+len; // in RM_PALETTE each component
  3235. else IO_col.a/=1.0+len; // in RM_BLEND only alpha
  3236. }
  3237. }
  3238. }
  3239. #endif
  3240. pos.xy+=offset*size;
  3241. // sky
  3242. MP Vec mp_pos =pos;
  3243. MP Flt d =Length(mp_pos);
  3244. LP Flt opacity=Sat(d*SkyFracMulAdd.x + SkyFracMulAdd.y);
  3245. if(palette!=0)IO_col *=opacity; // in RM_PALETTE each component
  3246. else IO_col.a*=opacity; // in RM_BLEND only alpha
  3247. #if anim!=ANIM_NONE
  3248. {
  3249. MP Flt frames=ParticleFrames.x*ParticleFrames.y,
  3250. frame =Frac(vtx_tex1().x/frames)*frames; // frame=[0..frames)
  3251. HP Flt f =Floor(frame); // keep this as HP because flickering can occur if MP is used (for example when ParticleFrames is 5x5)
  3252. #if anim==ANIM_SMOOTH // frame blending
  3253. {
  3254. MP Flt f1=f+1.0; if(f1+0.5>=frames)f1=0.0; // f1=(f+1)%frames;
  3255. IO_tex1 =IO_tex;
  3256. IO_tex_blend=frame-f; // [0..1) frac
  3257. f1/=ParticleFrames.x;
  3258. MP Flt y=Floor(f1);
  3259. IO_tex1.y+=y;
  3260. IO_tex1 /=ParticleFrames;
  3261. IO_tex1.x+=f1-y;
  3262. IO_tex1 *=ColSize.xy; // Image.partial
  3263. }
  3264. #endif
  3265. f/=ParticleFrames.x;
  3266. MP Flt y=Floor(f);
  3267. IO_tex.y+=y;
  3268. IO_tex /=ParticleFrames;
  3269. IO_tex.x+=f-y;
  3270. }
  3271. #endif
  3272. IO_tex*=ColSize.xy; // Image.partial
  3273. O_vtx=Project(pos);
  3274. }
  3275. @VS_END
  3276. @PS
  3277. #include "Glsl PS.h"
  3278. void main()
  3279. {
  3280. LP Vec4 tex= Tex(Col, IO_tex );
  3281. #if anim==ANIM_SMOOTH
  3282. tex=Lerp(tex, Tex(Col, IO_tex1), IO_tex_blend);
  3283. #endif
  3284. if(palette!=0)gl_FragColor=IO_col*tex.a;
  3285. else gl_FragColor=IO_col*tex ;
  3286. }
  3287. @PS_END
  3288. @GROUP_END
  3289. @GROUP "Sky" // params: per_vertex, DENSITY, textures, stars, clouds
  3290. @SHARED
  3291. #include "Glsl.h"
  3292. PAR HP Flt SkyDnsExp ; // need high precision
  3293. PAR MP Flt SkyHorExp ,
  3294. SkyBoxBlend ;
  3295. PAR LP Vec4 SkyHorCol ,
  3296. SkySkyCol ;
  3297. PAR MP Vec2 SkyDnsMulAdd ,
  3298. SkySunHighlight;
  3299. PAR MP Vec SkySunPos ;
  3300. #define LCScale 0.2
  3301. struct CloudLayer
  3302. {
  3303. LP Vec4 color;
  3304. MP Vec2 scale;
  3305. HP Vec2 position;
  3306. };
  3307. PAR MP Flt LCScaleY;
  3308. PAR MP Vec2 LCMaskContrast;
  3309. PAR CloudLayer CL[1];
  3310. inline LP Vec4 SkyColor(MP Flt y)
  3311. {
  3312. LP Flt hor=Pow(1.0-Sat(y), SkyHorExp);
  3313. return Lerp(SkySkyCol, SkyHorCol, hor);
  3314. }
  3315. VAR MP Vec IO_tex;
  3316. #if stars!=0
  3317. VAR MP Vec IO_tex_star;
  3318. #endif
  3319. #if per_vertex!=0
  3320. VAR LP Vec4 IO_col;
  3321. #endif
  3322. #if clouds!=0
  3323. VAR HP Vec IO_tex_cloud;
  3324. VAR LP Vec4 IO_col_cloud;
  3325. #endif
  3326. @SHARED_END
  3327. @VS
  3328. #include "Glsl VS.h"
  3329. #include "Glsl VS 3D.h"
  3330. PAR MP Matrix3(SkyStarOrn);
  3331. void main()
  3332. {
  3333. O_vtx=Project(TransformPos(vtx_pos()));
  3334. IO_tex=vtx_pos();
  3335. #if stars!=0
  3336. IO_tex_star=Transform(vtx_pos(), SkyStarOrn);
  3337. #endif
  3338. #if per_vertex!=0
  3339. IO_col=SkyColor(vtx_pos().y);
  3340. #endif
  3341. #if clouds!=0
  3342. {
  3343. MP Vec pos=vtx_pos(); pos*=Vec(LCScale, 1.0, LCScale);
  3344. IO_col_cloud=CL[0].color; IO_col_cloud.a*=Sat(pos.y*8.0-0.15); // CloudAlpha
  3345. IO_tex_cloud=pos;
  3346. }
  3347. #endif
  3348. }
  3349. @VS_END
  3350. @PS
  3351. #include "Glsl PS.h"
  3352. PAR ImageCube Cub;
  3353. inline LP Vec SkyTex()
  3354. {
  3355. if(textures==2)return Vec(Lerp(TexCube(Rfl, IO_tex).rgb, TexCube(Cub, IO_tex).rgb, SkyBoxBlend));else
  3356. if(textures==1)return Vec( TexCube(Rfl, IO_tex).rgb );else
  3357. {
  3358. LP Vec4 col;
  3359. #if per_vertex==0
  3360. {
  3361. MP Vec tex=Normalize(IO_tex);
  3362. col=SkyColor (tex.y );
  3363. MP Flt cos =Dot(SkySunPos, tex);
  3364. LP Flt highlight=1.0+Sqr(cos)*((cos>0.0) ? SkySunHighlight.x : SkySunHighlight.y); // rayleigh
  3365. col.rgb*=highlight;
  3366. }
  3367. #else
  3368. col=IO_col;
  3369. #endif
  3370. #if stars!=0
  3371. col.rgb=Lerp(TexCube(Rfl, IO_tex_star).rgb, col.rgb, col.a);
  3372. #endif
  3373. return col.rgb;
  3374. }
  3375. }
  3376. void main()
  3377. {
  3378. LP Vec col=SkyTex();
  3379. #if clouds!=0
  3380. {
  3381. HP Vec2 uv=Normalize(IO_tex_cloud).xz;
  3382. LP Vec4 tex=Tex(Col, uv*CL[0].scale+CL[0].position)*IO_col_cloud;
  3383. col.rgb=Lerp(col.rgb, tex.rgb, tex.a);
  3384. }
  3385. #endif
  3386. gl_FragColor.rgb=col;
  3387. gl_FragColor.a =0.0;
  3388. }
  3389. @PS_END
  3390. @GROUP_END
  3391. @GROUP "FXAA"
  3392. @SHARED
  3393. #include "Glsl.h"
  3394. VAR HP Vec2 IO_tex;
  3395. @SHARED_END
  3396. @VS
  3397. #include "Glsl VS.h"
  3398. void main()
  3399. {
  3400. O_vtx=vtx_pos4();
  3401. IO_tex=vtx_tex ();
  3402. }
  3403. @VS_END
  3404. @PS
  3405. #define FXAA_GLSL_130 1
  3406. #include "Glsl VS 2D.h"
  3407. #include "Glsl PS.h"
  3408. #include "FXAA_config.h"
  3409. #include "FXAA.h"
  3410. void main()
  3411. {
  3412. gl_FragColor=FxaaPixelShader(IO_tex, 0.0, Col, Col, Col, ColSize.xy, 0.0, 0.0, 0.0, 0.475, 0.15, 0.0833, 8.0, 0.125, 0.05, Vec4(1.0, -1.0, 0.25, -0.25));
  3413. }
  3414. @PS_END
  3415. @GROUP_END
  3416. @GROUP "SMAAEdge"
  3417. @SHARED
  3418. #define SMAA_GLSL_3 1
  3419. #include "Glsl.h"
  3420. #include "Glsl VS 2D.h"
  3421. PAR MP Flt SMAAThreshold;
  3422. #include "SMAA_config.h"
  3423. VAR HP Vec2 texcoord;
  3424. VAR HP Vec4 offset[3];
  3425. @SHARED_END
  3426. @VS
  3427. #define SMAA_INCLUDE_PS 0
  3428. #include "Glsl VS.h"
  3429. #include "SMAA.h"
  3430. void main()
  3431. {
  3432. O_vtx=vtx_pos4();
  3433. texcoord=vtx_tex();
  3434. SMAAEdgeDetectionVS(texcoord, offset);
  3435. }
  3436. @VS_END
  3437. @PS
  3438. #define SMAA_INCLUDE_VS 0
  3439. #include "Glsl PS.h"
  3440. #include "SMAA.h"
  3441. void main()
  3442. {
  3443. gl_FragColor.rg=SMAAColorEdgeDetectionPS(texcoord, offset, Col);
  3444. gl_FragColor.b=0;
  3445. gl_FragColor.a=1;
  3446. }
  3447. @PS_END
  3448. @GROUP_END
  3449. @GROUP "SMAABlend"
  3450. @SHARED
  3451. #define SMAA_GLSL_3 1
  3452. #include "Glsl.h"
  3453. #include "Glsl VS 2D.h"
  3454. #include "SMAA_config.h"
  3455. VAR HP Vec2 texcoord, pixcoord;
  3456. VAR HP Vec4 offset[3];
  3457. @SHARED_END
  3458. @VS
  3459. #define SMAA_INCLUDE_PS 0
  3460. #include "Glsl VS.h"
  3461. #include "SMAA.h"
  3462. void main()
  3463. {
  3464. O_vtx=vtx_pos4();
  3465. texcoord=vtx_tex();
  3466. SMAABlendingWeightCalculationVS(texcoord, pixcoord, offset);
  3467. }
  3468. @VS_END
  3469. @PS
  3470. #define SMAA_INCLUDE_VS 0
  3471. #include "Glsl PS.h"
  3472. #include "SMAA.h"
  3473. void main()
  3474. {
  3475. gl_FragColor=SMAABlendingWeightCalculationPS(texcoord, pixcoord, offset, Col, Col1, Col2, 0);
  3476. }
  3477. @PS_END
  3478. @GROUP_END
  3479. @GROUP "SMAA"
  3480. @SHARED
  3481. #define SMAA_GLSL_3 1
  3482. #include "Glsl.h"
  3483. #include "Glsl VS 2D.h"
  3484. #include "SMAA_config.h"
  3485. VAR HP Vec2 texcoord;
  3486. VAR HP Vec4 offset;
  3487. @SHARED_END
  3488. @VS
  3489. #define SMAA_INCLUDE_PS 0
  3490. #include "Glsl VS.h"
  3491. #include "SMAA.h"
  3492. void main()
  3493. {
  3494. O_vtx=vtx_pos4();
  3495. texcoord=vtx_tex();
  3496. SMAANeighborhoodBlendingVS(texcoord, offset);
  3497. }
  3498. @VS_END
  3499. @PS
  3500. #define SMAA_INCLUDE_VS 0
  3501. #include "Glsl PS.h"
  3502. #include "SMAA.h"
  3503. void main()
  3504. {
  3505. gl_FragColor=SMAANeighborhoodBlendingPS(texcoord, offset, Col, Col1);
  3506. }
  3507. @PS_END
  3508. @GROUP_END
  3509. #endif