MsMpGeneric.glsl 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /// @file
  2. ///
  3. /// This a generic shader to fill the deferred shading buffers. You can always
  4. /// build your own if you dont need to write in all the buffers
  5. ///
  6. /// Control defines:
  7. /// DIFFUSE_MAPPING, NORMAL_MAPPING, SPECULAR_MAPPING, PARALLAX_MAPPING,
  8. /// ENVIRONMENT_MAPPING, ALPHA_TESTING
  9. #if defined(ALPHA_TESTING) && !defined(DIFFUSE_MAPPING)
  10. # error "Cannot have ALPHA_TESTING without DIFFUSE_MAPPING"
  11. #endif
  12. #if defined(DIFFUSE_MAPPING) || defined(NORMAL_MAPPING) || defined(SPECULAR_MAPPING)
  13. # define NEEDS_TEX_MAPPING 1
  14. #else
  15. # define NEEDS_TEX_MAPPING 0
  16. #endif
  17. #if defined(NORMAL_MAPPING) || defined(PARALLAX_MAPPING)
  18. #define NEEDS_TANGENT 1
  19. #else
  20. #define NEEDS_TANGENT 0
  21. #endif
  22. #pragma anki start vertexShader
  23. /// @name Attributes
  24. /// @{
  25. in vec3 position;
  26. in vec3 normal;
  27. #if NEEDS_TEX_MAPPING
  28. in vec2 texCoords;
  29. #endif
  30. #if NEEDS_TANGENT
  31. in vec4 tangent;
  32. #endif
  33. /// @}
  34. /// @name Uniforms
  35. /// @{
  36. uniform mat4 modelMat;
  37. uniform mat4 viewMat;
  38. uniform mat4 projectionMat;
  39. uniform mat4 modelViewMat;
  40. uniform mat3 normalMat;
  41. uniform mat4 modelViewProjectionMat;
  42. /// @}
  43. /// @name Varyings
  44. /// @{
  45. out vec3 vNormal;
  46. out vec2 vTexCoords;
  47. out vec3 vTangent;
  48. out float vTangentW;
  49. out vec3 vVertPosViewSpace; ///< For env mapping. AKA view vector
  50. /// @}
  51. //==============================================================================
  52. // main =
  53. //==============================================================================
  54. void main()
  55. {
  56. // calculate the vert pos, normal and tangent
  57. vNormal = normalMat * normal;
  58. gl_Position = modelViewProjectionMat * vec4(position, 1.0);
  59. // calculate the rest
  60. #if NEEDS_TEX_MAPPING
  61. vTexCoords = texCoords;
  62. #endif
  63. #if NEEDS_TANGENT
  64. vTangent = normalMat * vec3(tangent);
  65. vTangentW = tangent.w;
  66. #endif
  67. #if defined(ENVIRONMENT_MAPPING) || defined(PARALLAX_MAPPING)
  68. vVertPosViewSpace = vec3(modelViewMat * vec4(position, 1.0));
  69. #endif
  70. }
  71. #pragma anki start fragmentShader
  72. /// @note The process of calculating the diffuse color for the diffuse MSFAI is
  73. /// divided into two parts. The first happens before the normal calculation and
  74. /// the other just after it. In the first part we read the texture (or the
  75. /// gl_Color) and we set the _diffColl_. In case of grass we discard. In the
  76. /// second part we calculate a SEM color and we combine it with the _diffColl_.
  77. /// We cannot put the second part before normal calculation because SEM needs
  78. /// the _normal_. Also we cannot put the first part after normal calculation
  79. /// because in case of grass we will waste calculations for the normal. For
  80. /// that two reasons we split the diffuse calculations in two parts
  81. #pragma anki include "shaders/Pack.glsl"
  82. #if defined(DIFFUSE_MAPPING)
  83. uniform sampler2D diffuseMap;
  84. #endif
  85. #if defined(NORMAL_MAPPING)
  86. uniform sampler2D normalMap;
  87. #endif
  88. #if defined(SPECULAR_MAPPING)
  89. uniform sampler2D specularMap;
  90. #endif
  91. #if defined(PARALLAX_MAPPING)
  92. uniform sampler2D heightMap;
  93. #endif
  94. #if defined(ENVIRONMENT_MAPPING)
  95. uniform sampler2D environmentMap;
  96. #endif
  97. uniform float shininess = 50.0;
  98. uniform vec3 diffuseCol = vec3(1.0, 0.0, 1.0);
  99. uniform vec3 specularCol = vec3(1.0, 0.0, 1.0);
  100. #if defined(ALPHA_TESTING)
  101. /// Below this value the pixels are getting discarded
  102. uniform float alphaTestingTolerance = 0.5;
  103. #endif
  104. uniform float blurring = 0.0;
  105. in vec3 vNormal;
  106. in vec3 vTangent;
  107. in float vTangentW;
  108. in vec2 vTexCoords;
  109. in vec3 vVertPosViewSpace;
  110. // @todo
  111. in vec3 eye;
  112. layout(location = 0) out vec3 fMsNormalFai;
  113. layout(location = 1) out vec3 fMsDiffuseFai;
  114. layout(location = 2) out vec4 fMsSpecularFai;
  115. const float MAX_SHININESS = 128.0;
  116. //==============================================================================
  117. // Normal funcs =
  118. //==============================================================================
  119. /// @param[in] normal The fragment's normal in view space
  120. /// @param[in] tangent The tangent
  121. /// @param[in] tangent Extra stuff for the tangent
  122. /// @param[in] map The map
  123. /// @param[in] texCoords Texture coordinates
  124. vec3 getNormalUsingMap(in vec3 normal, in vec3 tangent, in float tangentW,
  125. in sampler2D map, in vec2 texCoords)
  126. {
  127. vec3 n = normalize(normal);
  128. vec3 t = normalize(tangent);
  129. vec3 b = cross(n, t) * tangentW;
  130. mat3 tbnMat = mat3(t, b, n);
  131. vec3 nAtTangentspace = (texture2D(map, texCoords).rgb - 0.5) * 2.0;
  132. return normalize(tbnMat * nAtTangentspace);
  133. }
  134. /// Just normalize
  135. vec3 getNormalSimple(in vec3 normal)
  136. {
  137. return normalize(normal);
  138. }
  139. //==============================================================================
  140. // doEnvMapping =
  141. //==============================================================================
  142. /// Environment mapping calculations
  143. /// @param[in] vertPosViewSpace Fragment position in view space
  144. /// @param[in] normal Fragment's normal in view space as well
  145. /// @param[in] map The env map
  146. /// @return The color
  147. vec3 doEnvMapping(in vec3 vertPosViewSpace, in vec3 normal, in sampler2D map)
  148. {
  149. // In case of normal mapping I could play with vertex's normal but this
  150. // gives better results and its allready computed
  151. vec3 u = normalize(vertPosViewSpace);
  152. vec3 r = reflect(u, normal);
  153. r.z += 1.0;
  154. float m = 2.0 * length(r);
  155. vec2 semTexCoords = r.xy / m + 0.5;
  156. vec3 semCol = texture2D(map, semTexCoords).rgb;
  157. return semCol;
  158. }
  159. //==============================================================================
  160. // doAlpha =
  161. //==============================================================================
  162. /// Using a 4-channel texture and a tolerance discard the fragment if the
  163. /// texture's alpha is less than the tolerance
  164. /// @param[in] map The diffuse map
  165. /// @param[in] tolerance Tolerance value
  166. /// @param[in] texCoords Texture coordinates
  167. /// @return The RGB channels of the map
  168. vec3 doAlpha(in sampler2D map, in float tolerance, in vec2 texCoords)
  169. {
  170. vec4 col = texture2D(map, texCoords);
  171. if(col.a < tolerance)
  172. {
  173. discard;
  174. }
  175. return col.rgb;
  176. }
  177. //==============================================================================
  178. // main =
  179. //==============================================================================
  180. void main()
  181. {
  182. //
  183. // Paralax Mapping Calculations
  184. // The code below reads the height map, makes some calculations and returns
  185. // a new texCoords
  186. //
  187. #if defined(PARALLAX_MAPPING)
  188. /*const float _scale = 0.04;
  189. const float _bias = scale * 0.4;
  190. vec3 _norm_eye = normalize(eye);
  191. float _h = texture2D(heightMap, vTexCoords).r;
  192. float _height = _scale * _h - _bias;
  193. vec2 _superTexCoords__v2f = _height * _norm_eye.xy + vTexCoords;*/
  194. vec2 _superTexCoords_ = vTexCoords;
  195. const float maxStepCount = 100.0;
  196. float nSteps = maxStepCount * length(_superTexCoords_);
  197. vec3 dir = vVertPosViewSpace;
  198. dir.xy /= 8.0;
  199. dir /= -nSteps * dir.z;
  200. float diff0, diff1 = 1.0 - texture2D(heightMap, _superTexCoords_).a;
  201. if(diff1 > 0.0)
  202. {
  203. do
  204. {
  205. _superTexCoords_ += dir.xy;
  206. diff0 = diff1;
  207. diff1 = texture2D(heightMap, _superTexCoords_).w;
  208. } while(diff1 > 0.0);
  209. _superTexCoords_.xy += (diff1 / (diff0 - diff1)) * dir.xy;
  210. }
  211. #else
  212. # define _superTexCoords_ vTexCoords
  213. #endif
  214. //
  215. // Diffuse Calculations (Part I)
  216. // Get the color from the diffuse map and discard if alpha testing is on
  217. // and alpha is zero
  218. //
  219. vec3 _diffColl_;
  220. #if defined(DIFFUSE_MAPPING)
  221. # if defined(ALPHA_TESTING)
  222. _diffColl_ = doAlpha(diffuseMap, alphaTestingTolerance, _superTexCoords_);
  223. # else // no alpha
  224. _diffColl_ = texture2D(diffuseMap, _superTexCoords_).rgb;
  225. # endif
  226. _diffColl_ *= diffuseCol.rgb;
  227. #else // no diff mapping
  228. _diffColl_ = diffuseCol.rgb;
  229. #endif
  230. //
  231. // Normal Calculations
  232. // Either use a normap map and make some calculations or use the vertex
  233. // normal
  234. //
  235. #if defined(NORMAL_MAPPING)
  236. vec3 _normal_ = getNormalUsingMap(vNormal, vTangent, vTangentW,
  237. normalMap, _superTexCoords_);
  238. #else
  239. vec3 _normal_ = getNormalSimple(vNormal);
  240. #endif
  241. //
  242. // Diffuse Calculations (Part II)
  243. // If SEM is enabled make some calculations (using the vVertPosViewSpace,
  244. // environmentMap and the _normal_) and
  245. // combine colors of SEM and the _diffColl_
  246. //
  247. #if defined(ENVIRONMENT_MAPPING)
  248. // blend existing color with the SEM texture map
  249. _diffColl_ += doEnvMapping(vVertPosViewSpace, _normal_, environmentMap);
  250. #endif
  251. //
  252. // Specular Calculations
  253. //
  254. #if defined(SPECULAR_MAPPING)
  255. vec4 _specularCol_ = vec4(
  256. texture2D(specularMap, _superTexCoords_).rgb * specularCol,
  257. shininess / MAX_SHININESS);
  258. #else // no specular map
  259. vec4 _specularCol_ = vec4(specularCol, shininess / MAX_SHININESS);
  260. #endif
  261. //
  262. // Final Stage. Write all data
  263. //
  264. fMsNormalFai = vec3(packNormal(_normal_), blurring);
  265. fMsDiffuseFai = _diffColl_;
  266. fMsSpecularFai = _specularCol_;
  267. }