1
// This unit is part of the GLScene Engine https://github.com/glscene
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.
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.
12
At this time only one light source is supported
15
11/12/15 - J.Delauney - Creation
29
GLScene, GLCrossPlatform, GLBaseClasses, GLState, OpenGLTokens, OpenGL1x, GLContext, GLRenderContextInfo,
30
GLVectorGeometry, GLCoordinates,
31
GLTextureFormat,GLColor, GLTexture, GLMaterial,
32
GLSLShader, GLCustomShader;
34
//TGLCustomGLSLSimpleSemShader
36
{ Custom class for GLSLSEMShader.
37
SEM Shader : Spherical Environment Mapping }
39
TGLCustomGLSLSemShader = class(TGLCustomGLSLShader)
41
FAmbientColor: TGLColor;
42
// FDiffuseColor: TGLColor;
43
FSpecularColor: TGLColor;
44
FAmbientFactor : Single;
45
FDiffuseFactor : Single;
46
FSpecularFactor : Single;
48
FMaterialLibrary: TGLAbstractMaterialLibrary;
49
FMainTexture: TGLTexture;
50
FMainTexName : TGLLibMaterialName;
52
// FSpecularPower: Single;
53
// FLightPower: Single;
55
function GetMaterialLibrary: TGLAbstractMaterialLibrary;
57
procedure SetMainTexTexture(const Value: TGLTexture);
58
function GetMainTexName: TGLLibMaterialName;
59
procedure SetMainTexName(const Value: TGLLibMaterialName);
61
//procedure SetDiffuseColor(AValue: TGLColor);
62
procedure SetAmbientColor(AValue: TGLColor);
63
procedure SetSpecularColor(AValue: TGLColor);
66
procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
67
function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
69
procedure SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary); virtual;
70
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
72
constructor Create(AOwner : TComponent); override;
73
destructor Destroy; override;
75
// property DiffuseColor : TGLColor read FDiffuseColor Write setDiffuseColor;
76
property SpecularColor : TGLColor Read FSpecularColor Write setSpecularColor;
77
property AmbientColor : TGLColor Read FAmbientColor Write setAmbientColor;
79
property AmbientFactor : Single Read FAmbientFactor Write FAmbientFactor;
80
property DiffuseFactor : Single Read FDiffuseFactor Write FDiffuseFactor;
81
property SpecularFactor : Single Read FSpecularFactor Write FSpecularFactor;
83
property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
84
property MainTexture: TGLTexture read FMainTexture write SetMainTexTexture;
85
property MainTextureName: TGLLibMaterialName read GetMainTexName write SetMainTexName;
87
// property SpecularPower: Single read FSpecularPower write FSpecularPower;
88
// property LightPower: Single read FLightPower write FLightPower;
92
TGLSLSemShader = class(TGLCustomGLSLSemShader)
96
property AmbientColor;
97
// property DiffuseColor;
98
property SpecularColor;
100
property AmbientFactor;
101
property DiffuseFactor;
102
property SpecularFactor;
104
property MaterialLibrary;
105
property MainTexture;
106
property MainTextureName;
112
constructor TGLCustomGLSLSemShader.Create(AOwner: TComponent);
115
with VertexProgram.Code do
118
Add('varying vec3 viewVec; ');
119
Add('varying vec3 normal; ');
120
Add('varying vec3 lightVec; ');
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 ); ');
129
Add(' gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; ');
133
with FragmentProgram.Code do
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; ');
142
Add('uniform sampler2D MainTexture; ');
144
Add('varying vec3 viewVec; ');
145
Add('varying vec3 normal; ');
146
Add('varying vec3 lightVec; ');
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; ');
157
Add(' vec3 L = normalize(lightVec); ');
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); ');
166
Add(' vec4 FinalColour = AmbientColor*AmbientIntensity + ');
167
Add(' DiffuseColor*diffuse*DiffuseIntensity + ');
168
Add(' SpecularColor*specular*SpecularIntensity; ');
170
Add(' gl_FragColor = FinalColour; //vec4( FinalColour, 1.0 ); ');
174
FAmbientColor := TGLColor.Create(Self);
175
//FDiffuseColor := TGLColor.Create(Self);
176
FSpecularColor := TGLColor.Create(Self);
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;
189
destructor TGLCustomGLSLSemShader.Destroy;
191
FAmbientColor.Destroy;
192
// FDiffuseColor.Destroy;
193
FSpecularColor.Destroy;
198
procedure TGLCustomGLSLSemShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
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;
209
// Param['SpecPower'].AsVector1f := FSpecularPower;
210
// Param['LightIntensity'].AsVector1f := FLightPower;
212
Param['MainTexture'].AsTexture2D[0] := FMainTexture;
216
function TGLCustomGLSLSemShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
218
gl.ActiveTexture(GL_TEXTURE0_ARB);
219
GetGLSLProg.EndUseProgramObject;
224
function TGLCustomGLSLSemShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
226
Result := FMaterialLibrary;
229
procedure TGLCustomGLSLSemShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
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);
238
procedure TGLCustomGLSLSemShader.SetMainTexTexture(const Value: TGLTexture);
240
if FMainTexture = Value then Exit;
241
FMainTexture := Value;
245
function TGLCustomGLSLSemShader.GetMainTexName: TGLLibMaterialName;
247
Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FMainTexture);
248
if Result = '' then Result := FMainTexName;
251
procedure TGLCustomGLSLSemShader.SetMainTexName(const Value: TGLLibMaterialName);
253
// Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
254
if FMainTexName = Value then Exit;
255
FMainTexName := Value;
257
FMainTexture := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FMainTexName);
262
//procedure TGLCustomGLSLSemShader.SetDiffuseColor(AValue: TGLColor);
264
// FDiffuseColor.DirectColor := AValue.Color;
267
procedure TGLCustomGLSLSemShader.SetAmbientColor(AValue: TGLColor);
269
FAmbientColor.DirectColor := AValue.Color;
272
procedure TGLCustomGLSLSemShader.SetSpecularColor(AValue: TGLColor);
274
FSpecularColor.DirectColor := AValue.Color;
277
procedure TGLCustomGLSLSemShader.Notification(AComponent: TComponent; Operation: TOperation);
282
if Operation = opRemove then
283
if AComponent = FMaterialLibrary then
284
if FMaterialLibrary <> nil then
287
if FMainTexture <> nil then
289
Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FMainTexture);
291
SetMainTexTexture(nil);
294
FMaterialLibrary := nil;