fs_bokeh_forward.sc 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. $input v_normal, v_texcoord0, v_texcoord1, v_texcoord2
  2. /*
  3. * Copyright 2021 elven cache. All rights reserved.
  4. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  5. */
  6. #include "../common/common.sh"
  7. SAMPLER2D(s_albedo, 0);
  8. SAMPLER2D(s_normal, 1);
  9. // struct ModelUniforms
  10. uniform vec4 u_modelParams[2];
  11. #define u_color (u_modelParams[0].xyz)
  12. #define u_lightPosition (u_modelParams[1].xyz)
  13. // http://www.thetenthplanet.de/archives/1180
  14. // "followup: normal mapping without precomputed tangents"
  15. mat3 cotangentFrame(vec3 N, vec3 p, vec2 uv)
  16. {
  17. // get edge vectors of the pixel triangle
  18. vec3 dp1 = dFdx(p);
  19. vec3 dp2 = dFdy(p);
  20. vec2 duv1 = dFdx(uv);
  21. vec2 duv2 = dFdy(uv);
  22. // solve the linear system
  23. vec3 dp2perp = cross(dp2, N);
  24. vec3 dp1perp = cross(N, dp1);
  25. vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
  26. vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
  27. // construct a scale-invariant frame
  28. float invMax = inversesqrt(max(dot(T,T), dot(B,B)));
  29. return mat3(T*invMax, B*invMax, N);
  30. }
  31. void main()
  32. {
  33. vec3 albedo = toLinear(texture2D(s_albedo, v_texcoord0).xyz);
  34. // get vertex normal
  35. vec3 normal = normalize(v_normal);
  36. // get normal map normal, unpack, and calculate z
  37. vec3 normalMap;
  38. normalMap.xy = texture2D(s_normal, v_texcoord0).xy;
  39. normalMap.xy = normalMap.xy * 2.0 - 1.0;
  40. normalMap.z = sqrt(1.0 - dot(normalMap.xy, normalMap.xy));
  41. // swap x and y, because the brick texture looks flipped, don't copy this...
  42. normalMap.xy = -normalMap.yx;
  43. // perturb geometry normal by normal map
  44. vec3 pos = v_texcoord1.xyz; // contains world space pos
  45. mat3 TBN = cotangentFrame(normal, pos, v_texcoord0);
  46. vec3 bumpedNormal = normalize(instMul(TBN, normalMap));
  47. vec3 light = (u_lightPosition - pos);
  48. light = normalize(light);
  49. float NdotL = saturate(dot(bumpedNormal, light));
  50. float diffuse = NdotL * 1.0;
  51. vec3 V = v_texcoord2.xyz; // contains view vector
  52. vec3 H = normalize(V+light);
  53. float NdotH = saturate(dot(bumpedNormal, H));
  54. float specular = 5.0 * pow(NdotH, 256);
  55. float ambient = 0.1;
  56. float lightAmount = ambient + diffuse;
  57. vec3 color = u_color * albedo * lightAmount + specular;
  58. // leave color in linear space for better dof filter result
  59. gl_FragColor = vec4(color, 1.0);
  60. }