SHOW:
|
|
- or go back to the newest paste.
| 1 | const float rad = 0.25; | |
| 2 | const float maxdepth = 4.00; | |
| 3 | ||
| 4 | mat3 cotangent_frame(vec3 n, vec3 p, vec2 uv) | |
| 5 | {
| |
| 6 | // get edge vectors of the pixel triangle | |
| 7 | vec3 dp1 = dFdx(p); | |
| 8 | vec3 dp2 = dFdy(p); | |
| 9 | vec2 duv1 = dFdx(uv); | |
| 10 | vec2 duv2 = dFdy(uv); | |
| 11 | ||
| 12 | // solve the linear system | |
| 13 | vec3 dp2perp = cross(n, dp2); // cross(dp2, n); | |
| 14 | vec3 dp1perp = cross(dp1, n); // cross(n, dp1); | |
| 15 | vec3 t = dp2perp * duv1.x + dp1perp * duv2.x; | |
| 16 | vec3 b = dp2perp * duv1.y + dp1perp * duv2.y; | |
| 17 | ||
| 18 | // construct a scale-invariant frame | |
| 19 | float invmax = inversesqrt(max(dot(t,t), dot(b,b))); | |
| 20 | return mat3(t * invmax, b * invmax, n); | |
| 21 | } | |
| 22 | ||
| 23 | void SetupMaterial(inout Material mat) | |
| 24 | {
| |
| 25 | vec2 tc = vTexCoord.st; | |
| 26 | tc = fract(tc); | |
| 27 | mat.Base = getTexel(tc); | |
| 28 | ||
| 29 | vec2 centeruv = vec2(0.5, 0.5); | |
| 30 | vec2 uv = tc - centeruv; | |
| 31 | ||
| 32 | float radius = rad; | |
| 33 | float dist = length(uv); | |
| 34 | float mask = step(dist, radius); | |
| 35 | ||
| 36 | vec3 nWnormal = normalize(vWorldNormal.xyz); | |
| 37 | mat3 TBN = cotangent_frame(nWnormal, pixelpos.xyz, tc); | |
| 38 | mat3 invTBN = transpose(TBN); | |
| 39 | ||
| 40 | vec3 raydir_3D = normalize(invTBN * (pixelpos.xyz - uCameraPos.xyz)); | |
| 41 | vec3 raydir_2D = normalize(vec3(raydir_3D.xy, 0.0)); //camera dir in 2D on plane | |
| 42 | vec3 position = vec3(uv, 0.0); | |
| 43 | ||
| 44 | //distance from intersection point to hole edge | |
| 45 | float total = dot(position, raydir_2D) - sqrt( | |
| 46 | pow | |
| 47 | ( | |
| 48 | radius, | |
| 49 | 2.0 | |
| 50 | ) | |
| 51 | - | |
| 52 | pow | |
| 53 | ( | |
| 54 | length(cross(position, raydir_2D)), | |
| 55 | 2.0 | |
| 56 | ) | |
| 57 | ); | |
| 58 | ||
| 59 | //get the depth | |
| 60 | vec3 face = vec3(0,0,1.0); | |
| 61 | float z = dot(raydir_3D, face); | |
| 62 | float x = sqrt(1.0 - pow(z, 2.0)); //the 1.0 is length(raydir)^2 aka 1.0 | |
| 63 | float depth = (total * z) / x; | |
| 64 | depth = min(maxdepth, depth); | |
| 65 | ||
| 66 | //circumference texture mapping | |
| 67 | vec3 id = vec3(depth) / raydir_3D; | |
| 68 | vec3 k = abs(id) - position * id; | |
| 69 | float kMin = k.z; //for square hole kMin = min(min(k.x, k.y), k.z); | |
| 70 | position += kMin * raydir_3D; | |
| 71 | vec3 vec = position; | |
| 72 | ||
| 73 | vec = normalize(vec); | |
| 74 | float ang = atan(vec.y, vec.x); | |
| 75 | ||
| 76 | //hole coordinates | |
| 77 | float holey = ang / 3.1415; | |
| 78 | float holex = depth; | |
| 79 | ||
| 80 | vec4 hole = getTexel(vec2(holex, holey)); | |
| 81 | hole.rgb *= 1.0 - (depth / maxdepth); | |
| 82 | ||
| 83 | mat.Base = mix(mat.Base, hole, mask); | |
| 84 | } |