LZScene

Форк
0
/
GLSLGoochShader.pas 
260 строк · 8.3 Кб
1
//
2
// This unit is part of the GLScene Engine https://github.com/glscene
3
//
4
{
5
   Gooch shader : Gooch shading is used to substitute photorealistic
6
   rendering by rendering that focuses on structore and shape of the object.
7
   Instead of usage of light and shadow, Gooch shading uses concept of warm and cool colors.
8
   Standard Blinn-Phong shading only modulates base color of the object.
9
   In Gooch shading intensity of diffuse lighting is used to determine how to blend warm and cold colors together.
10

11
   At this time only one light source is supported
12

13
    History :  
14
     08/12/15 - J.Delauney - Creation
15

16
}
17
unit GLSLGoochShader;
18

19
interface
20

21
//{$I GLScene.inc}
22

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

31
//TGLCustomGLSLSimpleGoochShader
32
//
33
{ Custom class for GLSLSimpleGoochShader.}
34
type
35
  TGLCustomGLSLSimpleGoochShader = class(TGLCustomGLSLShader)
36
  private
37
    FDiffuseColor : TGLColor;
38
    FWarmColor : TGLColor;
39
    FCoolColor : TGLColor;
40
    FSpecularColor : TGLColor;
41
    FAmbientColor : TGLColor;
42
    FDiffuseWarm : Single;
43
    FDiffuseCool : Single;
44
    FAmbientFactor : Single;
45
    FDiffuseFactor : Single;
46
    FSpecularFactor : Single;
47

48
    FBlendingMode: TGLBlendingModeEx;
49

50
    procedure SetDiffuseColor(AValue: TGLColor);
51
    procedure SetAmbientColor(AValue: TGLColor);
52
    procedure SetSpecularColor(AValue: TGLColor);
53
    procedure SetWarmColor(AValue: TGLColor);
54
    procedure SetCoolColor(AValue: TGLColor);
55

56
  protected
57
    procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
58
    function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
59
  public
60
    constructor Create(AOwner : TComponent); override;
61
    destructor Destroy; override;
62

63
    property DiffuseColor : TGLColor read FDiffuseColor Write setDiffuseColor;
64
    property WarmColor : TGLColor read FWarmColor Write setWarmColor;
65
    property CoolColor : TGLColor Read FCoolColor Write setCoolColor;
66
    property SpecularColor : TGLColor Read FSpecularColor Write setSpecularColor;
67
    property AmbientColor : TGLColor Read FAmbientColor Write setAmbientColor;
68
    property WarmFactor : Single Read FDiffuseWarm Write FDiffuseWarm;
69
    property CoolFactor : Single Read FDiffuseCool Write FDiffuseCool;
70
    property AmbientFactor : Single Read FAmbientFactor Write FAmbientFactor;
71
    property DiffuseFactor : Single Read FDiffuseFactor Write FDiffuseFactor;
72
    property SpecularFactor : Single Read FSpecularFactor Write FSpecularFactor;
73

74
    property BlendingMode: TGLBlendingModeEx read FBlendingMode write FBlendingMode default bmxOpaque;
75
  end;
76

77
type
78
  TGLSLSimpleGoochShader = class(TGLCustomGLSLSimpleGoochShader)
79
  published
80
    property DiffuseColor;
81
    property WarmColor;
82
    property CoolColor;
83
    property SpecularColor;
84
    property AmbientColor;
85
    property WarmFactor;
86
    property CoolFactor;
87
    property AmbientFactor;
88
    property DiffuseFactor;
89
    property SpecularFactor;
90
  end;
91

92
implementation
93

94

95
{ TGLCustomGLSLSimpleGoochShader }
96

97
constructor TGLCustomGLSLSimpleGoochShader.Create(AOwner: TComponent);
98
begin
99
  inherited;
100

101
  with VertexProgram.Code do
102
  begin
103
    Clear;
104

105
    Add('varying vec3 vNormal; ');
106
    Add('varying vec3 lightVec; ');
107
    Add('varying vec3 viewVec; ');
108
    Add('varying vec3 ReflectVec; ');
109
    Add(' ');
110
    Add('void main() ');
111
    Add('{ ');
112
    Add('  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; ');
113
    Add('  vec4 lightPos = gl_LightSource[0].position;');
114
    Add('  vec4 vert =  gl_ModelViewMatrix * gl_Vertex; ');
115
    Add('  vec3 normal = gl_NormalMatrix * gl_Normal; ');
116
    Add('  vNormal  = normalize(normal); ');
117

118
    Add('  lightVec = vec3(lightPos - vert); ');
119
    Add('  ReflectVec    = normalize(reflect(-lightVec, vNormal)); ');
120
    Add('  viewVec = -vec3(vert); ');
121
    Add('} ');
122
  end;
123

124
  with FragmentProgram.Code do
125
  begin
126
    Clear;
127
    Add('uniform vec4  SurfaceColor; ');
128
    Add('uniform vec4  WarmColor; ');
129
    Add('uniform vec4  CoolColor; ');
130
    Add('uniform vec4  SpecularColor; ');
131
    Add('uniform vec4  AmbientColor; ');
132
    Add('uniform float DiffuseWarm; ');
133
    Add('uniform float DiffuseCool; ');
134
    Add('uniform float AmbientFactor; ');
135
    Add('uniform float DiffuseFactor; ');
136
    Add('uniform float SpecularFactor; ');
137

138
    Add('varying vec3 vNormal; ');
139
    Add('varying vec3 lightVec; ');
140
    Add('varying vec3 viewVec; ');
141
    Add('varying vec3 ReflectVec; ');
142
    Add(' ');
143
    Add('void main() ');
144
    Add('{ ');
145

146

147
    Add('vec3 L = normalize(lightVec); ');
148
    Add('vec3 V = normalize(viewVec); ');
149
    Add('vec3 halfAngle = normalize(L + V); ');
150
    Add('float NdotL   = (dot(L, vNormal) + 1.0) * 0.5; ');
151
    Add('float NdotH = clamp(dot(halfAngle, vNormal), 0.0, 1.0); ');
152
    Add('// "Half-Lambert" technique for more pleasing diffuse term ');
153
    Add('float diffuse = 0.5 * NdotL + 0.5; ');
154
    Add('vec3 nreflect = normalize(ReflectVec); ');
155
    Add('float specular    = max(dot(nreflect, V), 0.0); ');
156
    Add('specular          = pow(specular, 64.0); ');
157

158
    Add('vec4 kCool    = min(CoolColor + DiffuseCool * SurfaceColor, 1.0); ');
159
    Add('vec4 kWarm    = min(WarmColor + DiffuseWarm * SurfaceColor, 1.0); ');
160

161

162
    Add('vec4 Cgooch = mix(kWarm, kCool, diffuse); ');
163

164
    Add('vec3 result = AmbientFactor * AmbientColor.rgb + DiffuseFactor * Cgooch.rgb + SpecularColor.rgb * SpecularFactor *specular; ');
165

166
    Add('gl_FragColor = vec4(result,SurfaceColor.a); ');
167
    Add('} ');
168
  end;
169

170

171
  // Initial stuff.
172
  FDiffuseColor := TGLColor.Create(self);
173
  FDiffuseColor.SetColor(0.75,0.75,0.75,1.0);
174
  FWarmColor := TGLColor.Create(self);
175
  FWarmColor.SetColor(0.88,0.81,0.49,1.0);
176
  FCoolColor := TGLColor.Create(self);
177
  FCoolColor.SetColor(0.58,0.10,0.76,1.0);
178
  FAmbientColor := TGLColor.Create(self);
179
  FAmbientColor.SetColor(0.3,0.3,0.3,1.0);
180
  FSpecularColor := TGLColor.Create(self);
181
  FSpecularColor.SetColor(1.0,1.0,1.0,1.0);
182

183
  FDiffuseWarm    := 0.55;
184
  FDiffuseCool    := 0.30;
185
  FAmbientFactor  := 1.0;
186
  FDiffuseFactor  :=0.8;
187
  FSpecularFactor :=0.9;
188

189
  FBlendingMode:=bmxOpaque;
190
end;
191

192
destructor TGLCustomGLSLSimpleGoochShader.Destroy;
193
begin
194
  FDiffuseColor.Free;
195
  FWarmColor.Free;
196
  FCoolColor.Free;
197
  FSpecularColor.Free;
198
  FAmbientColor.Free;
199
  inherited;
200
end;
201

202
procedure TGLCustomGLSLSimpleGoochShader.DoApply(var rci: TGLRenderContextInfo;
203
  Sender: TObject);
204
begin
205

206

207
  GetGLSLProg.UseProgramObject;
208
  param['SurfaceColor'].AsVector4f := FDiffuseColor.Color;
209
  param['WarmColor'].AsVector4f := FWarmColor.Color;
210
  param['CoolColor'].AsVector4f := FCoolColor.Color;
211
  param['AmbientColor'].AsVector4f := FAmbientColor.Color;
212
  param['SpecularColor'].AsVector4f := FSpecularColor.Color;
213
  param['DiffuseWarm'].AsVector1f := FDiffuseWarm;
214
  param['DiffuseCool'].AsVector1f := FDiffuseCool;
215
  param['AmbientFactor'].AsVector1f := FAmbientFactor;
216
  param['DiffuseFactor'].AsVector1f := FDiffuseFactor;
217
  param['SpecularFactor'].AsVector1f := FSpecularFactor;
218

219
 // gl.PushAttrib(GL_COLOR_BUFFER_BIT);
220
  ApplyBlendingModeEx(FBlendingMode);
221
//  gl.Enable(GL_BLEND);
222
//  gl.BlendFunc(cGLBlendFunctionToGLEnum[FBlendSrc],cGLBlendFunctionToGLEnum[FBlendDst]);
223
end;
224

225
function TGLCustomGLSLSimpleGoochShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
226
begin
227

228
  gl.ActiveTexture(GL_TEXTURE0_ARB);
229
  GetGLSLProg.EndUseProgramObject;
230
  UnApplyBlendingModeEx;
231
 // gl.PopAttrib;
232
  Result := False;
233
end;
234

235
procedure TGLCustomGLSLSimpleGoochShader.SetDiffuseColor(AValue: TGLColor);
236
begin
237
  FDiffuseColor.DirectColor := AValue.Color;
238
end;
239

240
procedure TGLCustomGLSLSimpleGoochShader.SetAmbientColor(AValue: TGLColor);
241
begin
242
  FAmbientColor.DirectColor := AValue.Color;
243
end;
244

245
procedure TGLCustomGLSLSimpleGoochShader.SetSpecularColor(AValue: TGLColor);
246
begin
247
  FSpecularColor.DirectColor := AValue.Color;
248
end;
249

250
procedure TGLCustomGLSLSimpleGoochShader.SetWarmColor(AValue: TGLColor);
251
begin
252
  FWarmColor.DirectColor := AValue.Color;
253
end;
254

255
procedure TGLCustomGLSLSimpleGoochShader.SetCoolColor(AValue: TGLColor);
256
begin
257
  FCoolColor.DirectColor := AValue.Color;
258
end;
259

260
end.
261

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

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

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

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