/
cs_clip_box_shadow.glsl
117 lines (98 loc) · 3.42 KB
/
cs_clip_box_shadow.glsl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include shared,clip_shared
varying vec3 vLocalPos;
varying vec2 vUv;
flat varying vec4 vUvBounds;
flat varying float vLayer;
flat varying vec4 vEdge;
flat varying vec4 vUvBounds_NoClamp;
flat varying float vClipMode;
#define MODE_STRETCH 0
#define MODE_SIMPLE 1
#ifdef WR_VERTEX_SHADER
struct BoxShadowData {
vec2 src_rect_size;
float clip_mode;
int stretch_mode_x;
int stretch_mode_y;
RectWithSize dest_rect;
};
BoxShadowData fetch_data(ivec2 address) {
vec4 data[3] = fetch_from_resource_cache_3_direct(address);
RectWithSize dest_rect = RectWithSize(data[2].xy, data[2].zw);
BoxShadowData bs_data = BoxShadowData(
data[0].xy,
data[0].z,
int(data[1].x),
int(data[1].y),
dest_rect
);
return bs_data;
}
void main(void) {
ClipMaskInstance cmi = fetch_clip_item();
ClipArea area = fetch_clip_area(cmi.render_task_address);
Transform clip_transform = fetch_transform(cmi.clip_transform_id);
Transform prim_transform = fetch_transform(cmi.prim_transform_id);
BoxShadowData bs_data = fetch_data(cmi.clip_data_address);
ImageResource res = fetch_image_resource_direct(cmi.resource_address);
ClipVertexInfo vi = write_clip_tile_vertex(
bs_data.dest_rect,
prim_transform,
clip_transform,
area
);
vLocalPos = vi.local_pos;
vLayer = res.layer;
vClipMode = bs_data.clip_mode;
vec2 uv0 = res.uv_rect.p0;
vec2 uv1 = res.uv_rect.p1;
vec2 texture_size = vec2(textureSize(sColor0, 0));
vec2 local_pos = vLocalPos.xy / vLocalPos.z;
switch (bs_data.stretch_mode_x) {
case MODE_STRETCH: {
vEdge.x = 0.5;
vEdge.z = (bs_data.dest_rect.size.x / bs_data.src_rect_size.x) - 0.5;
vUv.x = (local_pos.x - bs_data.dest_rect.p0.x) / bs_data.src_rect_size.x;
break;
}
case MODE_SIMPLE:
default: {
vEdge.xz = vec2(1.0);
vUv.x = (local_pos.x - bs_data.dest_rect.p0.x) / bs_data.dest_rect.size.x;
break;
}
}
switch (bs_data.stretch_mode_y) {
case MODE_STRETCH: {
vEdge.y = 0.5;
vEdge.w = (bs_data.dest_rect.size.y / bs_data.src_rect_size.y) - 0.5;
vUv.y = (local_pos.y - bs_data.dest_rect.p0.y) / bs_data.src_rect_size.y;
break;
}
case MODE_SIMPLE:
default: {
vEdge.yw = vec2(1.0);
vUv.y = (local_pos.y - bs_data.dest_rect.p0.y) / bs_data.dest_rect.size.y;
break;
}
}
vUvBounds = vec4(uv0 + vec2(0.5), uv1 - vec2(0.5)) / texture_size.xyxy;
vUvBounds_NoClamp = vec4(uv0, uv1) / texture_size.xyxy;
}
#endif
#ifdef WR_FRAGMENT_SHADER
void main(void) {
vec2 local_pos = vLocalPos.xy / vLocalPos.z;
vec2 uv = clamp(vUv.xy, vec2(0.0), vEdge.xy);
uv += max(vec2(0.0), vUv.xy - vEdge.zw);
uv = mix(vUvBounds_NoClamp.xy, vUvBounds_NoClamp.zw, uv);
uv = clamp(uv, vUvBounds.xy, vUvBounds.zw);
float in_shadow_rect = init_transform_rough_fs(local_pos);
float texel = TEX_SAMPLE(sColor0, vec3(uv, vLayer)).r;
float alpha = mix(texel, 1.0 - texel, vClipMode);
oFragColor = vec4(mix(vClipMode, alpha, in_shadow_rect));
}
#endif