Changeset View
Changeset View
Standalone View
Standalone View
src/scenegraph/shaders/shadowedtexture.frag
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl> | 2 | * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl> | ||
3 | * | 3 | * | ||
4 | * SPDX-License-Identifier: LGPL-2.0-or-later | 4 | * SPDX-License-Identifier: LGPL-2.0-or-later | ||
5 | */ | 5 | */ | ||
6 | 6 | | |||
7 | // See sdf.glsl for the SDF related functions. | 7 | // See sdf.glsl for the SDF related functions. | ||
8 | 8 | | |||
9 | // This shader renders a texture on top of a rectangle with rounded corners and | 9 | // This shader renders a texture on top of a rectangle with rounded corners and | ||
10 | // a shadow below it. | 10 | // a shadow below it. | ||
11 | 11 | | |||
12 | uniform lowp float opacity; | 12 | uniform lowp float opacity; | ||
13 | uniform lowp float size; | 13 | uniform lowp float size; | ||
14 | uniform lowp float radius; | 14 | uniform lowp vec4 radius; | ||
15 | uniform lowp vec4 color; | 15 | uniform lowp vec4 color; | ||
16 | uniform lowp vec4 shadowColor; | 16 | uniform lowp vec4 shadowColor; | ||
17 | uniform lowp vec2 offset; | 17 | uniform lowp vec2 offset; | ||
18 | uniform lowp vec2 aspect; | 18 | uniform lowp vec2 aspect; | ||
19 | uniform sampler2D textureSource; | 19 | uniform sampler2D textureSource; | ||
20 | 20 | | |||
21 | #ifdef CORE_PROFILE | 21 | #ifdef CORE_PROFILE | ||
22 | in lowp vec2 uv; | 22 | in lowp vec2 uv; | ||
Show All 17 Lines | |||||
40 | void main() | 40 | void main() | ||
41 | { | 41 | { | ||
42 | // Scaling factor that is the inverse of the amount of scaling applied to the geometry. | 42 | // Scaling factor that is the inverse of the amount of scaling applied to the geometry. | ||
43 | lowp float inverse_scale = 1.0 / (1.0 + size + length(offset) * 2.0); | 43 | lowp float inverse_scale = 1.0 / (1.0 + size + length(offset) * 2.0); | ||
44 | 44 | | |||
45 | // Correction factor to round the corners of a larger shadow. | 45 | // Correction factor to round the corners of a larger shadow. | ||
46 | // We want to account for size in regards to shadow radius, so that a larger shadow is | 46 | // We want to account for size in regards to shadow radius, so that a larger shadow is | ||
47 | // more rounded, but only if we are not already rounding the corners due to corner radius. | 47 | // more rounded, but only if we are not already rounding the corners due to corner radius. | ||
48 | lowp float size_factor = 0.5 * (minimum_shadow_radius / max(radius, minimum_shadow_radius)); | 48 | lowp vec4 size_factor = 0.5 * (minimum_shadow_radius / max(radius, minimum_shadow_radius)); | ||
49 | lowp float shadow_radius = radius + size * size_factor; | 49 | lowp vec4 shadow_radius = radius + size * size_factor; | ||
50 | 50 | | |||
51 | lowp vec4 col = vec4(0.0); | 51 | lowp vec4 col = vec4(0.0); | ||
52 | 52 | | |||
53 | // Calculate the shadow's distance field. | 53 | // Calculate the shadow's distance field. | ||
54 | lowp float shadow = sdf_rounded_rectangle(uv - offset * 2.0 * inverse_scale, aspect * inverse_scale, vec4(shadow_radius * inverse_scale)); | 54 | lowp float shadow = sdf_rounded_rectangle(uv - offset * 2.0 * inverse_scale, aspect * inverse_scale, shadow_radius * inverse_scale); | ||
55 | // Render it, interpolating the color over the distance. | 55 | // Render it, interpolating the color over the distance. | ||
56 | col = mix(col, shadowColor * sign(size), 1.0 - smoothstep(-size * 0.5, size * 0.5, shadow)); | 56 | col = mix(col, shadowColor * sign(size), 1.0 - smoothstep(-size * 0.5, size * 0.5, shadow)); | ||
57 | 57 | | |||
58 | // Calculate the main rectangle distance field. | 58 | // Calculate the main rectangle distance field. | ||
59 | lowp float rect = sdf_rounded_rectangle(uv, aspect * inverse_scale, vec4(radius * inverse_scale)); | 59 | lowp float rect = sdf_rounded_rectangle(uv, aspect * inverse_scale, radius * inverse_scale); | ||
60 | 60 | | |||
61 | // First, remove anything that was rendered by the shadow if it is inside the rectangle. | 61 | // First, remove anything that was rendered by the shadow if it is inside the rectangle. | ||
62 | // This allows us to use colors with alpha without rendering artifacts. | 62 | // This allows us to use colors with alpha without rendering artifacts. | ||
63 | col = sdf_render(rect, col, vec4(0.0)); | 63 | col = sdf_render(rect, col, vec4(0.0)); | ||
64 | 64 | | |||
65 | // Then, render it again but this time with the proper color. | 65 | // Then, render it again but this time with the proper color. | ||
66 | col = sdf_render(rect, col, color); | 66 | col = sdf_render(rect, col, color); | ||
67 | 67 | | |||
68 | // Sample the texture, then blend it on top of the background color. | 68 | // Sample the texture, then blend it on top of the background color. | ||
69 | lowp vec2 texture_uv = ((uv / aspect) + (1.0 * inverse_scale)) / (2.0 * inverse_scale); | 69 | lowp vec2 texture_uv = ((uv / aspect) + (1.0 * inverse_scale)) / (2.0 * inverse_scale); | ||
70 | lowp vec4 texture_color = sample_texture(textureSource, texture_uv); | 70 | lowp vec4 texture_color = sample_texture(textureSource, texture_uv); | ||
71 | col = sdf_render(rect, col, texture_color, texture_color.a, sdf_default_smoothing); | 71 | col = sdf_render(rect, col, texture_color, texture_color.a, sdf_default_smoothing); | ||
72 | // col = sdf_render(rect, col, vec4(texture_uv / inverse_scale, sign(texture_uv).x, 1.0)); | | |||
73 | 72 | | |||
74 | #ifdef CORE_PROFILE | 73 | #ifdef CORE_PROFILE | ||
75 | out_color = col * opacity; | 74 | out_color = col * opacity; | ||
76 | #else | 75 | #else | ||
77 | gl_FragColor = col * opacity; | 76 | gl_FragColor = col * opacity; | ||
78 | #endif | 77 | #endif | ||
79 | } | 78 | } |