| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- // This unit is part of the GLScene Engine, http://glscene.org
- //
- unit GLSL.ShaderSem;
- (*
- SEM shader : Spherical Environment Mapping
- The main idea of SEM is to get the UV coordinates (which are used to lookup the matCap texture)
- from the normal vector on the fragment instead of the original texture coordinates from the object.
-
- A material using SEM is very useful to highlight variations in the mesh: creases, bumps, even slow ondulations.
- It doesn't work that well on a cube, for instance. And does absolutely nothing on a sphere:
- SEM on a sphere is exactly the same as a planar projection of the matCap texture.
- At this time only one light source is supported
- *)
- interface
- {$I GLScene.inc}
- uses
- Winapi.OpenGLext,
- System.Classes,
-
- OpenGLTokens,
- GLScene,
- GLBaseClasses,
- GLState,
- GLContext,
- GLRenderContextInfo,
- GLVectorGeometry,
- GLCoordinates,
- GLTextureFormat,
- GLColor,
- GLTexture,
- GLMaterial,
- GLSL.Shader,
- GLS.ShaderCustom;
- Type
- (* Custom class for GLSLSEMShader.
- SEM Shader : Spherical Environment Mapping *)
- TGLCustomGLSLSemShader = class(TGLCustomGLSLShader)
- private
- FAmbientColor: TGLColor;
- // FDiffuseColor: TGLColor;
- FSpecularColor: TGLColor;
- FAmbientFactor : Single;
- FDiffuseFactor : Single;
- FSpecularFactor : Single;
- FMaterialLibrary: TGLAbstractMaterialLibrary;
- FMainTexture: TGLTexture;
- FMainTexName : TGLLibMaterialName;
- // FSpecularPower: Single;
- // FLightPower: Single;
- function GetMaterialLibrary: TGLAbstractMaterialLibrary;
- procedure SetMainTexTexture(const Value: TGLTexture);
- function GetMainTexName: TGLLibMaterialName;
- procedure SetMainTexName(const Value: TGLLibMaterialName);
- //procedure SetDiffuseColor(AValue: TGLColor);
- procedure SetAmbientColor(AValue: TGLColor);
- procedure SetSpecularColor(AValue: TGLColor);
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
- procedure SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary); virtual;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- public
- constructor Create(AOwner : TComponent); override;
- destructor Destroy; override;
- // property DiffuseColor : TGLColor read FDiffuseColor Write setDiffuseColor;
- property SpecularColor : TGLColor Read FSpecularColor Write setSpecularColor;
- property AmbientColor : TGLColor Read FAmbientColor Write setAmbientColor;
- property AmbientFactor : Single Read FAmbientFactor Write FAmbientFactor;
- property DiffuseFactor : Single Read FDiffuseFactor Write FDiffuseFactor;
- property SpecularFactor : Single Read FSpecularFactor Write FSpecularFactor;
- property MaterialLibrary: TGLAbstractMaterialLibrary read getMaterialLibrary write SetMaterialLibrary;
- property MainTexture: TGLTexture read FMainTexture write SetMainTexTexture;
- property MainTextureName: TGLLibMaterialName read GetMainTexName write SetMainTexName;
- // property SpecularPower: Single read FSpecularPower write FSpecularPower;
- // property LightPower: Single read FLightPower write FLightPower;
- end;
- TGLSLSemShader = class(TGLCustomGLSLSemShader)
- published
- property AmbientColor;
- // property DiffuseColor;
- property SpecularColor;
- property AmbientFactor;
- property DiffuseFactor;
- property SpecularFactor;
- property MaterialLibrary;
- property MainTexture;
- property MainTextureName;
- end;
-
- //====================================================
- implementation
- //====================================================
- constructor TGLCustomGLSLSemShader.Create(AOwner: TComponent);
- begin
- inherited;
- with VertexProgram.Code do
- begin
- clear;
- Add('varying vec3 viewVec; ');
- Add('varying vec3 normal; ');
- Add('varying vec3 lightVec; ');
- Add('void main() { ');
- Add(' vec4 p = gl_ModelViewMatrix * gl_Vertex; ');
- Add(' vec4 lightPos = gl_LightSource[0].position;');
- Add(' lightVec = vec3(lightPos - p); ');
- Add(' viewVec = -vec3(p); ');
- Add(' normal = normalize(gl_NormalMatrix * gl_Normal ); ');
- Add(' gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; ');
- Add('} ');
- end;
- with FragmentProgram.Code do
- begin
- clear;
- Add('uniform vec4 AmbientColor; ');
- Add('uniform vec4 SpecularColor; ');
- Add('uniform float DiffuseIntensity; ');
- Add('uniform float AmbientIntensity; ');
- Add('uniform float SpecularIntensity; ');
- Add('uniform sampler2D MainTexture; ');
- Add('varying vec3 viewVec; ');
- Add('varying vec3 normal; ');
- Add('varying vec3 lightVec; ');
- Add('void main() { ');
- Add(' vec3 V = normalize(viewVec); ');
- Add(' vec3 r = reflect( V, normal ); ');
- Add(' float m = 2.0 * sqrt( pow( r.x, 2.0 ) + pow( r.y, 2.0 ) + pow( r.z + 1.0, 2.0 ) ); ');
- Add(' vec2 vN = r.xy / m + 0.5; ');
- Add(' vec4 DiffuseColor; ');
- Add(' DiffuseColor = texture2D( MainTexture, vN ); //.rgb; ');
- // Simple Lighting
- Add(' vec3 L = normalize(lightVec); ');
- Add(' vec3 halfAngle = normalize(L + V); ');
- Add(' float NdotL = dot(L, normal); ');
- Add(' float NdotH = clamp(dot(halfAngle, normal), 0.0, 1.0); ');
- Add(' // "Half-Lambert" technique for more pleasing diffuse term ');
- Add(' float diffuse = DiffuseColor*(0.5 * NdotL + 0.5); ');
- Add(' float specular = pow(NdotH, 64.0); ');
- Add(' vec4 FinalColour = AmbientColor*AmbientIntensity + ');
- Add(' DiffuseColor*diffuse*DiffuseIntensity + ');
- Add(' SpecularColor*specular*SpecularIntensity; ');
- Add(' gl_FragColor = FinalColour; //vec4( FinalColour, 1.0 ); ');
- Add('} ');
- end;
- FAmbientColor := TGLColor.Create(Self);
- //FDiffuseColor := TGLColor.Create(Self);
- FSpecularColor := TGLColor.Create(Self);
- //setup initial parameters
- FAmbientColor.SetColor(0.15, 0.15, 0.15, 1.0);
- //FDiffuseColor.SetColor(1, 1, 1, 1);
- FSpecularColor.SetColor(1.0, 1.0, 1.0, 1.0);
- FAmbientFactor := 0.8;
- FDiffuseFactor :=0.9;
- FSpecularFactor :=0.8;
- end;
- destructor TGLCustomGLSLSemShader.Destroy;
- begin
- FAmbientColor.Destroy;
- // FDiffuseColor.Destroy;
- FSpecularColor.Destroy;
- inherited;
- end;
- procedure TGLCustomGLSLSemShader.DoApply(var rci: TGLRenderContextInfo; Sender: TObject);
- begin
- GetGLSLProg.UseProgramObject;
- //Param['DiffuseColor'].AsVector4f := FDiffuseColor.Color;
- param['AmbientColor'].AsVector4f := FAmbientColor.Color;
- param['SpecularColor'].AsVector4f := FSpecularColor.Color;
- param['AmbientIntensity'].AsVector1f := FAmbientFactor;
- param['DiffuseIntensity'].AsVector1f := FDiffuseFactor;
- param['SpecularIntensity'].AsVector1f := FSpecularFactor;
- // Param['SpecPower'].AsVector1f := FSpecularPower;
- // Param['LightIntensity'].AsVector1f := FLightPower;
- Param['MainTexture'].AsTexture2D[0] := FMainTexture;
- end;
- function TGLCustomGLSLSemShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
- begin
- gl.ActiveTexture(GL_TEXTURE0_ARB);
- GetGLSLProg.EndUseProgramObject;
- Result := False;
- end;
- function TGLCustomGLSLSemShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
- begin
- Result := FMaterialLibrary;
- end;
- procedure TGLCustomGLSLSemShader.SetMaterialLibrary(const Value: TGLAbstractMaterialLibrary);
- begin
- if FMaterialLibrary <> nil then FMaterialLibrary.RemoveFreeNotification(Self);
- FMaterialLibrary := Value;
- if (FMaterialLibrary <> nil)
- and (FMaterialLibrary is TGLAbstractMaterialLibrary) then
- FMaterialLibrary.FreeNotification(Self);
- end;
- procedure TGLCustomGLSLSemShader.SetMainTexTexture(const Value: TGLTexture);
- begin
- if FMainTexture = Value then Exit;
- FMainTexture := Value;
- NotifyChange(Self)
- end;
- function TGLCustomGLSLSemShader.GetMainTexName: TGLLibMaterialName;
- begin
- Result := TGLMaterialLibrary(FMaterialLibrary).GetNameOfTexture(FMainTexture);
- if Result = '' then Result := FMainTexName;
- end;
- procedure TGLCustomGLSLSemShader.SetMainTexName(const Value: TGLLibMaterialName);
- begin
- // Assert(not(assigned(FMaterialLibrary)),'You must set Material Library Before');
- if FMainTexName = Value then Exit;
- FMainTexName := Value;
- FMainTexture := TGLMaterialLibrary(FMaterialLibrary).TextureByName(FMainTexName);
- NotifyChange(Self);
- end;
- //procedure TGLCustomGLSLSemShader.SetDiffuseColor(AValue: TGLColor);
- //begin
- // FDiffuseColor.DirectColor := AValue.Color;
- //end;
- procedure TGLCustomGLSLSemShader.SetAmbientColor(AValue: TGLColor);
- begin
- FAmbientColor.DirectColor := AValue.Color;
- end;
- procedure TGLCustomGLSLSemShader.SetSpecularColor(AValue: TGLColor);
- begin
- FSpecularColor.DirectColor := AValue.Color;
- end;
- procedure TGLCustomGLSLSemShader.Notification(AComponent: TComponent; Operation: TOperation);
- var
- Index: Integer;
- begin
- inherited;
- if Operation = opRemove then
- if AComponent = FMaterialLibrary then
- if FMaterialLibrary <> nil then
- begin
- if FMainTexture <> nil then
- begin
- Index := TGLMaterialLibrary(FMaterialLibrary).Materials.GetTextureIndex(FMainTexture);
- if Index <> -1 then
- SetMainTexTexture(nil);
- end;
- FMaterialLibrary := nil;
- end;
- end;
- end.
|