MsCommonFrag.glsl 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. // Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include "shaders/Pack.glsl"
  6. #include "shaders/MsFsCommon.glsl"
  7. //
  8. // Input
  9. //
  10. #if NVIDIA_LINK_ERROR_WORKAROUND
  11. layout(location = 0) in highp vec4 in_uv;
  12. #else
  13. layout(location = 0) in highp vec2 in_uv;
  14. #endif
  15. #if PASS == COLOR
  16. layout(location = 1) in mediump vec3 in_normal;
  17. layout(location = 2) in mediump vec4 in_tangent;
  18. #if CALC_BITANGENT_IN_VERT
  19. layout(location = 3) in mediump vec3 in_bitangent;
  20. #endif
  21. layout(location = 4) in mediump vec3 in_vertPosViewSpace;
  22. layout(location = 5) in mediump vec3 in_eyeTangentSpace; // Parallax
  23. layout(location = 6) in mediump vec3 in_normalTangentSpace; // Parallax
  24. #endif
  25. //
  26. // Output
  27. //
  28. #if PASS == COLOR
  29. layout(location = 0) out vec4 out_msRt0;
  30. layout(location = 1) out vec4 out_msRt1;
  31. layout(location = 2) out vec4 out_msRt2;
  32. #define out_msRt0_DEFINED
  33. #define out_msRt1_DEFINED
  34. #define out_msRt2_DEFINED
  35. #endif
  36. // Getter
  37. #if PASS == COLOR
  38. #define getNormal_DEFINED
  39. vec3 getNormal()
  40. {
  41. return normalize(in_normal);
  42. }
  43. #endif
  44. // Getter
  45. #if PASS == COLOR
  46. #define getTangent_DEFINED
  47. vec4 getTangent()
  48. {
  49. return in_tangent;
  50. }
  51. #endif
  52. // Getter
  53. #define getTextureCoord_DEFINED
  54. vec2 getTextureCoord()
  55. {
  56. #if NVIDIA_LINK_ERROR_WORKAROUND
  57. return in_uv.xy;
  58. #else
  59. return in_uv;
  60. #endif
  61. }
  62. // Getter
  63. #if PASS == COLOR
  64. #define getPositionViewSpace_DEFINED
  65. vec3 getPositionViewSpace()
  66. {
  67. #if TESSELLATION
  68. return vec3(0.0);
  69. #else
  70. return in_vertPosViewSpace;
  71. #endif
  72. }
  73. #endif
  74. // Do normal mapping
  75. #if PASS == COLOR
  76. #define readNormalFromTexture_DEFINED
  77. vec3 readNormalFromTexture(in vec3 normal, in vec4 tangent, in sampler2D map, in highp vec2 texCoords)
  78. {
  79. #if LOD > 0
  80. return normalize(normal);
  81. #else
  82. // First read the texture
  83. vec3 nAtTangentspace = normalize((texture(map, texCoords).rgb - 0.5) * 2.0);
  84. vec3 n = normal; // Assume that getNormal() is called
  85. vec3 t = normalize(tangent.xyz);
  86. #if CALC_BITANGENT_IN_VERT
  87. vec3 b = normalize(in_bitangent.xyz);
  88. #else
  89. vec3 b = cross(n, t) * tangent.w;
  90. #endif
  91. mat3 tbnMat = mat3(t, b, n);
  92. return tbnMat * nAtTangentspace;
  93. #endif
  94. }
  95. #endif
  96. // Do normal mapping by combining normal maps
  97. #if PASS == COLOR
  98. #define combineNormalFromTextures_DEFINED
  99. vec3 combineNormalFromTextures(in vec3 normal,
  100. in vec4 tangent,
  101. in sampler2D map,
  102. in sampler2D map2,
  103. in highp vec2 texCoords,
  104. in float texCoords2Scale)
  105. {
  106. #if LOD > 0
  107. return normalize(normal);
  108. #else
  109. // First read the textures
  110. vec3 nAtTangentspace0 = normalize((texture(map, texCoords).rgb - 0.5) * 2.0);
  111. vec3 nAtTangentspace1 = normalize((texture(map2, texCoords * texCoords2Scale).rgb - 0.5) * 2.0);
  112. vec3 nAtTangentspace = (nAtTangentspace0 + nAtTangentspace1) / 2.0;
  113. vec3 n = normal; // Assume that getNormal() is called
  114. vec3 t = normalize(tangent.xyz);
  115. vec3 b = cross(n, t) * tangent.w;
  116. mat3 tbnMat = mat3(t, b, n);
  117. return tbnMat * nAtTangentspace;
  118. #endif
  119. }
  120. #endif
  121. // Do environment mapping
  122. #if PASS == COLOR
  123. #define readEnvironmentColor_DEFINED
  124. vec3 readEnvironmentColor(in vec3 vertPosViewSpace, in vec3 normal, in sampler2D map)
  125. {
  126. // In case of normal mapping I could play with vertex's normal but this gives better results and its allready
  127. // computed
  128. vec3 u = normalize(vertPosViewSpace);
  129. vec3 r = reflect(u, normal);
  130. r.z += 1.0;
  131. float m = 2.0 * length(r);
  132. vec2 semTexCoords = r.xy / m + 0.5;
  133. vec3 semCol = texture(map, semTexCoords).rgb;
  134. return semCol;
  135. }
  136. #endif
  137. // Using a 4-channel texture and a tolerance discard the fragment if the texture's alpha is less than the tolerance
  138. #define readTextureRgbAlphaTesting_DEFINED
  139. vec3 readTextureRgbAlphaTesting(in sampler2D map, in highp vec2 texCoords, in float tolerance)
  140. {
  141. #if PASS == COLOR
  142. vec4 col = vec4(texture(map, texCoords));
  143. if(col.a < tolerance)
  144. {
  145. discard;
  146. }
  147. return col.rgb;
  148. #else // Depth
  149. #if LOD > 0
  150. return vec3(0.0);
  151. #else
  152. float a = float(texture(map, texCoords).a);
  153. if(a < tolerance)
  154. {
  155. discard;
  156. }
  157. return vec3(0.0);
  158. #endif
  159. #endif
  160. }
  161. // Just read the RGB color from texture
  162. #if PASS == COLOR
  163. #define readRgbFromTexture_DEFINED
  164. vec3 readRgbFromTexture(in sampler2D tex, in highp vec2 texCoords)
  165. {
  166. return vec3(texture(tex, texCoords)).rgb;
  167. }
  168. #endif
  169. // Just read the RGB color from cube texture
  170. #if PASS == COLOR
  171. #define readRgbFromCubeTexture_DEFINED
  172. vec3 readRgbFromCubeTexture(in samplerCube tex, in mediump vec3 texCoord)
  173. {
  174. return texture(tex, texCoord).rgb;
  175. }
  176. #endif
  177. // Just read the R color from texture
  178. #if PASS == COLOR
  179. #define readRFromTexture_DEFINED
  180. float readRFromTexture(in sampler2D tex, in highp vec2 texCoords)
  181. {
  182. return vec3(texture(tex, texCoords)).r;
  183. }
  184. #endif
  185. #define computeTextureCoordParallax_DEFINED
  186. vec2 computeTextureCoordParallax(in sampler2D heightMap, in vec2 uv, in float heightMapScale)
  187. {
  188. #if PASS == COLOR && LOD == 0
  189. const uint MAX_SAMPLES = 25;
  190. const uint MIN_SAMPLES = 1;
  191. const float MAX_EFFECTIVE_DISTANCE = 32.0;
  192. // Get that because we are sampling inside a loop
  193. vec2 dPdx = dFdx(uv);
  194. vec2 dPdy = dFdy(uv);
  195. vec3 eyeTangentSpace = in_eyeTangentSpace;
  196. vec3 normTangentSpace = in_normalTangentSpace;
  197. float parallaxLimit = -length(eyeTangentSpace.xy) / eyeTangentSpace.z;
  198. parallaxLimit *= heightMapScale;
  199. vec2 offsetDir = normalize(eyeTangentSpace.xy);
  200. vec2 maxOffset = offsetDir * parallaxLimit;
  201. vec3 E = normalize(eyeTangentSpace);
  202. float factor0 = -dot(E, normTangentSpace);
  203. float factor1 = in_vertPosViewSpace.z / -MAX_EFFECTIVE_DISTANCE;
  204. float factor = (1.0 - factor0) * (1.0 - factor1);
  205. float sampleCountf = mix(float(MIN_SAMPLES), float(MAX_SAMPLES), factor);
  206. float stepSize = 1.0 / sampleCountf;
  207. float crntRayHeight = 1.0;
  208. vec2 crntOffset = vec2(0.0);
  209. vec2 lastOffset = vec2(0.0);
  210. float lastSampledHeight = 1.0;
  211. float crntSampledHeight = 1.0;
  212. uint crntSample = 0;
  213. uint sampleCount = uint(sampleCountf);
  214. while(crntSample < sampleCount)
  215. {
  216. crntSampledHeight = textureGrad(heightMap, uv + crntOffset, dPdx, dPdy).r;
  217. if(crntSampledHeight > crntRayHeight)
  218. {
  219. float delta1 = crntSampledHeight - crntRayHeight;
  220. float delta2 = (crntRayHeight + stepSize) - lastSampledHeight;
  221. float ratio = delta1 / (delta1 + delta2);
  222. crntOffset = mix(crntOffset, lastOffset, ratio);
  223. crntSample = sampleCount + 1;
  224. }
  225. else
  226. {
  227. crntSample++;
  228. crntRayHeight -= stepSize;
  229. lastOffset = crntOffset;
  230. crntOffset += stepSize * maxOffset;
  231. lastSampledHeight = crntSampledHeight;
  232. }
  233. }
  234. return uv + crntOffset;
  235. #else
  236. return uv;
  237. #endif
  238. }
  239. // Write the data to FAIs
  240. #if PASS == COLOR
  241. #define writeRts_DEFINED
  242. void writeRts(in vec3 diffColor, // from 0 to 1
  243. in vec3 normal,
  244. in vec3 specularColor,
  245. in float roughness,
  246. in float subsurface,
  247. in float emission,
  248. in float metallic)
  249. {
  250. GbufferInfo g;
  251. g.diffuse = diffColor;
  252. g.normal = normal;
  253. g.specular = specularColor;
  254. g.roughness = roughness;
  255. g.subsurface = subsurface;
  256. g.emission = emission;
  257. g.metallic = metallic;
  258. writeGBuffer(g, out_msRt0, out_msRt1, out_msRt2);
  259. }
  260. #endif