| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098 |
- //
- // This unit is part of the GLScene Engine, http://glscene.org
- //
- unit GLSL.ShaderBump;
- (*
- A GLSL shader that applies bump mapping.
- This is a collection of GLSL Bump shaders, comes in these variaties
- (to know what these abriviations mean, see GLCustomShader.pas):
- - TGLSLBumpShader
- - TGLSLBumpShaderMT
- - TGLSLBumpShaderAM
- - TGLSLMLBumpShader
- - TGLSLMLBumpShaderMT
- Notes:
- 1) Alpha is a synthetic property, in real life your should set each
- color's Alpha individualy
- 2) TGLSLMLBumpShader takes all Light parameters directly
- from OpenGL (that includes TGLLightSource's)
- TODO:
- 1) Implement IGLShaderDescription in all shaders.
- *)
- interface
- {$I GLScene.inc}
- uses
- System.Classes,
- System.SysUtils,
- GLTexture,
- GLScene,
- GLVectorGeometry,
- GLVectorTypes,
- GLCadencer,
- GLS.Strings,
- OpenGLTokens,
- GLSL.Shader,
- GLS.ShaderCustom,
- GLColor,
- GLRenderContextInfo,
- GLMaterial;
- type
- EGLSLBumpShaderException = class(EGLSLShaderException);
- // An abstract class.
- TGLBaseCustomGLSLBumpShader = class(TGLCustomGLSLShader, IGLMaterialLibrarySupported)
- private
- FBumpHeight: Single;
- FBumpSmoothness: Integer;
- FSpecularPower: Single;
- FSpecularSpread: Single;
- FLightPower: Single;
- FMaterialLibrary: TGLMaterialLibrary;
- FNormalTexture: TGLTexture;
- FSpecularTexture: TGLTexture;
- FNormalTextureName: TGLLibMaterialName;
- FSpecularTextureName: TGLLibMaterialName;
- function GetNormalTextureName: TGLLibMaterialName;
- function GetSpecularTextureName: TGLLibMaterialName;
- procedure SetNormalTextureName(const Value: TGLLibMaterialName);
- procedure SetSpecularTextureName(const Value: TGLLibMaterialName);
- procedure SetSpecularTexture(const Value: TGLTexture);
- procedure SetNormalTexture(const Value: TGLTexture);
- // Implementing IGLMaterialLibrarySupported.
- function GetMaterialLibrary: TGLAbstractMaterialLibrary;
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
- procedure SetMaterialLibrary(const Value: TGLMaterialLibrary); virtual;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- public
- constructor Create(AOwner : TComponent); override;
- property BumpHeight: Single read FBumpHeight write FBumpHeight;
- property BumpSmoothness: Integer read FBumpSmoothness write FBumpSmoothness;
- property SpecularPower: Single read FSpecularPower write FSpecularPower;
- property SpecularSpread: Single read FSpecularSpread write FSpecularSpread;
- property LightPower: Single read FLightPower write FLightPower;
- property NormalTexture: TGLTexture read FNormalTexture write SetNormalTexture;
- property SpecularTexture: TGLTexture read FSpecularTexture write SetSpecularTexture;
- property NormalTextureName: TGLLibMaterialName read GetNormalTextureName write SetNormalTextureName;
- property SpecularTextureName: TGLLibMaterialName read GetSpecularTextureName write SetSpecularTextureName;
- property MaterialLibrary: TGLMaterialLibrary read FMaterialLibrary write SetMaterialLibrary;
- end;
- // An abstract class.
- TGLBaseCustomGLSLBumpShaderMT = class(TGLBaseCustomGLSLBumpShader)
- private
- FMainTexture: TGLTexture;
- FMainTextureName: TGLLibMaterialName;
- function GetMainTextureName: string;
- procedure SetMainTextureName(const Value: string);
- protected
- procedure SetMaterialLibrary(const Value: TGLMaterialLibrary); override;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- public
- property MainTexture: TGLTexture read FMainTexture write FMainTexture;
- property MainTextureName: TGLLibMaterialName read GetMainTextureName write SetMainTextureName;
- end;
- // One Light shaders.
- TGLCustomGLSLBumpShaderAM = class(TGLBaseCustomGLSLBumpShaderMT)
- private
- FAmbientColor: TGLColor;
- FDiffuseColor: TGLColor;
- FSpecularColor: TGLColor;
- function GetAlpha: Single;
- procedure SetAlpha(const Value: Single);
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- public
- constructor Create(AOwner : TComponent); override;
- destructor Destroy; override;
- property AmbientColor: TGLColor read FAmbientColor;
- property DiffuseColor: TGLColor read FDiffuseColor;
- property SpecularColor: TGLColor read FSpecularColor;
- property Alpha: Single read GetAlpha write SetAlpha;
- end;
- TGLCustomGLSLBumpShaderMT = class(TGLBaseCustomGLSLBumpShaderMT)
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- end;
- TGLCustomGLSLBumpShader = class(TGLBaseCustomGLSLBumpShader, IGLShaderDescription)
- private
- // Implementing IGLShaderDescription.
- procedure SetShaderTextures(const Textures: array of TGLTexture);
- procedure GetShaderTextures(var Textures: array of TGLTexture);
- procedure SetShaderColorParams(const AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
- procedure GetShaderColorParams(var AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
- procedure SetShaderMiscParameters(const ACadencer: TGLCadencer; const AMatLib: TGLMaterialLibrary; const ALightSources: TGLLightSourceSet);
- procedure GetShaderMiscParameters(var ACadencer: TGLCadencer; var AMatLib: TGLMaterialLibrary; var ALightSources: TGLLightSourceSet);
- function GetShaderAlpha: Single;
- procedure SetShaderAlpha(const Value: Single);
- function GetShaderDescription: string;
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- end;
- // MultiLight shaders.
- TGLCustomGLSLMLBumpShader = class(TGLBaseCustomGLSLBumpShader, IGLShaderDescription)
- private
- FLightSources: TGLLightSourceSet;
- FLightCompensation: Single;
- procedure SetLightSources(const Value: TGLLightSourceSet);
- procedure SetLightCompensation(const Value: Single);
- // Implementing IGLShaderDescription.
- procedure SetShaderTextures(const Textures: array of TGLTexture);
- procedure GetShaderTextures(var Textures: array of TGLTexture);
- procedure SetShaderColorParams(const AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
- procedure GetShaderColorParams(var AAmbientColor, ADiffuseColor, ASpecularcolor: TVector4f);
- procedure SetShaderMiscParameters(const ACadencer: TGLCadencer; const AMatLib: TGLMaterialLibrary; const ALightSources: TGLLightSourceSet);
- procedure GetShaderMiscParameters(var ACadencer: TGLCadencer; var AMatLib: TGLMaterialLibrary; var ALightSources: TGLLightSourceSet);
- function GetShaderAlpha: Single;
- procedure SetShaderAlpha(const Value: Single);
- function GetShaderDescription: string;
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- public
- constructor Create(AOwner : TComponent); override;
- property LightSources: TGLLightSourceSet read FLightSources write SetLightSources default [1];
- {Setting LightCompensation to a value less than 1 decreeses individual
- light intensity when using multiple lights }
- property LightCompensation: Single read FLightCompensation write SetLightCompensation;
- end;
- TGLCustomGLSLMLBumpShaderMT = class(TGLBaseCustomGLSLBumpShaderMT)
- private
- FLightSources: TGLLightSourceSet;
- FLightCompensation: Single;
- procedure SetLightSources(const Value: TGLLightSourceSet);
- procedure SetLightCompensation(const Value: Single);
- protected
- procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
- procedure DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject); override;
- public
- constructor Create(AOwner : TComponent); override;
- property LightSources: TGLLightSourceSet read FLightSources write SetLightSources default [1];
- {Setting LightCompensation to a value less than 1 decreeses individual
- light intensity when using multiple lights }
- property LightCompensation: Single read FLightCompensation write SetLightCompensation;
- end;
- {************** Published **************}
- // One light shaders.
- TGLSLBumpShaderMT = class(TGLCustomGLSLBumpShaderMT)
- published
- property MainTextureName;
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- end;
- TGLSLBumpShader = class(TGLCustomGLSLBumpShader)
- published
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- end;
- TGLSLBumpShaderAM = class(TGLCustomGLSLBumpShaderAM)
- published
- property AmbientColor;
- property DiffuseColor;
- property SpecularColor;
- property Alpha stored False;
- property MainTextureName;
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- end;
- // Multi light shaders.
- TGLSLMLBumpShader = class(TGLCustomGLSLMLBumpShader)
- published
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- property LightSources;
- property LightCompensation;
- end;
- TGLSLMLBumpShaderMT = class(TGLCustomGLSLMLBumpShaderMT)
- published
- property MainTextureName;
- property NormalTextureName;
- property SpecularTextureName;
- property MaterialLibrary;
- property BumpHeight;
- property BumpSmoothness;
- property SpecularPower;
- property SpecularSpread;
- property LightPower;
- property LightSources;
- property LightCompensation;
- end;
- //--------------------------------------------------------------
- implementation
- //--------------------------------------------------------------
- procedure GetVertexProgramCode(const Code: TStrings);
- begin
- with Code do
- begin
- Clear;
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add('varying vec3 LightDirection; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- Add(' gl_Position = ftransform(); ');
- Add(' Texcoord = gl_MultiTexCoord0.xy; ');
- Add(' ');
- Add(' vec3 fvViewDirection = (gl_ModelViewMatrix * gl_Vertex).xyz; ');
- Add(' vec3 fvLightDirection = gl_LightSource[0].position.xyz - fvViewDirection; ');
- Add(' ');
- Add(' vec3 fvNormal = gl_NormalMatrix * gl_Normal; ');
- Add(' vec3 fvBinormal = gl_NormalMatrix * gl_MultiTexCoord2.xyz; ');
- Add(' vec3 fvTangent = gl_NormalMatrix * gl_MultiTexCoord1.xyz; ');
- Add(' ');
- Add(' ViewDirection.x = dot( fvTangent, fvViewDirection ); ');
- Add(' ViewDirection.y = dot( fvBinormal, fvViewDirection ); ');
- Add(' ViewDirection.z = dot( fvNormal, fvViewDirection ); ');
- Add(' ');
- Add(' LightDirection.x = dot( fvTangent, fvLightDirection ); ');
- Add(' LightDirection.y = dot( fvBinormal, fvLightDirection ); ');
- Add(' LightDirection.z = dot( fvNormal, fvLightDirection ); ');
- Add(' ');
- Add(' LightDirection = normalize(LightDirection); ');
- Add(' ViewDirection = normalize(ViewDirection); ');
- Add('} ');
- end;
- end;
- procedure GetFragmentProgramCodeMP(const Code: TStrings; const UseSpecularMap: Boolean; const UseNormalMap: Boolean);
- begin
- with Code do
- begin
- Clear;
- Add('uniform vec4 fvAmbient; ');
- Add('uniform vec4 fvSpecular; ');
- Add('uniform vec4 fvDiffuse; ');
- Add(' ');
- Add('uniform float fLightPower; ');
- Add('uniform float fSpecularPower; ');
- Add('uniform float fSpecularSpread; ');
- if UseNormalMap then
- begin
- Add('uniform sampler2D bumpMap; ');
- Add('uniform float fBumpHeight; ');
- Add('uniform float fBumpSmoothness; ');
- end;
- Add(' ');
- Add('uniform sampler2D baseMap; ');
- if UseSpecularMap then
- Add('uniform sampler2D specMap; ');
- Add(' ');
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add('varying vec3 LightDirection; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- if UseNormalMap then
- Add(' vec3 fvNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * fBumpSmoothness) - fBumpHeight * fBumpSmoothness); ')
- else
- Add(' vec3 fvNormal = vec3(0.0, 0.0, 1);');
- Add(' ');
- Add(' float fNDotL = dot( fvNormal, LightDirection ); ');
- Add(' vec3 fvReflection = normalize( ( (fSpecularSpread * fvNormal ) * fNDotL ) - LightDirection ); ');
- Add(' ');
- Add(' float fRDotV = max( dot( fvReflection, -ViewDirection ), 0.0 ); ');
- Add(' ');
- Add(' vec4 fvBaseColor = texture2D( baseMap, Texcoord ); ');
- if UseSpecularMap then
- Add(' vec4 fvSpecColor = texture2D( specMap, Texcoord ) * fvSpecular; ')
- else
- Add(' vec4 fvSpecColor = fvSpecular; ');
- Add(' ');
- Add(' vec4 fvTotalDiffuse = clamp(fvDiffuse * fNDotL, 0.0, 1.0); ');
- Add(' ');
- Add(' // (fvTotalDiffuse + 0.2) / 1.2 is used for removing artefacts on the non-lit side ');
- Add(' vec4 fvTotalSpecular = clamp((pow(fRDotV, fSpecularPower ) ) * (fvTotalDiffuse + 0.2) / 1.2 * fvSpecColor, 0.0, 1.0); ');
- Add(' ');
- Add(' gl_FragColor = fLightPower * (fvBaseColor * ( fvAmbient + fvTotalDiffuse ) + fvTotalSpecular); ');
- Add('} ');
- end;
- end;
- procedure GetFragmentProgramCode(const Code: TStrings; const UseSpecularMap: Boolean; const UseNormalMap: Boolean);
- begin
- with Code do
- begin
- Clear;
- Add('uniform float fLightPower; ');
- Add('uniform float fSpecularPower; ');
- Add('uniform float fSpecularSpread; ');
- if UseNormalMap then
- begin
- Add('uniform sampler2D bumpMap; ');
- Add('uniform float fBumpHeight; ');
- Add('uniform float fBumpSmoothness; ');
- end;
- Add(' ');
- Add('uniform sampler2D baseMap; ');
- if UseSpecularMap then
- Add('uniform sampler2D specMap; ');
- Add(' ');
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add('varying vec3 LightDirection; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- if UseNormalMap then
- Add(' vec3 fvNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * fBumpSmoothness) - fBumpHeight * fBumpSmoothness); ')
- else
- Add(' vec3 fvNormal = vec3(0.0, 0.0, 1.0);');
- Add(' ');
- Add(' float fNDotL = dot( fvNormal, LightDirection ); ');
- Add(' vec3 fvReflection = normalize( ( (fSpecularSpread * fvNormal ) * fNDotL ) - LightDirection ); ');
- Add(' ');
- Add(' float fRDotV = max(dot( fvReflection, -ViewDirection ), 0.0); ');
- Add(' ');
- Add(' vec4 fvBaseColor = texture2D( baseMap, Texcoord ); ');
- if UseSpecularMap then
- Add(' vec4 fvSpecColor = texture2D( specMap, Texcoord ) * gl_LightSource[0].specular; ')
- else
- Add(' vec4 fvSpecColor = gl_LightSource[0].specular; ');
- Add(' ');
- Add(' vec4 fvTotalDiffuse = clamp(gl_LightSource[0].diffuse * fNDotL, 0.0, 1.0); ');
- Add(' ');
- Add(' // (fvTotalDiffuse + 0.2) / 1.2 is used for removing artefacts on the non-lit side ');
- Add(' vec4 fvTotalSpecular = clamp((pow(fRDotV, fSpecularPower ) ) * (fvTotalDiffuse + 0.2) / 1.2 * fvSpecColor, 0.0, 1.0); ');
- Add(' ');
- Add(' gl_FragColor = fLightPower * (fvBaseColor * ( gl_LightSource[0].ambient + fvTotalDiffuse ) + fvTotalSpecular); ');
- Add('} ');
- end;
- end;
- procedure GetMLVertexProgramCode(const Code: TStrings);
- begin
- with Code do
- begin
- Clear;
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add(' ');
- Add('varying vec3 fvViewDirection; ');
- Add('varying vec3 fvNormal; ');
- Add('varying vec3 fvBinormal; ');
- Add('varying vec3 fvTangent; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- Add(' gl_Position = ftransform(); ');
- Add(' Texcoord = gl_MultiTexCoord0.xy; ');
- Add(' ');
- Add(' fvViewDirection = (gl_ModelViewMatrix * gl_Vertex).xyz; ');
- Add(' ');
- Add(' fvNormal = gl_NormalMatrix * gl_Normal; ');
- Add(' fvBinormal = gl_NormalMatrix * gl_MultiTexCoord2.xyz; ');
- Add(' fvTangent = gl_NormalMatrix * gl_MultiTexCoord1.xyz; ');
- Add(' ');
- Add(' ViewDirection.x = dot( fvTangent, fvViewDirection ); ');
- Add(' ViewDirection.y = dot( fvBinormal, fvViewDirection ); ');
- Add(' ViewDirection.z = dot( fvNormal, fvViewDirection ); ');
- Add(' ');
- Add(' ViewDirection = normalize(ViewDirection); ');
- Add('} ');
- end;
- end;
- procedure GetMLFragmentProgramCodeBeg(const Code: TStrings; const UseSpecularMap: Boolean; const UseNormalMap: Boolean);
- begin
- with Code do
- begin
- Clear;
- Add('uniform float fLightPower; ');
- Add('uniform float fSpecularPower; ');
- Add('uniform float fSpecularSpread; ');
- if UseNormalMap then
- begin
- Add('uniform sampler2D bumpMap; ');
- Add('uniform float fBumpHeight; ');
- Add('uniform float fBumpSmoothness; ');
- end;
- Add(' ');
- Add('uniform sampler2D baseMap; ');
- if UseSpecularMap then
- Add('uniform sampler2D specMap; ');
- Add(' ');
- Add('varying vec2 Texcoord; ');
- Add('varying vec3 ViewDirection; ');
- Add(' ');
- Add('varying vec3 fvViewDirection; ');
- Add('varying vec3 fvNormal; ');
- Add('varying vec3 fvBinormal; ');
- Add('varying vec3 fvTangent; ');
- Add(' ');
- Add('void main( void ) ');
- Add('{ ');
- Add(' vec3 LightDirection;');
- Add(' vec3 fvLightDirection; ');
- Add(' ');
- if UseNormalMap then
- Add(' vec3 fvBumpNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * fBumpSmoothness) - fBumpHeight * fBumpSmoothness); ')
- else
- Add(' vec3 fvBumpNormal = vec3(0.0, 0.0, 1);');
- Add(' ');
- Add(' float fNDotL ; ');
- Add(' vec3 fvReflection ; ');
- Add(' float fRDotV ; ');
- Add(' vec4 fvBaseColor = texture2D( baseMap, Texcoord ); ');
- if UseSpecularMap then
- Add(' vec4 fvSpecColor = texture2D( specMap, Texcoord ); ')
- else
- Add(' vec4 fvSpecColor = vec4(1.0, 1.0, 1.0, 1.0); ');
- Add(' vec4 fvNewDiffuse ; ');
- Add(' vec4 fvTotalDiffuse = vec4(0, 0, 0, 0); ');
- Add(' vec4 fvTotalAmbient = vec4(0, 0, 0, 0); ');
- Add(' vec4 fvTotalSpecular = vec4(0, 0, 0, 0); ');
- end;
- end;
- procedure GetMLFragmentProgramCodeMid(const Code: TStrings; const CurrentLight: Integer);
- begin
- with Code do
- begin
- Add(' fvLightDirection = gl_LightSource[' + IntToStr(CurrentLight) + '].position.xyz - fvViewDirection; ');
- Add(' ');
- Add(' LightDirection.x = dot( fvTangent, fvLightDirection ); ');
- Add(' LightDirection.y = dot( fvBinormal, fvLightDirection ); ');
- Add(' LightDirection.z = dot( fvNormal, fvLightDirection ); ');
- Add(' LightDirection = normalize(LightDirection); ');
- Add(' ');
- Add(' fNDotL = dot( fvBumpNormal, LightDirection ); ');
- Add(' fvReflection = normalize( ( (fSpecularSpread * fvBumpNormal ) * fNDotL ) - LightDirection ); ');
- Add(' fRDotV = max( dot( fvReflection, -ViewDirection ), 0.0 ); ');
- Add(' fvNewDiffuse = clamp(gl_LightSource[' + IntToStr(CurrentLight) + '].diffuse * fNDotL, 0.0, 1.0); ');
- Add(' fvTotalDiffuse = min(fvTotalDiffuse + fvNewDiffuse, 1.0); ');
- Add(' fvTotalSpecular = min(fvTotalSpecular + clamp((pow(fRDotV, fSpecularPower ) ) * (fvNewDiffuse + 0.2) / 1.2 * (fvSpecColor * gl_LightSource[' + IntToStr(CurrentLight) + '].specular), 0.0, 1.0), 1.0); ');
- Add(' fvTotalAmbient = fvTotalAmbient + gl_LightSource[' + IntToStr(CurrentLight) + '].ambient; ');
- end;
- end;
- procedure GetMLFragmentProgramCodeEnd(const Code: TStrings; const FLightCount: Integer; const FLightCompensation: Single);
- var
- Temp: AnsiString;
- begin
- with Code do
- begin
- Str((1 + (FLightCount - 1) * FLightCompensation) / FLightCount :1 :1, Temp);
- if (FLightCount = 1) or (FLightCompensation = 1) then
- Add(' gl_FragColor = fLightPower * (fvBaseColor * ( fvTotalAmbient + fvTotalDiffuse ) + fvTotalSpecular); ')
- else
- Add(' gl_FragColor = fLightPower * (fvBaseColor * ( fvTotalAmbient + fvTotalDiffuse ) + fvTotalSpecular) * ' + string(Temp) + '; ');
- Add('} ');
- end;
- end;
- { TGLBaseCustomGLSLBumpShader }
- constructor TGLBaseCustomGLSLBumpShader.Create(AOwner: TComponent);
- begin
- inherited;
- FSpecularPower := 6;
- FSpecularSpread := 1.5;
- FLightPower := 1;
- FBumpHeight := 0.5;
- FBumpSmoothness := 300;
- TStringList(VertexProgram.Code).OnChange := nil;
- TStringList(FragmentProgram.Code).OnChange := nil;
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- end;
- procedure TGLBaseCustomGLSLBumpShader.DoApply(
- var rci: TGLRenderContextInfo; Sender: TObject);
- begin
- // Don't inherit not to call the event.
- GetGLSLProg.UseProgramObject;
- Param['fSpecularPower'].AsVector1f := FSpecularPower;
- Param['fSpecularSpread'].AsVector1f := FSpecularSpread;
- Param['fLightPower'].AsVector1f := FLightPower;
- if FSpecularTexture <> nil then
- Param['specMap'].AsTexture2D[2] := FSpecularTexture;
- {$IFNDEF USE_OPTIMIZATIONS}
- if FNormalTexture <> nil then
- {$ENDIF}
- begin
- Param['bumpMap'].AsTexture2D[1] := FNormalTexture;
- Param['fBumpHeight'].AsVector1f := FBumpHeight;
- Param['fBumpSmoothness'].AsVector1f := FBumpSmoothness;
- end;
- end;
- function TGLBaseCustomGLSLBumpShader.DoUnApply(
- var rci: TGLRenderContextInfo): Boolean;
- begin
- //don't inherit not to call the event
- Result := False;
- GetGLSLProg.EndUseProgramObject;
- end;
- function TGLBaseCustomGLSLBumpShader.GetMaterialLibrary: TGLAbstractMaterialLibrary;
- begin
- Result := FMaterialLibrary;
- end;
- function TGLBaseCustomGLSLBumpShader.GetNormalTextureName: TGLLibMaterialName;
- begin
- Result := FMaterialLibrary.GetNameOfTexture(FNormalTexture);
- if Result = '' then Result := FNormalTextureName;
- end;
- function TGLBaseCustomGLSLBumpShader.GetSpecularTextureName: TGLLibMaterialName;
- begin
- Result := FMaterialLibrary.GetNameOfTexture(FSpecularTexture);
- if Result = '' then Result := FSpecularTextureName;
- end;
- procedure TGLBaseCustomGLSLBumpShader.Notification(
- AComponent: TComponent; Operation: TOperation);
- var
- Index: Integer;
- begin
- inherited;
- if Operation = opRemove then
- if AComponent = FMaterialLibrary then
- if FMaterialLibrary <> nil then
- begin
- // Need to nil the textures that were ownned by it.
- if FNormalTexture <> nil then
- begin
- Index := FMaterialLibrary.Materials.GetTextureIndex(FNormalTexture);
- if Index <> -1 then
- SetNormalTexture(nil);
- end;
- if FSpecularTexture <> nil then
- begin
- Index := FMaterialLibrary.Materials.GetTextureIndex(FSpecularTexture);
- if Index <> -1 then
- SetSpecularTexture(nil);
- end;
- FMaterialLibrary := nil;
- end;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetMaterialLibrary(
- const Value: TGLMaterialLibrary);
- begin
- if FMaterialLibrary <> nil then
- FMaterialLibrary.RemoveFreeNotification(Self);
- FMaterialLibrary := Value;
- if FMaterialLibrary <> nil then
- begin
- FMaterialLibrary.FreeNotification(Self);
- if FNormalTextureName <> '' then
- SetNormalTextureName(FNormalTextureName);
- if FSpecularTextureName <> '' then
- SetSpecularTextureName(FSpecularTextureName);
- end
- else
- begin
- FNormalTextureName := '';
- FSpecularTextureName := '';
- end;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetNormalTexture(
- const Value: TGLTexture);
- begin
- FNormalTexture := Value;
- FinalizeShader;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetNormalTextureName(
- const Value: TGLLibMaterialName);
- begin
- if FMaterialLibrary = nil then
- begin
- FNormalTextureName := Value;
- if not (csLoading in ComponentState) then
- raise EGLSLBumpShaderException.Create(strErrorEx + strMatLibNotDefined);
- end
- else
- begin
- SetNormalTexture(FMaterialLibrary.TextureByName(Value));
- FNormalTextureName := '';
- end;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetSpecularTexture(
- const Value: TGLTexture);
- begin
- FSpecularTexture := Value;
- FinalizeShader;
- end;
- procedure TGLBaseCustomGLSLBumpShader.SetSpecularTextureName(
- const Value: TGLLibMaterialName);
- begin
- if FMaterialLibrary = nil then
- begin
- FSpecularTextureName := Value;
- if not (csLoading in ComponentState) then
- raise EGLSLBumpShaderException.Create(strErrorEx + strMatLibNotDefined);
- end
- else
- begin
- SetSpecularTexture(FMaterialLibrary.TextureByName(Value));
- FSpecularTextureName := '';
- end;
- end;
- { TGLBaseCustomGLSLBumpShaderMT }
- function TGLBaseCustomGLSLBumpShaderMT.GetMainTextureName: TGLLibMaterialName;
- begin
- Result := FMaterialLibrary.GetNameOfTexture(FMainTexture);
- if Result = '' then Result := FMainTextureName;
- end;
- procedure TGLBaseCustomGLSLBumpShaderMT.Notification(
- AComponent: TComponent; Operation: TOperation);
- var
- Index: Integer;
- begin
- if Operation = opRemove then
- if AComponent = FMaterialLibrary then
- if FMaterialLibrary <> nil then
- begin
- //need to nil the textures that were ownned by it
- if FMainTexture <> nil then
- begin
- Index := FMaterialLibrary.Materials.GetTextureIndex(FMainTexture);
- if Index <> -1 then
- FMainTexture := nil;
- end;
- end;
- inherited;
- end;
- procedure TGLBaseCustomGLSLBumpShaderMT.SetMainTextureName(
- const Value: TGLLibMaterialName);
- begin
- if FMaterialLibrary = nil then
- begin
- FMainTextureName := Value;
- if not (csLoading in ComponentState) then
- raise EGLSLBumpShaderException.Create(strErrorEx + strMatLibNotDefined);
- end
- else
- begin
- FMainTexture := FMaterialLibrary.TextureByName(Value);
- FMainTextureName := '';
- end;
- end;
- procedure TGLBaseCustomGLSLBumpShaderMT.SetMaterialLibrary(
- const Value: TGLMaterialLibrary);
- begin
- inherited;
- if FMaterialLibrary <> nil then
- begin
- if FMainTextureName <> '' then
- SetMainTextureName(FMainTextureName);
- end
- else
- FMainTextureName := '';
- end;
- { TGLCustomGLSLBumpShaderAM }
- constructor TGLCustomGLSLBumpShaderAM.Create(AOwner: TComponent);
- begin
- inherited;
- FAmbientColor := TGLColor.Create(Self);
- FDiffuseColor := TGLColor.Create(Self);
- FSpecularColor := TGLColor.Create(Self);
- // Setup initial parameters.
- FAmbientColor.SetColor(0.15, 0.15, 0.15, 1);
- FDiffuseColor.SetColor(1, 1, 1, 1);
- FSpecularColor.SetColor(1, 1, 1, 1);
- end;
- destructor TGLCustomGLSLBumpShaderAM.Destroy;
- begin
- FAmbientColor.Destroy;
- FDiffuseColor.Destroy;
- FSpecularColor.Destroy;
- inherited;
- end;
- procedure TGLCustomGLSLBumpShaderAM.DoApply(var rci: TGLRenderContextInfo;
- Sender: TObject);
- begin
- inherited;
- Param['fvAmbient'].AsVector4f := FAmbientColor.Color;
- Param['fvDiffuse'].AsVector4f := FDiffuseColor.Color;
- Param['fvSpecular'].AsVector4f := FSpecularColor.Color;
- Param['baseMap'].AsTexture2D[0] := FMainTexture;
- end;
- procedure TGLCustomGLSLBumpShaderAM.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- begin
- GetVertexProgramCode(VertexProgram.Code);
- GetFragmentProgramCodeMP(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- function TGLCustomGLSLBumpShaderAM.GetAlpha: Single;
- begin
- Result := (FAmbientColor.Alpha + FDiffuseColor.Alpha + FSpecularColor.Alpha) / 3;
- end;
- procedure TGLCustomGLSLBumpShaderAM.SetAlpha(const Value: Single);
- begin
- FAmbientColor.Alpha := Value;
- FDiffuseColor.Alpha := Value;
- FSpecularColor.Alpha := Value;
- end;
- { TGLCustomGLSLMLBumpShaderMT }
- constructor TGLCustomGLSLMLBumpShaderMT.Create(AOwner: TComponent);
- begin
- inherited;
- FLightSources := [1];
- FLightCompensation := 1;
- end;
- procedure TGLCustomGLSLMLBumpShaderMT.DoApply(var rci: TGLRenderContextInfo;
- Sender: TObject);
- begin
- inherited;
- Param['baseMap'].AsTexture2D[0] := FMainTexture;
- end;
- procedure TGLCustomGLSLMLBumpShaderMT.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- var
- I: Integer;
- lLightCount: Integer;
- begin
- GetMLVertexProgramCode(VertexProgram.Code);
-
- with FragmentProgram.Code do
- begin
- GetMLFragmentProgramCodeBeg(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- lLightCount := 0;
- // Repeat for all lights.
- for I := 0 to glsShaderMaxLightSources - 1 do
- if I + 1 in FLightSources then
- begin
- GetMLFragmentProgramCodeMid(FragmentProgram.Code, I);
- Inc(lLightCount);
- end;
- GetMLFragmentProgramCodeEnd(FragmentProgram.Code, lLightCount, FLightCompensation);
- end;
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- procedure TGLCustomGLSLMLBumpShaderMT.SetLightCompensation(
- const Value: Single);
- begin
- FLightCompensation := Value;
- FinalizeShader;
- end;
- procedure TGLCustomGLSLMLBumpShaderMT.SetLightSources(
- const Value: TGLLightSourceSet);
- begin
- Assert(Value <> [], strErrorEx + strShaderNeedsAtLeastOneLightSource);
- FLightSources := Value;
- FinalizeShader;
- end;
- { TGLCustomGLSLBumpShaderMT }
- procedure TGLCustomGLSLBumpShaderMT.DoApply(
- var rci: TGLRenderContextInfo; Sender: TObject);
- begin
- inherited;
- Param['baseMap'].AsTexture2D[0] := FMainTexture;
- end;
- procedure TGLCustomGLSLBumpShaderMT.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- begin
- GetVertexProgramCode(VertexProgram.Code);
- GetFragmentProgramCode(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- inherited;
- end;
- { TGLCustomGLSLBumpShader }
- procedure TGLCustomGLSLBumpShader.DoApply(var rci: TGLRenderContextInfo;
- Sender: TObject);
- begin
- inherited;
- Param['baseMap'].AsVector1i := 0; // Use the current texture.
- end;
- procedure TGLCustomGLSLBumpShader.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- begin
- GetVertexProgramCode(VertexProgram.Code);
- GetFragmentProgramCode(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- function TGLCustomGLSLBumpShader.GetShaderAlpha: Single;
- begin
- //ignore
- Result := -1;
- end;
- procedure TGLCustomGLSLBumpShader.GetShaderColorParams(var AAmbientColor,
- ADiffuseColor, ASpecularcolor: TVector4f);
- begin
- //ignore
- AAmbientColor := NullHmgVector;
- ADiffuseColor := NullHmgVector;
- ASpecularcolor := NullHmgVector;
- end;
- procedure TGLCustomGLSLBumpShader.GetShaderTextures(
- var Textures: array of TGLTexture);
- begin
- Textures[0] := FNormalTexture;
- Textures[1] := FSpecularTexture;
- end;
- procedure TGLCustomGLSLBumpShader.GetShaderMiscParameters(var ACadencer: TGLCadencer;
- var AMatLib: TGLMaterialLibrary; var ALightSources: TGLLightSourceSet);
- begin
- ACadencer := nil;
- AMatLib := FMaterialLibrary;
- ALightSources := [0];
- end;
- procedure TGLCustomGLSLBumpShader.SetShaderAlpha(const Value: Single);
- begin
- //ignore
- end;
- procedure TGLCustomGLSLBumpShader.SetShaderColorParams(const AAmbientColor,
- ADiffuseColor, ASpecularcolor: TVector4f);
- begin
- //ignore
- end;
- procedure TGLCustomGLSLBumpShader.SetShaderMiscParameters(
- const ACadencer: TGLCadencer; const AMatLib: TGLMaterialLibrary;
- const ALightSources: TGLLightSourceSet);
- begin
- SetMaterialLibrary(AMatLib);
- end;
- procedure TGLCustomGLSLBumpShader.SetShaderTextures(
- const Textures: array of TGLTexture);
- begin
- SetNormalTexture(Textures[0]);
- SetSpecularTexture(Textures[1]);
- end;
- function TGLCustomGLSLBumpShader.GetShaderDescription: string;
- begin
- Result := 'ShaderTexture1 is NormalMap, ShaderTexture2 is SpecularMap'
- end;
- { TGLCustomGLSLMLBumpShader }
- constructor TGLCustomGLSLMLBumpShader.Create(AOwner: TComponent);
- begin
- inherited;
- FLightSources := [1];
- FLightCompensation := 1;
- end;
- procedure TGLCustomGLSLMLBumpShader.DoApply(var rci: TGLRenderContextInfo;
- Sender: TObject);
- begin
- inherited;
- Param['baseMap'].AsVector1i := 0; // Use the current texture.
- end;
- procedure TGLCustomGLSLMLBumpShader.DoInitialize(var rci : TGLRenderContextInfo; Sender : TObject);
- var
- I: Integer;
- lLightCount: Integer;
- begin
- GetMLVertexProgramCode(VertexProgram.Code);
-
- with FragmentProgram.Code do
- begin
- GetMLFragmentProgramCodeBeg(FragmentProgram.Code, FSpecularTexture <> nil, FNormalTexture <> nil);
- lLightCount := 0;
- // Repeat for all lights.
- for I := 0 to glsShaderMaxLightSources - 1 do
- if I + 1 in FLightSources then
- begin
- GetMLFragmentProgramCodeMid(FragmentProgram.Code, I);
- Inc(lLightCount);
- end;
- GetMLFragmentProgramCodeEnd(FragmentProgram.Code, lLightCount, FLightCompensation);
- end;
- VertexProgram.Enabled := True;
- FragmentProgram.Enabled := True;
- inherited;
- end;
- procedure TGLCustomGLSLMLBumpShader.SetLightCompensation(
- const Value: Single);
- begin
- FLightCompensation := Value;
- FinalizeShader;
- end;
- procedure TGLCustomGLSLMLBumpShader.SetLightSources(
- const Value: TGLLightSourceSet);
- begin
- Assert(Value <> [], strErrorEx + strShaderNeedsAtLeastOneLightSource);
- FLightSources := Value;
- FinalizeShader;
- end;
- function TGLCustomGLSLMLBumpShader.GetShaderAlpha: Single;
- begin
- //ignore
- Result := -1;
- end;
- procedure TGLCustomGLSLMLBumpShader.GetShaderColorParams(var AAmbientColor,
- ADiffuseColor, ASpecularcolor: TVector4f);
- begin
- //ignore
- AAmbientColor := NullHmgVector;
- ADiffuseColor := NullHmgVector;
- ASpecularcolor := NullHmgVector;
- end;
- function TGLCustomGLSLMLBumpShader.GetShaderDescription: string;
- begin
- Result := 'ShaderTexture1 is NormalMap, ShaderTexture2 is SpecularMap';
- end;
- procedure TGLCustomGLSLMLBumpShader.GetShaderMiscParameters(
- var ACadencer: TGLCadencer; var AMatLib: TGLMaterialLibrary;
- var ALightSources: TGLLightSourceSet);
- begin
- ACadencer := nil;
- AMatLib := FMaterialLibrary;
- ALightSources := FLightSources;
- end;
- procedure TGLCustomGLSLMLBumpShader.GetShaderTextures(
- var Textures: array of TGLTexture);
- begin
- Textures[0] := FNormalTexture;
- Textures[1] := FSpecularTexture;
- end;
- procedure TGLCustomGLSLMLBumpShader.SetShaderAlpha(const Value: Single);
- begin
- //ignore
- end;
- procedure TGLCustomGLSLMLBumpShader.SetShaderColorParams(const AAmbientColor,
- ADiffuseColor, ASpecularcolor: TVector4f);
- begin
- //ignore
- end;
- procedure TGLCustomGLSLMLBumpShader.SetShaderMiscParameters(
- const ACadencer: TGLCadencer; const AMatLib: TGLMaterialLibrary;
- const ALightSources: TGLLightSourceSet);
- begin
- SetMaterialLibrary(AMatLib);
- SetLightSources(ALightSources);
- end;
- procedure TGLCustomGLSLMLBumpShader.SetShaderTextures(
- const Textures: array of TGLTexture);
- begin
- SetNormalTexture(Textures[0]);
- SetSpecularTexture(Textures[1]);
- end;
- initialization
- RegisterClasses([TGLSLBumpShaderMT, TGLSLBumpShader, TGLSLBumpShaderAM,
- TGLSLMLBumpShader, TGLSLMLBumpShaderMT]);
- end.
|