Guest User

Untitled

a guest
Jul 23rd, 2024
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. shader_type spatial;
  2. render_mode unshaded;
  3.  
  4. uniform sampler2D screen_texture : source_color, hint_screen_texture, filter_nearest;
  5. uniform sampler2D depth_texture : source_color, hint_depth_texture, filter_nearest;
  6. uniform sampler2D normal_texture : source_color, hint_normal_roughness_texture, filter_nearest;
  7.  
  8. uniform float depth_threshold : hint_range(0, 1) = 0.05;
  9. uniform float reverse_depth_threshold : hint_range(0, 1) = 0.25;
  10. uniform float normal_threshold : hint_range(0, 1) = 0.6;
  11.  
  12. uniform float darken_amount : hint_range(0, 1, 0.01) = 0.3;
  13. uniform float lighten_amount : hint_range(0, 10, 0.01) = 1.5;
  14.  
  15. uniform vec3 normal_edge_bias = vec3(1, 1, 1);
  16. uniform vec3 light_direction = vec3(-0.96, -0.18, 0.2);
  17.  
  18. float get_depth(vec2 screen_uv, mat4 inv_projection_matrix) {
  19.     float depth = texture(depth_texture, screen_uv).r;
  20.     vec3 ndc = vec3(screen_uv * 2.0 - 1.0, depth);
  21.     vec4 view = inv_projection_matrix * vec4(ndc, 1.0);
  22.     view.xyz /= view.w;
  23.     return -view.z;
  24. }
  25.  
  26. void vertex() {
  27.     POSITION = vec4(VERTEX, 1.0);
  28. }
  29.  
  30. void fragment() {
  31.     float depth = get_depth(SCREEN_UV, INV_PROJECTION_MATRIX);
  32.     vec3 normal = texture(normal_texture, SCREEN_UV).xyz * 2.0 - 1.0;
  33.     vec2 texel_size = 1.0 / VIEWPORT_SIZE.xy;
  34.    
  35.     vec2 uvs[4];
  36.     uvs[0] = vec2(SCREEN_UV.x, min(1.0 - 0.001, SCREEN_UV.y + texel_size.y));
  37.     uvs[1] = vec2(SCREEN_UV.x, max(0.0, SCREEN_UV.y - texel_size.y));
  38.     uvs[2] = vec2(min(1.0 - 0.001, SCREEN_UV.x + texel_size.x), SCREEN_UV.y);
  39.     uvs[3] = vec2(max(0.0, SCREEN_UV.x - texel_size.x), SCREEN_UV.y);
  40.    
  41.     float depth_diff = 0.0;
  42.     float depth_diff_reversed = 0.0;
  43.     float nearest_depth = depth;
  44.     vec2 nearest_uv = SCREEN_UV;
  45.    
  46.     float normal_sum = 0.0;
  47.     for (int i = 0; i < 4; i++) {
  48.         float d = get_depth(uvs[i], INV_PROJECTION_MATRIX);
  49.         depth_diff += depth - d;
  50.         depth_diff_reversed += d - depth;
  51.        
  52.         if (d < nearest_depth) {
  53.             nearest_depth = d;
  54.             nearest_uv = uvs[i];
  55.         }
  56.        
  57.         vec3 n = texture(normal_texture, uvs[i]).xyz * 2.0 - 1.0;
  58.         vec3 normal_diff = normal - n;
  59.        
  60.         // Edge pixels should yield to the normal closest to the bias direction
  61.         float normal_bias_diff = dot(normal_diff, normal_edge_bias);
  62.         float normal_indicator = smoothstep(-0.01, 0.01, normal_bias_diff);
  63.        
  64.         normal_sum += dot(normal_diff, normal_diff) * normal_indicator;
  65.     }
  66.     float depth_edge = step(depth_threshold, depth_diff);
  67.    
  68.     // The reverse depth sum produces depth lines inside of the object, but they don't look as nice as the normal depth_diff
  69.     // Instead, we can use this value to mask the normal edge along the outside of the object
  70.     float reverse_depth_edge = step(reverse_depth_threshold, depth_diff_reversed);
  71.    
  72.     float indicator = sqrt(normal_sum);
  73.     float normal_edge = step(normal_threshold, indicator - reverse_depth_edge);
  74.    
  75.     vec3 original = texture(screen_texture, SCREEN_UV).rgb;
  76.     vec3 nearest = texture(screen_texture, nearest_uv).rgb;
  77.    
  78.     mat3 view_to_world_normal_mat = mat3(
  79.             INV_VIEW_MATRIX[0].xyz,
  80.             INV_VIEW_MATRIX[1].xyz,
  81.             INV_VIEW_MATRIX[2].xyz
  82.     );
  83.     float ld = dot((view_to_world_normal_mat * normal), normalize(light_direction));
  84.    
  85.     vec3 depth_col = nearest * darken_amount;
  86.     vec3 normal_col = original * (ld > 0.0 ? darken_amount : lighten_amount);
  87.     vec3 edge_mix = mix(normal_col, depth_col, depth_edge);
  88.    
  89.     ALBEDO = mix(original, edge_mix, (depth_edge > 0.0 ? depth_edge : normal_edge));
  90. }
Advertisement
Add Comment
Please, Sign In to add comment