Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 110
- #define PI 3.141592653589793238462643383279
- //the six input textures
- uniform sampler2D frontTex;
- uniform sampler2D backTex;
- uniform sampler2D leftTex;
- uniform sampler2D rightTex;
- uniform sampler2D bottomTex;
- uniform sampler2D topTex;
- //whether or not to flip the image
- uniform int flip;
- //the amount of yaw and pitch correction to apply (in radians)
- uniform float yawCorrection;
- uniform float pitchCorrection;
- uniform float rollCorrection;
- //a plane in vector notation
- struct CubeFace {
- vec3 point; //a point on the plane
- vec3 norm; //the plane's normal vector
- vec3 corner00; //the corner that corresponds to texture position (0|0)
- vec3 corner01; //the corner that corresponds to texture position (0|1)
- vec3 corner10; //the corner that corresponds to texture position (1|0)
- } pTop, pBottom, pLeft, pRight, pFront, pBack;
- struct Line {
- vec3 point; //a point on the line
- vec3 dir; //the vector
- } lineH, lineV;
- //Rotates a cartesian vector around the X-, Y- and Z-axis.
- void rotateVector(inout vec3 vector, float rotX, float rotY, float rotZ) {
- //using a rotation matrix to calculate the new vector
- //rotate around the X-axis
- vector.x = vector.x;
- vector.y = vector.y * cos(rotX) - vector.z * sin(rotX);
- vector.z = vector.y * sin(rotX) + vector.z * cos(rotX);
- //rotate around the Y-axis
- vector.x = vector.x * cos(rotY) + vector.z * sin(rotY);
- vector.y = vector.y;
- vector.z = -vector.x * sin(rotY) + vector.z * cos(rotY);
- //rotate around the Z-axis
- vector.x = vector.x * cos(rotZ) - vector.y * sin(rotZ);
- vector.y = vector.x * sin(rotZ) + vector.y * cos(rotZ);
- vector.z = vector.z;
- }
- //calculates the four corner points of the cube face
- void calculateCorners(inout CubeFace plane,
- CubeFace faceLeft, CubeFace faceRight,
- CubeFace faceAbove, CubeFace faceBelow) {
- plane.corner00 = plane.point + faceLeft.point + faceAbove.point;
- plane.corner01 = plane.point + faceLeft.point + faceBelow.point;
- plane.corner10 = plane.point + faceRight.point + faceBelow.point;
- }
- //calculate the distance from the center to the point where
- //the view ray crosses a plane.
- // d = ((p0-l0) * n) / (l * n)
- float distance(vec3 ray, CubeFace plane) {
- //check if the plane is parallel to the ray
- if(dot(ray, plane.norm) == 0.0) {
- //as the plane can never cross the center
- //we simply return 0.0 to mark that this plane isn't the correct one.
- return 0.0;
- } else {
- float d = dot(plane.point, plane.norm) / dot(ray, plane.norm);
- return d;
- }
- }
- //calculate the distance from a point to a line.
- float distance(vec3 point, Line line) {
- return length((line.point - point) * line.dir) / length(line.dir);
- }
- //calculates the uv coordinates on the cube face where the ray intersects with the plane.
- //values not within the range of 0, 1 are outside of the cube face.
- vec2 intersection(vec3 ray, CubeFace plane) {
- //first, calculate the distance from the center to the intersection point
- float d = distance(ray, plane);
- //only intersections in the positive direction of the ray are handled
- if(d > 0.0) {
- //calculate the actual point in cartesian space
- vec3 intersection = d * ray;
- //translate the point in cartesian space to uv coordinates on the cube face
- //calculate the x position by calculating the distance from the intersection
- //to the cube faces y axis
- //constructing the y axis
- lineV.point = plane.corner00;
- lineV.dir = plane.corner01 - plane.corner00;
- //calculating the distance from the intersection to the line
- float u = distance(intersection, lineV);
- //constructing the x axis
- lineH.point = plane.corner00;
- lineH.dir = plane.corner10 - plane.corner00;
- float v = distance(intersection, lineH);
- return vec2(u, v);
- } else {
- //return invalid uv values
- return vec2(-1.0, -1.0);
- }
- }
- bool isPointOnCube(vec2 uv) {
- return uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0;
- }
- void main() {
- //normalized texture coordinates (from 0 to 1)
- float u = gl_TexCoord[0].x;
- float v = gl_TexCoord[0].y;
- //vertically flip the image if needed
- if(flip == 1) {
- v = 1.0 - gl_TexCoord[0].y;
- }
- //convert the texture coordinates to polar coordinates
- //which still resolve to points on the 2d face
- float phi = u * 2.0 * PI;
- float theta = v * PI;
- //calculate an unit vector in an cartesian coordinate system
- //that points from the center of a hypothetical sphere to the point on the sphere
- //that is mapped to the current pixel's location on the 2d face (the ray)
- float x = sin(phi) * sin(theta) * -1.0;
- float y = cos(theta);
- float z = cos(phi) * sin(theta) * -1.0;
- vec3 ray = vec3(x, y, z);
- //construct six planes representing the rotated cube with the six textures
- //create six vectors pointing towards the faces of the cube
- vec3 rightVec = vec3(1.0, 0.0, 0.0);
- vec3 leftVec = vec3(-1.0, 0.0, 0.0);
- vec3 topVec = vec3(0.0, 1.0, 0.0);
- vec3 bottomVec = vec3(0.0, -1.0, 0.0);
- vec3 frontVec = vec3(0.0, 0.0, 1.0);
- vec3 backVec = vec3(0.0, 0.0, -1.0);
- //rotate the vectors according to pitch, yaw and roll correction
- rotateVector(rightVec, -pitchCorrection, -yawCorrection, -rollCorrection);
- rotateVector(leftVec, -pitchCorrection, -yawCorrection, -rollCorrection);
- rotateVector(topVec, -pitchCorrection, -yawCorrection, -rollCorrection);
- rotateVector(bottomVec, -pitchCorrection, -yawCorrection, -rollCorrection);
- rotateVector(frontVec, -pitchCorrection, -yawCorrection, -rollCorrection);
- rotateVector(backVec, -pitchCorrection, -yawCorrection, -rollCorrection);
- //as the cube is 1*1*1 large, the distance to each of the planes is 0.5
- pRight.point = rightVec * 0.5;
- pRight.norm = rightVec;
- pLeft.point = leftVec * 0.5;
- pLeft.norm = leftVec;
- pTop.point = topVec * 0.5;
- pTop.norm = topVec;
- pBottom.point = bottomVec * 0.5;
- pBottom.norm = bottomVec;
- pFront.point = frontVec * 0.5;
- pFront.norm = frontVec;
- pBack.point = backVec * 0.5;
- pBack.norm = backVec;
- //calculate the corner points of the cube faces
- calculateCorners(pRight, pFront, pBack, pTop, pBottom);
- calculateCorners(pLeft, pBack, pFront, pTop, pBottom);
- calculateCorners(pTop, pLeft, pRight, pFront, pBack);
- calculateCorners(pBottom, pRight, pLeft, pFront, pBack);
- calculateCorners(pFront, pLeft, pRight, pTop, pBottom);
- calculateCorners(pBack, pRight, pLeft, pTop, pBottom);
- vec2 texPos;
- if(isPointOnCube(texPos = intersection(ray, pRight))) {
- gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
- } else if(isPointOnCube(texPos = intersection(ray, pLeft))) {
- gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
- } else if(isPointOnCube(texPos = intersection(ray, pTop))) {
- gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
- } else if(isPointOnCube(texPos = intersection(ray, pBottom))) {
- gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
- } else if(isPointOnCube(texPos = intersection(ray, pFront))) {
- gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
- } else if(isPointOnCube(texPos = intersection(ray, pBack))) {
- gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment