GLSL.ShaderPosts.pas 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLSL.ShaderPosts;
  5. (* Post shaders that simulate shader visions for a mask or the entire scene. *)
  6. interface
  7. {$I GLScene.inc}
  8. uses
  9. System.Classes,
  10. OpenGLTokens,
  11. GLTexture,
  12. GLScene,
  13. GLState,
  14. GLVectorGeometry,
  15. GLContext,
  16. GLMaterial,
  17. GLSL.Shader,
  18. GLS.ShaderCustom,
  19. GLRenderContextInfo,
  20. GLTextureFormat,
  21. GLVectorTypes;
  22. type
  23. // Custom class for GLSLPostBlurShader. A shader that blurs the entire scene
  24. TGLCustomGLSLPostBlurShader = class(TGLCustomGLSLShader, IGLPostShader)
  25. private
  26. FThreshold: Single;
  27. // Implementing IGLPostShader.
  28. procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;
  29. TextureTarget: TGLTextureTarget);
  30. function GetTextureTarget: TGLTextureTarget;
  31. function StoreThreshold: Boolean;
  32. protected
  33. procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
  34. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  35. public
  36. constructor Create(AOwner: TComponent); override;
  37. property Threshold: Single read FThreshold write FThreshold stored StoreThreshold;
  38. end;
  39. TGLSLPostBlurShader = class(TGLCustomGLSLPostBlurShader)
  40. published
  41. property Threshold;
  42. end;
  43. (* Custom class for GLSLPostThermalVisionShader.
  44. A Shader that simulate a thermal vision of the entire scene *)
  45. // A shader that simulate a Thermal Vision of the entire scene
  46. TGLCustomGLSLPostThermalVisionShader = class(TGLCustomGLSLShader, IGLPostShader)
  47. private
  48. FThreshold : Single;
  49. Fintensity : Single;
  50. // Implementing IGLPostShader.
  51. procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
  52. function GetTextureTarget: TGLTextureTarget;
  53. function StoreThreshold: Boolean;
  54. function StoreIntensity: Boolean;
  55. protected
  56. procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
  57. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  58. public
  59. constructor Create(AOwner: TComponent); override;
  60. property Threshold: Single read FThreshold write FThreshold stored StoreThreshold;
  61. property Intensity: Single read FIntensity write FIntensity stored StoreIntensity;
  62. end;
  63. TGLSLPostThermalVisionShader = class(TGLCustomGLSLPostThermalVisionShader)
  64. published
  65. property Threshold;
  66. property Intensity;
  67. end;
  68. (* Custom class for GLSLPostDreamVisionShader.
  69. A shader that simulate a grayscale threshold vision (aka dream) of the entire scene*)
  70. TGLCustomGLSLPostDreamVisionShader = class(TGLCustomGLSLShader, IGLPostShader)
  71. private
  72. FThreshold : Single; // In percent 0..100;
  73. // Implementing IGLPostShader.
  74. procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
  75. function GetTextureTarget: TGLTextureTarget;
  76. function StoreThreshold: Boolean;
  77. protected
  78. procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
  79. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  80. public
  81. constructor Create(AOwner: TComponent); override;
  82. property Threshold: Single read FThreshold write FThreshold stored StoreThreshold;
  83. end;
  84. TGLSLPostDreamVisionShader = class(TGLCustomGLSLPostDreamVisionShader)
  85. published
  86. property Threshold;
  87. end;
  88. (* Custom class for GLSLPostNightVisionShader.
  89. A shader that simulate a Night Vision of the scene throw a mask if enabled,
  90. or of the entire scene*)
  91. TGLCustomGLSLPostNightVisionShader = class(TGLCustomGLSLShader, IGLPostShader)
  92. private
  93. FMaterialLibrary: TGLAbstractMaterialLibrary;
  94. FLuminanceThreshold: Single;
  95. FColorAmplification:Single;
  96. FElapsedTime : Single;
  97. FUseMask : Integer;
  98. FNoiseTex : TGLTexture;
  99. FMaskTex : TGLTexture;
  100. FNoiseTexName : TGLLibMaterialName;
  101. FMaskTexName : TGLLibMaterialName;
  102. // Implementing IGLPostShader.
  103. procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
  104. function GetTextureTarget: TGLTextureTarget;
  105. function StoreLuminanceThreshold: Boolean;
  106. function StoreColorAmplification: Boolean;
  107. procedure SetMaskTexTexture(const Value: TGLTexture);
  108. procedure SetNoiseTexTexture(const Value: TGLTexture);
  109. function GetNoiseTexName: TGLLibMaterialName;
  110. procedure SetNoiseTexName(const Value: TGLLibMaterialName);
  111. function GetMaskTexName: TGLLibMaterialName;
  112. procedure SetMaskTexName(const Value: TGLLibMaterialName);
  113. function GetMaterialLibrary: TGLAbstractMaterialLibrary;
  114. protected
  115. procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
  116. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  117. procedure SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary); virtual;
  118. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  119. public
  120. constructor Create(AOwner: TComponent); override;
  121. property LuminanceThreshold: Single read FLuminanceThreshold write FLuminanceThreshold stored StoreLuminanceThreshold;
  122. property ColorAmplification: Single read FColorAmplification write FColorAmplification stored StoreColorAmplification;
  123. property ElapsedTime: Single read FElapsedTime write FElapsedTime stored false;
  124. property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
  125. property NoiseTex: TGLTexture read FNoiseTex write SetNoiseTexTexture;
  126. property NoiseTexName: TGLLibMaterialName read GetNoiseTexName write SetNoiseTexName;
  127. property MaskTex: TGLTexture read FMaskTex write SetMaskTexTexture;
  128. property MaskTexName: TGLLibMaterialName read GetMaskTexName write SetMaskTexName;
  129. property UseMask : Integer read FUseMask write FUseMask;
  130. end;
  131. TGLSLPostNightVisionShader = class(TGLCustomGLSLPostNightVisionShader)
  132. published
  133. property LuminanceThreshold;
  134. property ColorAmplification;
  135. property ElapsedTime;
  136. property MaterialLibrary;
  137. property NoiseTexName;
  138. property MaskTexName;
  139. property UseMask;
  140. end;
  141. (* Custom class for GLSLPostPixelateShader.
  142. A shader that pixelate of the entire scene*)
  143. TGLCustomGLSLPostPixelateShader = class(TGLCustomGLSLShader, IGLPostShader)
  144. private
  145. FPixelWidth : Single;
  146. FPixelHeight : Single;
  147. // Implementing IGLPostShader.
  148. procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
  149. function GetTextureTarget: TGLTextureTarget;
  150. function StorePixelWidth: Boolean;
  151. function StorePixelHeight: Boolean;
  152. protected
  153. procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
  154. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  155. public
  156. constructor Create(AOwner: TComponent); override;
  157. property PixelWidth: Single read FPixelWidth write FPixelWidth stored StorePixelWidth;
  158. property PixelHeight: Single read FPixelHeight write FPixelHeight stored StorePixelHeight;
  159. end;
  160. TGLSLPostPixelateShader = class(TGLCustomGLSLPostPixelateShader)
  161. published
  162. property PixelWidth;
  163. property PixelHeight;
  164. end;
  165. (* Custom class for GLSLPostPosterizeShader.
  166. A shader that posterize of the entire scene*)
  167. TGLCustomGLSLPostPosterizeShader = class(TGLCustomGLSLShader, IGLPostShader)
  168. private
  169. FGamma : Single;
  170. FNumColors : Single;
  171. // Implementing IGLPostShader.
  172. procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
  173. function GetTextureTarget: TGLTextureTarget;
  174. function StoreGamma: Boolean;
  175. function StoreNumColors: Boolean;
  176. protected
  177. procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
  178. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  179. public
  180. constructor Create(AOwner: TComponent); override;
  181. property Gamma: Single read FGamma write FGamma stored StoreGamma;
  182. property NumColors: Single read FNumColors write FNumColors stored StoreNumColors;
  183. end;
  184. TGLSLPostPosterizeShader = class(TGLCustomGLSLPostPosterizeShader)
  185. published
  186. property Gamma;
  187. property NumColors;
  188. end;
  189. (* Custom class for GLSLPostFrostShader.
  190. A shader that frost of the entire scene *)
  191. TGLCustomGLSLPostFrostShader = class(TGLCustomGLSLShader, IGLPostShader)
  192. private
  193. FRandScale : Single;
  194. FRandFactor : Single;
  195. // Implementing IGLPostShader.
  196. procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
  197. function GetTextureTarget: TGLTextureTarget;
  198. function StoreRandScale: Boolean;
  199. function StoreRandFactor: Boolean;
  200. protected
  201. procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
  202. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  203. public
  204. constructor Create(AOwner: TComponent); override;
  205. property RandScale: Single read FRandScale write FRandScale stored StoreRandScale;
  206. property RandFactor: Single read FRandFactor write FRandFactor stored StoreRandFactor;
  207. end;
  208. TGLSLPostFrostShader = class(TGLCustomGLSLPostFrostShader)
  209. published
  210. property RandScale;
  211. property RandFactor;
  212. end;
  213. (* Custom class for GLSLPostTroubleShader. A shader that trouble of the entire scene. v2
  214. This Shader is experimental it can do smooth the scene or double the scene and it's
  215. depends of PixelX, PixelY and Freq values if they are less than 1 or greater
  216. the effects will be very different *)
  217. TGLCustomGLSLPostTroubleShader = class(TGLCustomGLSLShader, IGLPostShader)
  218. private
  219. FPixelX : Single;
  220. FPixelY : Single;
  221. FFreq : Single;
  222. FMaterialLibrary: TGLAbstractMaterialLibrary;
  223. FNoiseTex : TGLTexture;
  224. FNoiseTexName : TGLLibMaterialName;
  225. // Implementing IGLPostShader.
  226. procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
  227. function GetTextureTarget: TGLTextureTarget;
  228. procedure SetNoiseTexTexture(const Value: TGLTexture);
  229. function GetNoiseTexName: TGLLibMaterialName;
  230. procedure SetNoiseTexName(const Value: TGLLibMaterialName);
  231. function GetMaterialLibrary: TGLAbstractMaterialLibrary;
  232. function StorePixelX: Boolean;
  233. function StorePixelY: Boolean;
  234. function StoreFreq: Boolean;
  235. protected
  236. procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
  237. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  238. procedure SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary); virtual;
  239. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  240. public
  241. constructor Create(AOwner: TComponent); override;
  242. property PixelX: Single read FPixelX write FPixelX stored StorePixelX;
  243. property PixelY: Single read FPixelY write FPixelY stored StorePixelY;
  244. property Freq: Single read FFreq write FFreq stored StoreFreq;
  245. property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
  246. property NoiseTex: TGLTexture read FNoiseTex write SetNoiseTexTexture;
  247. property NoiseTexName: TGLLibMaterialName read GetNoiseTexName write SetNoiseTexName;
  248. end;
  249. TGLSLPostTroubleShader = class(TGLCustomGLSLPostTroubleShader)
  250. published
  251. property PixelX;
  252. property PixelY;
  253. property Freq;
  254. property MaterialLibrary;
  255. property NoiseTexName;
  256. end;
  257. //----------------------------------------------------------------------
  258. implementation
  259. //----------------------------------------------------------------------
  260. //---------------------------------------
  261. // TGLCustomGLSLPostBlurShader
  262. //---------------------------------------
  263. constructor TGLCustomGLSLPostBlurShader.Create(
  264. AOwner: TComponent);
  265. begin
  266. inherited;
  267. with VertexProgram.Code do
  268. begin
  269. Add('varying vec2 vTexCoord; ');
  270. Add(' ');
  271. Add('void main(void) ');
  272. Add('{ ');
  273. Add(' ');
  274. Add(' // Clean up inaccuracies ');
  275. Add(' vec2 Position; ');
  276. Add(' Position.xy = sign(gl_Vertex.xy); ');
  277. Add(' ');
  278. Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
  279. Add(' vTexCoord = Position.xy *.5 + .5; ');
  280. Add(' ');
  281. Add('} ');
  282. end;
  283. with FragmentProgram.Code do
  284. begin
  285. Add('uniform float threshold; ');
  286. Add('uniform vec2 ScreenExtents; ');
  287. Add('uniform sampler2DRect Image; ');
  288. Add(' ');
  289. Add('varying vec2 vTexCoord; ');
  290. Add(' ');
  291. Add('void main() ');
  292. Add('{ ');
  293. Add(' ');
  294. Add(' vec2 samples[8]; ');
  295. Add(' vec2 vTexCoordScr = vTexCoord * ScreenExtents; ');
  296. Add(' ');
  297. Add(' samples[0] = vTexCoordScr + vec2(-1.0, -1.0); ');
  298. Add(' samples[1] = vTexCoordScr + vec2( 0.0, -1.0); ');
  299. Add(' samples[2] = vTexCoordScr + vec2( 1.0, -1.0); ');
  300. Add(' samples[3] = vTexCoordScr + vec2(-1.0, 0.0); ');
  301. Add(' samples[4] = vTexCoordScr + vec2( 1.0, 0.0); ');
  302. Add(' samples[5] = vTexCoordScr + vec2(-1.0, 1.0); ');
  303. Add(' samples[6] = vTexCoordScr + vec2( 0.0, 1.0); ');
  304. Add(' samples[7] = vTexCoordScr + vec2( 1.0, 1.0); ');
  305. Add(' ');
  306. Add(' vec4 sample = texture2DRect(Image, vTexCoordScr); ');
  307. Add(' ');
  308. Add(' // Neighborhood average ');
  309. Add(' vec4 avg = sample; ');
  310. Add(' for (int i = 0; i < 8; i++) ');
  311. Add(' { ');
  312. Add(' avg += texture2DRect(Image, samples[i]); ');
  313. Add(' } ');
  314. Add(' ');
  315. Add(' ');
  316. Add(' avg /= 9.0; ');
  317. Add(' ');
  318. Add(' // If the difference between the average and the sample is ');
  319. Add(' // large, we''ll assume it''s noise. ');
  320. Add(' vec4 diff = abs(sample - avg); ');
  321. Add(' float sel = float(dot(diff, vec4(0.25)) > threshold); ');
  322. Add(' ');
  323. Add(' gl_FragColor = mix(sample, avg, sel); ');
  324. Add('} ');
  325. end;
  326. FThreshold := 0.1;
  327. end;
  328. procedure TGLCustomGLSLPostBlurShader.DoApply(
  329. var rci: TGLRenderContextInfo; Sender: TObject);
  330. begin
  331. GetGLSLProg.UseProgramObject;
  332. GetGLSLProg.Uniform1f['threshold'] := FThreshold;
  333. GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
  334. end;
  335. function TGLCustomGLSLPostBlurShader.DoUnApply(
  336. var rci: TGLRenderContextInfo): Boolean;
  337. begin
  338. rci.GLStates.ActiveTexture := 0;
  339. GetGLSLProg.EndUseProgramObject;
  340. Result := False;
  341. end;
  342. procedure TGLCustomGLSLPostBlurShader.DoUseTempTexture(
  343. const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
  344. begin
  345. Param['Image'].AsCustomTexture[2, TextureTarget] := TempTexture.Handle;
  346. end;
  347. function TGLCustomGLSLPostBlurShader.GetTextureTarget: TGLTextureTarget;
  348. begin
  349. Result := ttTextureRect;
  350. end;
  351. function TGLCustomGLSLPostBlurShader.StoreThreshold: Boolean;
  352. begin
  353. Result := Abs(FThreshold - 0.1) > 0.00001;
  354. end;
  355. //---------------------------------------
  356. // TGLCustomGLSLPostThermalVisionShader
  357. //---------------------------------------
  358. constructor TGLCustomGLSLPostThermalVisionShader.Create(
  359. AOwner: TComponent);
  360. begin
  361. inherited;
  362. with VertexProgram.Code do
  363. begin
  364. Add('varying vec2 vTexCoord; ');
  365. Add(' ');
  366. Add('void main(void) ');
  367. Add('{ ');
  368. Add(' ');
  369. Add(' // Clean up inaccuracies ');
  370. Add(' vec2 Position; ');
  371. Add(' Position.xy = sign(gl_Vertex.xy); ');
  372. Add(' ');
  373. Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
  374. Add(' vTexCoord = Position.xy *.5 + .5; ');
  375. Add(' ');
  376. Add('} ');
  377. end;
  378. with FragmentProgram.Code do
  379. begin
  380. Add('uniform float Threshold; ');
  381. Add('uniform float Intensity; ');
  382. Add('uniform vec2 ScreenExtents; ');
  383. Add('uniform sampler2DRect ScreenTex; ');
  384. Add(' ');
  385. Add('varying vec2 vTexCoord; ');
  386. Add(' ');
  387. Add('void main() ');
  388. Add('{ ');
  389. Add(' vec2 uv = vTexCoord * ScreenExtents; ');
  390. Add(' vec3 tc = vec3(1.0, 0.0, 0.0);');
  391. Add(' vec3 pixcol = texture2DRect(ScreenTex, uv).rgb; ');
  392. Add(' vec3 colors[3];');
  393. Add(' colors[0] = vec3(0.,0.,1.); ');
  394. Add(' colors[1] = vec3(1.,1.,0.); ');
  395. Add(' colors[2] = vec3(1.,0.,0.); ');
  396. Add(' float lum = dot(vec3(0.30, 0.59, 0.11), pixcol.rgb); ');
  397. Add('// float lum = (pixcol.r+pixcol.g+pixcol.b)/3.;');
  398. Add(' tc = (lum < 0.5)? mix(colors[0],colors[1],lum/Threshold): mix(colors[1],colors[2],(lum-Intensity)/Threshold); ');
  399. Add(' gl_FragColor = vec4(tc, 1); ');
  400. Add('} ');
  401. end;
  402. FThreshold := 0.5;
  403. FIntensity := 0.5;
  404. end;
  405. procedure TGLCustomGLSLPostThermalVisionShader.DoApply(
  406. var rci: TGLRenderContextInfo; Sender: TObject);
  407. begin
  408. GetGLSLProg.UseProgramObject;
  409. GetGLSLProg.Uniform1f['Threshold'] := FThreshold;
  410. GetGLSLProg.Uniform1f['Intensity'] := FIntensity;
  411. GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
  412. end;
  413. function TGLCustomGLSLPostThermalVisionShader.DoUnApply(
  414. var rci: TGLRenderContextInfo): Boolean;
  415. begin
  416. rci.GLStates.ActiveTexture := 0;
  417. GetGLSLProg.EndUseProgramObject;
  418. Result := False;
  419. end;
  420. procedure TGLCustomGLSLPostThermalVisionShader.DoUseTempTexture(
  421. const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
  422. begin
  423. Param['ScreenTex'].AsCustomTexture[3, TextureTarget] := TempTexture.Handle;
  424. end;
  425. function TGLCustomGLSLPostThermalVisionShader.GetTextureTarget: TGLTextureTarget;
  426. begin
  427. Result := ttTextureRect; //ttTexture2D;
  428. end;
  429. function TGLCustomGLSLPostThermalVisionShader.StoreThreshold: Boolean;
  430. begin
  431. Result := (Abs(FThreshold) > 0) and (Abs(FThreshold) <= 1.0);
  432. end;
  433. function TGLCustomGLSLPostThermalVisionShader.StoreIntensity: Boolean;
  434. begin
  435. Result := (Abs(FIntensity) >= 0) and (Abs(FIntensity) <= 2.0);
  436. end;
  437. //---------------------------------------
  438. // TGLCustomGLSLPostThermalVisionShader
  439. //---------------------------------------
  440. constructor TGLCustomGLSLPostDreamVisionShader.Create(
  441. AOwner: TComponent);
  442. begin
  443. inherited;
  444. with VertexProgram.Code do
  445. begin
  446. Add('varying vec2 vTexCoord; ');
  447. Add(' ');
  448. Add('void main(void) ');
  449. Add('{ ');
  450. Add(' ');
  451. Add(' // Clean up inaccuracies ');
  452. Add(' vec2 Position; ');
  453. Add(' Position.xy = sign(gl_Vertex.xy); ');
  454. Add(' ');
  455. Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
  456. Add(' vTexCoord = Position.xy *.5 + .5; ');
  457. Add(' ');
  458. Add('} ');
  459. end;
  460. with FragmentProgram.Code do
  461. begin
  462. Add('uniform float Threshold; ');
  463. Add('uniform vec2 ScreenExtents; ');
  464. Add('uniform sampler2DRect ScreenTex; ');
  465. Add(' ');
  466. Add('varying vec2 vTexCoord; ');
  467. Add(' ');
  468. Add('void main() ');
  469. Add('{ ');
  470. Add(' vec2 uv = vTexCoord * ScreenExtents; ');
  471. Add(' vec3 c = texture2DRect(ScreenTex, uv).rgb; ');
  472. Add(' c += texture2DRect(ScreenTex, uv+0.001).rgb; ');
  473. Add(' c += texture2DRect(ScreenTex, uv+0.003).rgb; ');
  474. Add(' c += texture2DRect(ScreenTex, uv+0.005).rgb; ');
  475. Add(' c += texture2DRect(ScreenTex, uv+0.007).rgb; ');
  476. Add(' c += texture2DRect(ScreenTex, uv+0.009).rgb; ');
  477. Add(' c += texture2DRect(ScreenTex, uv+0.011).rgb; ');
  478. Add(' ');
  479. Add(' c += texture2DRect(ScreenTex, uv-0.001).rgb; ');
  480. Add(' c += texture2DRect(ScreenTex, uv-0.003).rgb; ');
  481. Add(' c += texture2DRect(ScreenTex, uv-0.005).rgb; ');
  482. Add(' c += texture2DRect(ScreenTex, uv-0.007).rgb; ');
  483. Add(' c += texture2DRect(ScreenTex, uv-0.009).rgb; ');
  484. Add(' c += texture2DRect(ScreenTex, uv-0.011).rgb; ');
  485. Add(' ');
  486. Add(' c.rgb = vec3((c.r+c.g+c.b)/3.0); ');
  487. Add(' c = c / Threshold; ');
  488. Add(' gl_FragColor = vec4(c,1.0); ');
  489. Add('} ');
  490. end;
  491. FThreshold := 5;
  492. end;
  493. procedure TGLCustomGLSLPostDreamVisionShader.DoApply(
  494. var rci: TGLRenderContextInfo; Sender: TObject);
  495. begin
  496. GetGLSLProg.UseProgramObject;
  497. GetGLSLProg.Uniform1f['Threshold'] := (FThreshold*255)/100;
  498. GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
  499. end;
  500. function TGLCustomGLSLPostDreamVisionShader.DoUnApply(
  501. var rci: TGLRenderContextInfo): Boolean;
  502. begin
  503. rci.GLStates.ActiveTexture := 0;
  504. GetGLSLProg.EndUseProgramObject;
  505. Result := False;
  506. end;
  507. procedure TGLCustomGLSLPostDreamVisionShader.DoUseTempTexture(
  508. const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
  509. begin
  510. Param['ScreenTex'].AsCustomTexture[2, TextureTarget] := TempTexture.Handle;
  511. end;
  512. function TGLCustomGLSLPostDreamVisionShader.GetTextureTarget: TGLTextureTarget;
  513. begin
  514. Result := ttTextureRect; //ttTexture2D;
  515. end;
  516. function TGLCustomGLSLPostDreamVisionShader.StoreThreshold: Boolean;
  517. begin
  518. Result := (Abs(FThreshold) > 0) and (Abs(FThreshold) <= 100);
  519. end;
  520. //---------------------------------------
  521. // TGLCustomGLSLPostThermalVisionShader
  522. //---------------------------------------
  523. constructor TGLCustomGLSLPostNightVisionShader.Create(
  524. AOwner: TComponent);
  525. begin
  526. inherited;
  527. with VertexProgram.Code do
  528. begin
  529. Add('varying vec2 vTexCoord; ');
  530. Add(' ');
  531. Add('void main(void) ');
  532. Add('{ ');
  533. Add(' ');
  534. Add(' // Clean up inaccuracies ');
  535. Add(' vec2 Position; ');
  536. Add(' Position.xy = sign(gl_Vertex.xy); ');
  537. Add(' ');
  538. Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
  539. Add(' vTexCoord = Position.xy *.5 + .5; ');
  540. Add(' ');
  541. Add('} ');
  542. end;
  543. with FragmentProgram.Code do
  544. begin
  545. Add('uniform float luminanceThreshold; ');
  546. Add('uniform float colorAmplification; ');
  547. Add('uniform float elapsedTime; ');
  548. Add('uniform int useMask;');
  549. Add('uniform vec2 ScreenExtents; ');
  550. Add('uniform sampler2D noiseTex; ');
  551. Add('uniform sampler2D maskTex; ');
  552. Add('uniform sampler2DRect ScreenTex; ');
  553. Add(' ');
  554. Add('varying vec2 vTexCoord; ');
  555. Add(' ');
  556. Add('void main () ');
  557. Add('{ ');
  558. Add(' vec2 uv = vTexCoord * ScreenExtents; ');
  559. Add(' vec4 finalColor; ');
  560. Add(' vec2 uvv; ');
  561. Add(' uvv.x = 0.4*sin(elapsedTime*50.0); ');
  562. Add(' uvv.y = 0.4*cos(elapsedTime*50.0); ');
  563. Add(' float m = 1; ');
  564. Add(' if (useMask==1) { m = texture2D(maskTex, vTexCoord.st).r; } '); // Problem Here I don't know how to solve ????
  565. Add(' vec3 n = texture2D(noiseTex,(uv.st*3.5) + uvv).rgb; ');
  566. Add(' vec3 c = texture2DRect(ScreenTex, uv.st+(n.xy*0.005)).rgb; ');
  567. Add(' float lum = dot(vec3(0.30, 0.59, 0.11), c); ');
  568. Add(' if (lum < luminanceThreshold) ');
  569. Add(' c *= colorAmplification; ');
  570. Add(' vec3 visionColor = vec3(0.1, 0.95, 0.2); ');
  571. Add(' finalColor.rgb = (c + (n*0.2)) * visionColor * m; ');
  572. Add(' ');
  573. Add(' gl_FragColor.rgb = finalColor.rgb; ');
  574. Add(' gl_FragColor.a = 1.0; ');
  575. Add('} ');
  576. end;
  577. FLuminanceThreshold := 0.2;
  578. FColorAmplification := 4.0;
  579. FElapsedTime:=0.1;
  580. FUseMask:=0; // Shader not working if we want to use mask
  581. end;
  582. procedure TGLCustomGLSLPostNightVisionShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
  583. begin
  584. GetGLSLProg.UseProgramObject;
  585. param['luminanceThreshold'].AsVector1f := FLuminanceThreshold;
  586. param['colorAmplification'].AsVector1f := FColorAmplification;
  587. param['elapsedTime'].AsVector1f := FElapsedTime;
  588. param['useMask'].AsVector1i := FUseMask;
  589. param['ScreenExtents'].AsVector2f := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
  590. param['noiseTex'].AsTexture2D[1]:= FNoiseTex;
  591. param['maskTex'].AsTexture2D[2]:= FMaskTex;
  592. end;
  593. function TGLCustomGLSLPostNightVisionShader.DoUnApply(
  594. var rci: TGLRenderContextInfo): Boolean;
  595. begin
  596. rci.GLStates.ActiveTexture := 0;
  597. GetGLSLProg.EndUseProgramObject;
  598. Result := False;
  599. end;
  600. procedure TGLCustomGLSLPostNightVisionShader.DoUseTempTexture(
  601. const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
  602. begin
  603. Param['ScreenTex'].AsCustomTexture[7, TextureTarget] := TempTexture.Handle;
  604. end;
  605. function TGLCustomGLSLPostNightVisionShader.GetTextureTarget: TGLTextureTarget;
  606. begin
  607. Result := ttTextureRect; //ttTexture2D;
  608. end;
  609. function TGLCustomGLSLPostNightVisionShader.StoreLuminanceThreshold: Boolean;
  610. begin
  611. Result := Abs(FLuminanceThreshold - 0.1) > 0.00001;
  612. end;
  613. function TGLCustomGLSLPostNightVisionShader.StoreColorAmplification: Boolean;
  614. begin
  615. Result := Abs(FColorAmplification - 0.1) > 0.00001;
  616. end;
  617. procedure TGLCustomGLSLPostNightVisionShader.SetMaskTexTexture(const Value: TGLTexture);
  618. begin
  619. if FMaskTex = Value then Exit;
  620. MaskTex := Value;
  621. NotifyChange(Self)
  622. end;
  623. procedure TGLCustomGLSLPostNightVisionShader.SetNoiseTexTexture(const Value: TGLTexture);
  624. begin
  625. if FNoiseTex = Value then Exit;
  626. NoiseTex := Value;
  627. NotifyChange(Self);
  628. end;
  629. function TGLCustomGLSLPostNightVisionShader.GetNoiseTexName: TGLLibMaterialName;
  630. begin
  631. Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FNoiseTex);
  632. if Result = '' then Result := FNoiseTexName;
  633. end;
  634. procedure TGLCustomGLSLPostNightVisionShader.SetNoiseTexName(const Value: TGLLibMaterialName);
  635. begin
  636. //Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
  637. if FNoiseTexName = Value then Exit;
  638. FNoiseTexName := Value;
  639. FNoiseTex := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FNoiseTexName);
  640. NotifyChange(Self);
  641. end;
  642. function TGLCustomGLSLPostNightVisionShader.GetMaskTexName: TGLLibMaterialName;
  643. begin
  644. Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FMaskTex);
  645. if Result = '' then Result := FMaskTexName;
  646. end;
  647. procedure TGLCustomGLSLPostNightVisionShader.SetMaskTexName(const Value: TGLLibMaterialName);
  648. begin
  649. // Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
  650. if FMaskTexName = Value then Exit;
  651. FMaskTexName := Value;
  652. FMaskTex := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FMaskTexName);
  653. NotifyChange(Self);
  654. end;
  655. function TGLCustomGLSLPostNightVisionShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
  656. begin
  657. Result := FMaterialLibrary;
  658. end;
  659. procedure TGLCustomGLSLPostNightVisionShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
  660. begin
  661. if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
  662. FMaterialLibrary := Value;
  663. if (FMaterialLibrary <> nil)
  664. and (FMaterialLibrary is TGLAbstractMaterialLibrary) then
  665. FMaterialLibrary.FreeNotification(Self);
  666. end;
  667. procedure TGLCustomGLSLPostNightVisionShader.Notification(AComponent: TComponent; Operation: TOperation);
  668. var
  669. Index: Integer;
  670. begin
  671. inherited;
  672. if Operation = opRemove then
  673. if AComponent = FMaterialLibrary then
  674. if FMaterialLibrary <> nil then
  675. begin
  676. // Need to nil the textures that were owned by it
  677. if FNoiseTex <> nil then
  678. begin
  679. Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FNoiseTex);
  680. if Index <> -1 then
  681. SetNoiseTexTexture(nil);
  682. end;
  683. if FMaskTex <> nil then
  684. begin
  685. Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FMaskTex);
  686. if Index <> -1 then
  687. SetMaskTexTexture(nil);
  688. end;
  689. FMaterialLibrary := nil;
  690. end;
  691. end;
  692. //---------------------------------------
  693. // TGLCustomGLSLPostPixelateShader
  694. //---------------------------------------
  695. constructor TGLCustomGLSLPostPixelateShader.Create(
  696. AOwner: TComponent);
  697. begin
  698. inherited;
  699. with VertexProgram.Code do
  700. begin
  701. Add('varying vec2 vTexCoord; ');
  702. Add(' ');
  703. Add('void main(void) ');
  704. Add('{ ');
  705. Add(' ');
  706. Add(' // Clean up inaccuracies ');
  707. Add(' vec2 Position; ');
  708. Add(' Position.xy = sign(gl_Vertex.xy); ');
  709. Add(' ');
  710. Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
  711. Add(' vTexCoord = Position.xy *.5 + .5; ');
  712. Add(' ');
  713. Add('} ');
  714. end;
  715. with FragmentProgram.Code do
  716. begin
  717. Add('uniform float pixel_w; // 8.0 ');
  718. Add('uniform float pixel_h; // 8.0 ');
  719. Add('uniform vec2 ScreenExtents; ');
  720. Add('uniform sampler2DRect ScreenTex; ');
  721. Add(' ');
  722. Add('varying vec2 vTexCoord; ');
  723. Add(' ');
  724. Add('void main() ');
  725. Add('{ ');
  726. Add(' vec2 uv = vTexCoord * ScreenExtents; ');
  727. Add(' vec3 tc = vec3(1.0, 0.0, 0.0); ');
  728. Add(' vec2 coord = vec2(pixel_w*floor(uv.x/pixel_w),pixel_h*floor(uv.y/pixel_h)); ');
  729. Add(' tc = texture2DRect(ScreenTex, coord).rgb; ');
  730. Add(' gl_FragColor = vec4(tc, 1); ');
  731. Add('} ');
  732. end;
  733. FPixelWidth := 8;
  734. FPixelHeight := 12;
  735. end;
  736. procedure TGLCustomGLSLPostPixelateShader.DoApply(
  737. var rci: TGLRenderContextInfo; Sender: TObject);
  738. begin
  739. GetGLSLProg.UseProgramObject;
  740. GetGLSLProg.Uniform1f['pixel_w'] := FPixelWidth;
  741. GetGLSLProg.Uniform1f['pixel_h'] := FPixelHeight;
  742. GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
  743. end;
  744. function TGLCustomGLSLPostPixelateShader.DoUnApply(
  745. var rci: TGLRenderContextInfo): Boolean;
  746. begin
  747. rci.GLStates.ActiveTexture := 0;
  748. GetGLSLProg.EndUseProgramObject;
  749. Result := False;
  750. end;
  751. procedure TGLCustomGLSLPostPixelateShader.DoUseTempTexture(
  752. const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
  753. begin
  754. Param['ScreenTex'].AsCustomTexture[3, TextureTarget] := TempTexture.Handle;
  755. end;
  756. function TGLCustomGLSLPostPixelateShader.GetTextureTarget: TGLTextureTarget;
  757. begin
  758. Result := ttTextureRect; //ttTexture2D;
  759. end;
  760. function TGLCustomGLSLPostPixelateShader.StorePixelWidth: Boolean;
  761. begin
  762. Result := (Abs(FPixelWidth) > 0) and (Abs(FPixelWidth) <= 64);
  763. end;
  764. function TGLCustomGLSLPostPixelateShader.StorePixelHeight: Boolean;
  765. begin
  766. Result := (Abs(FPixelHeight) > 0) and (Abs(FPixelHeight) <= 64);
  767. end;
  768. //---------------------------------------
  769. // TGLCustomGLSLPostPosterizeShader
  770. //---------------------------------------
  771. constructor TGLCustomGLSLPostPosterizeShader.Create(
  772. AOwner: TComponent);
  773. begin
  774. inherited;
  775. with VertexProgram.Code do
  776. begin
  777. Add('varying vec2 vTexCoord; ');
  778. Add(' ');
  779. Add('void main(void) ');
  780. Add('{ ');
  781. Add(' ');
  782. Add(' // Clean up inaccuracies ');
  783. Add(' vec2 Position; ');
  784. Add(' Position.xy = sign(gl_Vertex.xy); ');
  785. Add(' ');
  786. Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
  787. Add(' vTexCoord = Position.xy *.5 + .5; ');
  788. Add(' ');
  789. Add('} ');
  790. end;
  791. with FragmentProgram.Code do
  792. begin
  793. Add('uniform float gamma; // 8.0 ');
  794. Add('uniform float numColors; // 8.0 ');
  795. Add('uniform vec2 ScreenExtents; ');
  796. Add('uniform sampler2DRect ScreenTex; ');
  797. Add(' ');
  798. Add('varying vec2 vTexCoord; ');
  799. Add(' ');
  800. Add('void main() ');
  801. Add('{ ');
  802. Add(' vec2 uv = vTexCoord * ScreenExtents; ');
  803. Add(' vec3 c = texture2DRect(ScreenTex, uv.xy).rgb; ');
  804. Add(' c = pow(c, vec3(gamma, gamma, gamma)); ');
  805. Add(' c = c * numColors; ');
  806. Add(' c = floor(c); ');
  807. Add(' c = c / numColors; ');
  808. Add(' c = pow(c, vec3(1.0/gamma)); ');
  809. Add(' gl_FragColor = vec4(c, 1.0); ');
  810. Add('} ');
  811. end;
  812. FGamma := 0.6;
  813. FNumColors := 8;
  814. end;
  815. procedure TGLCustomGLSLPostPosterizeShader.DoApply(
  816. var rci: TGLRenderContextInfo; Sender: TObject);
  817. begin
  818. GetGLSLProg.UseProgramObject;
  819. GetGLSLProg.Uniform1f['gamma'] := FGamma;
  820. GetGLSLProg.Uniform1f['numColors'] := FNumColors;
  821. GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
  822. end;
  823. function TGLCustomGLSLPostPosterizeShader.DoUnApply(
  824. var rci: TGLRenderContextInfo): Boolean;
  825. begin
  826. rci.GLStates.ActiveTexture := 0;
  827. GetGLSLProg.EndUseProgramObject;
  828. Result := False;
  829. end;
  830. procedure TGLCustomGLSLPostPosterizeShader.DoUseTempTexture(
  831. const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
  832. begin
  833. Param['ScreenTex'].AsCustomTexture[3, TextureTarget] := TempTexture.Handle;
  834. end;
  835. function TGLCustomGLSLPostPosterizeShader.GetTextureTarget: TGLTextureTarget;
  836. begin
  837. Result := ttTextureRect; //ttTexture2D;
  838. end;
  839. function TGLCustomGLSLPostPosterizeShader.StoreGamma: Boolean;
  840. begin
  841. Result := (Abs(FGamma) > 0) and (Abs(FGamma) <= 3.0);
  842. end;
  843. function TGLCustomGLSLPostPosterizeShader.StoreNumColors: Boolean;
  844. begin
  845. Result := (Abs(FNumColors) > 0) and (Abs(FNumColors) <= 255);
  846. end;
  847. //---------------------------------------
  848. // TGLCustomGLSLPostFrostShader
  849. //---------------------------------------
  850. constructor TGLCustomGLSLPostFrostShader.Create(
  851. AOwner: TComponent);
  852. begin
  853. inherited;
  854. with VertexProgram.Code do
  855. begin
  856. Add('varying vec2 vTexCoord; ');
  857. Add(' ');
  858. Add('void main(void) ');
  859. Add('{ ');
  860. Add(' ');
  861. Add(' // Clean up inaccuracies ');
  862. Add(' vec2 Position; ');
  863. Add(' Position.xy = sign(gl_Vertex.xy); ');
  864. Add(' ');
  865. Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
  866. Add(' vTexCoord = Position.xy *.5 + .5; ');
  867. Add(' ');
  868. Add('} ');
  869. end;
  870. with FragmentProgram.Code do
  871. begin
  872. Add('uniform float rnd_scale; // 250 ');
  873. Add('uniform float rnd_factor; // 50 ');
  874. // Add('uniform vec2 v1; ');
  875. // Add('uniform vec2 v2; ');
  876. Add('uniform vec2 ScreenExtents; ');
  877. Add('uniform sampler2DRect ScreenTex; ');
  878. Add(' ');
  879. Add('varying vec2 vTexCoord; ');
  880. Add(' ');
  881. Add('float rand(vec2 co) ');
  882. Add('{ ');
  883. Add(' vec2 v1 = vec2(92.,80.); ');
  884. Add(' vec2 v2 = vec2(41.,62.); ');
  885. Add(' return fract(sin(dot(co.xy ,v1)) + cos(dot(co.xy ,v2)) * rnd_scale); ');
  886. Add('} ');
  887. Add(' ');
  888. Add('void main() ');
  889. Add('{ ');
  890. Add(' vec2 uv = vTexCoord * ScreenExtents; ');
  891. Add(' vec3 tc = vec3(1.0, 0.0, 0.0); ');
  892. Add(' vec2 rnd = vec2(rand(uv.xy),rand(uv.yx)); ');
  893. Add(' tc = texture2DRect(ScreenTex, uv+rnd*rnd_factor).rgb; ');
  894. Add(' gl_FragColor = vec4(tc, 1.0); ');
  895. Add('} ');
  896. end;
  897. FRandScale := 50;
  898. FRandFactor := 50;
  899. end;
  900. procedure TGLCustomGLSLPostFrostShader.DoApply(
  901. var rci: TGLRenderContextInfo; Sender: TObject);
  902. begin
  903. GetGLSLProg.UseProgramObject;
  904. GetGLSLProg.Uniform1f['rnd_scale'] := FRandScale;
  905. GetGLSLProg.Uniform1f['rnd_factor'] := FRandFactor;
  906. GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
  907. end;
  908. function TGLCustomGLSLPostFrostShader.DoUnApply(
  909. var rci: TGLRenderContextInfo): Boolean;
  910. begin
  911. rci.GLStates.ActiveTexture := 0;
  912. GetGLSLProg.EndUseProgramObject;
  913. Result := False;
  914. end;
  915. procedure TGLCustomGLSLPostFrostShader.DoUseTempTexture(
  916. const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
  917. begin
  918. Param['ScreenTex'].AsCustomTexture[3, TextureTarget] := TempTexture.Handle;
  919. end;
  920. function TGLCustomGLSLPostFrostShader.GetTextureTarget: TGLTextureTarget;
  921. begin
  922. Result := ttTextureRect; //ttTexture2D;
  923. end;
  924. function TGLCustomGLSLPostFrostShader.StoreRandScale: Boolean;
  925. begin
  926. Result := (Abs(FRandScale) > 0) and (Abs(FRandScale) <= 1000);
  927. end;
  928. function TGLCustomGLSLPostFrostShader.StoreRandFactor: Boolean;
  929. begin
  930. Result := (Abs(FRandFactor) > 0) and (Abs(FRandFactor) <= 1000);
  931. end;
  932. //---------------------------------------
  933. // TGLCustomGLSLPostTroubleShader
  934. //---------------------------------------
  935. constructor TGLCustomGLSLPostTroubleShader.Create( AOwner: TComponent);
  936. begin
  937. inherited;
  938. with VertexProgram.Code do
  939. begin
  940. Add('varying vec2 vTexCoord; ');
  941. Add(' ');
  942. Add('void main(void) ');
  943. Add('{ ');
  944. Add(' ');
  945. Add(' // Clean up inaccuracies ');
  946. Add(' vec2 Position; ');
  947. Add(' Position.xy = sign(gl_Vertex.xy); ');
  948. Add(' ');
  949. Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
  950. Add(' vTexCoord = Position.xy *.5 + .5; ');
  951. Add(' ');
  952. Add('} ');
  953. end;
  954. with FragmentProgram.Code do
  955. begin
  956. Add('uniform float PixelX; // = 2.0; ');
  957. Add('uniform float PixelY; // = 2.0; ');
  958. Add('uniform float Freq; // = 0.115; ');
  959. Add('uniform vec2 ScreenExtents; ');
  960. Add('uniform sampler2D noiseTex; '); // 1
  961. Add('uniform sampler2DRect ScreenTex; ');
  962. Add(' ');
  963. Add('varying vec2 vTexCoord; ');
  964. Add(' ');
  965. Add('vec4 spline(float x, vec4 c1, vec4 c2, vec4 c3, vec4 c4, vec4 c5, vec4 c6, vec4 c7, vec4 c8, vec4 c9) ');
  966. Add('{ ');
  967. Add(' float w1, w2, w3, w4, w5, w6, w7, w8, w9; ');
  968. Add(' w1 = 0.0; ');
  969. Add(' w2 = 0.0; ');
  970. Add(' w3 = 0.0; ');
  971. Add(' w4 = 0.0; ');
  972. Add(' w5 = 0.0; ');
  973. Add(' w6 = 0.0; ');
  974. Add(' w7 = 0.0; ');
  975. Add(' w8 = 0.0; ');
  976. Add(' w9 = 0.0; ');
  977. Add(' float tmp = x * 8.0; ');
  978. Add(' if (tmp<=1.0) { ');
  979. Add(' w1 = 1.0 - tmp; ');
  980. Add(' w2 = tmp; ');
  981. Add(' } ');
  982. Add(' else if (tmp<=2.0) { ');
  983. Add(' tmp = tmp - 1.0; ');
  984. Add(' w2 = 1.0 - tmp; ');
  985. Add(' w3 = tmp; ');
  986. Add(' } ');
  987. Add(' else if (tmp<=3.0) { ');
  988. Add(' tmp = tmp - 2.0; ');
  989. Add(' w3 = 1.0-tmp; ');
  990. Add(' w4 = tmp; ');
  991. Add(' } ');
  992. Add(' else if (tmp<=4.0) { ');
  993. Add(' tmp = tmp - 3.0; ');
  994. Add(' w4 = 1.0-tmp; ');
  995. Add(' w5 = tmp; ');
  996. Add(' } ');
  997. Add(' else if (tmp<=5.0) { ');
  998. Add(' tmp = tmp - 4.0; ');
  999. Add(' w5 = 1.0-tmp; ');
  1000. Add(' w6 = tmp; ');
  1001. Add(' } ');
  1002. Add(' else if (tmp<=6.0) { ');
  1003. Add(' tmp = tmp - 5.0; ');
  1004. Add(' w6 = 1.0-tmp; ');
  1005. Add(' w7 = tmp; ');
  1006. Add(' } ');
  1007. Add(' else if (tmp<=7.0) { ');
  1008. Add(' tmp = tmp - 6.0; ');
  1009. Add(' w7 = 1.0 - tmp; ');
  1010. Add(' w8 = tmp; ');
  1011. Add(' } ');
  1012. Add(' else ');
  1013. Add(' { ');
  1014. Add(' //tmp = saturate(tmp - 7.0); ');
  1015. // http://www.ozone3d.net/blogs/lab/20080709/saturate-function-in-glsl/
  1016. Add(' tmp = clamp(tmp - 7.0, 0.0, 1.0); ');
  1017. Add(' w8 = 1.0-tmp; ');
  1018. Add(' w9 = tmp; ');
  1019. Add(' } ');
  1020. Add(' return w1*c1 + w2*c2 + w3*c3 + w4*c4 + w5*c5 + w6*c6 + w7*c7 + w8*c8 + w9*c9; ');
  1021. Add('} ');
  1022. Add(' ');
  1023. Add('vec3 NOISE2D(vec2 p) ');
  1024. Add(' { return texture2D(noiseTex,p).xyz; } ');
  1025. Add(' ');
  1026. Add('void main() ');
  1027. Add('{ ');
  1028. Add(' vec2 uv = vTexCoord * ScreenExtents; ');
  1029. Add(' vec3 tc = vec3(1.0, 0.0, 0.0); ');
  1030. Add(' float DeltaX = PixelX; ');
  1031. Add(' float DeltaY = PixelY; ');
  1032. Add(' vec2 ox = vec2(DeltaX,0.0); ');
  1033. Add(' vec2 oy = vec2(0.0,DeltaY); ');
  1034. Add(' vec2 PP = uv - oy; ');
  1035. Add(' vec4 C00 = texture2DRect(ScreenTex,PP - ox); ');
  1036. Add(' vec4 C01 = texture2DRect(ScreenTex,PP); ');
  1037. Add(' vec4 C02 = texture2DRect(ScreenTex,PP + ox); ');
  1038. Add(' PP = uv; ');
  1039. Add(' vec4 C10 = texture2DRect(ScreenTex,PP - ox); ');
  1040. Add(' vec4 C11 = texture2DRect(ScreenTex,PP); ');
  1041. Add(' vec4 C12 = texture2DRect(ScreenTex,PP + ox); ');
  1042. Add(' PP = uv + oy; ');
  1043. Add(' vec4 C20 = texture2DRect(ScreenTex,PP - ox); ');
  1044. Add(' vec4 C21 = texture2DRect(ScreenTex,PP); ');
  1045. Add(' vec4 C22 = texture2DRect(ScreenTex,PP + ox); ');
  1046. Add(' float n = NOISE2D(Freq*uv).x; ');
  1047. Add(' n = mod(n, 0.111111)/0.111111; ');
  1048. Add(' vec4 result = spline(n,C00,C01,C02,C10,C11,C12,C20,C21,C22); ');
  1049. Add(' tc = result.rgb; ');
  1050. Add(' gl_FragColor = vec4(tc, 1.0); ');
  1051. Add('} ');
  1052. end;
  1053. FPixelX := 0.5;
  1054. FPixelY := 0.5;
  1055. FFreq:= 2.115;
  1056. end;
  1057. procedure TGLCustomGLSLPostTroubleShader.DoApply(
  1058. var rci: TGLRenderContextInfo; Sender: TObject);
  1059. begin
  1060. GetGLSLProg.UseProgramObject;
  1061. GetGLSLProg.Uniform1f['PixelX'] := FPixelX;
  1062. GetGLSLProg.Uniform1f['PixelY'] := FPixelY;
  1063. GetGLSLProg.Uniform1f['Freq'] := FFreq;
  1064. GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
  1065. param['noiseTex'].AsTexture2D[1]:= FNoiseTex;
  1066. end;
  1067. function TGLCustomGLSLPostTroubleShader.DoUnApply(
  1068. var rci: TGLRenderContextInfo): Boolean;
  1069. begin
  1070. rci.GLStates.ActiveTexture := 0;
  1071. GetGLSLProg.EndUseProgramObject;
  1072. Result := False;
  1073. end;
  1074. procedure TGLCustomGLSLPostTroubleShader.DoUseTempTexture(
  1075. const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
  1076. begin
  1077. Param['ScreenTex'].AsCustomTexture[5, TextureTarget] := TempTexture.Handle;
  1078. end;
  1079. function TGLCustomGLSLPostTroubleShader.GetTextureTarget: TGLTextureTarget;
  1080. begin
  1081. Result := ttTextureRect; //ttTexture2D;
  1082. end;
  1083. function TGLCustomGLSLPostTroubleShader.StorePixelX: Boolean;
  1084. begin
  1085. Result := (Abs(FPixelX) > 0) and (Abs(FPixelX) <= 1000);
  1086. end;
  1087. function TGLCustomGLSLPostTroubleShader.StorePixelY: Boolean;
  1088. begin
  1089. Result := (Abs(FPixelY) > 0) and (Abs(FPixelY) <= 1000);
  1090. end;
  1091. function TGLCustomGLSLPostTroubleShader.StoreFreq: Boolean;
  1092. begin
  1093. Result := (Abs(FPixelY) > 0) and (Abs(FPixelY) <= 5.0);
  1094. end;
  1095. procedure TGLCustomGLSLPostTroubleShader.SetNoiseTexTexture(const Value: TGLTexture);
  1096. begin
  1097. if FNoiseTex = Value then Exit;
  1098. NoiseTex := Value;
  1099. NotifyChange(Self);
  1100. end;
  1101. function TGLCustomGLSLPostTroubleShader.GetNoiseTexName: TGLLibMaterialName;
  1102. begin
  1103. Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FNoiseTex);
  1104. if Result = '' then Result := FNoiseTexName;
  1105. end;
  1106. procedure TGLCustomGLSLPostTroubleShader.SetNoiseTexName(const Value: TGLLibMaterialName);
  1107. begin
  1108. //Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
  1109. if FNoiseTexName = Value then Exit;
  1110. FNoiseTexName := Value;
  1111. FNoiseTex := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FNoiseTexName);
  1112. NotifyChange(Self);
  1113. end;
  1114. function TGLCustomGLSLPostTroubleShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
  1115. begin
  1116. Result := FMaterialLibrary;
  1117. end;
  1118. procedure TGLCustomGLSLPostTroubleShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
  1119. begin
  1120. if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
  1121. FMaterialLibrary := Value;
  1122. if (FMaterialLibrary <> nil)
  1123. and (FMaterialLibrary is TGLAbstractMaterialLibrary) then
  1124. FMaterialLibrary.FreeNotification(Self);
  1125. end;
  1126. procedure TGLCustomGLSLPostTroubleShader.Notification(AComponent: TComponent; Operation: TOperation);
  1127. var
  1128. Index: Integer;
  1129. begin
  1130. inherited;
  1131. if Operation = opRemove then
  1132. if AComponent = FMaterialLibrary then
  1133. if FMaterialLibrary <> nil then
  1134. begin
  1135. // Need to nil the textures that were owned by it
  1136. if FNoiseTex <> nil then
  1137. begin
  1138. Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FNoiseTex);
  1139. if Index <> -1 then
  1140. SetNoiseTexTexture(nil);
  1141. end;
  1142. FMaterialLibrary := nil;
  1143. end;
  1144. end;
  1145. end.