67 lines
2.2 KiB
GLSL
67 lines
2.2 KiB
GLSL
/*
|
|
Copyright (C) 2021 hiimgoodpack
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
#version 330 core
|
|
|
|
in vec2 vFragCoord;
|
|
in vec2 vTexCoord;
|
|
uniform sampler2D aTexture;
|
|
uniform float aHorizontalOffset;
|
|
|
|
// Set to 1 or -1 to flip Y
|
|
uniform float aTexCoordYScale;
|
|
|
|
// Adds the Z value to a vec2, calculating it assuming
|
|
// it's a sphere with a radius of 2
|
|
vec3 getZInSphere(vec2 v) {
|
|
const float radius = 2;
|
|
return vec3(v, sqrt(radius-dot(v,v)));
|
|
}
|
|
|
|
void main() {
|
|
float distanceFromCenterSquared = dot(vFragCoord, vFragCoord);
|
|
|
|
// alpha = 0 if fragment is outside circle
|
|
// alpha = 1 if fragment is inside circle
|
|
float alpha = distanceFromCenterSquared > 1 ? 0 : 1;
|
|
|
|
vec3 normal;
|
|
{
|
|
// Form a triangle to approximate the normal or something like that
|
|
const float offset = 0.001;
|
|
vec3 p0 = getZInSphere(vFragCoord + vec2(0, offset));
|
|
vec3 p1 = getZInSphere(vFragCoord + vec2(offset, -offset));
|
|
vec3 p2 = getZInSphere(vFragCoord + vec2(-offset, -offset));
|
|
|
|
// Now calculate the normal of the triangle
|
|
vec3 a = p0 - p1;
|
|
vec3 b = p2 - p1;
|
|
normal = normalize(cross(a, b));
|
|
}
|
|
|
|
const float pi = radians(180);
|
|
// Based off of https://stackoverflow.com/questions/41957890/how-to-properly-map-a-2d-image-texture-to-an-icosphere
|
|
vec2 texCoord = vec2(
|
|
atan(normal.x, normal.z) * (1.0f/pi),
|
|
asin(-normal.y) * (2.0f/pi) * aTexCoordYScale
|
|
) + vec2(0.5f+aHorizontalOffset, 0.5f);
|
|
|
|
// Some equation which seems to work good enough
|
|
float specular = (dot(normal, normalize(vec3(-1, 2, 0.5f))) - 0.25f) * 1.3f + 0.1f;
|
|
specular = specular*specular * sign(specular);
|
|
|
|
gl_FragColor = vec4(texture(aTexture, texCoord).rgb + (vec3(1,1,1) * specular), alpha);
|
|
}
|