60 lines
1.9 KiB
GLSL
60 lines
1.9 KiB
GLSL
#version 330 core
|
|
#define PI 3.1415926535897932384626433832795
|
|
#define TWO_PI 6.283185307179586476925286766559
|
|
|
|
// inputs from vertex shader, different for each fragment
|
|
in vec3 objectPosition;
|
|
in vec3 viewPosition;
|
|
in vec3 viewNormal;
|
|
|
|
// uniform variables, same for all fragments
|
|
uniform sampler2D colorTexture;
|
|
|
|
// outputs of the fragment shader, i.e., shaded pixels
|
|
out vec4 color;
|
|
|
|
// convert a cartesian unit normal vector to spherical coordinates
|
|
vec2 toSphereCoordinate(vec3 normal)
|
|
{
|
|
return vec2(atan(normal.y, normal.x) / TWO_PI, 1 - acos(normal.z) / PI);
|
|
}
|
|
|
|
// compute the screen space derivative in x of a cartesian unit normal vector converted to spherical coordinates
|
|
vec2 toSphereCoordinateGradX(vec3 n)
|
|
{
|
|
// screen space derivative in x
|
|
vec3 ndx = dFdx(n);
|
|
|
|
float xy2 = dot(n.xy, n.xy);
|
|
if(xy2 < 1e-6)
|
|
return vec2(0.0, 0.0);
|
|
return vec2((n.x * ndx.y - n.y * ndx.x) / xy2 / TWO_PI, ndx.z / sqrt(1.0 - n.z * n.z) / PI);
|
|
}
|
|
|
|
// compute the screen space derivative in y of a cartesian unit normal vector converted to spherical coordinates
|
|
vec2 toSphereCoordinateGradY(vec3 n)
|
|
{
|
|
// screen space derivative in y
|
|
vec3 ndx = dFdy(n);
|
|
|
|
float xy2 = dot(n.xy, n.xy);
|
|
if(xy2 < 1e-6)
|
|
return vec2(0.0, 0.0);
|
|
return vec2((n.x * ndx.y - n.y * ndx.x) / xy2 / TWO_PI, ndx.z / sqrt(1.0 - n.z * n.z) / PI);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
// get surface reflectance (albedo) from texture in spherical coordinates
|
|
vec3 objectNormal = clamp(normalize(objectPosition), -1.0, 1.0);
|
|
vec3 albedo = textureGrad(colorTexture, toSphereCoordinate(objectNormal), toSphereCoordinateGradX(objectNormal), toSphereCoordinateGradY(objectNormal)).rgb;
|
|
|
|
// compute simple lambert lighting with light at camera position and no distance-based falloff
|
|
vec3 n = normalize(viewNormal);
|
|
vec3 l = -normalize(viewPosition);
|
|
vec3 lit = albedo * vec3(max(dot(n, l), 0.0));
|
|
|
|
// write output color
|
|
color = vec4(lit, 1.0);
|
|
}
|