# Question
Title: How do I detect collisions with a circle sector against basic geometry?
For the 2D game that I'm building, I want some entities to be able to use areas of attack, such as a wedge/circle sector area of attack.

In this case, the circle sector is a pie-slice shaped section of a circle defined by:

* The circle centre coordinates
* The circle radius
* The angle of the slice's centre
* The angle size of the slice

With this information, I can easily detect if a point is contained inside the sector.

However, I want to test for collisions with:

* Other circle sectors
* Circles (2D)
* Rectangles (2D)

How can I do this?

# Answer
> 0 votes
I believe I may have an answer, though please do point out if I'm incorrect. I'll be pasting my answers in TypeScript, leaving out the basic functions that you can find pretty easily on the web.

## Wedge-Circle Collision

This appears to be the simplest. Already knowing how to make two circles collide (test their distances from one another is less than the two radiuses), we want to do a similar test for a wedge and a circle, and then determine if the point of collision is inside the wedge:

```
export function wedgeAndCircleCollide(
  wedge: BoundingWedge,
  circle: BoundingCircle,
): boolean {
  if (!circlesCollide(
    boundingCircleFromWedge(wedge),
    circle,
  )) {
    return false
  }

  // Determine the collision angle between the two circles for
  // the wedge
  const wedgeCollisionAngle = pointAngle(
    wedge.center,
    circle.center,
  )

  // Return whether the angle of collision is within the wedge's
  // angles
  return angleInRange(wedgeCollisionAngle, wedge.directionAngle, wedge.widthAngle)
}

```

## Wedge-Wedge Collision

Similarly, wedge-wedge collision adds a second step of testing if that angle is in the range of the second wedge as well:

```
export function wedgesCollide(bw1: BoundingWedge, bw2: BoundingWedge): boolean {
  if (!circlesCollide(
    boundingCircleFromWedge(bw1),
    boundingCircleFromWedge(bw2),
  )) {
    return false
  }

  // Determine the collision angle between the two circles for...
  //  ...wedge 1
  const w1CollisionAngle = pointAngle(
    bw1.center,
    bw2.center,
  )

  // ...wedge 2
  const w2CollisionAngle = pointAngle(
    bw2.center,
    bw1.center,
  )

  // If the collision angle for wedge 1 is within wedge 1's
  // angle, mark it down
  const collisionInW1 = angleInRange(w1CollisionAngle, bw1.directionAngle, bw1.widthAngle)

  // If the collision angle for wedge 2 is within wedge 2's
  // angle, mark it down
  const collisionInW2 = angleInRange(w2CollisionAngle, bw2.directionAngle, bw2.widthAngle)

  // Return whether the collision is in both wedge 1 and wedge 2
  return collisionInW1 && collisionInW2
}

```

## Box-Wedge Collision

This is by far the most complicated.

The main function goes something like:

```
export function wedgeAndBoxCollide(wedge: BoundingWedge, box: BoundingBox) {
  const circleFromWedge = boundingCircleFromWedge(wedge)

  // Cheap check:
  // Check that the circle is inside the rectangle. If so,
  // return true
  if (boundingCircleInBox(circleFromWedge, box)) {
    return true
  }

  const boxCentreX = box.x + (box.width / 2)
  const boxCentreY = box.y + (box height / 2)

  const topLeft: PointTuple = [box.x, box.y]
  const bottomLeft: PointTuple = [box.x, box.y + box.height]
  const topRight: PointTuple = [box.x + box.width, box.y]
  const bottomRight: PointTuple = [box.x + box.width, box.y + box.height]

  const closestHorizontalWall: LineTuple = wedge.center.x <= boxCentreX
    ? [topLeft, bottomLeft]
    : [topRight, bottomRight]

  const closestVerticallWall: LineTuple = wedge.center.y <= boxCentreY
    ? [topLeft, topRight]
    : [bottomLeft, bottomRight]

  // Check the two most relevant walls. If there's a collision,
  // return true
  return wedgeCollidesWithLine(closestHorizontalWall, wedge) ||
    wedgeCollidesWithLine(closestVerticallWall, wedge)
}

```

where `wedgeCollidesWithLine()` looks like:

```
export function wedgeCollidesWithLine(
  line: LineTuple,
  wedge: BoundingWedge,
): boolean {
  const safeDirectionAngle = getSafeAngle(wedge.directionAngle)
  const wedgeHalfAngle = getSafeAngle(wedge.widthAngle) / 2

  if (
    pointInWedge(line[0], wedge) ||
    pointInWedge(line[1], wedge)
  ) {
    return true
  }

  const lineSlope = getSlope(line)
  // y = mx + b
  // b = -mx + y
  const perpendicularLineIntercept = (lineSlope * wedge.center.x * -1) + wedge.center.y
  const perpendicularX = wedge.center.x + 10
  const perpendicularY = (lineSlope * perpendicularX) + perpendicularLineIntercept

  // Point-angle to box edge
  // Return true if in wedge
  const centreToLineIntersectionPoint = getLineIntersectionPoint(
    [ wedge.center, [perpendicularX, perpendicularY] ],
    line,
  )

  // If the distance from the line to the wedge circle
  // is greater than the radius length, there's not going
  // to be an intersection
  if (
    pointDistance(
      wedge.center,
      centreToLineIntersectionPoint,
    ) > wedgeRadius
  ) {
    return false
  }

  if (pointInWedge(centreToLineIntersectionPoint, wedge)) {
    return true
  }

  const safeLeftBound = getSafeAngle(safeDirectionAngle - wedgeHalfAngle)
  const safeRightBound = getSafeAngle(safeDirectionAngle + wedgeHalfAngle)
  // Get intersection by wedge bounds
  // Is it in the given line?
  const leftEdgePoint: PointTuple = [
    wedge.center.x + getLengthDirX(
      safeLeftBound,
      wedge.radius,
    ),
    wedge.center.y + getLengthDirY(
      safeLeftBound,
      wedge.radius,
    ),
  ]
  const leftIntersectionPoint = getLineIntersectionPoint(
    [wedgeCentre, leftEdgePoint],
    line,
  )

  const rightEdgePoint: PointTuple = [
    wedge.center.x + getLengthDirX(
      safeRightBound,
      wedge.radius,
    ),
    wedge.center.y + getLengthDirY(
      safeRightBound,
      wedge.radius,
    ),
  ]
  const rightIntersectionPoint = getLineIntersectionPoint(
    [wedgeCenter, rightEdgePoint],
    line,
  )

  // Check if the intersections with the wedge bounds
  // are within the wedge: if not, the wedge is not facing
  // the line, and thus no collision occurs
  return pointInWedge(leftIntersectionPoint, wedge) ||
    pointInWedge(rightIntersectionPoint, wedge)
}

```

The idea here being:

* If there's a collision with a corner, it's a collision
* For each relevant edge:
    + Get the distance to the edge
    + Get the point-angle between the wedge and the box edge
    + Determine if the line from the wedge to the edge is in the wedge
    + If not, extend the "wings" of the wedge, and see if they collide with the line at all. If they do, determine if that collision is inside the wedge bounds.

# Answer
> -1 votes
I have used this method when I want to my Enemy attack my Player when the Player go into the Enemy's attack area.

```
using UnityEngine;

public class EnemyCombat : EnemyCombat
{
    public Transform attackPoint;
    public float attackRange;
    private Collider2D[] hitPlayer;
    public LayerMask playerLayer;
    // Starthas Attackedbefore the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        Attack_FollowCharacter();
    }
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(attackPoint.position, attackRange);   //Use need to use this to visually the area, for this it will draw a circle with the attackPoint is the center of the circle
    }
    private void Attack_FollowCharacter()
    {
            hitPlayer = Physics2D.OverlapCircleAll(attackPoint.position, attackRange, playerLayer);  //Check the Player if they go into attack area
            foreach (Collider2D player in hitPlayer)
            {
                 //Write your code if Player went into
            }
   }

```

If anything hard to understand few free to respond

---
Tags: 2d, collision-detection, geometry
---


# Question
Title: How to achieve uniform speed of movement on a bezier curve?
I'm trying to move an image along Bezier curve. This is how I do it:

```
- (void)startFly
{
 [self runAction:[CCSequence actions:
             [CCBezierBy actionWithDuration:timeFlying bezier:[self getPathWithDirection:currentDirection]],
             [CCCallFuncN actionWithTarget:self selector:@selector(endFly)],
             nil]];

}

```

My issue is that the image moves not uniformly. In the beginning it's moving slowly and then it accelerates gradually and at the end it's moving really fast. What should I do to get rid of this acceleration?

# Answer
> 32 votes
It is possible to approximate a solution to this problem for most parametric trajectories. The idea is the following: if you zoom deep enough on a curve, you cannot tell the curve itself from its tangent at that point.

By making this assumption, there is no need to precompute anything more than two vectors (three for cubic Bezier curves, *etc.*).

So for a curve \\$M(t)\\$ we compute its tangent vector \\$\frac{dM}{dt}\\$ at point \\$t\\$. The norm of this vector is \\$\lVert \frac{dM}{dT} \rVert\\$ and thus the distance traveled for a duration \\$\Delta t\\$ can be approximated as \\$\lVert \frac{dM}{dT} \rVert \Delta t \\$. It follows that a distance \\$L\\$ is traveled for a duration \\$L \div \lVert \frac{dM}{dT} \rVert\\$.

### Application: quadratic Bezier curve

If the control points of the Bezier curve are \\$A\\$, \\$B\\$ and \\$C\\$, the trajectory can be expressed as:

$$ \begin{align} M(t) &= (1-t)^2A + 2t(1-t)B + t^2C \\ &= t^2(A - 2B + C) + t(-2A + 2B) + A \end{align} $$

So the derivative is:

$$ \frac{dM}{dt} = t(2A - 4B + 2C) + (-2A + 2B) $$

You just need to store vectors \\$\vec v\_1 = 2A - 4B + 2C\\$ and \\$\vec v\_2 = -2A + 2B\\$ somewhere. Then, for a given \\$t\\$, if you want to advance of a length \\$L\\$, you do:

$$ t = t + {L \over length(t \cdot \vec v\_1 + \vec v\_2)} $$

### Cubic Bezier curves

The same reasoning applies to a curve with four control points \\$A\\$, \\$B\\$, \\$C\\$ and \\$D\\$:

$$ \begin{align} M(t) &= (1-t)^3A + 3t(1-t)^2B + 3t^2(1-t)C + t^3D \\ &= t^3(-A + 3B - 3C + D) + t^2(3A - 6B + 3C) + t(-3A + 3B) + A \end{align} $$

The derivative is:

$$ \frac{dM}{dt} = t^2(-3A + 9B - 9C + 3D) + t(6A - 12B + 6C) + (-3A + 3B) $$

We precompute the three vectors:

$$ \begin{align} \vec v\_1 &= -3A + 9B - 9C + 3D \\ \vec v\_2 &= 6A - 12B + 6C \\ \vec v\_3 &= -3A + 3B \end{align} $$

and the final formula is:

$$ t = t + {L \over length(t^2 \cdot \vec v\_1 + t \cdot \vec v\_2 + \vec v\_3)} $$

### Accuracy issues

If you are running at a reasonable framerate, \\$L\\$ (which should be computed according to the frame duration) will be sufficiently small for the approximation to work.

However, you may experience inaccuracies in extreme cases. If \\$L\\$ is too large, you can do the computation piecewise, for instance using 10 parts:

```
for (int i = 0; i < 10; i++)
    t = t + (L / 10) / length(t * v1 + v2);

```

# Answer
> 6 votes
You need to reparamaterize the curve. The easiest way to do this is to calculate the arc lengths of several segments of the curve and use these to figure out where you should sample from. For example, maybe at t=0.5 (halfway through), you should pass s=0.7 to the curve to get the "halfway" position. You need to store a list of arc lengths of various curve segments to do this.

There are probably better ways, but here's some very simple C# code I wrote to do this in my game. It should be easy to port to Objective C:

```
public sealed class CurveMap<TCurve> where TCurve : struct, ICurve
{
    private readonly float[] _arcLengths;
    private readonly float _ratio;
    public float length { get; private set; }
    public TCurve curve { get; private set; }
    public bool isSet { get { return !length.isNaN(); } }
    public int resolution { get { return _arcLengths.Length; } }

    public CurveMap(int resolution)
    {
        _arcLengths = new float[resolution];
        _ratio = 1f / resolution;
        length = float.NaN;
    }

    public void set(TCurve c)
    {
        curve = c;
        Vector2 o = c.sample(0);
        float ox = o.X;
        float oy = o.Y;
        float clen = 0;
        int nSamples = _arcLengths.Length;
        for(int i = 0; i < nSamples; i++)
        {
            float t = (i + 1) * _ratio;
            Vector2 p = c.sample(t);
            float dx = ox - p.X;
            float dy = oy - p.Y;
            clen += (dx * dx + dy * dy).sqrt();
            _arcLengths[i] = clen;
            ox = p.X;
            oy = p.Y;
        }
        length = clen;
    }

    public Vector2 sample(float u)
    {
        if(u <= 0) return curve.sample(0);
        if(u >= 1) return curve.sample(1);

        int index = 0;
        int low = 0;
        int high = resolution - 1;
        float target = u * length;
        float found = float.NaN;

        // Binary search to find largest value <= target
        while(low < high)
        {
            index = (low + high) / 2;
            found = _arcLengths[index];
            if (found < target)
                low = index + 1;
            else
                high = index;
        }

        // If the value we found is greater than the target value, retreat
        if (found > target)
            index--;

        if(index < 0) return curve.sample(0);
        if(index >= resolution - 1) return curve.sample(1);

        // Linear interpolation for index
        float min = _arcLengths[index];
        float max = _arcLengths[index + 1];
        Debug.Assert(min <= target && max >= target);
        float interp = (target - min) / (max - min);
        Debug.Assert(interp >= 0 && interp <= 1);
        return curve.sample((index + interp + 1) * _ratio);
    }
}

```

**Edit:** It's worth noting that this won't give you the exact arc length, since it's impossible to get the arc length of a cubic curve. All this does is estimate the length of the various segments. Depending on how long the curve is, you may need to increase the resolution to prevent it from changing speeds when it reaches a new segment. I usually use ~100, which I have never had a problem with.

# Answer
> 2 votes
A very lightweight solution is to approximate the speed rather than approximating the curve. Actually this approach is independent of the curve function and enables you to use any exact curve instead of using derivatives or approximations.

Here is the code for C# Unity 3D:

```
public float speed; // target linear speed

// determine an initial value by checking where speedFactor converges
float speedFactor = speed / 10;

float targetStepSize = speed / 60f; // divide by fixedUpdate frame rate
float lastStepSize;

void Update ()
{
    // Take a note of your previous position.
    Vector3 previousPosition = transform.position;

    // Advance on the curve to the next t;
    transform.position = BezierOrOtherCurveFunction(p0, p1, ..., t);

    // Measure your movement length
    lastStepSize = Vector3.Magnitude(transform.position - previousPosition);

    // Accelerate or decelerate according to your latest step size.
    if (lastStepSize < targetStepSize)
    {
        speedFactor *= 1.1f;
    }
    else
    {
        speedFactor *= 0.9f;
    }

    t += speedFactor * Time.deltaTime;
}

```

Although the solution is independent of the curve function, I wanted to note it here as I was also looking for how to achieve constant speed on a Bezier curve, and then I come up with this solution. Considering the popularity of the function this may be helpful here.

# Answer
> 1 votes
There is a great answer from sam hocevar. However my very first naive attempt was to approximate `t` value while moving along curve with small iterations like in unity when we execute our calculations ones per frame with small delta time.

Things we know:

* Current moving progress as parameter \\$t\_0\in\[0;1\]\\$
* Current position \\$p\_0\\$
* Curve arc length \\$l\\$
* Distance \\$d\\$ which we want translate with on curve from position at \\$t\_0\\$

Now we can evaluate our naive \\$t\_1\\$ which brings us to the problem of uneven speed $$ t\_1 = t\_0 + d / l $$ And also calculate naive point on curve \\$p\_1\\$ (hope there is enough info about getting point on bezier curves)

We still remember that we actually want move only by \\$d\\$, so we can evaluate how \\$d\\$ differ from distance between \\$p\_0\\$ and \\$p\_1\\$ $$t\_d = d / distance(p\_0, p\_1) $$

And then by this value I've attempt to lerp between \\$t\_0\\$ and \\$t\_1\\$ $$ t = Lerp(t\_0, t\_1, t\_d) $$ and result is where on curve we should be by translating from \\$p\_0\\$ by \\$d\\$ distance.

Surprisingly works like mentioned solution but without storing any additional values. Though I'm not sure I did the same but with more calculations in between.

# Answer
> -3 votes
I don't know anything about cocos2, but a bezier curve is a kind of parametric equation, so you should be able to get your x and y values in terms of time.

---
Tags: ios, cocos2d-iphone, objective-c
---


# Question
Title: Unwanted darkening at polygon edges when using normal maps with SSAO
I'm using a SSAO alghorithm called "SAO", seen here: Scalable Ambient Obscurance.

I'm currently having issues with "smooth" normals, for example when using normal/height maps.

To give an example, here is the SAO and the normals for a chair rendered with "raw" normals, i.e not using the accompanied normal map:

Looks pretty OK overall.

now.. when I apply the chair's normal map:

What could be wrong? Is there anything obvious wrong with the normals?

I'm using the SAO shader, with only very minor changes. The normal/position textures are in world space, and then converted to view space. I know this is not optimal, but for the sake of the alghorithm it should not matter.

```
#ifndef SSAO_PIXEL_HLSL
#define SSAO_PIXEL_HLSL

#include "Constants.h"
#include "Common.hlsl"

static const float gNumSamples = 11.0;
static const float gRadius = 0.2;
static const float gRadius2 = gRadius * gRadius;
static const float gProjScale = 500.0;
static const float gNumSpiralTurns = 7;
static const float gBias = 0.01;
static const float gIntensity = 1.0;

cbuffer SSAOCBuffer : register(CBUFFER_REGISTER_PIXEL)
{
    float4x4 gViewProjMatrix;
    float4x4 gProjMatrix;
    float4x4 gViewMatrix;
    float2 gScreenSize;
};

Texture2D gPositionTexture : register(TEXTURE_REGISTER_POSITION);
Texture2D gNormalTexture : register(TEXTURE_REGISTER_NORMAL);
SamplerState gPointSampler : register(SAMPLER_REGISTER_POINT);

float3 reconstructNormal(float3 positionWorldSpace)
{
    return normalize(cross(ddx(positionWorldSpace), ddy(positionWorldSpace)));
}

/** Read the camera - space position of the point at screen - space pixel ssP + unitOffset * ssR.Assumes length(unitOffset) == 1 */
float3 getOffsetPosition(int2 ssC, float2 unitOffset, float ssR) {
    // Derivation:
    //  mipLevel = floor(log(ssR / MAX_OFFSET));

    // TODO: mip levels
    int mipLevel = 0; //TODO: clamp((int)floor(log2(ssR)) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL);

    int2 ssP = int2(ssR*unitOffset) + ssC;

    float3 P = gPositionTexture[ssP].xyz;

    P = mul(gViewMatrix, float4(P, 1.0)).xyz;

    return P;
}

float2 tapLocation(int sampleNumber, float spinAngle, out float ssR)
{
    // Radius relative to ssR
    float alpha = float(sampleNumber + 0.5) * (1.0 / gNumSamples);
    float angle = alpha * (gNumSpiralTurns * 6.28) + spinAngle;

    ssR = alpha;
    return float2(cos(angle), sin(angle));
}

float sampleAO(uint2 screenSpacePos, float3 originPos, float3 normal, float ssDiskRadius, int tapIndex, float randomPatternRotationAngle)
{
    float ssR;
    float2 unitOffset = tapLocation(tapIndex, randomPatternRotationAngle, ssR);
    ssR *= ssDiskRadius;

    // The occluding point in camera space
    float3 Q = getOffsetPosition(screenSpacePos, unitOffset, ssR);

    float3 v = Q - originPos;

    float vv = dot(v, v);
    float vn = dot(v, normal);

    const float epsilon = 0.01;
    float f = max(gRadius2 - vv, 0.0);

    return f * f * f * max((vn - gBias) / (epsilon + vv), 0.0);
}

float4 ps_main(float4 position : SV_Position) : SV_Target0
{
    uint2 screenSpacePos = (uint2)position.xy;

    float3 originPos = gPositionTexture[screenSpacePos].xyz;
    originPos = mul(gViewMatrix, float4(originPos, 1.0)).xyz;
    float3 normal = gNormalTexture[screenSpacePos].xyz;//reconstructNormal(originPos);
    normal = mul(gViewMatrix, float4(normal, 0.0)).xyz;

    // Hash function used in the HPG12 AlchemyAO paper
    float randomPatternRotationAngle = (3 * screenSpacePos.x ^ screenSpacePos.y + screenSpacePos.x * screenSpacePos.y) * 10;
    float ssDiskRadius = -gProjScale * gRadius / originPos.z;

    float ao = 0.0;
    for (int i = 0; i < gNumSamples; i++)
    {
        ao += sampleAO(screenSpacePos, originPos, normal, ssDiskRadius, i, randomPatternRotationAngle);
    }

    float temp = gRadius2 * gRadius;
    ao /= temp * temp;

    float A = max(0.0, 1.0 - ao * gIntensity * (5.0 / gNumSamples));

    return A;
}

#endif

```

EDIT: update, using reconstructNormals() to reconstruct normals - for simpler models it looks okay (the chair) but the more advanced models like the alien looks really bad/blocky. Any way to fix this?

# Answer
> 0 votes
I'm not the expert to answer this question, but perhaps:

Points on your detailed normal map are skewing some of your offset samples back into the geometry?

The details on your normal map contain dark spots/crevices, which are being read by the shader as corners?

---
Tags: directx, hlsl, ssao
---


# Question
Title: How to use unconventional texture format
I would like to use a texture that could have more than 4 channels.

I have seen a post where they use a single channel R8 texture to store string chars. I'm thinking of using something like that with width = TextureSizeX * n where n is my number of channel and texturesizeX the size of the screen for instance.

Then I'm planning to use texture.load instruction to get the data. In the case of data stored in 5 bytes channels (e.g. RGBAX), I'm considering Input.texCoord.x * 5 * ScreenSize + (0 or 1 or 2 or 3 or 4) as UV coord x parameter to recover the 5 data sequentially. Will this work?

I have also seen that we can use RWByteAddressBuffer that has load, load2 load3 and load4 functions. Will it be better? The idea here is that for my 5 bytes channel I could use load3 to have part of the data as uint3 and load2 for the rest as uint2 that will be ok for my needs.

This is for Directx11 HLSL SM5

# Answer
> 1 votes
Here my procedure for using multiple subcolor in one resource.

Why this : to create 4 layers of data (color, normal, depth) for a deferred lighting to be used in a screen space reflection pipeline when having only 8 rendertargets available.

1 ) Create resources compatible for being used as either UAV/SRV/RTV. Given a screen size of SCREENX and SCREENY, create the three resources with SCREENX\*4 size as we will store 4 interleaved data in the X axis.

Color as RGBA8 used as UAV/RTV (and SRV in SSR)

Normal as RG8 used as UAV/SRV (I’m using viewspace normal so Z is always negative and calculated back with NZ = srqt(dot(NXY,NXY))-1;

Depth R16 in my demo. Used as UAV/SRV

2 Generating the layers

Clear everything

OMSetRenderTargetAndUnorderedAccessViews(0,NULL,DepthStencil, 0, 3, UAVs, 0);//Note use of regular Depthstencil buffer for using \[earlydepthstencil\] in the PS.

Render the scene

In the shader Set the three UAV as resources to be modified in u0, u1, u2

In the ps shader I’ musing a selective UAV write to draw an object if it is visible in the corresponding layer. This is in a mesh buffer constant as float4 Vislay.x-w for layers 0-3. Vislay.x is always 1 in fact.

```
 float4 Color = calculate the pixel color;
 float3 Normal = calculate your normal;
 float Depth = input.pos.z;
 float2 uUV = Input.Pos.xy*float2(4,1);//get screen coordinate where to write for the first subdata. Remember we have 4 subdata to write so multiply x by 4.

```

In my app the first layer contains all objects, the other layers only objects visible in these layers if they are occluded once, twice or more than twice (stored in Vislay). So it is the same color as the whole image that will go to the selected layer (if any).

```
uavColorRGBA[uUV] = Color;
uavNormalRG[uUV] = Normal.rg;
uavDepthR[uUV] = Depth;
uUV.x++;
if ( VisLay.y )
{
    uavColorRGBA[uUV] = Color;
    uavNormalRG[uUV] = Normal.xy;
    uavDepthR[uUV] = Depth;
}
uUV.x++;
if ( VisLay.z )
{
    uavColorRGBA[uUV] = Color;
    uavNormalRG[uUV] = Normal.xy;
    uavDepthR[uUV] = Depth;
}
uUV.x++;
if ( VisLay.w )
{
    uavColorRGBA[uUV] = Color;
    uavNormalRG[uUV] = Normal.xy;
    uavDepthR[uUV] = Depth;
}

```

NOTE : you can do some depth peeling by changing the if ( Vislay ) statements ) by if ( Depth\>X)&&(Depth\<=Y) where X and Y are the limit of the current min and max Depth you want in the current layer. I have tested this as well. The problem is for objects too close to each other where my first method do better and is independant of depth of objects.

3 The lighting pass

Set the UAV color as regular rendertarget. Set the Normal and Depth UAVs as SRVs for the pixel shader.

```
OMSetRenderTargets(1, &uavColorRGBAasRTV, NULL);
PSSetShaderResources(4, 1, & uavNormalRGasSRV);//slot 4 and 8 in my app
PSSetShaderResources(8, 1, & uavDepthRasSRV);

```

Set the viewport to be SCREENX\*4 instead of SCREENX.

Render to a screen quad

Restore normal viewport if needed.

In the pixel shader, use a regular deferred lighting process. Here I’m combining the outputted light color (with shadows) with the target color in the blending stage.

```
float4 PS_PostDeferred(PS_INPUTQUAD Input) : SV_TARGET0
{
  float2 uUV = Input.Tex.xy*float2(SM_SCREENX4,SM_SCREENY);
  float Depth = txDepthR.Load(uint3(uUV,0)).r;
  if ( Depth==1) return float4(1,1,1,1);
  float3 Normal = txNormal0.Load(uint3(uUV, 0)).rgg;
  return GetLColor(Depth, Input.Tex, Normal);//Normal.xy to xyz in the GetLColor function
}

```

The whole result is below. Upper panels are : colors in the 4 layers, then normals, then normal for the plane to use for SSR (same 4 views), ZBuffer (same 4 views) , Depth in layers as R, G, B and white colors.

All this works fine but I have to admit that it is slower than regular rendertargets with the use of UAV having an intrinsic performance cost. Maybe someone will have a clever idea to exploit some UAV store instruction I'm not used of.

# Answer
> 0 votes
Your strategy will work, but is somewhat inefficient.

Each texture sample has some overhead, so you generally want each one to do as much work for you as it can. Using 5 samples to get 5 numbers gives us the least return on investment we can get. The `RWByteAddressBuffer` does better in terms of samples, but you lose benefits of texture sampling like filtering or reading from compressed formats, and I don't know if its caching performance differs.

I suspect you'll see better performance if you instead split this logical 5-channel texture into two stored textures: one RGB and one RG, both with the actual native dimensions you want (no 5x + i adjustment). Then you sample each one once (2 samples total) to get your 5 numbers, using the most simple addressing pattern that GPUs have been optimized to serve. This cuts down the number of sample requests (and the number of texture cache entries) by half. You can scale this up to 8 channels if you up the two textures to RGBA, and beyond by adding a third texture, etc.

Doing it this way also means that you can use built-in texture filtering or texture compression, if applicable to your use case. For instance, if two of your values are quite correlated or need lower precision than the other 3, you can store them in the RG texture in a compressed format to make more efficient use of the available video memory and texture bandwidth.

A good comparison here is G-buffers used for deferred shading, which also use this "multiple textures" approach rather than interleaving the extra channels in consecutive indices of a wider texture or byte buffer. It's easier to render into this format if you need to update the contents of the super-channel textures dynamically, while the interleaved formats need some more exotic solutions.

As always, the best way to know what performs best for your situation is to build a test and profile it. Something that's "usually faster" can still be slower for a specific situation because it's depending on a resource that's already over-taxed by something else in your scene - it all depends where your bottlenecks are, so profile to be sure.

---
Tags: textures, directx11, hlsl, format
---


# Question
Title: CharacterBody3D gravity isn't working, and player won't touch the floor
I'm trying to create an isometric game with *Diablo-like* control, but gravity isn't working. The CharacterBody3D won't touch the floor, the print(is\_on\_floor()) always results false.

Here's my code for **PlayerCapsule.gd**

```
extends ActorPlayable3D
class_name PlayerCapsule

var navigationAgent3D

func _ready():
    navigationAgent3D = get_node(navigationAgent)

func _physics_process(delta):
    velocity.y -= gravity * delta
    if navigationAgent3D.is_navigation_finished():
        return

    var movement_delta = speed * delta
    var next_path_position: Vector3 = navigationAgent3D.get_next_path_position()
    var current_agent_position: Vector3 = global_position
    var new_velocity: Vector3 = (next_path_position - current_agent_position).normalized() * speed
    if navigationAgent3D.avoidance_enabled:
        navigationAgent3D.set_velocity(new_velocity)
    else:
        _on_navigation_agent_3d_velocity_computed(new_velocity)

func setNavigationAgentToLocation(pos: Vector3):
    navigationAgent3D.set_target_position(pos)

func _on_navigation_agent_3d_velocity_computed(safe_velocity):
    velocity = safe_velocity
    print(safe_velocity)
    print(is_on_floor())
    move_and_slide()

```

And here's the **ActorPlayable3D.gd**

```
extends CharacterBody3D
class_name ActorPlayable3D

@export var speed: float = 5.0
@export var navigationAgent: NodePath

var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")

class Navigation:
    func setNavigationAgent(node: NavigationAgent3D) -> void:
        pass

```

And here's the image result of the output, and playable scene:

How can I fix the gravity and make the player touch the floor?

# Answer
For `is_on_floor` to return true, the body needs to be moving (e.g. `move_and_slide` was called) against a floor (e.g. with gravity applied).

But the next position according to navigation is not below the ground, so the new velocity you compute is not going to downwards. And thus, the body would not be falling.

Ergo, you need to apply gravity after navigation.

A lesser issue is that the result of `is_on_floor` is updated when you call `move_and_slide`, so if you check it before `move_and_slide` you are getting the result from last physics frame. Which might or might not be what you want.
> 0 votes

---
Tags: physics, 3d, path-finding, godot-4
---


title: How to increase Godot render distance?

text:
# Question
Title: How to increase Godot render distance?
I've tried changing the viewport far distance under `view > settings`, from 500 to 500 000 and nothing changes in game. The player can only see roughly 90-120 meters away.

It's not even about the camera zoom, because my camera can zoom from -150 to +150. By zooming all the way out my character becomes invisible and so does everything below its feet.

# Answer
As you found out the Editor far distance can be changed in the Viewport Settings (which you access via View -\> Settings...). But that is just for the editor.

For the running game, use the the `far` property in the `Camera`:
> 9 votes

---
Tags: 3d, rendering, opengl-es2, godot-3, camera3d
---


# Question
Title: Using spatial hash to determine view distance
I am creating a client/server that is 2D and based on a map. Characters on the server are then separated into a spatial hash. I am using this to determine who to send data to, essentially, people in your vicinity. I have an issue I am not sure how to resolve.

Let's say my view area is 7x6 grid around the character, with the character being in the center. What I am trying to figure out is how I can keep this grid size even throughout, even when the character is near the edge of the screen. The way I do this is just convert the character position to a grid position, then check for the grid positions surrounding in that area.

Essentially, I want the viewable area (which is the screen size) to still be a 7x6 grid. The problem is, after implementing, I started getting a lot of sync discrepancies. Something I didn't think of is that this method breaks, because now characters can essentially see beyond their normal range. (see illustration below) It seems a bit unfair to reduce their normal view size just because they are near the edge of the map.

Here is a small grid illustration:

The lightest colored areas are the view grids, while the darkest are the characters. As you can see in this example, blue characters can see red, but red cannot see blue characters.

Is there another solution I am not seeing here other than just biting the bullet and only letting them see 3 squares away even at the edges?

# Answer
> 0 votes
You are already computing a camera position (position of the "view grid"), which is the same as the character position normally but is different if the character is near the edge.

Instead of using the character position to determine the data you synchronize, use the camera position. That way, you always have data for the visible area.

# Answer
> 0 votes
Is it really that problematic to have the camera scroll past the edges of the map? Giving the "outside area" of the game space a design that looks natural (even though it is inaccessible) is usually a lot less immersion-breaking than the camera suddenly starting to behave differently when the player approaches the map edges.

---
Tags: client-server, character, view, spatial-partitioning
---


# Question
Title: How to adjust parabolic trajectory to hit the same point with the same launch angle, but faster speed?
I'm launching a ballistic projectile similar to this sample.

The projectile moves from the launch point to the target point, but it's too slow. When I try to increase the speed without changing the angle, it misses the target point.

Here is the code I use to set the projectile's velocity given the launch speed and angle:

```
float speed = 45;
float angle = (float) (90 * Math.PI / 180f);
cpBody.body.setLinearVelocity(new Vector2(
          speed * (float) Math.cos(angle),
          speed * (float) Math.sin(angle)
));
cpBody.body.setAwake(true);
cpBody.body.setGravityScale(1);
cpBody.body.setAngularVelocity(0);

```

And I display the body positions like so:

```
  for (Entity entity : bodiesQueue) {
      CPTransform tfm = mCPTransform.get(entity);
      CPBody cpBody = mCPBody.get(entity);
      Vector2 positionBody = cpBody.body.getPosition();
      tfm.position.x = positionBody.x;
      tfm.position.y = positionBody.y;
      tfm.rotation = cpBody.body.getAngle() * MathUtils.radiansToDegrees;
  }

```

I want to travel with the same angle and faster velocity. The destination x,y does not change. How can I speed up the projectile without missing?

# Answer
> 1 votes
For a given gravity value and target point, there's a one-to-one relationship between launch speed and angle that will hit that point. Any other speed with the same angle will either fall short (if it's too slow) or overshoot (if it's too fast). So you cannot change the speed alone.

The only way to get a parabola with the same launch angle to hit the same target point at a faster speed is to increase gravity.

We can work out the needed gravity for a given speed like so:

First, if we're travelling at speed \\$s\\$, at a given angle \\$\theta\\$, our velocity components are \\$v\_x = s \cos \theta\\$ and \\$v\_y = s \sin \theta\\$.

At that speed, we'll reach the target's horizontal position at time \\$t^\*\\$, using \\$L\\$ for the launch position and \\$T\\$ for the target position:

$$\begin{align} L\_x + t^\* v\_x &= T\_x\\ t^\* v\_x &= T\_x - L\_x\\ t^\* &= \frac {T\_x - L\_x} {v\_x} \end{align}$$

At that time, our vertical velocity, bent by gravity, will have taken us to a height of:

$$\begin{align} h(t) = L\_y + t v\_y + t^2 \frac {a\_g} 2\\ h(t^\*) = L\_y + t^\* v\_y + {t^\*}^2 \frac {a\_g} 2 &= T\_y\\ {t^\*}^2 \frac {a\_g} 2 &= T\_y - L\_y - t^\* v\_y\\ a\_g &= \frac 2 {{t^\*}^2}\left(T\_y - L\_y - t^\* v\_y \right)\\ \end{align}$$

That gives you the rate of acceleration due to gravity needed to bend the trajectory down to hit the target y at the same time we hit the target x.

---
Tags: libgdx, movement, box2d
---


title: Sprite is visibile through others

text:
# Question
Title: Sprite is visibile through others
I'm trying to give a card game the look as if you play at a table. The effect I'm aiming for looks like this

The camera used is just a perspective angled camera.

The card is a mesh with a 0.02 thickness and has a sprite renderer at the back and front. The backimage is placed at 0.01 and the front image at -0.01, they work well and the card feels good enough. But if I add more elements on top, they are visibile through the back. The mesh is disabled to better see the 3 Sprites, the crystal is a different one from the first image (and not some weird perspective)

Front, side and back view:

They are layered like this

And all 3 Sprites are imported the same, have the same sprite renderer settings and Order in the layer.

The question is:

Why is the crystal visible from the back and how do I fix this?

# Answer
> 2 votes
The position of the sub sprites was managed with an z offset, but certain rotations, placement or movements that happened closer to the side of the board were causing the issues. The comment from @DMGregory

> Sprites are sorted by their center point, so if the center point of a sprite in the corner happens to be closer to the camera than the center point of the card backing, it will sort in front. You might want to use a Canvas for this - then you can control the layering through canvas hierarchy order, without stacking up z offsets.

explained the issue. The solution I used was slightly different, there is a Sorting Group component.

> A Sorting Group is not dependent on any other Renderers, and any Renderers that are attached to that GameObject and its descendants are rendered together.

I might have added them to each parent (the documentation stated one at the highest parent should be enough) in my Gameobject but left the `order in layer` always on the default 0 since the sorting was done already by the z offset. I can not remember why I added more than one on the GameObject right now but the result was working as it should.

---
Tags: unity
---


# Question
Title: Particle system objects in UI disappears/appears on screen unless I change the sorting rank
This happens to all particle systems. I tried:

1. Changing the rendering mode to camera, setting culling mask to UI, particle system layer set to UI
2. Adding a canvas child, and attaching a particle system to this child
3. Tinkered with the camera's FoV and projection.

What happened was that the particle system worked in some areas of the UI, and was quite unstable, i.e. could disappear and appear again. I resolved it by adding a sorting group and setting order in layer to 1.

So my question is, why did it work so unstable? In all tutorials I saw it either worked 100% or not at all. What could cause its instability? In the first image, the ps is visible, in the other two not, after I moved it (left and right). So what causes this issue?

# Answer
> 1 votes
I encountered a similar error once similar to this with a custom card that had different layers of sprites stacked (as in child sprites) to build the card. And sometimes some layers would just vanish. One comment brought me closer to explain the issue:

> Sprites are sorted by their center point, so if the center point of a sprite in the corner happens to be closer to the camera than the center point of the card backing, it will sort in front. You might want to use a Canvas for this - then you can control the layering through canvas hierarchy order, without stacking up z offsets. (@DMGregory)

Since the particle system uses sprites as well, you might solve the problem by simply manipulating the sorting order. Adding a sorting group on my GameObject did the trick for me in the end.

---
Tags: unity, gui, unity-ui
---


# Question
Title: Making Multiple NavMesh agents go to different destinations in unity
I am trying to make an Rts game in unity and am trying to make it so that units can go to different destinations, I have a selection system that deactivates their Navmesh agents and the script that tells them where to go when they are not selected. they can go to different places if only one group/unit is moving, but if I try to make two groups/units move to different destinations they will just go to the first group's destination. How can I make two active pathfinding agents go to different destinations? or should I try to find a different method of pathfinding?

this is the code I'm using to move the units. but it isn't the only code affecting them. if there's nothing wrong here I can show the other script that's attached to them. I can also show the code for unit selction.

```
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class UnitMovement : MonoBehaviour
{
    Camera cam;
    NavMeshAgent myAgent;
    public LayerMask ground;
    public static List<NavMeshAgent> meshAgents = new List<NavMeshAgent>();

    void Start()
    {
        cam = Camera.main;
        myAgent = this.gameObject.GetComponent<NavMeshAgent>();

    }

    void Update()
    {
        if (meshAgents.Contains(myAgent))
        {
            //absolutely nothing
        }
        else
        {
            meshAgents.Add(myAgent);
        }
        if (Input.GetMouseButtonDown(1) && meshAgents.Contains(myAgent))
        {
            if (meshAgents.IndexOf(myAgent) == 0)
            {
                RaycastHit hit;
                Ray ray = cam.ScreenPointToRay(Input.mousePosition);

                if (Physics.Raycast(ray, out hit, Mathf.Infinity, ground))
                {
                    if (UnitSelections.Instance.unitsSelected.Contains(this.gameObject))
                    {

                        myAgent.SetDestination(hit.point);
                    }

                }

                float angle = 60; // angular step
                int countOnCircle = (int)(360 / angle); // max number in one round
                int count = meshAgents.Count; // number of agents
                float step = 1; // circle number
                int i = 1; // agent serial number
                float randomizeAngle = Random.Range(0, angle);
                while (count > 1)
                {
                    var vec = Vector3.forward;
                    vec = Quaternion.Euler(0, angle * (countOnCircle - 1) + randomizeAngle, 0) * vec;
                    meshAgents[i].SetDestination(myAgent.destination + vec * (myAgent.radius + meshAgents[i].radius + 0.5f) * step);
                    countOnCircle--;
                    count--;
                    i++;
                    if (countOnCircle == 0)
                    {
                        if (step != 3 && step != 4 && step < 6 || step == 10) { angle /= 2f; }

                        countOnCircle = (int)(360 / angle);
                        step++;
                        randomizeAngle = Random.Range(0, angle);
                    }
                }

            }
        }
    }

    void OnDisable()
    {
        meshAgents.Clear();
    }
}

```

Script that disables movement when unit not selected

```
using UnityEngine;
using UnityEngine.AI;
public class Unit : MonoBehaviour
{

    void Start()
    {
        UnitSelections.Instance.unitList.Add(this.gameObject);
    }

    void Update()
    {
        if(UnitSelections.Instance.unitsSelected.Contains(this.gameObject))
        {
            this.gameObject.GetComponent<UnitMovement>().enabled = true;
            this.gameObject.GetComponent<NavMeshAgent>().enabled = true;
        }
        else if(!UnitSelections.Instance.unitsSelected.Contains(this.gameObject) && this.gameObject.GetComponent<NavMeshAgent>().hasPath == false)
        {
            this.gameObject.GetComponent<UnitMovement>().enabled = false;
            this.gameObject.GetComponent<NavMeshAgent>().enabled = false;
        }

        if (transform.position.y < 1)
        {
            transform.position = new Vector3(transform.position.x, 1, transform.position.z);
        }
    }

    private void OnDestroy()
    {
        UnitSelections.Instance.unitList.Remove(this.gameObject);
    }
}

```

# Answer
"It looks like you have the script on every single selectable/movable unit also trying to process issuing commands to all of those units. This adds inefficiency like having every active unit checking to see if it's the first in the list so it can command the others. I'd recommend separating those concerns. The scripts on each unit should handle only acting on commands, not issuing them to other units. Then you can have a single script instance elsewhere that handles issuing commands. I show an example of such an architecture in this answer" -DMgregory
> 0 votes

---
Tags: unity, c#, path-finding
---


# Question
Title: In unity, How do I transfer data from a C# script to a shader?
Let's say I have a C# script that has a variable inside it.

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class flow : MonoBehaviour{
    float r = UnityEngine.Random.Range(0,1);
}

```

I want to access this variable from inside an unlit shader. How can I do this?

# Answer
Seems like what you're looking for is this: https://docs.unity3d.com/ScriptReference/Material.SetFloat.html

example:

```
Material.SetFloat("_VariableName",variableValue);

```

where Material is the material with the shader you want to send the value to.

You can find more similar functions for different value types (color, vector, etc) in the public methods part of this documentation page: https://docs.unity3d.com/ScriptReference/Material.html
> 1 votes

# Answer
Thanks to @DMGregory, I figured out what the solution to my question was.

In the properties section of the shader, I created a float.

```
properties{
radius ("radius", float) = 1
}

```

Then, I created a private material in the C# script, named the material, and then use the SetFloat function to set the value of the float.

```
private Material sdf;

void Start(){
    float r = UnityEngine.Random.Range(0,1);
    sdf = GetComponent<Renderer>().material;
    sdf.SetFloat("radius", r);
}

void Update(){
    //Fun fact: if you initialize r and SetFloat in Update(), then the value of radius is different for each frame.
}

```

Then, initialize radius in the shader and its value should be updated by the script.
> 1 votes

---
Tags: unity, c#
---


# Question
Title: How to reduce code duplication in a cross-platform renderer without tying the interface to one specific API?
I'm working on a game engine as a fun project over the spring+summer. I've decided that to allow myself to explore rendering APIs I'm unfamiliar with, and force myself to write reusable code, I'd separate my renderer from the main project as a library - or multiple libraries - and attempt to support multiple rendering APIs.

I started by making a library, `sg`, which served as a simple way for me to represent models - it provides simple concepts like a "Node", "Mesh", "Image", and "Light" in such a way that data can be easily fed into buffers for use in renderers. (I use an Assimp-based preprocessing program to convert models and images in distinct formats into this single format.)

After this, I made `sgrender`, which provides *this* interface:

```
namespace sgrender
{
    /** Models, images, and other resources being managed by some particular renderer.
        Ideally, all the models and images for a scene are loaded by the engine at the
        start of the scene and fed into ModelSet, so that each rendering API can use it
        to allocate buffers and store everything in an optimal format. */
    class ModelSet
    {
    public:
        virtual ~ModelSet() = default;
    };

    /** Generic renderer interface. */
    class Renderer
    {
    public:
        /** Get any SDL_Window flags that the engine should pass for this renderer to work,
            e.g. SDL_WINDOW_VULKAN, SDL_WINDOW_OPENGL, etc. The OpenGL renderer also takes
            this opportunity to call SDL_GL_SetAttribute. */
        virtual SDL_WindowFlags getWindowFlags() = 0;

        /** Initialize the rendering backend, targeting the given SDL_Window to draw to. */
        virtual void useWindow(SDL_Window *window) = 0;

        /** Clean up! */
        virtual ~Renderer() = default;

        /** Begin the process of drawing - after this point, drawModel can be called.
            In the Vulkan renderer, this is where a target image and
            command buffer are selected for the next frame, and basic
            setup (begin render pass) is written into the buffer.
            In the OpenGL renderer, this is basically a glorified glClear*/
        virtual void beginDraw() = 0;

        /** End the process of drawing and display the frame. */
        virtual void endDraw() = 0;

        /** @brief Create a renderer-specific ModelSet from a set of SG models and
            all the images they use (mapped by name.) Each Model passed into the ModelSet
            can be referenced for drawing by whichever index it occupied when passed in. */
        virtual std::shared_ptr<ModelSet> makeModelSet(const std::vector<sg::Model> &models, const std::map<std::string, sg::Image>& images) = 0;

        /** @brief Draw a model w/ the given transform - ensure beginDraw() was called first!
            Ideally, all drawModel calls for some particular modelSet are grouped back-to-back. */
        virtual void drawModel(ModelSet *modelSet, size_t model, glm::mat4 transform) = 0;
    };
}

```

This is implemented by two render backends, `sgvk` and `sggl`, which both have their own concept of a `ModelSet` that keeps track of things like VAOs and textures. I figured this method of bulk-allocating everything needed for a particular scene gave the opportunity to allow my rendering backends to make optimizations specific to the renderer, such as packing all textures into a texture array (Vulkan) and creating shared vertex and index buffers so that I can draw particular models with just some integer index.

The trouble is, this seems to be *too* high-level of a renderer - I'm running into quite a bit of duplicate code between the OpenGL and Vulkan renderers I've created so far, specifically around the time when I create a particular ModelSet, and around the time when I draw.

But I'm also not sure how I could make a lower-level abstraction that allows all the explicit setup (e.g. pipeline layouts, memory allocation, descriptor set layouts) used for Vulkan while not being *overly specific* to one API.

One big thing right now is *shaders* \- at the moment, I'm just working with a single shader pair that draws an object in 3D space with some particular projection, and applies a Diffuse texture and simple lighting... but when I get into my goal of deferred, PBR rendering later, I might want to allow specific models to use a custom shader (...and create a whole new pipeline on Vulkan? How would I handle re-creating it on resize if it's not managed by the renderer? And switching pipelines for one object sounds expensive...)

I've looked at other abstract renderers, such as the one used for DOOM 3 (via this interesting blog series), and they seem to have much lower-level abstractions than mine - but I'm finding it hard to understand *how* they managed that, especially when it comes to APIs like Vulkan where you have to do a lot of initialization before you can freely tell your renderer, "Draw this!."

# Answer
Old question, and hey if OP wants time chime in how it worked out (or not), go for it!

My own experience is doing exactly that, what you are describing for like 10 years in the industry.

I am familiar with vulkan but haven't personally had a project to use it. But. I've seen games coded against gl style calls, directx direct c++ calls, and switch or ps4 sdk calls.

Now in theory, if I was building this from scratch: I'd try using the most constraining of the supported platforms, and use it as the common API.

That means your going to be managing your own stateblocks. If that stateblock gets interpreted as 6 differed gl calls, that's fine, but you already have a stateblock to change just the things you needed to, rather than if you coded against gl directly you'd have an entire different codebase to write!
> 0 votes

---
Tags: c++, architecture, rendering, software-engineering, cross-platform
---


# Question
Title: What is the term for making an object transparent when it blocks the player's view?
In many games if your camera gets too close to certain objects, or the object starts to block your screen, the game turns it transparent so you can still see.

What is the name for this effect? It is not occlusion culling. The model does not reduce its polygons, it simply just gets transparent so that you can look through it.

# Answer
> 1 votes
I'm not aware of a standard term for this.

Depending on how it's implemented, I might call it...

* "obstacle/occluder fade-out" if the object gains transparency all-over, evenly. Or "...dither-out" if we clip out individual pixels of it in some ordered or noisy pattern while leaving the remaining pixels opaque (common when using deferred rendering and anti-aliasing filters that can smooth out the dither)
* "...cut-out" or "...x-ray" if only part of the object is chopped away or rendered see-through, like we've done an architectural cut-away rendering or are shining an see-through beam through the center of it.

I don't have any references to cite for common terms here. The search hits I've found so far mostly describe the effect as a sentence "hide objects between the player character and camera" or "make obstacles transparent" etc.

# Answer
> 0 votes
There is also near plane clipping. Modifying the near plane can have sometimes useful effects.

---
Tags: camera, graphic-effects, terminology
---


# Question
Title: Is there any standard format for engine agnostic 2D tilemaps?
Basically that. I tried searching for standard 2D tilemaps formats or encodings, but I haven't found anything significative. I know that big engines use their own formats (Godot Resources, for example) but I think it would be interesting to have a common ground in case you want to use third party applications to edit/generate/process/etc your tilemaps.

# Answer
I'd say the closest you're likely to get is Tiled's TMX format.

Many games will use Tiled as a map authoring tool and use import plugins for various engines to import those maps at development time.

Usually though, this is a developer-only workflow, not something that ships as part of the distributed game binary for modders to use in modifying/adding maps.

Tiled is mainly useful for laying out the base visuals of a game map, not the game logic or other custom/dynamic content the game might need, so those parts are frequently added in the game engine the game is being authored in - leading to what you've observed about game maps being saved as Godot Resources, Unity Scenes, etc. rather than a cross-engine format.
> 3 votes

---
Tags: tilemap, standards
---


title: Minimap doesn't see the terrain

text:
# Question
Title: Minimap doesn't see the terrain
The minimap does follow the player movement and does everything a minimap should be able to do... except it doesn't see the land...only the sea even tho land and sea are on the same maks level

Camera set up, just a secondary camera 200 meters above the player, point straight down and attached to a viewport

The camera also as the classic camroot spatial node with a script attached to it, the minimpa rotates around the player only on the vertical axis, completely locked so the minimap rotates to adjust to the direction of the player (kind of like in the mobile game free fire or other shooter games) and has a the basic script to make the camera follow the player

# Answer
> 0 votes
kind of Solved kind of not solved, I wasted a good half an hour changing all the camera settings to see if it helps..

all I had to was to do was to take the entire world node (the one that governs all the terrain) and move it down below vertical coordinate 0, still the tops of mountains are invisible in orthogonal mode and so is the sea level and anything underwater

But I mean, that's ok for now I'm not gonna add anything underwater for a while now

---
Tags: 3d, terrain, opengl-es2, godot-3, minimap
---


# Question
Title: Wondering if there is a more efficient way to store level data in my game?
I am trying to remake Super Mario Bros. in JavaScript and I am trying to figure out if there is a more efficient way to create and store the level data. I have created 1-1 and here's what the code looks like:

```
const repeatBlock = (block, start, end, array) => {
    let newData = {
        "tp1": "tlp",
        "tp0": "trp",
        "p1": "lp",
        "p0": "rp"
    };

    for (let i = start; i <= end; i++) {
        let oldBlock = block;

        if (newData.hasOwnProperty(block+(end-i))) {
            block = newData[block+(end-i)];
        }

        array[i] = block;

        block = oldBlock;
    }
}

let level1_1Overworld = [];

for (let i = 0; i <= 14; i++) {
    level1_1Overworld[i] = [];
    repeatBlock("", 0, 227, level1_1Overworld[i]);
}

level1_1Overworld[2][198] = "f";

level1_1Overworld[5][22] = "q c";
repeatBlock("b", 80, 87, level1_1Overworld[5]);
repeatBlock("b", 91, 93, level1_1Overworld[5]);
level1_1Overworld[5][94] = "q c";
level1_1Overworld[5][109] = "q p";
repeatBlock("b", 121, 123, level1_1Overworld[5]);
level1_1Overworld[5][128] = "b";
repeatBlock("q c", 129, 130, level1_1Overworld[5]);
level1_1Overworld[5][131] = "b";
repeatBlock("s", 188, 189, level1_1Overworld[5]);

repeatBlock("s", 187, 189, level1_1Overworld[6]);

repeatBlock("s", 186, 189, level1_1Overworld[7]);

level1_1Overworld[8][65] = "h";
repeatBlock("", 66, 184, level1_1Overworld[8]);
repeatBlock("s", 185, 189, level1_1Overworld[8]);
level1_1Overworld[8][202] = "C";

level1_1Overworld[9][16] = "q c";
level1_1Overworld[9][20] = "b";
level1_1Overworld[9][21] = "q p";
level1_1Overworld[9][22] = "b";
level1_1Overworld[9][23] = "q c";
level1_1Overworld[9][24] = "b";
repeatBlock("tp", 46, 47, level1_1Overworld[9]);
repeatBlock("tp", 57, 58, level1_1Overworld[9]);
level1_1Overworld[9][77] = "b";
level1_1Overworld[9][78] = "q p";
level1_1Overworld[9][79] = "b";
level1_1Overworld[9][94] = "b m";
level1_1Overworld[9][100] = "b";
level1_1Overworld[9][101] = "b s";
level1_1Overworld[9][106] = "q c";
level1_1Overworld[9][109] = "q c";
level1_1Overworld[9][112] = "q c";
level1_1Overworld[9][118] = "b";
repeatBlock("b", 129, 130, level1_1Overworld[9]);
level1_1Overworld[9][137] = "s";
level1_1Overworld[9][140] = "s";
repeatBlock("s", 151, 152, level1_1Overworld[9]);
level1_1Overworld[9][155] = "s";
repeatBlock("b", 168, 169, level1_1Overworld[9]);
level1_1Overworld[9][170] = "q c";
level1_1Overworld[9][171] = "b";
repeatBlock("", 172, 183, level1_1Overworld[9]);
repeatBlock("s", 184, 189, level1_1Overworld[9]);

repeatBlock("tp", 38, 39, level1_1Overworld[10]);
repeatBlock("p", 46, 47, level1_1Overworld[10]);
repeatBlock("p", 57, 58, level1_1Overworld[10]);
repeatBlock("s", 136, 137, level1_1Overworld[10]);
repeatBlock("s", 140, 141, level1_1Overworld[10]);
repeatBlock("s", 150, 152, level1_1Overworld[10]);
repeatBlock("s", 155, 156, level1_1Overworld[10]);
repeatBlock("s", 183, 189, level1_1Overworld[10]);

repeatBlock("tp", 28, 29, level1_1Overworld[11]);
repeatBlock("p", 38, 39, level1_1Overworld[11]);
repeatBlock("p", 46, 47, level1_1Overworld[11]);
repeatBlock("p", 57, 58, level1_1Overworld[11]);
repeatBlock("s", 135, 137, level1_1Overworld[11]);
repeatBlock("s", 140, 142, level1_1Overworld[11]);
repeatBlock("s", 149, 152, level1_1Overworld[11]);
repeatBlock("s", 155, 157, level1_1Overworld[11]);
repeatBlock("tp", 163, 164, level1_1Overworld[11]);
repeatBlock("tp", 179, 180, level1_1Overworld[11]);
repeatBlock("s", 182, 189, level1_1Overworld[11]);

repeatBlock("p", 28, 29, level1_1Overworld[12]);
repeatBlock("p", 38, 39, level1_1Overworld[12]);
repeatBlock("p", 46, 47, level1_1Overworld[12]);
repeatBlock("p", 57, 58, level1_1Overworld[12]);
repeatBlock("s", 134, 137, level1_1Overworld[12]);
repeatBlock("s", 140, 143, level1_1Overworld[12]);
repeatBlock("s", 148, 152, level1_1Overworld[12]);
repeatBlock("s", 155, 158, level1_1Overworld[12]);
repeatBlock("p", 163, 164, level1_1Overworld[12]);
repeatBlock("p", 179, 180, level1_1Overworld[12]);
repeatBlock("s", 181, 189, level1_1Overworld[12]);
level1_1Overworld[12][198] = "s";

for (let i = 13; i <= 14; i++) {
    repeatBlock("g", 0, 68, level1_1Overworld[i]);
    repeatBlock("g", 71, 85, level1_1Overworld[i]);
    repeatBlock("g", 89, 152, level1_1Overworld[i]);
    repeatBlock("g", 155, 227, level1_1Overworld[i]);
}

//1-1 Bonus 16x15
let level1_1Bonus = [];

for (let i = 0; i <= 15; i++) {
    level1_1Bonus[i] = [];
    repeatBlock("", 0, 15, level1_1Bonus[i]);
}

for (let i = 2; i <= 12; i++) {
    level1_1Bonus[i][0] = "b";

    if (i < 11) {
        level1_1Bonus[i][15] = "lp";
    }
}

repeatBlock("b", 4, 10, level1_1Bonus[2]);

repeatBlock("c", 5, 9, level1_1Bonus[5]);
repeatBlock("c", 4, 10, level1_1Bonus[7]);
repeatBlock("c", 4, 10, level1_1Bonus[9]);

for (let i = 10; i <= 12; i++) {
    repeatBlock("b", 4, 10, level1_1Bonus[i]);
}

level1_1Bonus[11][13] = "spul";
level1_1Bonus[11][14] = "spum";
level1_1Bonus[11][15] = "spur";

level1_1Bonus[12][13] = "spll";
level1_1Bonus[12][14] = "splm";
level1_1Bonus[12][15] = "splr";

for (let i = 13; i <= 14; i++) {
    repeatBlock("g", 0, 15, level1_1Bonus[i]);
}

```

After the arrays I have a function that translates each index of the array to what it's corresponding type would be. This code works and I am able to render everything properly but I feel like there could be a better way to create this data especially when this is only the first level. Any ideas?

# Answer
> 29 votes
You should have the data for your level in an external source, such as an XML, JSON, YAML, CSV, or even a .txt file. Then you write your logic to read from the file, and generate the level procedurally.

This will let you play all of the levels with the same code, and you can make changes to levels, or add new levels, without touching the code. This also lets designers who aren't familiar with programming to create fun levels.

This also opens the door for user-generated content. You can create a level editor that auto-generates this file. A level editor will also make it easier to make fun levels, since they can be visually designed, instead of by writing text into a doc.

For example, your external file may look something like this:

```
                                F
          ?*?    C              F
                                F
     M           G              F
======================    =======

```
* `M` \- Mario's starting position
* `G` \- Goomba
* `?` \- Breakable Block
* `*` \- Breakable Coin Block
* `C` \- Coin
* `=` \- Ground
* `F` \- Flag

Then your (pseudo)code would look something like this:

```
Level CreateLevel(File file)
{
    char[][] blocks = file.GetASCIICharacters();
    int width = blocks.Length;
    int height = blocks[0].Length;
    Level level = new Level(width, height);
    for(int y = 0; y < height; y++)
        for(int x = 0; x < width; i++)
        {
            char block = blocks[x][y];
            if(block == `M`)
            {
                Mario mario = new Mario();
                level.SetBlock(x, y, mario);
            }
            else if(block == `G`)
            {
                Goomba goomba = new Goomba();
                level.SetBlock(x, y, goomba);
            }
            else if(block == `?`)
            {
                BreakableBlock breakableBlock = new BreakableBlock();
                level.SetBlock(x, y, breakableBlock);
            }
            else if(block == `*`)
            {
                CoinBlock coinBlock = new CoinBlock();
                level.SetBlock(x, y, coinBlock);
            }
            else if(block == `C`)
            {
                Coin coin = new Coin();
                level.SetBlock(x, y, coin);
            }
            else if(block == `=`)
            {
                Ground ground = new Ground();
                level.SetBlock(x, y, ground);
            }
            else if(block == `F`)
            {
                Flag flag = new Flag();
                level.SetBlock(x, y, flag);
            }
        }
    }
}

```

NOTE: There are some significant issues with this implementation. Specifically, if you wanted to give a Goomba a different amount of health, one ASCII character isn't enough to store that data. But by using a format such as `YAML`, you could put extra data in there. This is intended to be a simple example. It's also not well architected code.

# Answer
> 8 votes
# String literals

An easy way could be to use a string-literal and a function which loops over it and creates the level:

```
const level1_1 = `
    ggggg   ggggg
       p        p
ssssssssssssssssss
`

function parseLevel(level) {
  const lines = level.split()
  for (let y=0;y<lines;y++) {
    const l=lines[y]
    for (let x=0;x<l.length;x++) {
      const blockChar = l[x]
      levelArray[y][x] = createBlock(blockChar)
    }
  }
}

```

In this way you can easily edit the levels and visually see the layout while editing. You can also use a lot of tools from your text-editor for copy/paste and multiline editing. You can put each level in its own "level1-1.js" file and import the files.

# Pro/Con to external files (like XML,JSON,...)

I think external files can be a great solution especially when using a tool like a level-editor ("tiled" is great and open source). But if you don't want to use an external editor I'd prefer an inline solution.

When using inline levels you don't need additional file handling and error handling logic to load the files. And with JS you don't compile your code anyway, so just let the browser do the loading and parsing (via import). And you can still put the levels in their own js-files, so you don't have to touch the complex code when editing levels.

---
Tags: javascript, level-design, efficiency, compression, time-management
---


# Question
Title: How do I play a video in Unity using input text
I'm trying to play a video when a text command is typed.

What I expect to happen is the user inputs "play video 1" in an input text box, and after the command is sent via a button press, the video will play.

To remove the video, the user then types "clear video" in the input text box. After the command is sent via a button press, the video will stop playing and not be visible any longer until the user again types "play video 1" into the input text box.

this is the code I have so far but I can't get it to work.

```
{
//this is where it will play the video. using a raw image with a render texture
    public VideoPlayer videoPlayer

//this will be the placeholder when no video is playing
    public Texture nVideo;

// these are the videoclips
    public videoclip m_video1;
    public videoclip m_video2;
    public videoclip m_video3;
//

    private string lastInput;

    void Start()
    {
        videoPlayer = GetComponent<VideoPlayer>();
    }

    void Update()
    {

        if  (lastInput == "clear video")
            {
            Texture.Texture = nVideo;
           }
        else if
           (lastInput == "show video 1")
            {
            playvideo = m_video1;
        }
        else if
          (lastInput == "show video 2")
        {
             playvideo = m_video2;
        }
        else if
           (lastInput == "show video 3")
            {
             playvideo = m_video3;
        }
        }

 public void GetInputText(InputField input)
    {

        //lastInput = input.text.ToLower();
        lastInput = input.text.ToString();
    }

}

```

As you can see, the problem I am having is I don't have the correct namespaces and I'm also sure I don't have the right commands to play the video.

I hope someone understands what I'm trying to accomplish and can point me in the right direction. Any help will be greatly appreciated.

# Answer
> -2 votes
Here's an updated version of your code

using UnityEngine; using UnityEngine.UI; using UnityEngine.Video;

public class VideoPlayerController : MonoBehaviour { public VideoPlayer videoPlayer; public RawImage videoImage; public Texture noVideoTexture;

```
public VideoClip videoClip1;
public VideoClip videoClip2;
public VideoClip videoClip3;

private string lastInput;

private void Start()
{
    videoPlayer = GetComponent<VideoPlayer>();
}

private void Update()
{
    if (lastInput == "clear video")
    {
        videoPlayer.Stop();
        videoImage.texture = noVideoTexture;
    }
    else if (lastInput == "play video 1")
    {
        PlayVideo(videoClip1);
    }
    else if (lastInput == "play video 2")
    {
        PlayVideo(videoClip2);
    }
    else if (lastInput == "play video 3")
    {
        PlayVideo(videoClip3);
    }
}

private void PlayVideo(VideoClip videoClip)
{
    videoPlayer.Stop();
    videoPlayer.clip = videoClip;
    videoPlayer.Play();
    videoImage.texture = videoPlayer.texture;
}

public void GetInputText(InputField input)
{
    lastInput = input.text.ToLower();
    input.text = ""; // Clear the input field after processing the command
}

```

}

---
Tags: unity, c#, input, text, video
---


# Question
Title: Which method of preventing viewport distortions is most ideal?
I am working on rendering various 2D shapes in OpenGL. After initial experimentation, I came to the conclusion that the rendered image is distorted due to the window having a non-square aspect ratio:

*See how the hexagon looks squashed and the circle looks like an oval due to aspect ratio distortion*

The code that produced this issue is given here \- I linked it as it is quite long and complex and separated over multiple files.

I have also come to the conclusion that there are 3 methods of rectifying this issue:

* Adjusting `glViewport()` such that the viewport is square (but this would lead to large gaps on each side of the square viewport)
* Using a projection matrix to achieve the same effect as the prior method (but again, this would lead to large gaps)
* Changing the vertices of the polygons themselves with an offset so they are drawn with the correct aspect ratio and do not get stretched

Which of these methods is the suggested method for dealing with viewport distortion?

# Answer
> 2 votes
Your vertex shader code takes the vertex position and dumps it straight into `gl_Position`:

```
#version 330 core
in vec2 position;
in vec3 color;
out vec3 Color;
void main() {
    Color = color;
    gl_Position = vec4(position, 0.0, 1.0);
}

```

The trouble with this is that `gl_Position` expects a position (that, after the perspective divide by w, will be) in a coordinate system called Normalized Device Coordinates (NDC). In this coordinate system, x=-1 is the left edge of the viewport, x=+1 is the right edge, y=-1 is the bottom, and y=+1 is the top, *regardless of the size or aspect ratio of that viewport*.

That means a horizontal edge of length 1 in NDC will be small on a narrow viewport and longer on a wide viewport.

By passing your positions through unchanged this way, you're saying "I already handled converting to NDC CPU-side, so the GPU doesn't have to worry about transforming these coordinates to match the window/screen". But that's not true here.

The simplest fix would be to add a uniform `aspectRatio`, which you populate just before drawing to be the ratio of the current height to its width. Then you can adjust your vertex shader to say...

```
gl_Position = vec4(position.x * aspectRatio, position.y, 0.0, 1.0);

```

On tall skinny windows, `aspectRatio` will be greater than one, stretching the x axis to compensate for the shrinking of the NDC coordinate space's screen coverage in that direction. On squat wide windows, `aspectRatio` will be less than one, shrinking the x axis to compensate for the stretching of the NDC coordinate space. Either way, squares stay square.

This particular approach keeps the y axis unchanged, so you'll still fit the same amount of content between the bottom and top edge of the window no matter how large the window is - the content will just shrink or grow uniformly as the window is scaled vertically. Changing the window's width will act like cropping - keeping the displayed content the same size, but shrinking or growing the aperture through which we're viewing it.

A projection matrix can do the same job, just with more generality to encompass other kinds of transforms a 3D app might want to do too. But that does come with (minor) extra costs - 16 floats instead of one, 4 dot products instead of one scalar multiply. Nothing that would break the bank - modern games use matrix multiplies in shaders all the time - just a bit overkill if you only need aspect ratio adjustment in one axis.

# Answer
> -1 votes
the suggested method for dealing with viewport distortion in this case is to adjust the vertices of the polygons themselves with an offset so they are drawn with the correct aspect ratio and do not get stretched. This approach allows you to maintain control over the shape of the objects being rendered and ensures that they appear undistorted regardless of the window's aspect ratio.

By modifying the vertices with an offset, you can compensate for the stretching or shrinking of the NDC coordinate space's screen coverage in a specific direction. This method keeps the y axis unchanged, so the content will fit between the bottom and top edges of the window while the x axis is adjusted to maintain the correct aspect ratio. This ensures that squares stay square, and the overall appearance of the rendered shapes remains consistent.

and so while using a projection matrix can achieve similar results, it introduces additional complexity and overhead, as it encompasses other kinds of transformations that may not be necessary in this scenario. If you only need aspect ratio adjustment in one axis, modifying the vertices directly provides a more straightforward and efficient solution.

i mean adjusting the vertices of the polygons themselves with an offset is the suggested method for preventing viewport distortion in this context. It allows you to maintain control over the shape of the rendered objects and ensures that they appear undistorted regardless of the window's aspect ratio.

---
Tags: opengl, graphics
---


# Question
Title: How does 3D games work so fluent provided that each mesh's size is so big?
I'm surprised to find that each mesh takes at least 5-6 MB,

how can a 3D game be so fluent when there are hundreds of models?

I'm expecting it will simply go out of memory or something else that makes the game un-playable..

What's the trick employed here?

# Answer
There are tons of tricks developers use to get the maximum out of their art assets.

**Optimizing models**

The first is to optimize for *polycount*. Here's a great example:

When you look at the texture model, it looks amazing detailed with probably like a million triangles. But the truth is, it only has the polygons shown on the right! In this case, an artist used the following process:

* Build an amazingly detailed demon model in Maya, 3DS Max or Blender. We're talking a million or more polygons.
* She reduces the amount of polygons in the model to a more reasonable size, like 400 or so, and saves it to a new file.
* Finally, she uses a package to generate a normal map from the million-polygon model and puts it on the reduced detail model.
* Alternatively, she uses ZBrush to "sculpt" the normals for the model.

There is also tons of detail being added using just the diffuse texture.

**Batching and instancing**

Others have touched upon this, but it's very true. If you're going to render the same tree model hundreds of times, it makes no sense to load it into memory a hundred times. It's better to load it into memory once and render it at different positions.

Here's a great article on that: http://blog.wolfire.com/2009/11/Fast-object-instancing

**Reduced level-of-detail**

For our space RTS, we actually had multiple representations for our ships:

* Very far away - icons. No model or anything, just a small icon to show the position of a ship on the map.
* Far away - small ship. These ships had about 100 triangles each. But even at that reduced scale, it doesn't matter. At that range, all you really care about is that the *outline* of the model stays the same.
* Near - big ship. These are the base models. Each had about 2000 triangles, with a diffuse map, normal map, specular map and glow map. Shaders became more expensive (alpha pass, glow pass) and particles were turned on.

**Occlusion culling**

This is a topic of research that is increasingly becoming more important. The basic idea is: why render something that is drawn *behind* something else? However, the intricacies can become quite complicated.

The most common approach is to label certain objects as "occluders". The rendering then happens in stages:

* First, the occluders are rendered into a depth buffer without textures or shaders.
* Objects compare themselves to this buffer, if they're behind it they don't get drawn.
* Objects that are still in view are rendered with textures and shaders.

A very simple approach to occlusion culling could be: "don't render anything that isn't in the camera's view frustum". Objects check if they're inside the camera's view frustum (the box that defines the camera's transformation of the world to the screen) and if they are, they're added to a list of objects to render.

**Chunking**

Finally, the mother of all memory savings: chunking. If you're playing in a large open world, it makes no sense to load everything into memory at once. Especially on platforms like the Xbox 360 and the PS3, where memory is worth its weight in *gold*. So a solution could be to divide your level into chunks.

When you turn a corner in an FPS game, the next section is loaded while the old one is thrown away. However, this affects the level design greatly and basically ensures corridors everywhere. There's also no silver bullet: what works for a game like Just Cause 2 doesn't work at all for a game like Fable 3.

**Conclusion**

For any game, you should look at what's important to you. If you're on PC, you don't have to care about memory *that much*. Most gaming rigs these days will have at least 2 GB of memory and 1 GB of video memory. That's a lot of models and textures! Keep in mind that any optimization you make for *memory* will usually have a price for *processing*. If you compress your textures to PNG for example, your files will be smaller than BMP images, but they'll take longer to load.
> 14 votes

# Answer
If you downloaded a model from an online source, it is most likely not in an optimized format. It will be in a format designed for use in a 3D modeling program, which may be much larger than the optimized/compressed mesh data that will eventually be sent to the game engine (usually generated by the game's level builder or other workflow tools). If the downloaded package includes textures, those also might not be compressed as aggressively as they would be for the final game data.
> 2 votes

# Answer
This is just 5-6 MB of GPU memory (textures, vertices or indices, does not really matter). With an average 256mb you can load dozens of such models into GPURAM. When model is rendered for more than 1 time it's usually just instanced (e.g. 12 identical cars in a racing game you see at once are rendered from 1 model with just color/position changed). And usually only player objects are fine detailed, with the rest of the scene using less details per unit of rendered surface.

Now, GPUs are very good at what they are designed to do - rendering tons of textured/shaded/transformed polygons. No wonder typical scenes can have million of polygons and few hundreds of megabytes of textures.

Optimizations kick in as well - when you cant see full-resolution texture it is rendered in smaller resolution (mipmaping + anisotropic filtering make it almost unnoticeable). Every model that is too far away is rendered in lower details (LOD). When you play MMO games only things that are in reach are loaded/rendered, everything else gets streamed when you get closer to it. Thats how 20gb WoW works.

P.S. In my experience with circuit racing games typical car models were 0.5-16mb. 8 per race. Scenery being another 30mb. Scenery objects were 5-10mb. HUD - another 5mb. Sound and everything else another 5mb. All-n-all just some 60-120mb. And you could cut that size by half just by switching to lower res textures.
> 1 votes

# Answer
The trick employed in making a 3D game with hundreds of models run smoothly despite each mesh taking at least 5-6 MB is a combination of various optimization techniques.

i mean developers utilize strategies such as optimizing models by reducing polygon count and using normal maps, batching and instancing to render multiple instances of the same object efficiently, employing reduced level-of-detail representations for distant objects, implementing occlusion culling to avoid rendering objects that are not visible, and utilizing chunking to load and unload game sections dynamically.

These techniques help manage memory usage, reduce processing requirements, and ensure that the game maintains a high level of performance while still delivering visually appealing content. It's important to strike a balance between memory optimization and processing efficiency based on the target platform and specific game requirements.

If you want to research more about 3d modeling for games, remember to verify the credibility and expertise of the sources you come across and cross-reference information from multiple reputable sources to ensure accuracy and relevance to your specific needs.

Actually I recommend some game development forums (you can find it by yourself)
> 0 votes

---
Tags: 3d
---


# Question
Title: Generating a texture and applying it to an object at runtime
In Unity, I want to generate a texture and apply it to a material. The following method generates a 16x16 Texture2D and applies it. However, my object with the material shows only a gray "default" texture. The texture WILL show if I open it in the inspector and change the filtering mode (Bilinear to Point, etc), but doing this in the script does nothing. Is there something I am missing?

```
public Texture2D myTexture;
public Material myMaterial; //Assigned in inspector

void generateMyTexture()
{
    List<Color> colorList = new List<Color>();
    for (int i = 0; i < 256; i++)
    {
        colorList.Add(Random.ColorHSV());
    }
    myTexture = new Texture2D(16, 16);
    myTexture.SetPixels(colorList.ToArray());
    myMaterial.mainTexture = myTexture;
}

```

EDIT - SOLVED by DMGregory. I was missing a crucial last line, `myTexture.Apply();`

# Answer
> 2 votes
Try this adjustment:

```
// Put dimensions somewhere they're easy to edit
// without having to change magic numbers throughout the function.
int width = 16;
int height = 16;
int texelCount = width * height;

// Rent a temporary array to hold the colours
// so we don't allocate large structures unnecessarily.
var colors = System.Buffers.ArrayPool<Color32>.Shared.Rent(texelCount);
for (int i = 0; i < texelCount; i++)
{
    colors[i] = Random.ColorHSV();
}
myTexture = new Texture2D(width, height);
// Using 32-bit colours uses 1/4 the memory, for efficiency.
myTexture.SetPixels32(colors);

// Recycle the temporary array we rented.
System.Buffers.ArrayPool<Color32>.Shared.Return(colors);

// Update the GPU copy of the texture, including mipmaps.
myTexture.Apply(true, false);

myMaterial.mainTexture = myTexture;

```

The main change is calling Texture2D.Apply() to update the texture's mipmaps and copy the whole thing into GPU memory where your changes will be visible.

The other changes I showed are just for efficiency - renting a reusable array instead of allocating a new list from scratch each time this is called and resizing it as we fill it up, using 32-bit colours instead of 16 bytes of floating point values, and pulling out the magic numbers for the texture size so it's easy to update this function if your size needs change.

---
Tags: unity, c#, textures, materials
---


# Question
Title: OpenGL ES + SDL texture can only be moved with the combination of two keys
I making a simple game following JoeyDeVrieses guide on OpenGL, I followed the guide and created an input system, which handles the keyboard inputs and quitting the application, the issue is I cannot control my texture in a proper way, it can only move when I quickly press two keys, also the application doesn't quit when I press the x button

**main.cpp**(Test object is the initialized game class)

```
SDL_Event event;

    while (is_running)
    {
        last_frame = current_frame;
        current_frame = SDL_GetPerformanceCounter();

        delta_time = (double)((current_frame - last_frame) * 1000 / (double)SDL_GetPerformanceFrequency());

        if(is_running == false)
            std::cout << "closing application" << std::endl;

        while(SDL_PollEvent(&event))
        {
            Test.proccess_input(delta_time, event);
            if(event.type == SDL_EVENT_QUIT)
                is_running = false;
        }
        Test.update(delta_time);

        glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        Test.render();

        SDL_GL_SwapWindow(window);
    }

```

**game.cpp**

void Game::proccess_input(float dt, SDL_Event event)
{
    if (this->State == GAME_ACTIVE)
    {
        float velocity = PLAYER_VELOCITY * dt;

        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_EVENT_KEY_DOWN:
                    switch (event.key.keysym.sym)
                    {
                        case SDLK_a:
                            if (player->position.x >= 0.0f)
                            {
                                player->position.x -= velocity;
                                player->rotation = 270.0f;
                            }
                            break;
                        case SDLK_d:
                            if (player->position.x <= this->width - player->size.x)
                            {
                                player->position.x += velocity;
                                player->rotation = 90.0f;
                            }
                            break;
                        case SDLK_w:
                            if (player->position.y >= 0.0f)
                            {
                                player->position.y -= velocity;
                                player->rotation = 0.0f;
                            }
                            break;
                        case SDLK_s:
                            if (player->position.y <= this->height - player->size.y)
                            {
                                player->position.y += velocity;
                                player->rotation = 180.0f;
                            }
                            break;
                        default:
                            break;
                    }
                    break;
            }
        }
    }
}
```
</code></pre>

# Answer
> 1 votes
I see a couple issues with your code.

The first one is that you process events in two locations, which may work correctly in this context, but will eventually explode in your face when you decide to make something a bit more complicated. The core of this issue is that, for instance, a "quit" event may occur the same frame as a "key" event, but since the "key" events are processed in a loop that ignores all other events, the "quit" event is ignored by your code. You should poll for the events in a single loop.

main.cpp

```
...

while(SDL_PollEvent(&event))
{
    switch(event.type)
    {
    case SDL_EVENT_QUIT:
    {
        is_running = false;
        break;
    }
    case SDL_EVENT_KEY_DOWN:
    {
        switch (event.key.keysym.sym)
        {
            case SDLK_a:
            case SDLK_d:
            case SDLK_w:
            case SDLK_s:
                Test.proccess_input(delta_time, event);
        }

        break;
    }

    };
}
...

```

game.cpp

```
void Game::proccess_input(float dt, SDL_Event event)
{
    float velocity = PLAYER_VELOCITY * dt;

    switch (event.key.keysym.sym)
    {
        case SDLK_a:
            if (player->position.x >= 0.0f)
            {
                player->position.x -= velocity;
                player->rotation = 270.0f;
            }
            break;
        case SDLK_d:
            if (player->position.x <= this->width - player->size.x)
            {
                player->position.x += velocity;
                player->rotation = 90.0f;
            }
            break;
        case SDLK_w:
            if (player->position.y >= 0.0f)
            {
                player->position.y -= velocity;
                player->rotation = 0.0f;
            }
            break;
        case SDLK_s:
            if (player->position.y <= this->height - player->size.y)
            {
                player->position.y += velocity;
                player->rotation = 180.0f;
            }
            break;
        default:
            break;
    }
}

```

The second issue is that SDL may be using the calls from the OS, which will only be active for the frame they occur, and sometimes a "key down" event will "erase" the previous "key down" event, although both keys are down.

The way to solve this is to wrap the events in your own structure which keeps track of which keys are down and which keys are up.

Assuming you have such class variable where you have initialized all your key values to "false": `std::map<int, bool> keyStates;`

main.cpp

```
...

while(SDL_PollEvent(&event))
{
    switch(event.type)
    {
    case SDL_EVENT_QUIT:
    {
        is_running = false;
        break;
    }
    case SDL_EVENT_KEY_DOWN:
    {
        switch (event.key.keysym.sym)
        {
            case SDLK_a:
            case SDLK_d:
            case SDLK_w:
            case SDLK_s:
                Test.proccess_input(event, true);
        }

        break;
    }
    case SDL_EVENT_KEY_UP:
    {
        switch (event.key.keysym.sym)
        {
            case SDLK_a:
            case SDLK_d:
            case SDLK_w:
            case SDLK_s:
                Test.proccess_input(event, false);
        }

        break;
    }

    };
}
Test.update_player_input(dt)
...

```

game.cpp

```
void Game::proccess_input(SDL_Event event, bool isKeyDown)
{
    keyStates[event.key.keysym.sym] = isKeyDown;
}

void Game::update_player_input(float dt)
{
    float velocity = PLAYER_VELOCITY * dt;

    if (keyStates[SDLK_a])
    {
        if (player->position.x >= 0.0f)
        {
            player->position.x -= velocity;
            player->rotation = 270.0f;
        }
    }

    if (keyStates[SDLK_d])
    {
        if (player->position.x <= this->width - player->size.x)
        {
            player->position.x += velocity;
            player->rotation = 90.0f;
        }
    }

    if (keyStates[SDLK_w])
    {
        if (player->position.y >= 0.0f)
        {
            player->position.y -= velocity;
            player->rotation = 0.0f;
        }
    }

    if (keyStates[SDLK_s])
    {
        if (player->position.y <= this->height - player->size.y)
        {
            player->position.y += velocity;
            player->rotation = 180.0f;
        }
    }
}

```

With this approach, though, and assuming that your texture only has 4 directions, there will be a bias toward the keys handled last when hitting more than one key, and so the texture will always face the same direction when two keys are pressed.

---
Tags: opengl, input, sdl
---


# Question
Title: Implementing clutch kicking in a racing simulator
I'm currently in the process of programming a racing simulator. I currently have a full drivetrain set up that includes an Engine, Transmission, Transfer case, and differential.

The engine has two rpm values that it mixes into one value, "UnloadedRPM" & "ActualRPM". UnloadedRPM is used when the clutch is fully depressed or if I am in neutral. ActualRPM is derived from the average wheel rpm and multiplied through the differential, transfer case, and transmission to give me the engine rpm when in gear.

The issue I am running into is with the phenomena known as "Clutch kicking".

In a manual transmission, if you rev the engine close to its max rpm while in gear but with the clutch fully depressed and suddenly release the clutch the sudden jolt of force should cause the connected wheels to spin and lose traction. Given they receive enough force.

My issue is that with my current simulation model when I attempt to perform a "clutch kick" no torque is sent to the wheels because the engine rpm changes from "UnloadedRPM" to "ActualRPM" to quickly and if the wheel are not rotating then the "ActualRPM" is at 0 which also means the Engines output torque is 0.

Solutions that I have tried inlude;

interpolating the clutch value from 1 to 0 so that there is a smooth transition from "UnloadedRPM" and "ActualRPM" but that does not satisfy the conditions for a "clutch kick".

Calculating flywheel torque from it's inertia and angular acceleration/deceleration and applying it the wheels. This does not produce nearly enough torque to rotate the wheels and only applies the torque for one simulation cycle.

setting the wheel velocity manually to the engine RPM right before I release the clutch. this created a very jarring and "spaztic" behavior for the engine.

This does not need to be 100% accurate to the real world. However, it should be able to mimic the real thing and come off as passable for realistic

Any help would be very appreciated.

# Answer
Instead of setting the RPM of the engine, instead model the clutch as a variable torque limited connection.

When UnloadedRPM (clutch input) != ActualRPM (clutch output), then apply torque to the wheels and counter torque to engine based on the difference and the clutch engagement.

The effect of the counter torque on the unloaded RPM is going to depend on the engine stats. In extreme that might even cause a stall.
> 1 votes

# Answer
I'm making an engine simulation of my own as well and in my opinion my solution works kinda well:

You said you tried the flywheel thing and it only goes for one cycle. This is the right path, you just gotta model the way that the torque from the kinetic energy of the flywheel dissipates, either through clutch slip or even better if you have an aggressive clutch: drivetrain flex. Really think about it: probably in those cases where the car barely clutch kicks/almost stalls, the thing that saves it from stalling is some sort of flexing in the drivetrain that creates a fast and slight RPM slip not from the engine to the gearbox input but from the gearbox output to the other ends (even the suspension and struts contributes to this but not necessary in the simulation; just do it for gearbox output to diff input I think).

You pair this with the correct flywheel kinetic energy model (where to accelerate the engine, the flywheel torque is "subtracted" from final torque, and when the engine is decelerating that signal is instead positive; smoothing/adding delay in this case will reduce KE torque when hitting the rpm limiter so i wouldn't recommend but idk, it could be right). Include some initial clutch slip as well (obviously not too much, smoothing/delaying clutch torque until it fully locks could be a nice addition to the model) and I think you're good.

I'm not a physicist by any means, but adding all of this feels realistic, not too much torque, it can still stall with a lighter flywheel and lower torque, which should happen still, and adding more flywheel weight and/or more torque helps in a way that at least feels realistic.

If you've not solved this yet, I hope it helps, good luck!!!
> 0 votes

---
Tags: game-mechanics, simulations, vehicle
---


# Question
Title: How to add weapon trail to sword swings?
I want to add the translucent blue swish following the sword when it is swung, but I don't even know what to call it, so I can't search it.

# Answer
> 2 votes
I can think of two ways of doing this in Godot 3:

* Animated: You can use `CSGPolygon`, keyframe the `polygon` property in an `AnimationPlayer` and make sure the track is set to continuous.
* Procedural: Create an `ImmediateGeometry`, have it follow to points (e.g. `Position3D`) which can be attached to the character via `BoneAttachment` or via `RemoteTransform`, and each frame it records the positions in an array, an outputs new geometry. See Using ImmediateGeometry.

*I had a look at the asset library, and the solution we can find there uses `ImmediateGeometry`.*

In either case you need to use a material that completes the effect with color and transparency.

---

Note for Godot 4 users: `ImmediateGeometry` was removed in favor or `ImmediateMesh`. So instead of a `ImmediateGeometry` node, you have a `MeshInstance3D` node with its `mesh` set to a `ImmediateMesh`.

---
Tags: 3d, opengl-es2, graphic-effects, combat, godot-3
---