LZScene

Форк
0
/
glslwatershader.pas 
264 строки · 8.3 Кб
1
// This unit is part of the GLScene Engine https://github.com/glscene
2
//
3
{
4
   SEM shader : Spherical Environment Mapping
5
   The main idea of SEM is to get the UV coordinates (which are used to lookup the matCap texture)
6
   from the normal vector on the fragment instead of the original texture coordinates from the object.
7
   
8
   A material using SEM is very useful to highlight variations in the mesh: creases, bumps, even slow ondulations.
9
   It doesn't work that well on a cube, for instance. And does absolutely nothing on a sphere:
10
   SEM on a sphere is exactly the same as a planar projection of the matCap texture.
11

12
   At this time only one light source is supported
13

14
    History :  
15
     11/12/15 - J.Delauney - Creation
16

17
}
18

19

20
unit GLSLWaterShader;
21

22
interface
23

24
{$I ../GLScene.inc}
25

26
uses
27
  Classes,
28
   
29
  GLScene, GLCrossPlatform, OpenGLTokens, OpenGL1x, GLContext, GLRenderContextInfo,
30
  GLVectorGeometry, GLCoordinates,
31
  GLColor, GLTexture, GLMaterial,
32
  GLSLShader, GLCustomShader;
33

34
//TGLCustomGLSLSimpleWaterShader
35
//
36
{ Custom class for GLSLWaterShader. Very simple water shader }
37
Type
38
  TGLCustomGLSLWaterShader = class(TGLCustomGLSLShader)
39
  private
40

41
    FMaterialLibrary: TGLAbstractMaterialLibrary;
42

43
    FWaterTexture: TGLTexture;
44
    FWaterTexName   : TGLLibMaterialName;
45

46
    FWaterRefTexture: TGLTexture;
47
    FWaterRefTexName   : TGLLibMaterialName;
48

49
    FWaveTime : Single;
50
//    FSpecularPower: Single;
51
//    FLightPower: Single;
52

53
    function GetMaterialLibrary: TGLAbstractMaterialLibrary;
54

55
    procedure SetWaterTexTexture(const Value: TGLTexture);
56
    function GetWaterTexName: TGLLibMaterialName;
57
    procedure SetWaterTexName(const Value: TGLLibMaterialName);
58

59
    procedure SetWaterRefTexture(const Value: TGLTexture);
60
    function GetWaterRefTexName: TGLLibMaterialName;
61
    procedure SetWaterRefTexName(const Value: TGLLibMaterialName);
62

63

64
  protected
65
    procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
66
    function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
67

68
    procedure SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary); virtual;
69
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
70
  public
71
    constructor Create(AOwner : TComponent); override;
72
    destructor Destroy; override;
73

74
    property WaveTime : Single Read FWaveTime Write FWaveTime;
75
    property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
76
    property WaterTexture: TGLTexture read FWaterTexture write SetWaterTexTexture;
77
    property WaterTextureName: TGLLibMaterialName read GetWaterTexName write SetWaterTexName;
78
    property WaterRefTexture: TGLTexture read FWaterRefTexture write SetWaterRefTexture;
79
    property WaterRefTextureName: TGLLibMaterialName read GetWaterRefTexName write SetWaterRefTexName;
80

81
  end;
82

83
  TGLSLWaterShader = class(TGLCustomGLSLWaterShader)
84
  published
85

86
    property MaterialLibrary;
87
    property WaterTexture;
88
    property WaterTextureName;
89
    property WaterRefTexture;
90
    property WaterRefTextureName;
91

92
  end;
93
implementation
94

95
constructor TGLCustomGLSLWaterShader.Create(AOwner: TComponent);
96
begin
97
  inherited;
98
  with VertexProgram.Code do
99
  begin
100
    clear;
101
    Add('uniform float waveTime; ');
102
    Add('varying vec3 vTexCoord; ');
103

104
    Add('void main() { ');
105
    Add('  gl_TexCoord[0] = gl_MultiTexCoord0; ');
106
    Add('  gl_TexCoord[1] = gl_MultiTexCoord1;');
107
    //Move the water...
108
    Add('gl_TexCoord[0].x += waveTime*0.25; ');
109
    Add('gl_TexCoord[0].y += waveTime-4.0; '); //Make the water move direction vary a little.
110
    // Normal in Eye Space
111
    Add('vec3 vEyeNormal = gl_NormalMatrix * gl_Normal; ');
112
    // Vertex position in Eye Space
113
    Add('vec4 vVert4 = gl_ModelViewMatrix * gl_Vertex; ');
114
    Add('vec3 vEyeVertex = normalize(vVert4.xyz / vVert4.w); ');
115
    Add('vec4 vCoords = vec4(reflect(vEyeVertex, vEyeNormal), 0.0); ');
116
    // Rotate by flipped camera
117
    Add('//vCoords = gl_ModelViewMatrixInverse * vCoords; ');
118
    Add('vTexCoord.xyz =normalize(vCoords.xyz); ');
119
    Add('  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; ');
120
    Add('} ');
121
  end;
122

123
  with FragmentProgram.Code do
124
  begin
125
    clear;
126
    Add('uniform sampler2D waveTextureId; ');
127
    Add('uniform sampler2D waveTextureIdRef; ');
128
    Add('uniform float waveTime; ');
129
    Add('varying vec3 vTexCoord; ');
130

131
    Add('void main() { ');
132
    Add('  vec4 color1 = texture2D(waveTextureId, vec2(gl_TexCoord[0])); ');
133
    Add('  vec4 color2 = texture2D(waveTextureIdRef, vec2(vTexCoord)); ');
134

135

136
    Add('  gl_FragColor = 0.6 * vec4(color1 + color2) * vec4(0.0, 1.0, 1.0, 0.50); ');
137
    Add('} ');
138
  end;
139

140
  FWaveTime := 1.0;
141

142
end;
143

144
destructor TGLCustomGLSLWaterShader.Destroy;
145
begin
146

147
  inherited;
148
end;
149

150
procedure TGLCustomGLSLWaterShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
151
begin
152

153
  GetGLSLProg.UseProgramObject;
154

155

156
//  Param['SpecPower'].AsVector1f := FSpecularPower;
157
//  Param['LightIntensity'].AsVector1f := FLightPower;
158
  Param['waveTime'].AsVector1f := FWaveTime;
159
  Param['waveTextureId'].AsTexture2D[0] := FWaterTexture;
160
  Param['waveTextureIdRef'].AsTexture2D[1] := FWaterRefTexture;
161

162
end;
163

164
function TGLCustomGLSLWaterShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
165
begin
166
  gl.ActiveTexture(GL_TEXTURE0_ARB);
167
  //gl.ActiveTexture(GL_TEXTURE1_ARB);
168
  GetGLSLProg.EndUseProgramObject;
169
  Result := False;
170
end;
171

172

173
function TGLCustomGLSLWaterShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
174
begin
175
  Result := FMaterialLibrary;
176
end;
177

178
procedure TGLCustomGLSLWaterShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
179
begin
180
  if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
181
  FMaterialLibrary := Value;
182
  if (FMaterialLibrary <> nil)
183
    and (FMaterialLibrary is TGLAbstractMaterialLibrary) then
184
      FMaterialLibrary.FreeNotification(Self);
185
end;
186

187
procedure TGLCustomGLSLWaterShader.SetWaterTexTexture(const Value: TGLTexture);
188
begin
189
  if FWaterTexture = Value then Exit;
190
  FWaterTexture := Value;
191
  NotifyChange(Self)
192
end;
193

194
function TGLCustomGLSLWaterShader.GetWaterTexName: TGLLibMaterialName;
195
begin
196
  Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FWaterTexture);
197
  if Result = '' then Result := FWaterTexName;
198
end;
199

200
procedure TGLCustomGLSLWaterShader.SetWaterTexName(const Value: TGLLibMaterialName);
201
begin
202
 // Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
203
  if FWaterTexName = Value then Exit;
204
  FWaterTexName  := Value;
205

206
  FWaterTexture := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FWaterTexName);
207
  NotifyChange(Self);
208
end;
209

210
procedure TGLCustomGLSLWaterShader.SetWaterRefTexture(const Value: TGLTexture);
211
begin
212
  if FWaterRefTexture = Value then Exit;
213
  FWaterRefTexture := Value;
214
  NotifyChange(Self)
215
end;
216

217
function TGLCustomGLSLWaterShader.GetWaterRefTexName: TGLLibMaterialName;
218
begin
219
  Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FWaterRefTexture);
220
  if Result = '' then Result := FWaterRefTexName;
221
end;
222

223
procedure TGLCustomGLSLWaterShader.SetWaterRefTexName(const Value: TGLLibMaterialName);
224
begin
225
 // Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
226
  if FWaterRefTexName = Value then Exit;
227
  FWaterRefTexName  := Value;
228

229
  FWaterRefTexture := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FWaterRefTexName);
230
  NotifyChange(Self);
231
end;
232

233

234

235
procedure TGLCustomGLSLWaterShader.Notification(AComponent: TComponent; Operation: TOperation);
236
var
237
  Index: Integer;
238
begin
239
  inherited;
240
  if Operation = opRemove then
241
    if AComponent = FMaterialLibrary then
242
      if FMaterialLibrary <> nil then
243
      begin
244

245
        if FWaterTexture <> nil then
246
        begin
247
          Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FWaterTexture);
248
          if Index <> -1 then
249
            SetWaterTexTexture(nil);
250
        end;
251

252
        if FWaterRefTexture <> nil then
253
        begin
254
          Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FWaterRefTexture);
255
          if Index <> -1 then
256
            SetWaterRefTexture(nil);
257
        end;
258

259
        FMaterialLibrary := nil;
260
      end;
261
end;
262

263

264
end.
265

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

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

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

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