2
// This unit is part of the GLScene Engine https://github.com/glscene
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.
11
At this time only one light source is supported
14
08/12/15 - J.Delauney - Creation
26
GLScene, GLCrossPlatform, GLBaseClasses, GLState, OpenGLTokens, OpenGL1x, GLContext, GLRenderContextInfo,
27
GLVectorGeometry, GLCoordinates,
28
GLTextureFormat,GLColor, GLTexture, GLMaterial,
29
GLSLShader, GLCustomShader;
31
//TGLCustomGLSLSimpleGoochShader
33
{ Custom class for GLSLSimpleGoochShader.}
35
TGLCustomGLSLSimpleGoochShader = class(TGLCustomGLSLShader)
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;
48
FBlendingMode: TGLBlendingModeEx;
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);
57
procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
58
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
60
constructor Create(AOwner : TComponent); override;
61
destructor Destroy; override;
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;
74
property BlendingMode: TGLBlendingModeEx read FBlendingMode write FBlendingMode default bmxOpaque;
78
TGLSLSimpleGoochShader = class(TGLCustomGLSLSimpleGoochShader)
80
property DiffuseColor;
83
property SpecularColor;
84
property AmbientColor;
87
property AmbientFactor;
88
property DiffuseFactor;
89
property SpecularFactor;
95
{ TGLCustomGLSLSimpleGoochShader }
97
constructor TGLCustomGLSLSimpleGoochShader.Create(AOwner: TComponent);
101
with VertexProgram.Code do
105
Add('varying vec3 vNormal; ');
106
Add('varying vec3 lightVec; ');
107
Add('varying vec3 viewVec; ');
108
Add('varying vec3 ReflectVec; ');
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); ');
118
Add(' lightVec = vec3(lightPos - vert); ');
119
Add(' ReflectVec = normalize(reflect(-lightVec, vNormal)); ');
120
Add(' viewVec = -vec3(vert); ');
124
with FragmentProgram.Code do
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; ');
138
Add('varying vec3 vNormal; ');
139
Add('varying vec3 lightVec; ');
140
Add('varying vec3 viewVec; ');
141
Add('varying vec3 ReflectVec; ');
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); ');
158
Add('vec4 kCool = min(CoolColor + DiffuseCool * SurfaceColor, 1.0); ');
159
Add('vec4 kWarm = min(WarmColor + DiffuseWarm * SurfaceColor, 1.0); ');
162
Add('vec4 Cgooch = mix(kWarm, kCool, diffuse); ');
164
Add('vec3 result = AmbientFactor * AmbientColor.rgb + DiffuseFactor * Cgooch.rgb + SpecularColor.rgb * SpecularFactor *specular; ');
166
Add('gl_FragColor = vec4(result,SurfaceColor.a); ');
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);
183
FDiffuseWarm := 0.55;
184
FDiffuseCool := 0.30;
185
FAmbientFactor := 1.0;
186
FDiffuseFactor :=0.8;
187
FSpecularFactor :=0.9;
189
FBlendingMode:=bmxOpaque;
192
destructor TGLCustomGLSLSimpleGoochShader.Destroy;
202
procedure TGLCustomGLSLSimpleGoochShader.DoApply(var rci: TGLRenderContextInfo;
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;
219
// gl.PushAttrib(GL_COLOR_BUFFER_BIT);
220
ApplyBlendingModeEx(FBlendingMode);
221
// gl.Enable(GL_BLEND);
222
// gl.BlendFunc(cGLBlendFunctionToGLEnum[FBlendSrc],cGLBlendFunctionToGLEnum[FBlendDst]);
225
function TGLCustomGLSLSimpleGoochShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
228
gl.ActiveTexture(GL_TEXTURE0_ARB);
229
GetGLSLProg.EndUseProgramObject;
230
UnApplyBlendingModeEx;
235
procedure TGLCustomGLSLSimpleGoochShader.SetDiffuseColor(AValue: TGLColor);
237
FDiffuseColor.DirectColor := AValue.Color;
240
procedure TGLCustomGLSLSimpleGoochShader.SetAmbientColor(AValue: TGLColor);
242
FAmbientColor.DirectColor := AValue.Color;
245
procedure TGLCustomGLSLSimpleGoochShader.SetSpecularColor(AValue: TGLColor);
247
FSpecularColor.DirectColor := AValue.Color;
250
procedure TGLCustomGLSLSimpleGoochShader.SetWarmColor(AValue: TGLColor);
252
FWarmColor.DirectColor := AValue.Color;
255
procedure TGLCustomGLSLSimpleGoochShader.SetCoolColor(AValue: TGLColor);
257
FCoolColor.DirectColor := AValue.Color;