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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
out vec4 fragColor;
uniform mat4 ProjectionMatrix;
uniform usampler2D objectId;
uniform sampler2D colorBuffer;
uniform sampler2D specularBuffer;
uniform sampler2D normalBuffer;
/* normalBuffer contains viewport normals */
uniform sampler2D cavityBuffer;
uniform vec2 invertedViewportSize;
uniform vec4 viewvecs[3];
uniform float shadowMultiplier;
uniform float lightMultiplier;
uniform float shadowShift = 0.1;
uniform mat3 normalWorldMatrix;
#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
uniform sampler2D matcapImage;
#endif
layout(std140) uniform world_block {
WorldData world_data;
};
void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize;
uint object_id = texelFetch(objectId, texel, 0).r;
#ifndef V3D_SHADING_OBJECT_OUTLINE
if (object_id == NO_OBJECT_ID) {
fragColor = vec4(background_color(world_data, uv_viewport.y), world_data.background_alpha);
return;
}
#else /* !V3D_SHADING_OBJECT_OUTLINE */
float object_outline = calculate_object_outline(objectId, texel, object_id);
if (object_id == NO_OBJECT_ID) {
vec3 background = background_color(world_data, uv_viewport.y);
if (object_outline == 0.0) {
fragColor = vec4(background, world_data.background_alpha);
}
else {
/* Do correct alpha blending. */
vec4 background_color = vec4(background, 1.0) * world_data.background_alpha;
vec4 outline_color = vec4(world_data.object_outline_color.rgb, 1.0);
fragColor = mix(outline_color, background_color, object_outline);
fragColor = vec4(fragColor.rgb / max(1e-8, fragColor.a), fragColor.a);
}
return;
}
#endif /* !V3D_SHADING_OBJECT_OUTLINE */
vec4 diffuse_color = texelFetch(colorBuffer, texel, 0);
/* Do we need normals */
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
# ifdef WORKBENCH_ENCODE_NORMALS
vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg);
if (diffuse_color.a == 0.0) {
normal_viewport = -normal_viewport;
}
# else /* WORKBENCH_ENCODE_NORMALS */
vec3 normal_viewport = texelFetch(normalBuffer, texel, 0).rgb;
# endif /* WORKBENCH_ENCODE_NORMALS */
#endif
vec3 I_vs = view_vector_from_screen_uv(uv_viewport, viewvecs, ProjectionMatrix);
#ifdef STUDIOLIGHT_ORIENTATION_VIEWNORMAL
bool flipped = world_data.matcap_orientation != 0;
vec2 matcap_uv = matcap_uv_compute(I_vs, normal_viewport, flipped);
diffuse_color = textureLod(matcapImage, matcap_uv, 0.0);
#endif
#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
vec4 specular_data = texelFetch(specularBuffer, texel, 0);
vec3 specular_color = get_world_specular_lights(world_data, specular_data, normal_viewport, I_vs);
#else
vec3 specular_color = vec3(0.0);
#endif
#ifdef V3D_LIGHTING_FLAT
vec3 diffuse_light = vec3(1.0);
#endif
#ifdef V3D_LIGHTING_MATCAP
vec3 diffuse_light = texelFetch(specularBuffer, texel, 0).rgb;
#endif
#ifdef V3D_LIGHTING_STUDIO
# ifdef STUDIOLIGHT_ORIENTATION_CAMERA
vec3 diffuse_light = get_camera_diffuse_light(world_data, normal_viewport);
# endif
# ifdef STUDIOLIGHT_ORIENTATION_WORLD
vec3 normal_world = normalWorldMatrix * normal_viewport;
vec3 diffuse_light = get_world_diffuse_light(world_data, normal_world);
# endif
#endif
vec3 shaded_color = diffuse_light * diffuse_color.rgb + specular_color;
#ifdef V3D_SHADING_SSAO
vec2 cavity = texelFetch(cavityBuffer, texel, 0).rg;
shaded_color *= 1.0 - cavity.x;
shaded_color *= 1.0 + cavity.y;
#endif
#ifdef V3D_SHADING_CURVATURE
float curvature = calculate_curvature(objectId, normalBuffer, texel, world_data.curvature_ridge, world_data.curvature_valley);
shaded_color *= curvature + 1.0;
#endif
#ifdef V3D_SHADING_SHADOW
float light_factor = -dot(normal_viewport, world_data.shadow_direction_vs.xyz);
/* The step function might be ok for meshes but it's
* clearly not the case for hairs. Do smoothstep in this case. */
float shadow_mix = smoothstep(1.0, shadowShift, light_factor);
float light_multiplier = mix(lightMultiplier, shadowMultiplier, shadow_mix);
#else /* V3D_SHADING_SHADOW */
float light_multiplier = 1.0;
#endif /* V3D_SHADING_SHADOW */
shaded_color *= light_multiplier;
#ifdef V3D_SHADING_OBJECT_OUTLINE
shaded_color = mix(world_data.object_outline_color.rgb, shaded_color, object_outline);
#endif /* V3D_SHADING_OBJECT_OUTLINE */
fragColor = vec4(shaded_color, 1.0);
}
|