# Question
Title: Intersection of a Line Segment and a Rectangle
I have to calculate the intersection of a line segment (represented by 2 points) with a rectangle.

For example:

**Axis aligned rectangle corners:** (0, 0) (100, 100)

**Point 1:** (50, 50)

**Point 2:** (50, 150)

**Expected result:** (50, 100)

What would be the way to find the intersection of the line segment with the rectangle?

# Answer
> 6 votes
As you will easily find out, the most straight-forward solution is to run multiple times an algorithm that checks whether there is an intersection between the segment formed by Point1 and Point2 (let's call them p1 and p2) and the ones formed by each of the vertices of the rectangle (let's call them r1, r2, r3 and r4).

A clean implementation line-seg/line-seg intersection in C# (which can easily be converted to JavaScript, which I think is closer to what you need) is the following:

```
Vector2? LSegsIntersectionPoint(Vector2 ps1, Vector2 pe1, Vector2 ps2, Vector2 pe2)
{
    // Get A,B of first line - points : ps1 to pe1
    float A1 = pe1.y-ps1.y;
    float B1 = ps1.x-pe1.x;
    // Get A,B of second line - points : ps2 to pe2
    float A2 = pe2.y-ps2.y;
    float B2 = ps2.x-pe2.x;

    // Get delta and check if the lines are parallel
    float delta = A1*B2 - A2*B1;
    if(delta == 0) return null;

    // Get C of first and second lines
    float C2 = A2*ps2.x+B2*ps2.y;
    float C1 = A1*ps1.x+B1*ps1.y;
    //invert delta to make division cheaper
    float invdelta = 1/delta;
    // now return the Vector2 intersection point
    return new Vector2( (B2*C1 - B1*C2)*invdelta, (A1*C2 - A2*C1)*invdelta );
}

```

Now, considering that you have mentioned to me in the comments of your question that p1 is always inside the rectangle, you will never have more than one intersection between the segment formed by p1 and p2, and the rectangle. So, you just have to repeat the above code for each sides of the rectangle with:

```
Vector2? LSegRec_IntersPoint_v01(Vector2 p1, Vector2 p2, Vector2 r1, Vector2 r2, Vector2 r3, Vector2 r4)
{
    Vector2? intersection = null;
    intersection = LSegsIntersectionPoint(p1,p2,r1,r2);
    if(intersection == null) intersection = LSegsIntersectionPoint(p1,p2,r2,r3);
    if(intersection == null) intersection = LSegsIntersectionPoint(p1,p2,r3,r4);
    if(intersection == null) intersection = LSegsIntersectionPoint(p1,p2,r4,r1);
    return intersection;
}

```

I don't know if you plan to perform such checking hundreds of thousands of times, or if performance even is an issue for you. Anyways, for completeness (and for fun), notice that you also have said in your question that your rectangle is axis aligned. This information, summed to the fact that p1 is always inside the rectangle, can raise a much faster solution. Not necessarily easier to code (sorry for calling it "easier"), but much more efficient in case you have a lot of segment-rectangle checks to make. The trick here is the following. You first calculate the min\_x, min\_y, max\_x and max\_y of your rectangle. Then, you can use the following function to first check where p2 is in relation to the rectangle and then just do the line-seg checks if the precise sides of the rectangle (never having to check more than 2, while in the worst case the first solution had to check all 4):

```
Vector2? LSegRec_IntersPoint_v02(Vector2 p1, Vector2 p2, float min_x, float min_y, float max_x, float max_y)
{
    Vector2? intersection;

    if (p2.x < min_x) //If the second point of the segment is at left/bottom-left/top-left of the AABB
    {
        if (p2.y > min_y && p2.y < max_y) { return LSegsIntersectionPoint(p1, p2, new Vector2(min_x, min_y), new Vector2(min_x, max_y)); } //If it is at the left
        else if (p2.y < min_y) //If it is at the bottom-left
        {
            intersection = LSegsIntersectionPoint(p1, p2, new Vector2(min_x, min_y), new Vector2(max_x, min_y));
            if (intersection == null) intersection = LSegsIntersectionPoint(p1, p2, new Vector2(min_x, min_y), new Vector2(min_x, max_y));
            return intersection;
        }
        else //if p2.y > max_y, i.e. if it is at the top-left
        {
            intersection = LSegsIntersectionPoint(p1, p2, new Vector2(min_x, max_y), new Vector2(max_x, max_y));
            if (intersection == null) intersection = LSegsIntersectionPoint(p1, p2, new Vector2(min_x, min_y), new Vector2(min_x, max_y));
            return intersection;
        }
    }

    else if (p2.x > max_x) //If the second point of the segment is at right/bottom-right/top-right of the AABB
    {
        if (p2.y > min_y && p2.y < max_y) { return LSegsIntersectionPoint(p1, p2, new Vector2(max_x, min_y), new Vector2(max_x, max_y)); } //If it is at the right
        else if (p2.y < min_y) //If it is at the bottom-right
        {
            intersection = LSegsIntersectionPoint(p1, p2, new Vector2(min_x, min_y), new Vector2(max_x, min_y));
            if (intersection == null) intersection = LSegsIntersectionPoint(p1, p2, new Vector2(max_x, min_y), new Vector2(max_x, max_y));
            return intersection;
        }
        else //if p2.y > max_y, i.e. if it is at the top-left
        {
            intersection = LSegsIntersectionPoint(p1, p2, new Vector2(min_x, max_y), new Vector2(max_x, max_y));
            if (intersection == null) intersection = LSegsIntersectionPoint(p1, p2, new Vector2(max_x, min_y), new Vector2(max_x, max_y));
            return intersection;
        }
    }

    else //If the second point of the segment is at top/bottom of the AABB
    {
        if (p2.y < min_y) return LSegsIntersectionPoint(p1, p2, new Vector2(min_x, min_y), new Vector2(max_x, min_y)); //If it is at the bottom
        if (p2.y > max_y) return LSegsIntersectionPoint(p1, p2, new Vector2(min_x, max_y), new Vector2(max_x, max_y)); //If it is at the top
    }

    return null;

}

```

But notice: that second solution is only faster if you can calculate the min\_x, min\_y, max\_x and max\_y of your rectangle beforehand. Otherwise, you will have to calculate those inside the function and that will make it slower. Let's say you use the exact same code as the second solution, but just doing that calculation of mins and maxs of the rectangle within the function:

```
Vector2? LSegRec_IntersPoint_v03(Vector2 p1, Vector2 p2, Vector2 r1, Vector2 r2, Vector2 r3, Vector2 r4)
{
    Vector2? intersection;
    float min_x = Mathf.Min(r1.x, r2.x, r3.x, r4.x);
    float min_y = Mathf.Min(r1.y, r2.y, r3.y, r4.y);
    float max_x = Mathf.Max(r1.x, r2.x, r3.x, r4.x);
    float max_y = Mathf.Max(r1.y, r2.y, r3.y, r4.y);

... then the rest of the the second version continues here

```

In order to profile that, I created a rectangle where r1 = (-2,-2), r2 = (2,-2), r3 = (2,2) and r4 = (-2,2), p1 = (0,0) and then randomly positioned p2 a bunch of times, always have its X and Y coordinates between -4 and 4. Here are the results, where N is the number of iterations of the simulation:

Notice that, as expected, version 2 is generally much faster to run. The only exception is for N\<=1000, when it is roughly the same thing. For greater number of iterations, however, it becomes much faster. But as I've pointed, that's only the case if the mins and maxs of the rectangle are calculated beforehand, because if they have to be calculated within the function (i.e. v03), then it becomes much slower.

# Answer
> 1 votes
One easy approach is: check intersection with each rectangle line.

Here follow my lua code for that (Line line intersection)

```
function getVec2(x_,y_)
    vec2={}
    vec2.x=x_
    vec2.y=y_

    function vec2:dist() --set relative position
        return math.sqrt(vec2.x*vec2.x + vec2.y*vec2.y)
    end

    function vec2:sqrdist() --set relative position
        return vec2.x*vec2.x + vec2.y*vec2.y
    end

    function vec2.mulf(v,f  )
        return getVec2(v.x*f , v.y*f)
    end

    function vec2.minus(v1 ,v2  )
        return getVec2(v1.x-v2.x , v1.y-v2.y)
    end

    --cross product v × w to be vx wy − vy wx
    function vec2.cross(v1,v2  )
        return v1.x*v2.y - v1.y*v2.x
    end
    function vec2.dot(v1,v2  )
        return v1.x*v2.x + v1.y*v2.y
    end
    function vec2.add(v1,v2  )
        return getVec2(v1.x+v2.x , v1.y+v2.y)
    end

    function vec2.normalize(v1)
        local d = v1:dist()
        if d> 0 then
            return getVec2(v1.x/d,v1.y/d)
        else
            return getVec2(0,0)
        end
    end

    function vec2.normal(v1)
        return getVec2(-v1.y ,v1.x)
    end

    function vec2.left(v1)
        return getVec2(-v1.y ,v1.x)
    end

    function vec2.right(v1)
        return getVec2(v1.y ,-v1.x)
    end
    return vec2
end
function findIntersect(l1p1x,l1p1y, l1p2x,l1p2y, l2p1x,l2p1y, l2p2x,l2p2y)
    local p = getVec2(l1p1x,l1p1y)
    local p1 = getVec2(l1p2x,l1p2y)
    local q = getVec2(l2p1x,l2p1y)
    local q1 = getVec2(l2p2x,l2p2y)

    return  vec2findIntersect(p,p1,q,q1)

end

function vec2findIntersect(p,p1,q,q1)
--https://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect

    local r = vec2.minus(p1 ,p  )
    local s = vec2.minus(q1 ,q  )

    --t = (q − p) × s / (r × s)
    --u = (q − p) × r / (r × s)

    local q_p = vec2.minus(q,p)
    local q_pdots = vec2.cross(q_p,s)
    local q_pdotr = vec2.cross(q_p,r)
    local rdots = vec2.cross(r,s)

    --If r × s = 0
    if rdots == 0 then
        return false,false,nil
    end

    local t = q_pdots / rdots
    local u = q_pdotr / rdots

    --if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1, the two line segments meet at the point p + t r = q + u s.
    if ((t>= 0 ) and (t<=1) and (u>= 0 ) and (u<= 1 )) then
        --p + t  *r
        local ret = vec2.mulf(r,t)
        ret = vec2.add(p,ret  )
        return ret.x,ret.y,ret
    end
    return false,false,nil
end

```

# Answer
> 1 votes
Technically, you have a line expressed as a series of points. Then, you express the rectangle as **bounded constraints**. Then you would create sub-lines from the original lines by the bounded constraints. Depending on **your own algorithm**, this may have different effects, but this is the general idea.

# Answer
> 1 votes
You can use the **Line-Line** intersection formula, Line-line intersection.

If you consider a class `Line` class that is made up of two `Vector2`s you can calculate, using the above formula, the intersection between them.

```
class Line {
    public Vector2 a;
    public Vector2 b;

    public Line(Vector2 a, Vector2 b) {
        this.a = a;
        this.b = b;
    }

    Vector2 findIntersection(Line a, Line b)
        float x1 = a.a.x;
        float y1 = a.a.y;
        float x2 = a.b.x;
        float y2 = a.b.y;

        float x3 = b.a.x;
        float y3 = b.a.y;
        float x4 = b.b.x;
        float y4 = b.b.y;

        float denominator = (x1 - x2)*(y3 - y4) - (y1 - y2)*(x3 - x4);
        if (denominator == 0)
            return null;

        float xNominator = (x1*y2 - y1*x2)*(x3 - x4) - (x1 - x2)*(x3*y4 - y3*x4);
        float yNominator = (x1*y2 - y1*x2)*(y3 - y4) - (y1 - y2)*(x3*y4 - y3*x4);

        float px = xNominator / denominator;
        float py = yNominator / denominator;

        return new Vector2D(px, py);
    }
}

```

The above maps onto the function on wikipedia where you've got two points on a line (Given two points on each line).

Then it's a matter of turning the rectangle into `Line` which is of course done by taking the different corners as the points on the line and call the above method for each line and corner-to-corner line. Somewhat ugly that can be solved like this;

```
Vector2 findIntersection(Line a, Vector2 c0, Vector2 c1, Vector2 c2, Vector2 c3) {
    Line l0 = new Line(c0, c1);
    Line l1 = new Line(c1, c2);
    Line l2 = new Line(c2, c3);
    Line l3 = new Line(c3, c0);

    Vector2 intersection = null;

    intersection = findIntersection(a, l0);
    if (intersection != null) return intersection;

    intersection = findIntersection(a, l1);
    if (intersection != null) return intersection;

    intersection = findIntersection(a, l2);
    if (intersection != null) return intersection;

    intersection = findIntersection(a, l3);
    if (intersection != null) return intersection;

    return null;

}

```

An important thing to point out here is that the formula will give you an intersection even if that intersection isn't *between* `a` and `b`, so you likely will want to constrain the results to results that fall within that range (one way to do that would be to do an bounds-inclusive contains on the source rectangle).

# Answer
> 0 votes
**The Abstract-Is-Better way**

Below we talk about \\$n\\$-dimensional space. I'll use "\\$n\\$-dimensional hyper-xyz" to denote something that would be called xyz in 3 dimensions. For example, a 2-dimensional hyper-block is a rectangle, etc).

Say you want to divide an \\$n\\$-dimensional hyper-block with a \\$n-1\\$ dimensional hyper-plane. The hyper-plane has a normal unit vector \\$N\\$ and its points \\$X\\$ satisfy:

$$N\cdot X + d = 0$$

where \\$N\cdot X\\$ is a scalar: the dot product of the vectors \\$N\\$ and \\$X\\$, and \\$d\\$ is a scalar giving the distance from the origin to the hyper-plane in units of \\$N\\$: if \\$d\\$ is negative then the hyper-plane just lays in the direction of \\$-N\\$ from the origin.

The \\$n\\$-dimensional hyper-block can be thought of as being spanned by a set of \\$n\\$ orthogonal "base vectors" \\$B=(v\_0, v\_1, v\_2, ...)\\$ and has \\$2n\\$ hyper-planes as borders and \\$2^n\\$ corners. Let's denote these corners with an \\$n\\$-dimensional boolean vector (aka, \\$C=(0,0,1,1,0,1,...)\\$) where the \\$i\\$th boolean gives us whether that corner is a part of the lower or higher hyper-plane that is perpendicular to the \\$i\\$th base vector \\$v\_i\\$.

Note the exact coordinates of corner \\$C\\$ is now given by \\$B\cdot C\\$, aka corner \\$(0,0,0...)\\$ is given by \\$O + O + O + ... = O\\$ (where \\$O\\$ is the origin) and \\$(1,1,1,...)\\$ is given by \\$v0 + v1 + v2 + ....\\$

We have to run over all corners and see on which side of the hyper-plane they are on; that is, if the distance from the corner to the hyper-plane requires adding or subtracting (a fraction of) \\$N\\$.

We can determine this distance \\$k\\$ by solving the line equation for \\$B\cdot C + kN\\$ (aka, how many times do we have to add the normal \\$N\\$ to the corner to reach the hyper-plane?):

$$N\cdot(B\cdot C + kN) + d = 0$$

and since \\$N\\$ is a unit vector \\$N\cdot kN = k N\cdot N = k * 1 = k\\$, therefore:

$$k = - N\cdot (B\cdot C) - d$$

If this \\$k\\$ is negative then this Corner is on one side, if \\$k\\$ is positive is it on the other side and if \\$k=0\\$ then the hyper-plane goes through that corner and it doesn't matter which side you pick, so let's say:

$$ \begin{align} k' &= 0 \text{ if } k \<= 0 \text{ and}\\ k' &= 1 \text{ if } k \> 0 \end{align} $$

and we have as many \\$k'\\$ values as corners (one for each \\$C\\$): \\$2^n\\$ of them. You can draw a line between any two corner points that only differ in one bit of \\$C\\$: \\$n\\$ edges from every corner, where then you count every edge twice; so there are \\$2^n \frac{n}{2} = 2^{n-1} n\\$ edges. However, you can also just run over all corners and then only toggle a single 1 (if there is one) to a 0 (for each 1 that that corner has); if the corresponding \\$k'\\$ changes value then the corresponding edge is cut by your hyper-plane and you can calculate the intersection point.

Let's apply the above to an axis aligned rectangle (where one corner is the origin); in that case:

\\$B = \[(100,0), (0,100)\]\\$

Having two points on the line: \\$P\_1 = (x\_1,y\_1)=(50,50)\\$ and \\$P\_2 = (x\_2,y\_2)=(50,150)\\$, the line goes -say- from \\$P\_1\\$ to \\$P\_2\\$: \\$P\_2-P\_1 = (x\_2 - x\_1, y\_2 - y\_1)\\$ and the normal to that line \\$N = (-(y\_2 - y\_1), x\_2 - x\_1)\\$. And the distance to the origin is for example \\$d = -N\cdot P\_1\\$. Working that out we get:

$$ \begin{align} N &= (-(150 - 50), 50 - 50) = (-100, 0) = (-1, 0) \textit{ (normalized to length 1)} \\ d &= -(-1\*50 + 0\*50) = 50 \end{align} $$

Assuming \\$B\\$ is column vector, let's make \\$C\\$ a matrix that includes all corners at once:

$$C = \[(0,0),(1,0),(0,1),(1,1)\]$$

where the first element of each column vector tells us if \\$b\_0\\$ participates and the second element if \\$b\_1\\$ does.

That makes

$$B\cdot C = \[(0,0), (100,0), (0,100), (100,100)\]$$

the four corners. And the corresponding \\$k\\$ values:

$$K = -N\cdot (B\cdot C) - d = \[-50,50,-50,50\]$$

which gives us sign changes for (100,0)-\>(0,0) and (100,100)-\>(0,100).

Hence the line cuts the bottom edge and the top edge respectively.

To calculate where, just parameterize the edge using the two corners that made the sign of \\$k\\$ change - say \\$C\_1\\$ and \\$C\_2\\$ (e.g. (100,0) and (0,0)):

Edge: \\$C\_1 + g(C\_2 - C\_1)\\$

and fill that in in the line equation:

$$N\cdot (C\_1 + g(C\_2 - C\_1)) + d = 0$$

to find \\$g\\$:

$$g = -\frac{N\cdot C\_1 + d}{N\cdot (C\_2 - C\_1)}$$

The intersection point then is \\$C\_1 + g(C\_2 - C\_1)\\$.

For example, with \\$C\_1=(100,0)\\$ and \\$C\_2=(0,0)\\$: $$ \begin{align} g &= -\frac{(-1,0)\cdot (100,0) + 50}{(-1,0)\cdot ((0,0)-(100,0))} \\ &= -\frac{-100 + 50}{(-1,0)\cdot (-100,0)} \\ &= \frac{50}{100} \\ &= \frac{1}{2} \\ \end{align} $$ And thus the intersection is at (100,0) + 1/2(-100,0) = (50,0). While for \\$C\_1=(100,100)\\$ and \\$C\_2=(0,100)\\$ we get (50,100).

PS If \\$N\cdot (C\_2 - C\_1) = 0\\$ we can't devide through it; this means that the hyper-plane goes through both corners and intersects the edge everywhere. In that case one should have picked the other possibility for when \\$k=0\\$ for at least one of the corners.

I wrote an implementation:

```
#include <array>
#include <vector>
#include <concepts>
#include <stdexcept>
#include <iostream>

namespace intersections {

// An n-dimensional vector (a column vector with n elements).
template<std::floating_point FloatType, int n>
struct Vector
{
  std::array<FloatType, n> v_;                          // The elements of the vector.

  // Construct a zeroed vector.
  Vector() : v_{} { }

  // Initialize this Vector from an initializer list.
  Vector(std::initializer_list<FloatType> v)
  {
    if (v.size() != n)
      throw std::invalid_argument("Initializer list must have exactly n elements.");
    std::copy(v.begin(), v.end(), v_.begin());
  }

  // Element access.
  FloatType& operator[](int i) { return v_[i]; }
  FloatType operator[](int i) const { return v_[i]; }

  // Add v2.
  Vector& operator+=(Vector const& v2)
  {
    for (int i = 0; i < n; ++i)
      v_[i] += v2[i];
    return *this;
  }

  // Add v1 and v2.
  friend Vector operator+(Vector const& v1, Vector const& v2)
  {
    Vector result(v1);
    result += v2;
    return result;
  }

  // Subtract v2.
  Vector& operator-=(Vector const& v2)
  {
    for (int i = 0; i < n; ++i)
      v_[i] -= v2[i];
    return *this;
  }

  // Subtract v2 from v1.
  friend Vector operator-(Vector const& v1, Vector const& v2)
  {
    Vector result(v1);
    result -= v2;
    return result;
  }

  // Return the dot product of v1 and v2.
  friend FloatType operator*(Vector const& v1, Vector const& v2)
  {
    FloatType result = 0;
    for (int i = 0; i < n; ++i)
      result += v1[i] * v2[i];
    return result;
  }

  // Elementwise multiply with scalar g.
  friend Vector operator*(FloatType g, Vector const& v)
  {
    Vector result(v);
    for (int i = 0; i < n; ++i)
      result[i] *= g;
    return result;
  }

  // For debugging purposes.
  void print_on(std::ostream& os) const
  {
    char const* sep = "";
    os << '(';
    for (int i = 0; i < n; ++i)
    {
      os << sep << v_[i];
      sep = ", ";
    }
    os << ')';
  }

  friend std::ostream& operator<<(std::ostream& os, Vector const& v)
  {
    v.print_on(os);
    return os;
  }
};

// An n-1 dimensional hyper-plane, orthogonal to a given normal unit vector N, with offset dN from the origin.
template<std::floating_point FloatType, int n>
struct HyperPlane
{
  using VectorType = Vector<FloatType, n>;

  VectorType N_;                                        // The unit normal of the hyper-plane.
  FloatType d_;                                         // The signed distance (in Normal vectors) from origin to hyper-plane.

  // Create a hyper-plane that satisfies N·X + d = 0.
  HyperPlane(VectorType const& N, FloatType d) : N_(N), d_(d) { }

  // Return the number of N_'s that have to be added to P to end up on this HyperPlane.
  // The sign tells you which "side" of the hyper-plane the point is on.
  FloatType distance(VectorType const& P) const
  {
    FloatType dist = -(N_ * P + d_);
    return dist;
  }

  // Return intersection of the line through C1 and C2 with this HyperPlane.
  VectorType intersection(VectorType const& C1, VectorType const& C2) const
  {
    // Let E be a line through C1 and C2: E: C1 + g(C2 - C1), where g parameterizes the points on E.
    // Fill that in in the line equation to find the intersection:
    // N·(C1 + g(C2 - C1)) + d = 0 --> N·C1 + d + g N·(C2 - C1) = 0 --> g = -(N·C1 + d) / N·(C2 - C1)
    VectorType diff = C2 - C1;
    FloatType g = -(N_ * C1 + d_) / (N_ * diff);
    return C1 + g * diff;
  }
};

template<std::floating_point FloatType, int n>
struct HyperBlock
{
  using VectorType = Vector<FloatType, n>;
  static constexpr int number_of_corners = 1 << n;

  std::array<VectorType, number_of_corners> C_;         // The 2^n corners of the hyper-block.

  // Construct an axis-aligned hyper-block from two adjecent corner vectors.
  HyperBlock(VectorType const& c1, VectorType const& c2)
  {
    VectorType base = c2 - c1;
    for (int ci = 0; ci < number_of_corners; ++ci)
    {
      VectorType c;
      for (int d = 0; d < n; ++d)
      {
        int bit = 1 << d;
        if ((ci & bit))
          c[d] += base[d];
      }
      C_[ci] = c1 + c;
    }
  }

  std::vector<VectorType> intersection_points(HyperPlane<FloatType, n> const& plane);
};

template<std::floating_point FloatType, int n>
std::vector<typename HyperBlock<FloatType, n>::VectorType> HyperBlock<FloatType, n>::intersection_points(HyperPlane<FloatType, n> const& plane)
{
  std::vector<VectorType> intersections;

  std::array<bool, number_of_corners> side;
  for (int ci = 0; ci < number_of_corners; ++ci)
    side[ci] = plane.distance(C_[ci]) <= 0;

  for (int ci = 0; ci < number_of_corners; ++ci)
  {
    for (int d = 0; d < n; ++d)
    {
      int bit = 1 << d;
      int ci2 = ci & ~bit;
      if (side[ci] != side[ci2])
      {
        // Found two corners on opposite sides of the hyper-plane.
        intersections.push_back(plane.intersection(C_[ci], C_[ci2]));
      }
    }
  }

  return intersections;
}

} // namespace intersections

```

Online test case
Latest version

---
Tags: intersection
---


# Question
Title: How to compute XP thresholds when scaling changes for each level range?
I am developing mobile game and I am stuck on an issue regarding proper player stats scaling based on level.

As a parameters for the computation we have:

* base XP value
* multiple increment values (for example one increment for levels 1-5, another one for 6-10 and so on...)

We are using this formula: `current level XP = previous Level XP + (previous level XP ^ increment)`.

Let's break it down on an example: We want to get the XP threshold to graduate from level 3. The base XP value is 100, increment for levels 1-5 is 0.5.

To get the needed XP, we first need to get the value for level 2:

`level2Value = 100 + 100^0.5`

Now we have stat value for level 2 and we are able to get `level3Value` like this:

`level3Value = level2Value + level2Value^0.5.`

If we had to calculate values for some high levels, this seems like a rather inefficient way to do things, as values for all previous levels must be computed prior, and in addition we are changing the increment value based on level - we cannot simple have one line of formula which gets us the number that we wan; all is dependent on previous values.

Of course we can compute all previous values, cache it on the server and then do the lookup to the data, but we would like to avoid it if possible - still I have a feeling that there must be better way to deal with this problem.

**My question is the following:**

Can you suggest some other (similar) formulas or ways to compute this? Ideally just one line of code should do the trick (something like \`level X XP = X * baseXp * increment|, but more complex which allows usage of different increment values)

# Answer
> 1 votes
You are overcomplicating it. Doing the math once and storing it in a dictionary or list is perfectly fine. The time and memory footprint for the calculation (or read it from a config/ database) is so small, even if you have 500 or more levels, that a single formula is not worth it. There are even some benefits to not use a single formula:

* You can way easier adjust the correct value. A formula that changes every 5 level over 100 will look like a monster. By doing a small change, did you really manage to change the amount for lvl 29 to 30 or was it perhaps for lvl 65?
* With one look you know how much exp is needed and even people with no math background can make changes.
* The actual footprint will be smaller. For a formula you still would call it at least once per level up. A lookup can be reused for every player server side.
* Making changes in the dev process is faster, instead of coming up each time with a new formula that might reflect what you want

If there is no bottleneck (and if the level calculation is the bottleneck in your game you have a different problem - usually by calling it too often), don't try to optimize the code too early. For simple things, a simple solution is faster and less bug prone. By the time you are done with a full custom formula once, you could have used that time for other features of your game.

# Answer
> 0 votes
This is a piece-wise(1-5,6-10) sum of a geometric series.

```
if (n< 6)
   a =100^(1+1/(2*n))
else
  a=251.188643150958 + 100^(1/(3*n)) //assuming level6 = level5 + 100^(1/3)..

```

the 251 is n=5 and the starting point for the 6-10 levels.

That is the closed form formula for the desired calculations.

---
Tags: mathematics, game-design, algorithm, progression, scalability
---


# Question
Title: Emissive material not casting light on itself in Unreal
I have a static mesh that has an emissive material applied to part of the mesh. The emissive material successfully cast light to surrounding objects. However, the face of the mesh with the emissive material fails to cast light on the rest of the mesh.

This is how the unlit scene look:

The parts circled blue has the emissive material, and the sphere and cube are both lit by the emissive material. However, the part of the stairs (highlighted in red) does not get lit.

The lit scene:

Is there a way for the stairs to be lit by itself?

# Answer
Firstly create the instance material of the emmisive material and delete that mesh which is having a problem and replace it again and build the lighting .
> 0 votes

# Answer
The rest of the mesh will not be calculated as part of the lighting calculation.

This is done on purpose since light sources do not typically need to accept light. The behavior is different under raytracing with UE5.

Split the emitter into its own object.
> 0 votes

# Answer
from the UE4 docs on Emissive lighting there are a couple of things that may not have been done. These would be to have the Stairs set to be lit by emissive lighting and the Emissive Strength is not strong enough to reach the steps of the stairs. So:

1. Check to True that the Stairs receive emissive lighting.
2. Add a property to your Material that will multiply the emissive color by a value called Emissive Strength. This will increase the influence of the emissive light.
> -1 votes

---
Tags: lighting, unreal, unreal-4, materials
---


# Question
Title: What specific lighting property creates "the unity look"
Nearly all unity games have specific "unity" look. It is quite obvious that it is caused by the rendering pipeline and shading, but I was wondering which specific part is responsible for that and if there is a way to change it.

Edit: As per request a few references (subnautica and two point campus):

I chose 2 premium indie games, to show that this is not a simple case of "spend money on resources/modelling scrub", but most likely some property of rendering engine. All the surfaces and models seem to have this... plastic(?) look? The point of this post in a way is to point out what exactly is causing this.

# Answer
Personally I wouldn't say that there is a universal "Unity look"; see games like *Cities: Skylines*, *Battletech*, *Dave the Diver*, and *Mechanicus* for examples of different visual styles in 3D Unity games.

The "plastic" look you are seeing is caused by giving a material a medium-to-high amount of smoothness and not assigning a specular map or normal map.

The standard shader in Unity is a Physically Based Rendering (PBR) shader. Without getting into too much detail about the nature of PBR, one of the characteristics is a 'smoothness' setting that defines how glossy the surface is (some renderers invert this value and call it "roughness" instead).

With a very simple Standard Shader setup, the material might only have an albedo texture (defining the color of the material) and a fixed value for Smoothness (in range 0 - 1 where 0 is not glossy at all and 1 is fully glossy). This gives the entire material a uniform level of smoothness/glossiness...

...which looks unrealistic. But why?

Here's a photo of one of my tablets. The screen certainly isn't uniform in glossiness, and probably hasn't been since the day I took it out of the box. There's dust and smudged finger oils all over the screen.

Using the Standard Shader in Unity, we can create this kind of look using a Specular Map or Metallic Map with an alpha channel. With this setup, the alpha channel defines the Smoothness, or glossiness, of the surface, meaning it doesn't have to be uniform over the entire surface.

Here's the same cylinder with a simple Specular Map added to make the smoothness of the material non-uniform. Now the cylinder looks like it's got smudges or other wear on the surface, which looks much more realistic:

The alpha channel of the Specular map looks like this. The brightness corresponds to glossiness of the surface, where black is no gloss and white is full gloss.

Specular maps aren't only used to make glossy surfaces look smudged. They can also be used for effects like making part of a rough surface (such as a stone) look like it's been worn smooth, or to make it look as if paint has been scratched and worn off of the corners of metallic objects.

Of course, in reality, most surfaces besides polished glass have some texture to them. In video games, we often add texture to a surface with Normal Maps, which are special textures which alter the direction of a surface for lightning calculations. Normal maps (sometimes referred to in slang as "bump maps") can add a lot of realism to a surface without increasing the polygon count.

Here's our cylinder with a Normal Map added to give it a brushed-metal look:

The example screenshots you shared don't appear to make use of Specular or Normal maps, which is why the surfaces have that artificially smooth look.
> 2 votes

---
Tags: unity, 3d, shaders, shading
---


# Question
Title: What is the relation between the magnitude of the cross product and dot product of two vectors?
If I have an equation:

|A×B|=A.B

What would be the angle in between A and B?

# Answer
This question was originally titled:

> What is the relation between the scalar product and dot product of two vectors?

But that didn't match what the body of the question asks, so let's start by clarifying some terms:

The **scalar product** and the **dot product** are two names for the *same thing*, written \\$\vec a \cdot \vec b\\$.

What's written on the left side of the equation there is the magnitude of the ***vector* product**, also called the **cross product**.

With that terminology cleared up, we can say something about the equation in question:

$$\begin{align} \left \\| \vec a \times \vec b \right\\| &= \vec a \cdot \vec b\\ ab \left| \sin \theta \right| &= ab \left| \cos \theta \right| \end{align}$$

Where \\$a \ge 0\\$ and \\$b \ge 0\\$ are the lengths of vectors \\$\vec a\\$ and \\$\vec b\\$, respectively, and \\$\theta\\$ is the angle between them.

We can see that this equation will hold true if either \\$a = 0\\$ or \\$b = 0\\$ (either \\$\vec a\\$ or \\$\vec b\\$ or both are the zero vector), or if the angle obeys \\$ \left| \sin \theta \right| = \left| \cos \theta \right|\\$, which happens if there's an angle of \\$\frac {\pi} 4\\$, \\$\frac {- \pi} 4\\$, \\$\frac {4 \pi} 4\\$, or \\$\frac {-3 \pi} 4\\$ between them.

(The latter two are the same separation between the vectors as the first two, just "in the opposite order". This is the difference between \\$\vec a\\$ being clockwise or counterclockwise of \\$\vec b\\$, if you fix one view/orientation of the plane containing them. This matters for the sign of the cross product, but not its magnitude: \\$ \vec a \times \vec b = - \vec b \times \vec a\\$)
> 2 votes

---
Tags: vector, linear-algebra, trigonometry
---


# Question
Title: godot importing mesh files without the inheritances of useless spatial nodes
when you drag and drop a folder with GLB files in godot, when you access those files with code... they are automatically imported with useless spatial nodes as their root scene. like swordmesh1 will be imported as a child of an utterly useless scene root node called swordmesh1... same name but one is a spatial by default. I've seen that I can change the type of scene root but I have not found how to delete the scene root to begin with... I want the raw mesh to be the only node in the scene that is being imported.

# Answer
> 0 votes
Sadly this is not straightforward, so...

1. Do you want the `Mesh` or the `MeshInstance3D`?

* If you need a `Mesh` you can enable "Save to File" in the `Mesh` in the Advanced Import Settings dialog.
    * If you need a `MeshInstance3D`, keep reading.
2. Does it has to be what is imported, or is it OK to extract it?

* If it is OK to extract it, you can add the imported scene as a child of another scene, then select "Make Local" on the context menu in the Scene dock, and take the node you want, and remove the rest.
    * Otherwise, keep reading.
3. Are you willing to write code for this?

* If you are OK writing code for this, then you are going to create a `@tool` script that extends `EditorScenePostImport`. In it you override the `_post_import` method to extract the `MeshInstance3D` you want:

    ```
    @tool
    extends EditorScenePostImport

    func _post_import(scene:Node) -> Object:
       return find_mesh_instance(scene)

    func find_mesh_instance(node:Node) -> MeshInstance3D:
       if not is_instance_valid(node):
           return null

       for child in node.get_children():
           if child is MeshInstance3D:
               return child

           var found := find_mesh_instance(child)
           if is_instance_valid(found):
               return found

       return null

    ```

    And you are going to set this script as "Import Script" in the import settings and reimport.

    Notes:

    + Be aware that there might not be a `MeshInstance3D` or there might be multiple. The code above only takes one, and it does not apply transforms from the skipped `Node3D` to the returned `MeshInstance3D`, modify it to your needs.
        + If you are authoring the GLB file, you might define a naming convention so the script can use the names of the nodes to better identify what it should get.
    * If you are not willing to write code... I don't know how to solve this.

The relevant documentation is in Importing 3D scenes.

---
Tags: godot, mesh
---


title: What this code do?

text:
# Question
Title: What this code do?
I investigate source code old game for 90s, dont understand math stuff.

```
#define W2V_SHIFT 14

#define PREDICTIVE_SCALE_FACTOR 14

{
z = (enemy->pos.z_pos + (enemy->speed * PREDICTIVE_SCALE_FACTOR * phd_cos(enemy->pos.y_rot) >> W2V_SHIFT)) - (item->pos.z_pos + (object->pivot_length * phd_cos(item->pos.y_rot) >> W2V_SHIFT));
x = (enemy->pos.x_pos + (enemy->speed * PREDICTIVE_SCALE_FACTOR * phd_sin(enemy->pos.y_rot) >> W2V_SHIFT)) - (item->pos.x_pos + (object->pivot_length * phd_sin(item->pos.y_rot) >> W2V_SHIFT));
    }
angle = phd_atan(z, x);

```

"enemy" is an object on the scene, for example main game character. "item" is for example tiger. Tiger attacks the main character. This source code uses fixed point math (shift with W2V\_SHIFT). y\_rot - rotation angle. x\_pos and z\_pos - position on scene. phd\_sin and phd\_cos - assembler fixed point math routines.

My question is - what are the results x and z in this math calculations (suppose)? And what is the angle variable? Is this the next coordinate to move the character, or what? For what in this calculation is cos() and sin()? Maybe x and z are the distance between the tiger and main character?

Definition of phd\_atan() is:

```
;******************************************************************************
;*          Int phd_atan( int x,int y );
;*
;*      Entry EAX: Distance along X axis..
;*            EDX: Distance along Y axis..
;*      Exit  EAX: Angle ( 0 - 65536 )

```

# Answer
This is using a common formula for polar coordinates, expressing one point as an offset from a pivot point by some radius at a particular angle:

```
x = pivot.x + radius * cos(angle)
z = pivot.z + radius * sin(angle)

```

The left half of the x & z code is a prediction for where the enemy will be one time step in the future, given its current position, speed, and heading angle.

The second half is the position of the swiveling arm of the item, given the position of its pivot, the length of its arm, and its rotation angle.

By subtracting these halves, we get a vector pointing from the end of the item's swiveling arm to where the enemy is predicted to be.

The `atan` function is giving the heading angle of this vector.

This might be used to make the "tiger" item face toward where the enemy character is moving, anticipating its movement.
> 1 votes

---
Tags: c++, mathematics
---


title: Is OpenGL 2.0 possible in unity?

text:
# Question
Title: Is OpenGL 2.0 possible in unity?
I want to develop a game in unity, just a small scale simple game without heavy computation nor complicated feature, and does not use a lot of ram either (2-3 GB). I want player with "outdated device" (device that does not support OpenGL 3.0 or higher) still able to play my game because apparently these outdated device is still widely used, especially in poor region, due to their cheap price. Forcing OpenGL 3.0 would prevent these device from playing my game despite my game using feature that can be implemented in OpenGL 2.0, so this does not make sense to use OpenGL 3.0 in the first place.

I try to find information regarding OpenGL version used by unity, however i have only found https://docs.unity3d.com/Manual/OpenGLCoreDetails.html. In that article it was said

> This scales from OpenGL 3.2 to OpenGL 4.5 depending on the OpenGL driver support.

I even tried changing the documentation version to the oldest one possible (2017.1) and it still said the same exact sentence.

Does this mean OpenGL older than 3.2 is not supported by Unity ? or is there any workaround to this ?

# Answer
According to this post on Unity Forums website, OpenGL 2 support was dropped since Unity 5.5:

> ...since Unity 5.5, OpenGL core profile 3.2 is the minimum supported version.

And OpenGL ES 2 support was dropped in Unity 2022:

> Unity 2022 will offer no GLES2 support for Android and will instead raise an error on importing an older project.

So, basically, you'll need to use an Editor version pre 5.5 (5.4 and older). You can still download previous Editor versions from the archive: here.
> 2 votes

---
Tags: unity, opengl, compatibility
---


# Question
Title: How can I orbit a camera about it's target point?
I'm drawing a scene where the camera freely moves about the universe. The camera class keeps track of the view (or *look at*) point, the position of the camera, and the up vector. These vectors/points are then passed into gluLookAt.

Pan and zoom are nearly trivial to implement. However, I'm finding rotation about the *look at* point to be much more of an issue. I want to write a function Camera.rotate that takes 2 angles, one that rotates up/down and one that rotates left/right along an imaginary sphere that is centered about the *look at* point.

Is there an easy way to do this?

I've (briefly) read about quaternions, but I wanted to see if there was an easier solution given the relatively simple construction of my scene.

# Answer
> 28 votes
What you are asking for is called Arcball rotation. Quaternions are the easy solution only if you understand how they work. You can achieve the same without quaternions however.

**Pre-requisites**

Do you know how to rotate objects in general? Let's say you have an object at the origin. Do you know how you rotate it (hint: multiply by some rotation matrix)? If yes, then I am assuming you know what will happen if you translate the object first and then rotate it?

You must know how to calculate a rotation matrix from angle-axis (easy as pie, look at the myriad of equations online, a lot of them give you the code as well)

**Solution**

* Get the camera's **up** and **right** vectors. Note that they should be normalized.
* Get the vector from the focus point to the camera (camPosition - Focus). This is the vector that you are going to be rotating. Let's call this **camFocusVector**.
* Decide how much you want to rotate in yaw/pitch in relation to the camera
* Create two rotation matrices. The 1st rotation matrix will use the **up** of the camera as the axis and **yaw** angle that you decided. The 2nd rotation matrix will use the **right** of the camera as the axis and **pitch** angle that you decided.
* Now rotate the **camFocusVector** with the new rotation matrices. This is now your new position of the camera relative to the origin. We of course, want it to be relative to the focus point...
* Add the focus point position to **camFocusVector**. This is now your camera's new position. Translate your camera accordingly.
* Finally, ask the camera to focus on the focus point by calling your lookAt() function

**Caveats**

You will have to lookout for certain cases or singularities at which your camera will stop working. Looking straight down/up for example. I will let you figure out how to deal with those.

**EDIT1: How to recalculate the orthonormal vectors of the camera**

You already know the direction of the camera ( (cameraPos - focusPoint).normalize() ). Now assume that your camera's up is +Y (or w/e your world's current up axis is... that is up to you). Now simply cross the **direction** with the **up** to get the **right**. Done? Nope! Your up vector is no longer orthogonal to the other two. To fix that, cross **right** with **direction** and you get your new **up**.

Note that the Gram-Schmidt is really what should be used to orthonormalize vectors.

Again, take a note of the caveats as this will fail to work in some cases (**direction** is parallel to **up** for example).

# Answer
> 2 votes
This very simple algorith to achieve that is pretty awesome:

Being P the center point about you want to rotate (the "look at"or "target" point):

```
translate(-P)

rotate horizontal
rotate vertical

translate(P)

```

I used it and its nice.

Source found at sister-site stackoverflow: https://stackoverflow.com/questions/287655/opengl-rotating-a-camera-around-a-point

# Answer
> 1 votes
What you need is a typical ArcBall camera, which is basically a camera that keeps a target location and allows you to move the camera in a "spherical" way around that target.

It's in XNA but IIRC I've used this implementation before, and it worked quite well:

http://roy-t.nl/index.php/2010/02/21/xna-simple-arcballcamera/

# Answer
> 0 votes
Here's my code for rotating around a point, found myself reusing it a lot.

```
float distance;      // Straight line distance between the camera and look at point

// Calculate the camera position using the distance and angles
float camX = distance * -sinf(camAngleX*(M_PI/180)) * cosf((camAngleY)*(M_PI/180));
float camY = distance * -sinf((camAngleY)*(M_PI/180));
float camZ = -distance * cosf((camAngleX)*(M_PI/180)) * cosf((camAngleY)*(M_PI/180));

// Set the camera position and lookat point
gluLookAt(camX,camY,camZ,   // Camera position
          0.0, 0.0, 0.0,    // Look at point
          0.0, 1.0, 0.0);   // Up vector

```

# Answer
> 0 votes
I made a code to be used in my games, the code works very well.

```
#pragma once

#include <cmath>
#include <directxtk/SimpleMath.h>

using namespace DirectX::SimpleMath;

class OrbitateCamera
{
private:
    const float PI = 3.14159265358979323846f;
    inline float Clamp(float nV, float minV, float maxV) const { return max(min(nV, maxV), minV); }
    inline float DegreesToRadians(float degrees) const { return degrees * PI / 180.0f; }
    inline float RadiansToDegrees(float radians) const { return radians * 180.0f / PI; }

    Vector2 PreviousCursorPos{ Vector2::Zero };
    Vector2 SmoothedCursorPos{ Vector2::Zero };

    float Pitch{ 0.0f };
    float Yaw{ -(PI / 2.0f) };

public:
    Matrix View         { Matrix::Identity };
    Matrix Projection   { Matrix::Identity };

    Vector3 Position    { Vector3::Zero  };
    Vector3 Front       { Vector3::Forward };
    Vector3 Up          { Vector3::Up };
    Vector3 Right       { Vector3::Right };

    float AspectRatio   { 0.f };
    float NearPlane     { 0.1f };
    float FarPlane      { 100.f };
    float Fov           { 90.f };

    float SmoothingCursorFactor{ 4.2f };

    OrbitateCamera(Vector3 position, float aspectRatio, float fovDegrees, float nearPlane, float farPlane)
    {
        Position    = position;
        AspectRatio     = aspectRatio;
        Fov     = fovDegrees;
        NearPlane   = nearPlane;
        FarPlane    = farPlane;

        GenerateMatrices();
    }

    void Update(int MousePosX, int MousePosY, float Distance, const Vector3 TargetPosition)
    {
        SmoothingCursorFactor = Clamp(SmoothingCursorFactor, 0.1f, 10.f);
        SmoothedCursorPos = Vector2::Lerp(SmoothedCursorPos, Vector2(MousePosX, MousePosY), SmoothingCursorFactor * 0.0001f);

        Vector2 MouseDelta = SmoothedCursorPos - PreviousCursorPos;
        PreviousCursorPos = SmoothedCursorPos;

        Yaw += MouseDelta.x;
        Pitch -= MouseDelta.y;

        // without it it's shit
        Pitch = Clamp(Pitch, -89, 89);

        Quaternion orientation = Quaternion::CreateFromYawPitchRoll(DegreesToRadians(Yaw), DegreesToRadians(Pitch), 0);

        Front   = Vector3::Transform(Vector3::UnitZ, orientation);
        Right   = Front.Cross(Vector3::UnitY); Right.Normalize();
        Up  = Right.Cross(Front); Up.Normalize();
        Position = TargetPosition - Front * Clamp(Distance, 1.f, 100.f);

        GenerateMatrices();
    }

    inline void UpdateAspect(int Width, int Height)
    {
        AspectRatio = Width / (float)Height;
    }
    void GenerateMatrices()
    {
        View        = Matrix::CreateLookAt(Position, Position + Front, Up);
        Projection  = Matrix::CreatePerspectiveFieldOfView(DegreesToRadians(Fov), AspectRatio, NearPlane, FarPlane);
    }
};

```

---
Tags: opengl, camera, rotation
---


# Question
Title: How to get nested child node without using full path in Godot?
How to get nested child node without using full path? I tried with just node name, it doesn't work.

The script is on top level so the path is quite long:

```
dialogText = GetNodeOrNull<RichTextLabel>("VBoxContainer/Panel/MarginContainer/DialogContainer/DialogTextWrapper/DialogText");

```

*(Question originally posed on Discord and copied here.)*

# Answer
> 1 votes
The simplest way is `Node.find_child()`, but that does a search each time it's called which can be slow.\* When you're done prototyping, you'll want to change to another method.

You could do a Unique Name.

Or an `@export` in gdscript or C#.

---

* And by slow, I mean `find_child()` can be so slow that the docs warn about using it:

> Note: As this method walks through all the descendants of the node, it is the slowest way to get a reference to another node. Whenever possible, consider using get\_node with unique names instead (see unique\_name\_in\_owner), or caching the node references into variable.

# Answer
> 0 votes
`get_node(NodePath)` fetches a node & can use the `NodePath` can be either a relative path (from the current node) or absolute. The relative path is typically shorter. When used as a literal you can further shorten the expression to `$NodePath`.

So with this `Player` scene:

And this `PlayerGun` scene:

Then in order to access the somewhat deeply nested `Muzzle` node from within my script for `Player` I would do this in 3.x:

```
onready var muzzle = $Sprite/PlayerGun/Sprite/Muzzle

```

or this in 4.x:

```
@onready var muzzle = $Sprite/PlayerGun/Sprite/Muzzle

```

Because I'm using a relative path, I don't need the full / absolute path. As as a bonus, the absolute path could possible change, but as long as I don't change the relative relationship between `Player` and `Muzzle` nothing breaks.

`get_node()` is more performant than `find_node()`. `find_node()` has to do a pattern matching search for its target whereas `get_node()` uses a hash map to children (which is also how unique scene nodes work).

# Answer
> 0 votes
I use `@export` for this, especially in e.g. UI components in which I may re-organize things often that end up changing all paths.

I do something like:

```
@export_group("Internal")
@export var foo_button: Button
@export var bar_button: Button
...

```

Then you can assign your button deep within tree by either dragging or clicking on the inspector and assigning.

The main advantage of this method is that you don't have to do anything if you re-organize the tree. The references are kept even if you move nodes around, add nodes to the hierarchy, etc.

I add them to the "Internal" export group so they don't pollute the "external interface" of the scene.

The variables are assigned by the time `_ready()` is called.

---
Tags: godot, godot-4
---


title: Difference of angle by Y value

text:
# Question
Title: Difference of angle by Y value
This code from game 90s years. For example on scene there is tiger as "item" and main character as "enemy". This code calculate vector or direction of attack tiger to main character. Used fixed point math.

```
#define W2V_SHIFT 14

#define PREDICTIVE_SCALE_FACTOR 14

{
z = (enemy->pos.z_pos + (enemy->speed * PREDICTIVE_SCALE_FACTOR * phd_cos(enemy->pos.y_rot) >> W2V_SHIFT)) - (item->pos.z_pos + (object->pivot_length * phd_cos(item->pos.y_rot) >> W2V_SHIFT));
x = (enemy->pos.x_pos + (enemy->speed * PREDICTIVE_SCALE_FACTOR * phd_sin(enemy->pos.y_rot) >> W2V_SHIFT)) - (item->pos.x_pos + (object->pivot_length * phd_sin(item->pos.y_rot) >> W2V_SHIFT));
}

angle = phd_atan(z, x);

z = abs(z);
x = abs(x);

if (x > z)
info->x_angle = phd_atan(x + (z >> 1), y);
else
info->x_angle = phd_atan(z + (x >> 1), y);

```

x\_angle is seems angle from Y position of item relatively to Y position of enemy?

What do this calculations: x + (z \>\> 1) and z + (x \>\> 1)? Explain this calculations please.

# Answer
> 1 votes
The code is functionally equivalent to:

`angle = atan(max(x,y) + min(x,y)/2,y);`

Not overly helpful.

## So let's examine it from a different perspective:

This is a variation of axis interlacing used in sorting algorithms:

Say, You have 2 integers X and Y. X0 is the most-significant bit...

using the bit pattern: X0 Y0 X1 Y1 ...

You can approximate the sort on two axes at the same time as if they were a single dimension. Reducing complexity from N^2 to N.

---

The given code does a similar thing for lengths.

It is a very fast, but rather poor approximation of `sqrt(x^2 + z^2)`

In the sorting case above, X0 was arbitrarily chosen to go first. In this case the larger value goes first. `if (x > z)`

The reason for the bit shift is twofold:

1. It keeps the output values from overly exceeding the expected output `(1.0,1.0) = 1.1` instead of returning 2.0, when the actual value is `sqrt(2) = 1.414...`
2. It approximates a rounding effect in log2 space. 2 values with similar MSBs will carry the bits leading to closer to accurate results.

---

The `atan` functions in the 90s were simple lookup-tables so only the most significant values mattered.

---
Tags: c++, mathematics
---


# Question
Title: How to create terrain with multiple textures
I have a giant terrain. I have grass/stone/mud/and so on...

As for the test I am using raw color assigned to each vertex to render triangles of terrain. When I have a terrain like that I set upper 4 vertices to red to represent, let's say "dirt" then lower dot to blue to represent "stone". Then I get this...

what I want to get is this

to represent upper "dirt"(red) area and lower blue "stone" area. and the upper square and lower square to blend a little in the middle like this game

I am stuck

# Answer
You must either increase your grid resolution by a factor of 2, since the shared vertex color will be interpolated across the triangle/quad, or break the efficiency of triangle fan, and express duplicate vertices for each shared boundary each with its own color attribute.
> 0 votes

---
Tags: terrain-rendering
---


# Question
Title: Zoom at a specific point using Orthographic camera
Currently I can perform Zoom which seems to be working fine but essentially what I'm really trying to do is zoom on a position offset from center as currently when I zoom then zoom is performed at the center.

Not sure how to achieve this ?

One way i'v though is either not use the orthographic camera and rather clip the texture, so that the my clipped texture will be drawn onto my directx surface covering the entire view. I could possibly perform the clipping using a constant buffer but then that would stretch the entire clipped texture over my viewport area.

Any suggestions on the above ?

I'm using Directx11, SharpDx with D3DImage & C#.

Do note: I'v created my vertexes directly screen co-ordinates.

Edit:

```
    this.eye = new Vector3(0.0f, 0.0f, 0.0f);
    this.lookAt = new Vector3(0.0f, 0.0f, 1.0f);
    this.up = new Vector3(0.0f, 1.0f, 0.0f);
    viewMatrix = Matrix.LookAtLH(eye, lookAt, up);

```

**NOTE:** My application isn't a game but rather a video player

# Answer
Zooming in/out to a particular point on the screen isn't an independent action for the camera to perform, but a combination of two simpler transformations: zooming in and moving the camera for a proper distance.

Let's suppose we zoom in with the camera, and we reduce the Field of View angle so that the final view focuses on the objects in the center. Then, we move the camera to center a particular object on the left. We can perform the two actions in whatever order we want ("Zoom, then move" or "Move, then zoom"), the final result will be the same.

But now, we can imagine to zoom in 1/10th than before, and then to move the camera 1/10th toward the position we found out in the previous example. So, zoom again and move again. After ten steps, we get the same previous results, but now we created the illusion of zooming and moving at the same time, which results in zooming in to a particular point in the space.

If you want to zoom on a particular position on the screen instantaneously, you can just try the first example, when the latter works better on a zooming animation.
> 0 votes

# Answer
Unless your video contains depth information, your solution is given in the question.

> One way I've though is either not use the orthographic camera and rather clip the texture, so that the my clipped texture will be drawn onto my directx surface covering the entire view. I could possibly perform the clipping using a constant buffer but then that would stretch the entire clipped texture over my viewport area.

At that point the only consideration is aspect ratio. There is no single solution to that problem.
> 0 votes

---
Tags: c#, rendering, directx11, sharpdx
---


# Question
Title: Int vs Float, which one is faster for gpu?
My game need to loop through massive amount of data, and the amount of data can increase by a lot depending on world settings set by player. The data is too big for CPU so i need to use GPU for it using compute shader. The numerical range of the data is the same as int range so i can store it either as int or bigger (float, double, ect). I initially thought to store it as int because i tried benchmarking int vs float addition loop performance on CPU, int loop is averagely 16 times faster (at least on my computer).

However, after some googling, some said that some GPU is designed around float operation, so integer operation need to be simulated, which imply that integer operation could actually be slower than floats. Is this true to most GPU ? should i use floats instead of int to store my data when calculated using GPU ?

# Answer
> 0 votes
When it comes to performance, nothing beats testing the data and algorithms that you're interested in on the hardware that you care about to find out what performs best. Performance almost always depends on the specifics of what you're actually doing.

Also, when doing any optimization investigations, make sure you're getting the correct results from each approach. For example, beware that 32-bit floats won't hold the full range of 32-bit integer values accurately. The biggest odd integer that they can store accurately is 16,777,215 - every value above that is even. 64-bit doubles can accurately store every 32-bit integer.

As a rough guideline, on a GPU, you should generally expect the smallest data type to be fastest. For maximum speed, that means using 8-bit integers where you can, followed by 16 bit (half-float / integer) data, and then 32-bit types. One reason for small size being important is that smaller types take the least amount of storage (and therefore memory bandwidth). In addition it's common for GPUs to be able to do calculations on smaller data types faster too.

Also note that just running code on a GPU doesn't automatically make it faster. It's only going to be faster if you can take advantage of the parallel nature of the GPU.

---
Tags: unity, opengl, performance, gpu
---


title: Why can't I get the AnimationTree node?

text:
# Question
Title: Why can't I get the AnimationTree node?
This is my code:

```
extends CharacterBody2D

@export var SPEED = 300.0
@export var maxHP = 100
@export var curHP = 100

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var state_machine = $AnimationTree.get("parameters/playback")

func _ready():
    pass

func _physics_process(delta):
    if not is_on_floor():
        velocity.y += gravity * delta

    var direction = Input.get_axis("ui_left", "ui_right")
    if direction:
        velocity.x = direction * SPEED
    else:
        velocity.x = move_toward(velocity.x, 0, SPEED)

    if velocity.length() > 0:
        state_machine.travel("run")
    else:
        state_machine.travel("idle")

    if Input.is_action_pressed("ui_left"):
        $Sprite2D.set("flip_h", true)
    if Input.is_action_pressed("ui_right"):
        $Sprite2D.set("flip_h", false)

    move_and_slide()

    if Input.is_action_just_pressed("attack"):
        _shoot()

func _losehp():
    curHP -= 10

func _die():
    if curHP == 0:
        pass

func _shoot():
    if Input.is_action_just_pressed("attack"):
        pass

```

I get errors on the line:

```
var state_machine = $AnimationTree.get("parameters/playback")

```

These are the errors:

> CharacterBody2D.gd:9 @ @implicit\_new(): Node not found: "AnimationTree" (relative to "CharacterBody2d").

> Cannot call method `get` on a null value.

the tree:

please help:(

# Answer
> 2 votes
In this line:

```
var state_machine = $AnimationTree.get("parameters/playback")

```

The expression `$AnimationTree` is equivalent to `get_node("AnimationTree")`, which is trying to access the scene tree.

However, the aforementioned line will run before the `CharacterBody2D` is in the scene tree. To solve this, you can use `@onready`:

```
@onready var state_machine = $AnimationTree.get("parameters/playback")

```

Then, assuming the the `AnimationTree` is there (you didn't share how the scene tree looks like in your project), it should work.

---
Tags: godot, gdscript, godot-4
---


# Question
Title: Min - Max Weapon Damage formula in video games
I currently working on an RPG game and I'm looking for are formula for creating/generating a min-max weapon damage for an item.

Why in Diablo for example, when a weapon is dropped from an enemy, the weapon damage is 24-72 (just as an example)? it seems that each time the item is dropped those values are randomly generated and changed. So the same weapon could drop twice but his min-max weapon damage could be different.

Is there a math formula that calculates those min-max values when the engine creates the item? what's the legality of that formula? like `ItemLevel` * 2 or something.

I couldn't find on the internet anyone who talks about how those min-max values are generated in video games.

Does anyone have an idea?

# Answer
> 5 votes
The short answer is: because the developers made it that way. There's no single rule that all game use to generate randomized ranges. Usually, *how* the randomness is implemented will depend on *why* the developers are adding it. And again, that's going to vary depending on the game & situation.

Some of the reasons designers might add randomness because it:

* is an expected convention of a genre. For example games based on table top RPGs.
* may reduce guaranteed win scenarios and or create the opportunity for upset victories. For example an overpowered attacker might still get low random numbers allowing an underdog defender to survive.
* might be introduced to adjust the skill ceiling. The outcome of static (non-random) events puts a greater emphasis on player skill.
* is considered part of "finding the fun." Some players enjoy pouring over multiple variables of uncertainty to find ideal combinations for their play style.

For additional information on the *why* of randomness I suggest searching through our questions searching for "random" and either the or tags. I specifically recommend:

For more information about the math behind these calculations, I suggest:

---
Tags: mathematics, unreal, rpg
---


# Question
Title: About possibly using Depthstencil 2D array in multiplerendertarget mode
I'm rendering in forward mode my scene with its depth buffer and because I'm using animated characters I'm plannig to find a way to use multiple rendertargets to do the directional shadow pass at the same time using a geometry shader. The reason for this is also that I have arranged my shadowmap size to be the same as the screen size. Moreover I'm doing "transparent colored shadows" inspired from here that requires for my needs an extra color channel and an additional depth information. The effect is cool but has some impact on the performance so doing the animation only once should be interesting. So my plan is :

with geometry shader:

send to RTV0+Depth0 the scene

send to RTV1+RTV2+Depth1 shadow colored(RTV1)+additional depth layer(RTV2) and regular shadowmap (depth1)

currently I have these two rendering made in two passes (scene then shadows).

I have already used depthmap cube for pointlight shadow so I wonder if we can use 2Darray depth with multiple targets.

If using 2DARRAY depth with 2Darray rendertarget is possible I'm wondering how this must be arranged. Do we need the number of slices for the target 2Darray to match the number of slice for the depth 2DArray or is it possible to use less depth buffer than the number of rendertarget? Or can the number of target per depth not be the same? Is the device managing this automatically and how?

# Answer
> 0 votes
Still learning a global answer to my question is yes we can render in 2DArray n targets with a 2Darray n depthstencil and the device knows that RTVn must be linked to DSVn.

Below I present how I proceeded for my application to btain a scene with colored shadow in one pass.

Create 2DArray RTV0 with array=2 for colors (scene/shadow) (RGBA format)
From RTV0 texture create RTV1 from array=0 (scene colors)
From RTV0 texture create RTV2 from array=1 (shadow colors) and its SRV2

Create 2DArray DSV0 with array=2 for depths (scene/shadows) (R16/32 format)
From DSV0 texture create DSV1 from arrayslice=0 (scene depth)
From DSV0 texture create SRV1 from arrayslice=1 (shadow depth)

Create 2D RTV3 for depth of colored shadow (R16/32 format) and its SRV3

Set viewproj0 in shader to SceneViewProjection for RTVIndex 0;
Set viewproj1 in shader to LightViewProjection for RTVIndex 1;
Clear RTV0 to white, DSV0 to 1, RTV3 to 1

//\************** Scene opaque pass
//in the shader the object on RTVIndex0 are colored and those on RTVIndex1 are drawn white, the result is no object visible on a white background in RTVIndex1 but array 1 of DSV0 is filled
SetRenderTargets(1, RTV0, DSV0);
SetShaderOpaque; //use the geometry shader below
SetBlendState(Opaque); //SRC COLOR/ZERO/ADD
RenderOpaque;//cullback

//\************** Scene alpha pass add only alpha object in the scene
SetRenderTargets(1, RTV1, DSV1);
SetShaderAlpha;
SetBlendState(Alpha); //SRC\_ALPHA/INV\_SRC\_ALPHA/ADD
RenderAlpha;//cull None

//\************** Shadow color pass
//renders only transparent objet in the shadow view color/depth surfaces. I disable depthstencil here as depth is written to a color RTV3 but a dedicated depthbuffer can be used instead. The point is that we are sure that the object will be visible if in shadow scene
Set viewproj0 in shader to LightViewProjection
SetBlendState(ShadowColor)//RTV2 Alpha blending SRC\_ALPHA/INVALPHA ADD//RTV3 ONE/ONE MIN
SetShaderShadowAlpha; //write color in RTV2 and depth in RTV3
ID3D11RenderTargetView\* pRT;
pRT\[0\] = RTV2 //shadow colors
pRT = RTV3;//shadow depth;
SetRenderTargets(2, pRT, NULL);
SetDepthStencilOff;
RenderAlpha ;// cull None

After copying the Scene (from RTV0 array=0 that gives SRV0) to the main buffer with a simple blitting pixel shader, the result is in the picture below.

All opaque objects are rendered once and only transparent ones must be rendered twice. I have to search more to render everything only once.

Everything is prepared in one batch and I first used a deferred shadow rendering. But as shown in the left picture shadows behind transparent object are missing due to the reconstructed depth from DSV0 scene depth. Storing the depth buffer before rendering the transparent object for later comparison during deferred shadowing can solve this but I did not try.

I finaly used forward rendering. We need to store SRV1, SRV2 and SRV3 SRVs to 3 additional resources to allow writing to their original RTVs during forward rendering. On my system rendering with a pixel shader from SRV1-3 to their copies is more efficient (125FPS) than using copysubresource (100FPS). Using a multirendertarget setting works also but less efficiently than a separate rendering. Finally I also tested a rolling method with two duplicates of surfaces RTV0/DSV0/RTV3, one serving as resource for the other and vice versa. This is the faster method (200FPS) as no copy is required for SRV1/2/3. The price is to have duplicated surfaces.

Below I added only the geometry and final shadowing shader, other are classical. No lighting is done.

The geometry shader. The major interest for doing this is to have matrix skinning for animated characters in the vertex shader outputing GS\_INPUT struct, avoiding calculating them twice.

```
[maxvertexcount(6)]
void GS_Array2D( triangle GS_INPUT input[3], inout, TriangleStream<PS_ARRAY2D_IN> Map2DStream )
{
    PS_ARRAY2D_IN output;
    output.RTIndex = 0;//scene target
    int v;
    for( v = 0; v < 3; v++ ) )//this gives a back culling for objects in scene
    {
        output.Pos = mul( input[v].Pos, ViewProjection);
        output.Col = input[v].Col;
        output.Tex = input[v].Tex;
        Map2DStream.Append( output );
    }
    Map2DStream.RestartStrip();
    output.RTIndex = 1; // light view target,
    for( v = 2; v >-1; v-- )//this gives a front culling for objects as shadows
    {
        output.Pos = mul( input[v].Pos, LightViewProjection );
        output.Col = input[v].Col;
        output.Tex = input[v].Tex;
        Map2DStream.Append( output );
    }
    Map2DStream.RestartStrip();
}

```

In the final pixel shader
for RTVIndex 0 set colors normally
for RTVIndex1 set opaque object to white, alpha 0 and normal colors for transparent ones with alpha =1. Alpha channel can be used later as a mask.

Below is the pixel shader valid for a single shadow color but adaptable to more

// LightViewProjection = LightView x LightProjection x TexOffset. TexOffset includes 0.5 shift used for translating to texture coordinate

```
float4 dPS = mul(worldpos, LightViewProjection);
dPS/=dPS.w;
float3 Color = SRV1.Sample(samPoint, Input.Tex);
float2 Depth;
Depth.x = SRV1.Sample(samClamp, dPS.xy).r+0.0005f;//includes Z bias
Depth.y = SRV3.Sample(samClamp, dPS.xy).r+0.0005f;
float2 DZH = float2(dPS.z, 0);
DZH = (Depth.x<DZH.x)?float2(Depth.x,1):DZH;
DZH = ((Depth.y<DZH.x)&&(DZH.x==dPS.z))?float2(Depth.y,2):DZH;
float Shadow = (DZH.y==1)?0:1;
if ( DZH.y==2)
{
    float4 RGBA = SRV2.Sample(samClamp, dPS.xy);
    Color*=RGBA.rgb;
}
return float4(Color*Shadow,1);

```

---
Tags: directx11, shadow-mapping, depth-buffer, multiple-render-targets
---


# Question
Title: How to take a screenshot beyond the viewport?
I have a large level design & I'm trying to take a *pixel perfect* screen shot of a particular area and/or the entire map bound within a region like this:

The region can be changed in size and position so I used a `ReferenceRect` ( Green box in the image) node to manually change it

So far I've come up with this:

```
extends ReferenceRect

func capture_image():
    var viewport=get_viewport()
    viewport.set_size_override(true, Vector2(rect_size.x, rect_size.x * viewport.size.y / viewport.size.x ))

    var image = viewport.get_texture().get_data()
    image.flip_y()
    image.save_png("res://screenshot.png")
    print("Took Screenshot!")

func _unhandled_input(event):
    if event is InputEventKey:
        if event.pressed and event.scancode == KEY_SPACE: # try pressing space twice
            capture_image()

```

This fits the entire game within the screen window but the image generated does not give a pixel perfect screenshot & the image size/resolution remains `1024 x 600 pixels` as you can see:

I suspect the window size itself would have to be increased to fit the `ReferenceRect` in order to get a *pixel perfect screenshot*

So is it possible to achieve this?
A crude method would also work since this is purely for development stage

**Note:** I'm using godot v3.5

# Answer
Came up with a hacky solution,

Just add this script to the `ReferenceRect` & extend it's borders to encapsulate the area to screenshot & press space:

```
extends ReferenceRect

func capture_image():
    var camera=Camera2D.new()
    camera.anchor_mode=Camera2D.ANCHOR_MODE_FIXED_TOP_LEFT
    camera.current=true
    self.add_child(camera)

    var tree=get_tree()
    tree.paused = true
    yield(tree, "idle_frame")

    var viewport_size=get_viewport().size
    var image=Image.new()

    image.create(rect_size.x, rect_size.y, false, Image.FORMAT_RGBAH)

    camera.position=Vector2.ZERO

    while camera.position.y < rect_size.y:
        while camera.position.x < rect_size.x:
            yield(tree, "idle_frame")
            var segment=get_viewport().get_texture().get_data()
            segment.flip_y()
            image.blit_rect(segment, Rect2(Vector2.ZERO,segment.get_size()), camera.position)
            camera.position.x+=viewport_size.x

        camera.position.x=0
        camera.position.y+=viewport_size.y

    image.save_png("res://screenshot.png")

    get_tree().paused = false
    camera.queue_free()

func _unhandled_input(event):
    if event is InputEventKey:
        if event.pressed and event.scancode == KEY_SPACE:
            capture_image()

```

If anyone has a more elegant solution please share

---

**Note:**
As per the docs:

> The maximum width and height for an Image are MAX\_WIDTH and MAX\_HEIGHT.

so the `rect_size` for the `ReferenceRect` you attach this script to cannot exceed (16384 x 16384) sucks :/

On the bright side the limit for this in Godot 4 is `16777216 x 16777216` which is much more better but I haven't gotten to that, so feel free to translate the above code to Godot 4

**Edit**
Added zoom:

```
extends ReferenceRect

export var zoom=1.0

func capture_image():
    var camera=Camera2D.new()
    camera.anchor_mode=Camera2D.ANCHOR_MODE_FIXED_TOP_LEFT
    camera.current=true
    camera.zoom=Vector2(zoom,zoom)
    self.add_child(camera)
    camera.position=Vector2.ZERO

    var tree=get_tree()
    tree.paused = true
    yield(tree, "idle_frame")

    var zoom_rect=rect_size/zoom
    var viewport_size=get_viewport().size * zoom

    var image=Image.new()
    image.create(zoom_rect.x, zoom_rect.y, false, Image.FORMAT_RGBAH)

    while camera.position.y < zoom_rect.y:
        while camera.position.x < zoom_rect.x:
            yield(tree, "idle_frame")
            var segment=get_viewport().get_texture().get_data()
            segment.flip_y()
            image.blit_rect(segment, Rect2(Vector2.ZERO,segment.get_size()), camera.position/zoom)
            camera.position.x+=viewport_size.x

        camera.position.x=0
        camera.position.y+=viewport_size.y

    image.save_png("res://screenshot.png")
    get_tree().paused = false
    camera.queue_free()

func _unhandled_input(event):
    if event is InputEventKey:
        if event.pressed and event.scancode == KEY_SPACE:
            capture_image()

```
> 0 votes

---
Tags: godot, gdscript, godot-3
---


# Question
Title: GLSL 9-Slice (or 9-Patch) working with single texture, but not with atlas texture
I've been able to implement 9Slice for textures when the texture is just itself, that means, it does not contain any subtexture except itself. This is the code I'm using:

```
#version 330 core

in vec2 uv;
in vec4 color;
in vec2 size;
in vec4 nine_slice;

uniform sampler2D tex;
uniform float dt;
uniform vec2 mouse_position;
uniform vec2 texture_size;

layout(location = 0) out vec4 out_color;

vec2 uv9slice(vec2 uv, vec2 s, vec4 b) {
    vec2 t = clamp((s * uv - b.xy) / (s - b.xy - b.zw), 0., 1.);
        return mix(uv * s, 1. - s * (1. - uv), t);
}

vec4 draw_nine_slice() {
    vec2 _s = size.xy / texture_size;
    vec4 _b = nine_slice / texture_size.xxyy;
    vec2 _uv = uv9slice(uv, _s, _b);
    vec3 _col = vec3(texture(tex, _uv).x);
    return vec4(_col, 1.0);
}

void main(void) {
        out_color = draw_nine_slice();
}

```

Where vars are:

* size: Size of the nine patch (the imgui window shown on the second image)
* nine\_slice: These are the paddings vec4(left, right, bottom, top)
* texture\_size: This is the size of the texture, which will be fixed. If it is a non-atlas texture, the size is the size of the whole image, if it is a subtexture from an atlas, the size will be the size of the subtexture inside the atlas. This is the texture:

And this is how it looks with the 9-Slice:

Working example of single texture 9-Slice

So as you can see, it expands nicely. The problem comes when I use my texture atlas (change the white color of the sub textures with gray, as they could not be seen on this site white background):

I have a way in my program to get the texture coordinates, size and everything from each subtexture in the atlas, and when I render them as a non-9Slice it works great, the problem is the shader. If I try to run the engine with a subtexture from the atlas, the shader I posted before won't work, as it takes the whole texture as if it was a single one (which works on the previuos case but not this one). This is what happens when running with the shader:

Which make sense (don't mind the transparency not working). I know I have to change how the coordinates are calculated in the shader to be relative to the sub-texture coordinates, but I cannot really seem to understand how to do it, this is what I tried:

```
#version 330 core

in vec2 uv;
in vec4 color;
in vec2 size;
in vec4 nine_slice;

uniform sampler2D tex;
uniform float dt;
uniform vec2 mouse_position;
uniform vec2 texture_size; // If drawing a subtexture from an atlas, this is the size of the subtexture

layout(location = 0) out vec4 out_color;

vec2 uv9slice(vec2 _uv, vec2 _s, vec4 _b) {
    vec2 _t = clamp((_s * _uv - _b.xz) / (_s - _b.xz - _b.yw), 0.0, 1.0);
    vec2 _t_0 = _uv * _s;
    vec2 _t_1 = 1.0 - _s * (1.0 - _uv);
    return clamp(mix(_t_0, _t_1, _t), vec2(0, 0.75), vec2(0.25, 1.0));
}

vec4 draw_nine_slice() {
    vec2 _s = size.xy / texture_size;
    vec4 _b = nine_slice / texture_size.xxyy;
    vec2 _uv = uv9slice(uv, _s, _b);
    vec3 _col = vec3(texture(tex, _uv).x);
    return vec4(_col, 1.0);
}

void main(void) {
    out_color = draw_nine_slice()
}

```

Values are hardcoded in here, because I'm doing a test. Bottom-Left coord of the texture in the atlas is (0.0, 0.75) and Top-Right is (0.25, 1.0).

I thought clamping the values within the sub-texture range would work, but it does not. I tried also other combinations but noting seems to be working, does anyone have an idea on how to achieve the first behaviour with the single texture on the second scenario with an atlas?

Tried different ways to convert from whole image coordinates to a sub-space of the image, one of the attempts is in the description of the issue, no success with any of them.

# Answer
Figured it out guys, the shader is not as compact as the first one, but is working like a charm, with single textures and with atlas textures:

#version 330 core

in vec2 uv;
in vec4 color;
in vec2 size;
in vec4 nine_slice;
in vec4 sub_texture_uv;

uniform sampler2D tex;
uniform vec2 texture_size; // If drawing a subtexture from an atlas, this is the size of the subtexture

layout(location = 0) out vec4 out_color;

vec4 draw_nine_slice() {
    // This is just to make the image scale correctly
    vec2 _prop = vec2(sub_texture_uv.z - sub_texture_uv.x, sub_texture_uv.w - sub_texture_uv.y);

    // Point of start if sub-texture
    vec2 _ratio = (texture_size.xy / size.xy);
    vec2 _border = vec2(nine_slice.x, nine_slice.z);
    vec2 _border_custom_prop = (_border / size) * _prop;
    vec2 _border_original_prop = (_border / texture_size) * _prop;
    vec2 _texture_coord = vec2(0);
    vec2 _atlas_offset = vec2(0);

    //         x padding min   x padding max
    //               |            |
    //        *------*------------*------*
    //        |      |            |      |
    //        |  L/T |       M/T  |  R/T |
    //        |      |            |      |
    //      --*------*------------*------*-- y padding max
    //        |      |            |      |
    //        |  L/M |       M/M  |  R/M |
    //        |      |            |      |
    //      --*------*------------*------*-- y padding min
    //        |      |            |      |
    //        |  L/D |       M/D  |  R/D |
    //        |      |            |      |
    //        *------*------------*------*
    //               |            |

    // --------------------- X Axis
    // Left
    if(uv.x < sub_texture_uv.x + _border_custom_prop.x) {
        _texture_coord.x = (uv.x - sub_texture_uv.x) / _ratio.x;
        _atlas_offset.x = sub_texture_uv.x;
    }

    // Right
    else if(uv.x > (sub_texture_uv.z - _border_custom_prop.x)) {
        _texture_coord.x = (uv.x - sub_texture_uv.z) / _ratio.x;
        _atlas_offset.x = sub_texture_uv.z;
    }

    // Middle
    else {
        _texture_coord.x = uv.x + (_border_original_prop.x - _border_custom_prop.x);
        if(_texture_coord.x > sub_texture_uv.z - _border_original_prop.x) {
                _texture_coord.x = sub_texture_uv.z - _border_original_prop.x;
        }
    }

    // --------------------- Y Axis
    // Down
    if(uv.y < sub_texture_uv.y + _border_custom_prop.y) {
        _texture_coord.y = (uv.y - sub_texture_uv.y) / _ratio.y;
        _atlas_offset.y = sub_texture_uv.y;
    }

    // Up
    else if(uv.y > (sub_texture_uv.w - _border_custom_prop.y)) {
        _texture_coord.y = (uv.y - sub_texture_uv.w) / _ratio.y;
        _atlas_offset.y = sub_texture_uv.w;
    }

    // Middle
    else {
        _texture_coord.y = uv.y + _border_original_prop.y - _border_custom_prop.y;
        if(_texture_coord.y > sub_texture_uv.w - _border_original_prop.y) {
            _texture_coord.y = sub_texture_uv.w - _border_original_prop.y;
        }
    }

    vec4 _color = texture(tex, _texture_coord + _atlas_offset);
    if(_color.w < 0.05) {
            discard;
    }

    return texture(tex, _texture_coord + _atlas_offset) * vec4(color.x / 255.f, color.y / 255.f, color.z / 255.f, color.w / 255.f);
}

void main() {
    out_color = draw_nine_slice();
}
```

> 1 votes

---
Tags: opengl, glsl
---


# Question
Title: How to make sure my UI remains the same across multiple screens?
How to make sure my UI remains the same across multiple screens? I've looked at some tutorials, but they didn't seem to apply to my situation.

I tried the following, but they didn't resolve my problem:

* Various combinations in the window setting of Godot
* Making a scene with graphic options where you can resize the screen ratio

If I can manage to get the UI to not fly around every time I resize the screen I either face two other problems:

1. Making the screen smaller means the UI maintains its place but doesn't scale correctly, they stay in place.... but if the screen is; say reduced by like 50%, the UI is only reduced by like 25%, just giving random numbers cause I didn't measure it manually but visually the UI is clearly scaling at a different pace
2. This time the UI scales correctly and remains in place but resizing the screen gives black borders around the edges.... my screen is 1366x768.... my window settings say so and also my Nvidia settings say so, they aren't lying... but if I set this to be the screen size in Godot, I get black borders...

The dilemma is that I can only manage to get 2 out of following 3 things that I want:

1. The UI scaling properly
2. The UI maintaining its place
3. No black borders

How do I get all three?

I'm only showing the mininimap because changing resolutions requires me to rearrange every single piece of UI even if it is literally set to be anchored, it flies around in some screen sizes and even goes outside of the screen.

and here's the main menu, just to showcase how stupid the situation is

# Answer
There are a few concepts to address if you want to get the entire UI working smoothly.

**Black borders** \- The size of the screen ("game") in Godot is simply the size, in "units", of the visible area you have to work with in the editor. It is independent of the resolution that a player is playing the game at. If the player wants to play at a different aspect ratio than that of your screen size, you can control if they see "black bars" or something else by modifying your project's Stretch Settings. In particular, the stretch aspect will change whether or not the player sees black bars. Keep in mind that designing a game to work at an arbitrary aspect ratio can be *very difficult*, so you may want to assume a 16:9, 4:3, etc aspect ratio to make your life easier.

**Scaling** \- if you have your project's stretch aspect set to something other than "ignore", you will not have to worry about stretching, but you will have to worry about scaling. If you are using anchors (not containers), you'll want to make sure your anchors have a non-zero size (left≠right, top≠bottom), which will allow the anchored element to expand and contract at the same rate as the player's screen resolution. If you are using containers (not anchors), the scaling problem should already be solved, *provided* that your top-level container has its anchors set to a non-zero size. From the screenshots you provided, it looks like the anchor (if you are using them) for the minimap is set to a zero-size in the top-right corner - the anchor should instead have its bottom-left corner set somewhere towards the centre of the screen. NOTE: for **TextureRect**s specifically, you'll want to change the Expand Mode away from "Keep Size" - that will prevent your UI images from scaling.

**Placement** \- This is similar to the scaling problem. If you are using anchors, you typically want your anchors to be next to some fixed position (in your case, the edge of the screen). That way, you know your UI elements will always be relative to some fixed point. If you're using containers, this problem typically solves itself, because elements are always relative to their enclosing container. If an element is not properly positioned in a container, you likely want to change the container's settings or use a different type of container.

It is a bit hard to give specifics since we can't see your project, but I hope this helps.
> 3 votes

# Answer
To remove the black borders when you set the resolution to your screens size you need to get rid of the header at the top of the screen, if you go Fullscreen mode you'll find that the black borders are gone but you now need a way to exit Fullscreen mode when you want to exit your game as there are no close minimize of maximize buttons.

```
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
#sets fullscreen mode

DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
#sets window mode

```
> 0 votes

---
Tags: gui, godot, resolution, screen
---


# Question
Title: Help with calculating tangent/binormal in Vulkan fragment shader using GLSL
I need help understanding what am I doing wrong with transformation/calculation of tangents and binormals using GLSL. I'm using Willems' PBR demo shaders as a reference: https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/pbr.vert https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/pbr\_khr.frag

I start by programmatically generating a sphere with normals and texture coordinates as seen in this image:

The "light" is directly to the left (-10, 0, 0) and both texture coordinates and normals seem to be proper as per smooth gradient and appropriately wrapped texture

However the moment I try to add binormal and tangent into the equation using the "getNormals" code from fragment shader above - it all gets messed up, lit from improper direction, not evenly and blocky:

I tried to RenderDoc that PBR demo and the only big difference I see thus far is that he uses right handed system (Z is going backwards) whereas I'm using left-handed system (Z is forward) through GLM - but I'm not sure if that's what ruins calculations?

Do note that I'm using identity matrices so the only transformation that sphere encounters is projection\*view as vertex main output and identity as "world position" (worldPos) output because there are no world-level transformations happening to vertices themselves.

I then feed this worldPos together with texCoord and normal into getNormals() using the following code:

```
vec3 Q1 = dFdx(worldPos);
vec3 Q2 = dFdy(worldPos);
vec2 st1 = dFdx(texCoord);
vec2 st2 = dFdy(texCoord);

vec3 N = normalize(normal);
vec3 T = normalize(Q1 * st2.t - Q2 * st1.t);
vec3 B = -normalize(cross(N, T));

mat3 TBN = mat3(T, B, N);

return normalize(TBN * normal); // transform normal

```

and get that issue. Setting T and B to vec3(0.0) both returns the smooth shading back and the result is equal to just passing normal as return.

does it have anything to do with the coordinate system I'm using? E.g. X is right, Y is up, Z is forward, U is right, V is down?

any ideas or tips?

# Answer
I resolved it a long time ago, just wanted to post an answer. I was suffering by trying to "fix" the shader for an unexpected reason - an incorrect compression of a normal map using NVidia Texture Tools. It was messing up all the tangents causing a ton of graphical issues. Upon selecting a fitting compression the issue was resolved.
> 0 votes

---
Tags: c++, glsl, vulkan
---


# Question
Title: If I chose to make a game engine with GPL license, does anyone who build a project with it have to disclose the license or is that for distros only?
Title says it all, here are my concerns.

1. I want a copyleft license, but not at the cost of having to reveal private code in a game project.
2. I mostly just want to create a game engine that can serve as a 'base' that other developers can build distros with that may target different languages, platforms, runtimes etc etc.

I will likely be building my app with GTK and some language bindings, but those are my main concerns. Otherwise, If companies have to release their code with my engine, I would switch to something more permissive like Apache 2.0 If anyone can give me an in depth answer for someone who wants to do exclusively open source, please let me know! Thank you very much ahead of time!

Edit 1: So just to be clear, I am looking at GPL/LGPL but if game developers have to release their source code for their game, I would like an alternative. I am mostly just concerned about the GPL 'share source code' clause with new projects that build off my soon to be work.

**Edit 2** (IMPORTANT!): I love all the answers here everyone and I learned a lot! I decided to split my project into two licenses, and instead go with the more 'permissive' MPLv2 and LGPLv3. While all the answers were a great resource, be sure to do your own research on licensing! A great bit of helpful resources I found during this mission.

MPL compatibility: https://www.fsf.org/blogs/licensing/mpl-2.0-release General License List: https://www.gnu.org/licenses/license-list.html

And of course, the MPL license itself: https://www.mozilla.org/en-US/MPL/2.0/FAQ/

As noted by the highlighted answer, none of us (including me) is a lawyer. Be skeptical but also inquisitive.

Thank you all so much!

# Answer
> 18 votes
*I'm not a lawyer, this is not legal advice.*

When you make a model in Blender, despite blender being under GPL, the model is not. Similarly when you make a program with GCC, despite GCC being under GPL, the program is not. This is because the model and the program, do not include any part of the code of Blender or GCC respectively... **But that is not how game engines work.**

To be able to properly answer this question I need to define Game Engine, game development and game development framework.

For the purposes of this answer, I'll define them like this:

* A game development library, is a library intended to be used by game developers as a part of their game.
* A game development framework, is also a library, which also covers most of the needs of game development and provides extension points for the game specific code to be added.
* A game engine is *at least* a few components:

+ An executable runtime, which is what actually make the games run.
    + An authoring tool (game development environment or editor) which is used to create games.
    + A building tool, which converts the projects made with the authoring tool into the final game (which uses the executable runtime).

*I'd argue that what makes engine the engine is the executable runtime. **Addendum**: I'm not trying to define what features you would expect an engine to have, but what is the bare minimum to make the category.*

Now, while the final game created with a game engine would likely not include any code from the authoring tool, or the building tool, but it would include the runtime. And so we have to consider the license of the runtime when licensing the games. So let us talk about the runtime...

The game engine runtimes are not libraries, so (unlike game development libraries and frameworks) they provide the entry point. Also (unlike game development libraries, but similarly to frameworks) they have extension points where code created by the game authors can execute. This means that the code of the game is a plugin to the game engine, and not the other way around.

So if the final executable of the game includes the runtime (it is bundled in the same program), we can consider the games created with a game engine to be derived software to the game engine runtime, meaning that licenses such as GPL which apply to derived software (a.k.a. viral licenses) would carry from the game engine to the game.

One possible way to work around this is to create the games as a separate package (including scripts and other assets), which the runtime loads. This way the package can be under a license unrelated to the runtime. **Addendum**: While I frame this is a workaround for copyleft, this is how many non-copyleft game engines work, both open source and closed source.

*Notice that the mentioned package would have to be created in a standard format for the runtime to load it, and if said runtime is open source, the code to load said package is open source. Thus, the code of the game is practically revealed regardless. Similarly, we can argue that whatever runs on the end machine could be reverse engineered anyway (given enough time, effort and resources). But not necessarily legally.*

It is also worth noting that LGPL might allow developers to use the code as a library... Which means that to allow game developers to use any license on their game, you might make your code as a library under LGPL that game developers can include with their code... Meaning that it would be closer to a game development framework than to an game engine.

*Of course, if the definitions used in this answer do not align with the software you have you have in mind, I hope at least to have given you a working model to reason about this.*

*Be aware that this answer is not a replacement to reading the aforementioned licenses or asking a lawyer.*

---

**Addendum on adding an exception to GPL**: I agree that parts of the code can be exempt from the license. However, the way I read the question the exception would have to be based on usage (using it for creating game vs using it for creating game engines). I want to reiterate that I'm not a lawyer to emphasize that I do know if such exception would be compatible with GPL. Please hire a lawyer instead of relying on comments on the internet alleging it to be possible or not.

# Answer
> 8 votes
It depends. The Open Source Stack Exchange has a question about GPL game engines and an answer that address some of your questions (emphasis is my own):

> A game engine has properties similar to both these cases. The input and output of the game engine (e.g. models, textures, rendered frames) are not subject to the GPL. The output (e.g. screenshots of a rendered scene) may be subject to the GPL if it shows GPL-licensed assets or other media that were somehow generated by the engine authors. (A similar case is discussed in the GPL FAQ here and here: “Keep in mind that some programs, particularly video games, can have artwork/audio that is licensed separately from the underlying GPLed game.”)
>
> Scripts executed by the game engine would usually be subject to the GPL because they will call into APIs provided by the game engine. **This can be avoided if the authors of the game engine explicitly issue an exception to the GPL requirements. The GPLv3 includes a specific, well-defined mechanism for issuing exceptions to the GPL.** The LGPLv3 license is in fact implemented as such an exception. As an alternative, the game engine can offer merely a language and not an API. This is in many cases entirely sufficient, but could mean that the engine implements its own domain-specific language, rather than adding APIs to a known scripting language such as Lua or Python.

So my read of that is a *carefully worded* GPL license could cover the engine and changes in a strong copyleft manner (meaning if someone else used the engine code to make a variant engine, that engine would be subject to GPL) but would not automatically subject games made with the engine to GPL. Because of the potential complexity, I would strong recommend working with a legal professional with experience in licensing to craft it.

The id Tech 4 (also known as the Doom 3 engine) might be a good example how you might use the GPL as you described. It's licensed under the terms of the GNU General Public License v3.0 or later and here's an excerpt from their (now archived) licensing page:

> **D. You keep it!**
> You get to keep the technology you create. We do not ask for your proprietary technology - which stifles innovation and creativity. If another of our licensees likes something that you come up with, we allow you to license your innovations to them (certain restrictions apply pertaining to id Software maintaining its proprietary interest in the underlying engine technology). This allows licensees to build equity within their own modified engine, which they can license out or keep to themselves for use in future licensed titles.

There are a number of Id Tech 4 games using proprietary licenses. This demonstrates that it is possible to put a game engine out with GPL, but force GPL on games built using that engine.

# Answer
> 4 votes
Normally the way you do this, **and make a living**, is to license your engine under very tight copyleft (GPL or even AGPL), but retain full copyright yourself (either don't accept third party contributions, or only accept contributions under a CLA or copyright assignment) and **offer alternative commercial license** to anyone who wants to pay to use it in a game. Then, anyone making free games (or commercial games they're willing to accept the terms of the GPL for) gets to use your engine at no cost, while commercial users who want the privilege of keeping their source closed while they take advantage of you have to fairly compensate you for getting to profit off your work.

# Answer
> 1 votes
Instead of the GNU GPL or LGPL, you can use the Mozilla Public License 2 or Eclipse Public License 2. These only require you to publish changes to the source files under that license (the engine, in this case), rather than requiring you to open source the entire software/game.

---
Tags: licensing
---