LZScene

Форк
0
/
GLSLSemShader.pas 
299 строк · 9.4 Кб
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 GLSLSemShader;
21

22
interface
23

24
{$I GLScene.inc}
25

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

34
//TGLCustomGLSLSimpleSemShader
35
//
36
{ Custom class for GLSLSEMShader.
37
 SEM Shader : Spherical Environment Mapping }
38
Type
39
TGLCustomGLSLSemShader = class(TGLCustomGLSLShader)
40
  private
41
    FAmbientColor: TGLColor;
42
//    FDiffuseColor: TGLColor;
43
    FSpecularColor: TGLColor;
44
    FAmbientFactor : Single;
45
    FDiffuseFactor : Single;
46
    FSpecularFactor : Single;
47

48
    FMaterialLibrary: TGLAbstractMaterialLibrary;
49
    FMainTexture: TGLTexture;
50
    FMainTexName   : TGLLibMaterialName;
51

52
//    FSpecularPower: Single;
53
//    FLightPower: Single;
54

55
    function GetMaterialLibrary: TGLAbstractMaterialLibrary;
56

57
    procedure SetMainTexTexture(const Value: TGLTexture);
58
    function GetMainTexName: TGLLibMaterialName;
59
    procedure SetMainTexName(const Value: TGLLibMaterialName);
60

61
    //procedure SetDiffuseColor(AValue: TGLColor);
62
    procedure SetAmbientColor(AValue: TGLColor);
63
    procedure SetSpecularColor(AValue: TGLColor);
64

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

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

75
//    property DiffuseColor : TGLColor read FDiffuseColor Write setDiffuseColor;
76
    property SpecularColor : TGLColor Read FSpecularColor Write setSpecularColor;
77
    property AmbientColor : TGLColor Read FAmbientColor Write setAmbientColor;
78

79
    property AmbientFactor : Single Read FAmbientFactor Write FAmbientFactor;
80
    property DiffuseFactor : Single Read FDiffuseFactor Write FDiffuseFactor;
81
    property SpecularFactor : Single Read FSpecularFactor Write FSpecularFactor;
82

83
    property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
84
    property MainTexture: TGLTexture read FMainTexture write SetMainTexTexture;
85
    property MainTextureName: TGLLibMaterialName read GetMainTexName write SetMainTexName;
86

87
//    property SpecularPower: Single read FSpecularPower write FSpecularPower;
88
//    property LightPower: Single read FLightPower write FLightPower;
89

90
  end;
91

92
  TGLSLSemShader = class(TGLCustomGLSLSemShader)
93
  published
94

95

96
    property AmbientColor;
97
//    property DiffuseColor;
98
    property SpecularColor;
99

100
    property AmbientFactor;
101
    property DiffuseFactor;
102
    property SpecularFactor;
103

104
    property MaterialLibrary;
105
    property MainTexture;
106
    property MainTextureName;
107

108

109
  end;
110
implementation
111

112
constructor TGLCustomGLSLSemShader.Create(AOwner: TComponent);
113
begin
114
  inherited;
115
  with VertexProgram.Code do
116
  begin
117
    clear;
118
    Add('varying vec3 viewVec; ');
119
    Add('varying vec3 normal; ');
120
    Add('varying vec3 lightVec; ');
121

122
    Add('void main() { ');
123
    Add('  vec4 p = gl_ModelViewMatrix * gl_Vertex; ');
124
    Add('  vec4 lightPos = gl_LightSource[0].position;');
125
    Add('  lightVec = vec3(lightPos - p); ');
126
    Add('  viewVec = -vec3(p); ');
127
    Add('  normal = normalize(gl_NormalMatrix * gl_Normal ); ');
128

129
    Add('  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; ');
130
    Add('} ');
131
  end;
132

133
  with FragmentProgram.Code do
134
  begin
135
    clear;
136
    Add('uniform vec4 AmbientColor; ');
137
    Add('uniform vec4 SpecularColor; ');
138
    Add('uniform float DiffuseIntensity; ');
139
    Add('uniform float AmbientIntensity; ');
140
    Add('uniform float SpecularIntensity; ');
141

142
    Add('uniform sampler2D MainTexture; ');
143

144
    Add('varying vec3 viewVec; ');
145
    Add('varying vec3 normal; ');
146
    Add('varying vec3 lightVec; ');
147

148
    Add('void main() { ');
149
    Add('  vec3 V = normalize(viewVec); ');
150
    Add('  vec3 r = reflect( V, normal ); ');
151
    Add('  float m = 2.0 * sqrt( pow( r.x, 2.0 ) + pow( r.y, 2.0 ) + pow( r.z + 1.0, 2.0 ) ); ');
152
    Add('  vec2 vN = r.xy / m + 0.5; ');
153
    Add('  vec4 DiffuseColor;    ');
154
    Add('  DiffuseColor = texture2D( MainTexture, vN ); //.rgb; ');
155

156
    // Simple Lighting
157
    Add('  vec3 L = normalize(lightVec); ');
158

159
    Add('  vec3 halfAngle = normalize(L + V); ');
160
    Add('  float NdotL = dot(L, normal); ');
161
    Add('  float NdotH = clamp(dot(halfAngle, normal), 0.0, 1.0); ');
162
    Add('  // "Half-Lambert" technique for more pleasing diffuse term ');
163
    Add('  float diffuse = DiffuseColor*(0.5 * NdotL + 0.5); ');
164
    Add('  float specular = pow(NdotH, 64.0); ');
165

166
    Add('  vec4 FinalColour = AmbientColor*AmbientIntensity + ');
167
    Add('                     DiffuseColor*diffuse*DiffuseIntensity + ');
168
    Add('                     SpecularColor*specular*SpecularIntensity; ');
169

170
    Add('  gl_FragColor = FinalColour; //vec4( FinalColour, 1.0 ); ');
171
    Add('} ');
172
  end;
173

174
  FAmbientColor := TGLColor.Create(Self);
175
  //FDiffuseColor := TGLColor.Create(Self);
176
  FSpecularColor := TGLColor.Create(Self);
177

178
  //setup initial parameters
179
  FAmbientColor.SetColor(0.15, 0.15, 0.15, 1.0);
180
  //FDiffuseColor.SetColor(1, 1, 1, 1);
181
  FSpecularColor.SetColor(1.0, 1.0, 1.0, 1.0);
182
  FAmbientFactor  := 0.8;
183
  FDiffuseFactor  :=0.9;
184
  FSpecularFactor :=0.8;
185

186

187
end;
188

189
destructor TGLCustomGLSLSemShader.Destroy;
190
begin
191
  FAmbientColor.Destroy;
192
 // FDiffuseColor.Destroy;
193
  FSpecularColor.Destroy;
194

195
  inherited;
196
end;
197

198
procedure TGLCustomGLSLSemShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
199
begin
200

201
  GetGLSLProg.UseProgramObject;
202
  //Param['DiffuseColor'].AsVector4f := FDiffuseColor.Color;
203
  param['AmbientColor'].AsVector4f := FAmbientColor.Color;
204
  param['SpecularColor'].AsVector4f := FSpecularColor.Color;
205
  param['AmbientIntensity'].AsVector1f := FAmbientFactor;
206
  param['DiffuseIntensity'].AsVector1f := FDiffuseFactor;
207
  param['SpecularIntensity'].AsVector1f := FSpecularFactor;
208

209
//  Param['SpecPower'].AsVector1f := FSpecularPower;
210
//  Param['LightIntensity'].AsVector1f := FLightPower;
211

212
  Param['MainTexture'].AsTexture2D[0] := FMainTexture;
213

214
end;
215

216
function TGLCustomGLSLSemShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
217
begin
218
  gl.ActiveTexture(GL_TEXTURE0_ARB);
219
  GetGLSLProg.EndUseProgramObject;
220
  Result := False;
221
end;
222

223

224
function TGLCustomGLSLSemShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
225
begin
226
  Result := FMaterialLibrary;
227
end;
228

229
procedure TGLCustomGLSLSemShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
230
begin
231
  if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
232
  FMaterialLibrary := Value;
233
  if (FMaterialLibrary <> nil)
234
    and (FMaterialLibrary is TGLAbstractMaterialLibrary) then
235
      FMaterialLibrary.FreeNotification(Self);
236
end;
237

238
procedure TGLCustomGLSLSemShader.SetMainTexTexture(const Value: TGLTexture);
239
begin
240
  if FMainTexture = Value then Exit;
241
  FMainTexture := Value;
242
  NotifyChange(Self)
243
end;
244

245
function TGLCustomGLSLSemShader.GetMainTexName: TGLLibMaterialName;
246
begin
247
  Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FMainTexture);
248
  if Result = '' then Result := FMainTexName;
249
end;
250

251
procedure TGLCustomGLSLSemShader.SetMainTexName(const Value: TGLLibMaterialName);
252
begin
253
 // Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
254
  if FMainTexName = Value then Exit;
255
  FMainTexName  := Value;
256

257
  FMainTexture := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FMainTexName);
258
  NotifyChange(Self);
259
end;
260

261

262
//procedure TGLCustomGLSLSemShader.SetDiffuseColor(AValue: TGLColor);
263
//begin
264
//  FDiffuseColor.DirectColor := AValue.Color;
265
//end;
266

267
procedure TGLCustomGLSLSemShader.SetAmbientColor(AValue: TGLColor);
268
begin
269
  FAmbientColor.DirectColor := AValue.Color;
270
end;
271

272
procedure TGLCustomGLSLSemShader.SetSpecularColor(AValue: TGLColor);
273
begin
274
  FSpecularColor.DirectColor := AValue.Color;
275
end;
276

277
procedure TGLCustomGLSLSemShader.Notification(AComponent: TComponent; Operation: TOperation);
278
var
279
  Index: Integer;
280
begin
281
  inherited;
282
  if Operation = opRemove then
283
    if AComponent = FMaterialLibrary then
284
      if FMaterialLibrary <> nil then
285
      begin
286

287
        if FMainTexture <> nil then
288
        begin
289
          Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FMainTexture);
290
          if Index <> -1 then
291
            SetMainTexTexture(nil);
292
        end;
293

294
        FMaterialLibrary := nil;
295
      end;
296
end;
297

298

299
end.
300

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

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

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

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