123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- #ifndef SKY_MATH_UTILITIES
- #define SKY_MATH_UTILITIES
- // Copyright(c) 2018 Funly LLC
- //
- // Author: Jason Ederle
- // Description: Math utility functions for working with skyboxes.
- // Contact: jason@funly.io
- #include "UnityCG.cginc"
- float rand(float2 co) {
- return frac(sin(dot(co.xy, float2(12.9898, 78.233))) * 43758.5453);
- }
- float AngleBetweenNormalizedVectors(float3 v1, float3 v2) {
- return acos(dot(v1, v2));
- }
- float Atan2Positive(float y, float x) {
- float angle = atan2(y, x);
- // This is the same as: angle = (angle > 0) ? angle : UNITY_PI + (UNITY_PI + angle)
- float isPositive = step(0, angle);
- float posAngle = angle * isPositive;
- float negAngle = (UNITY_PI + (UNITY_PI + angle)) * !isPositive;
- return posAngle + negAngle;
- }
- float2 DirectionToSphericalCoordinate(float3 direction) {
- float3 normDirection = normalize(direction);
- float horizontalRotation = Atan2Positive(normDirection.z, normDirection.x);
- float verticalRotation = 0;
- float angleToUp = AngleBetweenNormalizedVectors(direction, float3(0.0f, 1.0f, 0.0f));
-
- bool angleGreater = step(angleToUp, UNITY_HALF_PI);
- bool angleLesser = !angleGreater;
- float greaterValue = (-1.0f * (angleToUp - UNITY_HALF_PI)) * angleGreater;
- float lesserValue = (UNITY_HALF_PI - angleToUp) * angleLesser;
- verticalRotation = greaterValue + lesserValue;
- // This is the logic for the previous few lines.
- // if (angleToUp <= UNITY_HALF_PI) {
- // verticalRotation = UNITY_HALF_PI - angleToUp;
- // }
- // else {
- // verticalRotation = -1.0f * (angleToUp - UNITY_HALF_PI);
- // }
- return float2(horizontalRotation, verticalRotation);
- }
- float3 SphericalCoordinateToDirection(float2 spherePoint) {
- // Find the y coordinate and radius.
- float x = cos(spherePoint.y);
- float y = sin(spherePoint.y);
- float radius = x;
- float z = 0.0f;
- x = radius * cos(spherePoint.x);
- z = radius * sin(spherePoint.x);
- return normalize(float3(x, y, z));
- }
- inline float2 Rotate2d(float2 p, float angle) {
- return mul(float2x2(cos(angle), -sin(angle),
- sin(angle), cos(angle)),
- p);
- }
- float3 RotateAroundXAxis(float3 p, float angle) {
- float2 rotation = Rotate2d(p.zy, angle);
- return float3(p.x, rotation.y, rotation.x);
- }
- float3 RotateAroundYAxis(float3 p, float angle) {
- float2 rotation = Rotate2d(p.xz, angle);
- return float3(rotation.x, p.y, rotation.y);
- }
- float3 RotatePoint(float3 p, float xAxisRotation, float yAxisRotation) {
- float3 rotated = RotateAroundYAxis(p, yAxisRotation);
- return RotateAroundXAxis(rotated, xAxisRotation);
- }
- float AngleToReachTarget(float2 spot, float targetAngle) {
- float angle = Atan2Positive(spot.y, spot.x);
- return (UNITY_TWO_PI - angle) + targetAngle;
- }
- // Convert a 2D UV percent into spherical rotations.
- float2 ConvertUVToSphericalCoordinate(float2 uv) {
- return float2(
- lerp(0.0f, UNITY_TWO_PI, uv.x),
- lerp(-UNITY_HALF_PI, UNITY_HALF_PI, uv.y));
- }
- // Convert spherical rotations into a 2D UV percent.
- float2 ConvertSphericalCoordateToUV(float2 sphereCoord) {
- return float2(
- sphereCoord.x / UNITY_TWO_PI,
- (sphereCoord.y + UNITY_HALF_PI) / UNITY_PI
- );
- }
- float2 ConvertSphericalCoordinateToPercentage(float2 sphereCoord) {
- return float2(
- sphereCoord.x / UNITY_TWO_PI,
- (sphereCoord.y + UNITY_HALF_PI) / UNITY_PI
- );
- }
- float2 ConvertPercentToSphericalCoordinate(float2 percents) {
- return float2(
- lerp(0, UNITY_TWO_PI, percents.x),
- lerp(-UNITY_HALF_PI, UNITY_HALF_PI, percents.y)
- );
- }
- float2 ConvertPointToPercents(float3 starPoint) {
- float2 sphericalCoord = DirectionToSphericalCoordinate(starPoint);
- return ConvertSphericalCoordinateToPercentage(sphericalCoord);
- }
- float3 ConvertPercentToPoint(float2 percents) {
- float2 sphericalCoord = ConvertPercentToSphericalCoordinate(percents);
- return SphericalCoordinateToDirection(sphericalCoord);
- }
- bool IsSamePoint(float3 p1, float3 p2) {
- float xDelta = p1.x - p2.x;
- float yDelta = p1.y - p2.y;
- float zDelta = p1.z - p2.z;
- float nearZero = .01f;
- return xDelta < nearZero && yDelta < nearZero && zDelta < nearZero;
- }
- float2 GetPixelCeneteredUV(float2 uv, int imageSize) {
- float cellSize = 1.0f / (float)imageSize;
- float halfCellSize = cellSize / 2.0f;
- int xUnits = uv.x / cellSize;
- int yUnits = uv.y / cellSize;
- return float2(xUnits * cellSize + halfCellSize,
- yUnits * cellSize + halfCellSize);
- }
- #endif
|