Builtin names staring with gl_ will not be available in core profile. Same with the ftransform function. New matrix API provides the same names minus the gl_ prefix. Part of T49450
267 lines
7.2 KiB
GLSL
267 lines
7.2 KiB
GLSL
|
|
/* Options:
|
|
*
|
|
* USE_COLOR: use glColor for diffuse colors
|
|
* USE_TEXTURE: use texture for diffuse colors
|
|
* USE_TEXTURE_RECTANGLE: use GL_TEXTURE_RECTANGLE instead of GL_TEXTURE_2D
|
|
* USE_SCENE_LIGHTING: use lights (up to 8)
|
|
* USE_SOLID_LIGHTING: assume 3 directional lights for solid draw mode
|
|
* USE_TWO_SIDED: flip normal towards viewer
|
|
* NO_SPECULAR: use specular component
|
|
*/
|
|
|
|
#define NUM_SOLID_LIGHTS 3
|
|
#define NUM_SCENE_LIGHTS 8
|
|
|
|
/* Keep these in sync with GPU_basic_shader.h */
|
|
#define STIPPLE_HALFTONE 0
|
|
#define STIPPLE_QUARTTONE 1
|
|
#define STIPPLE_CHECKER_8PX 2
|
|
#define STIPPLE_HEXAGON 3
|
|
#define STIPPLE_DIAG_STRIPES 4
|
|
#define STIPPLE_DIAG_STRIPES_SWAP 5
|
|
|
|
#ifndef NO_SPECULAR
|
|
uniform mat4 ProjectionMatrix;
|
|
#endif
|
|
|
|
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
|
|
#if defined(USE_FLAT_NORMAL)
|
|
varying vec3 eyespace_vert_pos;
|
|
#else
|
|
varying vec3 varying_normal;
|
|
#endif
|
|
#ifndef USE_SOLID_LIGHTING
|
|
varying vec3 varying_position;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef USE_COLOR
|
|
varying vec4 varying_vertex_color;
|
|
#endif
|
|
|
|
#ifdef USE_TEXTURE
|
|
#ifdef USE_TEXTURE_RECTANGLE
|
|
#define sampler2D_default sampler2DRect
|
|
#define texture2D_default texture2DRect
|
|
#else
|
|
#define sampler2D_default sampler2D
|
|
#define texture2D_default texture2D
|
|
#endif
|
|
|
|
varying vec2 varying_texture_coord;
|
|
uniform sampler2D_default texture_map;
|
|
#endif
|
|
|
|
#ifdef USE_STIPPLE
|
|
uniform int stipple_id;
|
|
#if defined(DRAW_LINE)
|
|
varying float t;
|
|
uniform int stipple_pattern;
|
|
#endif
|
|
#endif
|
|
|
|
void main()
|
|
{
|
|
#if defined(USE_STIPPLE)
|
|
#if defined(DRAW_LINE)
|
|
/* GLSL 1.3 */
|
|
if (!bool((1 << int(mod(t, 16))) & stipple_pattern))
|
|
discard;
|
|
#else
|
|
/* We have to use mod function and integer casting.
|
|
* This can be optimized further with the bitwise operations
|
|
* when GLSL 1.3 is supported. */
|
|
if (stipple_id == STIPPLE_HALFTONE) {
|
|
int result = int(mod(gl_FragCoord.x + gl_FragCoord.y, 2));
|
|
bool dis = result == 0;
|
|
if (dis)
|
|
discard;
|
|
}
|
|
else if (stipple_id == STIPPLE_QUARTTONE) {
|
|
int mody = int(mod(gl_FragCoord.y, 4));
|
|
int modx = int(mod(gl_FragCoord.x, 4));
|
|
if (mody == 0) {
|
|
if (modx != 2)
|
|
discard;
|
|
}
|
|
else if (mody == 2) {
|
|
if (modx != 0)
|
|
discard;
|
|
}
|
|
else
|
|
discard;
|
|
}
|
|
else if (stipple_id == STIPPLE_CHECKER_8PX) {
|
|
int result = int(mod(int(gl_FragCoord.x) / 8 + int(gl_FragCoord.y) / 8, 2));
|
|
if (result != 0)
|
|
discard;
|
|
}
|
|
else if (stipple_id == STIPPLE_DIAG_STRIPES) {
|
|
int mody = int(mod(gl_FragCoord.y, 16));
|
|
int modx = int(mod(gl_FragCoord.x, 16));
|
|
if ((16 - modx > mody && mody > 8 - modx) || mody > 24 - modx)
|
|
discard;
|
|
}
|
|
else if (stipple_id == STIPPLE_DIAG_STRIPES_SWAP) {
|
|
int mody = int(mod(gl_FragCoord.y, 16));
|
|
int modx = int(mod(gl_FragCoord.x, 16));
|
|
if (!((16 - modx > mody && mody > 8 - modx) || mody > 24 - modx))
|
|
discard;
|
|
}
|
|
else if (stipple_id == STIPPLE_HEXAGON) {
|
|
int mody = int(mod(gl_FragCoord.y, 2));
|
|
int modx = int(mod(gl_FragCoord.x, 4));
|
|
if (mody != 0) {
|
|
if (modx != 1)
|
|
discard;
|
|
}
|
|
else {
|
|
if (modx != 3)
|
|
discard;
|
|
}
|
|
}
|
|
#endif /* !DRAW_LINE */
|
|
#endif /* USE_STIPPLE */
|
|
|
|
#if defined(USE_SOLID_LIGHTING) || defined(USE_SCENE_LIGHTING)
|
|
/* compute normal */
|
|
#if defined(USE_FLAT_NORMAL)
|
|
vec3 N = normalize(cross(dFdx(eyespace_vert_pos), dFdy(eyespace_vert_pos)));
|
|
#else
|
|
vec3 N = normalize(varying_normal);
|
|
#endif
|
|
|
|
#ifdef USE_TWO_SIDED
|
|
if (!gl_FrontFacing)
|
|
N = -N;
|
|
#endif
|
|
|
|
/* compute diffuse and specular lighting */
|
|
vec3 L_diffuse = vec3(0.0);
|
|
#ifndef NO_SPECULAR
|
|
vec3 L_specular = vec3(0.0);
|
|
#endif
|
|
|
|
#ifdef USE_SOLID_LIGHTING
|
|
/* assume 3 directional lights */
|
|
for (int i = 0; i < NUM_SOLID_LIGHTS; i++) {
|
|
vec3 light_direction = gl_LightSource[i].position.xyz;
|
|
|
|
/* diffuse light */
|
|
vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
|
|
float diffuse_bsdf = max(dot(N, light_direction), 0.0);
|
|
L_diffuse += light_diffuse * diffuse_bsdf;
|
|
|
|
#ifndef NO_SPECULAR
|
|
/* specular light */
|
|
vec3 light_specular = gl_LightSource[i].specular.rgb;
|
|
vec3 H = gl_LightSource[i].halfVector.xyz;
|
|
|
|
float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
|
|
L_specular += light_specular * specular_bsdf;
|
|
#endif
|
|
}
|
|
#else
|
|
/* all 8 lights, makes no assumptions, potentially slow */
|
|
|
|
#ifndef NO_SPECULAR
|
|
/* view vector computation, depends on orthographics or perspective */
|
|
vec3 V = (ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position) : vec3(0.0, 0.0, -1.0);
|
|
#endif
|
|
|
|
for (int i = 0; i < NUM_SCENE_LIGHTS; i++) {
|
|
/* todo: this is a slow check for disabled lights */
|
|
if (gl_LightSource[i].specular.a == 0.0)
|
|
continue;
|
|
|
|
float intensity = 1.0;
|
|
vec3 light_direction;
|
|
|
|
if (gl_LightSource[i].position.w == 0.0) {
|
|
/* directional light */
|
|
light_direction = gl_LightSource[i].position.xyz;
|
|
}
|
|
else {
|
|
/* point light */
|
|
vec3 d = gl_LightSource[i].position.xyz - varying_position;
|
|
light_direction = normalize(d);
|
|
|
|
/* spot light cone */
|
|
if (gl_LightSource[i].spotCutoff < 90.0) {
|
|
float cosine = max(dot(light_direction, -gl_LightSource[i].spotDirection), 0.0);
|
|
intensity = pow(cosine, gl_LightSource[i].spotExponent);
|
|
intensity *= step(gl_LightSource[i].spotCosCutoff, cosine);
|
|
}
|
|
|
|
/* falloff */
|
|
float distance = length(d);
|
|
|
|
intensity /= gl_LightSource[i].constantAttenuation +
|
|
gl_LightSource[i].linearAttenuation * distance +
|
|
gl_LightSource[i].quadraticAttenuation * distance * distance;
|
|
}
|
|
|
|
/* diffuse light */
|
|
vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
|
|
float diffuse_bsdf = max(dot(N, light_direction), 0.0);
|
|
L_diffuse += light_diffuse * diffuse_bsdf * intensity;
|
|
|
|
#ifndef NO_SPECULAR
|
|
/* specular light */
|
|
vec3 light_specular = gl_LightSource[i].specular.rgb;
|
|
vec3 H = normalize(light_direction - V);
|
|
|
|
float specular_bsdf = pow(max(dot(N, H), 0.0), gl_FrontMaterial.shininess);
|
|
L_specular += light_specular * specular_bsdf * intensity;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/* compute diffuse color, possibly from texture or vertex colors */
|
|
float alpha;
|
|
|
|
#if defined(USE_TEXTURE) && defined(USE_COLOR)
|
|
vec4 texture_color = texture2D_default(texture_map, varying_texture_coord);
|
|
|
|
L_diffuse *= texture_color.rgb * varying_vertex_color.rgb;
|
|
alpha = texture_color.a * varying_vertex_color.a;
|
|
#elif defined(USE_TEXTURE)
|
|
vec4 texture_color = texture2D_default(texture_map, varying_texture_coord);
|
|
|
|
L_diffuse *= texture_color.rgb;
|
|
alpha = texture_color.a;
|
|
#elif defined(USE_COLOR)
|
|
L_diffuse *= varying_vertex_color.rgb;
|
|
alpha = varying_vertex_color.a;
|
|
#else
|
|
L_diffuse *= gl_FrontMaterial.diffuse.rgb;
|
|
alpha = gl_FrontMaterial.diffuse.a;
|
|
#endif
|
|
|
|
/* sum lighting */
|
|
vec3 L = gl_FrontLightModelProduct.sceneColor.rgb + L_diffuse;
|
|
|
|
#ifndef NO_SPECULAR
|
|
L += L_specular * gl_FrontMaterial.specular.rgb;
|
|
#endif
|
|
|
|
/* write out fragment color */
|
|
gl_FragColor = vec4(L, alpha);
|
|
#else
|
|
|
|
/* no lighting */
|
|
#if defined(USE_TEXTURE) && defined(USE_COLOR)
|
|
gl_FragColor = texture2D_default(texture_map, varying_texture_coord) * varying_vertex_color;
|
|
#elif defined(USE_TEXTURE)
|
|
gl_FragColor = texture2D_default(texture_map, varying_texture_coord);
|
|
#elif defined(USE_COLOR)
|
|
gl_FragColor = varying_vertex_color;
|
|
#else
|
|
gl_FragColor = gl_FrontMaterial.diffuse;
|
|
#endif
|
|
|
|
#endif
|
|
}
|
|
|