GLSL.PostShaders.pas 41 KB

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