Guest User

Untitled

a guest
Nov 16th, 2020
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.72 KB | None | 0 0
  1. #version 450
  2.  
  3. #define PI 3.1415926535f
  4.  
  5. float GGXPartialGeometry(float NV, float roughness)
  6. {
  7. float k = (roughness + 1.0f) * (roughness + 1.0f) * 0.125f;
  8. return NV / (NV * (1.0f - k) + k);
  9. }
  10.  
  11. float GGXDistribution(float NH, float roughness)
  12. {
  13. float roughness2 = roughness * roughness;
  14. float alpha2 = roughness2 * roughness2;
  15. float distr = (NH * NH) * (alpha2 - 1.0f) + 1.0f;
  16. float distr2 = distr * distr;
  17. float totalDistr = alpha2 / (PI * distr2);
  18. return totalDistr;
  19. }
  20.  
  21. float GGXSmith(float NV, float NL, float roughness)
  22. {
  23. return GGXPartialGeometry(NV, roughness)* GGXPartialGeometry(NL, roughness);
  24. }
  25.  
  26. vec3 fresnelSchlick(vec3 F0, float HV)
  27. {
  28. float p = (-5.55473f * HV - 6.98136f) * HV;
  29. return F0 + (vec3(1.0f) - F0) * pow(2.0f, p);
  30. }
  31.  
  32. mat3 computeSampleTransform(vec3 normal)
  33. {
  34. vec3 up = abs(normal.z) < 0.999f ? vec3(0.0f, 0.0f, 1.0f) : vec3(1.0f, 0.0f, 0.0f);
  35.  
  36. mat3 w;
  37. w[0] = normalize(cross(normal, up));
  38. w[1] = cross(normal, w[0]);
  39. w[2] = normal;
  40. return w;
  41. }
  42.  
  43. vec3 GGXImportanceSample(vec2 Xi, float roughness, vec3 normal)
  44. {
  45. mat3 transform = computeSampleTransform(normal);
  46.  
  47. float alpha = roughness * roughness;
  48. float phi = 2.0f * PI * Xi.x;
  49. float cosTheta = sqrt((1.0f - Xi.y) / (1.0f + (alpha * alpha - 1.0f) * Xi.y));
  50. float sinTheta = sqrt(1.0f - cosTheta * cosTheta);
  51. vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
  52. return transform * H;
  53. }
  54.  
  55. float computeA(samplerCube tex, int sampleCount)
  56. {
  57. vec2 sizes = textureSize(tex, 0);
  58. float A = 0.5f * log2(sizes.x * sizes.y / float(sampleCount));
  59. return A;
  60. }
  61.  
  62. float computeLOD(float A, float pdf, vec3 lightDirection)
  63. {
  64. float du = 2.0f * 1.2f * abs(lightDirection.y + 1.0f);
  65. return max(0.0f, A - 0.5f * log2(pdf * du * du) + 1.0f);
  66. }
  67.  
  68. float radicalInverseVDC(uint bits)
  69. {
  70. bits = (bits << 16u) | (bits >> 16u);
  71. bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
  72. bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
  73. bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
  74. bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
  75. return float(bits) * 2.3283064365386963e-10; // / 0x100000000
  76. }
  77.  
  78. vec2 sampleHammersley(uint i, float invSampleCount)
  79. {
  80. return vec2(i * invSampleCount, radicalInverseVDC(i));
  81. }
  82.  
  83. vec3 GGXCookTorranceSampled(vec3 normal, vec3 lightDirection, vec3 viewDirection, float roughness, float metallic, vec3 albedo, out vec3 FK, out float pdf)
  84. {
  85. vec3 H = normalize(viewDirection + lightDirection);
  86. float NV = dot(normal, viewDirection);
  87. float NL = dot(normal, lightDirection);
  88. float NH = dot(normal, H);
  89. float HV = dot(H, viewDirection);
  90.  
  91. if (NV < 0.0f) return vec3(0.0f);
  92. if (NL < 0.0f) return vec3(0.0f);
  93.  
  94. vec3 F0 = mix(vec3(0.04f), albedo, metallic);
  95.  
  96. float G = GGXSmith(NV, NL, roughness);
  97. float D = GGXDistribution(NH, roughness);
  98. vec3 F = fresnelSchlick(F0, HV);
  99.  
  100. FK = F;
  101. pdf = D * NH / (4.0f * HV);
  102.  
  103. vec3 specular = G * F * HV / (NV * NH);
  104. return max(vec3(0.0f), specular);
  105. }vec3 reconstructWorldPosition(float depth, vec2 texcoord, mat4 invViewProjMatrix)
  106. {
  107. vec4 normPosition = vec4(2.0f * texcoord - vec2(1.0f), depth, 1.0f);
  108. vec4 worldPosition = invViewProjMatrix * normPosition;
  109. worldPosition /= worldPosition.w;
  110. return worldPosition.xyz;
  111. }
  112.  
  113. float calcShadowFactor2D(vec4 fragPosLight, sampler2D depthMap, float bias, int blurIterations)
  114. {
  115. vec3 projCoords = fragPosLight.xyz / fragPosLight.w;
  116. if (projCoords.z > 0.99f) return 1.0f; // do not handle corner cases, assume now shadows
  117. float currentDepth = projCoords.z - bias;
  118. float shadowFactor = 0.0f;
  119. vec2 texelSize = 1.0f / textureSize(depthMap, 0);
  120. for (int x = -blurIterations; x <= blurIterations; x++)
  121. {
  122. for (int y = -blurIterations; y <= blurIterations; y++)
  123. {
  124. float pcfDepth = textureLod(depthMap, projCoords.xy + vec2(x, y) * 1.5f * texelSize, 0).r;
  125. shadowFactor += (currentDepth > pcfDepth) ? 0.0f : 1.0f;
  126. }
  127. }
  128. int iterations = 2 * blurIterations + 1;
  129. shadowFactor /= float(iterations * iterations);
  130. return shadowFactor;
  131. }
  132.  
  133. const int POINT_LIGHT_SAMPLES = 20;
  134. vec3 sampleOffsetDirections[POINT_LIGHT_SAMPLES] = vec3[]
  135. (
  136. vec3(1, 1, 1), vec3(1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
  137. vec3(1, 1, -1), vec3(1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
  138. vec3(1, 1, 0), vec3(1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
  139. vec3(1, 0, 1), vec3(-1, 0, 1), vec3(1, 0, -1), vec3(-1, 0, -1),
  140. vec3(0, 1, 1), vec3(0, -1, 1), vec3(0, -1, -1), vec3(0, 1, -1)
  141. );
  142.  
  143. float CalcShadowFactor3D(vec3 fragToLightRay, vec3 viewDist, float zfar, float bias, samplerCube depthMap)
  144. {
  145. float invZfar = 1.0f / zfar;
  146. float currentDepth = length(fragToLightRay);
  147. currentDepth = (currentDepth - bias) * invZfar;
  148. float diskRadius = (1.0f + invZfar) * 0.04f;
  149. float shadowFactor = 0.0f;
  150.  
  151. for (int i = 0; i < POINT_LIGHT_SAMPLES; i++)
  152. {
  153. float closestDepth = textureLod(depthMap, sampleOffsetDirections[i] * diskRadius - fragToLightRay, 0).r;
  154. shadowFactor += (currentDepth > closestDepth) ? 0.0f : 1.0f;
  155. }
  156. shadowFactor /= float(POINT_LIGHT_SAMPLES);
  157. return shadowFactor;
  158. }
  159.  
  160. vec3 calcReflectionColor(samplerCube reflectionMap, mat3 reflectionMapTransform, vec3 viewDir, vec3 normal)
  161. {
  162. vec3 I = -viewDir;
  163. vec3 reflectionRay = reflect(I, normal);
  164. reflectionRay = reflectionMapTransform * reflectionRay;
  165. vec3 color = texture(reflectionMap, reflectionRay).rgb;
  166. return color;
  167. }
  168.  
  169. vec4 worldToFragSpace(vec3 v, mat4 viewProj)
  170. {
  171. vec4 proj = viewProj * vec4(v, 1.0f);
  172. proj.xyz /= proj.w;
  173. proj.xy = proj.xy * 0.5f + vec2(0.5f);
  174. return proj;
  175. }
  176.  
  177. struct FragmentInfo
  178. {
  179. vec3 albedo;
  180. float ambientOcclusion;
  181. float emmisionFactor;
  182. float roughnessFactor;
  183. float metallicFactor;
  184. float depth;
  185. vec3 normal;
  186. vec3 position;
  187. };
  188.  
  189. struct EnvironmentInfo
  190. {
  191. samplerCube skybox;
  192. samplerCube irradiance;
  193. mat3 skyboxRotation;
  194. float intensity;
  195. };
  196.  
  197. FragmentInfo getFragmentInfo(vec2 texCoord, sampler2D albedoTexture, sampler2D normalTexture, sampler2D materialTexture, sampler2D depthTexture, mat4 invViewProjMatrix)
  198. {
  199. FragmentInfo fragment;
  200.  
  201. fragment.normal = normalize(texture(normalTexture, texCoord).rgb - vec3(0.5f));
  202. vec4 albedo = texture(albedoTexture, texCoord).rgba;
  203. vec4 material = texture(materialTexture, texCoord).rgba;
  204. fragment.depth = texture(depthTexture, texCoord).r;
  205.  
  206. fragment.albedo = albedo.rgb;
  207. fragment.ambientOcclusion = albedo.a;
  208. fragment.emmisionFactor = material.r / (1.0f - material.r);
  209. fragment.roughnessFactor = material.g;
  210. fragment.metallicFactor = material.b;
  211.  
  212. fragment.position = reconstructWorldPosition(fragment.depth, texCoord, invViewProjMatrix);
  213.  
  214. return fragment;
  215. }
  216.  
  217.  
  218. vec3 calculateLighting(FragmentInfo fragment, vec3 viewDirection, vec3 lightDirection, EnvironmentInfo environment, int GGXSamples, vec3 lightColor, float ambientFactor, float shadowFactor)
  219. {
  220. vec3 normLightDirection = normalize(lightDirection);
  221.  
  222. vec3 specularColor = vec3(0.0f);
  223. vec3 FKtotal = vec3(0.0f);
  224.  
  225. float roughness = clamp(fragment.roughnessFactor, 0.01f, 0.99f);
  226. float metallic = clamp(fragment.metallicFactor, 0.01f, 0.99f);
  227.  
  228. float invEnvironmentSampleCount = 1.0f / float(GGXSamples);
  229. float A = computeA(environment.skybox, GGXSamples);
  230. for (uint i = 0; i < uint(GGXSamples); i++)
  231. {
  232. vec2 Xi = sampleHammersley(i, invEnvironmentSampleCount);
  233. vec3 H = GGXImportanceSample(Xi, roughness, fragment.normal);
  234. vec3 direction = 2.0f * dot(viewDirection, H) * H - viewDirection;
  235.  
  236. vec3 FK;
  237. float pdf;
  238.  
  239. vec3 specularK = GGXCookTorranceSampled(fragment.normal, direction, viewDirection, roughness, fragment.metallicFactor, fragment.albedo, FK, pdf);
  240. FKtotal += FK;
  241. float lod = computeLOD(A, pdf, direction);
  242.  
  243. vec3 sampleDirection = environment.skyboxRotation * direction;
  244. vec3 sampledColor = textureLod(environment.skybox, sampleDirection, lod).rgb;
  245. specularColor += specularK * sampledColor;
  246. }
  247. specularColor *= invEnvironmentSampleCount * environment.intensity;
  248. FKtotal *= invEnvironmentSampleCount;
  249. vec3 irradianceColor = calcReflectionColor(environment.irradiance, environment.skyboxRotation, viewDirection, fragment.normal);
  250.  
  251. vec3 diffuseColor = fragment.albedo * (1.0f - metallic) * (1.0f - FKtotal) * irradianceColor;
  252. vec3 ambientColor = diffuseColor * ambientFactor;
  253.  
  254. float NL = max(dot(normLightDirection, fragment.normal), 0.0f);
  255.  
  256. diffuseColor *= NL;
  257. specularColor *= NL;
  258.  
  259. vec3 totalColor = ambientColor + shadowFactor * (diffuseColor + specularColor);
  260. return totalColor * lightColor * fragment.ambientOcclusion;
  261. }
  262.  
  263. out vec4 OutColor;
  264.  
  265. uniform sampler2D albedoTex;
  266. uniform sampler2D normalTex;
  267. uniform sampler2D materialTex;
  268. uniform sampler2D depthTex;
  269.  
  270. in PointLightInfo
  271. {
  272. vec3 position;
  273. float radius;
  274. vec4 color;
  275. } pointLight;
  276.  
  277. struct PointLight
  278. {
  279. vec3 position;
  280. float radius;
  281. vec4 color;
  282. };
  283.  
  284. struct Camera
  285. {
  286. vec3 position;
  287. mat4 invViewProjMatrix;
  288. mat4 viewProjMatrix;
  289. };
  290.  
  291. uniform samplerCube lightDepthMap;
  292. uniform bool castsShadows;
  293. uniform Camera camera;
  294. uniform int pcfDistance;
  295. uniform int lightSamples;
  296. uniform vec2 viewportSize;
  297.  
  298. uniform EnvironmentInfo environment;
  299.  
  300. vec3 calcColorUnderPointLight(FragmentInfo fragment, PointLight light, vec3 viewDir, samplerCube map_shadow, bool computeShadow)
  301. {
  302. vec3 lightPath = light.position - fragment.position;
  303. float lightDistance = length(lightPath);
  304.  
  305. if (light.radius < lightDistance || isnan(lightDistance))
  306. discard;
  307.  
  308. float shadowFactor = 1.0f;
  309. if (computeShadow) { shadowFactor = CalcShadowFactor3D(lightPath, viewDir, light.radius, 0.15f, map_shadow); }
  310. float intensity = clamp(pow(1.0f - pow(lightDistance / light.radius, 4.0f), 2.0f), 0.0f, 1.0f) / (lightDistance * lightDistance + 1.0f);
  311.  
  312. return calculateLighting(fragment, viewDir, lightPath, environment, lightSamples, intensity * light.color.rgb, light.color.a, shadowFactor);
  313. }
  314.  
  315. void main()
  316. {
  317. vec2 TexCoord = gl_FragCoord.xy / viewportSize;
  318. FragmentInfo fragment = getFragmentInfo(TexCoord, albedoTex, normalTex, materialTex, depthTex, camera.invViewProjMatrix);
  319.  
  320. float fragDistance = length(camera.position - fragment.position);
  321. vec3 viewDirection = normalize(camera.position - fragment.position);
  322.  
  323. PointLight light;
  324. light.position = pointLight.position;
  325. light.radius = pointLight.radius;
  326. light.color = pointLight.color;
  327.  
  328. vec3 totalColor = vec3(0.0f);
  329. totalColor += calcColorUnderPointLight(fragment, light, viewDirection, lightDepthMap, castsShadows);
  330.  
  331. OutColor = vec4(totalColor, 1.0f);
  332. }
Advertisement
Add Comment
Please, Sign In to add comment