/* 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 . */ #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); }