LZScene

Форк
0
/
GLSLErosionShader.pas 
449 строк · 15.5 Кб
1
//
2
// This unit is part of the GLScene Engine https://github.com/glscene
3
//
4
{
5
   Erosion shader Erode surface object and render with Anisotropic Specular Reflection
6

7
   At this time one light source is supported
8

9
    History :  
10
     08/12/15 - J.Delauney - Improved and Made compatible with the latest SVN version of GLScene
11
     02/11/06 - Da Stranger - Creation
12
}
13
unit GLSLErosionShader;
14

15
interface
16

17
{$I GLScene.inc}
18

19
uses
20
  Classes,
21
   
22
  GLScene, GLCrossPlatform, GLBaseClasses, GLState, OpenGLTokens, OpenGL1x, GLContext, GLRenderContextInfo,
23
  GLCoordinates, GLVectorGeometry, GLVectorTypes,
24
  GLTextureFormat,GLColor, GLTexture, GLMaterial,
25
  GLSLShader, GLCustomShader;
26

27
//TGLCustomGLSLSimpleErosionShader
28
//
29
{ Custom class for GLSLSimpleErosionShader.
30
 A shader that Erode surface object }
31
Type
32
  TGLCustomGLSLSimpleErosionShader = class(TGLCustomGLSLShader)
33
  private
34

35

36
    FMaterialLibrary: TGLAbstractMaterialLibrary;
37

38
    FMainTex  : TGLTexture;
39
    FNoiseTex : TGLTexture;
40
    FErosionTex : TGLTexture;
41

42
    FMainTexName   : TGLLibMaterialName;
43
    FNoiseTexName  : TGLLibMaterialName;
44
    FErosionTexName  : TGLLibMaterialName;
45

46
    FErosionScale: Single;
47
    FErosionFactor: Single;
48
    FIntensityFactor1: Single;
49
    FIntensityFactor2: Single;
50

51
    FSpecularColor : TGLColor;
52
    FAmbientColor : TGLColor;
53
    FAmbientFactor : Single;
54
    FDiffuseFactor : Single;
55
    FSpecularFactor : Single;
56
    FSpecularRoughness : Single;
57
    FAnisotropicRoughness : Single;
58

59
    function GetMaterialLibrary: TGLAbstractMaterialLibrary;
60

61
    procedure SetMainTexTexture(const Value: TGLTexture);
62
    procedure SetNoiseTexTexture(const Value: TGLTexture);
63
    procedure SetErosionTexTexture(const Value: TGLTexture);
64

65
    function GetMainTexName: TGLLibMaterialName;
66
    procedure SetMainTexName(const Value: TGLLibMaterialName);
67
    function GetNoiseTexName: TGLLibMaterialName;
68
    procedure SetNoiseTexName(const Value: TGLLibMaterialName);
69
    function GetErosionTexName: TGLLibMaterialName;
70
    procedure SetErosionTexName(const Value: TGLLibMaterialName);
71

72
    procedure SetAmbientColor(AValue: TGLColor);
73
    procedure SetSpecularColor(AValue: TGLColor);
74

75
  protected
76
    procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
77
    function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
78

79
    procedure SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary); virtual;
80
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
81
  public
82
    constructor Create(AOwner : TComponent); override;
83
    destructor Destroy; override;
84

85
//    property Color1: TGLColor read FColor1;
86
//    property Color2: TGLColor read FColor2;
87

88
    property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
89
    property MainTexture: TGLTexture read FMainTex write SetMainTexTexture;
90
    property MainTextureName: TGLLibMaterialName read GetMainTexName write SetMainTexName;
91
    property NoiseTexture: TGLTexture read FNoiseTex write SetNoiseTexTexture;
92
    property NoiseTextureName: TGLLibMaterialName read GetNoiseTexName write SetNoiseTexName;
93
    property ErosionTexture: TGLTexture read FErosionTex write SetErosionTexTexture;
94
    property ErosionTextureName: TGLLibMaterialName read GetErosionTexName write SetErosionTexName;
95

96
    property ErosionFactor: Single read FErosionFactor write FErosionFactor;
97
    property ErosionScale: Single read FErosionFactor write FErosionFactor;
98
    property IntensityFactor1: Single read FIntensityFactor1 write FIntensityFactor1;
99
    property IntensityFactor2: Single read FIntensityFactor2 write FIntensityFactor2;
100

101
    property SpecularColor : TGLColor Read FSpecularColor Write setSpecularColor;
102
    property AmbientColor : TGLColor Read FAmbientColor Write setAmbientColor;
103
    property AmbientFactor : Single Read FAmbientFactor Write FAmbientFactor;
104
    property DiffuseFactor : Single Read FDiffuseFactor Write FDiffuseFactor;
105
    property SpecularFactor : Single Read FSpecularFactor Write FSpecularFactor;
106
    property SpecularRoughness : Single Read FSpecularRoughness  Write FSpecularRoughness;
107
    property AnisotropicRoughness : Single Read FAnisotropicRoughness Write FAnisotropicRoughness;
108

109
  end;
110

111
  TGLSLSimpleErosionShader = class(TGLCustomGLSLSimpleErosionShader)
112
  published
113
//    property Color1;
114
//    property Color2;
115

116
    property MaterialLibrary;
117

118
    property MainTexture;
119
    property MainTextureName;
120
    property NoiseTexture;
121
    property NoiseTextureName;
122
    property ErosionTexture;
123
    property ErosionTextureName;
124

125
    property ErosionScale;
126
    property ErosionFactor;
127
    property IntensityFactor1;
128
    property IntensityFactor2;
129

130
    property SpecularColor;
131
    property AmbientColor;
132
    property AmbientFactor;
133
    property DiffuseFactor;
134
    property SpecularFactor;
135
    property SpecularRoughness;
136
    property AnisotropicRoughness;
137

138
  end;
139

140
implementation
141

142

143

144
{ TGLCustomGLSLSimpleErosionShader }
145

146
constructor TGLCustomGLSLSimpleErosionShader.Create(AOwner: TComponent);
147
begin
148
  inherited;
149
  with VertexProgram.Code do
150
  begin
151

152
    Add('uniform float Scale; ');
153

154
    Add('varying vec3 normal; ');
155
    Add('varying vec2 vTexCoord; ');
156
    Add('varying vec3 lightVec; ');
157
    Add('varying vec3 viewVec; ');
158
    Add('varying vec3 Position; ');
159

160
    Add(' ');
161
    Add('void main(void) { ');
162
   // Add('  mat4 mWorld = gl_ModelViewMatrix; ');
163
    Add('  vec3 Normal = gl_Normal; ');
164
    Add('  vec4 lightPos = gl_LightSource[0].position;');
165
    Add('  vec4 vert =  gl_ModelViewMatrix * gl_Vertex; ');
166
    Add('  normal = gl_NormalMatrix * gl_Normal; ');
167

168
    Add('  Position       = vec3(gl_Vertex)*Scale; ');
169
    Add('  vTexCoord = gl_MultiTexCoord0; ');
170
    Add('  lightVec = vec3(lightPos - vert); ');
171
    Add('  viewVec = -vec3(vert); ');
172
    Add('  gl_Position    = ftransform(); ');
173
    Add('} ');
174
  end;
175

176
  with FragmentProgram.Code do
177
  begin
178

179
    Add('uniform float ErosionFactor; ');
180
    Add('uniform float IntensityFactor1; ');
181
    Add('uniform float IntensityFactor2; ');
182

183
    Add('uniform sampler2D MainTexture; ');
184
    Add('uniform sampler2D Noise2d; ');
185
    Add('uniform sampler2D ErosionTexture; ');
186

187
    Add('uniform vec4  SpecularColor; ');
188
    Add('uniform vec4  AmbientColor; ');
189
    Add('uniform float DiffuseIntensity; ');
190
    Add('uniform float AmbientIntensity; ');
191
    Add('uniform float SpecularIntensity; ');
192
    Add('uniform float SpecularRoughness; ');
193
    Add('uniform float AnisoRoughness; ');
194

195
    Add('varying vec3 normal; ');
196
    Add('varying vec2 vTexCoord; ');
197
    Add('varying vec3 lightVec; ');
198
    Add('varying vec3 viewVec; ');
199
    Add('varying vec3 Position; ');
200
    Add(' ');
201
    Add('void main (void) ');
202
    Add('{ ');
203
    Add('  vec3 offset     = vec3(- ErosionFactor, - ErosionFactor + 0.06, - ErosionFactor * 0.92); ');
204
    Add('  vec4 DiffuseColor;    ');
205

206
    Add('  vec4 Color1 = texture2D(MainTexture,vTexCoord); ');
207
    Add('  vec4 Color2 = texture2D(ErosionTexture,vTexCoord); ');
208

209
    Add('  // Compute noise ');
210
    Add('  vec3 noiseCoord = Position.xyz + offset; ');
211
    Add('  vec4 noiseVec   = texture2D(Noise2d, noiseCoord.xy); ');
212
    Add('  float intensity = (abs(noiseVec[0] - 0.25) + ');
213
    Add('                     abs(noiseVec[1] - 0.125) + ');
214
    Add('                     abs(noiseVec[2] - 0.0625) + ');
215
    Add('                     abs(noiseVec[3] - 0.03125)); ');
216
    Add('  // continue noise evaluation');
217
    Add('  intensity = IntensityFactor1 * (noiseVec.x + noiseVec.y+ noiseVec.z + noiseVec.w); ');
218
    Add('  intensity = IntensityFactor2 * abs(2.0 * intensity -1.0); ');
219

220
    Add('  // discard pixels in a psuedo-random fashion (noise) ');
221
    Add('  if (intensity < fract(0.5 - offset.x - offset.y - offset.z)) discard; ');
222

223
    Add('  // color fragments different colors using noise ');
224
    Add('  clamp(intensity, 0.0, 1.0); ');
225
    Add('  Color2.a =1.0-intensity; ');
226
    Add('  Color1.a =1.0; ');
227
    Add('  DiffuseColor = mix(Color2, Color1, intensity); ');
228
    Add('  DiffuseColor.a = intensity; ');
229

230
    Add('  // Anisotropic Specular Lighting Reflection ');
231
    // Anisotropic Specular Reflection
232
    // This  is useful for depicting surfaces
233
    // such as velvet or brushed metal,
234
    // it allows you to stretch the highlight along a
235
    // SpecDirection vector (in object space)
236
    // add  new var and replace the follow line
237
    // vec3 T = cross(norm,V) by vec3 T = cross(norm,normalize(SpecDirection));
238

239
    Add('  vec3 norm = normalize(normal); ');
240
    Add('  vec3 L = normalize(lightVec); ');
241
    Add('  vec3 V = normalize(viewVec); ');
242
    Add('  vec3 halfAngle = normalize(L + V); ');
243
    Add('  vec3 T = cross(norm,V);  ');
244

245
    Add('  float NdotL = dot(L, norm); ');
246
    Add('  float NdotH = clamp(dot(halfAngle, norm), 0.0, 1.0); ');
247

248
    Add('  // "Half-Lambert" technique for more pleasing diffuse term ');
249
    Add('  float diffuse = 0.5 * NdotL + 0.5; ');
250
    Add('  float specular = pow(NdotH,1.0/SpecularRoughness); '); //54
251
    Add('  // Heidrich-Seidel anisotropic distribution ');
252
    Add('  float ldott = dot(L,T); ');
253
    Add('  float vdott = dot(V,T); ');
254
    Add('  float aniso = pow(sin(ldott)*sin(vdott) + cos(ldott)*cos(vdott),1.0/AnisoRoughness); ');
255

256
    Add(' vec3 FinalColour = AmbientColor*AmbientIntensity + ');
257
    Add('                         DiffuseColor*diffuse*DiffuseIntensity + ');
258
    Add('                         SpecularColor*aniso*specular*SpecularIntensity; ');
259

260

261
    Add('  gl_FragColor = vec4(FinalColour,intensity); ');
262
    Add('} '); 
263
  end;
264

265
  //setup initial parameters
266

267
  FAmbientColor := TGLColor.Create(self);
268
  FAmbientColor.SetColor(0.2,0.2,0.2,1.0);
269
  FSpecularColor := TGLColor.Create(self);
270
  FSpecularColor.SetColor(0.75,0.75,0.75,1.0);
271
  FAmbientFactor  := 0.8;
272
  FDiffuseFactor  :=0.9;
273
  FSpecularFactor :=0.8;
274
  FSpecularRoughness :=0.45;
275
  FAnisotropicRoughness :=0.35;
276

277
  FErosionScale     := 0.03;
278
  FErosionFactor    := 0.35;
279
  FIntensityFactor1 := 0.75;
280
  FIntensityFactor2 := 1.95;
281
end;
282

283
destructor TGLCustomGLSLSimpleErosionShader.Destroy;
284
begin
285
  FAmbientColor.Free;
286
  FSpecularColor.Free;
287
  inherited;
288
end;
289

290
procedure TGLCustomGLSLSimpleErosionShader.DoApply(var rci : TGLRenderContextInfo; Sender : TObject);
291
begin
292
  GetGLSLProg.UseProgramObject;
293

294
  param['AmbientColor'].AsVector4f := FAmbientColor.Color;
295
  param['SpecularColor'].AsVector4f := FSpecularColor.Color;
296
  param['AmbientIntensity'].AsVector1f := FAmbientFactor;
297
  param['DiffuseIntensity'].AsVector1f := FDiffuseFactor;
298
  param['SpecularIntensity'].AsVector1f := FSpecularFactor;
299
  param['SpecularRoughness'].AsVector1f := FSpecularRoughness;
300
  param['AnisoRoughness'].AsVector1f := FAnisotropicRoughness;
301

302

303
  param['ErosionFactor'].AsVector1f := FErosionFactor;
304
  param['IntensityFactor1'].AsVector1f := FIntensityFactor1;
305
  param['IntensityFactor2'].AsVector1f := FIntensityFactor2;
306
  param['Scale'].AsVector1f := FErosionScale;
307

308
  param['MainTexture'].AsTexture2D[0] := FMainTex;
309
  param['Noise2d'].AsTexture2D[1] := FNoiseTex;
310
  param['ErosionTexture'].AsTexture2D[2] := FErosionTex;
311
 // GetGLSLProg.UniformTextureHandle['Noise2d', 1, GL_TEXTURE_2D] := FNoiseTexture.Handle;
312
end;
313

314
function TGLCustomGLSLSimpleErosionShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
315
begin
316
  GetGLSLProg.EndUseProgramObject;
317
  //gl.PopAttrib;
318
  Result := False;
319
end;
320

321
function TGLCustomGLSLSimpleErosionShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
322
begin
323
  Result := FMaterialLibrary;
324
end;
325

326
procedure TGLCustomGLSLSimpleErosionShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
327
begin
328
  if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
329
  FMaterialLibrary := Value;
330
  if (FMaterialLibrary <> nil)
331
    and (FMaterialLibrary is TGLAbstractMaterialLibrary) then
332
      FMaterialLibrary.FreeNotification(Self);
333
end;
334

335
procedure TGLCustomGLSLSimpleErosionShader.SetMainTexTexture(const Value: TGLTexture);
336
begin
337
  if FMainTex = Value then Exit;
338
  FMainTex := Value;
339
  NotifyChange(Self)
340
end;
341

342
procedure TGLCustomGLSLSimpleErosionShader.SetNoiseTexTexture(const Value: TGLTexture);
343
begin
344
  if FNoiseTex = Value then Exit;
345
  FNoiseTex := Value;
346
  NotifyChange(Self);
347
end;
348

349
procedure TGLCustomGLSLSimpleErosionShader.SetErosionTexTexture(const Value: TGLTexture);
350
begin
351
  if FErosionTex = Value then Exit;
352
  FErosionTex := Value;
353
  NotifyChange(Self);
354
end;
355

356
function TGLCustomGLSLSimpleErosionShader.GetNoiseTexName: TGLLibMaterialName;
357
begin
358
  Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FNoiseTex);
359
  if Result = '' then Result := FNoiseTexName;
360
end;
361

362
procedure TGLCustomGLSLSimpleErosionShader.SetNoiseTexName(const Value: TGLLibMaterialName);
363
begin
364
  //Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
365
  if FNoiseTexName = Value then Exit;
366
  FNoiseTexName  := Value;
367
  FNoiseTex := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FNoiseTexName);
368
  NotifyChange(Self);
369
end;
370

371
function TGLCustomGLSLSimpleErosionShader.GetMainTexName: TGLLibMaterialName;
372
begin
373
  Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FMainTex);
374
  if Result = '' then Result := FMainTexName;
375
end;
376

377
procedure TGLCustomGLSLSimpleErosionShader.SetMainTexName(const Value: TGLLibMaterialName);
378
begin
379
 // Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
380
  if FMainTexName = Value then Exit;
381
  FMainTexName  := Value;
382

383
  FMainTex := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FMainTexName);
384
  NotifyChange(Self);
385
end;
386

387
function TGLCustomGLSLSimpleErosionShader.GetErosionTexName: TGLLibMaterialName;
388
begin
389
  Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FErosionTex);
390
  if Result = '' then Result := FErosionTexName;
391
end;
392

393
procedure TGLCustomGLSLSimpleErosionShader.SetErosionTexName(const Value: TGLLibMaterialName);
394
begin
395
 // Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
396
  if FErosionTexName = Value then Exit;
397
  FErosionTexName  := Value;
398

399
  FErosionTex := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FErosionTexName);
400
  NotifyChange(Self);
401
end;
402

403
procedure TGLCustomGLSLSimpleErosionShader.SetAmbientColor(AValue: TGLColor);
404
begin
405
  FAmbientColor.DirectColor := AValue.Color;
406
end;
407

408
procedure TGLCustomGLSLSimpleErosionShader.SetSpecularColor(AValue: TGLColor);
409
begin
410
  FSpecularColor.DirectColor := AValue.Color;
411
end;
412

413

414
procedure TGLCustomGLSLSimpleErosionShader.Notification(AComponent: TComponent; Operation: TOperation);
415
var
416
  Index: Integer;
417
begin
418
  inherited;
419
  if Operation = opRemove then
420
    if AComponent = FMaterialLibrary then
421
      if FMaterialLibrary <> nil then
422
      begin
423
        // Need to nil the textures that were owned by it
424
        if FNoiseTex <> nil then
425
        begin
426
          Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FNoiseTex);
427
          if Index <> -1 then
428
            SetNoiseTexTexture(nil);
429
        end;
430

431
        if FMainTex <> nil then
432
        begin
433
          Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FMainTex);
434
          if Index <> -1 then
435
            SetMainTexTexture(nil);
436
        end;
437

438
        if FErosionTex <> nil then
439
        begin
440
          Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FErosionTex);
441
          if Index <> -1 then
442
            SetErosionTexTexture(nil);
443
        end;
444

445
        FMaterialLibrary := nil;
446
      end;
447
end;
448

449
end.
450

451

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.