Cleanup: manually remove header text not handled by automation
[blender.git] / intern / opensubdiv / shader / gpu_shader_opensubdiv_fragment.glsl
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2014 Blender Foundation.
17  * All rights reserved.
18  */
19
20 struct VertexData {
21         vec4 position;
22         vec3 normal;
23         vec2 uv;
24 };
25
26 #define MAX_LIGHTS 8
27 #define NUM_SOLID_LIGHTS 3
28
29 struct LightSource {
30         vec4 position;
31         vec4 ambient;
32         vec4 diffuse;
33         vec4 specular;
34         vec4 spotDirection;
35 #ifdef SUPPORT_COLOR_MATERIAL
36         float constantAttenuation;
37         float linearAttenuation;
38         float quadraticAttenuation;
39         float spotCutoff;
40         float spotExponent;
41         float spotCosCutoff;
42         float pad, pad2;
43 #endif
44 };
45
46 layout(std140) uniform Lighting {
47         LightSource lightSource[MAX_LIGHTS];
48         int num_enabled_lights;
49 };
50
51 uniform vec4 diffuse;
52 uniform vec4 specular;
53 uniform float shininess;
54
55 uniform sampler2D texture_buffer;
56
57 in block {
58         VertexData v;
59 } inpt;
60
61 void main()
62 {
63 #ifdef WIREFRAME
64         gl_FragColor = diffuse;
65 #else
66         vec3 N = inpt.v.normal;
67
68         if (!gl_FrontFacing)
69                 N = -N;
70
71         /* Compute diffuse and specular lighting. */
72         vec3 L_diffuse = vec3(0.0);
73         vec3 L_specular = vec3(0.0);
74
75 #ifdef USE_LIGHTING
76 #ifndef USE_COLOR_MATERIAL
77         /* Assume NUM_SOLID_LIGHTS directional lights. */
78         for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
79                 vec4 Plight = lightSource[i].position;
80 #ifdef USE_DIRECTIONAL_LIGHT
81                 vec3 l = (Plight.w == 0.0)
82                             ? normalize(Plight.xyz)
83                             : normalize(inpt.v.position.xyz);
84 #else  /* USE_DIRECTIONAL_LIGHT */
85                 /* TODO(sergey): We can normalize it outside of the shader. */
86                 vec3 l = normalize(Plight.xyz);
87 #endif  /* USE_DIRECTIONAL_LIGHT */
88                 vec3 h = normalize(l + vec3(0, 0, 1));
89                 float d = max(0.0, dot(N, l));
90                 float s = pow(max(0.0, dot(N, h)), shininess);
91                 L_diffuse += d * lightSource[i].diffuse.rgb;
92                 L_specular += s * lightSource[i].specular.rgb;
93         }
94 #else  /* USE_COLOR_MATERIAL */
95         vec3 varying_position = inpt.v.position.xyz;
96         vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ?
97                  normalize(varying_position) : vec3(0.0, 0.0, -1.0);
98         for (int i = 0; i < num_enabled_lights; i++) {
99                 /* todo: this is a slow check for disabled lights */
100                 if (lightSource[i].specular.a == 0.0)
101                         continue;
102
103                 float intensity = 1.0;
104                 vec3 light_direction;
105
106                 if (lightSource[i].position.w == 0.0) {
107                         /* directional light */
108                         light_direction = lightSource[i].position.xyz;
109                 }
110                 else {
111                         /* point light */
112                         vec3 d = lightSource[i].position.xyz - varying_position;
113                         light_direction = normalize(d);
114
115                         /* spot light cone */
116                         if (lightSource[i].spotCutoff < 90.0) {
117                                 float cosine = max(dot(light_direction,
118                                                        -lightSource[i].spotDirection.xyz),
119                                                    0.0);
120                                 intensity = pow(cosine, lightSource[i].spotExponent);
121                                 intensity *= step(lightSource[i].spotCosCutoff, cosine);
122                         }
123
124                         /* falloff */
125                         float distance = length(d);
126
127                         intensity /= lightSource[i].constantAttenuation +
128                                 lightSource[i].linearAttenuation * distance +
129                                 lightSource[i].quadraticAttenuation * distance * distance;
130                 }
131
132                 /* diffuse light */
133                 vec3 light_diffuse = lightSource[i].diffuse.rgb;
134                 float diffuse_bsdf = max(dot(N, light_direction), 0.0);
135                 L_diffuse += light_diffuse * diffuse_bsdf * intensity;
136
137                 /* specular light */
138                 vec3 light_specular = lightSource[i].specular.rgb;
139                 vec3 H = normalize(light_direction - V);
140
141                 float specular_bsdf = pow(max(dot(N, H), 0.0),
142                                           gl_FrontMaterial.shininess);
143                 L_specular += light_specular * specular_bsdf * intensity;
144         }
145 #endif  /* USE_COLOR_MATERIAL */
146 #else  /* USE_LIGHTING */
147         L_diffuse = vec3(1.0);
148 #endif
149
150         /* Compute diffuse color. */
151 #ifdef USE_TEXTURE_2D
152         L_diffuse *= texture2D(texture_buffer, inpt.v.uv).rgb;
153 #else
154         L_diffuse *= diffuse.rgb;
155 #endif
156
157         /* Sum lighting. */
158         vec3 L = L_diffuse;
159         if (shininess != 0) {
160                 L += L_specular * specular.rgb;
161         }
162
163         /* Write out fragment color. */
164         gl_FragColor = vec4(L, diffuse.a);
165 #endif
166 }