2
// This unit is part of the GLScene Engine https://github.com/glscene
5
Post shaders that simulate shader visions for a mask or the entire scene.
8
04/11/15 - PW - Combined all post shaders into GLSLPostShaders unit
9
01/11/15 - J.Delauney - Initial versions for
10
GLSLPostThermalVisionShader
11
GLSLPostDreamVisionShader
12
GLSLPostNightVisionShader
13
GLSLPostPixelateShader
14
GLSLPostPosterizeShader
17
05/04/07 - DaStr - Initial version for GLSLPostBlurShader
18
based on RenderMonkey demo
29
GLTexture, GLScene, GLVectorGeometry, GLContext, GLMaterial,
30
GLSLShader, GLCustomShader, GLRenderContextInfo, GLTextureFormat,
33
//TGLCustomGLSLPostBlurShader
35
{ Custom class for GLSLPostBlurShader.
36
A shader that blurs the entire scene }
38
TGLCustomGLSLPostBlurShader = class(TGLCustomGLSLShader, IGLPostShader)
42
// Implementing IGLPostShader.
43
procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;
44
TextureTarget: TGLTextureTarget);
45
function GetTextureTarget: TGLTextureTarget;
46
function StoreThreshold: Boolean;
48
procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
49
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
51
constructor Create(AOwner: TComponent); override;
53
property Threshold: Single read FThreshold write FThreshold stored StoreThreshold;
56
TGLSLPostBlurShader = class(TGLCustomGLSLPostBlurShader)
62
//TGLCustomGLSLPostThermalVisionShader
64
{ Custom class for GLSLPostThermalVisionShader.
65
A Shader that simulate a thermal vision of the entire scene }
68
{ A shader that simulate a Thermal Vision of the entire scene}
69
TGLCustomGLSLPostThermalVisionShader = class(TGLCustomGLSLShader, IGLPostShader)
75
// Implementing IGLPostShader.
76
procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
77
function GetTextureTarget: TGLTextureTarget;
79
function StoreThreshold: Boolean;
80
function StoreIntensity: Boolean;
83
procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
84
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
86
constructor Create(AOwner: TComponent); override;
88
property Threshold: Single read FThreshold write FThreshold stored StoreThreshold;
89
property Intensity: Single read FIntensity write FIntensity stored StoreIntensity;
92
TGLSLPostThermalVisionShader = class(TGLCustomGLSLPostThermalVisionShader)
99
//TGLCustomGLSLPostDreamVisionShader
101
{ Custom class for GLSLPostDreamVisionShader.
102
A shader that simulate a grayscale threshold vision (aka dream) of the entire scene}
104
TGLCustomGLSLPostDreamVisionShader = class(TGLCustomGLSLShader, IGLPostShader)
107
FThreshold : Single; // In percent 0..100;
109
// Implementing IGLPostShader.
110
procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
111
function GetTextureTarget: TGLTextureTarget;
113
function StoreThreshold: Boolean;
116
procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
117
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
119
constructor Create(AOwner: TComponent); override;
121
property Threshold: Single read FThreshold write FThreshold stored StoreThreshold;
124
TGLSLPostDreamVisionShader = class(TGLCustomGLSLPostDreamVisionShader)
130
//TGLCustomGLSLPostNightVisionShader
132
{ Custom class for GLSLPostNightVisionShader.
133
A shader that simulate a Night Vision of the scene throw a mask if enabled,
134
or of the entire scene}
137
TGLCustomGLSLPostNightVisionShader = class(TGLCustomGLSLShader, IGLPostShader)
139
FMaterialLibrary: TGLAbstractMaterialLibrary;
141
FLuminanceThreshold: Single;
142
FColorAmplification:Single;
143
FElapsedTime : Single;
145
FNoiseTex : TGLTexture;
146
FMaskTex : TGLTexture;
147
FNoiseTexName : TGLLibMaterialName;
148
FMaskTexName : TGLLibMaterialName;
150
// Implementing IGLPostShader.
151
procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
152
function GetTextureTarget: TGLTextureTarget;
154
function StoreLuminanceThreshold: Boolean;
155
function StoreColorAmplification: Boolean;
157
procedure SetMaskTexTexture(const Value: TGLTexture);
158
procedure SetNoiseTexTexture(const Value: TGLTexture);
160
function GetNoiseTexName: TGLLibMaterialName;
161
procedure SetNoiseTexName(const Value: TGLLibMaterialName);
162
function GetMaskTexName: TGLLibMaterialName;
163
procedure SetMaskTexName(const Value: TGLLibMaterialName);
165
function GetMaterialLibrary: TGLAbstractMaterialLibrary;
168
procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
169
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
171
procedure SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary); virtual;
172
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
175
constructor Create(AOwner: TComponent); override;
177
property LuminanceThreshold: Single read FLuminanceThreshold write FLuminanceThreshold stored StoreLuminanceThreshold;
178
property ColorAmplification: Single read FColorAmplification write FColorAmplification stored StoreColorAmplification;
179
property ElapsedTime: Single read FElapsedTime write FElapsedTime stored false;
181
property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
182
property NoiseTex: TGLTexture read FNoiseTex write SetNoiseTexTexture;
183
property NoiseTexName: TGLLibMaterialName read GetNoiseTexName write SetNoiseTexName;
184
property MaskTex: TGLTexture read FMaskTex write SetMaskTexTexture;
185
property MaskTexName: TGLLibMaterialName read GetMaskTexName write SetMaskTexName;
186
property UseMask : Integer read FUseMask write FUseMask;
189
TGLSLPostNightVisionShader = class(TGLCustomGLSLPostNightVisionShader)
191
property LuminanceThreshold;
192
property ColorAmplification;
193
property ElapsedTime;
194
property MaterialLibrary;
195
property NoiseTexName;
196
property MaskTexName;
200
//TGLCustomGLSLPostPixelateShader
202
{ Custom class for GLSLPostPixelateShader.
203
A shader that pixelate of the entire scene}
205
TGLCustomGLSLPostPixelateShader = class(TGLCustomGLSLShader, IGLPostShader)
208
FPixelWidth : Single;
209
FPixelHeight : Single;
211
// Implementing IGLPostShader.
212
procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
213
function GetTextureTarget: TGLTextureTarget;
215
function StorePixelWidth: Boolean;
216
function StorePixelHeight: Boolean;
219
procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
220
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
222
constructor Create(AOwner: TComponent); override;
224
property PixelWidth: Single read FPixelWidth write FPixelWidth stored StorePixelWidth;
225
property PixelHeight: Single read FPixelHeight write FPixelHeight stored StorePixelHeight;
228
TGLSLPostPixelateShader = class(TGLCustomGLSLPostPixelateShader)
231
property PixelHeight;
234
//TGLCustomGLSLPostPosterizeShader
236
{ Custom class for GLSLPostPosterizeShader.
237
A shader that posterize of the entire scene}
239
TGLCustomGLSLPostPosterizeShader = class(TGLCustomGLSLShader, IGLPostShader)
245
// Implementing IGLPostShader.
246
procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
247
function GetTextureTarget: TGLTextureTarget;
249
function StoreGamma: Boolean;
250
function StoreNumColors: Boolean;
253
procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
254
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
256
constructor Create(AOwner: TComponent); override;
258
property Gamma: Single read FGamma write FGamma stored StoreGamma;
259
property NumColors: Single read FNumColors write FNumColors stored StoreNumColors;
262
TGLSLPostPosterizeShader = class(TGLCustomGLSLPostPosterizeShader)
268
//TGLCustomGLSLPostFrostShader
270
{ Custom class for GLSLPostFrostShader.
271
A shader that frost of the entire scene}
273
TGLCustomGLSLPostFrostShader = class(TGLCustomGLSLShader, IGLPostShader)
277
FRandFactor : Single;
279
// Implementing IGLPostShader.
280
procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
281
function GetTextureTarget: TGLTextureTarget;
283
function StoreRandScale: Boolean;
284
function StoreRandFactor: Boolean;
287
procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
288
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
290
constructor Create(AOwner: TComponent); override;
292
property RandScale: Single read FRandScale write FRandScale stored StoreRandScale;
293
property RandFactor: Single read FRandFactor write FRandFactor stored StoreRandFactor;
296
TGLSLPostFrostShader = class(TGLCustomGLSLPostFrostShader)
302
//TGLCustomGLSLPostTroubleShader
304
{ Custom class for GLSLPostTroubleShader.
305
A shader that trouble of the entire scene. v2
306
This Shader is experimental it can do smooth the scene or double the scene and it's
307
depends of PixelX, PixelY and Freq values if they are less than 1 or greater
308
the effects will be very different}
310
TGLCustomGLSLPostTroubleShader = class(TGLCustomGLSLShader, IGLPostShader)
317
FMaterialLibrary: TGLAbstractMaterialLibrary;
318
FNoiseTex : TGLTexture;
319
FNoiseTexName : TGLLibMaterialName;
321
// Implementing IGLPostShader.
322
procedure DoUseTempTexture(const TempTexture: TGLTextureHandle;TextureTarget: TGLTextureTarget);
323
function GetTextureTarget: TGLTextureTarget;
325
procedure SetNoiseTexTexture(const Value: TGLTexture);
327
function GetNoiseTexName: TGLLibMaterialName;
328
procedure SetNoiseTexName(const Value: TGLLibMaterialName);
331
function GetMaterialLibrary: TGLAbstractMaterialLibrary;
333
function StorePixelX: Boolean;
334
function StorePixelY: Boolean;
335
function StoreFreq: Boolean;
338
procedure DoApply(var rci: TGLRenderContextInfo; Sender: TObject); override;
339
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
341
procedure SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary); virtual;
342
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
344
constructor Create(AOwner: TComponent); override;
346
property PixelX: Single read FPixelX write FPixelX stored StorePixelX;
347
property PixelY: Single read FPixelY write FPixelY stored StorePixelY;
348
property Freq: Single read FFreq write FFreq stored StoreFreq;
350
property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
351
property NoiseTex: TGLTexture read FNoiseTex write SetNoiseTexTexture;
352
property NoiseTexName: TGLLibMaterialName read GetNoiseTexName write SetNoiseTexName;
355
TGLSLPostTroubleShader = class(TGLCustomGLSLPostTroubleShader)
360
property MaterialLibrary;
361
property NoiseTexName;
364
//----------------------------------------------------------------------
365
//----------------------------------------------------------------------
366
//----------------------------------------------------------------------
368
//----------------------------------------------------------------------
369
//----------------------------------------------------------------------
370
//----------------------------------------------------------------------
372
{ TGLCustomGLSLPostBlurShader }
374
constructor TGLCustomGLSLPostBlurShader.Create(
378
with VertexProgram.Code do
380
Add('varying vec2 vTexCoord; ');
382
Add('void main(void) ');
385
Add(' // Clean up inaccuracies ');
386
Add(' vec2 Position; ');
387
Add(' Position.xy = sign(gl_Vertex.xy); ');
389
Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
390
Add(' vTexCoord = Position.xy *.5 + .5; ');
395
with FragmentProgram.Code do
397
Add('uniform float threshold; ');
398
Add('uniform vec2 ScreenExtents; ');
399
Add('uniform sampler2DRect Image; ');
401
Add('varying vec2 vTexCoord; ');
406
Add(' vec2 samples[8]; ');
407
Add(' vec2 vTexCoordScr = vTexCoord * ScreenExtents; ');
409
Add(' samples[0] = vTexCoordScr + vec2(-1.0, -1.0); ');
410
Add(' samples[1] = vTexCoordScr + vec2( 0.0, -1.0); ');
411
Add(' samples[2] = vTexCoordScr + vec2( 1.0, -1.0); ');
412
Add(' samples[3] = vTexCoordScr + vec2(-1.0, 0.0); ');
413
Add(' samples[4] = vTexCoordScr + vec2( 1.0, 0.0); ');
414
Add(' samples[5] = vTexCoordScr + vec2(-1.0, 1.0); ');
415
Add(' samples[6] = vTexCoordScr + vec2( 0.0, 1.0); ');
416
Add(' samples[7] = vTexCoordScr + vec2( 1.0, 1.0); ');
418
Add(' vec4 sample = texture2DRect(Image, vTexCoordScr); ');
420
Add(' // Neighborhood average ');
421
Add(' vec4 avg = sample; ');
422
Add(' for (int i = 0; i < 8; i++) ');
424
Add(' avg += texture2DRect(Image, samples[i]); ');
428
Add(' avg /= 9.0; ');
430
Add(' // If the difference between the average and the sample is ');
431
Add(' // large, we''ll assume it''s noise. ');
432
Add(' vec4 diff = abs(sample - avg); ');
433
Add(' float sel = float(dot(diff, vec4(0.25)) > threshold); ');
435
Add(' gl_FragColor = mix(sample, avg, sel); ');
441
procedure TGLCustomGLSLPostBlurShader.DoApply(
442
var rci: TGLRenderContextInfo; Sender: TObject);
444
GetGLSLProg.UseProgramObject;
445
GetGLSLProg.Uniform1f['threshold'] := FThreshold;
446
GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
449
function TGLCustomGLSLPostBlurShader.DoUnApply(
450
var rci: TGLRenderContextInfo): Boolean;
452
rci.GLStates.ActiveTexture := 0;
453
GetGLSLProg.EndUseProgramObject;
457
procedure TGLCustomGLSLPostBlurShader.DoUseTempTexture(
458
const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
460
Param['Image'].AsCustomTexture[2, TextureTarget] := TempTexture.Handle;
463
function TGLCustomGLSLPostBlurShader.GetTextureTarget: TGLTextureTarget;
465
Result := ttTextureRect;
468
function TGLCustomGLSLPostBlurShader.StoreThreshold: Boolean;
470
Result := Abs(FThreshold - 0.1) > 0.00001;
473
{ TGLCustomGLSLPostThermalVisionShader }
475
constructor TGLCustomGLSLPostThermalVisionShader.Create(
479
with VertexProgram.Code do
481
Add('varying vec2 vTexCoord; ');
483
Add('void main(void) ');
486
Add(' // Clean up inaccuracies ');
487
Add(' vec2 Position; ');
488
Add(' Position.xy = sign(gl_Vertex.xy); ');
490
Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
491
Add(' vTexCoord = Position.xy *.5 + .5; ');
496
with FragmentProgram.Code do
498
Add('uniform float Threshold; ');
499
Add('uniform float Intensity; ');
500
Add('uniform vec2 ScreenExtents; ');
501
Add('uniform sampler2DRect ScreenTex; ');
503
Add('varying vec2 vTexCoord; ');
507
Add(' vec2 uv = vTexCoord * ScreenExtents; ');
508
Add(' vec3 tc = vec3(1.0, 0.0, 0.0);');
509
Add(' vec3 pixcol = texture2DRect(ScreenTex, uv).rgb; ');
510
Add(' vec3 colors[3];');
511
Add(' colors[0] = vec3(0.,0.,1.); ');
512
Add(' colors[1] = vec3(1.,1.,0.); ');
513
Add(' colors[2] = vec3(1.,0.,0.); ');
514
Add(' float lum = dot(vec3(0.30, 0.59, 0.11), pixcol.rgb); ');
515
Add('// float lum = (pixcol.r+pixcol.g+pixcol.b)/3.;');
516
Add(' tc = (lum < 0.5)? mix(colors[0],colors[1],lum/Threshold): mix(colors[1],colors[2],(lum-Intensity)/Threshold); ');
517
Add(' gl_FragColor = vec4(tc, 1); ');
526
procedure TGLCustomGLSLPostThermalVisionShader.DoApply(
527
var rci: TGLRenderContextInfo; Sender: TObject);
529
GetGLSLProg.UseProgramObject;
530
GetGLSLProg.Uniform1f['Threshold'] := FThreshold;
531
GetGLSLProg.Uniform1f['Intensity'] := FIntensity;
532
GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
536
function TGLCustomGLSLPostThermalVisionShader.DoUnApply(
537
var rci: TGLRenderContextInfo): Boolean;
539
rci.GLStates.ActiveTexture := 0;
540
GetGLSLProg.EndUseProgramObject;
544
procedure TGLCustomGLSLPostThermalVisionShader.DoUseTempTexture(
545
const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
547
Param['ScreenTex'].AsCustomTexture[3, TextureTarget] := TempTexture.Handle;
550
function TGLCustomGLSLPostThermalVisionShader.GetTextureTarget: TGLTextureTarget;
552
Result := ttTextureRect; //ttTexture2D;
555
function TGLCustomGLSLPostThermalVisionShader.StoreThreshold: Boolean;
557
Result := (Abs(FThreshold) > 0) and (Abs(FThreshold) <= 1.0);
560
function TGLCustomGLSLPostThermalVisionShader.StoreIntensity: Boolean;
562
Result := (Abs(FIntensity) >= 0) and (Abs(FIntensity) <= 2.0);
565
{ TGLCustomGLSLPostThermalVisionShader }
567
constructor TGLCustomGLSLPostDreamVisionShader.Create(
571
with VertexProgram.Code do
573
Add('varying vec2 vTexCoord; ');
575
Add('void main(void) ');
578
Add(' // Clean up inaccuracies ');
579
Add(' vec2 Position; ');
580
Add(' Position.xy = sign(gl_Vertex.xy); ');
582
Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
583
Add(' vTexCoord = Position.xy *.5 + .5; ');
588
with FragmentProgram.Code do
590
Add('uniform float Threshold; ');
591
Add('uniform vec2 ScreenExtents; ');
592
Add('uniform sampler2DRect ScreenTex; ');
594
Add('varying vec2 vTexCoord; ');
598
Add(' vec2 uv = vTexCoord * ScreenExtents; ');
599
Add(' vec3 c = texture2DRect(ScreenTex, uv).rgb; ');
600
Add(' c += texture2DRect(ScreenTex, uv+0.001).rgb; ');
601
Add(' c += texture2DRect(ScreenTex, uv+0.003).rgb; ');
602
Add(' c += texture2DRect(ScreenTex, uv+0.005).rgb; ');
603
Add(' c += texture2DRect(ScreenTex, uv+0.007).rgb; ');
604
Add(' c += texture2DRect(ScreenTex, uv+0.009).rgb; ');
605
Add(' c += texture2DRect(ScreenTex, uv+0.011).rgb; ');
607
Add(' c += texture2DRect(ScreenTex, uv-0.001).rgb; ');
608
Add(' c += texture2DRect(ScreenTex, uv-0.003).rgb; ');
609
Add(' c += texture2DRect(ScreenTex, uv-0.005).rgb; ');
610
Add(' c += texture2DRect(ScreenTex, uv-0.007).rgb; ');
611
Add(' c += texture2DRect(ScreenTex, uv-0.009).rgb; ');
612
Add(' c += texture2DRect(ScreenTex, uv-0.011).rgb; ');
614
Add(' c.rgb = vec3((c.r+c.g+c.b)/3.0); ');
615
Add(' c = c / Threshold; ');
616
Add(' gl_FragColor = vec4(c,1.0); ');
624
procedure TGLCustomGLSLPostDreamVisionShader.DoApply(
625
var rci: TGLRenderContextInfo; Sender: TObject);
627
GetGLSLProg.UseProgramObject;
628
GetGLSLProg.Uniform1f['Threshold'] := (FThreshold*255)/100;
629
GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
633
function TGLCustomGLSLPostDreamVisionShader.DoUnApply(
634
var rci: TGLRenderContextInfo): Boolean;
636
rci.GLStates.ActiveTexture := 0;
637
GetGLSLProg.EndUseProgramObject;
641
procedure TGLCustomGLSLPostDreamVisionShader.DoUseTempTexture(
642
const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
644
Param['ScreenTex'].AsCustomTexture[2, TextureTarget] := TempTexture.Handle;
647
function TGLCustomGLSLPostDreamVisionShader.GetTextureTarget: TGLTextureTarget;
649
Result := ttTextureRect; //ttTexture2D;
652
function TGLCustomGLSLPostDreamVisionShader.StoreThreshold: Boolean;
654
Result := (Abs(FThreshold) > 0) and (Abs(FThreshold) <= 100);
657
{ TGLCustomGLSLPostThermalVisionShader }
659
constructor TGLCustomGLSLPostNightVisionShader.Create(
663
with VertexProgram.Code do
665
Add('varying vec2 vTexCoord; ');
667
Add('void main(void) ');
670
Add(' // Clean up inaccuracies ');
671
Add(' vec2 Position; ');
672
Add(' Position.xy = sign(gl_Vertex.xy); ');
674
Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
675
Add(' vTexCoord = Position.xy *.5 + .5; ');
680
with FragmentProgram.Code do
682
Add('uniform float luminanceThreshold; ');
683
Add('uniform float colorAmplification; ');
684
Add('uniform float elapsedTime; ');
685
Add('uniform int useMask;');
686
Add('uniform vec2 ScreenExtents; ');
687
Add('uniform sampler2D noiseTex; ');
688
Add('uniform sampler2D maskTex; ');
689
Add('uniform sampler2DRect ScreenTex; ');
691
Add('varying vec2 vTexCoord; ');
693
Add('void main () ');
695
Add(' vec2 uv = vTexCoord * ScreenExtents; ');
696
Add(' vec4 finalColor; ');
698
Add(' uvv.x = 0.4*sin(elapsedTime*50.0); ');
699
Add(' uvv.y = 0.4*cos(elapsedTime*50.0); ');
700
Add(' float m = 1; ');
701
Add(' if (useMask==1) { m = texture2D(maskTex, vTexCoord.st).r; } '); // Problem Here I don't know how to solve ????
702
Add(' vec3 n = texture2D(noiseTex,(uv.st*3.5) + uvv).rgb; ');
703
Add(' vec3 c = texture2DRect(ScreenTex, uv.st+(n.xy*0.005)).rgb; ');
704
Add(' float lum = dot(vec3(0.30, 0.59, 0.11), c); ');
705
Add(' if (lum < luminanceThreshold) ');
706
Add(' c *= colorAmplification; ');
707
Add(' vec3 visionColor = vec3(0.1, 0.95, 0.2); ');
708
Add(' finalColor.rgb = (c + (n*0.2)) * visionColor * m; ');
710
Add(' gl_FragColor.rgb = finalColor.rgb; ');
711
Add(' gl_FragColor.a = 1.0; ');
716
FLuminanceThreshold := 0.2;
717
FColorAmplification := 4.0;
719
FUseMask:=0; // Shader not working if we want to use mask
723
procedure TGLCustomGLSLPostNightVisionShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
726
GetGLSLProg.UseProgramObject;
727
param['luminanceThreshold'].AsVector1f := FLuminanceThreshold;
728
param['colorAmplification'].AsVector1f := FColorAmplification;
729
param['elapsedTime'].AsVector1f := FElapsedTime;
730
param['useMask'].AsVector1i := FUseMask;
731
param['ScreenExtents'].AsVector2f := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
732
param['noiseTex'].AsTexture2D[1]:= FNoiseTex;
733
param['maskTex'].AsTexture2D[2]:= FMaskTex;
736
function TGLCustomGLSLPostNightVisionShader.DoUnApply(
737
var rci: TGLRenderContextInfo): Boolean;
739
rci.GLStates.ActiveTexture := 0;
740
GetGLSLProg.EndUseProgramObject;
744
procedure TGLCustomGLSLPostNightVisionShader.DoUseTempTexture(
745
const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
747
Param['ScreenTex'].AsCustomTexture[7, TextureTarget] := TempTexture.Handle;
750
function TGLCustomGLSLPostNightVisionShader.GetTextureTarget: TGLTextureTarget;
752
Result := ttTextureRect; //ttTexture2D;
756
function TGLCustomGLSLPostNightVisionShader.StoreLuminanceThreshold: Boolean;
758
Result := Abs(FLuminanceThreshold - 0.1) > 0.00001;
761
function TGLCustomGLSLPostNightVisionShader.StoreColorAmplification: Boolean;
763
Result := Abs(FColorAmplification - 0.1) > 0.00001;
767
procedure TGLCustomGLSLPostNightVisionShader.SetMaskTexTexture(const Value: TGLTexture);
769
if FMaskTex = Value then Exit;
774
procedure TGLCustomGLSLPostNightVisionShader.SetNoiseTexTexture(const Value: TGLTexture);
776
if FNoiseTex = Value then Exit;
781
function TGLCustomGLSLPostNightVisionShader.GetNoiseTexName: TGLLibMaterialName;
783
Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FNoiseTex);
784
if Result = '' then Result := FNoiseTexName;
787
procedure TGLCustomGLSLPostNightVisionShader.SetNoiseTexName(const Value: TGLLibMaterialName);
789
//Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
790
if FNoiseTexName = Value then Exit;
791
FNoiseTexName := Value;
792
FNoiseTex := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FNoiseTexName);
796
function TGLCustomGLSLPostNightVisionShader.GetMaskTexName: TGLLibMaterialName;
798
Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FMaskTex);
799
if Result = '' then Result := FMaskTexName;
802
procedure TGLCustomGLSLPostNightVisionShader.SetMaskTexName(const Value: TGLLibMaterialName);
804
// Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
805
if FMaskTexName = Value then Exit;
806
FMaskTexName := Value;
808
FMaskTex := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FMaskTexName);
812
function TGLCustomGLSLPostNightVisionShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
814
Result := FMaterialLibrary;
817
procedure TGLCustomGLSLPostNightVisionShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
819
if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
820
FMaterialLibrary := Value;
821
if (FMaterialLibrary <> nil)
822
and (FMaterialLibrary is TGLAbstractMaterialLibrary) then
823
FMaterialLibrary.FreeNotification(Self);
826
procedure TGLCustomGLSLPostNightVisionShader.Notification(AComponent: TComponent; Operation: TOperation);
831
if Operation = opRemove then
832
if AComponent = FMaterialLibrary then
833
if FMaterialLibrary <> nil then
835
// Need to nil the textures that were owned by it
836
if FNoiseTex <> nil then
838
Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FNoiseTex);
840
SetNoiseTexTexture(nil);
843
if FMaskTex <> nil then
845
Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FMaskTex);
847
SetMaskTexTexture(nil);
850
FMaterialLibrary := nil;
854
{ TGLCustomGLSLPostPixelateShader }
856
constructor TGLCustomGLSLPostPixelateShader.Create(
860
with VertexProgram.Code do
862
Add('varying vec2 vTexCoord; ');
864
Add('void main(void) ');
867
Add(' // Clean up inaccuracies ');
868
Add(' vec2 Position; ');
869
Add(' Position.xy = sign(gl_Vertex.xy); ');
871
Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
872
Add(' vTexCoord = Position.xy *.5 + .5; ');
877
with FragmentProgram.Code do
879
Add('uniform float pixel_w; // 8.0 ');
880
Add('uniform float pixel_h; // 8.0 ');
881
Add('uniform vec2 ScreenExtents; ');
882
Add('uniform sampler2DRect ScreenTex; ');
884
Add('varying vec2 vTexCoord; ');
888
Add(' vec2 uv = vTexCoord * ScreenExtents; ');
889
Add(' vec3 tc = vec3(1.0, 0.0, 0.0); ');
890
Add(' vec2 coord = vec2(pixel_w*floor(uv.x/pixel_w),pixel_h*floor(uv.y/pixel_h)); ');
891
Add(' tc = texture2DRect(ScreenTex, coord).rgb; ');
892
Add(' gl_FragColor = vec4(tc, 1); ');
901
procedure TGLCustomGLSLPostPixelateShader.DoApply(
902
var rci: TGLRenderContextInfo; Sender: TObject);
904
GetGLSLProg.UseProgramObject;
905
GetGLSLProg.Uniform1f['pixel_w'] := FPixelWidth;
906
GetGLSLProg.Uniform1f['pixel_h'] := FPixelHeight;
907
GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
911
function TGLCustomGLSLPostPixelateShader.DoUnApply(
912
var rci: TGLRenderContextInfo): Boolean;
914
rci.GLStates.ActiveTexture := 0;
915
GetGLSLProg.EndUseProgramObject;
919
procedure TGLCustomGLSLPostPixelateShader.DoUseTempTexture(
920
const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
922
Param['ScreenTex'].AsCustomTexture[3, TextureTarget] := TempTexture.Handle;
925
function TGLCustomGLSLPostPixelateShader.GetTextureTarget: TGLTextureTarget;
927
Result := ttTextureRect; //ttTexture2D;
930
function TGLCustomGLSLPostPixelateShader.StorePixelWidth: Boolean;
932
Result := (Abs(FPixelWidth) > 0) and (Abs(FPixelWidth) <= 64);
935
function TGLCustomGLSLPostPixelateShader.StorePixelHeight: Boolean;
937
Result := (Abs(FPixelHeight) > 0) and (Abs(FPixelHeight) <= 64);
940
{ TGLCustomGLSLPostPosterizeShader }
942
constructor TGLCustomGLSLPostPosterizeShader.Create(
946
with VertexProgram.Code do
948
Add('varying vec2 vTexCoord; ');
950
Add('void main(void) ');
953
Add(' // Clean up inaccuracies ');
954
Add(' vec2 Position; ');
955
Add(' Position.xy = sign(gl_Vertex.xy); ');
957
Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
958
Add(' vTexCoord = Position.xy *.5 + .5; ');
963
with FragmentProgram.Code do
965
Add('uniform float gamma; // 8.0 ');
966
Add('uniform float numColors; // 8.0 ');
967
Add('uniform vec2 ScreenExtents; ');
968
Add('uniform sampler2DRect ScreenTex; ');
970
Add('varying vec2 vTexCoord; ');
974
Add(' vec2 uv = vTexCoord * ScreenExtents; ');
975
Add(' vec3 c = texture2DRect(ScreenTex, uv.xy).rgb; ');
976
Add(' c = pow(c, vec3(gamma, gamma, gamma)); ');
977
Add(' c = c * numColors; ');
978
Add(' c = floor(c); ');
979
Add(' c = c / numColors; ');
980
Add(' c = pow(c, vec3(1.0/gamma)); ');
981
Add(' gl_FragColor = vec4(c, 1.0); ');
990
procedure TGLCustomGLSLPostPosterizeShader.DoApply(
991
var rci: TGLRenderContextInfo; Sender: TObject);
993
GetGLSLProg.UseProgramObject;
994
GetGLSLProg.Uniform1f['gamma'] := FGamma;
995
GetGLSLProg.Uniform1f['numColors'] := FNumColors;
996
GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
1000
function TGLCustomGLSLPostPosterizeShader.DoUnApply(
1001
var rci: TGLRenderContextInfo): Boolean;
1003
rci.GLStates.ActiveTexture := 0;
1004
GetGLSLProg.EndUseProgramObject;
1008
procedure TGLCustomGLSLPostPosterizeShader.DoUseTempTexture(
1009
const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
1011
Param['ScreenTex'].AsCustomTexture[3, TextureTarget] := TempTexture.Handle;
1014
function TGLCustomGLSLPostPosterizeShader.GetTextureTarget: TGLTextureTarget;
1016
Result := ttTextureRect; //ttTexture2D;
1019
function TGLCustomGLSLPostPosterizeShader.StoreGamma: Boolean;
1021
Result := (Abs(FGamma) > 0) and (Abs(FGamma) <= 3.0);
1024
function TGLCustomGLSLPostPosterizeShader.StoreNumColors: Boolean;
1026
Result := (Abs(FNumColors) > 0) and (Abs(FNumColors) <= 255);
1029
{ TGLCustomGLSLPostFrostShader }
1031
constructor TGLCustomGLSLPostFrostShader.Create(
1032
AOwner: TComponent);
1035
with VertexProgram.Code do
1037
Add('varying vec2 vTexCoord; ');
1039
Add('void main(void) ');
1042
Add(' // Clean up inaccuracies ');
1043
Add(' vec2 Position; ');
1044
Add(' Position.xy = sign(gl_Vertex.xy); ');
1046
Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
1047
Add(' vTexCoord = Position.xy *.5 + .5; ');
1052
with FragmentProgram.Code do
1054
Add('uniform float rnd_scale; // 250 ');
1055
Add('uniform float rnd_factor; // 50 ');
1056
// Add('uniform vec2 v1; ');
1057
// Add('uniform vec2 v2; ');
1058
Add('uniform vec2 ScreenExtents; ');
1059
Add('uniform sampler2DRect ScreenTex; ');
1061
Add('varying vec2 vTexCoord; ');
1063
Add('float rand(vec2 co) ');
1065
Add(' vec2 v1 = vec2(92.,80.); ');
1066
Add(' vec2 v2 = vec2(41.,62.); ');
1067
Add(' return fract(sin(dot(co.xy ,v1)) + cos(dot(co.xy ,v2)) * rnd_scale); ');
1070
Add('void main() ');
1072
Add(' vec2 uv = vTexCoord * ScreenExtents; ');
1073
Add(' vec3 tc = vec3(1.0, 0.0, 0.0); ');
1074
Add(' vec2 rnd = vec2(rand(uv.xy),rand(uv.yx)); ');
1075
Add(' tc = texture2DRect(ScreenTex, uv+rnd*rnd_factor).rgb; ');
1076
Add(' gl_FragColor = vec4(tc, 1.0); ');
1085
procedure TGLCustomGLSLPostFrostShader.DoApply(
1086
var rci: TGLRenderContextInfo; Sender: TObject);
1088
GetGLSLProg.UseProgramObject;
1089
GetGLSLProg.Uniform1f['rnd_scale'] := FRandScale;
1090
GetGLSLProg.Uniform1f['rnd_factor'] := FRandFactor;
1091
GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
1095
function TGLCustomGLSLPostFrostShader.DoUnApply(
1096
var rci: TGLRenderContextInfo): Boolean;
1098
rci.GLStates.ActiveTexture := 0;
1099
GetGLSLProg.EndUseProgramObject;
1103
procedure TGLCustomGLSLPostFrostShader.DoUseTempTexture(
1104
const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
1106
Param['ScreenTex'].AsCustomTexture[3, TextureTarget] := TempTexture.Handle;
1109
function TGLCustomGLSLPostFrostShader.GetTextureTarget: TGLTextureTarget;
1111
Result := ttTextureRect; //ttTexture2D;
1114
function TGLCustomGLSLPostFrostShader.StoreRandScale: Boolean;
1116
Result := (Abs(FRandScale) > 0) and (Abs(FRandScale) <= 1000);
1119
function TGLCustomGLSLPostFrostShader.StoreRandFactor: Boolean;
1121
Result := (Abs(FRandFactor) > 0) and (Abs(FRandFactor) <= 1000);
1124
{ TGLCustomGLSLPostTroubleShader }
1126
constructor TGLCustomGLSLPostTroubleShader.Create( AOwner: TComponent);
1129
with VertexProgram.Code do
1131
Add('varying vec2 vTexCoord; ');
1133
Add('void main(void) ');
1136
Add(' // Clean up inaccuracies ');
1137
Add(' vec2 Position; ');
1138
Add(' Position.xy = sign(gl_Vertex.xy); ');
1140
Add(' gl_Position = vec4(Position.xy, 0.0, 1.0); ');
1141
Add(' vTexCoord = Position.xy *.5 + .5; ');
1146
with FragmentProgram.Code do
1148
Add('uniform float PixelX; // = 2.0; ');
1149
Add('uniform float PixelY; // = 2.0; ');
1150
Add('uniform float Freq; // = 0.115; ');
1151
Add('uniform vec2 ScreenExtents; ');
1152
Add('uniform sampler2D noiseTex; '); // 1
1153
Add('uniform sampler2DRect ScreenTex; ');
1155
Add('varying vec2 vTexCoord; ');
1157
Add('vec4 spline(float x, vec4 c1, vec4 c2, vec4 c3, vec4 c4, vec4 c5, vec4 c6, vec4 c7, vec4 c8, vec4 c9) ');
1159
Add(' float w1, w2, w3, w4, w5, w6, w7, w8, w9; ');
1169
Add(' float tmp = x * 8.0; ');
1170
Add(' if (tmp<=1.0) { ');
1171
Add(' w1 = 1.0 - tmp; ');
1174
Add(' else if (tmp<=2.0) { ');
1175
Add(' tmp = tmp - 1.0; ');
1176
Add(' w2 = 1.0 - tmp; ');
1179
Add(' else if (tmp<=3.0) { ');
1180
Add(' tmp = tmp - 2.0; ');
1181
Add(' w3 = 1.0-tmp; ');
1184
Add(' else if (tmp<=4.0) { ');
1185
Add(' tmp = tmp - 3.0; ');
1186
Add(' w4 = 1.0-tmp; ');
1189
Add(' else if (tmp<=5.0) { ');
1190
Add(' tmp = tmp - 4.0; ');
1191
Add(' w5 = 1.0-tmp; ');
1194
Add(' else if (tmp<=6.0) { ');
1195
Add(' tmp = tmp - 5.0; ');
1196
Add(' w6 = 1.0-tmp; ');
1199
Add(' else if (tmp<=7.0) { ');
1200
Add(' tmp = tmp - 6.0; ');
1201
Add(' w7 = 1.0 - tmp; ');
1206
Add(' //tmp = saturate(tmp - 7.0); ');
1207
// http://www.ozone3d.net/blogs/lab/20080709/saturate-function-in-glsl/
1208
Add(' tmp = clamp(tmp - 7.0, 0.0, 1.0); ');
1209
Add(' w8 = 1.0-tmp; ');
1212
Add(' return w1*c1 + w2*c2 + w3*c3 + w4*c4 + w5*c5 + w6*c6 + w7*c7 + w8*c8 + w9*c9; ');
1215
Add('vec3 NOISE2D(vec2 p) ');
1216
Add(' { return texture2D(noiseTex,p).xyz; } ');
1218
Add('void main() ');
1220
Add(' vec2 uv = vTexCoord * ScreenExtents; ');
1221
Add(' vec3 tc = vec3(1.0, 0.0, 0.0); ');
1222
Add(' float DeltaX = PixelX; ');
1223
Add(' float DeltaY = PixelY; ');
1224
Add(' vec2 ox = vec2(DeltaX,0.0); ');
1225
Add(' vec2 oy = vec2(0.0,DeltaY); ');
1226
Add(' vec2 PP = uv - oy; ');
1227
Add(' vec4 C00 = texture2DRect(ScreenTex,PP - ox); ');
1228
Add(' vec4 C01 = texture2DRect(ScreenTex,PP); ');
1229
Add(' vec4 C02 = texture2DRect(ScreenTex,PP + ox); ');
1231
Add(' vec4 C10 = texture2DRect(ScreenTex,PP - ox); ');
1232
Add(' vec4 C11 = texture2DRect(ScreenTex,PP); ');
1233
Add(' vec4 C12 = texture2DRect(ScreenTex,PP + ox); ');
1234
Add(' PP = uv + oy; ');
1235
Add(' vec4 C20 = texture2DRect(ScreenTex,PP - ox); ');
1236
Add(' vec4 C21 = texture2DRect(ScreenTex,PP); ');
1237
Add(' vec4 C22 = texture2DRect(ScreenTex,PP + ox); ');
1238
Add(' float n = NOISE2D(Freq*uv).x; ');
1239
Add(' n = mod(n, 0.111111)/0.111111; ');
1240
Add(' vec4 result = spline(n,C00,C01,C02,C10,C11,C12,C20,C21,C22); ');
1241
Add(' tc = result.rgb; ');
1242
Add(' gl_FragColor = vec4(tc, 1.0); ');
1252
procedure TGLCustomGLSLPostTroubleShader.DoApply(
1253
var rci: TGLRenderContextInfo; Sender: TObject);
1255
GetGLSLProg.UseProgramObject;
1256
GetGLSLProg.Uniform1f['PixelX'] := FPixelX;
1257
GetGLSLProg.Uniform1f['PixelY'] := FPixelY;
1258
GetGLSLProg.Uniform1f['Freq'] := FFreq;
1259
GetGLSLProg.Uniform2f['ScreenExtents'] := Vector2fMake(rci.viewPortSize.cx, rci.viewPortSize.cy);
1261
param['noiseTex'].AsTexture2D[1]:= FNoiseTex;
1265
function TGLCustomGLSLPostTroubleShader.DoUnApply(
1266
var rci: TGLRenderContextInfo): Boolean;
1268
rci.GLStates.ActiveTexture := 0;
1269
GetGLSLProg.EndUseProgramObject;
1273
procedure TGLCustomGLSLPostTroubleShader.DoUseTempTexture(
1274
const TempTexture: TGLTextureHandle; TextureTarget: TGLTextureTarget);
1276
Param['ScreenTex'].AsCustomTexture[5, TextureTarget] := TempTexture.Handle;
1279
function TGLCustomGLSLPostTroubleShader.GetTextureTarget: TGLTextureTarget;
1281
Result := ttTextureRect; //ttTexture2D;
1284
function TGLCustomGLSLPostTroubleShader.StorePixelX: Boolean;
1286
Result := (Abs(FPixelX) > 0) and (Abs(FPixelX) <= 1000);
1289
function TGLCustomGLSLPostTroubleShader.StorePixelY: Boolean;
1291
Result := (Abs(FPixelY) > 0) and (Abs(FPixelY) <= 1000);
1294
function TGLCustomGLSLPostTroubleShader.StoreFreq: Boolean;
1296
Result := (Abs(FPixelY) > 0) and (Abs(FPixelY) <= 5.0);
1299
procedure TGLCustomGLSLPostTroubleShader.SetNoiseTexTexture(const Value: TGLTexture);
1301
if FNoiseTex = Value then Exit;
1306
function TGLCustomGLSLPostTroubleShader.GetNoiseTexName: TGLLibMaterialName;
1308
Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FNoiseTex);
1309
if Result = '' then Result := FNoiseTexName;
1312
procedure TGLCustomGLSLPostTroubleShader.SetNoiseTexName(const Value: TGLLibMaterialName);
1314
//Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
1315
if FNoiseTexName = Value then Exit;
1316
FNoiseTexName := Value;
1317
FNoiseTex := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FNoiseTexName);
1321
function TGLCustomGLSLPostTroubleShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
1323
Result := FMaterialLibrary;
1326
procedure TGLCustomGLSLPostTroubleShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
1328
if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
1329
FMaterialLibrary := Value;
1330
if (FMaterialLibrary <> nil)
1331
and (FMaterialLibrary is TGLAbstractMaterialLibrary) then
1332
FMaterialLibrary.FreeNotification(Self);
1335
procedure TGLCustomGLSLPostTroubleShader.Notification(AComponent: TComponent; Operation: TOperation);
1340
if Operation = opRemove then
1341
if AComponent = FMaterialLibrary then
1342
if FMaterialLibrary <> nil then
1344
// Need to nil the textures that were owned by it
1345
if FNoiseTex <> nil then
1347
Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FNoiseTex);
1349
SetNoiseTexTexture(nil);
1352
FMaterialLibrary := nil;