lightingPass_optimized.frag 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361
  1. #version 430 core
  2. #pragma debug(on)
  3. //#extension GL_NV_shadow_samplers_cube : enable
  4. //#extension ARB_program_interface_query : enable
  5. #extension GL_ARB_bindless_texture: require
  6. layout(location = 0) out vec4 a_outColor;
  7. layout(location = 1) out vec4 a_outBloom;
  8. noperspective in vec2 v_texCoords;
  9. uniform isampler2D u_normals;
  10. uniform samplerCube u_skyboxFiltered;
  11. uniform samplerCube u_skyboxIradiance;
  12. uniform sampler2D u_brdfTexture;
  13. uniform sampler2DArrayShadow u_cascades;
  14. uniform sampler2DArrayShadow u_spotShadows;
  15. uniform samplerCubeArrayShadow u_pointShadows;
  16. uniform isampler2D u_materialIndex;
  17. uniform sampler2D u_textureUV;
  18. uniform sampler2D u_lastFrameTexture;
  19. uniform sampler2D u_positionViewSpace;
  20. uniform isampler2D u_textureDerivates;
  21. uniform int u_hasLastFrameTexture;
  22. //uniform sampler2D u_textureDerivates;
  23. uniform mat4 u_cameraProjection;
  24. uniform mat4 u_view;
  25. uniform mat4 u_inverseView;
  26. uniform vec3 u_eyePosition;
  27. uniform int u_transparentPass;
  28. struct MaterialStruct
  29. {
  30. vec4 kd;
  31. vec4 rma; //last component emmisive
  32. //float kdr; //= 1;
  33. //float kdg; //= 1;
  34. //float kdb; //= 1;
  35. //float roughness;
  36. //float metallic;
  37. //float ao; //one means full light
  38. //layout(bindless_sampler) sampler2D albedoSampler;
  39. //layout(bindless_sampler) sampler2D rmaSampler;
  40. //layout(bindless_sampler) sampler2D emmissiveSampler;
  41. //vec2 notUsed;
  42. uvec4 firstBIndlessSamplers; // xy albedoSampler, zw rmaSampler
  43. uvec2 secondBIndlessSamplers; // xy emmissiveSampler
  44. int rmaLoaded;
  45. int notUsed;
  46. };
  47. readonly layout(std140) buffer u_material
  48. {
  49. MaterialStruct mat[];
  50. };
  51. layout (std140) uniform u_lightPassData
  52. {
  53. vec4 ambientColor;
  54. float bloomTresshold;
  55. int lightSubScater;
  56. float exposure;
  57. int skyBoxPresent;
  58. float SSR_minRayStep;
  59. int SSR_maxSteps;
  60. int SSR_numBinarySearchSteps;
  61. float SSR_maxRayStep;
  62. float SSR_maxRayDelta;
  63. }lightPassData;
  64. struct PointLight
  65. {
  66. vec3 positions;
  67. float dist;
  68. vec3 color;
  69. float attenuation;
  70. int castShadowsIndex;
  71. float hardness;
  72. int castShadows;
  73. int changedThisFrame;
  74. };
  75. readonly restrict layout(std140) buffer u_pointLights
  76. {
  77. PointLight light[];
  78. };
  79. uniform int u_pointLightCount;
  80. struct DirectionalLight
  81. {
  82. vec3 direction;
  83. int castShadowsIndex;
  84. int changedThisFrame; //not used here
  85. int castShadows;
  86. int notUsed1;
  87. int notUsed2;
  88. vec4 color; //w is a hardness exponent
  89. mat4 firstLightSpaceMatrix;
  90. mat4 secondLightSpaceMatrix;
  91. mat4 thirdLightSpaceMatrix;
  92. };
  93. readonly restrict layout(std140) buffer u_directionalLights
  94. {
  95. DirectionalLight dLight[];
  96. };
  97. uniform int u_directionalLightCount;
  98. struct SpotLight
  99. {
  100. vec4 position; //w = cos(half angle)
  101. vec4 direction; //w dist
  102. vec4 color; //w attenuation
  103. float hardness;
  104. int shadowIndex;
  105. int castShadows;
  106. int changedThisFrame; //not used in the gpu
  107. float near;
  108. float far;
  109. float notUsed1;
  110. float notUsed2;
  111. mat4 lightSpaceMatrix;
  112. };
  113. readonly restrict layout(std140) buffer u_spotLights
  114. {
  115. SpotLight spotLights[];
  116. };
  117. uniform int u_spotLightCount;
  118. const float PI = 3.14159265359;
  119. //todo reduce
  120. const float randomNumbers[100] = float[100](
  121. 0.05535, 0.22262, 0.93768, 0.80063, 0.40089, 0.49459, 0.44997, 0.27060, 0.58789, 0.61765,
  122. 0.87949, 0.38913, 0.23154, 0.27249, 0.93448, 0.71567, 0.26940, 0.32226, 0.73918, 0.30905,
  123. 0.98754, 0.82585, 0.84031, 0.60059, 0.56027, 0.10819, 0.55848, 0.95612, 0.88034, 0.94950,
  124. 0.53892, 0.86421, 0.84131, 0.39158, 0.25861, 0.10192, 0.19673, 0.25165, 0.68675, 0.79157,
  125. 0.94730, 0.36948, 0.27978, 0.66377, 0.38935, 0.93795, 0.83168, 0.01452, 0.51242, 0.12272,
  126. 0.61045, 0.34752, 0.13781, 0.92361, 0.73422, 0.31213, 0.55513, 0.81074, 0.56166, 0.31797,
  127. 0.09507, 0.50049, 0.44248, 0.38244, 0.58468, 0.32327, 0.61830, 0.67908, 0.16011, 0.82861,
  128. 0.36502, 0.12052, 0.28872, 0.73448, 0.51443, 0.99355, 0.75244, 0.22432, 0.95501, 0.90914,
  129. 0.37992, 0.61330, 0.49202, 0.69464, 0.14831, 0.51697, 0.34620, 0.55315, 0.41602, 0.49807,
  130. 0.15133, 0.07372, 0.75259, 0.59642, 0.35652, 0.60051, 0.08879, 0.59271, 0.29388, 0.69505
  131. );
  132. const float INFINITY = 1.f/0.f;
  133. float attenuationFunctionNotClamped(float x, float r, float p)
  134. {
  135. float p4 = p*p*p*p;
  136. float power = pow(x/r, p4);
  137. float rez = (1-power);
  138. rez = rez * rez;
  139. return rez;
  140. }
  141. //n normal
  142. //h halfway vector
  143. //a roughness (1 rough, 0 glossy)
  144. //this gets the amount of specular light reflected
  145. float DistributionGGX(vec3 N, vec3 H, float roughness)
  146. {
  147. //GGX/Trowbridge-Reitz
  148. // a^2
  149. // ------------------------
  150. // PI ((N*H)^2 (a^2-1)+1)^2
  151. float a = roughness*roughness;
  152. float a2 = a*a;
  153. float NdotH = max(dot(N, H), 0.0);
  154. float NdotH2 = NdotH*NdotH;
  155. float denom = (NdotH2 * (a2 - 1.0) + 1.0);
  156. denom = PI * denom * denom;
  157. return a2 / max(denom, 0.0000001);
  158. }
  159. float GeometrySchlickGGX(float NdotV, float roughness)
  160. {
  161. //float r = (roughness + 1.0);
  162. //float k = (r*r) / 8.0; //disney
  163. float k = roughness*roughness / 2;
  164. float num = NdotV;
  165. float denom = NdotV * (1.0 - k) + k;
  166. return num / max(denom, 0.0000001);
  167. }
  168. //oclude light that is hidded begind small geometry roughnesses
  169. float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
  170. {
  171. float NdotV = max(dot(N, V), 0.0);
  172. float NdotL = max(dot(N, L), 0.0);
  173. float ggx2 = GeometrySchlickGGX(NdotV, roughness);
  174. float ggx1 = GeometrySchlickGGX(NdotL, roughness);
  175. return ggx1 * ggx2;
  176. }
  177. //cosTheta is the dot between the normal and halfway
  178. //ratio between specular and diffuse reflection
  179. vec3 fresnelSchlick(float cosTheta, vec3 F0)
  180. {
  181. return F0 + (1.0 - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);
  182. }
  183. vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
  184. {
  185. return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);
  186. }
  187. vec3 fSpecular(vec3 normal, vec3 halfwayVec, vec3 viewDir,
  188. vec3 lightDirection, float dotNVclamped, float roughness, vec3 F)
  189. {
  190. //fCook-Torrance
  191. float NDF = DistributionGGX(normal, halfwayVec, roughness);
  192. float G = GeometrySmith(normal, viewDir, lightDirection, roughness);
  193. float denominator = 4.0 * dotNVclamped
  194. * max(dot(normal, lightDirection), 0.0);
  195. vec3 specular = (NDF * G * F) / max(denominator, 0.001);
  196. return specular;
  197. }
  198. vec3 fDiffuse(vec3 color)
  199. {
  200. //fLambert
  201. return color.rgb / PI;
  202. }
  203. vec3 fDiffuseOrenNayar(vec3 color, float roughness, vec3 L, vec3 V, vec3 N)
  204. {
  205. float a = roughness;
  206. float a2 = a*a;
  207. float cosi = max(dot(L, N), 0);
  208. float cosr = max(dot(V, N), 0);
  209. float sini = sqrt(1-cosi*cosi);
  210. float sinr = sqrt(1-cosr*cosr);
  211. float tani = sini/cosi;
  212. float tanr = sinr/cosr;
  213. float A = 1 - 0.5 * a2/(a2 + 0.33);
  214. float B = 0.45*a2/(a2+0.09);
  215. float sinAlpha = max(sini, sinr);
  216. float tanBeta = min(tani, tanr);
  217. return color.rgb * (A + (B* max(0, dot(L,reflect(V,N))) * sinAlpha * tanBeta )) / PI;
  218. }
  219. //https://mimosa-pudica.net/improved-oren-nayar.html
  220. vec3 fDiffuseOrenNayar2(vec3 color, float roughness, vec3 L, vec3 V, vec3 N)
  221. {
  222. float a = roughness;
  223. float a2 = a*a;
  224. //vec3 A = 1.f/PI * (1 - 0.5 * a2/(a2 + 0.33) + 0.17*color*a2/(a2+0.13));
  225. //float B = 0.45*a2/(a2+0.09);
  226. float A = 1.0/(PI+(PI/2.0-2/3.0)*a);
  227. float B = PI/(PI+(PI/2.0-2/3.0)*a);
  228. float s = dot(L,N) - dot(N,L)*dot(N,V);
  229. float t;
  230. if(s <= 0)
  231. t = 1;
  232. else
  233. t = max(dot(N,L), dot(N,V));
  234. return color * (A + B * s/t);
  235. }
  236. vec3 computePointLightSource(vec3 lightDirection, float metallic, float roughness, in vec3 lightColor, in vec3 worldPosition,
  237. in vec3 viewDir, in vec3 color, in vec3 normal, in vec3 F0)
  238. {
  239. //lightDirection = direction to light
  240. //vec3 lightDirection = normalize(lightPosition - worldPosition);
  241. float dotNVclamped = clamp(dot(normal, viewDir), 0.0, 0.99);
  242. vec3 halfwayVec = normalize(lightDirection + viewDir);
  243. vec3 radiance = lightColor; //here the first component is the light color
  244. vec3 F = fresnelSchlick(max(dot(halfwayVec, viewDir), 0.0), F0);
  245. vec3 specular = fSpecular(normal, halfwayVec, viewDir, lightDirection, dotNVclamped, roughness, F);
  246. vec3 kS = F; //this is the specular contribution
  247. vec3 kD = vec3(1.0) - kS; //the difuse is the remaining specular
  248. kD *= 1.0 - metallic; //metallic surfaces are darker
  249. //vec3 diffuse = fDiffuse(color.rgb);
  250. //vec3 diffuse = fDiffuseOrenNayar(color.rgb, roughness, lightDirection, viewDir, normal);
  251. vec3 diffuse = fDiffuseOrenNayar2(color.rgb, roughness, lightDirection, viewDir, normal);
  252. float NdotL = max(dot(normal, lightDirection), 0.0);
  253. return (kD * diffuse + specular) * radiance * NdotL;
  254. }
  255. float testShadowValue(sampler2DArrayShadow map, vec2 coords, float currentDepth, float bias, int index)
  256. {
  257. //float closestDepth = texture(map, coords).r;
  258. //return (currentDepth - bias) < closestDepth ? 1.0 : 0.0;
  259. return texture(map, vec4(coords, index, currentDepth-bias)).r;
  260. }
  261. //https://www.youtube.com/watch?v=yn5UJzMqxj0&ab_channel=thebennybox
  262. //float sampleShadowLinear(sampler2DArrayShadow map, vec2 coords, vec2 texelSize, float currentDepth, float bias)
  263. //{
  264. //
  265. // vec2 pixelPos = coords / texelSize + vec2(0.5);
  266. // vec2 fracPart = fract(pixelPos);
  267. // vec2 startTexel = (pixelPos-fracPart) * texelSize;
  268. //
  269. // float blTexture = testShadowValue(map, startTexel, currentDepth, bias).r;
  270. // float brTexture = testShadowValue(map, startTexel + vec2(texelSize.x, 0), currentDepth, bias).r;
  271. // float tlTexture = testShadowValue(map, startTexel + vec2(0, texelSize.y), currentDepth, bias).r;
  272. // float trTexture = testShadowValue(map, startTexel + texelSize, currentDepth, bias).r;
  273. //
  274. // float mixA = mix(blTexture, tlTexture, fracPart.y);
  275. // float mixB = mix(brTexture, trTexture, fracPart.y);
  276. //
  277. // return mix(mixA, mixB, fracPart.x);
  278. //}
  279. //https://developer.download.nvidia.com/cg/sincos.html
  280. void sincos(float a, out float s, out float c)
  281. {
  282. s = sin(a);
  283. c = cos(a);
  284. }
  285. //https://www.gamedev.net/tutorials/programming/graphics/contact-hardening-soft-shadows-made-fast-r4906/
  286. vec2 vogelDiskSample(int sampleIndex, int samplesCount, float phi)
  287. {
  288. float GoldenAngle = 2.4f;
  289. float r = sqrt(sampleIndex + 0.5f) / sqrt(samplesCount);
  290. float theta = sampleIndex * GoldenAngle + phi;
  291. float sine, cosine;
  292. sincos(theta, sine, cosine);
  293. return vec2(r * cosine, r * sine);
  294. }
  295. //https://www.gamedev.net/tutorials/programming/graphics/contact-hardening-soft-shadows-made-fast-r4906/
  296. float InterleavedGradientNoise(vec2 position_screen)
  297. {
  298. vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);
  299. return fract(magic.z * fract(dot(position_screen, magic.xy)));
  300. }
  301. float shadowCalculation(vec3 projCoords, float bias, sampler2DArrayShadow shadowMap, int index)
  302. {
  303. // keep the shadow at 1.0 when outside or close to the far_plane region of the light's frustum.
  304. if(projCoords.z > 0.99995)
  305. return 1.f;
  306. //if(projCoords.z < 0)
  307. // return 1.f;
  308. //float closestDepth = texture(shadowMap, projCoords.xy).r;
  309. float currentDepth = projCoords.z;
  310. //todo move
  311. vec2 texelSize = 1.0 / textureSize(shadowMap, 0).xy;
  312. float shadow = 0.0;
  313. bool fewSamples = false;
  314. int kernelHalf = 1;
  315. int kernelSize = kernelHalf*2 + 1;
  316. int kernelSize2 = kernelSize*kernelSize;
  317. //float receiverDepth = currentDepth;
  318. //float averageBlockerDepth = texture(sampler2DArray(shadowMap), vec3(projCoords.xy, index)).r;
  319. //float penumbraSize = 4.f * (receiverDepth - averageBlockerDepth) / averageBlockerDepth;
  320. float penumbraSize = 1.f;
  321. //standard implementation
  322. if(false)
  323. {
  324. float shadowValueAtCentre = 0;
  325. //optimization
  326. if(false)
  327. {
  328. float offsetSize = kernelSize/2;
  329. const int OFFSETS = 4;
  330. vec2 offsets[OFFSETS] =
  331. {
  332. vec2(offsetSize,offsetSize),
  333. vec2(-offsetSize,offsetSize),
  334. vec2(offsetSize,-offsetSize),
  335. vec2(-offsetSize,-offsetSize),
  336. };
  337. fewSamples = true;
  338. float s1 = testShadowValue(shadowMap, projCoords.xy,
  339. currentDepth, bias, index);
  340. shadowValueAtCentre = s1;
  341. for(int i=0;i<OFFSETS; i++)
  342. {
  343. float s2 = testShadowValue(shadowMap, projCoords.xy + offsets[i] * texelSize * 2,
  344. currentDepth, bias, index);
  345. if(s1 != s2)
  346. {
  347. fewSamples = false;
  348. break;
  349. }
  350. s1 = s2;
  351. }
  352. }
  353. if(fewSamples)
  354. {
  355. shadow = shadowValueAtCentre;
  356. }else
  357. {
  358. for(int y = -kernelHalf; y <= kernelHalf; ++y)
  359. {
  360. for(int x = -kernelHalf; x <= kernelHalf; ++x)
  361. {
  362. vec2 offset = vec2(x, y);
  363. if(false)
  364. {
  365. int randomOffset1 = (x*kernelSize) + y;
  366. int randomOffset2 = randomOffset1 + kernelSize2;
  367. offset += vec2(randomNumbers[randomOffset1, randomOffset2]);
  368. }
  369. if(false)
  370. {
  371. float u = (offset.x + kernelHalf)/float(kernelSize-1);
  372. float v = (offset.y + kernelHalf)/float(kernelSize-1);
  373. offset.x = sqrt(v) * cos(2*PI * u)* kernelHalf;
  374. offset.y = sqrt(v) * sin(2*PI * u)* kernelHalf;
  375. }
  376. vec2 finalOffset = offset * texelSize * penumbraSize;
  377. //float newDepth = sqrt(currentDepth*currentDepth + finalOffset.x*finalOffset.x + finalOffset.y * finalOffset.y);
  378. float s = testShadowValue(shadowMap, projCoords.xy + finalOffset,
  379. currentDepth, bias, index);
  380. //float s = sampleShadowLinear(shadowMap, projCoords.xy + vec2(x, y) * offset,
  381. // texelSize, currentDepth, bias);
  382. shadow += s;
  383. }
  384. }
  385. shadow /= kernelSize2;
  386. // texture(map, vec4(coords, index, currentDepth-bias)).r;
  387. //for(int y = -kernelHalf; y <= kernelHalf; ++y)
  388. //{
  389. // for(int x = -kernelHalf; x <= kernelHalf; ++x)
  390. // {
  391. // vec2 offset = vec2(x, y);
  392. // vec2 finalOffset = offset * texelSize * 2;
  393. //
  394. // vec4 shadowGather =
  395. // textureGather(shadowMap, vec3(projCoords.xy+finalOffset,
  396. // index), currentDepth-bias);
  397. //
  398. // shadow += shadowGather.r;
  399. // shadow += shadowGather.g;
  400. // shadow += shadowGather.b;
  401. // shadow += shadowGather.a;
  402. //
  403. // }
  404. //}
  405. //
  406. //shadow /= 4*kernelSize2;
  407. }
  408. }else
  409. {
  410. int sampleSize = 9;
  411. int checkSampleSize = 5;
  412. float size = 1.5;
  413. float noise = InterleavedGradientNoise(v_texCoords) * 2 * PI;
  414. for(int i=sampleSize-1; i>=sampleSize-checkSampleSize; i--)
  415. {
  416. vec2 offset = vogelDiskSample(i, sampleSize, noise);
  417. vec2 finalOffset = offset * texelSize * size;
  418. float s = testShadowValue(shadowMap, projCoords.xy + finalOffset,
  419. currentDepth, bias, index);
  420. shadow += s;
  421. }
  422. //optimization
  423. if(true && (shadow == 0 || shadow == checkSampleSize))
  424. {
  425. shadow /= checkSampleSize;
  426. }else
  427. {
  428. for(int i=sampleSize-checkSampleSize-1; i>=0; i--)
  429. {
  430. vec2 offset = vogelDiskSample(i, sampleSize, noise);
  431. vec2 finalOffset = offset * texelSize * size;
  432. float s = testShadowValue(shadowMap, projCoords.xy + finalOffset,
  433. currentDepth, bias, index);
  434. shadow += s;
  435. }
  436. shadow /= sampleSize;
  437. }
  438. }
  439. return clamp(shadow, 0, 1);
  440. }
  441. float shadowCalculationLinear(vec3 projCoords, vec3 normal, vec3 lightDir, sampler2DArrayShadow shadowMap, int index)
  442. {
  443. float bias = max((10.f/1024.f) * (1.0 - dot(normal, -lightDir)), 3.f/1024.f);
  444. return shadowCalculation(projCoords, bias, shadowMap, index);
  445. }
  446. float linearizeDepth(float depth, float near, float far)
  447. {
  448. float z = depth * 2.0 - 1.0; // Back to NDC
  449. return (2.0 * near * far) / (far + near - z * (far - near));
  450. }
  451. float nonLinearDepth(float depth, float near, float far)
  452. {
  453. return ((1.f/depth) - (1.f/near)) / ((1.f/far) - (1.f/near));
  454. }
  455. //https://developer.nvidia.com/gpugems/gpugems2/part-ii-shading-lighting-and-shadows/chapter-17-efficient-soft-edged-shadows-using
  456. float shadowCalculationLogaritmic(vec3 projCoords, vec3 normal, vec3 lightDir,
  457. sampler2DArrayShadow shadowMap, int index, float near, float far)
  458. {
  459. //float bias = max((0.00005) * (1.0 - dot(normal, -lightDir)), 0.00001);
  460. float bias = max((0.01f) * (1.0 - dot(normal, -lightDir)), 0.001f);
  461. //bias = nonLinearDepth(bias, near, far);
  462. float currentDepth = projCoords.z;
  463. float liniarizedDepth = linearizeDepth(currentDepth, near, far);
  464. liniarizedDepth += bias;
  465. float biasedLogDepth = nonLinearDepth(liniarizedDepth, near, far);
  466. bias = biasedLogDepth - currentDepth;
  467. bias += 0.00003f;
  468. return shadowCalculation(projCoords, bias, shadowMap, index);
  469. }
  470. vec3 getProjCoords(in mat4 matrix, in vec3 pos)
  471. {
  472. vec4 p = matrix * vec4(pos,1);
  473. vec3 r = p .xyz / p .w;
  474. r = r * 0.5 + 0.5;
  475. return r;
  476. }
  477. void generateTangentSpace(in vec3 v, out vec3 outUp, out vec3 outRight)
  478. {
  479. vec3 up = vec3(0.f, 1.f, 0.f);
  480. if (v == up)
  481. {
  482. outRight = vec3(1, 0, 0);
  483. }
  484. else
  485. {
  486. outRight = normalize(cross(v, up));
  487. }
  488. outUp = normalize(cross(outRight, v));
  489. }
  490. float pointShadowCalculation(vec3 pos, vec3 normal, int index)
  491. {
  492. vec3 fragToLight = pos - light[index].positions;
  493. vec3 lightDir = normalize(fragToLight);
  494. //float closestDepth = texture(u_pointShadows, lightDir).r;
  495. //closestDepth *= light[index].dist; //multiply by far plane
  496. float bias = max((60.f/512.f) * (1.0 - dot(normal, -lightDir)), 35.f/512.f);
  497. //float shadow = currentDepth - bias < closestDepth ? 1.0 : 0.0;
  498. float shadow = 0.0;
  499. vec3 tangent;
  500. vec3 coTangent;
  501. generateTangentSpace(lightDir, tangent, coTangent);
  502. float texel = 1.f / textureSize(u_pointShadows, 0).x;
  503. //todo fix for even numbers
  504. int kernel = 5;
  505. int kernelHalf = kernel/2;
  506. for(int y = -kernelHalf; y<=kernelHalf; y++)
  507. {
  508. for(int x = -kernelHalf; x<=kernelHalf; x++)
  509. {
  510. vec3 fragToLight = pos - light[index].positions;
  511. fragToLight += 6*x * texel * tangent;
  512. fragToLight += 6*y * texel * coTangent;
  513. float currentDepth = length(fragToLight);
  514. float value = texture(u_pointShadows,
  515. vec4(fragToLight, light[index].castShadowsIndex),
  516. (currentDepth-bias)/light[index].dist ).r;
  517. shadow += value;
  518. }
  519. }
  520. if(shadow <3)
  521. {
  522. shadow = 0;
  523. }
  524. shadow /= (kernel * kernel);
  525. //float samples = 5.0;
  526. //float offset = 0.1;
  527. //for(float x = -offset; x < offset; x += offset / (samples * 0.5))
  528. //{
  529. // for(float y = -offset; y < offset; y += offset / (samples * 0.5))
  530. // {
  531. // for(float z = -offset; z < offset; z += offset / (samples * 0.5))
  532. // {
  533. // vec3 fragToLight = pos - light[index].positions;
  534. // float currentDepth = length(fragToLight + vec3(x,y,z));
  535. //
  536. //
  537. // float value = texture(u_pointShadows,
  538. // vec4(fragToLight + vec3(x, y, z), light[index].castShadowsIndex),
  539. // (currentDepth-bias)/light[index].dist ).r;
  540. // shadow += value;
  541. //
  542. // }
  543. // }
  544. //}
  545. //shadow /= (samples * samples * samples);
  546. shadow = clamp(shadow, 0, 1);
  547. //if(shadow < 0.1)
  548. //{
  549. // shadow = 0;
  550. //}
  551. return shadow;
  552. }
  553. float cascadedShadowCalculation(vec3 pos, vec3 normal, vec3 lightDir, int index)
  554. {
  555. vec3 firstProjCoords = getProjCoords(dLight[index].firstLightSpaceMatrix, pos);
  556. vec3 secondProjCoords = getProjCoords(dLight[index].secondLightSpaceMatrix, pos);
  557. vec3 thirdProjCoords = getProjCoords(dLight[index].thirdLightSpaceMatrix, pos);
  558. if(
  559. firstProjCoords.x < 0.98 &&
  560. firstProjCoords.x > 0.01 &&
  561. firstProjCoords.y < 0.98 &&
  562. firstProjCoords.y > 0.01 &&
  563. firstProjCoords.z < 0.98 &&
  564. firstProjCoords.z > 0
  565. )
  566. {
  567. //return 0;
  568. firstProjCoords.y /= 3.f;
  569. return shadowCalculationLinear(firstProjCoords, normal, lightDir, u_cascades, index);
  570. }else
  571. if(
  572. secondProjCoords.x > 0 &&
  573. secondProjCoords.x < 1 &&
  574. secondProjCoords.y > 0 &&
  575. secondProjCoords.y < 1 &&
  576. //secondProjCoords.z > 0 &&
  577. secondProjCoords.z < 0.98
  578. )
  579. {
  580. //return 1;
  581. secondProjCoords.y /= 3.f;
  582. secondProjCoords.y += 1.f / 3.f;
  583. return shadowCalculationLinear(secondProjCoords, normal, lightDir, u_cascades, index);
  584. }
  585. else
  586. {
  587. //return 2;
  588. thirdProjCoords.y /= 3.f;
  589. thirdProjCoords.y += 2.f / 3.f;
  590. return shadowCalculationLinear(thirdProjCoords, normal, lightDir, u_cascades, index);
  591. }
  592. }
  593. vec4 fromuShortToFloat2(ivec4 a)
  594. {
  595. vec4 ret = a;
  596. //[0 65536] -> [0 1]
  597. ret /= 65536;
  598. //[0 1] -> [0 4]
  599. ret *= 4.f;
  600. //[0 4] -> [-2 2]
  601. ret -= 2.f;
  602. return ret;
  603. }
  604. vec3 fromuShortToFloat(ivec3 a)
  605. {
  606. vec3 ret = a;
  607. //[0 65536] -> [0 1]
  608. ret /= 65536;
  609. //[0 1] -> [0 2]
  610. ret *= 2.f;
  611. //[0 2] -> [-1 1]
  612. ret -= 1.f;
  613. return normalize(ret);
  614. }
  615. //////////////////////////////////////////////
  616. //https://imanolfotia.com/blog/1
  617. //https://github.com/ImanolFotia/Epsilon-Engine/blob/master/bin/Release/shaders/SSR.glsl
  618. //SSR
  619. //vec3 PositionFromDepth(float depth) {
  620. // float z = depth * 2.0 - 1.0;
  621. //
  622. // vec4 clipSpacePosition = vec4(TexCoords * 2.0 - 1.0, z, 1.0);
  623. // vec4 viewSpacePosition = invprojection * clipSpacePosition;
  624. //
  625. // // Perspective division
  626. // viewSpacePosition /= viewSpacePosition.w;
  627. //
  628. // return viewSpacePosition.xyz;
  629. //}
  630. vec2 BinarySearch(inout vec3 dir, inout vec3 hitCoord,
  631. inout float dDepth, vec2 oldValue)
  632. {
  633. float depth;
  634. vec4 projectedCoord;
  635. vec2 foundProjectedCoord = oldValue;
  636. for(int i = 0; i < lightPassData.SSR_numBinarySearchSteps; i++)
  637. {
  638. projectedCoord = u_cameraProjection * vec4(hitCoord, 1.0);
  639. projectedCoord.xy /= projectedCoord.w;
  640. projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
  641. //depth = textureLod(gPosition, projectedCoord.xy, 2).z;
  642. depth = texture(u_positionViewSpace, projectedCoord.xy).z;
  643. if(depth < -1000) //-INFINITY
  644. continue;
  645. foundProjectedCoord = projectedCoord.xy;
  646. dDepth = hitCoord.z - depth;
  647. dir *= 0.5;
  648. if(dDepth > 0.0)
  649. hitCoord += dir;
  650. else
  651. hitCoord -= dir;
  652. }
  653. projectedCoord = u_cameraProjection * vec4(hitCoord, 1.0);
  654. projectedCoord.xy /= projectedCoord.w;
  655. projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
  656. depth = texture(u_positionViewSpace, projectedCoord.xy).z;
  657. if(!(depth < -1000))
  658. {
  659. foundProjectedCoord = projectedCoord.xy;
  660. }
  661. return foundProjectedCoord.xy;
  662. }
  663. vec2 RayMarch(vec3 dir, inout vec3 hitCoord, out float dDepth, vec3 worldNormal, vec3 viewDir)
  664. {
  665. dir *= mix(lightPassData.SSR_minRayStep, lightPassData.SSR_maxRayStep, abs(dot(worldNormal, viewDir)));//maxRayStep;
  666. float depth;
  667. vec4 projectedCoord;
  668. for(int i = 0; i < lightPassData.SSR_maxSteps; i++)
  669. {
  670. hitCoord += dir;
  671. projectedCoord = u_cameraProjection * vec4(hitCoord, 1.0);
  672. projectedCoord.xy /= projectedCoord.w;
  673. projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
  674. if(projectedCoord.x > 1.f || projectedCoord.y > 1.f
  675. ||projectedCoord.x < -1.f || projectedCoord.y < -1.f
  676. )
  677. {
  678. break;
  679. }
  680. //depth = textureLod(gPosition, projectedCoord.xy, 2).z;
  681. depth = texture(u_positionViewSpace, projectedCoord.xy).z;
  682. if(depth > 1000.0)
  683. continue;
  684. if(depth < -1000) //-INFINITY
  685. continue;
  686. dDepth = hitCoord.z - depth;
  687. if((dir.z - dDepth) < lightPassData.SSR_maxRayStep && dDepth <= 0.0)
  688. {
  689. vec2 Result;
  690. Result = BinarySearch(dir, hitCoord, dDepth, projectedCoord.xy);
  691. //Result = projectedCoord.xy;
  692. if(dDepth < -lightPassData.SSR_maxRayDelta)
  693. {
  694. break; //fail //project to infinity :(((
  695. }
  696. depth = texture(u_positionViewSpace, Result.xy).z;
  697. if(depth < -10000)
  698. {break;}//fail
  699. return Result;
  700. }
  701. }
  702. //signal fail
  703. dDepth = -INFINITY;
  704. return vec2(0,0);
  705. }
  706. uvec3 murmurHash33(uvec3 src) {
  707. const uint M = 0x5bd1e995u;
  708. uvec3 h = uvec3(1190494759u, 2147483647u, 3559788179u);
  709. src *= M; src ^= src>>24u; src *= M;
  710. h *= M; h ^= src.x; h *= M; h ^= src.y; h *= M; h ^= src.z;
  711. h ^= h>>13u; h *= M; h ^= h>>15u;
  712. return h;
  713. }
  714. // 3 outputs, 3 inputs
  715. vec3 hash33(vec3 src) {
  716. uvec3 h = murmurHash33(floatBitsToUint(src));
  717. return uintBitsToFloat(h & 0x007fffffu | 0x3f800000u) - 1.0;
  718. }
  719. vec3 computeJitt(vec3 wp, vec2 Resolution, vec3 viewNormal, float Roughness)
  720. {
  721. vec2 NoiseScale = Resolution / 4.0;
  722. //vec3 random = hash33(wp + iTime);//vec3(texture(noiseTexture, (TexCoords.xy*10.0) + (1.0 - iTime)).rgb);
  723. vec3 random = hash33(wp);//vec3(texture(noiseTexture, (TexCoords.xy*10.0) + (1.0 - iTime)).rgb);
  724. random = dot(random, viewNormal) > 0.0 ? random : -random;
  725. float factor = Roughness*0.20;
  726. vec3 hs = random * 2.0 - 1.0;
  727. vec3 jitt = hs * factor;
  728. return vec3(jitt);
  729. }
  730. vec3 SSR(vec3 viewPos, vec3 N, float metallic, vec3 F,
  731. out float mixFactor, float roughness, vec3 wp, vec3 viewDir, vec3 viewSpaceNormal, vec2 rezolution)
  732. {
  733. mixFactor = 0;
  734. // Reflection vector
  735. vec3 reflected = normalize(reflect(normalize(viewPos), viewSpaceNormal));
  736. //vec3 reflected = R; //todo check
  737. //found = true;
  738. //return viewPos;
  739. if(reflected.z > 0){return vec3(0,0,0);}
  740. vec3 hitPos = viewPos;
  741. float dDepth;
  742. //vec3 wp = vec3(vec4(viewPos, 1.0) * invView);
  743. //vec3 jitt = mix(vec3(0.0), vec3(hash(wp)), spec);
  744. //todo test
  745. vec3 jitt = computeJitt(wp, rezolution, viewSpaceNormal, roughness); //use roughness for specular factor
  746. //vec3 jitt = vec3(0.0);
  747. vec2 coords = RayMarch( normalize((vec3(jitt) + reflected) *
  748. max(lightPassData.SSR_minRayStep, -viewPos.z)), hitPos, dDepth,
  749. N, viewDir);
  750. if(dDepth < -1000){return vec3(0);}
  751. vec2 dCoords = smoothstep(0.2, 0.6, abs(vec2(0.5, 0.5) - coords.xy));
  752. float screenEdgefactor = clamp(1.0 - (dCoords.x + dCoords.y), 0.0, 1.0);
  753. float ReflectionMultiplier =
  754. screenEdgefactor *
  755. -reflected.z;
  756. if(ReflectionMultiplier <= 0.001)
  757. {
  758. return vec3(0.f);
  759. }
  760. // Get color
  761. vec3 lastFrameColor = textureLod(u_lastFrameTexture, coords.xy, 0).rgb;
  762. //vec3 SSR = lastFrameColor * clamp(ReflectionMultiplier, 0.0, 0.9) * F;
  763. vec3 SSR = lastFrameColor;
  764. mixFactor = clamp(ReflectionMultiplier, 0.0, 1.f);
  765. return SSR;
  766. }
  767. ////////////////////////////////////////////
  768. //normal in world space, viewDir, wp = world space position
  769. //F = freshnell
  770. //todo send F
  771. vec3 computeAmbientTerm(vec3 N, vec3 V, vec3 F0, float roughness, vec3 R,
  772. float metallic, vec3 albedo, vec3 wp, vec3 viewPos, vec3 viewSpaceNormal, vec2 rezolution)
  773. {
  774. vec3 gammaAmbient = pow(lightPassData.ambientColor.rgb, vec3(2.2)); //just the static ambient color
  775. vec3 ambient = vec3(0);
  776. float dotNVClamped = clamp(dot(N, V), 0.0, 0.99);
  777. vec3 F = fresnelSchlickRoughness(dotNVClamped, F0, roughness);
  778. vec3 kS = F;
  779. vec3 irradiance = vec3(0,0,0); //diffuse
  780. vec3 radiance = vec3(0,0,0); //specular
  781. vec2 brdf = vec2(0,0);
  782. vec2 brdfVec = vec2(dotNVClamped, roughness);
  783. float mixFactor = 0;
  784. if(u_hasLastFrameTexture != 0) //ssr
  785. {
  786. radiance = SSR(viewPos, N, metallic, F, mixFactor, roughness, wp, V, viewSpaceNormal, rezolution);
  787. }
  788. if(lightPassData.skyBoxPresent != 0)
  789. {
  790. irradiance = texture(u_skyboxIradiance, N).rgb * gammaAmbient; //this color is coming directly at the object
  791. // sample both the pre-filter map and the BRDF lut and combine them together as per the Split-Sum approximation to get the IBL specular part.
  792. const float MAX_REFLECTION_LOD = 4.0;
  793. if(mixFactor < 0.999)
  794. {
  795. radiance = mix(textureLod(u_skyboxFiltered, R, roughness * MAX_REFLECTION_LOD).rgb * gammaAmbient, radiance, mixFactor);
  796. }
  797. //brdfVec.y = 1 - brdfVec.y;
  798. brdf = texture(u_brdfTexture, brdfVec).rg;
  799. }else
  800. {
  801. radiance = mix(gammaAmbient, radiance, mixFactor);
  802. irradiance = gammaAmbient ; //this color is coming directly at the object
  803. //brdfVec.y = 1 - brdfVec.y;
  804. brdf = texture(u_brdfTexture, brdfVec).rg;
  805. }
  806. if(lightPassData.lightSubScater == 0)
  807. {
  808. vec3 kD = 1.0 - kS;
  809. kD *= 1.0 - metallic;
  810. vec3 diffuse = irradiance * albedo;
  811. vec3 specular = radiance * (F * brdf.x + brdf.y);
  812. //no multiple scattering
  813. ambient = (kD * diffuse + specular);
  814. }else
  815. {
  816. //http://jcgt.org/published/0008/01/03/
  817. // Multiple scattering version
  818. vec3 FssEss = kS * brdf.x + brdf.y;
  819. float Ess = brdf.x + brdf.y;
  820. float Ems = 1-Ess;
  821. vec3 Favg = F0 + (1-F0)/21;
  822. vec3 Fms = FssEss*Favg/(1-(1-Ess)*Favg);
  823. // Dielectrics
  824. vec3 Edss = 1 - (FssEss + Fms * Ems);
  825. vec3 kD = albedo * Edss;
  826. // Multiple scattering version
  827. ambient = FssEss * radiance + (Fms*Ems+kD) * irradiance;
  828. }
  829. return ambient;
  830. }
  831. void main()
  832. {
  833. int materialIndex = textureLod(u_materialIndex, v_texCoords, 0).r;
  834. if(materialIndex == 0)
  835. {
  836. //no material, no alpha component that is important
  837. //discard ??
  838. //discard;
  839. if(u_transparentPass != 0)
  840. {
  841. discard;
  842. }else
  843. {
  844. a_outColor = vec4(0,0,0,0);
  845. a_outBloom = vec4(0,0,0,1);
  846. return;
  847. }
  848. //albedoAlpha = vec4(0,0,0,0);
  849. }
  850. //vec3 pos = texture(u_positions, v_texCoords).xyz;
  851. vec3 posViewSpace = texture(u_positionViewSpace, v_texCoords).xyz;
  852. vec3 pos = vec3(u_inverseView * vec4(posViewSpace,1));
  853. if(posViewSpace.z == -INFINITY){discard;}
  854. vec3 normal = fromuShortToFloat(texture(u_normals, v_texCoords).xyz);
  855. vec3 viewSpaceNormal = normalize( vec3(transpose(inverse(mat3(u_view))) * normal));
  856. vec2 sampledUV = texture(u_textureUV, v_texCoords).xy;
  857. ivec4 sampledDerivatesInt = texture(u_textureDerivates, v_texCoords).xyzw;
  858. vec4 sampledDerivates = fromuShortToFloat2(sampledDerivatesInt);
  859. //vec4 sampledDerivates = texture(u_textureDerivates, v_texCoords).xyzw;
  860. vec2 rezolution = textureSize(u_lastFrameTexture, 0);
  861. vec4 albedoAlpha = vec4(0,0,0,0);
  862. vec3 emissive = vec3(0,0,0);
  863. //vec4 sampledDerivates = texture(u_textureDerivates, v_texCoords).xyzw;
  864. vec3 material = vec3(0,0,0);
  865. {
  866. uvec2 albedoSampler = mat[materialIndex-1].firstBIndlessSamplers.xy;
  867. if(albedoSampler.x == 0 && albedoSampler.y == 0)
  868. {
  869. albedoAlpha.rgba = vec4(1,1,1,1); //multiply after with color;
  870. }else
  871. {
  872. albedoAlpha =
  873. textureGrad(sampler2D(albedoSampler), sampledUV.xy,
  874. sampledDerivates.xy, sampledDerivates.zw).rgba;
  875. }
  876. albedoAlpha.rgb *= pow( vec3(mat[materialIndex-1].kd), vec3(1.0/2.2) );
  877. albedoAlpha.a *= mat[materialIndex-1].kd.a;
  878. uvec2 emmisiveSampler = mat[materialIndex-1].secondBIndlessSamplers.xy;
  879. if(emmisiveSampler.x == 0 && emmisiveSampler.y == 0)
  880. {
  881. emissive.rgb = albedoAlpha.rgb;
  882. }else
  883. {
  884. emissive =
  885. textureGrad(sampler2D(emmisiveSampler), sampledUV.xy,
  886. sampledDerivates.xy, sampledDerivates.zw).rgb;
  887. }
  888. emissive.rgb *= mat[materialIndex-1].rma.a;
  889. emissive = pow(emissive , vec3(2.2)).rgb; //gamma corection
  890. uvec2 rmaSampler = mat[materialIndex-1].firstBIndlessSamplers.zw;
  891. if(rmaSampler.x == 0 && rmaSampler.y == 0 && mat[materialIndex-1].rmaLoaded != 0)
  892. {
  893. material.r = mat[materialIndex-1].rma.r;
  894. material.g = mat[materialIndex-1].rma.g;
  895. material.b = mat[materialIndex-1].rma.b;
  896. }
  897. else
  898. {
  899. vec3 materialData = textureGrad(sampler2D(rmaSampler), sampledUV.xy,
  900. sampledDerivates.xy, sampledDerivates.zw).rgb;
  901. int roughnessPrezent = mat[materialIndex-1].rmaLoaded & 0x4;
  902. int metallicPrezent = mat[materialIndex-1].rmaLoaded & 0x2;
  903. int ambientPrezent = mat[materialIndex-1].rmaLoaded & 0x1;
  904. if(roughnessPrezent != 0)
  905. {
  906. material.r = materialData.r;
  907. }else
  908. {
  909. material.r = mat[materialIndex-1].rma.r;
  910. }
  911. if(metallicPrezent != 0)
  912. {
  913. material.g = materialData.g;
  914. }else
  915. {
  916. material.g = mat[materialIndex-1].rma.g;
  917. }
  918. if(ambientPrezent != 0)
  919. {
  920. material.b = materialData.b;
  921. }else
  922. {
  923. material.b = mat[materialIndex-1].rma.b;
  924. }
  925. }
  926. }
  927. //calculate BRDF
  928. vec3 albedo = albedoAlpha.rgb;
  929. albedo = pow(albedo , vec3(2.2)).rgb; //gamma corection
  930. float roughness = clamp(material.r, 0.09, 0.99);
  931. float metallic = clamp(material.g, 0.0, 0.98);
  932. float ambientOcclution = material.b;
  933. vec3 viewDir = normalize(u_eyePosition - pos); //towards hemisphere
  934. //vec3 I = normalize(pos - u_eyePosition); //looking direction (towards eye)
  935. vec3 R = reflect(-viewDir, normal); //reflected vector
  936. //vec3 skyBoxSpecular = texture(u_skybox, R).rgb; //this is the reflected color
  937. vec3 Lo = vec3(0,0,0); //this is the accumulated light
  938. vec3 F0 = vec3(0.04);
  939. F0 = mix(F0, albedo.rgb, vec3(metallic));
  940. //foreach point light
  941. for(int i=0; i<u_pointLightCount;i++)
  942. {
  943. vec3 lightPosition = light[i].positions.xyz;
  944. vec3 lightColor = light[i].color.rgb;
  945. vec3 lightDirection = normalize(lightPosition - pos);
  946. float currentDist = distance(lightPosition, pos);
  947. if(currentDist >= light[i].dist)
  948. {
  949. continue;
  950. }
  951. float attenuation = attenuationFunctionNotClamped(currentDist, light[i].dist, light[i].attenuation);
  952. float shadow = 1.f;
  953. if(light[i].castShadows != 0)
  954. {
  955. shadow = pointShadowCalculation(pos, normal, i);
  956. shadow = pow(shadow, light[i].hardness);
  957. }
  958. Lo += computePointLightSource(lightDirection, metallic, roughness, lightColor,
  959. pos, viewDir, albedo, normal, F0) * attenuation * shadow;
  960. }
  961. for(int i=0; i<u_directionalLightCount; i++)
  962. {
  963. vec3 lightDirection = dLight[i].direction.xyz;
  964. vec3 lightColor = dLight[i].color.rgb;
  965. float shadow = 1;
  966. if(dLight[i].castShadows != 0)
  967. {
  968. int castShadowInd = dLight[i].castShadowsIndex;
  969. shadow = cascadedShadowCalculation(pos, normal, lightDirection, castShadowInd);
  970. shadow = pow(shadow, dLight[i].color.w);
  971. }
  972. //if(shadow == 0)
  973. //{
  974. // albedo.rgb = vec3(1,0,0);
  975. //}else if(shadow >= 0.9 && shadow <= 1.1)
  976. //{
  977. // albedo.rgb = vec3(0,1,0);
  978. //}else
  979. //{
  980. // albedo.rgb = vec3(0,0,1);
  981. //}
  982. //shadow = 1;
  983. Lo += computePointLightSource(-lightDirection, metallic, roughness, lightColor,
  984. pos, viewDir, albedo, normal, F0) * shadow;
  985. }
  986. for(int i=0; i<u_spotLightCount; i++)
  987. {
  988. vec3 lightPosition = spotLights[i].position.xyz;
  989. vec3 lightColor = spotLights[i].color.rgb;
  990. vec3 spotLightDirection = spotLights[i].direction.xyz;
  991. vec3 lightDirection = -normalize(lightPosition - pos);
  992. float angle = spotLights[i].position.w;
  993. float dist = spotLights[i].direction.w;
  994. float at = spotLights[i].color.w;
  995. float dotAngle = dot(normalize(vec3(pos - lightPosition)), spotLightDirection);
  996. float currentDist = distance(lightPosition, pos);
  997. if(currentDist >= dist)
  998. {
  999. continue;
  1000. }
  1001. if(dotAngle > angle && dotAngle > 0)
  1002. {
  1003. float attenuation = attenuationFunctionNotClamped(currentDist, dist, at);
  1004. //attenuation = 1;
  1005. float smoothingVal = 0.01; //
  1006. float innerAngle = angle + smoothingVal;
  1007. float smoothing = clamp((dotAngle-angle)/smoothingVal,0.0,1.0);
  1008. //smoothing = 1;
  1009. vec3 shadowProjCoords = getProjCoords(spotLights[i].lightSpaceMatrix, pos);
  1010. float shadow = 1;
  1011. if(spotLights[i].castShadows != 0)
  1012. {
  1013. shadow = shadowCalculationLogaritmic(shadowProjCoords, normal, lightDirection,
  1014. u_spotShadows, spotLights[i].shadowIndex, spotLights[i].near, spotLights[i].far);
  1015. shadow = pow(shadow, spotLights[i].hardness);
  1016. }
  1017. smoothing = pow(smoothing, spotLights[i].hardness);
  1018. Lo += computePointLightSource(-lightDirection, metallic, roughness, lightColor,
  1019. pos, viewDir, albedo, normal, F0) * smoothing * attenuation * shadow;
  1020. }
  1021. }
  1022. vec3 color = Lo + computeAmbientTerm(normal, viewDir, F0, roughness, R, metallic,
  1023. albedo, pos, posViewSpace, viewSpaceNormal, rezolution)
  1024. * ambientOcclution;
  1025. //vec3 hdrCorrectedColor = color;
  1026. //hdrCorrectedColor.rgb = vec3(1.0) - exp(-hdrCorrectedColor.rgb * lightPassData.exposure);
  1027. //hdrCorrectedColor.rgb = pow(hdrCorrectedColor.rgb, vec3(1.0/2.2));
  1028. //float lightIntensity = dot(hdrCorrectedColor.rgb, vec3(0.2126, 0.7152, 0.0722));
  1029. ////float lightIntensity = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
  1030. //gama correction and hdr is done and applied in the post process step
  1031. if(u_transparentPass != 0)
  1032. {
  1033. float a = albedoAlpha.a;
  1034. a = 1-a;
  1035. a *= dot(viewDir, normal);
  1036. a = 1-a;
  1037. a_outColor = vec4(color.rgb + emissive.rgb, a);
  1038. a_outBloom = vec4(emissive.rgb, a);
  1039. }else
  1040. {
  1041. a_outColor = vec4(color.rgb + emissive.rgb, 1);
  1042. a_outBloom = vec4(emissive.rgb, 1);
  1043. }
  1044. //a_outColor.rgb = vec3(albedoAlpha);
  1045. //a_outColor.rgb = material.bbb;
  1046. //a_outColor.rgba = vec4(albedoAlpha.aaa, 1);
  1047. //a_outColor.rgb = vec3(ssaof, ssaof, ssaof);
  1048. }