!Header.h 86 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
  1. /******************************************************************************
  2. * Copyright (c) Grzegorz Slazinski. All Rights Reserved. *
  3. * Esenthel Engine (http://www.esenthel.com) shader file. *
  4. /******************************************************************************
  5. Optimization guidelines:
  6. -use MAD wherever possible A*B+C
  7. -Sign(x)*y can be replaced with (x>=0) ? y : -y (if Sign(x)==0 is not important)
  8. -use Sat(x) instead of Max(0, x) or Min(1, x) where 'x' is expected to be in 0..1 range
  9. -use Half, VecH2, VecH, VecH4 precision where possible
  10. -use NOPERSP for flat 2D shaders
  11. -offload some calculations on the CPU or Vertex Shader
  12. -use 'TexPoint' or 'TexLod' wherever possible
  13. /******************************************************************************/
  14. // MODEL AND TECHNIQUES
  15. /******************************************************************************/
  16. // Here are listed enums for different Shader Models:
  17. #define SM_GL 0 // (OpenGL )
  18. #define SM_3 1 // Model 3.0 (DirectX 9 )
  19. #define SM_4 2 // Model 4.0+ (DirectX 10+) D3D_FEATURE_LEVEL_10_0+
  20. #ifndef MODEL // MODEL is a macro automatically defined by the engine, set to one of the SM_ values above
  21. #define MODEL SM_4 // this line only makes Visual Studio properly highlight SM_4 parts of the codes when editing a shader file in Visual Studio
  22. #endif
  23. #if MODEL==SM_3
  24. #define API(dx9, dx10, gl) dx9
  25. #elif MODEL>=SM_4
  26. #define API(dx9, dx10, gl) dx10
  27. #elif MODEL==SM_GL
  28. #define API(dx9, dx10, gl) gl
  29. #endif
  30. #define GL (MODEL==SM_GL)
  31. #define DX9 (MODEL==SM_3)
  32. #define DX11 (MODEL>=SM_4)
  33. #if MODEL==SM_GL
  34. #define TECHNIQUE(name, vs, ps) technique name{pass p0{VertexShader=compile glslv vs; PixelShader=compile glslf ps;}}
  35. #elif MODEL==SM_3
  36. #define TECHNIQUE(name, vs, ps) technique name{pass p0{VertexShader=compile vs_3_0 vs; PixelShader=compile ps_3_0 ps;}}
  37. #elif MODEL==SM_4
  38. #define TECHNIQUE(name, vs, ps) technique10 name{pass p0{SetVertexShader(CompileShader(vs_4_0, vs)); SetPixelShader(CompileShader(ps_4_0, ps));}}
  39. #endif
  40. #if MODEL>=SM_4
  41. #define TECHNIQUE_4_1(name, vs, ps) technique10 name{pass p0{SetVertexShader(CompileShader(vs_4_1, vs)); SetPixelShader(CompileShader(ps_4_1, ps));}}
  42. #else
  43. #define TECHNIQUE_4_1(name, vs, ps)
  44. #endif
  45. #if MODEL==SM_GL
  46. #define TECHNIQUE_TESSELATION(name, vs, ps, hs, ds) TECHNIQUE(name, vs, ps) // tesselation not supported in OpenGL
  47. #elif MODEL==SM_3
  48. #define TECHNIQUE_TESSELATION(name, vs, ps, hs, ds) TECHNIQUE(name, vs, ps) // tesselation not supported in SM_3
  49. #elif MODEL>=SM_4
  50. #define TECHNIQUE_TESSELATION(name, vs, ps, hs, ds) technique11 name{pass p0{SetVertexShader(CompileShader(vs_4_0, vs)); SetPixelShader(CompileShader(ps_4_0, ps)); SetHullShader(CompileShader(hs_5_0, hs)); SetDomainShader(CompileShader(ds_5_0, ds));}}
  51. #endif
  52. /******************************************************************************/
  53. // MODIFIERS
  54. /******************************************************************************/
  55. #if MODEL>=SM_3 // SM_3 and SM_4
  56. #define FLOW 1
  57. #define FLATTEN [flatten] // will make a conditional statement flattened, use before 'if' statement
  58. #define BRANCH [branch ] // will make a conditional statement branched , use before 'if' statement
  59. #define LOOP [loop ] // will make a loop looped , use before 'for while' statements
  60. #define UNROLL [unroll ] // will make a loop unrolled , use before 'for while' statements
  61. #define NOPERSP noperspective // will disable perspective interpolation
  62. #else // SM_GL
  63. #define FLOW GL // there is flow control on GL however without the keywords
  64. #define FLATTEN // not available in SM_GL
  65. #define BRANCH // not available in SM_GL
  66. #define LOOP // not available in SM_GL
  67. #define UNROLL // not available in SM_GL
  68. #define NOPERSP // not available in SM_GL
  69. #endif
  70. /******************************************************************************/
  71. // DATA TYPES
  72. /******************************************************************************/
  73. #pragma pack_matrix(column_major) // always use "Column Major" matrix packing, TODO: should we use 'row_major ' "Row Major" and replace float4x3 with float3x4 and adjust operations on 'GpuMatrix'? first check if that can fit in DX9 Deferred shader, however it's possible Matrix can no longer be able to access vectors using [i], and "Transform(Vec v, Matrix m)" would need to be adjusted among others, possibly "v*m or mul(v,m)" replaced with "m*v or mul(m,v)"
  74. #define Bool bool
  75. #define Int int
  76. #define UInt uint
  77. #define Flt float
  78. #define VecI2 int2
  79. #define VecI int3
  80. #define VecI4 int4
  81. #define VecU2 uint2
  82. #define VecU uint3
  83. #define VecU4 uint4
  84. #define Vec2 float2
  85. #define Vec float3
  86. #define Vec4 float4
  87. #define Matrix3 float3x3
  88. #define Matrix float4x3
  89. #define Matrix4 float4x4
  90. #if MODEL==SM_GL || 1
  91. #define Half half
  92. #define VecH2 half2
  93. #define VecH half3
  94. #define VecH4 half4
  95. #define MatrixH3 half3x3
  96. #define MatrixH half4x3
  97. #define MatrixH4 half4x4
  98. #elif 1
  99. #define Half min16float
  100. #define VecH2 min16float2
  101. #define VecH min16float3
  102. #define VecH4 min16float4
  103. #define MatrixH3 min16float3x3
  104. #define MatrixH min16float4x3
  105. #define MatrixH4 min16float4x4
  106. #else
  107. #define Half float
  108. #define VecH2 float2
  109. #define VecH float3
  110. #define VecH4 float4
  111. #define MatrixH3 float3x3
  112. #define MatrixH float4x3
  113. #define MatrixH4 float4x4
  114. #endif
  115. #if DX11
  116. #define Image Texture2D
  117. #define Image3D Texture3D
  118. #define ImageCube TextureCube
  119. #define ImageShadow Texture2D
  120. #define SAMPLER(name, index) sampler name : register(s##index) // sampler
  121. #define SHADOW_SAMPLER(name, index) SamplerComparisonState name : register(s##index) // shadow sampler
  122. #elif DX9
  123. #define Image sampler2D
  124. #define Image3D sampler3D
  125. #define ImageCube samplerCUBE
  126. #define ImageShadow sampler2D
  127. #elif GL
  128. #define Image sampler2D
  129. #define Image3D sampler3D
  130. #define ImageCube samplerCUBE
  131. #define ImageShadow sampler2DShadow
  132. #endif
  133. /******************************************************************************/
  134. // MODEL DEPENDENT FUNCTIONALITY
  135. /******************************************************************************/
  136. #if MODEL==SM_GL
  137. #define PIXEL Vec4 pixel:WPOS // pixel coordinates, integer based in format Vec4(x, y, 0, 0) ranges from (0, 0) to (D.resW, D.resH)
  138. #define IF_IS_FRONT Bool front:VFACE, // face front side
  139. #define IF_IS_CLIP out Flt O_clip:BCOL1, // clip plane distance, this will generate "gl_BackSecondaryColor" which is later replaced with "gl_ClipDistance[0]"
  140. #define CLIP(pos) O_clip=Dot(Vec4((pos).xyz, 1), ClipPlane) // perform user plane clipping
  141. #define PIXEL_TO_SCREEN PixelToScreen(pixel) // PixelToScreen is faster and more accurate than PosToScreen
  142. #define BUFFER(name) // constant buffers (not available in OpenGL)
  143. #define BUFFER_I(name, index) // constant buffers (not available in OpenGL)
  144. #define BUFFER_END // constant buffers (not available in OpenGL)
  145. #elif MODEL==SM_3
  146. #define PIXEL Vec4 pixel:VPOS // pixel coordinates, integer based in format Vec4(x, y, 0, 0) ranges from (0, 0) to (D.resW, D.resH)
  147. #define IF_IS_FRONT Flt front:VFACE, // face front side , its sign (<0 or >0) specifies primitives back or front facing
  148. #define IF_IS_CLIP // clip plane distance (not needed in SM 3.0)
  149. #define CLIP(pos) // perform user plane clipping (not needed in SM 3.0)
  150. #define PIXEL_TO_SCREEN PixelToScreen(pixel) // PixelToScreen is faster and more accurate than PosToScreen
  151. #define BUFFER(name) // constant buffers (not available in SM 3.0)
  152. #define BUFFER_I(name, index) // constant buffers (not available in SM 3.0)
  153. #define BUFFER_END // constant buffers (not available in SM 3.0)
  154. #elif MODEL==SM_4
  155. #define PIXEL Vec4 pixel :SV_Position // pixel coordinates, integer based in format Vec4(x, y, 0, 0) ranges from (0, 0) to (D.resW, D.resH)
  156. #define IF_IS_FRONT Bool front :SV_IsFrontFace , // face front side
  157. #define IF_IS_CLIP out Flt O_clip:SV_ClipDistance, // clip plane distance
  158. #define CLIP(pos) O_clip=Dot(Vec4((pos).xyz, 1), ClipPlane) // perform user plane clipping
  159. #define PIXEL_TO_SCREEN PixelToScreen(pixel) // PixelToScreen is faster and more accurate than PosToScreen
  160. #define BUFFER(name) cbuffer name { // declare a constant buffer
  161. #define BUFFER_I(name, index) cbuffer name : register(b##index) { // declare a constant buffer with custom buffer index
  162. #define BUFFER_END } // end constant buffer declaration
  163. #endif
  164. /******************************************************************************/
  165. // FUNCTIONS
  166. /******************************************************************************/
  167. #define Dot dot
  168. #define Cross cross
  169. #define Sign sign
  170. #define Abs abs
  171. #define Sat saturate
  172. #define Mid clamp
  173. #define Frac frac
  174. #define Round round
  175. #define Trunc trunc
  176. #define Floor floor
  177. #define Ceil ceil
  178. #define Sqrt sqrt
  179. #define Normalize normalize
  180. #define Pow pow
  181. #define Sin sin
  182. #define Cos cos
  183. #define Acos acos
  184. #define Asin asin
  185. #define Lerp lerp
  186. /******************************************************************************/
  187. // CONSTANTS
  188. /******************************************************************************/
  189. #if MODEL>=SM_4
  190. #define MAX_MATRIX 256 // maximum number of matrixes
  191. #else
  192. #define MAX_MATRIX 60 // maximum number of matrixes
  193. #endif
  194. #define EPS 0.0001f // float epsilon
  195. #define EPS_COL (1.0f/256) // color epsilon
  196. #define PI_6 0.5235987755982988f // PI/6 ( 30 deg) Flt
  197. #define PI_4 0.7853981633974483f // PI/4 ( 45 deg) Flt
  198. #define PI_3 1.0471975511965977f // PI/3 ( 60 deg) Flt
  199. #define PI_2 1.5707963267948966f // PI/2 ( 90 deg) Flt
  200. #define PI 3.1415926535897932f // PI (180 deg) Flt
  201. #define PI2 6.2831853071795864f // PI*2 (360 deg) Flt
  202. #define SQRT2 1.4142135623730950f // Sqrt(2)
  203. #define SQRT3 1.7320508075688773f // Sqrt(3)
  204. #define SQRT2_2 0.7071067811865475f // Sqrt(2)/2
  205. #define SQRT3_3 0.5773502691896257f // Sqrt(3)/3
  206. #define TAN 0.5f // tangent calculation constant
  207. #define ColorLumWeight VecH(0.2126f, 0.7152f, 0.0722f)
  208. #define ColorLumWeight2 VecH(0.2990f, 0.5870f, 0.1140f)
  209. /******************************************************************************/
  210. // RENDER TARGETS
  211. /******************************************************************************/
  212. #define MS_SAMPLES 4 // number of samples in multi-sampled render targets
  213. #define SIGNED_NRM_RT (MODEL>=SM_4) // Normal Render Target is signed only on SM_4+, GL depends on GL_EXT_render_snorm
  214. #define SIGNED_VEL_RT (MODEL>=SM_4) // Velocity Render Target is signed only on SM_4+, GL depends on GL_EXT_render_snorm
  215. #define FULL_PRECISION_SPEC 0 // if use full precision for specular intensity in SIGNED_NRM_RT, we can disable this because we lose only 1-bit of precision
  216. #define REVERSE_DEPTH (!GL) // if Depth Buffer is reversed, GL uses different depth range -1..1
  217. #if REVERSE_DEPTH
  218. #define DEPTH_MIN Max
  219. #define DEPTH_MAX Min
  220. #define DEPTH_FOREGROUND(x) ((x)> 0.0f)
  221. #define DEPTH_BACKGROUND(x) ((x)<=0.0f)
  222. #define DEPTH_SMALLER(x, y) ((x)>(y))
  223. #else
  224. #define DEPTH_MIN Min
  225. #define DEPTH_MAX Max
  226. #define DEPTH_FOREGROUND(x) ((x)< 1.0f)
  227. #define DEPTH_BACKGROUND(x) ((x)>=1.0f)
  228. #define DEPTH_SMALLER(x, y) ((x)<(y))
  229. #endif
  230. /******************************************************************************/
  231. // TEXTURE ACCESSING
  232. /******************************************************************************/
  233. #if MODEL>=SM_4
  234. #define Tex( image, uv ) image.Sample(SamplerDefault, uv ) // access a 2D texture
  235. #define Tex3D( image, uvw) image.Sample(SamplerDefault, uvw) // access a 3D texture
  236. #define TexCube(image, uvw) image.Sample(SamplerDefault, uvw) // access a Cube texture
  237. #define TexLod( image, uv ) image.SampleLevel(SamplerDefault, uv , 0) // access 2D texture's 0-th MipMap (LOD level=0)
  238. #define TexLodI( image, uv , i) image.SampleLevel(SamplerDefault, uv , i) // access 2D texture's i-th MipMap (LOD level=i)
  239. #define Tex3DLod( image, uvw ) image.SampleLevel(SamplerDefault, uvw, 0) // access 3D texture's 0-th MipMap (LOD level=0)
  240. #define TexCubeLod(image, uvw ) image.SampleLevel(SamplerDefault, uvw, 0) // access Cube texture's 0-th MipMap (LOD level=0)
  241. #define TexPoint(image, uv) image.SampleLevel(SamplerPoint, uv, 0)
  242. #define TexSample(image, pixel, i) image.Load(pixel, i) // access i-th sample of a multi-sampled texture
  243. #define TexShadow(image, uvw) image.SampleCmpLevelZero(SamplerShadowMap, uvw.xy, uvw.z)
  244. #define TexClamp( image, uv ) image.Sample (SamplerLinearClamp, uv )
  245. #define TexLodClamp( image, uv ) image.SampleLevel(SamplerLinearClamp, uv , 0)
  246. #define Tex3DLodWrap(image, uvw) image.SampleLevel(SamplerLinearWrap , uvw, 0)
  247. #elif MODEL==SM_3 || MODEL==SM_GL
  248. #define Tex( image, uv ) tex2D (image, uv ) // access a 2D texture
  249. #define Tex3D( image, uvw) tex3D (image, uvw) // access a 3D texture
  250. #define TexCube(image, uvw) texCUBE(image, uvw) // access a Cube texture
  251. #define TexLod( image, uv ) tex2Dlod (image, Vec4(uv, 0, 0)) // access 2D texture's 0-th MipMap (LOD level=0)
  252. #define TexLodI( image, uv , i) tex2Dlod (image, Vec4(uv, 0, i)) // access 2D texture's i-th MipMap (LOD level=i)
  253. #define Tex3DLod( image, uvw ) tex3Dlod (image, Vec4(uvw , 0)) // access 3D texture's 0-th MipMap (LOD level=0)
  254. #define TexCubeLod(image, uvw ) texCUBElod(image, Vec4(uvw , 0)) // access Cube texture's 0-th MipMap (LOD level=0)
  255. #define TexPoint(image, uv) TexLod(image, uv)
  256. #define TexClamp( image, uv ) Tex (image, uv )
  257. #define TexLodClamp( image, uv ) TexLod (image, uv )
  258. #define Tex3DLodWrap(image, uvw) Tex3DLod(image, uvw)
  259. #if MODEL==SM_3
  260. #if REVERSE_DEPTH // there's no way to set comparison function for HW shadow mapping on DX9, so simple workaround is to reverse the result
  261. #define TexShadow(image, uvw) (1-tex2Dlod(image, Vec4(uvw, 0)).x)
  262. #else
  263. #define TexShadow(image, uvw) tex2Dlod(image, Vec4(uvw, 0)).x
  264. #endif
  265. #elif MODEL==SM_GL
  266. #define TexShadow(image, uvw) tex2Dproj(image, Vec4(uvw.xy, uvw.z*0.5f+0.5f, 1)) // adjust OpenGL depth scale (z' = z*0.5 + 0.5), have to use 'tex2Dproj' because on Windows GL 'tex2Dlod' doesn't work here, perhaps it's a problem with CG that converts HLSL to GLSL, can't return .x because it's not Vec4 but a Flt already (since we're using 'sampler2DShadow')
  267. #endif
  268. #endif
  269. #define TexDepthRawPoint( uv) TexPoint (Depth , uv).x
  270. #define TexDepthRawLinear(uv) TexLod (Depth , uv).x
  271. #define TexDepthPoint( uv) LinearizeDepth(TexPoint (Depth , uv).x)
  272. #define TexDepthLinear( uv) LinearizeDepth(TexLod (Depth , uv).x)
  273. #define TexDepthMSRaw(pixel, sample) TexSample(DepthMS, pixel, sample).x
  274. #define TexDepthMS( pixel, sample) LinearizeDepth(TexSample(DepthMS, pixel, sample).x)
  275. /******************************************************************************/
  276. #include "!Header CPU.h"
  277. /******************************************************************************/
  278. // CONSTANTS
  279. /******************************************************************************/
  280. struct ViewportClass
  281. {
  282. Flt from, range;
  283. Vec2 center, size, size_fov_tan;
  284. Vec4 FracToPosXY, ScreenToPosXY, PosToScreen;
  285. };
  286. BUFFER_I(Viewport, SBI_VIEWPORT)
  287. Vec4 Coords ;
  288. ViewportClass Viewport;
  289. Vec2 RTSizeI ;
  290. #if DX9
  291. Vec2 PixelOffset;
  292. #endif
  293. BUFFER_END
  294. BUFFER(Blend)
  295. const Vec2 BlendOfs4[4]=
  296. {
  297. Vec2( 0.5f, -1.5f),
  298. Vec2(-1.5f, -0.5f),
  299. Vec2( 1.5f, 0.5f),
  300. Vec2(-0.5f, 1.5f),
  301. };
  302. /*const Vec2 BlendOfs5[5]=
  303. {
  304. Vec2(-0.5f, -1.5f),
  305. Vec2(-1.5f, -0.5f),
  306. Vec2( 1.5f, -0.5f),
  307. Vec2(-0.5f, 1.5f),
  308. Vec2( 1.5f, 1.5f),
  309. };*/
  310. const Vec2 BlendOfs6[6]=
  311. {
  312. Vec2( 0.5f, -2.5f),
  313. Vec2(-0.5f, -0.5f),
  314. Vec2( 1.5f, -0.5f),
  315. Vec2(-2.5f, 0.5f),
  316. Vec2(-0.5f, 1.5f),
  317. Vec2( 1.5f, 1.5f),
  318. };
  319. const Vec2 BlendOfs8[8]=
  320. {
  321. Vec2(-1.5f, -2.5f),
  322. Vec2( 0.5f, -1.5f),
  323. Vec2( 2.5f, -1.5f),
  324. Vec2(-1.5f, -0.5f),
  325. Vec2( 1.5f, 0.5f),
  326. Vec2(-2.5f, 1.5f),
  327. Vec2(-0.5f, 1.5f),
  328. Vec2( 1.5f, 2.5f),
  329. };
  330. /*const Vec2 BlendOfs9[9]=
  331. {
  332. Vec2(-2.5f, -2.5f),
  333. Vec2(-0.5f, -2.5f),
  334. Vec2( 1.5f, -2.5f),
  335. Vec2(-2.5f, -0.5f),
  336. Vec2(-0.5f, -0.5f),
  337. Vec2( 1.5f, -0.5f),
  338. Vec2(-2.5f, 1.5f),
  339. Vec2(-0.5f, 1.5f),
  340. Vec2( 1.5f, 1.5f),
  341. };*/
  342. const Vec2 BlendOfs12[12]=
  343. {
  344. Vec2( 0.5f, -3.5f),
  345. Vec2(-1.5f, -2.5f),
  346. Vec2( 0.5f, -1.5f),
  347. Vec2( 2.5f, -1.5f),
  348. Vec2(-3.5f, -0.5f),
  349. Vec2(-1.5f, -0.5f),
  350. Vec2( 1.5f, 0.5f),
  351. Vec2( 3.5f, 0.5f),
  352. Vec2(-2.5f, 1.5f),
  353. Vec2(-0.5f, 1.5f),
  354. Vec2( 1.5f, 2.5f),
  355. Vec2(-0.5f, 3.5f),
  356. };
  357. /*const Vec2 BlendOfs13[13]=
  358. {
  359. Vec2(-0.5f, -3.5f),
  360. Vec2( 1.5f, -2.5f),
  361. Vec2(-0.5f, -1.5f),
  362. Vec2(-3.5f, -0.5f),
  363. Vec2(-1.5f, -0.5f),
  364. Vec2( 1.5f, -0.5f),
  365. Vec2( 3.5f, -0.5f),
  366. Vec2(-2.5f, 1.5f),
  367. Vec2(-0.5f, 1.5f),
  368. Vec2( 1.5f, 1.5f),
  369. Vec2( 3.5f, 1.5f),
  370. Vec2(-0.5f, 3.5f),
  371. Vec2( 1.5f, 3.5f),
  372. };*/
  373. BUFFER_END
  374. BUFFER(Step)
  375. Flt Step;
  376. BUFFER_END
  377. BUFFER(ColSize)
  378. Vec4 ColSize; // xy=1/Col.hwSize(), zw=Col.hwSize(), this format is also required for SMAA
  379. BUFFER_END
  380. BUFFER(ColClamp)
  381. Vec4 ColClamp; // xy=min.xy, zw=max.xy
  382. BUFFER_END
  383. BUFFER_I(Color, SBI_COLOR)
  384. VecH4 Color[2];
  385. BUFFER_END
  386. /******************************************************************************/
  387. BUFFER_I(Global, SBI_GLOBAL)
  388. Matrix4 ProjMatrix ; // projection matrix
  389. VecH CamAngVel ; // camera angular velocity, pre-multiplied by 'D.motionScale'
  390. Matrix CamMatrix ; // camera matrix
  391. Vec4 ClipPlane =Vec4(0, 0, 0, 1); // clipping plane
  392. Half AllowBackFlip= -1, // normal flipping TODO: this probably needs to be handled differently, so it can work for mirrored reflections too
  393. TesselationDensity ; // tesselation density
  394. Vec2 GrassRangeMulAdd ; // factors used for grass opacity calculation
  395. Vec4 BendFactor ; // factors used for grass/leaf bending calculation
  396. BUFFER_END
  397. BUFFER_I(ObjMatrix, SBI_OBJ_MATRIX) // this CB is dynamically resized, do not add other members
  398. Matrix ViewMatrix[MAX_MATRIX]; // object transformation matrixes relative to view space (this is object matrix * inversed camera matrix = object matrix / camera matrix)
  399. BUFFER_END
  400. BUFFER_I(ObjVel, SBI_OBJ_VEL) // this CB is dynamically resized, do not add other members
  401. VecH ObjVel[MAX_MATRIX]; // object linear velocities (use this for skinning) (this is the linear velocity in view space, pre-multiplied by 'D.motionScale')
  402. BUFFER_END
  403. BUFFER_I(Mesh, SBI_MESH)
  404. Flt VtxHeightmap;
  405. Flt VtxSkinning ;
  406. #if DX9
  407. VecH2 VtxNrmMulAdd;
  408. #endif
  409. VecH4 Highlight; // this can be modified by engine's 'SetHighlight' function
  410. VecH ObjAngVel; // object angular velocity, pre-multiplied by 'D.motionScale', TODO: in the future merge this with 'ObjVel' as half3x2/half2x3 (also for GLSL and adjust everything related to 'ObjVel' in shaders and on CPU side, #VelAngVel)
  411. BUFFER_END
  412. /******************************************************************************/
  413. // MATERIALS
  414. /******************************************************************************/
  415. struct MaterialClass // this is used when a MeshPart has only one material
  416. {
  417. #if 0 // methods produce compile errors in this case, instead of them use "Material*" global functions listed below
  418. VecH4 color () {return _color;}
  419. VecH ambient () {return _ambient_specular.xyz;}
  420. Half specular() {return _ambient_specular.w;}
  421. Half sss () {return _sss_glow_rough_bump.x;}
  422. Half glow () {return _sss_glow_rough_bump.y;}
  423. Half rough () {return _sss_glow_rough_bump.z;}
  424. Half bump () {return _sss_glow_rough_bump.w;}
  425. Flt texScale() {return _texscale_detscale_detpower_reflect.x;}
  426. Flt detScale() {return _texscale_detscale_detpower_reflect.y;}
  427. Half detPower() {return _texscale_detscale_detpower_reflect.z;}
  428. Half reflect () {return _texscale_detscale_detpower_reflect.w;}
  429. #endif
  430. VecH4 _color, // !! color must be listed first because ShaderParam handle for setting Material.color is set from the entire Material object pointer !!
  431. _ambient_specular,
  432. _sss_glow_rough_bump;
  433. Vec4 _texscale_detscale_detpower_reflect;
  434. };
  435. BUFFER_I(Material, SBI_MATERIAL)
  436. MaterialClass Material;
  437. BUFFER_END
  438. inline VecH4 MaterialColor () {return Material._color;}
  439. inline VecH MaterialColor3 () {return Material._color.rgb;}
  440. inline Half MaterialAlpha () {return Material._color.a;}
  441. inline VecH MaterialAmbient () {return Material._ambient_specular.xyz;}
  442. inline Half MaterialSpecular() {return Material._ambient_specular.w;}
  443. inline Half MaterialSss () {return Material._sss_glow_rough_bump.x;}
  444. inline Half MaterialGlow () {return Material._sss_glow_rough_bump.y;}
  445. inline Half MaterialRough () {return Material._sss_glow_rough_bump.z;}
  446. inline Half MaterialBump () {return Material._sss_glow_rough_bump.w;}
  447. inline Flt MaterialTexScale() {return Material._texscale_detscale_detpower_reflect.x;}
  448. inline Flt MaterialDetScale() {return Material._texscale_detscale_detpower_reflect.y;}
  449. inline Half MaterialDetPower() {return Material._texscale_detscale_detpower_reflect.z;}
  450. inline Half MaterialReflect () {return Material._texscale_detscale_detpower_reflect.w;}
  451. /******************************************************************************/
  452. struct MultiMaterialClass // this is used when a MeshPart has multiple materials
  453. {
  454. #if 0 // methods produce compile errors in this case, instead of them use "MultiMaterial*()" global functions listed below
  455. VecH4 color () {return _color ;}
  456. VecH color3 () {return _color.rgb ;}
  457. VecH4 normalMul() {return _normal_mul;}
  458. VecH4 normalAdd() {return _normal_add;}
  459. Flt texScale () {return _texscale_detscale_detmul_detadd.x;}
  460. Flt detScale () {return _texscale_detscale_detmul_detadd.y;}
  461. Half detMul () {return _texscale_detscale_detmul_detadd.z;}
  462. Half detAdd () {return _texscale_detscale_detmul_detadd.w;}
  463. Half bump () {return _bump_macro_reflect.x;}
  464. Half macro () {return _bump_macro_reflect.y;}
  465. Half reflect () {return _bump_macro_reflect.z;}
  466. #endif
  467. VecH4 _color,
  468. _normal_mul,
  469. _normal_add;
  470. Vec4 _texscale_detscale_detmul_detadd;
  471. VecH _bump_macro_reflect;
  472. };
  473. BUFFER(MultiMaterial0) MultiMaterialClass MultiMaterial0; BUFFER_END
  474. BUFFER(MultiMaterial1) MultiMaterialClass MultiMaterial1; BUFFER_END
  475. BUFFER(MultiMaterial2) MultiMaterialClass MultiMaterial2; BUFFER_END
  476. BUFFER(MultiMaterial3) MultiMaterialClass MultiMaterial3; BUFFER_END
  477. inline VecH4 MultiMaterial0Color () {return MultiMaterial0._color ;}
  478. inline VecH MultiMaterial0Color3 () {return MultiMaterial0._color.rgb ;}
  479. inline VecH4 MultiMaterial0NormalMul() {return MultiMaterial0._normal_mul;}
  480. inline VecH4 MultiMaterial0NormalAdd() {return MultiMaterial0._normal_add;}
  481. inline Flt MultiMaterial0TexScale () {return MultiMaterial0._texscale_detscale_detmul_detadd.x;}
  482. inline Flt MultiMaterial0DetScale () {return MultiMaterial0._texscale_detscale_detmul_detadd.y;}
  483. inline Half MultiMaterial0DetMul () {return MultiMaterial0._texscale_detscale_detmul_detadd.z;}
  484. inline Half MultiMaterial0DetAdd () {return MultiMaterial0._texscale_detscale_detmul_detadd.w;}
  485. inline Half MultiMaterial0Bump () {return MultiMaterial0._bump_macro_reflect.x;}
  486. inline Half MultiMaterial0Macro () {return MultiMaterial0._bump_macro_reflect.y;}
  487. inline Half MultiMaterial0Reflect () {return MultiMaterial0._bump_macro_reflect.z;}
  488. inline VecH4 MultiMaterial1Color () {return MultiMaterial1._color ;}
  489. inline VecH MultiMaterial1Color3 () {return MultiMaterial1._color.rgb ;}
  490. inline VecH4 MultiMaterial1NormalMul() {return MultiMaterial1._normal_mul;}
  491. inline VecH4 MultiMaterial1NormalAdd() {return MultiMaterial1._normal_add;}
  492. inline Flt MultiMaterial1TexScale () {return MultiMaterial1._texscale_detscale_detmul_detadd.x;}
  493. inline Flt MultiMaterial1DetScale () {return MultiMaterial1._texscale_detscale_detmul_detadd.y;}
  494. inline Half MultiMaterial1DetMul () {return MultiMaterial1._texscale_detscale_detmul_detadd.z;}
  495. inline Half MultiMaterial1DetAdd () {return MultiMaterial1._texscale_detscale_detmul_detadd.w;}
  496. inline Half MultiMaterial1Bump () {return MultiMaterial1._bump_macro_reflect.x;}
  497. inline Half MultiMaterial1Macro () {return MultiMaterial1._bump_macro_reflect.y;}
  498. inline Half MultiMaterial1Reflect () {return MultiMaterial1._bump_macro_reflect.z;}
  499. inline VecH4 MultiMaterial2Color () {return MultiMaterial2._color ;}
  500. inline VecH MultiMaterial2Color3 () {return MultiMaterial2._color.rgb ;}
  501. inline VecH4 MultiMaterial2NormalMul() {return MultiMaterial2._normal_mul;}
  502. inline VecH4 MultiMaterial2NormalAdd() {return MultiMaterial2._normal_add;}
  503. inline Flt MultiMaterial2TexScale () {return MultiMaterial2._texscale_detscale_detmul_detadd.x;}
  504. inline Flt MultiMaterial2DetScale () {return MultiMaterial2._texscale_detscale_detmul_detadd.y;}
  505. inline Half MultiMaterial2DetMul () {return MultiMaterial2._texscale_detscale_detmul_detadd.z;}
  506. inline Half MultiMaterial2DetAdd () {return MultiMaterial2._texscale_detscale_detmul_detadd.w;}
  507. inline Half MultiMaterial2Bump () {return MultiMaterial2._bump_macro_reflect.x;}
  508. inline Half MultiMaterial2Macro () {return MultiMaterial2._bump_macro_reflect.y;}
  509. inline Half MultiMaterial2Reflect () {return MultiMaterial2._bump_macro_reflect.z;}
  510. inline VecH4 MultiMaterial3Color () {return MultiMaterial3._color ;}
  511. inline VecH MultiMaterial3Color3 () {return MultiMaterial3._color.rgb ;}
  512. inline VecH4 MultiMaterial3NormalMul() {return MultiMaterial3._normal_mul;}
  513. inline VecH4 MultiMaterial3NormalAdd() {return MultiMaterial3._normal_add;}
  514. inline Flt MultiMaterial3TexScale () {return MultiMaterial3._texscale_detscale_detmul_detadd.x;}
  515. inline Flt MultiMaterial3DetScale () {return MultiMaterial3._texscale_detscale_detmul_detadd.y;}
  516. inline Half MultiMaterial3DetMul () {return MultiMaterial3._texscale_detscale_detmul_detadd.z;}
  517. inline Half MultiMaterial3DetAdd () {return MultiMaterial3._texscale_detscale_detmul_detadd.w;}
  518. inline Half MultiMaterial3Bump () {return MultiMaterial3._bump_macro_reflect.x;}
  519. inline Half MultiMaterial3Macro () {return MultiMaterial3._bump_macro_reflect.y;}
  520. inline Half MultiMaterial3Reflect () {return MultiMaterial3._bump_macro_reflect.z;}
  521. /******************************************************************************/
  522. BUFFER(Behind)
  523. Half BehindBias; // this can be modified by engine's 'SetBehindBias' function
  524. BUFFER_END
  525. /******************************************************************************/
  526. // IMAGES
  527. /******************************************************************************/
  528. Image Col, Col1, Col2, Col3,
  529. Nrm, Nrm1, Nrm2, Nrm3,
  530. Det, Det1, Det2, Det3,
  531. Mac, Mac1, Mac2, Mac3,
  532. Lum,
  533. Depth;
  534. ImageCube Rfl, Rfl1, Rfl2, Rfl3;
  535. #if MODEL>=SM_4
  536. Texture2DMS<Vec4, MS_SAMPLES> ColMS;
  537. Texture2DMS<Vec4, MS_SAMPLES> NrmMS;
  538. Texture2DMS<Vec4, MS_SAMPLES> LumMS;
  539. Texture2DMS<Flt , MS_SAMPLES> DepthMS;
  540. #endif
  541. #if DX11
  542. SAMPLER(SamplerDefault , SSI_DEFAULT );
  543. SAMPLER(SamplerPoint , SSI_POINT );
  544. SAMPLER(SamplerLinearClamp, SSI_LINEAR_CLAMP);
  545. SAMPLER(SamplerLinearWrap , SSI_LINEAR_WRAP );
  546. SAMPLER(SamplerLinearCWW , SSI_LINEAR_CWW );
  547. SHADOW_SAMPLER(SamplerShadowMap , SSI_SHADOW );
  548. SAMPLER(SamplerFont , SSI_FONT );
  549. #endif
  550. /******************************************************************************/
  551. struct VtxInput // Vertex Input, use this class to access vertex data in vertex shaders
  552. {
  553. #if MODEL==SM_GL
  554. // !! must be in sync with GL_VTX_SEMANTIC !!
  555. Vec4 _pos :ATTR0 ;
  556. VecH _hlp :ATTR9 ;
  557. VecH _nrm :ATTR1 ;
  558. VecH4 _tan :ATTR2 ;
  559. Vec2 _tex :ATTR3 ;
  560. Vec2 _tex1 :ATTR4 ;
  561. Vec2 _tex2 :ATTR11;
  562. Half _size :ATTR10;
  563. Vec4 _bone :ATTR5 ;
  564. VecH4 _weight :ATTR6 ;
  565. VecH4 _material:ATTR8 ;
  566. VecH4 _color :ATTR7 ;
  567. #else
  568. Vec4 _pos :POSITION0 ;
  569. VecH _hlp :POSITION1 ;
  570. VecH _nrm :NORMAL ;
  571. VecH4 _tan :TANGENT ;
  572. Vec2 _tex :TEXCOORD0 ;
  573. Vec2 _tex1 :TEXCOORD1 ;
  574. Vec2 _tex2 :TEXCOORD2 ;
  575. Half _size :PSIZE ;
  576. VecU4 _bone :BLENDINDICES;
  577. VecH4 _weight :BLENDWEIGHT ;
  578. VecH4 _material:COLOR0 ;
  579. VecH4 _color :COLOR1 ;
  580. #endif
  581. #if DX9
  582. VecH nrm ( ) {return _nrm *VtxNrmMulAdd.x+VtxNrmMulAdd.y ;} // vertex normal
  583. VecH tan (VecH nrm , uniform Bool heightmap=false) {return heightmap ? VecH(1-nrm.x*nrm.x, -nrm.y*nrm.x, -nrm.z*nrm.x) : _tan.xyz*VtxNrmMulAdd.x+VtxNrmMulAdd.y ;} // vertex tangent, for heightmap: PointOnPlane(Vec(1,0,0), nrm()), Vec(1,0,0)-nrm*nrm.x, which gives a perpendicular however not Normalized !!
  584. VecH bin (VecH nrm, VecH tan, uniform Bool heightmap=false) {return heightmap ? Cross(nrm, tan) : Cross(nrm, tan)*(_tan.w *VtxNrmMulAdd.x+VtxNrmMulAdd.y);} // binormal from transformed normal and tangent
  585. #else
  586. VecH nrm ( ) {return _nrm ;} // vertex normal
  587. VecH tan (VecH nrm , uniform Bool heightmap=false) {return heightmap ? VecH(1-nrm.x*nrm.x, -nrm.y*nrm.x, -nrm.z*nrm.x) : _tan.xyz;} // vertex tangent, for heightmap: PointOnPlane(Vec(1,0,0), nrm()), Vec(1,0,0)-nrm*nrm.x, which gives a perpendicular however not Normalized !!
  588. VecH bin (VecH nrm, VecH tan, uniform Bool heightmap=false) {return heightmap ? Cross(nrm, tan) : Cross(nrm, tan)*_tan.w ;} // binormal from transformed normal and tangent
  589. #endif
  590. Vec2 pos2 ( ) {return _pos.xy ;} // vertex position
  591. Vec pos ( ) {return _pos.xyz ;} // vertex position
  592. Vec4 pos4 ( ) {return _pos ;} // vertex position in Vec4(pos.xyz, 1) format
  593. VecH hlp ( ) {return _hlp ;} // helper position
  594. VecH tan ( ) {return _tan.xyz ;} // helper position
  595. Vec2 tex ( uniform Bool heightmap=false) {return heightmap ? _pos.xz*Vec2(VtxHeightmap, -VtxHeightmap) : _tex ;} // tex coords 0
  596. Vec2 tex1 ( ) {return _tex1 ;} // tex coords 1
  597. Vec2 tex2 ( ) {return _tex2 ;} // tex coords 2
  598. VecI bone ( ) {return VtxSkinning ? _bone.xyz : VecI(0, 0, 0) ;} // bone matrix indexes
  599. VecH weight ( ) {return _weight.xyz ;} // bone matrix weights
  600. VecH4 color ( ) {return _color ;} // vertex color
  601. VecH color3 ( ) {return _color.rgb ;} // vertex color
  602. VecH4 material ( ) {return _material ;} // material weights
  603. VecH material3( ) {return _material.xyz ;} // material weights
  604. Half size ( ) {return _size ;} // point size
  605. #if MODEL>=SM_4
  606. uint _instance:SV_InstanceID;
  607. uint instance() {return _instance;}
  608. #elif MODEL==SM_GL
  609. uint _instance:ATTR15; // we can't use "gl_InstanceID/SV_InstanceID", so instead use ATTR15, which will generate "attribute ivec4 ATTR15;" and "int(ATTR15.x)" which we'll replace with "gl_InstanceID"
  610. uint instance() {return _instance;}
  611. #endif
  612. };
  613. /******************************************************************************/
  614. #define SRGBToLinear Sqr // simple and fast sRGB -> Linear conversion
  615. #define LinearToSRGB Sqrt // simple and fast Linear -> sRGB conversion
  616. /******************************************************************************/
  617. inline Int Min(Int x, Int y ) {return min(x, y);}
  618. inline Half Min(Half x, Half y ) {return min(x, y);}
  619. inline Flt Min(Flt x, Flt y ) {return min(x, y);}
  620. inline Flt Min(Int x, Flt y ) {return min(x, y);}
  621. inline Flt Min(Flt x, Int y ) {return min(x, y);}
  622. inline VecH2 Min(VecH2 x, VecH2 y ) {return min(x, y);}
  623. inline Vec2 Min(Vec2 x, Vec2 y ) {return min(x, y);}
  624. inline VecH Min(VecH x, VecH y ) {return min(x, y);}
  625. inline Vec Min(Vec x, Vec y ) {return min(x, y);}
  626. inline VecH4 Min(VecH4 x, VecH4 y ) {return min(x, y);}
  627. inline Vec4 Min(Vec4 x, Vec4 y ) {return min(x, y);}
  628. inline Int Min(Int x, Int y, Int z ) {return min(x, min(y, z));}
  629. inline Half Min(Half x, Half y, Half z ) {return min(x, min(y, z));}
  630. inline Flt Min(Flt x, Flt y, Flt z ) {return min(x, min(y, z));}
  631. inline VecH2 Min(VecH2 x, VecH2 y, VecH2 z ) {return min(x, min(y, z));}
  632. inline Vec2 Min(Vec2 x, Vec2 y, Vec2 z ) {return min(x, min(y, z));}
  633. inline VecH Min(VecH x, VecH y, VecH z ) {return min(x, min(y, z));}
  634. inline Vec Min(Vec x, Vec y, Vec z ) {return min(x, min(y, z));}
  635. inline VecH4 Min(VecH4 x, VecH4 y, VecH4 z ) {return min(x, min(y, z));}
  636. inline Vec4 Min(Vec4 x, Vec4 y, Vec4 z ) {return min(x, min(y, z));}
  637. inline Int Min(Int x, Int y, Int z, Int w) {return min(x, min(y, min(z, w)));}
  638. inline Half Min(Half x, Half y, Half z, Half w) {return min(x, min(y, min(z, w)));}
  639. inline Flt Min(Flt x, Flt y, Flt z, Flt w) {return min(x, min(y, min(z, w)));}
  640. inline VecH2 Min(VecH2 x, VecH2 y, VecH2 z, VecH2 w) {return min(x, min(y, min(z, w)));}
  641. inline Vec2 Min(Vec2 x, Vec2 y, Vec2 z, Vec2 w) {return min(x, min(y, min(z, w)));}
  642. inline VecH Min(VecH x, VecH y, VecH z, VecH w) {return min(x, min(y, min(z, w)));}
  643. inline Vec Min(Vec x, Vec y, Vec z, Vec w) {return min(x, min(y, min(z, w)));}
  644. inline VecH4 Min(VecH4 x, VecH4 y, VecH4 z, VecH4 w) {return min(x, min(y, min(z, w)));}
  645. inline Vec4 Min(Vec4 x, Vec4 y, Vec4 z, Vec4 w) {return min(x, min(y, min(z, w)));}
  646. inline Int Max(Int x, Int y ) {return max(x, y);}
  647. inline Half Max(Half x, Half y ) {return max(x, y);}
  648. inline Flt Max(Flt x, Flt y ) {return max(x, y);}
  649. inline Flt Max(Int x, Flt y ) {return max(x, y);}
  650. inline Flt Max(Flt x, Int y ) {return max(x, y);}
  651. inline VecH2 Max(VecH2 x, VecH2 y ) {return max(x, y);}
  652. inline Vec2 Max(Vec2 x, Vec2 y ) {return max(x, y);}
  653. inline VecH Max(VecH x, VecH y ) {return max(x, y);}
  654. inline Vec Max(Vec x, Vec y ) {return max(x, y);}
  655. inline VecH4 Max(VecH4 x, VecH4 y ) {return max(x, y);}
  656. inline Vec4 Max(Vec4 x, Vec4 y ) {return max(x, y);}
  657. inline Int Max(Int x, Int y, Int z ) {return max(x, max(y, z));}
  658. inline Half Max(Half x, Half y, Half z ) {return max(x, max(y, z));}
  659. inline Flt Max(Flt x, Flt y, Flt z ) {return max(x, max(y, z));}
  660. inline VecH2 Max(VecH2 x, VecH2 y, VecH2 z ) {return max(x, max(y, z));}
  661. inline Vec2 Max(Vec2 x, Vec2 y, Vec2 z ) {return max(x, max(y, z));}
  662. inline VecH Max(VecH x, VecH y, VecH z ) {return max(x, max(y, z));}
  663. inline Vec Max(Vec x, Vec y, Vec z ) {return max(x, max(y, z));}
  664. inline VecH4 Max(VecH4 x, VecH4 y, VecH4 z ) {return max(x, max(y, z));}
  665. inline Vec4 Max(Vec4 x, Vec4 y, Vec4 z ) {return max(x, max(y, z));}
  666. inline Int Max(Int x, Int y, Int z, Int w) {return max(x, max(y, max(z, w)));}
  667. inline Half Max(Half x, Half y, Half z, Half w) {return max(x, max(y, max(z, w)));}
  668. inline Flt Max(Flt x, Flt y, Flt z, Flt w) {return max(x, max(y, max(z, w)));}
  669. inline VecH2 Max(VecH2 x, VecH2 y, VecH2 z, VecH2 w) {return max(x, max(y, max(z, w)));}
  670. inline Vec2 Max(Vec2 x, Vec2 y, Vec2 z, Vec2 w) {return max(x, max(y, max(z, w)));}
  671. inline VecH Max(VecH x, VecH y, VecH z, VecH w) {return max(x, max(y, max(z, w)));}
  672. inline Vec Max(Vec x, Vec y, Vec z, Vec w) {return max(x, max(y, max(z, w)));}
  673. inline VecH4 Max(VecH4 x, VecH4 y, VecH4 z, VecH4 w) {return max(x, max(y, max(z, w)));}
  674. inline Vec4 Max(Vec4 x, Vec4 y, Vec4 z, Vec4 w) {return max(x, max(y, max(z, w)));}
  675. inline Half Avg(Half x, Half y ) {return (x+y )/2 ;}
  676. inline Flt Avg(Flt x, Flt y ) {return (x+y )*0.50f;}
  677. inline VecH2 Avg(VecH2 x, VecH2 y ) {return (x+y )/2 ;}
  678. inline Vec2 Avg(Vec2 x, Vec2 y ) {return (x+y )*0.50f;}
  679. inline VecH Avg(VecH x, VecH y ) {return (x+y )/2 ;}
  680. inline Vec Avg(Vec x, Vec y ) {return (x+y )*0.50f;}
  681. inline VecH4 Avg(VecH4 x, VecH4 y ) {return (x+y )/2 ;}
  682. inline Vec4 Avg(Vec4 x, Vec4 y ) {return (x+y )*0.50f;}
  683. inline Half Avg(Half x, Half y, Half z ) {return (x+y+z )/3 ;}
  684. inline Flt Avg(Flt x, Flt y, Flt z ) {return (x+y+z )/3.00f;}
  685. inline VecH2 Avg(VecH2 x, VecH2 y, VecH2 z ) {return (x+y+z )/3 ;}
  686. inline Vec2 Avg(Vec2 x, Vec2 y, Vec2 z ) {return (x+y+z )/3.00f;}
  687. inline VecH Avg(VecH x, VecH y, VecH z ) {return (x+y+z )/3 ;}
  688. inline Vec Avg(Vec x, Vec y, Vec z ) {return (x+y+z )/3.00f;}
  689. inline VecH4 Avg(VecH4 x, VecH4 y, VecH4 z ) {return (x+y+z )/3 ;}
  690. inline Vec4 Avg(Vec4 x, Vec4 y, Vec4 z ) {return (x+y+z )/3.00f;}
  691. inline Half Avg(Half x, Half y, Half z, Half w) {return (x+y+z+w)/4 ;}
  692. inline Flt Avg(Flt x, Flt y, Flt z, Flt w) {return (x+y+z+w)*0.25f;}
  693. inline VecH2 Avg(VecH2 x, VecH2 y, VecH2 z, VecH2 w) {return (x+y+z+w)/4 ;}
  694. inline Vec2 Avg(Vec2 x, Vec2 y, Vec2 z, Vec2 w) {return (x+y+z+w)*0.25f;}
  695. inline VecH Avg(VecH x, VecH y, VecH z, VecH w) {return (x+y+z+w)/4 ;}
  696. inline Vec Avg(Vec x, Vec y, Vec z, Vec w) {return (x+y+z+w)*0.25f;}
  697. inline VecH4 Avg(VecH4 x, VecH4 y, VecH4 z, VecH4 w) {return (x+y+z+w)/4 ;}
  698. inline Vec4 Avg(Vec4 x, Vec4 y, Vec4 z, Vec4 w) {return (x+y+z+w)*0.25f;}
  699. inline Half Min(VecH2 v) {return Min(v.x, v.y);}
  700. inline Half Max(VecH2 v) {return Max(v.x, v.y);}
  701. inline Half Avg(VecH2 v) {return Avg(v.x, v.y);}
  702. inline Flt Min(Vec2 v) {return Min(v.x, v.y);}
  703. inline Flt Max(Vec2 v) {return Max(v.x, v.y);}
  704. inline Flt Avg(Vec2 v) {return Avg(v.x, v.y);}
  705. inline Half Min(VecH v) {return Min(v.x, v.y, v.z);}
  706. inline Half Max(VecH v) {return Max(v.x, v.y, v.z);}
  707. inline Half Avg(VecH v) {return Avg(v.x, v.y, v.z);}
  708. inline Flt Min(Vec v) {return Min(v.x, v.y, v.z);}
  709. inline Flt Max(Vec v) {return Max(v.x, v.y, v.z);}
  710. inline Flt Avg(Vec v) {return Avg(v.x, v.y, v.z);}
  711. inline Half Min(VecH4 v) {return Min(v.x, v.y, v.z, v.w);}
  712. inline Half Max(VecH4 v) {return Max(v.x, v.y, v.z, v.w);}
  713. inline Half Avg(VecH4 v) {return Avg(v.x, v.y, v.z, v.w);}
  714. inline Flt Min(Vec4 v) {return Min(v.x, v.y, v.z, v.w);}
  715. inline Flt Max(Vec4 v) {return Max(v.x, v.y, v.z, v.w);}
  716. inline Flt Avg(Vec4 v) {return Avg(v.x, v.y, v.z, v.w);}
  717. inline Half Sum(VecH2 v) {return v.x+v.y ;}
  718. inline Flt Sum(Vec2 v) {return v.x+v.y ;}
  719. inline Half Sum(VecH v) {return v.x+v.y+v.z ;}
  720. inline Flt Sum(Vec v) {return v.x+v.y+v.z ;}
  721. inline Half Sum(VecH4 v) {return v.x+v.y+v.z+v.w;}
  722. inline Flt Sum(Vec4 v) {return v.x+v.y+v.z+v.w;}
  723. inline Int Sqr (Int x) {return x*x ;}
  724. inline Half Sqr (Half x) {return x*x ;}
  725. inline Flt Sqr (Flt x) {return x*x ;}
  726. inline VecH2 Sqr (VecH2 x) {return x*x ;}
  727. inline Vec2 Sqr (Vec2 x) {return x*x ;}
  728. inline VecH Sqr (VecH x) {return x*x ;}
  729. inline Vec Sqr (Vec x) {return x*x ;}
  730. inline VecH4 Sqr (VecH4 x) {return x*x ;}
  731. inline Vec4 Sqr (Vec4 x) {return x*x ;}
  732. inline Int Cube(Int x) {return x*x*x;}
  733. inline Half Cube(Half x) {return x*x*x;}
  734. inline Flt Cube(Flt x) {return x*x*x;}
  735. inline VecH2 Cube(VecH2 x) {return x*x*x;}
  736. inline Vec2 Cube(Vec2 x) {return x*x*x;}
  737. inline VecH Cube(VecH x) {return x*x*x;}
  738. inline Vec Cube(Vec x) {return x*x*x;}
  739. inline VecH4 Cube(VecH4 x) {return x*x*x;}
  740. inline Vec4 Cube(Vec4 x) {return x*x*x;}
  741. inline Half Length(VecH2 v) {return length(v);}
  742. inline Flt Length(Vec2 v) {return length(v);}
  743. inline Half Length(VecH v) {return length(v);}
  744. inline Flt Length(Vec v) {return length(v);}
  745. inline Half Length(VecH4 v) {return length(v);}
  746. inline Flt Length(Vec4 v) {return length(v);}
  747. inline Half Length2(VecH2 v) {return Dot(v, v);}
  748. inline Flt Length2(Vec2 v) {return Dot(v, v);}
  749. inline Half Length2(VecH v) {return Dot(v, v);}
  750. inline Flt Length2(Vec v) {return Dot(v, v);}
  751. inline Half Length2(VecH4 v) {return Dot(v, v);}
  752. inline Flt Length2(Vec4 v) {return Dot(v, v);}
  753. inline Flt Dist(Int a, Int b) {return Sqrt(Flt(a*a + b*b));}
  754. inline Half Dist(Half a, Half b) {return Sqrt( a*a + b*b );}
  755. inline Flt Dist(Flt a, Flt b) {return Sqrt( a*a + b*b );}
  756. inline Half Dist(VecH2 a, VecH2 b) {return distance(a, b );}
  757. inline Flt Dist(Vec2 a, Vec2 b) {return distance(a, b );}
  758. inline Half Dist(VecH a, VecH b) {return distance(a, b );}
  759. inline Flt Dist(Vec a, Vec b) {return distance(a, b );}
  760. inline Int Dist2(Int a, Int b) {return a*a + b*b;}
  761. inline Half Dist2(Half a, Half b) {return a*a + b*b;}
  762. inline Flt Dist2(Flt a, Flt b) {return a*a + b*b;}
  763. inline Half Dist2(VecH2 a, VecH2 b) {return Length2(a-b);}
  764. inline Flt Dist2(Vec2 a, Vec2 b) {return Length2(a-b);}
  765. inline Half Dist2(VecH a, VecH b) {return Length2(a-b);}
  766. inline Flt Dist2(Vec a, Vec b) {return Length2(a-b);}
  767. inline Half Dist2(VecH4 a, VecH4 b) {return Length2(a-b);}
  768. inline Flt Dist2(Vec4 a, Vec4 b) {return Length2(a-b);}
  769. inline Half DistPointPlane(VecH2 pos, VecH2 plane_normal) {return Dot(pos , plane_normal);}
  770. inline Flt DistPointPlane(Vec2 pos, Vec2 plane_normal) {return Dot(pos , plane_normal);}
  771. inline Half DistPointPlane(VecH pos, VecH plane_normal) {return Dot(pos , plane_normal);}
  772. inline Flt DistPointPlane(Vec pos, Vec plane_normal) {return Dot(pos , plane_normal);}
  773. inline Half DistPointPlane(VecH2 pos, VecH2 plane_pos, VecH2 plane_normal) {return Dot(pos-plane_pos, plane_normal);}
  774. inline Flt DistPointPlane(Vec2 pos, Vec2 plane_pos, Vec2 plane_normal) {return Dot(pos-plane_pos, plane_normal);}
  775. inline Half DistPointPlane(VecH pos, VecH plane_pos, VecH plane_normal) {return Dot(pos-plane_pos, plane_normal);}
  776. inline Flt DistPointPlane(Vec pos, Vec plane_pos, Vec plane_normal) {return Dot(pos-plane_pos, plane_normal);}
  777. inline VecH2 PointOnPlane(VecH2 pos, VecH2 plane_normal) {return pos-plane_normal*DistPointPlane(pos, plane_normal);}
  778. inline Vec2 PointOnPlane(Vec2 pos, Vec2 plane_normal) {return pos-plane_normal*DistPointPlane(pos, plane_normal);}
  779. inline VecH PointOnPlane(VecH pos, VecH plane_normal) {return pos-plane_normal*DistPointPlane(pos, plane_normal);}
  780. inline Vec PointOnPlane(Vec pos, Vec plane_normal) {return pos-plane_normal*DistPointPlane(pos, plane_normal);}
  781. inline VecH2 PointOnPlane(VecH2 pos, VecH2 plane_pos, VecH2 plane_normal) {return pos-plane_normal*DistPointPlane(pos, plane_pos, plane_normal);}
  782. inline Vec2 PointOnPlane(Vec2 pos, Vec2 plane_pos, Vec2 plane_normal) {return pos-plane_normal*DistPointPlane(pos, plane_pos, plane_normal);}
  783. inline VecH PointOnPlane(VecH pos, VecH plane_pos, VecH plane_normal) {return pos-plane_normal*DistPointPlane(pos, plane_pos, plane_normal);}
  784. inline Vec PointOnPlane(Vec pos, Vec plane_pos, Vec plane_normal) {return pos-plane_normal*DistPointPlane(pos, plane_pos, plane_normal);}
  785. inline Half Angle (Half x, Half y) {return atan2( y, x);}
  786. inline Flt Angle (Flt x, Flt y) {return atan2( y, x);}
  787. inline Half Angle (VecH2 v ) {return atan2(v.y, v.x);}
  788. inline Flt Angle (Vec2 v ) {return atan2(v.y, v.x);}
  789. inline Half CosSin(Half cs ) {return Sqrt (1-cs*cs );} // NaN
  790. inline Flt CosSin(Flt cs ) {return Sqrt (1-cs*cs );} // NaN
  791. inline void CosSin(out Half cos, out Half sin, Half angle) {sincos(angle, sin, cos);}
  792. inline void CosSin(out Flt cos, out Flt sin, Flt angle) {sincos(angle, sin, cos);}
  793. inline Half Cross2D(VecH2 a, VecH2 b) {return a.x*b.y - a.y*b.x;}
  794. inline Flt Cross2D(Vec2 a, Vec2 b) {return a.x*b.y - a.y*b.x;}
  795. inline Half CalcZ(VecH2 v) {return Sqrt(Sat(1-Dot(v, v)));} // 1 - v.x*v.x - v.y*v.y, NaN
  796. inline Flt CalcZ(Vec2 v) {return Sqrt(Sat(1-Dot(v, v)));} // 1 - v.x*v.x - v.y*v.y, NaN
  797. inline Half SignFast(Half x) {return (x>=0) ? 1 : -1;} // ignores 0
  798. inline Flt SignFast(Flt x) {return (x>=0) ? 1 : -1;} // ignores 0
  799. inline Half AngleFull (Half angle ) {return Frac(angle/PI2 )*PI2 ;} // normalize angle to 0..PI2
  800. inline Flt AngleFull (Flt angle ) {return Frac(angle/PI2 )*PI2 ;} // normalize angle to 0..PI2
  801. inline Half AngleNormalize(Half angle ) {return Frac(angle/PI2 + PI/PI2)*PI2-PI;} // normalize angle to -PI..PI
  802. inline Flt AngleNormalize(Flt angle ) {return Frac(angle/PI2 + PI/PI2)*PI2-PI;} // normalize angle to -PI..PI
  803. inline Half AngleDelta (Half from, Half to) {return AngleNormalize(to-from) ;} // get angle delta -PI..PI
  804. inline Flt AngleDelta (Flt from, Flt to) {return AngleNormalize(to-from) ;} // get angle delta -PI..PI
  805. inline Half AngleBetween (VecH2 a , VecH2 b ) {return AngleDelta(Angle(a), Angle(b)) ;}
  806. inline Flt AngleBetween (Vec2 a , Vec2 b ) {return AngleDelta(Angle(a), Angle(b)) ;}
  807. inline VecH2 Perp(VecH2 vec) {return VecH2(vec.y, -vec.x);} // get perpendicular vector
  808. inline Vec2 Perp(Vec2 vec) {return Vec2 (vec.y, -vec.x);} // get perpendicular vector
  809. inline VecH2 Rotate(VecH2 vec, VecH2 cos_sin) // rotate vector by cos and sin values obtained from a custom angle
  810. {
  811. return VecH2(vec.x*cos_sin.x - vec.y*cos_sin.y,
  812. vec.x*cos_sin.y + vec.y*cos_sin.x);
  813. }
  814. inline Vec2 Rotate(Vec2 vec, Vec2 cos_sin) // rotate vector by cos and sin values obtained from a custom angle
  815. {
  816. return Vec2(vec.x*cos_sin.x - vec.y*cos_sin.y,
  817. vec.x*cos_sin.y + vec.y*cos_sin.x);
  818. }
  819. inline Half LerpR (Half from, Half to, Half v) {return (v-from)/(to-from) ;}
  820. inline Flt LerpR (Flt from, Flt to, Flt v) {return (v-from)/(to-from) ;}
  821. inline Half LerpRS(Half from, Half to, Half v) {return Sat((v-from)/(to-from));}
  822. inline Flt LerpRS(Flt from, Flt to, Flt v) {return Sat((v-from)/(to-from));}
  823. /******************************************************************************/
  824. inline VecH Transform (VecH v, MatrixH3 m) {return mul(v, m) ;} // transform 'v' vector by 'm' orientation-scale matrix
  825. inline VecH Transform3(VecH v, Matrix m) {return mul(v, (MatrixH3)m) ;} // transform 'v' vector by 'm' orientation-scale matrix, faster version of "v.x*m[0] + (v.y*m[1] + (v.z*m[2]))"
  826. #if 1 // TODO: check if future generation GPU's have 'mul' faster (GeForce 650m GT has 'mul' slower)
  827. inline Vec Transform (Vec v, Matrix m) {return v.x*m[0] + (v.y*m[1] + (v.z*m[2] + m[3]));} // transform 'v' vector by 'm' orientation-scale-translation matrix, faster version of "mul(Vec4(v, 1), m)"
  828. inline Vec4 Transform (Vec v, Matrix4 m) {return v.x*m[0] + (v.y*m[1] + (v.z*m[2] + m[3]));} // transform 'v' vector by 'm' 4x4 matrix, faster version of "mul(Vec4(v, 1), m)"
  829. #else
  830. inline Vec Transform (Vec v, Matrix m) {return mul(Vec4(v, 1), m);} // transform 'v' vector by 'm' orientation-scale-translation matrix
  831. inline Vec4 Transform (Vec v, Matrix4 m) {return mul(Vec4(v, 1), m);} // transform 'v' vector by 'm' 4x4 matrix
  832. #endif
  833. inline Vec TransformPos(Vec pos) {return Transform (pos, ViewMatrix[0]);}
  834. inline VecH TransformDir(VecH dir) {return Transform3(dir, ViewMatrix[0]);}
  835. inline Vec TransformPos(Vec pos, uniform uint mtrx) {return Transform (pos, ViewMatrix[mtrx]);}
  836. inline VecH TransformDir(VecH dir, uniform uint mtrx) {return Transform3(dir, ViewMatrix[mtrx]);}
  837. inline Vec TransformPos(Vec pos, VecI bone, Vec weight) {return weight.x*Transform (pos, ViewMatrix[bone.x]) + weight.y*Transform (pos, ViewMatrix[bone.y]) + weight.z*Transform (pos, ViewMatrix[bone.z]);}
  838. inline VecH TransformDir(VecH dir, VecI bone, VecH weight) {return weight.x*Transform3(dir, ViewMatrix[bone.x]) + weight.y*Transform3(dir, ViewMatrix[bone.y]) + weight.z*Transform3(dir, ViewMatrix[bone.z]);}
  839. inline VecH GetBoneVel ( VecI bone, VecH weight) {return weight.x* ( ObjVel [bone.x]) + weight.y* ( ObjVel [bone.y]) + weight.z* ( ObjVel [bone.z]);}
  840. inline Vec4 Project(Vec pos) {return Transform(pos, ProjMatrix);}
  841. /******************************************************************************/
  842. inline Vec MatrixX(Matrix3 m) {return m[0];}
  843. inline Vec MatrixY(Matrix3 m) {return m[1];}
  844. inline Vec MatrixZ(Matrix3 m) {return m[2];}
  845. inline Vec MatrixX (Matrix m) {return m[0];}
  846. inline Vec MatrixY (Matrix m) {return m[1];}
  847. inline Vec MatrixZ (Matrix m) {return m[2];}
  848. inline Vec MatrixPos(Matrix m) {return m[3];}
  849. inline Vec ObjWorldPos(uniform uint mtrx=0) {return Transform(MatrixPos(ViewMatrix[mtrx]), CamMatrix);} // get the world position of the object matrix
  850. /******************************************************************************/
  851. inline void UpdateColorBySss(in out VecH color, VecH normal, uniform Half sub_surf_scatter)
  852. {
  853. color*=(1-Abs(normal.z))*sub_surf_scatter+1;
  854. }
  855. /******************************************************************************/
  856. Flt SRGBLumOfSRGBColor(Vec s) {return LinearToSRGB(Dot(SRGBToLinear(s), ColorLumWeight2));}
  857. /******************************************************************************/
  858. inline void AdjustPixelCenter(in out Vec4 vtx)
  859. {
  860. #if DX9
  861. vtx.xy+=PixelOffset;
  862. #endif
  863. }
  864. /******************************************************************************/
  865. inline Vec2 UVClamp(Vec2 screen, uniform Bool do_clamp=true)
  866. {
  867. return do_clamp ? Mid(screen, ColClamp.xy, ColClamp.zw) : screen;
  868. }
  869. /******************************************************************************/
  870. inline Vec2 FracToPosXY(Vec2 frac) // return view space xy position at z=1
  871. {
  872. return frac * Viewport.FracToPosXY.xy + Viewport.FracToPosXY.zw;
  873. }
  874. inline Vec2 ScreenToPosXY(Vec2 screen) // return view space xy position at z=1
  875. {
  876. return screen * Viewport.ScreenToPosXY.xy + Viewport.ScreenToPosXY.zw;
  877. }
  878. inline Vec2 ScreenToPosXY(Vec2 screen, Flt z) // return view space xy position at z='z'
  879. {
  880. return ScreenToPosXY(screen)*z;
  881. }
  882. /******************************************************************************/
  883. inline Vec2 PosToScreen(Vec4 pos)
  884. {
  885. return (pos.xy/pos.w) * Viewport.PosToScreen.xy + Viewport.PosToScreen.zw;
  886. }
  887. /******************************************************************************/
  888. inline Vec2 PixelToScreen(Vec4 pixel)
  889. {
  890. #if DX9
  891. pixel.xy+=0.5f;
  892. #endif
  893. pixel.xy/=RTSizeI;
  894. return pixel.xy;
  895. }
  896. /******************************************************************************/
  897. // DEPTH
  898. /******************************************************************************/
  899. inline Flt DelinearizeDepth(Flt z, uniform Bool perspective=true)
  900. {
  901. Flt a=ProjMatrix[2][2], // ProjMatrix.z .z
  902. b=ProjMatrix[3][2], // ProjMatrix.pos.z
  903. w=(perspective ? (z*a+b)/z : (z*a+REVERSE_DEPTH));
  904. #if MODEL==SM_GL
  905. w=w*0.5f+0.5f;
  906. #endif
  907. return w;
  908. }
  909. inline Flt LinearizeDepth(Flt w, uniform Bool perspective=true)
  910. {
  911. Flt a=ProjMatrix[2][2], // ProjMatrix.z .z
  912. b=ProjMatrix[3][2]; // ProjMatrix.pos.z
  913. #if MODEL==SM_GL
  914. w=w*2-1;
  915. #endif
  916. // w = (z*a+b)/z
  917. // w*z = a*z + b
  918. // a*z - w*z + b = 0
  919. // (a-w)*z + b = 0
  920. // z = -b/(a-w)
  921. // z = b/(w-a)
  922. // precise: if(perspective && w>=1)return Viewport.range;
  923. return perspective ? b/(w-a) : (w-REVERSE_DEPTH)/a;
  924. }
  925. /******************************************************************************/
  926. // Perspective: pos.xy=pos_xy*z
  927. // Orthogonal : pos.xy=pos_xy
  928. inline Vec GetPos(Flt z, Vec2 pos_xy) // Get Viewspace Position at 'z' depth, 'pos_xy'=known xy position at depth=1
  929. {
  930. Vec pos; pos.z =z;
  931. //if(ORTHO_SUPPORT)pos.xy=pos_xy*(Viewport.ortho ? 1 : pos.z);else
  932. pos.xy=pos_xy*pos.z;
  933. return pos;
  934. }
  935. inline Vec GetPosPoint (Vec2 tex ) {return GetPos(TexDepthPoint (tex), ScreenToPosXY(tex));} // Get Viewspace Position at 'tex' screen coordinates
  936. inline Vec GetPosPoint (Vec2 tex, Vec2 pos_xy) {return GetPos(TexDepthPoint (tex), pos_xy );} // Get Viewspace Position at 'tex' screen coordinates, 'pos_xy'=known xy position at depth=1
  937. inline Vec GetPosLinear(Vec2 tex ) {return GetPos(TexDepthLinear(tex), ScreenToPosXY(tex));} // Get Viewspace Position at 'tex' screen coordinates
  938. inline Vec GetPosLinear(Vec2 tex, Vec2 pos_xy) {return GetPos(TexDepthLinear(tex), pos_xy );} // Get Viewspace Position at 'tex' screen coordinates, 'pos_xy'=known xy position at depth=1
  939. #if MODEL>=SM_4
  940. inline Vec GetPosMS(VecI2 pixel, UInt sample, Vec2 pos_xy) {return GetPos(TexDepthMS(pixel, sample), pos_xy);}
  941. #endif
  942. /******************************************************************************/
  943. void DrawPixel_VS(VtxInput vtx,
  944. out Vec4 outVtx:POSITION)
  945. {
  946. 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)
  947. }
  948. void Draw_VS(VtxInput vtx,
  949. out Vec2 outTex:TEXCOORD0,
  950. out Vec4 outVtx:POSITION )
  951. {
  952. outTex=vtx.tex();
  953. 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)
  954. }
  955. void DrawPosXY_VS(VtxInput vtx,
  956. out Vec2 outTex :TEXCOORD0,
  957. out Vec2 outPosXY:TEXCOORD1,
  958. out Vec4 outVtx :POSITION )
  959. {
  960. outTex =vtx.tex();
  961. outPosXY=ScreenToPosXY(outTex);
  962. 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)
  963. }
  964. /******************************************************************************/
  965. inline Half DistPointPlaneRay(VecH2 p, VecH2 plane_normal, VecH2 ray) {Half rd=Dot(ray, plane_normal); return rd ? Dot (p, plane_normal)/rd : 0;}
  966. inline Flt DistPointPlaneRay(Vec2 p, Vec2 plane_normal, Vec2 ray) {Flt rd=Dot(ray, plane_normal); return rd ? Dot (p, plane_normal)/rd : 0;}
  967. inline Half DistPointPlaneRay(VecH p, VecH plane_normal, VecH ray) {Half rd=Dot(ray, plane_normal); return rd ? Dot (p, plane_normal)/rd : 0;}
  968. inline Flt DistPointPlaneRay(Vec p, Vec plane_normal, Vec ray) {Flt rd=Dot(ray, plane_normal); return rd ? Dot (p, plane_normal)/rd : 0;}
  969. inline Half DistPointPlaneRay(VecH2 p, VecH2 plane_pos, VecH2 plane_normal, VecH2 ray) {Half rd=Dot(ray, plane_normal); return rd ? DistPointPlane(p, plane_pos, plane_normal)/rd : 0;}
  970. inline Flt DistPointPlaneRay(Vec2 p, Vec2 plane_pos, Vec2 plane_normal, Vec2 ray) {Flt rd=Dot(ray, plane_normal); return rd ? DistPointPlane(p, plane_pos, plane_normal)/rd : 0;}
  971. inline Half DistPointPlaneRay(VecH p, VecH plane_pos, VecH plane_normal, VecH ray) {Half rd=Dot(ray, plane_normal); return rd ? DistPointPlane(p, plane_pos, plane_normal)/rd : 0;}
  972. inline Flt DistPointPlaneRay(Vec p, Vec plane_pos, Vec plane_normal, Vec ray) {Flt rd=Dot(ray, plane_normal); return rd ? DistPointPlane(p, plane_pos, plane_normal)/rd : 0;}
  973. inline VecH2 PointOnPlaneRay(VecH2 p, VecH2 plane_normal, VecH2 ray) {return p-ray*DistPointPlaneRay(p, plane_normal, ray);}
  974. inline Vec2 PointOnPlaneRay(Vec2 p, Vec2 plane_normal, Vec2 ray) {return p-ray*DistPointPlaneRay(p, plane_normal, ray);}
  975. inline VecH PointOnPlaneRay(VecH p, VecH plane_normal, VecH ray) {return p-ray*DistPointPlaneRay(p, plane_normal, ray);}
  976. inline Vec PointOnPlaneRay(Vec p, Vec plane_normal, Vec ray) {return p-ray*DistPointPlaneRay(p, plane_normal, ray);}
  977. inline VecH2 PointOnPlaneRay(VecH2 p, VecH2 plane_pos, VecH2 plane_normal, VecH2 ray) {return p-ray*DistPointPlaneRay(p, plane_pos, plane_normal, ray);}
  978. inline Vec2 PointOnPlaneRay(Vec2 p, Vec2 plane_pos, Vec2 plane_normal, Vec2 ray) {return p-ray*DistPointPlaneRay(p, plane_pos, plane_normal, ray);}
  979. inline VecH PointOnPlaneRay(VecH p, VecH plane_pos, VecH plane_normal, VecH ray) {return p-ray*DistPointPlaneRay(p, plane_pos, plane_normal, ray);}
  980. inline Vec PointOnPlaneRay(Vec p, Vec plane_pos, Vec plane_normal, Vec ray) {return p-ray*DistPointPlaneRay(p, plane_pos, plane_normal, ray);}
  981. /******************************************************************************/
  982. inline Matrix3 Inverse(Matrix3 m, uniform Bool normalized)
  983. {
  984. m=transpose(m);
  985. if(!normalized)
  986. {
  987. m[0]/=Length2(m[0]);
  988. m[1]/=Length2(m[1]);
  989. m[2]/=Length2(m[2]);
  990. }
  991. return m;
  992. }
  993. /******************************************************************************/
  994. inline Flt Lerp4(Flt v0, Flt v1, Flt v2, Flt v3, Flt s)
  995. {
  996. return s*s*s * ((2-TAN)*(v1-v2) + TAN*(v3-v0) )
  997. + s*s * ((TAN-3)*(v1 ) - TAN*(v3 ) - (2*TAN-3)*v2 + (2*TAN)*v0)
  998. + s * ( TAN *(v2-v0) )
  999. + v1;
  1000. }
  1001. inline Vec Lerp4(Vec v0, Vec v1, Vec v2, Vec v3, Flt s)
  1002. {
  1003. Flt s2=s*s,
  1004. s3=s*s*s;
  1005. return v1 * ((2-TAN)*s3 + ( TAN-3)*s2 + 1)
  1006. - v2 * ((2-TAN)*s3 + (2*TAN-3)*s2 - TAN*s )
  1007. - v0 * ( TAN*(s3+s ) - (2*TAN )*s2 )
  1008. + v3 * ( TAN*(s3-s2) );
  1009. }
  1010. inline Vec4 Lerp4(Vec4 v0, Vec4 v1, Vec4 v2, Vec4 v3, Flt s)
  1011. {
  1012. Flt s2=s*s,
  1013. s3=s*s*s;
  1014. return v1 * ((2-TAN)*s3 + ( TAN-3)*s2 + 1)
  1015. - v2 * ((2-TAN)*s3 + (2*TAN-3)*s2 - TAN*s )
  1016. - v0 * ( TAN*(s3+s ) - (2*TAN )*s2 )
  1017. + v3 * ( TAN*(s3-s2) );
  1018. }
  1019. inline Half LerpCube(Half s) {return (3-2*s)*s*s;}
  1020. inline Flt LerpCube(Flt s) {return (3-2*s)*s*s;}
  1021. inline Half LerpCube(Half from, Half to, Half s) {return Lerp(from, to, LerpCube(s));}
  1022. inline Flt LerpCube(Flt from, Flt to, Flt s) {return Lerp(from, to, LerpCube(s));}
  1023. inline Flt LerpSmoothPow(Flt s, Flt p)
  1024. {
  1025. s=Sat(s);
  1026. if(s<=0.5f)return 0.5f*Pow( 2*s, p);
  1027. return 1-0.5f*Pow(2-2*s, p);
  1028. }
  1029. inline Half BlendSqr(Half x) {return Sat(1-x*x);}
  1030. inline Flt BlendSqr(Flt x) {return Sat(1-x*x);}
  1031. inline Half BlendSmoothCube(Half x) {x=Sat(Abs(x)); return 1-LerpCube(x);}
  1032. inline Flt BlendSmoothCube(Flt x) {x=Sat(Abs(x)); return 1-LerpCube(x);}
  1033. inline Half BlendSmoothSin(Half x) {x=Sat(Abs(x)); return Cos(x*PI)*0.5f+0.5f;}
  1034. inline Flt BlendSmoothSin(Flt x) {x=Sat(Abs(x)); return Cos(x*PI)*0.5f+0.5f;}
  1035. inline Half Gaussian(Half x) {return exp(-x*x);}
  1036. inline Flt Gaussian(Flt x) {return exp(-x*x);}
  1037. /******************************************************************************/
  1038. inline Flt VisibleOpacity(Flt density, Flt range) {return Pow(1-density, range);} // calculate visible opacity (0..1) having 'density' environment density (0..1), and 'range' (0..Inf)
  1039. inline Flt AccumulatedDensity(Flt density, Flt range) {return 1-Pow(1-density, range);} // calculate accumulated density (0..1) having 'density' environment density (0..1), and 'range' (0..Inf)
  1040. /******************************************************************************/
  1041. inline Half DitherValue(Vec4 pixel) // returns range -0.5 .. 0.5
  1042. {
  1043. #if 0 // low, but good for 6-7 bit panels
  1044. return Frac(Dot(pixel.xy, Vec2(1.0f, 0.5f)/3))-0.5f;
  1045. #elif 0 // medium
  1046. return Frac(Dot(pixel.xy, Vec2(3, 1)/8))-0.5f;
  1047. #elif 1 // good
  1048. return Frac(Dot(pixel.xy, Vec2(1.6f, 1)*0.25f))-0.5f;
  1049. #endif
  1050. }
  1051. inline VecH DitherValueColor(Vec4 pixel)
  1052. {
  1053. #if 1 // mono
  1054. return DitherValue(pixel)/256; // normally we should divide by 255, however we choose 256 so -0.5 .. 0.5 don't accidentally bump by 1 byte color value
  1055. #else // chroma noise, slower but higher quality
  1056. Flt d=pixel.x*1.6f + pixel.y; // Dot(pixel, Vec2(1.6f, 1));
  1057. Vec f=Frac(d*Vec(0.225f, 0.252f, 0.254f));
  1058. return f/256 - 0.5f/256; // (f-0.5f)/256 - normally we should divide by 255, however we choose 256 so -0.5 .. 0.5 don't accidentally bump by 1 byte color value
  1059. #endif
  1060. }
  1061. /******************************************************************************/
  1062. // RGB <-> HSB
  1063. /******************************************************************************/
  1064. inline Vec RgbToHsb(Vec rgb)
  1065. {
  1066. Flt max=Max(rgb),
  1067. min=Min(rgb),
  1068. d =max-min;
  1069. Vec hsb;
  1070. if(d <= 0)hsb.x=0;else
  1071. if(rgb.x>=max)
  1072. {
  1073. if(rgb.y>=rgb.z)hsb.x=(rgb.y-rgb.z)/d;
  1074. else hsb.x=(rgb.y-rgb.z)/d+6;
  1075. }else
  1076. if(rgb.y>=max)hsb.x=(rgb.z-rgb.x)/d+2;
  1077. else hsb.x=(rgb.x-rgb.y)/d+4;
  1078. hsb.x/=6;
  1079. hsb.y =(max ? 1-min/max : 1);
  1080. hsb.z = max;
  1081. return hsb;
  1082. }
  1083. inline Vec HsbToRgb(Vec hsb)
  1084. {
  1085. Flt h=Frac(hsb.x)*6,
  1086. s=Sat (hsb.y),
  1087. f=Frac(h),
  1088. v=hsb.z,
  1089. p=hsb.z*(1-s ),
  1090. q=hsb.z*(1-s*( f)),
  1091. t=hsb.z*(1-s*(1-f));
  1092. if(h<1)return Vec(v, t, p);
  1093. if(h<2)return Vec(q, v, p);
  1094. if(h<3)return Vec(p, v, t);
  1095. if(h<4)return Vec(p, q, v);
  1096. if(h<5)return Vec(t, p, v);
  1097. return Vec(v, p, q);
  1098. }
  1099. /******************************************************************************/
  1100. // ALPHA TEST
  1101. /******************************************************************************/
  1102. inline void AlphaTest(Half alpha, Half fade_out, uniform Int fx)
  1103. {
  1104. if(fx==FX_GRASS)alpha-=fade_out;
  1105. clip(alpha+MaterialAlpha()-1);
  1106. }
  1107. /******************************************************************************/
  1108. // NORMAL
  1109. /******************************************************************************/
  1110. inline void UnpackNormal(in out VecH nrm, uniform Int quality)
  1111. {
  1112. #if !SIGNED_NRM_RT
  1113. nrm=nrm*2-1;
  1114. #endif
  1115. if(quality>0) // always leave as it is for quality<=0 because this is used for High Precision Nrm RT, for which we don't need any dequantization
  1116. { // see 'DequantizeNormal'
  1117. quality=3; // always use quality 3 because in the engine we only have 0..1 options
  1118. Half z=CalcZ(nrm.xy);
  1119. if(quality==1){nrm.z=((nrm.z>=0) ? z : -z);}else
  1120. if(quality==2){nrm.z=Lerp((nrm.z>=0) ? z : -z, nrm.z, Sqr(1-z));}else // errorNoNormalize 793122 (has some artifacts for ground, when looking forward with high specular, and light direction in "sunset mode")
  1121. if(quality==3){nrm.z=Lerp(nrm.z, (nrm.z>=0) ? z : -z, z); nrm=Normalize(nrm);}else // error 7035 (looks almost the same as quality 4 but faster)
  1122. {nrm.z=Lerp((nrm.z>=0) ? z : -z, nrm.z, Length(nrm.xy)); nrm=Normalize(nrm);} // error 5425
  1123. }
  1124. }
  1125. inline VecH4 GetNormal(Vec2 tex, uniform Int quality)
  1126. {
  1127. VecH4 nrm=TexPoint(Nrm, tex); UnpackNormal(nrm.xyz, quality);
  1128. #if SIGNED_NRM_RT && FULL_PRECISION_SPEC
  1129. nrm.w=nrm.w*0.5f+0.5f; // -1..1 -> 0..1
  1130. #endif
  1131. return nrm;
  1132. }
  1133. #if MODEL>=SM_4
  1134. inline VecH4 GetNormalMS(VecI2 pixel, UInt sample, uniform Int quality)
  1135. {
  1136. VecH4 nrm=TexSample(NrmMS, pixel, sample); UnpackNormal(nrm.xyz, quality);
  1137. #if SIGNED_NRM_RT && FULL_PRECISION_SPEC
  1138. nrm.w=nrm.w*0.5f+0.5f; // -1..1 -> 0..1
  1139. #endif
  1140. return nrm;
  1141. }
  1142. #endif
  1143. /******************************************************************************/
  1144. // LOD INDEX
  1145. /******************************************************************************/
  1146. inline Half GetLod(Vec2 tex_coord, Flt tex_size)
  1147. {
  1148. Vec2 tex=tex_coord*tex_size;
  1149. return 0.5f*log2(Max(Length2(ddx(tex)) , Length2(ddy(tex)))); // NVIDIA
  1150. //return 0.5f*log2(Max(Sqr (ddx(tex)) + Sqr (ddy(tex)))); // ATI
  1151. }
  1152. inline Half GetLod(Vec2 tex_coord, Vec2 tex_size)
  1153. {
  1154. Vec2 tex=tex_coord*tex_size;
  1155. return 0.5f*log2(Max(Length2(ddx(tex)) , Length2(ddy(tex)))); // NVIDIA
  1156. //return 0.5f*log2(Max(Sqr (ddx(tex)) + Sqr (ddy(tex)))); // ATI
  1157. }
  1158. /******************************************************************************/
  1159. // GRASS AND LEAF
  1160. /******************************************************************************/
  1161. #define GrassBendFreq 1.0f
  1162. #define GrassBendScale 0.18f
  1163. #define LeafBendFreq 2.0f
  1164. #define LeafBendScale 0.13f
  1165. #define LeafsBendScale (LeafBendScale/2)
  1166. /******************************************************************************/
  1167. inline Vec2 GetGrassBend(Vec center)
  1168. {
  1169. Flt offset=Sum(center.xz*(Vec2(0.7f, 0.9f)*GrassBendFreq));
  1170. return Vec2((0.28f*GrassBendScale)*Sin(offset+BendFactor.x) + (0.32f*GrassBendScale)*Sin(offset+BendFactor.y),
  1171. (0.18f*GrassBendScale)*Sin(offset+BendFactor.z) + (0.24f*GrassBendScale)*Sin(offset+BendFactor.w));
  1172. }
  1173. inline Vec2 GetLeafBend(Vec center)
  1174. {
  1175. Flt offset=Sum(center.xy*(Vec2(0.7f, 0.8f)*LeafBendFreq));
  1176. return Vec2((0.28f*LeafBendScale)*Sin(offset+BendFactor.x) + (0.32f*LeafBendScale)*Sin(offset+BendFactor.y),
  1177. (0.18f*LeafBendScale)*Sin(offset+BendFactor.z) + (0.24f*LeafBendScale)*Sin(offset+BendFactor.w));
  1178. }
  1179. inline Vec2 GetLeafsBend(Vec center)
  1180. {
  1181. Flt offset=Sum(center.xy*(Vec2(0.7f, 0.8f)*LeafBendFreq));
  1182. return Vec2((0.28f*LeafsBendScale)*Sin(offset+BendFactor.x) + (0.32f*LeafsBendScale)*Sin(offset+BendFactor.y),
  1183. (0.18f*LeafsBendScale)*Sin(offset+BendFactor.z) + (0.24f*LeafsBendScale)*Sin(offset+BendFactor.w));
  1184. }
  1185. /******************************************************************************/
  1186. inline Half GrassFadeOut(uniform uint mtrx=0)
  1187. {
  1188. return Sat(Length2(MatrixPos(ViewMatrix[mtrx]))*GrassRangeMulAdd.x+GrassRangeMulAdd.y); // - fade_out
  1189. }
  1190. inline void BendGrass(Vec local_pos, in out Vec view_pos, uniform uint mtrx=0)
  1191. {
  1192. Vec world_pos=ObjWorldPos(mtrx);
  1193. Flt b =Cube(Sat(local_pos.y));
  1194. Vec2 bend =GetGrassBend(world_pos)*(b*Length(MatrixY(ViewMatrix[mtrx])));
  1195. view_pos+=Vec(CamMatrix[0].x, CamMatrix[1].x, CamMatrix[2].x)*bend.x;
  1196. view_pos+=Vec(CamMatrix[0].y, CamMatrix[1].y, CamMatrix[2].y)*bend.y;
  1197. }
  1198. /******************************************************************************/
  1199. inline void BendLeaf(Vec center, in out Vec pos)
  1200. {
  1201. pos-=center;
  1202. Vec2 cos_sin, bend=GetLeafBend(center);
  1203. CosSin(cos_sin.x, cos_sin.y, bend.x); pos.xy=Rotate(pos.xy, cos_sin);
  1204. CosSin(cos_sin.x, cos_sin.y, bend.y); pos.zy=Rotate(pos.zy, cos_sin);
  1205. pos+=center;
  1206. }
  1207. inline void BendLeaf(Vec center, in out Vec pos, in out VecH nrm)
  1208. {
  1209. pos-=center;
  1210. Vec2 cos_sin, bend=GetLeafBend(center);
  1211. CosSin(cos_sin.x, cos_sin.y, bend.x); pos.xy=Rotate(pos.xy, cos_sin); nrm.xy=Rotate(nrm.xy, cos_sin);
  1212. CosSin(cos_sin.x, cos_sin.y, bend.y); pos.zy=Rotate(pos.zy, cos_sin); nrm.zy=Rotate(nrm.zy, cos_sin);
  1213. pos+=center;
  1214. }
  1215. inline void BendLeaf(Vec center, in out Vec pos, in out VecH nrm, in out VecH tan)
  1216. {
  1217. pos-=center;
  1218. Vec2 cos_sin, bend=GetLeafBend(center);
  1219. CosSin(cos_sin.x, cos_sin.y, bend.x); pos.xy=Rotate(pos.xy, cos_sin); nrm.xy=Rotate(nrm.xy, cos_sin); tan.xy=Rotate(tan.xy, cos_sin);
  1220. CosSin(cos_sin.x, cos_sin.y, bend.y); pos.zy=Rotate(pos.zy, cos_sin); nrm.zy=Rotate(nrm.zy, cos_sin); tan.zy=Rotate(tan.zy, cos_sin);
  1221. pos+=center;
  1222. }
  1223. /******************************************************************************/
  1224. inline void BendLeafs(Vec center, Flt offset, in out Vec pos)
  1225. {
  1226. pos-=center;
  1227. Vec2 cos_sin, bend=GetLeafsBend(center+offset);
  1228. CosSin(cos_sin.x, cos_sin.y, bend.x); pos.xy=Rotate(pos.xy, cos_sin);
  1229. CosSin(cos_sin.x, cos_sin.y, bend.y); pos.zy=Rotate(pos.zy, cos_sin);
  1230. pos+=center;
  1231. }
  1232. inline void BendLeafs(Vec center, Flt offset, in out Vec pos, in out VecH nrm)
  1233. {
  1234. pos-=center;
  1235. Vec2 cos_sin, bend=GetLeafsBend(center+offset);
  1236. CosSin(cos_sin.x, cos_sin.y, bend.x); pos.xy=Rotate(pos.xy, cos_sin); nrm.xy=Rotate(nrm.xy, cos_sin);
  1237. CosSin(cos_sin.x, cos_sin.y, bend.y); pos.zy=Rotate(pos.zy, cos_sin); nrm.zy=Rotate(nrm.zy, cos_sin);
  1238. pos+=center;
  1239. }
  1240. inline void BendLeafs(Vec center, Flt offset, in out Vec pos, in out VecH nrm, in out VecH tan)
  1241. {
  1242. pos-=center;
  1243. Vec2 cos_sin, bend=GetLeafsBend(center+offset);
  1244. CosSin(cos_sin.x, cos_sin.y, bend.x); pos.xy=Rotate(pos.xy, cos_sin); nrm.xy=Rotate(nrm.xy, cos_sin); tan.xy=Rotate(tan.xy, cos_sin);
  1245. CosSin(cos_sin.x, cos_sin.y, bend.y); pos.zy=Rotate(pos.zy, cos_sin); nrm.zy=Rotate(nrm.zy, cos_sin); tan.zy=Rotate(tan.zy, cos_sin);
  1246. pos+=center;
  1247. }
  1248. /******************************************************************************/
  1249. // DEPTH WEIGHT
  1250. /******************************************************************************/
  1251. BUFFER(DepthWeight)
  1252. Flt DepthWeightScale=0.005f;
  1253. BUFFER_END
  1254. #if 0
  1255. Flt P1=0.004f, P2=2;
  1256. inline Vec2 DepthWeightMAD(Flt depth) {return Vec2(-1.0f/(depth*DepthWeightScale+P1), P2);}
  1257. #else
  1258. inline Vec2 DepthWeightMAD(Flt depth) {return Vec2(-1.0f/(depth*DepthWeightScale+0.004f), 2);}
  1259. #endif
  1260. inline Flt DepthWeight(Flt delta, Vec2 dw_mad)
  1261. {
  1262. return Sat(Abs(delta)*dw_mad.x + dw_mad.y);
  1263. }
  1264. /******************************************************************************/
  1265. // DETAIL
  1266. /******************************************************************************/
  1267. inline Vec GetDetail(Vec2 tex)
  1268. {
  1269. return (Tex(Det, tex*MaterialDetScale()).xyz-0.5f)*MaterialDetPower(); // tex.xy=nrm.xy, tex.z=color, #MaterialTextureChannelOrder
  1270. }
  1271. /******************************************************************************/
  1272. // FACE NORMAL HANDLING
  1273. /******************************************************************************/
  1274. #if MODEL==SM_GL
  1275. inline void BackFlip(in out VecH dir, Bool front) {if(front<=0)dir*=AllowBackFlip;} // keep this as "front<=0" instead of "!front" because Mac OpenGL drivers for Intel fail to compile this correctly, resulting in reversed lighting
  1276. #elif MODEL==SM_3
  1277. inline void BackFlip(in out VecH dir, Flt front) {if(front< 0)dir*=AllowBackFlip;}
  1278. #else
  1279. inline void BackFlip(in out VecH dir, Bool front) {if(!front )dir*=AllowBackFlip;}
  1280. #endif
  1281. /******************************************************************************/
  1282. // VELOCITIES
  1283. /******************************************************************************/
  1284. inline void UpdateVelocities_VS(in out Vec vel, Vec local_pos, Vec view_space_pos, uniform uint mtrx=0)
  1285. {
  1286. // on start 'vel'=object linear velocity in view space
  1287. vel-=Transform3(Cross(local_pos , ObjAngVel), ViewMatrix[mtrx]); // add object angular velocity in view space
  1288. vel+= Cross( view_space_pos, CamAngVel); // add camera angular velocity
  1289. }
  1290. inline void UpdateVelocities_PS(in out Vec vel, Vec view_space_pos)
  1291. {
  1292. // divide by distance to camera (there is no NaN because in PixelShader view_space_pos.z>0)
  1293. //if(ORTHO_SUPPORT && !Viewport.ortho)
  1294. vel/=view_space_pos.z;
  1295. #if !SIGNED_VEL_RT
  1296. vel=vel*0.5f+0.5f; // scale from signed to unsigned (-1..1 -> 0..1)
  1297. #endif
  1298. }
  1299. inline Vec GetVelocitiesCameraOnly(Vec view_space_pos)
  1300. {
  1301. Vec vel =ObjVel[0]; // set to object linear velocity in view space
  1302. vel+=Cross(view_space_pos, CamAngVel); // add camera angular velocity
  1303. // divide by distance to camera (there is no NaN because in PixelShader view_space_pos.z>0)
  1304. //if(ORTHO_SUPPORT && !Viewport.ortho)
  1305. vel/=view_space_pos.z;
  1306. vel=Mid(vel, Vec(-1, -1, -1), Vec(1, 1, 1)); // clamp to get the same results as if stored in a RT
  1307. return vel; // this function always returns signed -1..1 version
  1308. }
  1309. /******************************************************************************/
  1310. inline Half MultiMaterialWeight(Half weight, Half alpha) // 'weight'=weight of this material, 'alpha'=color texture alpha (opacity or bump)
  1311. {
  1312. // sharpen alpha
  1313. #if 0 // not needed when ALPHA_POWER is big
  1314. #if 0 // good but slow
  1315. if(alpha<=0.5f)alpha= 2*Sqr( alpha);
  1316. else alpha=1-2*Sqr(1-alpha);
  1317. #else // fast approximation
  1318. alpha=Sat(alpha*1.5f + (-0.5f*1.5f+0.5f)); // Sat((alpha-0.5f)*1.5f+0.5f)
  1319. #endif
  1320. #endif
  1321. #if 1 // works best
  1322. #define ALPHA_POWER 10.0f
  1323. Half w=weight // base
  1324. +weight*(1-weight)*(alpha*ALPHA_POWER - 0.5f*ALPHA_POWER); // "weight"=ignore alpha at start "1-weight" ignore alpha at end, "(alpha-0.5f)*ALPHA_POWER" alpha
  1325. if(ALPHA_POWER>2)w=Max(w, weight/16); // if ALPHA_POWER>2 then this formula could go below zero which could result in artifacts, because weights could be negative or all zero, so maximize with a small slope (has to be zero at start, and small after that)
  1326. return w;
  1327. #elif 1
  1328. #define ALPHA_POWER 0.5f
  1329. return Sat(weight*(1+ALPHA_POWER) + alpha*ALPHA_POWER - ALPHA_POWER); // start at "-ALPHA_POWER" so it can clear out any alpha we have at the start (we always want up to zero weight at the start even if we have high alpha) and always want at least 1 weight at the end, even if we have low alpha
  1330. #else
  1331. return Lerp(weight, alpha, weight*(1-weight)*2);
  1332. #endif
  1333. }
  1334. /******************************************************************************/
  1335. // LIGHTS
  1336. /******************************************************************************/
  1337. struct LIGHT_DIR
  1338. {
  1339. VecH dir;
  1340. VecH4 color; // a=spec
  1341. VecH vol_exponent_steam;
  1342. };
  1343. struct LIGHT_POINT
  1344. {
  1345. Half power, vol, vol_max;
  1346. Vec pos;
  1347. VecH4 color; // a=spec
  1348. };
  1349. struct LIGHT_SQR
  1350. {
  1351. Half range, vol, vol_max;
  1352. Vec pos;
  1353. VecH4 color; // a=spec
  1354. };
  1355. struct LIGHT_CONE
  1356. {
  1357. MatrixH3 mtrx; // must be at start because of ATI OpenGL bug
  1358. Half length, scale, vol, vol_max;
  1359. VecH2 falloff;
  1360. Vec pos;
  1361. VecH4 color; // a=spec
  1362. };
  1363. BUFFER(LightDir ) LIGHT_DIR Light_dir ; BUFFER_END
  1364. BUFFER(LightPoint) LIGHT_POINT Light_point; BUFFER_END
  1365. BUFFER(LightSqr ) LIGHT_SQR Light_sqr ; BUFFER_END
  1366. BUFFER(LightCone ) LIGHT_CONE Light_cone ; BUFFER_END
  1367. /******************************************************************************/
  1368. inline Half LightPointDist(Vec pos ) {return Sat( Light_point.power/Length2(pos ));} // NaN
  1369. inline Half LightSqrDist (Vec pos, Flt range) {return Sat(1-Length2(pos) /Sqr ( range ));}
  1370. inline Half LightSqrDist (Vec pos ) {return Sat(1-Length2(pos) /Sqr (Light_sqr .range ));}
  1371. inline Half LightConeDist (Vec pos ) {return Sat(1-Length2(pos) /Sqr (Light_cone.length ));}
  1372. inline Half LightConeAngle(Vec2 pos ) {return Sat( Length (pos)*Light_cone.falloff.x+Light_cone.falloff.y);}
  1373. inline Half LightDiffuse (VecH nrm, VecH light_dir ) {return Sat(Dot(nrm, light_dir));}
  1374. inline Half LightSpecular(VecH nrm, Half specular, VecH light_dir, VecH eye_dir, Half power=64)
  1375. {
  1376. #if 1 // blinn
  1377. return Pow(Sat(Dot(nrm, Normalize(light_dir+eye_dir))), power)*specular;
  1378. #else // phong
  1379. Vec reflection=Normalize(nrm*(2*Dot(nrm, light_dir)) - light_dir);
  1380. return Pow(Sat(Dot(reflection, eye_dir)), power)*specular;
  1381. #endif
  1382. }
  1383. /******************************************************************************/
  1384. // SHADOWS
  1385. /******************************************************************************/
  1386. BUFFER(Shadow)
  1387. Flt ShdRange ,
  1388. ShdStep[6] ;
  1389. Vec2 ShdRangeMulAdd,
  1390. ShdOpacity ;
  1391. Vec4 ShdJitter ;
  1392. Matrix ShdMatrix ;
  1393. Matrix4 ShdMatrix4[6] ;
  1394. BUFFER_END
  1395. ImageShadow ShdMap;
  1396. Image ShdMap1;
  1397. inline Half ShadowFinal(Half shadow) {return shadow*ShdOpacity.x+ShdOpacity.y;}
  1398. inline Vec ShadowDirTransform(Vec pos, uniform Int num)
  1399. { // using "Int/UInt matrix_index" and "matrix_index=.." and "ShdMatrix4[matrix_index]" was slower
  1400. // using "Matrix4 m" and "m=ShdMatrix4[..]" and "p=Transform(pos, m)" had the same performance as version below
  1401. // imitate binary search
  1402. Vec4 p;
  1403. if(num<=4)
  1404. {
  1405. BRANCH if(num<=2 || pos.z<=ShdStep[1])
  1406. {
  1407. BRANCH if(num<=1 || pos.z<=ShdStep[0])p=Transform(pos, ShdMatrix4[0]);else
  1408. p=Transform(pos, ShdMatrix4[1]);
  1409. }else
  1410. {
  1411. BRANCH if(num<=3 || pos.z<=ShdStep[2])p=Transform(pos, ShdMatrix4[2]);else
  1412. p=Transform(pos, ShdMatrix4[3]);
  1413. }
  1414. }else
  1415. {
  1416. BRANCH if(num<=3 || pos.z<=ShdStep[2])
  1417. {
  1418. BRANCH if(num<=1 || pos.z<=ShdStep[0])p=Transform(pos, ShdMatrix4[0]);else
  1419. BRANCH if(num<=2 || pos.z<=ShdStep[1])p=Transform(pos, ShdMatrix4[1]);else
  1420. p=Transform(pos, ShdMatrix4[2]);
  1421. }else
  1422. {
  1423. BRANCH if(num<=4 || pos.z<=ShdStep[3])p=Transform(pos, ShdMatrix4[3]);else
  1424. BRANCH if(num<=5 || pos.z<=ShdStep[4])p=Transform(pos, ShdMatrix4[4]);else
  1425. p=Transform(pos, ShdMatrix4[5]);
  1426. }
  1427. }
  1428. return p.xyz/p.w;
  1429. }
  1430. inline Vec ShadowPointTransform(Vec pos)
  1431. {
  1432. Vec local=Transform(pos, ShdMatrix);
  1433. Flt a=Max(Abs(local));
  1434. Vec4 p;
  1435. // order of matrixes is based on probability of their usage (most frequently light is hanged upwards, making lower texture most used, then sides -x +x -z +z, and last is top y+)
  1436. BRANCH if(-local.y>=a)p=Transform(pos, ShdMatrix4[3]);else
  1437. BRANCH if( local.x>=a)p=Transform(pos, ShdMatrix4[0]);else
  1438. BRANCH if(-local.x>=a)p=Transform(pos, ShdMatrix4[1]);else
  1439. BRANCH if( local.z>=a)p=Transform(pos, ShdMatrix4[4]);else
  1440. BRANCH if(-local.z>=a)p=Transform(pos, ShdMatrix4[5]);else
  1441. p=Transform(pos, ShdMatrix4[2]);
  1442. return p.xyz/p.w;
  1443. }
  1444. /******************************************************************************/
  1445. inline VecH2 ShadowJitter(Vec2 pixel)
  1446. {
  1447. #if DX9
  1448. pixel-=0.5f; // yes this is needed
  1449. #endif
  1450. VecH2 offset;
  1451. offset=Frac(pixel*0.5f)*2 - 0.5f;
  1452. offset.y+= offset.x;
  1453. if(offset.y>1.1f)offset.y=0;
  1454. return offset*ShdJitter.xy+ShdJitter.zw;
  1455. }
  1456. /******************************************************************************/
  1457. inline Half CompareDepth(Vec pos, Vec2 jitter_value, uniform Bool jitter)
  1458. {
  1459. if(jitter)pos.xy+=jitter_value;
  1460. return TexShadow(ShdMap, pos);
  1461. }
  1462. inline Half CompareDepth2(Vec pos) // 'ShdMap1' is not a Shadow Map Depth Buffer but a Shadow Intensity Color RT
  1463. {
  1464. return Tex(ShdMap1, pos.xy).API(a, r, r); // DX9 uses A8 while others use R8 RT
  1465. }
  1466. /******************************************************************************/
  1467. inline Half ShadowDirValue(Vec pos, Vec2 jitter_value, uniform Bool jitter, uniform Int num, uniform Bool cloud)
  1468. {
  1469. Half fade=Sat(Length2(pos)*ShdRangeMulAdd.x+ShdRangeMulAdd.y);
  1470. Vec p=ShadowDirTransform(pos, num);
  1471. if(cloud)return fade+CompareDepth(p, jitter_value, jitter)*CompareDepth2(p);
  1472. else return fade+CompareDepth(p, jitter_value, jitter);
  1473. }
  1474. inline Half ShadowPointValue(Vec pos, Vec2 jitter_value, uniform Bool jitter)
  1475. {
  1476. Vec p=ShadowPointTransform(pos);
  1477. return CompareDepth(p, jitter_value, jitter);
  1478. }
  1479. inline Half ShadowConeValue(Vec pos, Vec2 jitter_value, uniform Bool jitter)
  1480. {
  1481. Vec4 p=Transform(pos, ShdMatrix4[0]); p.xyz/=p.w;
  1482. return CompareDepth(p.xyz, jitter_value, jitter);
  1483. }
  1484. /******************************************************************************/
  1485. struct DeferredSolidOutput // use this structure in Pixel Shader for setting the output of RT_DEFERRED solid modes
  1486. {
  1487. // !! if making any change here then adjust Water shader too !!
  1488. VecH4 out0:COLOR0,
  1489. out1:COLOR1,
  1490. out2:COLOR2;
  1491. // set components
  1492. inline void color (VecH color ) {out0.rgb=color;}
  1493. inline void glow (Half glow ) {out0.w =glow ;}
  1494. inline void normal(VecH normal)
  1495. {
  1496. #if SIGNED_NRM_RT
  1497. out1.xyz=normal;
  1498. #else
  1499. out1.xyz=normal*0.5f+0.5f; // -1..1 -> 0..1
  1500. #endif
  1501. }
  1502. #if SIGNED_NRM_RT && FULL_PRECISION_SPEC
  1503. inline void specular(Half specular) {out1.w=specular*2-1;} // 0..1 -> -1..1
  1504. #else
  1505. inline void specular(Half specular) {out1.w=specular;}
  1506. #endif
  1507. inline void velocity(Vec vel, Vec view_space_pos) {UpdateVelocities_PS(vel, view_space_pos); out2.xyz=vel; out2.w=0;}
  1508. };
  1509. /******************************************************************************/
  1510. // TESSELATION
  1511. /******************************************************************************/
  1512. struct HSData
  1513. {
  1514. Flt TessFactor[3] :SV_TessFactor,
  1515. InsideTessFactor:SV_InsideTessFactor;
  1516. Vec B210:TEXCOORD0,
  1517. B120:TEXCOORD1,
  1518. B021:TEXCOORD2,
  1519. B012:TEXCOORD3,
  1520. B102:TEXCOORD4,
  1521. B201:TEXCOORD5,
  1522. B111:TEXCOORD6;
  1523. Vec N110:NORMAL0,
  1524. N011:NORMAL1,
  1525. N101:NORMAL2;
  1526. };
  1527. inline Vec2 ToScreen(Vec pos)
  1528. {
  1529. return pos.xy/Max(0.1f, pos.z);
  1530. }
  1531. inline HSData GetHSData(Vec pos0, Vec pos1, Vec pos2, Vec nrm0, Vec nrm1, Vec nrm2, uniform Bool shadow_map=false)
  1532. {
  1533. HSData O;
  1534. //BRANCH if(AdaptiveTesselation)
  1535. {
  1536. Vec2 p0=ToScreen(shadow_map ? Transform(pos0, ShdMatrix) : pos0),
  1537. p1=ToScreen(shadow_map ? Transform(pos1, ShdMatrix) : pos1),
  1538. p2=ToScreen(shadow_map ? Transform(pos2, ShdMatrix) : pos2);
  1539. O.TessFactor[0]=Dist(p2, p0)*TesselationDensity;
  1540. O.TessFactor[1]=Dist(p0, p1)*TesselationDensity;
  1541. O.TessFactor[2]=Dist(p1, p2)*TesselationDensity;
  1542. O.InsideTessFactor=Avg(O.TessFactor[0], O.TessFactor[1], O.TessFactor[2]);
  1543. }/*else
  1544. {
  1545. O.TessFactor[0]=O.TessFactor[1]=O.TessFactor[2]=Tess;
  1546. O.InsideTessFactor=Tess;
  1547. }*/
  1548. BRANCH if(O.InsideTessFactor>1)
  1549. {
  1550. Vec B003=pos0,
  1551. B030=pos1,
  1552. B300=pos2;
  1553. Vec N002=nrm0,
  1554. N020=nrm1,
  1555. N200=nrm2;
  1556. O.B210=2*B003+B030-Dot(B030-B003,N002)*N002;
  1557. O.B120=2*B030+B003-Dot(B003-B030,N020)*N020;
  1558. O.B021=2*B030+B300-Dot(B300-B030,N020)*N020;
  1559. O.B012=2*B300+B030-Dot(B030-B300,N200)*N200;
  1560. O.B102=2*B300+B003-Dot(B003-B300,N200)*N200;
  1561. O.B201=2*B003+B300-Dot(B300-B003,N002)*N002;
  1562. Vec E=O.B210+O.B120+O.B021+O.B012+O.B102+O.B201,
  1563. V=B003+B030+B300;
  1564. O.B111=E*0.5f-V;
  1565. }
  1566. #if 0 // cubic normal interpolation
  1567. Flt V12=2*Dot(B030-B003, N002+N020)/Dot(B030-B003, B030-B003); O.N110=Normalize(N002+N020-V12*(B030-B003));
  1568. Flt V23=2*Dot(B300-B030, N020+N200)/Dot(B300-B030, B300-B030); O.N011=Normalize(N020+N200-V23*(B300-B030));
  1569. Flt V31=2*Dot(B003-B300, N200+N002)/Dot(B003-B300, B003-B300); O.N101=Normalize(N200+N002-V31*(B003-B300));
  1570. #endif
  1571. return O;
  1572. }
  1573. /******************************************************************************/
  1574. inline void SetDSPosNrm(out Vec pos, out Vec nrm, Vec pos0, Vec pos1, Vec pos2, Vec nrm0, Vec nrm1, Vec nrm2, Vec B, HSData hs_data, uniform Bool clamp_tess, Flt clamp_tess_factor)
  1575. {
  1576. // TODO: we could encode 'clamp_tess_factor' in vtx.nrm.w
  1577. Flt U=B.x, UU=U*U,
  1578. V=B.y, VV=V*V,
  1579. W=B.z, WW=W*W;
  1580. #if 0 // cubic normal interpolation
  1581. nrm=Normalize(nrm0*WW
  1582. +nrm1*UU
  1583. +nrm2*VV
  1584. +hs_data.N110*W*U
  1585. +hs_data.N011*U*V
  1586. +hs_data.N101*W*V);
  1587. #else // linear normal interpolation
  1588. nrm=Normalize(nrm0*W + nrm1*U + nrm2*V);
  1589. #endif
  1590. BRANCH if(hs_data.InsideTessFactor>1)
  1591. {
  1592. pos=pos0*(WW*W)
  1593. +pos1*(UU*U)
  1594. +pos2*(VV*V)
  1595. +hs_data.B210*(WW*U)
  1596. +hs_data.B120*(W*UU)
  1597. +hs_data.B201*(WW*V)
  1598. +hs_data.B021*(UU*V)
  1599. +hs_data.B102*(W*VV)
  1600. +hs_data.B012*(U*VV)
  1601. +hs_data.B111*(W*U*V);
  1602. if(clamp_tess)pos=Lerp(pos0*W + pos1*U + pos2*V, pos, clamp_tess_factor);
  1603. }else
  1604. {
  1605. pos=pos0*W + pos1*U + pos2*V;
  1606. }
  1607. }
  1608. /******************************************************************************/