Merge branch 'master' into blender2.8
[blender.git] / source / blender / gpu / shaders / gpu_shader_basic_frag.glsl
1
2 /* Options:
3  *
4  * USE_COLOR: use glColor for diffuse colors
5  * USE_TEXTURE: use texture for diffuse colors
6  * USE_SCENE_LIGHTING: use lights (up to 8)
7  * USE_SOLID_LIGHTING: assume 3 directional lights for solid draw mode
8  * USE_TWO_SIDED: flip normal towards viewer
9  * NO_SPECULAR: use specular component
10  */
11
12 #define NUM_SOLID_LIGHTS 3
13 #define NUM_SCENE_LIGHTS 8
14
15 /* Keep these in sync with GPU_basic_shader.h */
16 #define STIPPLE_HALFTONE                               0
17 #define STIPPLE_QUARTTONE                              1
18 #define STIPPLE_CHECKER_8PX                            2
19 #define STIPPLE_HEXAGON                                3
20 #define STIPPLE_DIAG_STRIPES                           4
21 #define STIPPLE_DIAG_STRIPES_SWAP                      5
22 #define STIPPLE_S3D_INTERLACE_ROW                      6
23 #define STIPPLE_S3D_INTERLACE_ROW_SWAP                 7
24 #define STIPPLE_S3D_INTERLACE_COLUMN                   8
25 #define STIPPLE_S3D_INTERLACE_COLUMN_SWAP              9
26 #define STIPPLE_S3D_INTERLACE_CHECKERBOARD             10
27 #define STIPPLE_S3D_INTERLACE_CHECKERBOARD_SWAP        11
28
29 #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
30 #if defined(USE_FLAT_NORMAL)
31 varying vec3 eyespace_vert_pos;
32 #else
33 varying vec3 varying_normal;
34 #endif
35 #ifndef USE_SOLID_LIGHTING
36 varying vec3 varying_position;
37 #endif
38 #endif
39
40 #ifdef USE_COLOR
41 varying vec4 varying_vertex_color;
42 #endif
43
44 #ifdef USE_TEXTURE
45 varying vec2 varying_texture_coord;
46 uniform sampler2D texture_map;
47 #endif
48
49 #ifdef USE_STIPPLE
50 uniform int stipple_id;
51 #if defined(DRAW_LINE)
52 varying in float t;
53 uniform int stipple_pattern;
54 #endif
55 #endif
56
57 void main()
58 {
59 #if defined(USE_STIPPLE)
60 #if defined(DRAW_LINE)
61         /* GLSL 1.3 */
62         if (!bool((1 << int(mod(t, 16))) & stipple_pattern))
63                 discard;
64 #else
65         /* We have to use mod function and integer casting.
66          * This can be optimized further with the bitwise operations
67          * when GLSL 1.3 is supported. */
68         if (stipple_id == STIPPLE_HALFTONE ||
69             stipple_id == STIPPLE_S3D_INTERLACE_CHECKERBOARD ||
70             stipple_id == STIPPLE_S3D_INTERLACE_CHECKERBOARD_SWAP)
71         {
72                 int result = int(mod(gl_FragCoord.x + gl_FragCoord.y, 2));
73                 bool dis = result == 0;
74                 if (stipple_id == STIPPLE_S3D_INTERLACE_CHECKERBOARD_SWAP)
75                         dis = !dis;
76                 if (dis)
77                         discard;
78         }
79         else if (stipple_id == STIPPLE_QUARTTONE) {
80                 int mody = int(mod(gl_FragCoord.y, 4));
81                 int modx = int(mod(gl_FragCoord.x, 4));
82                 if (mody == 0) {
83                         if (modx != 2)
84                                 discard;
85                 }
86                 else if (mody == 2) {
87                         if (modx != 0)
88                                 discard;
89                 }
90                 else
91                         discard;
92         }
93         else if (stipple_id == STIPPLE_CHECKER_8PX) {
94                 int result = int(mod(int(gl_FragCoord.x)/8 + int(gl_FragCoord.y) / 8, 2));
95                 if (result != 0)
96                         discard;
97         }
98         else if (stipple_id == STIPPLE_DIAG_STRIPES) {
99                 int mody = int(mod(gl_FragCoord.y, 16));
100                 int modx = int(mod(gl_FragCoord.x, 16));
101                 if ((16 - modx > mody && mody > 8 - modx) || mody > 24 - modx)
102                         discard;
103         }
104         else if (stipple_id == STIPPLE_DIAG_STRIPES_SWAP) {
105                 int mody = int(mod(gl_FragCoord.y, 16));
106                 int modx = int(mod(gl_FragCoord.x, 16));
107                 if (!((16 - modx > mody && mody > 8 - modx) || mody > 24 - modx))
108                         discard;
109         }
110         else if (stipple_id == STIPPLE_S3D_INTERLACE_ROW || stipple_id == STIPPLE_S3D_INTERLACE_ROW_SWAP) {
111                 int result = int(mod(gl_FragCoord.y, 2));
112                 bool dis = result == 0;
113                 if (stipple_id == STIPPLE_S3D_INTERLACE_ROW_SWAP)
114                         dis = !dis;
115                 if (dis)
116                         discard;
117         }
118         else if (stipple_id == STIPPLE_S3D_INTERLACE_COLUMN || stipple_id == STIPPLE_S3D_INTERLACE_COLUMN_SWAP) {
119                 int result = int(mod(gl_FragCoord.x, 2));
120                 bool dis = result != 0;
121                 if (stipple_id == STIPPLE_S3D_INTERLACE_COLUMN_SWAP)
122                         dis = !dis;
123                 if (dis)
124                         discard;
125         }
126         else if (stipple_id == STIPPLE_HEXAGON) {
127                 int mody = int(mod(gl_FragCoord.y, 2));
128                 int modx = int(mod(gl_FragCoord.x, 4));
129                 if (mody != 0) {
130                         if (modx != 1)
131                                 discard;
132                 }
133                 else {
134                         if (modx != 3)
135                                 discard;
136                 }
137         }
138 #endif /* !DRAW_LINE */
139 #endif /* USE_STIPPLE */
140
141 #if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
142         /* compute normal */
143 #if defined(USE_FLAT_NORMAL)
144         vec3 N = normalize(cross(dFdx(eyespace_vert_pos), dFdy(eyespace_vert_pos)));
145 #else
146         vec3 N = normalize(varying_normal);
147 #endif
148
149 #ifdef USE_TWO_SIDED
150         if (!gl_FrontFacing)
151                 N = -N;
152 #endif
153
154         /* compute diffuse and specular lighting */
155         vec3 L_diffuse = vec3(0.0);
156 #ifndef NO_SPECULAR
157         vec3 L_specular = vec3(0.0);
158 #endif
159
160 #ifdef USE_SOLID_LIGHTING
161         /* assume 3 directional lights */
162         for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
163                 vec3 light_direction = gl_LightSource[i].position.xyz;
164
165                 /* diffuse light */
166                 vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
167                 float diffuse_bsdf = max(dot(N, light_direction), 0.0);
168                 L_diffuse += light_diffuse*diffuse_bsdf;
169
170 #ifndef NO_SPECULAR
171                 /* specular light */
172                 vec3 light_specular = gl_LightSource[i].specular.rgb;
173                 vec3 H = gl_LightSource[i].halfVector.xyz;
174
175                 float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
176                 L_specular += light_specular*specular_bsdf;
177 #endif
178         }
179 #else
180         /* all 8 lights, makes no assumptions, potentially slow */
181
182 #ifndef NO_SPECULAR
183         /* view vector computation, depends on orthographics or perspective */
184         vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position): vec3(0.0, 0.0, -1.0);
185 #endif
186
187         for (int i = 0; i < NUM_SCENE_LIGHTS; i++) {
188                 /* todo: this is a slow check for disabled lights */
189                 if (gl_LightSource[i].specular.a == 0.0)
190                         continue;
191
192                 float intensity = 1.0;
193                 vec3 light_direction;
194
195                 if (gl_LightSource[i].position.w == 0.0) {
196                         /* directional light */
197                         light_direction = gl_LightSource[i].position.xyz;
198                 }
199                 else {
200                         /* point light */
201                         vec3 d = gl_LightSource[i].position.xyz - varying_position;
202                         light_direction = normalize(d);
203
204                         /* spot light cone */
205                         if (gl_LightSource[i].spotCutoff < 90.0) {
206                                 float cosine = max(dot(light_direction, -gl_LightSource[i].spotDirection), 0.0);
207                                 intensity = pow(cosine, gl_LightSource[i].spotExponent);
208                                 intensity *= step(gl_LightSource[i].spotCosCutoff, cosine);
209                         }
210
211                         /* falloff */
212                         float distance = length(d);
213
214                         intensity /= gl_LightSource[i].constantAttenuation +
215                                 gl_LightSource[i].linearAttenuation * distance +
216                                 gl_LightSource[i].quadraticAttenuation * distance * distance;
217                 }
218
219                 /* diffuse light */
220                 vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
221                 float diffuse_bsdf = max(dot(N, light_direction), 0.0);
222                 L_diffuse += light_diffuse*diffuse_bsdf*intensity;
223
224 #ifndef NO_SPECULAR
225                 /* specular light */
226                 vec3 light_specular = gl_LightSource[i].specular.rgb;
227                 vec3 H = normalize(light_direction - V);
228
229                 float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
230                 L_specular += light_specular*specular_bsdf*intensity;
231 #endif
232         }
233 #endif
234
235         /* compute diffuse color, possibly from texture or vertex colors */
236         float alpha;
237
238 #if defined(USE_TEXTURE) && defined(USE_COLOR)
239         vec4 texture_color = texture2D(texture_map, varying_texture_coord);
240
241         L_diffuse *= texture_color.rgb * varying_vertex_color.rgb;
242         alpha = texture_color.a * varying_vertex_color.a;
243 #elif defined(USE_TEXTURE)
244         vec4 texture_color = texture2D(texture_map, varying_texture_coord);
245
246         L_diffuse *= texture_color.rgb;
247         alpha = texture_color.a;
248 #elif defined(USE_COLOR)
249         L_diffuse *= varying_vertex_color.rgb;
250         alpha = varying_vertex_color.a;
251 #else
252         L_diffuse *= gl_FrontMaterial.diffuse.rgb;
253         alpha = gl_FrontMaterial.diffuse.a;
254 #endif
255
256         /* sum lighting */
257         vec3 L = gl_FrontLightModelProduct.sceneColor.rgb + L_diffuse;
258
259 #ifndef NO_SPECULAR
260         L += L_specular*gl_FrontMaterial.specular.rgb;
261 #endif
262
263         /* write out fragment color */
264         gl_FragColor = vec4(L, alpha);
265 #else
266
267         /* no lighting */
268 #if defined(USE_TEXTURE) && defined(USE_COLOR)
269         gl_FragColor = texture2D(texture_map, varying_texture_coord) * varying_vertex_color;
270 #elif defined(USE_TEXTURE)
271         gl_FragColor = texture2D(texture_map, varying_texture_coord);
272 #elif defined(USE_COLOR)
273         gl_FragColor = varying_vertex_color;
274 #else
275         gl_FragColor = gl_FrontMaterial.diffuse;
276 #endif
277
278 #endif
279 }
280