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