GLSL.ShaderGooch.pas 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLSL.ShaderGooch;
  5. (*
  6. Gooch shader : Gooch shading is used to substitute photorealistic
  7. rendering by rendering that focuses on structore and shape of the object.
  8. Instead of usage of light and shadow, Gooch shading uses concept of warm and cool colors.
  9. Standard Blinn-Phong shading only modulates base color of the object.
  10. 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
  12. *)
  13. interface
  14. {$I GLScene.inc}
  15. uses
  16. Winapi.OpenGLext,
  17. System.Classes,
  18. OpenGLTokens,
  19. GLScene,
  20. GLBaseClasses,
  21. GLState,
  22. GLContext,
  23. GLRenderContextInfo,
  24. GLVectorGeometry,
  25. GLCoordinates,
  26. GLTextureFormat,
  27. GLColor,
  28. GLTexture,
  29. GLMaterial,
  30. GLSL.Shader,
  31. GLS.ShaderCustom;
  32. // Custom class for GLSLSimpleGoochShader.
  33. type
  34. TGLCustomGLSLSimpleGoochShader = class(TGLCustomGLSLShader)
  35. private
  36. FDiffuseColor : TGLColor;
  37. FWarmColor : TGLColor;
  38. FCoolColor : TGLColor;
  39. FSpecularColor : TGLColor;
  40. FAmbientColor : TGLColor;
  41. FDiffuseWarm : Single;
  42. FDiffuseCool : Single;
  43. FAmbientFactor : Single;
  44. FDiffuseFactor : Single;
  45. FSpecularFactor : Single;
  46. FBlendingMode: TGLBlendingModeEx;
  47. procedure SetDiffuseColor(AValue: TGLColor);
  48. procedure SetAmbientColor(AValue: TGLColor);
  49. procedure SetSpecularColor(AValue: TGLColor);
  50. procedure SetWarmColor(AValue: TGLColor);
  51. procedure SetCoolColor(AValue: TGLColor);
  52. protected
  53. procedure DoApply(var rci : TGLRenderContextInfo; Sender : TObject); override;
  54. function DoUnApply(var rci: TGLRenderContextInfo): Boolean; override;
  55. public
  56. constructor Create(AOwner : TComponent); override;
  57. destructor Destroy; override;
  58. property DiffuseColor : TGLColor read FDiffuseColor Write setDiffuseColor;
  59. property WarmColor : TGLColor read FWarmColor Write setWarmColor;
  60. property CoolColor : TGLColor Read FCoolColor Write setCoolColor;
  61. property SpecularColor : TGLColor Read FSpecularColor Write setSpecularColor;
  62. property AmbientColor : TGLColor Read FAmbientColor Write setAmbientColor;
  63. property WarmFactor : Single Read FDiffuseWarm Write FDiffuseWarm;
  64. property CoolFactor : Single Read FDiffuseCool Write FDiffuseCool;
  65. property AmbientFactor : Single Read FAmbientFactor Write FAmbientFactor;
  66. property DiffuseFactor : Single Read FDiffuseFactor Write FDiffuseFactor;
  67. property SpecularFactor : Single Read FSpecularFactor Write FSpecularFactor;
  68. property BlendingMode: TGLBlendingModeEx read FBlendingMode write FBlendingMode default bmxOpaque;
  69. end;
  70. type
  71. TGLSLSimpleGoochShader = class(TGLCustomGLSLSimpleGoochShader)
  72. published
  73. property DiffuseColor;
  74. property WarmColor;
  75. property CoolColor;
  76. property SpecularColor;
  77. property AmbientColor;
  78. property WarmFactor;
  79. property CoolFactor;
  80. property AmbientFactor;
  81. property DiffuseFactor;
  82. property SpecularFactor;
  83. end;
  84. //-------------------------------------------------------------
  85. implementation
  86. //-------------------------------------------------------------
  87. //-------------------------------------------------------------
  88. // TGLCustomGLSLSimpleGoochShader
  89. //-------------------------------------------------------------
  90. constructor TGLCustomGLSLSimpleGoochShader.Create(AOwner: TComponent);
  91. begin
  92. inherited;
  93. with VertexProgram.Code do
  94. begin
  95. Clear;
  96. Add('varying vec3 vNormal; ');
  97. Add('varying vec3 lightVec; ');
  98. Add('varying vec3 viewVec; ');
  99. Add('varying vec3 ReflectVec; ');
  100. Add(' ');
  101. Add('void main() ');
  102. Add('{ ');
  103. Add(' gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; ');
  104. Add(' vec4 lightPos = gl_LightSource[0].position;');
  105. Add(' vec4 vert = gl_ModelViewMatrix * gl_Vertex; ');
  106. Add(' vec3 normal = gl_NormalMatrix * gl_Normal; ');
  107. Add(' vNormal = normalize(normal); ');
  108. Add(' lightVec = vec3(lightPos - vert); ');
  109. Add(' ReflectVec = normalize(reflect(-lightVec, vNormal)); ');
  110. Add(' viewVec = -vec3(vert); ');
  111. Add('} ');
  112. end;
  113. with FragmentProgram.Code do
  114. begin
  115. Clear;
  116. Add('uniform vec4 SurfaceColor; ');
  117. Add('uniform vec4 WarmColor; ');
  118. Add('uniform vec4 CoolColor; ');
  119. Add('uniform vec4 SpecularColor; ');
  120. Add('uniform vec4 AmbientColor; ');
  121. Add('uniform float DiffuseWarm; ');
  122. Add('uniform float DiffuseCool; ');
  123. Add('uniform float AmbientFactor; ');
  124. Add('uniform float DiffuseFactor; ');
  125. Add('uniform float SpecularFactor; ');
  126. Add('varying vec3 vNormal; ');
  127. Add('varying vec3 lightVec; ');
  128. Add('varying vec3 viewVec; ');
  129. Add('varying vec3 ReflectVec; ');
  130. Add(' ');
  131. Add('void main() ');
  132. Add('{ ');
  133. Add('vec3 L = normalize(lightVec); ');
  134. Add('vec3 V = normalize(viewVec); ');
  135. Add('vec3 halfAngle = normalize(L + V); ');
  136. Add('float NdotL = (dot(L, vNormal) + 1.0) * 0.5; ');
  137. Add('float NdotH = clamp(dot(halfAngle, vNormal), 0.0, 1.0); ');
  138. Add('// "Half-Lambert" technique for more pleasing diffuse term ');
  139. Add('float diffuse = 0.5 * NdotL + 0.5; ');
  140. Add('vec3 nreflect = normalize(ReflectVec); ');
  141. Add('float specular = max(dot(nreflect, V), 0.0); ');
  142. Add('specular = pow(specular, 64.0); ');
  143. Add('vec4 kCool = min(CoolColor + DiffuseCool * SurfaceColor, 1.0); ');
  144. Add('vec4 kWarm = min(WarmColor + DiffuseWarm * SurfaceColor, 1.0); ');
  145. Add('vec4 Cgooch = mix(kWarm, kCool, diffuse); ');
  146. Add('vec3 result = AmbientFactor * AmbientColor.rgb + DiffuseFactor * Cgooch.rgb + SpecularColor.rgb * SpecularFactor *specular; ');
  147. Add('gl_FragColor = vec4(result,SurfaceColor.a); ');
  148. Add('} ');
  149. end;
  150. // Initial stuff.
  151. FDiffuseColor := TGLColor.Create(self);
  152. FDiffuseColor.SetColor(0.75,0.75,0.75,1.0);
  153. FWarmColor := TGLColor.Create(self);
  154. FWarmColor.SetColor(0.88,0.81,0.49,1.0);
  155. FCoolColor := TGLColor.Create(self);
  156. FCoolColor.SetColor(0.58,0.10,0.76,1.0);
  157. FAmbientColor := TGLColor.Create(self);
  158. FAmbientColor.SetColor(0.3,0.3,0.3,1.0);
  159. FSpecularColor := TGLColor.Create(self);
  160. FSpecularColor.SetColor(1.0,1.0,1.0,1.0);
  161. FDiffuseWarm := 0.55;
  162. FDiffuseCool := 0.30;
  163. FAmbientFactor := 1.0;
  164. FDiffuseFactor :=0.8;
  165. FSpecularFactor :=0.9;
  166. FBlendingMode:=bmxOpaque;
  167. end;
  168. destructor TGLCustomGLSLSimpleGoochShader.Destroy;
  169. begin
  170. FDiffuseColor.Free;
  171. FWarmColor.Free;
  172. FCoolColor.Free;
  173. FSpecularColor.Free;
  174. FAmbientColor.Free;
  175. inherited;
  176. end;
  177. procedure TGLCustomGLSLSimpleGoochShader.DoApply(var rci: TGLRenderContextInfo;
  178. Sender: TObject);
  179. begin
  180. GetGLSLProg.UseProgramObject;
  181. param['SurfaceColor'].AsVector4f := FDiffuseColor.Color;
  182. param['WarmColor'].AsVector4f := FWarmColor.Color;
  183. param['CoolColor'].AsVector4f := FCoolColor.Color;
  184. param['AmbientColor'].AsVector4f := FAmbientColor.Color;
  185. param['SpecularColor'].AsVector4f := FSpecularColor.Color;
  186. param['DiffuseWarm'].AsVector1f := FDiffuseWarm;
  187. param['DiffuseCool'].AsVector1f := FDiffuseCool;
  188. param['AmbientFactor'].AsVector1f := FAmbientFactor;
  189. param['DiffuseFactor'].AsVector1f := FDiffuseFactor;
  190. param['SpecularFactor'].AsVector1f := FSpecularFactor;
  191. // gl.PushAttrib(GL_COLOR_BUFFER_BIT);
  192. ApplyBlendingModeEx(FBlendingMode);
  193. // gl.Enable(GL_BLEND);
  194. // gl.BlendFunc(cGLBlendFunctionToGLEnum[FBlendSrc],cGLBlendFunctionToGLEnum[FBlendDst]);
  195. end;
  196. function TGLCustomGLSLSimpleGoochShader.DoUnApply(var rci: TGLRenderContextInfo): Boolean;
  197. begin
  198. gl.ActiveTexture(GL_TEXTURE0_ARB);
  199. GetGLSLProg.EndUseProgramObject;
  200. UnApplyBlendingModeEx;
  201. // gl.PopAttrib;
  202. Result := False;
  203. end;
  204. procedure TGLCustomGLSLSimpleGoochShader.SetDiffuseColor(AValue: TGLColor);
  205. begin
  206. FDiffuseColor.DirectColor := AValue.Color;
  207. end;
  208. procedure TGLCustomGLSLSimpleGoochShader.SetAmbientColor(AValue: TGLColor);
  209. begin
  210. FAmbientColor.DirectColor := AValue.Color;
  211. end;
  212. procedure TGLCustomGLSLSimpleGoochShader.SetSpecularColor(AValue: TGLColor);
  213. begin
  214. FSpecularColor.DirectColor := AValue.Color;
  215. end;
  216. procedure TGLCustomGLSLSimpleGoochShader.SetWarmColor(AValue: TGLColor);
  217. begin
  218. FWarmColor.DirectColor := AValue.Color;
  219. end;
  220. procedure TGLCustomGLSLSimpleGoochShader.SetCoolColor(AValue: TGLColor);
  221. begin
  222. FCoolColor.DirectColor := AValue.Color;
  223. end;
  224. end.