# Question
Title: D3D12: how to enable perspective correction when interpolating UV coordinates?
Good morning, I am currently running into a UV interpolation issue with D3D12 that looks like this:

Is there something that needs to be set when initialising the pipeline so that the GPU does the correct interpolation or do I have to do it myself? I have seen several examples of textured 3D objects that looked fine and the associated code did not seem to do anything specific to compute the correct UVs manually, so I guess I just forgot to set a flag or something?

EDIT: here is some additional information (shaders are trimmed to the core):

```
// Input data layout:

D3D12_INPUT_ELEMENT_DESC mesh_layout[NUM_ELEMENTS_IN_MESH_LAYOUT] = {
    {"Vertex_Position",  0, DXGI_FORMAT_R32G32B32_FLOAT,    0, 0,                            D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,   0},
    {"Normal",           0, DXGI_FORMAT_R32G32B32_FLOAT,    0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,   0},
    {"U_Axis",           0, DXGI_FORMAT_R32G32B32_FLOAT,    0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,   0},
    {"V_Axis",           0, DXGI_FORMAT_R32G32B32_FLOAT,    0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,   0},
    {"Uv_Coords",        0, DXGI_FORMAT_R32G32_FLOAT,       0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,   0},

    {"Position",         0, DXGI_FORMAT_R32G32B32_FLOAT,    1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Scale",            0, DXGI_FORMAT_R32G32B32_FLOAT,    1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Orientation",      0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Colour",           0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Shadow_Map_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Shadow_Map_X_Axis",   0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Shadow_Map_Y_Axis",   0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Shadow_Map_Z_Axis",   0, DXGI_FORMAT_R32G32B32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Shadow_Map_Uvs",   0, DXGI_FORMAT_R32G32_FLOAT,       1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Material_Index",   0, DXGI_FORMAT_R32_UINT,           1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
};

/*
The vertex buffer looks like this (only positions and UVs are represented here as this is what interests us):

{ // First triangle.
    { 1, -1, 0}, {1, 0},
    {-1,  1, 0}, {0, 1},
    {-1, -1, 0}, {0, 0},
},
{ // Second triangle.
    { 1, -1, 0}, {1, 0},
    { 1,  1, 0}, {1, 1},
    {-1,  1, 0}, {0, 1},
}
*/

```

```
// Vertex shader:

ConstantBuffer<Renderer_Info> renderer_info : register(b0, space2);
StructuredBuffer<Material> materials : register(t0, space2);

struct To_Pixel_Shader
{
    v4  position              : SV_Position;
    v4  colour                : Colour;
    v3  origin                : Origin;
    v3  position_3d           : Position_3d;
    v3  normal                : Normal;
    v2  uvs                   : Uv_Coords;
    v3  camera_view_direction : Camera_View_Direction;
    u32 material_index        : Material_Index;
    f32 scale                 : Uniform_Scale;
};

To_Pixel_Shader main(
    v3  vertex_position : Vertex_Position,
    v3  normal          : Normal,
    v3  u_axis          : U_Axis,
    v3  v_axis          : V_Axis,
    v2  uvs             : Uv_Coords,

    v3  position            : Position,
    v3  scale               : Scale,
    v4  orientation         : Orientation,
    v4  colour              : Colour,
    v3  shadow_map_position : Shadow_Map_Position,
    v3  shadow_map_x_axis   : Shadow_Map_X_Axis,
    v3  shadow_map_y_axis   : Shadow_Map_Y_Axis,
    v3  shadow_map_z_axis   : Shadow_Map_Z_Axis,
    v2  shadow_map_uvs      : Shadow_Map_Uvs,
    u32 material_index      : Material_Index
)
{
    To_Pixel_Shader result;

    v2  rt_dimensions = {renderer_info.rt_width, renderer_info.rt_height};
    f32 rt_ratio = rt_dimensions.y / rt_dimensions.x;

    // Calculate the vertex world position. START
    v4 orientation_inverse = quaternion_inverse_no_norm(orientation); // @ This could be given in the mesh instance along with the orientation.

    vertex_position *= scale;
    vertex_position  = rotate_point(orientation, vertex_position, orientation_inverse);
    vertex_position += position;

    result.position_3d = vertex_position;
    // Calculate the vertex world position. END

    // Calculate the vertex screen position. START
    v3 eye_to_vertex = vertex_position - renderer_info.camera_eye_position;
    result.camera_view_direction = eye_to_vertex; // This is normalised in the pixel shader.

    f32 vertex_dot_camera_z = -dot(eye_to_vertex, renderer_info.camera_z_direction);
    f32 distance_to_vertex = distance(renderer_info.camera_eye_position, vertex_position);

    f32 triangle_ratio = renderer_info.camera_eye_offset / vertex_dot_camera_z;

    f32 MAX_DEPTH_DISTANCE = 1000.0f;
    f32 NEAR_CLIP_PLANE    = 1;

    v3 vertex_position_on_screen = {
        dot(eye_to_vertex, renderer_info.camera_x_direction),
        dot(eye_to_vertex, renderer_info.camera_y_direction),
        (distance_to_vertex - NEAR_CLIP_PLANE) / MAX_DEPTH_DISTANCE
    };

    vertex_position_on_screen.xy *= triangle_ratio;
    vertex_position_on_screen.x  *= rt_ratio;

    ///////////////////////////////////////////////////////////////////////////////////////////
    // NOTE: @ for now we do not take vertices lying behind the near clip plane into account!!!
    ///////////////////////////////////////////////////////////////////////////////////////////

    result.screen_depth = vertex_position_on_screen.z;
    // Calculate the vertex screen position. END

    result.origin         = position;
    result.position       = v4(vertex_position_on_screen.xyz, 1);
    result.normal         = rotate_point(orientation, normal, orientation_inverse);
    result.uvs            = uvs;
    result.material_index = material_index;
    result.colour         = colour;
    result.scale          = scale.x;

    return result;
}

```

```
// Pixel shader:

Texture2D<v4> colour_atlas : register(t0, space3);
StructuredBuffer<Atlas_Texture> colour_textures : register(t1, space3);
ConstantBuffer<Renderer_Info> renderer_info : register(b0, space3);
StructuredBuffer<Material> materials : register(t2, space3);
Texture2D<f32> shadow_map_atlas : register(t3, space3);
sampler bilinear_sampler : register(s0);
sampler point_sampler    : register(s1);

v4 main(
    v4  position              : SV_Position,
    v4  colour                : Colour,
    v3  origin                : Origin,
    v3  position_3d           : Position_3d,
    v3  normal                : Normal,
    v2  uvs                   : Uv_Coords,
    v3  camera_view_direction : Camera_View_Direction,
    u32 material_index        : Material_Index,
    f32 scale                 : Uniform_Scale
) : SV_Target
{
    u32 real_material_index = material_index & 0x00ffFFff; // The top 8 bits are reserved for flags.

    Material material = materials[real_material_index];
    colour *= material.colour;

    if(material.flags & TEXTURED)
    {
        Atlas_Texture t = colour_textures[material.texture_index];
        v2 sample_uvs = uvs * t.uv_ratio + t.uv_offset_in_atlas;
        colour *= colour_atlas.Sample(bilinear_sampler, sample_uvs);
    }

    return linear_to_srgb(colour);
}

```

# Answer
> 3 votes
You've lost perspective correctness due to the way you've written your vertex shader.

Ordinarily, we'll transform our vertex from view space to clip space by multiplying it by a projection matrix that looks something a bit like... (depending on your conventions)

$$\begin{bmatrix} a \cdot \cot \frac {fov} 2 & 0 & 0 & 0\\ 0 & \cot \frac {fov} 2 & 0 & 0\\ 0 & 0 & \frac f {f - n} & - \frac {f\cdot n} {f - n}\\ 0 & 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} x\\y\\z\\1 \end{bmatrix} = \begin{bmatrix} x\cdot a\cdot \cot \frac {fov} 2\\ y\cdot \cot \frac {fov} 2\\ \frac {f \cdot z - f \cdot n} {f - n}\\ z \end{bmatrix} $$

You'll notice that this puts the depth of the vertex into the w component.

After this shader has run, the next stage of the graphics pipeline divides the xyz by w (depth), creating the flared shape of the perspective frustum, and ensuring the left/right/top/bottom clipping planes map to x = ±1 and y = ±1 respectively, and the near to far depth range maps to the interval \\$z \in \[0, 1\]\\$ (we call this normalized device coordinates)

Crucially, even after z has been mapped to NDC like this, w still contains the original depth information, which can be used to ensure we get perspective-correct interpolation of all vertex attributes, including texture coordinates.

But in your shader, you've manually performed the conversion to NDC yourself, and output just 1.0 as w. That makes the division by w in the next stage a no-op, so you get exactly the on-screen vertex coordinates that you set, no additional perspective adjustment.

Wait... *no additional perspective adjustment*!?

Yep. To the rest of the graphics pipeline, this polygon appears to be sitting flat on the z=1 plane, facing the camera directly. So it can't detect any tilting or foreshortening that would demand additional perspective correction in the interpolation of vertex attributes. You've destroyed that information before the interpolator stage of the graphics pipeline can use it.

The solution: Don't do your own perspective divide in the vertex shader. Output depth in the w component. That's enough to get correct interpolation of vertex attributes like UV coordinates automatically.

If you need to get a screen position in the fragment shader, be sure to do your perspective divide *there*, on a per-fragment basis. That way the nonlinearity of the perspective projection is retained. Dividing in the vertex shader will give you linear interpolation of screen position over the triangle in 3D space, which will not match the correct interpolation in the 2D space of the triangle's pixels. (Or you can use an input with the `SV_Position` semantic to get a correctly computed position on screen automatically)

---
Tags: projection, uv-mapping, interpolation, directx12
---


# Question
Title: How To Calculate The Correct Sprite Dimensions?
I am creating a 2.5D game similar to Paper Mario. I want the sprites that I import to Unity to be the perfect dimensions so that quality is not affected by the camera's position. If I'm understanding correctly, I need to know how many pixels the sprite is taking up on screen, using my camera's current position, is that correct?

For example, if I want my character to be this size, while my default camera position is this, how do I know what dimensions to make the sprite?

Game Display: 1920 X 1080P

This is the CinemachineVirtualCam following the sprite.

Here is a screenshot of the MainCamera:

I imagine there must be an easy way to figure this out, as many devs seem to know exactly how big to make their sprites. Thanks for taking the time to read!

Kind regards,

# Answer
I'll pretend for a moment that your sprite is billboarded, so it always exactly faces the camera.

At a depth of \\$z\\$ units in front of a perspective camera with (half) vertical field of view \\$fov\\$, the camera sees a rectangular slice of the world that's exactly...

$$h\_\text{world} = z \cdot 2 \tan (\text {fov})$$

...world units tall. That corresponds to \\$h\_\text{screen}\\$ pixels, the height of your screen/window.

So if your screen is 1080 pixels tall, and your camera has a 30° field of view, and is following your character a distance of 5 units along its z axis, then each unit of world space at your character's depth maps to:

$$ppu = \frac {h\_\text{screen}} {h\_\text{world}} = \frac {1080} {(5) \cdot 2 \tan (30^\circ)} = \frac {108} {\frac 1 {\sqrt 3}} \approx 187.06$$

187.06 pixels per unit of world space.

You can use this as the Pixels Per Unit setting in the inspector when importing your sprite, and your sprite's vertical resolution should be the character's height in world space multiplied by this number. (So if you wanted your character to be 1.5 world units tall, that would be \\$1.5 \cdot 187.06 \approx 281\\$ pixels tall).

(Using a field of view whose tangent ratio is a rational number will help you get a nice neat integer here instead of a messy irrational that could experience rounding errors)

Or, you can use any power of 2 times this ppu, and similarly bump up the resolution of your sprite by the same power of two, so that the \\$i^{th}\\$ mipmap exactly matches the screen resolution.

Now, when the sprite is not exactly billboarded to the camera... it gets complicated. Your vertical height will now be foreshortened by the camera's tilt, which will cause the sprite to span fewer on-screen pixels top-to-bottom. But just reducing its height won't fix that, because the rows of texels will no longer be evenly spaced - rows farther from the camera will cluster closer together, and the columns won't be straight verticals, but converging diagonals. That means you will not be able to get a 1:1 match between the grid of sprite texels and the grid of screen pixels, and some interpolation and blurring will have to occur somewhere.

One way around this - without tilting all your characters back so they stand on a diagonal, leading to weird clipping with vertical walls and such - is to not tilt your camera downward. Instead, have it look directly horizontally. Then, use an oblique frustum to shift the image plane vertically, so that you lift up the horizon on the screen, and the portion below the horizon where the camera is looking "down" fills your view. This shift does not disturb the spacing or parallel-ness of a grid drawn in the XY plane, so it won't distort your sprites.
> 0 votes

---
Tags: unity, sprites, graphics
---


title: Particles not rendering over projectors

text:
# Question
Title: Particles not rendering over projectors
I am using projectors for shadows...When I use particles for bike speed up i.e., nitro speed the particles get cutout by those shadows....

Here is screenshot of it,

Here is my shader code of projectors ,

```
Shader "Projector/Projector Multiply Black"
{
    Properties
    {
        _ShadowTex("Cookie", 2D) = "gray" { TexGen ObjectLinear }
    _ShadowStrength("Strength",float) = 1
    }

        Subshader
    {
        Tags{ "RenderType" = "Transparent"  "Queue" = "Transparent+100" }
        Pass
    {
        ZWrite Off

        //Fog { Mode Off }

        Blend DstColor Zero

        CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"

        struct v2f
    {
        float4 pos : SV_POSITION;
        float2 uv_Main     : TEXCOORD0;
    };

    sampler2D _ShadowTex;
    float4x4 unity_Projector;
    float _ShadowStrength;

    v2f vert(appdata_tan v)
    {
        v2f o;

        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

        o.uv_Main = mul(unity_Projector, v.vertex).xy;

        return o;
    }

    half4 frag(v2f i) : COLOR
    {
        half4 tex = tex2D(_ShadowTex, i.uv_Main);
        half strength = (1 - tex.a*_ShadowStrength);
        tex = (strength,strength,strength,strength);
        return tex;
    }
        ENDCG

    }
    }
}

```

Here is my particle code,

```
// Simple additive particle shader.

Shader "Custom/Particle additive"
{
Properties
{
    _MainTexture ("Particle Texture (Alpha8)", 2D) = "white" {}
}

Category
{
    Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    Blend SrcAlpha One
    Cull Off Lighting Off ZWrite Off Fog {Color (0,0,0,0)}

    BindChannels
    {
        Bind "Color", color
        Bind "Vertex", vertex
        Bind "TexCoord", texcoord
    }

    SubShader
    {
        Pass
        {
            SetTexture [_MainTexture]
            {
                combine primary, texture * primary
            }
        }
    }
}
}

```

# Answer
> 0 votes
Seems like the problem is that your shader does multiply blend, not additive blend, contrary to its name. The shadow shader configured to produce fully black color and when you multiply it by particle color, it's still, expectedly, completely black.

# Answer
> 0 votes
To try to give this old Q&A some closure:

The direct cause of this issue is the queue settings that have been applied to the shadow projector and particle system shaders.

The additive particle shader has `"Queue"="Transparent"`, meaning it will render after all of the opaque and alpha-tested content has been drawn. It also has `ZWrite Off`, as we'd expect from a transparent effect, so it does not write to the depth buffer.

The "multiply black" shadow shader has `"Queue" = "Transparent+100"`, meaning it will render *after* anything in the transparent queue above, (and after anything with queue `Transparent+1` to `+99`). Because the additive effect did not write to the depth buffer, the shadow was allowed to draw over the flame, erasing it.

The fix is to change the queue settings so that the shadow renders before transparent effects that you want to render on top of it. Using `"Queue"="Transparent-1"` for the shadow would be suitable.

At the time, OP reported trying to change the queue setting of the flame, to no effect, but there was a bug in a Unity version around that time that could cause it to not handle queue settings correctly \- it's possible this bug gave a false negative when trying to apply this fix.

---
Tags: shaders, unity, particles, shadows
---


title: Change screen size in PyBox2D

text:
# Question
Title: Change screen size in PyBox2D
I would like to use `pybox2d`'s `Framework` class to visualize the simulation. However, the default screen / windows size is 640 x 480 pixels and I don't find a way to change it. I would like to know how I can change the screen size. The code below is a minimal working example:

```
from Box2D.examples.framework import Framework, main
from Box2D import b2EdgeShape, b2FixtureDef, b2PolygonShape, b2Vec2, b2Color

class TestObject(Framework):

    def __init__(self):
        super(TestObject, self).__init__()

        # World
        self.world.gravity = (0.0, -10.0)
        self.world.CreateStaticBody(
            shapes=[
                    b2EdgeShape(vertices=[(-10, 0), (10, 0)]),
                    b2EdgeShape(vertices=[(-10, 0), (-20, 20)]),
                    b2EdgeShape(vertices=[(10, 0), (20, 20)]),
                ]
        )

        obj_vertices = [(0.5, 0.5), (-0.5, 0.5), (-0.5, -0.5), (0.5, -0.5)]

        # Create object
        position = b2Vec2(12, 20)
        linear_velocity = (0.0, -10.0)
        self.obj = self.world.CreateDynamicBody(position=position, linearVelocity=linear_velocity, allowSleep=False)

        density = 1
        height, width = 6, 4
        vertices = [(width * item[0], height * item[1]) for item in obj_vertices]
        shape = b2PolygonShape(vertices=vertices)
        fixture_def = b2FixtureDef(shape=shape, density=density)
        self.obj.CreateFixture(fixture_def)

    def Step(self, settings):
        super(TestObject, self).Step(settings)

if __name__ == "__main__":
    main(TestObject)

```

# Answer
I have not used this framework before, so this is untested, but looking at the code, I would try this first:

One way to go appears to by modify the file `pybox2d/library/Box2D/examples/backends/pygame_framework.py`, where it calls `pygame.display.set_mode` (or `pybox2d/library/Box2D/examples/backends/opencv_framework.py` where it defines the ctor  `def __init__(self, w=640, h=480, resizable=False)`) and set the size you want, but I presume this is a hackish way to do it.

It could get you going for the tests you're doing.

If you need a "cleaner" way, *maybe* what you need to do it is to clone the `pybox2d/library/Box2D/examples/backends/pygame_framework.py` file and implement the `w=640, h=480` in the ctor like it's being done in the other backend, then you would pass the values at object construction in your own test code.

It seems the way to integrate a Framework with a Backend is described at the end of framework.py,

```
# Your framework classes should follow this format. If it is the 'foobar'
# framework, then your file should be 'backends/foobar_framework.py' and you
# should have a class 'FoobarFramework' that subclasses FrameworkBase. Ensure
# proper capitalization for portability.
from Box2D.examples import backends

try:
    framework_name = '%s_framework' % (fwSettings.backend.lower())
    __import__('backends', globals(), fromlist=[framework_name], level=1)
    framework_module = getattr(backends, framework_name)
    Framework = getattr(framework_module,
                        '%sFramework' % fwSettings.backend.capitalize())
except Exception as ex:
    print('Unable to import the back-end %s: %s' % (fwSettings.backend, ex))
    print('Attempting to fall back on the pygame back-end.')

    from Box2D.examples.backends.pygame_framework import PygameFramework as Framework

```

This may not be the complete/right solution but I hope it will help you get started finding it. And whenever you find it, please don't hesitate to write an answer to this question and mark it as accepted :)
> 1 votes

---
Tags: box2d, python
---


# Question
Title: Instantiate only specific objects in Unity
Here is the situation: I have 10 weapons in my game, in main menu player may choose only two weapons that could take to the game, and this information about two weapons will save in a kind of "inventory". So the question is how I could instantiate only two objects from "inventory"?

# Answer
I found the solution by loading from Resource folder. `GameObject weaponOne = Instantiate(Resources.Load("Gun1"), this.gameObject.transform) as GameObject;`
> 0 votes

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


# Question
Title: How to pan and zoom an isometric map on a canvas
I'm new to html canvas.

So far I am following this code as base for simple isometric tiles.

I made an empty isometric grid map that only shows the grid.

I want to offset the position of my isometric map, down and right and vice versa.

The code that I am using as an example has a little map, with a few tiles and its a fixed position, in my code, I made 10x bigger. I want to navigate through my 100 tiles, navigate to the edges.

This is my code

In the example code there is a function **renderTiles**, where it has two function inside that has **renderY + 48**.

**renderTileBackground** and **renderTileHover**

When I increase these values to offset an certain axis,the function **renderTileHover** get buggy, it hovers the wrong tile.

I did follow these instructions for isometric, but I am so lost in this canvas thing.

How do I zoom in and out and pan this isometric canvas grid?

# Answer
> 0 votes
I finally got the right solution, the problem was that there were some variables where the values were fixed and also the values from it was from the code that I was following as reference. It was mismatching with my added logic.

In my old code in the `render()` I had the following:

```
 const render = () => {
  tileStartX = canvas.width / 2 - 50;
  tileStartY = canvas.height / 2 - 200;
  ctx.fillStyle = "#151d26";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  renderTiles(tileStartX, tileStartY);
};

```

Reading this article that I was using also as reference. I changed my code to the following:

```
 ...some code
 let tile_height = 50;
 let tile_width = 100;

 const render = () => {
  let tile_half_width = tile_width / 2;
  let tile_half_height = tile_height / 2;
  tileStartX = canvas.width / 2 - tile_half_width + viewport.x;
  tileStartY = canvas.height / 2 - tile_half_height + viewport.y;
  ctx.fillStyle = "#151d26";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  renderTiles(tileStartX, tileStartY);
};

```

Now I want to share my code, to help anyone who wants to pan in the isometric grid in canvas. This is a basic code of isometric grid with pan to any directions. Use the arrow keys for it.

```
<!-- Code ref
https://codepen.io/zerratar/pen/GMjYyW -->
<template>
  <div id="page-container">
    <div class="top-nav">
      <button class="btn btn-outline-info" id="reset-view">Reset view</button>
    </div>
    <canvas class="le-canvas position-absolute"></canvas>
  </div>
</template>
<script setup>
import { onMounted, reactive, ref } from "vue";
onMounted(() => {
  setTimeout(() => {
    let tile_height = 50;
    let tile_width = 100;
    let resetView = document.getElementById("reset-view");
    let tileMap = [];
    let gridSize = 20;
    let canvas = document.querySelector(".le-canvas");
    let ctx = canvas.getContext("2d");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    let mousePosition = { x: 0, y: 0 };
    let viewport = { x: 0, y: 0 };
    let kbd = {
      ctrl: false,
      u: false,
      d: false,
      l: false,
      r: false,
    };
    // Solution below ref from https://gamedev.stackexchange.com/questions/167038/canvas-infinite-map-how-to-have-reappearing-objects-at-static-x-y-even-when-loo?rq=1
    // Code ref for panning the map https://jsfiddle.net/n8d5kbau/
    document.addEventListener("keydown", (e) => {
      if (e.keyCode === 37) {
        kbd.l = true;
        e.preventDefault();
      } else if (e.keyCode === 38) {
        kbd.u = true;
        e.preventDefault();
      } else if (e.keyCode === 39) {
        kbd.r = true;
        e.preventDefault();
      } else if (e.keyCode === 40) {
        kbd.d = true;
        e.preventDefault();
      } else if (e.keyCode === 32) {
        kbd.space = true;
        e.preventDefault();
      }
    });
    document.addEventListener("keyup", (e) => {
      if (e.keyCode === 37) {
        kbd.l = false;
        e.preventDefault();
      } else if (e.keyCode === 38) {
        kbd.u = false;
        e.preventDefault();
      } else if (e.keyCode === 39) {
        kbd.r = false;
        e.preventDefault();
      } else if (e.keyCode === 40) {
        kbd.d = false;
        e.preventDefault();
      } else if (e.keyCode === 32) {
        kbd.space = false;
        e.preventDefault();
      }
    });

    if (resetView) {
      resetView.onclick = () => {
        viewport = { x: 0, y: 0 };
      };
    }

    let hoverTileX = -1;
    let hoverTileY = -1;

    let tileStartX = canvas.width / 2 - tile_width / 2 + viewport.x;
    let tileStartY = canvas.height / 2 - tile_height / 2 + viewport.y;

    var isMouseDown = false;

    const getMousePos = (canvas, evt) => {
      var rect = canvas.getBoundingClientRect();
      return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top,
      };
    };
    const renderMouseAndGridPosition = () => {
      let mouse_over_grid =
        hoverTileX >= 0 &&
        hoverTileY >= 0 &&
        hoverTileY <= gridSize &&
        hoverTileX <= gridSize
          ? `Grid: ${hoverTileX}, ${hoverTileY}`
          : "";
      ctx.font = "12pt Calibri";
      ctx.fillStyle = "white";
      ctx.fillText(`Mouse: ${mousePosition.x}, ${mousePosition.y}`, 20, 100);
      ctx.fillText(`${mouse_over_grid}`, 20, 120);
    };
    const render = () => {
      let tile_half_width = tile_width / 2;
      let tile_half_height = tile_height / 2;
      tileStartX = canvas.width / 2 - tile_half_width + viewport.x;
      tileStartY = canvas.height / 2 - tile_half_height + viewport.y;
      ctx.fillStyle = "#151d26";
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      renderTiles(tileStartX, tileStartY);
      renderMouseAndGridPosition();
    };

    const renderTileHover = (x, y, width, height) => {
      ctx.beginPath();
      ctx.setLineDash([]);
      ctx.strokeStyle = "rgba(192, 57, 43, 0.8)";
      ctx.fillStyle = "rgba(192, 57, 43, 0.4)";
      ctx.lineWidth = 2;
      ctx.moveTo(x, y);
      ctx.lineTo(x + width / 2, y - height / 2);
      ctx.lineTo(x + width, y);
      ctx.lineTo(x + width / 2, y + height / 2);
      ctx.lineTo(x, y);
      ctx.stroke();
      ctx.fill();
    };
    const renderTiles = (x, y) => {
      let tileWidth = tile_width;
      let tileHeight = tile_height;
      let tile_half_width = tileWidth / 2;
      let tile_half_height = tileHeight / 2;

      if (kbd) {
        if (kbd.l) {
          viewport.x += 3;
        }
        if (kbd.r) {
          viewport.x -= 3;
        }
        if (kbd.u) {
          viewport.y += 3;
        }
        if (kbd.d) {
          viewport.y -= 3;
        }
      }
      // if (viewport.x > 0) viewport.x = -canvas.width;
      // if (viewport.y > 0) viewport.y = -canvas.height;
      // if (viewport.x < -canvas.width) viewport.x = 0;
      // if (viewport.y < -canvas.height) viewport.y = 0;

      for (let tileX = 0; tileX < gridSize; ++tileX) {
        for (let tileY = 0; tileY < gridSize; ++tileY) {
          let renderX = x + (tileX - tileY) * tile_half_width;
          let renderY = y + (tileX + tileY) * tile_half_height;
          let tile = tileMap[tileY * gridSize + tileX];
          //   if(tile !== tiletype_empty) renderTexturedTile(tile_images[tile], renderX, renderY, 80);
          //   else renderTileBackground(renderX, renderY+50, tileWidth, tileHeight);

          renderTileBackground(renderX, renderY + 50, tileWidth, tileHeight);
        }
      }

      if (
        hoverTileX >= 0 &&
        hoverTileY >= 0 &&
        hoverTileX < gridSize &&
        hoverTileY < gridSize
      ) {
        let renderX = x + (hoverTileX - hoverTileY) * tile_half_width;
        let renderY = y + (hoverTileX + hoverTileY) * tile_half_height;

        renderTileHover(renderX, renderY + 50, tileWidth, tileHeight);
      }
    };

    const renderTileBackground = (x, y, width, height) => {
      ctx.beginPath();
      ctx.setLineDash([5, 5]);
      ctx.strokeStyle = "rgba(255,255,255,0.4)";
      ctx.fillStyle = "rgba(25,34, 44,0.2)";
      ctx.lineWidth = 1;
      ctx.moveTo(x, y);
      ctx.lineTo(x + width / 2, y - height / 2);
      ctx.lineTo(x + width, y);
      ctx.lineTo(x + width / 2, y + height / 2);
      ctx.lineTo(x, y);
      ctx.stroke();
      ctx.fill();
    };

    const update = (elapsed) => {
      let mouse_y = mousePosition.y - tileStartY;
      let mouse_x = mousePosition.x - tileStartX;

      hoverTileX = Math.floor(mouse_y / tile_height + mouse_x / tile_width) - 1;
      hoverTileY = Math.floor(-mouse_x / tile_width + mouse_y / tile_height);

      if (isMouseDown === true) {
        if (
          hoverTileX >= 0 &&
          hoverTileY >= 0 &&
          hoverTileX < gridSize &&
          hoverTileY < gridSize
        ) {
          var tileIndex = hoverTileY * gridSize + hoverTileX;
          //   if (tileIndex < tileMap.length) {
          //     let tileType = selectedTileType; // (tileMap[tileIndex] + 1) % tile_textures.length;
          //     tileMap[tileIndex] = tileType;
          //   }
        }
      }
    };

    canvas.addEventListener(
      "mousemove",
      (evt) => {
        mousePosition = getMousePos(canvas, evt);
      },
      false
    );

    const run = (e) => {
      update(e);
      render();
      window.requestAnimationFrame(run);
    };
    run();
  }, 1000);
});
</script>
<style lang="scss">
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: black;
}

#page-container {
  position: relative;
  min-height: 100vh;
}

.top-nav {
  position: absolute;
  top: 0;
  width: 100%;
  height: 10vh;
  z-index: 5;
  background-color: rgba(0, 0, 0, 0.349);
}

</style>

```

---
Tags: html-canvas, isometric
---


# Question
Title: How will I make my character jump only when it is pressed once
I have scoured through the internet to find a solution of this but this is the only solution that I could find but it cancels the `yMove += jumpingVelocity * deltatime` as soon as collision is not detected anymore thus it instantly just goes down. If I remove the `isJumping` the character continues to go up as long as the jump button is pressed.

```
xMove = 0;
yMove = 0;

if (handler.getKeyManager().left) xMove -= movementVelocity * deltaTime;
if (handler.getKeyManager().right) xMove += movementVelocity * deltaTime;
if (handler.getKeyManager().jump && onFloor && !isJumping) {
    yMove += jumpingVelocity * deltaTime;
    isJumping = true;
}
else{
   isJumping = false;
}
// gravity
yMove += gravity * deltaTime;

```

This is the code that updates the player position

```
public void moveX(){

    if (xMove > 0){

        int tx = (int) (x + xMove + bounds.x + bounds.width) / Tile.TILEWIDTH;
        if (!collisionWithTile(tx,(int) (y + bounds.y) / Tile.TILEHEIGHT) && !collisionWithTile(tx,(int) (y + bounds.y + bounds.height) / Tile.TILEHEIGHT) && tx < handler.getWorld().getWidth()){
            x += xMove;
        }
        else{
            x = tx * Tile.TILEWIDTH - bounds.x - bounds.width - 1;
        }
    }
    else if (xMove < 0){
        int tx = (int) (x + xMove + bounds.x) / Tile.TILEWIDTH;

        if (!collisionWithTile(tx,(int) (y + bounds.y) / Tile.TILEHEIGHT) && !collisionWithTile(tx,(int) (y + bounds.y + bounds.height) / Tile.TILEHEIGHT)){
            x += xMove;
        }
        else{
            x = tx * Tile.TILEWIDTH + Tile.TILEWIDTH - bounds.x;
        }
    }
}

public void moveY(){
    if (yMove < 0){
       int ty = (int) (y + yMove + bounds.y) / Tile.TILEWIDTH;

       if (!collisionWithTile((int) (x + bounds.x) / Tile.TILEWIDTH, ty) && !collisionWithTile((int) (x + bounds.x + bounds.width) / Tile.TILEWIDTH, ty)){
           y += yMove;
       }
       else{
           y = ty * Tile.TILEHEIGHT + Tile.TILEHEIGHT - bounds.y;
       }
    }
    else if (yMove > 0){
        int ty = (int) (y + yMove + bounds.y + bounds.height) / Tile.TILEWIDTH;

        if (!collisionWithTile((int) (x + bounds.x) / Tile.TILEWIDTH, ty) && !collisionWithTile((int) (x + bounds.x + bounds.width) / Tile.TILEWIDTH, ty)){
            y += yMove;
            onFloor = false;
        }
        else {
            y = ty * Tile.TILEHEIGHT - bounds.y - bounds.height - 1;
            onFloor = true;
        }

    }

}

```

# Answer
Your code is missing the concept of velocity and inertia. This is what keeps the character rising in the air after the initial thrust of their jump, and what allows them to come to a gradual stop at the peak of their jump and then start accelerating downward. To get this familiar behaviour, you need to track velocity as a persistent physical property of the object that carries over from frame to frame.

Here's a minimal adaptation of your current code to incorporate velocity. The other points BlackGlory raises in the comments above about implementing a movement state machine are also useful improvements, but to keep this answer manageable in scope I'll stick closely to your current version:

```
// Note that we do not zero yVelocity (at least not till we hit the ground!)
xVelocity = 0;

if (handler.getKeyManager().left) xVelocity -= movementVelocity;
if (handler.getKeyManager().right) xVelocity += movementVelocity;

if (handler.getKeyManager().jump && onFloor && !isJumping) {
    yVelocity += jumpingVelocity;
    // From the moment we jump,
    // we're airborne, and can't jump again till we land.
    onFloor = false;
}

yVelocity += gravity * deltaTime;

```

Note that only gravity is scaled by `deltaTime`, because it's an acceleration. Acceleration multiplied by a time interval gives you a change in velocity.

Your other parameters here are velocities already, so they don't need to be scaled by time until we want to integrate them into changes in position:

```
public void moveX() {
    // Now we integrate our velocity by time to get a displacement
    // (change in position)
    float xMove = xVelocity * deltaTime;

    // The rest can stay the same.
    // ...

public void moveY() {
    // Same here.
    float yMove = yVelocity * deltaTime;

    // The rest can stay the same, except your collision clauses,
    // where we need to kill our vertical velocity.
    // ...
        // First: the rising case, where we hit our head on a ceiling:
        else{
           y = ty * Tile.TILEHEIGHT + Tile.TILEHEIGHT - bounds.y;
           yVelocity = 0;
        }

    // ...

        // Then: the falling case, where we stop upon hitting a floor:
        else {
            y = ty * Tile.TILEHEIGHT - bounds.y - bounds.height - 1;
            onFloor = true;
            yVelocity = 0;
        }

```

So here `xVelocity` and `yVelocity` are member variables that persist from frame to frame, and `xMove`/`yMove` have been demoted to temporary variables we use just for integrating our position change and doing collision checks.

You might want to build on this by making your character have some acceleration/deceleration when moving left/right, or carrying some inertia while airborne so they can't stop on a dime in mid-air. To do that, make sure you add similar velocity-zeroing to your `moveX()` function when you hit an obstacle. You can use an acceleration scheme similar to this to let your character accelerate up to but not past a maximum speed, with controllable traction (so you can make them sharper to control on dry ground, and more floaty in the air or slippery on ice)
> 1 votes

---
Tags: java, jumping
---


# Question
Title: How to know what is included in a Unity Asset Store asset
I'm very new to Unity and game development in general.

I'd like to re-create the birch forest demo video shown here. I presume this isn't a scene that comes with your purchase, but just "what you could do"? It looks like you get assets and prefab to put in your own creations using something like Vegetation Studio / Vegetation Studio Pro?

I'd like to know how I can find out whether this scene is included in the asset, or if I'd have to build it myself from the bits and pieces that are included.

I'm emailing the asset seller too, but thought I'd check here first.

# Answer
Nevermind! I see the scenes in the *Package Content* section of the Assets Store item page. Apologies for the noise.
> 1 votes

---
Tags: unity, assets
---


# Question
Title: Smoothing transition between Animator and script controlled character
I have a NPC which has a strict match logic (bot player), and I am moving it on `FixedUpdate()`, However, on certain events in the game I am activating animations which are controlled by the Animator - animations that are not very feasible to script.

So, when I enable the Animator, the position of my character "jumps" to the animation frame position, which causes a very jittery/unsmooth behavior. In order to move between the animations themselves, I use `Animator.Crossfade` which works great, but does not work on the first animation I play when I enable the Animator.

I am trying to find a way to smooth the transition, e.g. using `MoveTowards()` to the first frame position of the animation right before it starts playing, but I couldn't find any workaround that solves this case.

Here's an example of the character and the positions - the character has 3 `Rigidbodies` that I am moving independently.

Origin position when moving with `FixedUpdate()` (no Animator enabled):

Animation 1st frame position:

P.S: Try setting the animation first frame to the (approximately) last `FixedUpdate()` cycle is not really an option, since the position is subject to change, significantly.

Any ideas or ways of implementation would be highly appreciated.

# Answer
> 0 votes
Does something like this work? (On mobile atm, so this is a shot in the dark)

```
float _blendSpeed;
Vector3 _preBlendPosition;
Quaternion _preBlendOrientation;
float _blendInProgress = 1f;

void LateUpdate() {
    if (_blendInProgress >= 1f) return;

    _blendInProgress += Time.deltaTime * blendSpeed;

    float t = Mathf.SmoothStep(0f, 1f, _blendInProgress);

    transform.localPosition = Vector3.Lerp(
         _preBlendPosition,
         transform.localPositiom,
         t
    );

    transform.localRotation = Quaternion.Slerp(
        _preBlendOrientation,
        transform.localRotation,
        t
    );
}

public void StartBlend(float durationSeconds) {
    _blendSpeed = 1f/durationSeconds;
    _preBlendPosition = transform.localPosition;
    _preBlendOrientation = transform.localRotation;
    _blendInProgress = 0f;
    // Trigger your animation here.
}

```

The idea is to save a snapshot of your object's position/orientation just before triggering the animation.

Then, each `LateUpdate`, after the animation has overwritten our position and orientation with the animated values, we blend back toward our snapshot. (This doesn't affect the animated value you get *next* frame, since it doesn't read back "how successful" its last animated update was)

By varying the blend weight over the chosen duration, we smoothly reduce the influence of the snapshot and let the animation take over, easing at both ends to avoid a harsh snap.

(If you had a script/physics-driven velocity/angular velocity at the moment of transition, you may want to integrate your snapshot forward along that velocity each frame to give it some follow-through and blend-out, rather than a hard stop as the transition starts)

Repeat this for each bone transform that needs to be blended. For objects that have rigid body components, you may want to use`MovePosition` and `MoveRotation` instead, with world positions/orientations rather than local, to play nicer with the physics.

---
Tags: unity, animator, npc
---


# Question
Title: Create token in Unity to send post request to Laravel controller
Some time ago I wanted to be able to create a token in Unity and send it to a Laravel Controller for saving logins and user game data to an account.

I eventually got this working so I am sharing my approach.

# Answer
> 0 votes
It is a combination of this tutorial on YouTube: How to Use UnityWebRequest - Replacement for WWW Class - Unity Tutorial and this answer on a similar question: UnityWebRequest POST to PHP not work

The technology I am using:

* Laravel Framework 7.15.0 (PHP)
* Unity: 2019.3.11f1 (script is C#)

Now I am just sending basic forms not images etc - so I haven't tried anything complex but this sends a get to one URL on Laravel which returns the CSRF token.

This is then added as an additional field to the post request.

I am clicking the 2 buttons pretty quickly - I would suggest (and will implement this myself later) that you don't ask for the token until your ready to submit the form - to avoid it expiring if your form is quite long etc.

**The C# Script (Unity)**

Both the functions are set as ON Click() on the buttons in a simple UI Canvas in Unity.

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

public class BasicWebCall : MonoBehaviour
{
    public Text messageText;
    public InputField scoreToSend;
    private string csrf_token;

    readonly string getURL = "http://mazegames.test/leaderboard/1";
    readonly string postURL = "http://mazegames.test/register/1";

    private void Start()
    {
        messageText.text = "Press buttons to interact with web server";
    }

    public void OnButtonGetScore()
    {
        messageText.text = "Getting Token";
        StartCoroutine(SimpleGetRequest());
    }

    IEnumerator SimpleGetRequest()
    {
        UnityWebRequest www = UnityWebRequest.Get(getURL);

        yield return www.SendWebRequest();

        if(www.isNetworkError || www.isHttpError)
        {
            Debug.LogError(www.error);
        }
        else
        {
            messageText.text = "Token Received: " + www.downloadHandler.text;
            csrf_token = www.downloadHandler.text;
        }
    }

    public void OnButtonSendScore()
    {
        if (scoreToSend.text == string.Empty)
        {
            messageText.text = "Error: No high score to send.\nEnter a value in the input field.";
        }
        else
        {
            messageText.text = "Sending Post Request";
            StartCoroutine(SimplePostRequest(scoreToSend.text));
        }
    }

    IEnumerator SimplePostRequest(string curScore)
    {

        Dictionary<string, string> wwwForm = new Dictionary<string, string>();
        wwwForm.Add("_token", csrf_token);
        UnityWebRequest www = UnityWebRequest.Post(postURL, wwwForm);
        yield return www.SendWebRequest();

        if (www.isNetworkError || www.isHttpError)
        {
            Debug.LogError(www.error);
        }

        else
        {
            messageText.text = www.downloadHandler.text;
        }
    }
}

```

**Laravel routes/web.php**

Obviously you need to configure your end points to receive your data, validate and store it if necessary. In this example its just validating the token as part of the post request.

```
Route::post('register/{game_id}', function($game_id) {
    return "Game On!";
});

Route::get('leaderboard/{game_id}', function($game_id) {
    return csrf_token();
});

```

And that is pretty much it - hope this helps someone else.

**Request Token on Submission**

To only get the token when your submitting the form, literally all you have to do is put this line:

```
StartCoroutine(SimpleGetRequest());

```

above the line:

```
StartCoroutine(SimplePostRequest(scoreToSend.text));

```

so that is looks like this:

```
StartCoroutine(SimpleGetRequest());
StartCoroutine(SimplePostRequest(scoreToSend.text));

```

Obviously you could then remove the function `SimpleGetRequest` altogether.

---
Tags: unity, php
---


# Question
Title: Finding point along vector to maintain distance to an arbitrary point
I'm currently working on a particular project where orthographic and perspective projections are both used interchangeably. To keep the transition between both projection modes somewhat seamless, I make use of an adjustable focus point in 3D space. This works really well for my use case, but I'm having a bit of trouble getting some of the vector math right to maintain the distance between the camera and the given focus point when the user is in orthographic mode.

I'll try and demonstrate the problem with a small mock-up drawing below. The actual rendering is in 3D but I don't think this particular problem differs much in 2D.

The red circle is the focus point. It initially exists at **position 1** with a particular distance between it and the camera, and I want to maintain this camera distance when the focus point is moved to **position 2**. One way to accomplish this is to apply the same translation to the camera as the focus point, but I don't want the view itself to visibly shift. What I think I need to do is project the camera along its forward vector by an unknown amount, so that it reaches one of the **blue line** positions so that the distance between **position 2** and the **camera** is still the same. That 'unknown' distance is what I'm trying to solve. It seems that projecting the delta of the two positions along the camera's forward vector is not enough.

While I know how to find the *closest* distance to the line, I can't really see this basic formula being adapted for maintaining a *specific* distance. I feel like I'm failing to grasp some fairly simple math here and would really appreciate if someone could point me in the right direction.

# Answer
**What you've asked for** is easy:

Just draw a circle around your initial focus point, whose radius is equal to your camera's distance from the point, so the circle crosses your camera's axis at the camera's position.

Now draw a circle with the same radius around your shifted point. The (up to two) points where this crosses the camera's forward axis are the points that are the same distance away as the original point was from the camera.

You can find the closest of these two points with a "ray versus circle intersection test" — search those keywords to find existing answers here showing the math. In 3D, it's a ray vs sphere intersection test, but the math is pretty much identical.

But there is a risk that this second circle/sphere sits entirely on one side of the camera's axis and never crosses it. In this situation, no exact solution exists, and the best you can do is fall back to the closest point on the line, or rotate/strafe your camera to follow the point.

**What I think you *actually want*** is even easier though:

If you're doing this to try to control the amount of perspective scaling an object at that point experiences through the camera's linear perspective lens, then it's important to note that this scaling varies based on the *depth* to the point, not the *distance*. That is, take the displacement vector between the camera and the point, and measure only the component parallel to the camera's forward axis, not its entire diagonal length.

This is both easier to compute, and guaranteed to always have an exact solution, so you don't need a fallback strategy like when the line misses the sphere.

```
Vector3 pointShift = point2position - point1position;
float depthShift = Vector3.Dot(pointShift, camera.forward);
camera.position += camera.forward * depthShift;

```

Here assuming `camera.forward` is a unit vector in the direction the camera is looking.

If you're always trying to maintain some fixed depth, this version will be more numerically stable and prevent accumulating rounding errors by taking the target depth as an input:

```
float currentDepth = Vector3.Dot(point2position - cameraPosition, camera.forward);
float error = currentDepth - targetDepth;
camera.position += camera.forward * error;

```
> 0 votes

---
Tags: mathematics, vector, geometry
---


# Question
Title: What is ratio of paper drawing to GameMaker Studio drawing?
I was wondering, if I have character/object on paper (A4 format with grid) and I wish to transfer it to GameMaker Studio, then what should the ratio be between them?

I assume it can't be 1:1 or it will be too small on screen.

To clarify, by ratio I mean 1 square of grid on A4 paper, that I treat as a pixel to pixel in GameMaker Studio.

# Answer
I don't know how many cells the A4 has. I suppose there are a few common ones. Yet, you can even consider a custom grid for your particular needs.

And I don't know how big do you want the result to be on screen. Keep in mind that this is also related to the pixel resolution, screen size, and scaling.

So, you see, I cannot prescribe you a number.

---

But you do know. You have the A4 paper in question, and the size on screen is for you to decide.

Thus: make an A4 worth of pixels at one to one ratio. Then compare it with the size you want. If it is a good result, then that's it.

If it isn't, then you can decide if you are going to use a different ratio based on the size comparison between what you want and what you got. Or if you are going to use the one to one ratio but scale the result afterwards via software.

And if you are yet to produce the drawings in paper, then you can consider printing a custom grid. Or perhaps you can cut and glue some of those A4 to make the size you need. Or make the sprite fully digitally, no paper involved. Or some other solution I might not have thought of… To the strength of the artist and the limitations of the budget.
> 0 votes

---
Tags: game-maker
---


# Question
Title: 2D Vector local to global space without trig/sqrt
Per this answer to this question, a cheap way (i.e., without trig/sqrt) to convert from global to local space, given LocalOrigin, LocalI, LocalJ, and GloablPoint is (in rough pseudo code)

```
Vec2D PointToLocalSpace(Vec2D GlobalPoint, Vec2D LocalI, Vec2D LocalJ, Vec2D LocalOrigin) {
    offset = GlobalPoint.Subtract(LocalOrigin)
    return new Vector2D(
      offset.Dot(LocalI),
      offset.Dot(LocalJ),
    )

```

(where LocalI and LocalJ are two unit vectors at right angles that specify the x and y axis for local space)

What would be the inverse operation (local to global space)?

# Answer
```
WorldPoint = LocalPoint.x * LocalI
           + LocalPoint.y * LocalJ
           + LocalOrigin;

```

Here the * refers to scalar multiplication (ie. scaling the vector's length up or down by multiplying each component by the scalar value)

Checking if this is right:

* If `LocalPoint = (0, 0)`, then we get `LocalOrigin` exactly.
* If `LocalPoint = (x, 0)`, then we get a point `x` units' distance away from `LocalOrigin` in direction `LocalI`, if that's a unit vector, or `x` times the length of `LocalI` more generally.
* And the same for `y` and `LocalJ`.
* Because this is an affine combination, this holds for any linear combination of `x` and `y`.
> 2 votes

---
Tags: 2d, vector, transformation, linear-algebra
---


# Question
Title: Deal damage just once, rather than repeatedly till the enemy dies
I am new to making games with Unity.

I am trying to damage the enemy. So far, the damage works. The problem is it will repeat it until the enemy is dead, but I want it to damage the enemy only once.

```
void Update()
{
    if(Input.GetMouseButton(0) && !isCooldown){
        StartCoroutine(Cooldown());
        Attack();                                                       //ATTACK
    }
}

private void Attack() {
    anim.SetTrigger("attack");

    Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackPoint.position, attackRange, enemyLayers);

    foreach(Collider2D enemy in hitEnemies)
    {
        Enemy.GetComponent<EnemyHP>().TakeDamageEnemy(damage);
        Debug.Log("DamageENEMYYYYYYY");
    }
}

```
* \`Damage| is a public float with a value of 1.
* the `EnemyHP` component has code to remove hit points corresponding to the damage dealt.

I've tested the code out with a `Debug.Log` and it does indeed remove the HP corresponding to the amount of damage. But it repeats the `TakeDamageEnemy` function.

The total hp = 3, so it repeats the code 3 times (the console shows the log 3 times).

How can I change it so it will only play it once?

# Answer
> 1 votes
> The total hp = 3, so it repeats the code 3 times (the console shows the log 3 times).

It seems like you've misinterpreted how the code works. There's nothing in the code that you've shared that would repeat based on the amount of HP that the enemy has. However, your code will repeat the attack each frame that the mouse is held down.

The code you've shared finds all colliders in a circular area, gets the `EnemyHP` component from each collider, and applies damage to each. If the message "DamageENEMYYYYYYY" appears in the console 3 times, that may mean that Physics.OverlapCircleAll() found 3 different enemies (or one enemy with multiple colliders). You can make this more obvious by including information about the enemy in your console output:

```
foreach(Collider2D enemy in hitEnemies)
{
    Enemy.GetComponent<EnemyHP>().TakeDamageEnemy(damage);
    Debug.Log($"Apply {damage} damage to {enemy}", enemy);
}

```

Here, we pass an interpolated string to `Debug.Log()`; within the interpolated string, we can include variables within braces, e.g. `{damage}` will output the value of the `damage` variable.

Notice that I included a second argument to `Debug.Log()`, the `enemy` variable. The second argument is called the "context". If the value we pass for the context is a GameObject or component, clicking on the log message in the Unity Editor will select that GameObject/component. This makes it much easier to quickly find the object that a log message is related to. In this case, if you click on the log message that says "Apply \[...\] damage to \[...\]", it will select the enemy that the damage was applied to.

Your current code has a design flaw - it will throw an error if there are any colliders in the circular area that do not have the `EnemyHP` component. Your code should look like this:

```
foreach(Collider2D collider in hitEnemies)
{
    var enemy = collider.GetComponent<EnemyHP>();
    //this prevents an error if the collider doesn't have the EnemyHP component
    if (enemy != null) {
        enemy.TakeDamageEnemy(damage);
        Debug.Log($"Apply {damage} damage to {enemy}", enemy);
    }
}

```

---

You should also consider changing your `Update()` function. Right now, you're using `GetMouseButton()`, which will repeat each frame that the mouse is held down. The code you shared doesn't have a fully implemented cooldown, so `Attack()` will get called *every frame until you release the mouse*. It's difficult to release the mouse after only one frame, so it's likely that you're initiating multiple attacks each time you click.

If you use `GetMouseButtonDown()` instead, it will only attack on the frame that the user pressed down the button, and won't keep attacking every frame that the button is held down. Once you've implemented the cooldown, you can go back to `GetMouseButton()` if you prefer the attack to automatically repeat after the cooldown if the mouse button is held down.

```
void Update()
{
    //use GetMouseButtonDown instead of GetMouseButton() so the damage
    //doesn't repeat each frame
    if(Input.GetMouseButtonDown(0) && !isCooldown){
        StartCoroutine(Cooldown());
        Attack();                                                       //ATTACK
    }
}

```

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


# Question
Title: Arrow key presses stop affecting game after pressing them 4-5 times
I'm trying to program a simple space shooter and my goal right now is that when the player presses down and holds a key, the ship accelerates to a max velocity.

I have that somewhat; the problem is that when starting the game I can press the directional/arrow keys on my keyboard about 4 or 5 times (in any direction) and get the desired result before further key presses have no effect on the velocity and the ship just floats.

It's like the keyboard gets disabled. Here are the relevant parts of the program:

void Ship::handleEvent( SDL_Event &e ) {
290
291         const Uint8* keystate = SDL_GetKeyboardState(NULL);
292
293         bool keydown = false;
294
295         if ( e.type == SDL_KEYDOWN )
296                 keydown = true;
297
298         if ( keydown ) {
299
300 //              std::cout << std::boolalpha << "keydown: " << keydown << "\n" << "keyup: " << keyup << "\n";
301
302 //              std::cout << holdTime << "\n";
303
304                 if ( keystate[SDL_SCANCODE_UP] && std::abs(mVelY) <= SHIP_MAX_VELOCITY ) {
305
306                         if (mVelY <= SHIP_MAX_VELOCITY) {
307                                 mVelY -= SHIP_ACCELERATION;
308                                 direction = UP;
309                         }
310                 }
311
312                 if ( keystate[SDL_SCANCODE_DOWN] && std::abs(mVelY) <= SHIP_MAX_VELOCITY ) {
313
314                         if (mVelY <= SHIP_MAX_VELOCITY) {
315                                 mVelY += SHIP_ACCELERATION;
316                                 direction = DOWN;
317                         }
318                 }
319
320                 if ( keystate[SDL_SCANCODE_LEFT] && std::abs(mVelX) <= SHIP_MAX_VELOCITY ) {
321
322                         if (mVelX <= SHIP_MAX_VELOCITY) {
323                                 mVelX -= SHIP_ACCELERATION;
324                                 direction = LEFT;
325                         }
326                 }
327
328                 if ( keystate[SDL_SCANCODE_RIGHT] ) {
329
330                         if (mVelX <= SHIP_MAX_VELOCITY) {
331                                 mVelX += SHIP_ACCELERATION;
332                                 direction = RIGHT;
333                         }
334                 }
335
336         }
337
338 // std::cout << std::boolalpha << "keydown: " << keydown << "\n" << "keyup: " << keyup << "\n";
339
340 }

357 void Ship::move() {
358
359                 mPosX += mVelX;
360                 shipCollBox.x = mPosX;
361
362                 if ( mPosX < 0 || mPosX + SHIP_WIDTH > LEVEL_WIDTH || checkCollision( shipCollBox, wall1 ) || checkCollision( ship    CollBox, wall2) || checkCollision( shipCollBox, wall3 ) ) {
363                         mPosX -= mVelX;
364                         shipCollBox.x = mPosX;
365                 }
366
367                 mPosY += mVelY;
368                 shipCollBox.y = mPosY;
369                 std::cout << "mVelY: " << mVelY << "\n" << "mPosY: " << mPosY << "\n";
370 //              SDL_Delay(100);
371         if ( mPosY < 0 || mPosY + SHIP_HEIGHT > LEVEL_HEIGHT || ( checkCollision( shipCollBox, wall1 ) || checkCollision( shipColl    Box, wall2) || checkCollision( shipCollBox, wall3 ) ) ) {
372                         mPosY -= mVelY;
373                         shipCollBox.y = mPosY;
374                 }
375 }
379 void Ship::render( int camX, int camY ) {
380
381         switch (direction) {
382
383                 case UP: shipTextureUp.render( mPosX - camX, mPosY - camY ); break;
384                 case DOWN: shipTextureDown.render(mPosX - camX, mPosY - camY ); break;
385                 case LEFT: shipTextureLeft.render(mPosX - camX, mPosY - camY ); break;
386                 case RIGHT: shipTextureRight.render(mPosX - camX, mPosY - camY ); break;
387         }
388 }
445 int main( int argc, char* args[] ) {
446
447         bool quit = false;
448         SDL_Event e;
449         Ship ship;
450         Projectile bullet;
451         SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
452         init();
453         loadMedia();
454
455         while( !quit ) {
456
457                 while ( SDL_PollEvent( &e ) !=0 ) {
458                         if( e.type == SDL_QUIT ) {
459                                 quit = true;
460                         }
461
462                         ship.handleEvent( e );
463                         bullet.handleEvent( e, ship.getDirection(), ship.getPosX(), ship.getPosY() );
464                 }
465
466                 bullet.update();
467                 ship.move();
468                 camera.x = ( ship.getPosX() + Ship::SHIP_WIDTH / 2 ) - SCREEN_WIDTH / 4;
469                 camera.y = ( ship.getPosY() + Ship::SHIP_HEIGHT / 2 ) - SCREEN_HEIGHT / 4;
470
471                 if (camera.x < 0)
472                         camera.x = 0;
473                 if (camera.y < 0)
474                         camera.y = 0;
475                 if (camera.x > LEVEL_WIDTH - camera.w)
476                         camera.x = LEVEL_WIDTH - camera.w;
477                 if (camera.y > LEVEL_HEIGHT - camera.h)
478                         camera.y = LEVEL_HEIGHT - camera.h;
479
480                 // Clear the screen
481                 SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
482                 SDL_RenderClear( gRenderer );
483
484                 bullet.render();
485                 backgroundTexture.render( 0, 0, &camera );
486                 ship.render( camera.x, camera.y );
487
488                 // Update screen
489                 SDL_RenderPresent( gRenderer );
490                 SDL_Delay(10);
491         }
492
493         close();
494
495         return 0;
496 }

```
</code></pre>

# Answer
Try simplifying your `if` conditions, and enforce the max speed by clamping instead:

```
if ( keystate[SDL_SCANCODE_UP] ) {
    mVelY = std::max(mVelY - SHIP_ACCELERATION, -SHIP_MAX_VELOCITY);
    direction = UP;
}

if ( keystate[SDL_SCANCODE_DOWN] ) {
    mVelY = std::min(mVelY + SHIP_ACCELERATION, SHIP_MAX_VELOCITY);
    direction = DOWN;
}

```

This ensures you can accelerate to your max speed exactly, never exceeding it by any loose change, and it ensures you don't skip processing key presses if you're already travelling at max speed.

Bonus: shorter, simpler, less repetitive code with fewer branches.

There are other problems in this code though. You're handling an `SDL_KEYDOWN` event, but then applying effects from *any* keys that are currently held down. So if I press and hold say the UP button, then rapidly tap an unrelated key like Q, I'll get more vertical acceleration each time I press Q. That's not what you want.

Either read the event's `keysym` field to determine the single key that was pressed in this event, or move this code to your update loop to react to all keys equally, once per frame.
> 0 votes

---
Tags: c++, input, sdl, keyboard, motion
---


# Question
Title: Keep player within screen bounds, top down shooter
I am using x and z axis to go left/right ; up/down respectively. The Camera is on the y-axis.

I have the following code so far -

private float playerWidth; private float playerDepth;

```
private Vector2 screenBounds;

// Other Variables and Initiators

// Start is called before the first frame update
void Start()
{
    playerRigidbody = GetComponent<Rigidbody>();
    screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
    //gives x and y values that will be half the screen value. Screen coordinate system is reversed, so these will be negative values
    playerWidth = transform.GetComponent<BoxCollider>().bounds.size.x / 2;
    playerDepth = transform.GetComponent<BoxCollider>().bounds.size.z / 2;
    // we need half the size as we already are at the center of the object, using clamp
}

```

Tutorials are using SpriteRenderer as this would make more sense in a 2D game, however I am working in 3D space, creating a 2.5D effect.

```
private void LateUpdate()
    {
        withinScreenBounds();
    }

private void withinScreenBounds()
{
    // check if player does not exceed camera view, else stop all movement.
    Vector3 viewPos = transform.position;
    viewPos.x = Mathf.Clamp(viewPos.x, screenBounds.x + playerWidth, screenBounds.x * -1 - playerWidth);
    viewPos.z = Mathf.Clamp(viewPos.z, screenBounds.y + playerDepth, screenBounds.y * -1 - playerDepth);
    transform.position = viewPos;
    // the above will work with the center of the tank.
}

```

The tank is currently jittering between screenpoints, not sure if this has to do with the boxcollider itself.

# Answer
> 1 votes
Change:

`viewPos.z = Mathf.Clamp(viewPos.z, screenBounds.y + playerDepth, screenBounds.y * -1 - playerDepth);`

to:

`viewPos.z = Mathf.Clamp(viewPos.z, screenBounds.z + playerDepth, screenBounds.z * -1 - playerDepth);`

---
Tags: unity, viewport, 2.5d
---


title: Vulkan SSBO Array Of Structs

text:
# Question
Title: Vulkan SSBO Array Of Structs
I am trying to create a Vulkan Storage Space Buffer Object which contains an array of structs for use in my vertex shader. I believe I'm missing something fundamental here because the 1st struct in the array works but all others give garbage data. Heres what I'm doing:

C++ I've got a simple struct defined:

```
struct InstanceData {
    glm::mat4 model;
};

```

Later on I have a vector of these structs which I push data into:

```
std::vector<InstanceData> instanceData;
instanceData.push_back(InstanceData());
instanceData.push_back(InstanceData());

```

And finally memcpy the data from our vector into our VkBuffer (managed by VMA):

```
memcpy(instanceStorageSpaceAllocations[currentImage]->GetMappedData(), instanceData.data(), sizeof(InstanceData) * instanceData.size());

```

In our vertex shader, I am attempting to access this data like so:

```
layout(std140, binding = 0) readonly buffer InstanceData {
    mat4 model;
} ssbo[];

void main() {
    gl_Position = PushConstants.view_proj * ssbo[gl_InstanceIndex].model * inPosition;
}

```

Back in C++, we VkCmdDrawIndexed with the amount of instances currently in our instanceData vector:

```
vkCmdDrawIndexed(CmdBuffer, static_cast<uint32_t>(_GLTF->Indices.size()), 1, instanceData.size()-1, 0, 0);

```

So, however many instances of InstanceData we push into our instanceData vector will be drawn by the GPU.

When setting up our SSBO descriptor we do like so:

```
VkDescriptorBufferInfo bufferInfo = {};
    bufferInfo.buffer = StorageBuffers[i];
    bufferInfo.offset = 0;
    bufferInfo.range = VK_WHOLE_SIZE;

```

VK\_WHOLE\_SIZE is used here so it uses the entire size of the VkBuffer (because we will resize the buffer when it becomes to small to hold all our InstanceData objects).

So this works for the 1st instanced draw (when instanceData.size() == 1), but any after results in garbage data when accessing the SSBO from within our shader.

Any ideas about what I'm doing wrong here..?

# Answer
I was doing 3 things wrong here.

First, the parameters of my VkDrawIndexed call were swapped:

```
vkCmdDrawIndexed(CmdBuffer, static_cast<uint32_t>(_GLTF->Indices.size()), instanceData.size(), 0, 0, 0);

```

Second, my shader was incorrectly accessing the data:

```
layout(std140, binding = 0) readonly buffer InstanceData {
    mat4 model[];
} ssbo;

void main() {
    gl_Position = PushConstants.view_proj * ssbo.model[gl_InstanceIndex] * inPosition;
}

```

Third, even though I was using VK\_WHOLE\_SIZE when setting up the SSBO Descriptor, I needed to call VkUpdateDescriptorSets again after every time that I increase the size of the SSBO VkBuffer.

All works as expected now.
> 2 votes

---
Tags: instancing, vulkan
---


# Question
Title: Mirror a 3d position vector3 based on a vector3 and rotation
I have a point in 3d space and a coordinate with angle (a imaginary plane)

**Here's my input data :**

A ) a vector3 which defines a position in world space

B ) a vector3 which defines a mirror position

C ) a vector3 which defines rotation of mirror in Euler

**Now i want to mirror A based on B and C** (orange point)

# Answer
If you use normal vectors to define the plane, you can use Vector3.Reflect:

```
public Vector3 GetMirroredPos(Vector3 mirrorPos, Vector3 mirrorNormal, Vector3 inputPos)
{
    var v1 = mirrorPos - inputPos;
    var v2 = Vector3.Reflect(v1, mirrorNormal);
    return mirrorPos - v2;
}

```

If you define the plane using Euler angles, you can convert it to a direction vector like this:

```
public Vector3 EulerToDir(Vector3 euler)
{
    return Quaternion.Euler(euler) * Vector3.forward;
}

```

Using a rotation to define a plane is not enough, you need to know its initial orientation. So it's better to use the normal vector to define it.
> 1 votes

---
Tags: unity, c#, 3d, mathematics
---


# Question
Title: Get connected GameObject information in unity C#
I am working on a project where I want to know which nodes are connected with the connection Hub. Like the picture below:  These nodes are the game objects and I want to know their connection status with connection hub. Remember the connection is breakable on runtime. So any time user can break the chain within two nodes or multiple nodes. Then, the subsequent node should know that the connection has broken. I am currently trying to write its solution. One way I think to do this:

1. attach a script with each object.
2. Get a list of upward connected nodes information and check each connection state.
3. Check the upward node information one by one, if all are okay it means the connection is right otherwise it is disconnected.

But this approach required manual work. Like I have to identify each node that is part of my connection chain and then manually assign it. So is there anyway to do this task? Using events or tirgger.

# Answer
> 0 votes
I would solve this by turning each chain into a linked list with each node having a reference to the next node in the chain. So you can find out it a node is connected by following that chain of references until you find a node which is either a hub (then it is connected) or a node which doesn't have a next node (then it is not connected).

That means we have two kinds of nodes, `ConnectionHub` and `ConnectionNode` which both inherit from an abstract base class `Connectable`.

The abstract base class for both would define the method needed to find out if there is a hub connection:

```
public abstract class Connectable : MonoBehavior {
    public abstract bool isConnectedToHub();
}

```

The regular nodes have a public variable `connectedTo`. This variable needs to be assigned to the next Connectable, which can be a hub, another node or nothing if the node is disconnected. If you call the `isConnectedToHub()` method on a regular node, it would return false if it isn't connected. If it is connected, it would delegate the response to the next node up the chain:

```
public class ConnectionNode : Connectable {
     public Connectable connectedTo;
     public override bool isConnectedToHub() {
          if (connectedTo == null) {
              return false;
          } else {
              return connectedTo.isConnectedToHub();
          }
     }
}

```

The connection hub has no next node. It would return `true`. That result would then get passed down the call chain and back to the original caller:

```
public class ConnectionHub : Connectable {
     public override bool isConnectedToHub() {
          return true;
     }
}

```

---

**Alternative solution:**

When link changes are relatively rare events but checking if a node is connected happens a lot, then the above solution might get unperformant. Especially if you have very long chains and keep checking different members of the same chain over and over again. It would be better if each node would know whether or not it is connected right now, so you don't need to reevaluate it all the time.

In that case you could also do it the other way around: Nodes don't know their parent, they know their descendant. When a node gets disconnected, then it propagates this status down the chain to set all its descendants to disconnected.

When a node gets a new descendant, then it first disconnects the old descendant as previously described and then passes on its own connection status (connected or not) down the new descendant chain.

```
public class ConnectionNode : MonoBehaviour {

     private ConnectionNode descendant;
     private bool isConnectedToHub;

     public void DisconnectDescendant() {
         if (descendant != null) {
             descendant.SetConnected(false);
             descentant = null:
         }
     }

     public void ConnectNewDescendant(ConnectionNode newDescendant) {
         DisconnectDescendant();
         descendant = newDescendant;
         descendant.SetConnected(isConnectedToHub);
     }

     private void SetConnected(bool newConnectionStatus) {
         isConnectedToHub = newConnectionStatus;
         if (descendant != null) descendant.SetConnected(newConnectionStatus);
     }
}

```

If you want to turn a node into a hub node, you just need to call `SetConnected(true)` on that node. That will make all its descendants connected nodes and also cause the node to mark any future descendants it receives as connected.

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


# Question
Title: Efficiently pass one uniform value per polygon or quad to the fragment shader in a single batched draw call in WebGL?
I want to render multiple colored quads, with one solid color per quad, using WebGL 2.0 and Javascript. However, this question is probably generalisable to other OpenGL implementations as well.

The default way to pass a color to the fragment shader seems to be a through a uniform. However, I have many quads each with it's own color. For performance reasons, I need to batch render them with one draw call. And I can't do that if I have to change the uniform for every quad.

The next solution seems to be to include the color in the vertex buffer and pass them as a attribute to the vertex shader and from there as a varying to the fragment shader. This works, but to me it seems very inefficient. Firstly, I need to repeat the color four times per quad, increasing the traffic from the CPU to the GPU. Secondly, the GPU has to interpolate my solid color whish is just pointless calculations.

Isn't there a more straight forward way to solve this fairly simple problem without wasting performance? Could I somehow list the colors in an array and get WebGL to pick one element from the array per polygon or quad?

Or in more general terms: How do I efficiently pass one uniform value per polygon or quad to the fragment shader in a single batched draw call?

# Answer
You could use `gl_VertexId` to get the index of the vertex you're transforming in the vertex shader.

From this we can compute a triangle or quad index if your indices follow a predictable pattern. For instance, if they go:

```
0, 1, 2, 2, 1, 3, 4, 5, 6, 6, 5, 7...

```

then you can divide by 4 and floor the result to get an index of the quad:

```
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1...

```

Output this quad index value as a varying sent to the fragment shader, where it's used to look up into a uniform array of colours.

If you object to the overhead of interpolating this index when it should be the same for every fragment in a polygon, you can try declaring the varying with the `flat` keyword, so only the value from the "provoking vertex" is used for the whole polygon, though I don't know if you actually save any performance this way.

Or you could look up from the array in the vertex shader and pass the resulting colour — the extra interpolation might be faster than the array lookup on every fragment, but you'd have to test to find out for certain.

Be sure to profile this versus the conventional approach of just adding vertex colour attributes. While it's 3-4x the memory use, it's also more conventional. Doing things in more "inventive" ways can sometimes disable an optimized fast path and lead to unexpected pessimization.
> 2 votes

---
Tags: opengl, rendering, webgl, batching
---


# Question
Title: Using cubemap in view space for shadowing in deferred rendering
I want to render shadows for point lights with a cubemap. My shader uses view space for lighting (directional and point). So I convert ligthposW/lightfocusW in world space to ligthposV/lightfocusV in view space by doing ligthposW x View and lightfocusW x view. ligthposV-lightfocusV gives me the direction of light and direction of pointlight to pixel in view space that I use for doting to normals in view space. Works fine for lights and directional shadows.

I have difficulties to use the same idea for shadowcube mapping in view space. The idea is to use the same light to pixel direction calculated in viewspace to save some instructions.

Currently I'm falling back to world space for point lights shadows. Consequently the shadowcube is filled with depth of object in world space (World x LightViewProj)

so the goal is to do ShadowCubeMap.Sample(point, direction in view space).r.

I've tried to adapt the method I use for directional shadows in viewspace (Shadowmapping in view space) doing the following:

given:

```
 LPosR[n] the position of pointlight[n] in the world
 vLookDir[Face], vUpDir[Face] the usual vectors used to orient the projection in cubemaps
 gLightProjectionCube = XMMatrixPerspectiveFovLH(XM_PIDIV2, 1, 0.5, 1000); the projection matrix for cubemap shadows

```

CPU settings

```
for (DWORD l = 0; l < cMaxLight; l++)
for (DWORD f = 0; f < 6; f++)
{
    XMVECTOR vEyePt = XMVectorSet(LPosR[l].x, LPosR[l].y, LPosR[l].z, 1);
    gLightViewProjCube[l][f] = XMMatrixLookAtLH(vEyePt, vEyePt + vLookDir[f], vUpDir[f])*gLightProjectionCube;
}

```

Use these matrices to render the cubemaps in world space

I’m also having some light data in view space:

```
LPosV[n] = LPosW[n]*View
InvViewLightViewProj[n][face]= Inverse(View of scene)* gLightViewProjCube[n][face]

```

At deferred pass

```
Get Posisition in view space PosV
Get direction of pos to light in view space txDirV = PosV – LPosV[n]
Use txDirV to sample the cubemap[n] to get Depth
Get Projected data dPS for shadow
float4 dPS = mul(PosV, InvViewLightViewProjCube[n][Face]);
Shadow*=( Depth *dPS.w < dPS.z )? 0.5:1;

```

What I see is a rotating shadow as my scene is rotating, the shadowed part being not fully opaque (see picture). txDirV is clearly not compatible with orientation in worldspace of my cubemaps. I can imagine multiplying txDirV by InverseView but I’m not sure it will work and it adds more instructions. Alternatively is it an option to change in view space the vLookDir\[f\], vUpDir\[f\] used for creating the cubemap matrices ?

Another option is a correct setting of the matrices used to render the cubemap but I don't see how to proceed. I've tried to pass view space data (Position, (View or inverseview)\*gLightViewProjCube) to the geometry shader used for rendering cubemaps but the shadows are still not correct.

# Answer
> 0 votes
Finally the idea of transforming the direction was ok. I had search for an equivalent of converting normals to view space to reorient my cubemap projection direction.

so:

Get the inverse of View, view being the scene view matrix.

```
 I_View[n] = Inverse(View);

```

pass it to the constant buffer,

```
TI_View[n] = Transpose(I_View[n]);//transpose for directx

```

in the shader get the direction of point to light in view space, PosV being the position in viewspace of the pixel and LPosV the position of light in view space, convert back to world space, and sample

```
txDirV = PosV - LPosV[n];
txDirV = mul (txDirV, (float3x3)TI_View[n]);//not necessary to normalize, we just want the direction
float D = txShadowCubeMap[n].SampleLevel(samLinear, txDirV, 0).r;

```

not a big boost but a couple of instruction removed compared to calculating the shadow in world space when your deferred pipeline is all in view space.

---
Tags: shadow-mapping, deferred-rendering, view
---


# Question
Title: How do I convert from Cartesian to spherical coordinates?
This seems like a fairly basic and common problem. Is there a builtin way to achieve it or do I have to write the algorithm on my own? If I do, how should it work?

# Answer
Not that I'm aware of (you're asking if there's some sort of glsl function that would do the conversion, right?)

It's a pretty simple conversion though, just three lines; here it is in pseudocode:

```
r = sqrt(x*x+y*y+z*z);
theta = atan2(y,x);
phi = atan2(sqrt(x*x+y*y),z);

```
> 4 votes

# Answer
This did not helpe me achieve a full sphere coordinate conversions, I always got all my coordinates for a sphere in only half the sphere whether using atan with one parameter (atan(y/x)) or with two (atan(y, x)).

Here's what worked for me. I based the calculations on the formulas in https://en.wikipedia.org/wiki/Spherical\_coordinate\_system .

In this example vertex shader, the radius is distorted based upon phi and theta.

```
const float PI = 3.1415926535897932384626433832795028841971693993751058209749;

float getPhi(in float y, in float x)
{
    if (x == 0.0) {
        if (y == 0.0) {
            return 0.0;
        } else if (y > 0.0) {
            return PI/2.0;
        } else {
            return -1.0 * PI/2.0;
        }
    } else if (x > 0.0) {
        return atan(y/x);
    } else if (x < 0.0) {
        if (y >= 0.0) {
            return atan(y/x) + PI;
        } else {
            return atan(y/x) + PI;
        }
    }
}

vec3 toPolar(in vec3 cart)
{
    float xySquared = (cart.x * cart.x) + (cart.y * cart.y);
    float radius = sqrt(xySquared + (cart.z * cart.z));
    return vec3(radius, atan(sqrt(xySquared), cart.z), getPhi(cart.y, cart.x));
}

vec3 toCartesian(in vec3 sph) {
    return vec3(
        sin(sph.y) * cos(sph.z) * sph.x,
        sin(sph.y) * sin(sph.z) * sph.x,
        cos(sph.y) * sph.x
    );
}

void main()
{
    float disp = 2.0;
    vec3 sphericalPt = toPolar(position);

    vec3 sphericalDisp = vec3(
        sphericalPt.x + sin(position.x * 2.0 + position.y * 5.0 + position.z * 12.0 ) * disp,
        sphericalPt.y,
        sphericalPt.z
    );

    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(toCartesian(sphericalDisp), 1.0);
}

```
> 1 votes

---
Tags: opengl, glsl, coordinates
---


# Question
Title: Change the "Font Asset" of every TextMeshPro object
I have a large project in Unity and I would like to change the font for every TextMeshPro Object in every scene. I've tried changing the "Default Font Asset" in Edit \> TextMesh Pro \> Settings but it doesn't work as I wished. It change the font of newly created TextMeshPro Object but old one have still the old font.

The working solution I found is renaming my Font Asset file. For example, my old font was "LiberationSans SDF.asset" and my new font is "Almendra-Regular SDF.asset" so I just rename "Almendra-Regular SDF.asset" into "LiberationSans SDF.asset" and it works.

However, this solution is... dirty. Is there a better web to change the font of every TextMeshPro Object in every Scene ?

# Answer
I think your solution of renaming the file in your file explorer is quite good, actually. You can then rename it back to the name you *want* inside Unity, and all the assets will point to the correct font.

The reason is that Unity assets reference each other not by name, but by GUID. The GUID is stored in the .meta file of the same name that you'll find alongside the asset file in your file explorer (though you may need to enable showing hidden files to see it).

By renaming the source file, you pair your new font asset with the existing asset's GUID, so all the existing files point to it now.

You could accomplish something similar by just renaming LiberationSans.ttf.meta to your new font's name (and placing it in the same folder). Then the existing GUID would point to your new font, and Unity would generate a new GUID for LiberationSans.ttf upon noticing that it doesn't have a .meta file of its own anymore.

Or, if you have settings on your new font asset that you want to preserve, you can open up the two assets' meta files and swap their GUIDs. Here's what LiberationSans.ttf.meta looks like for me:

```
fileFormatVersion: 2
guid: e3265ab4bf004d28a9537516768c1c75
timeCreated: 1484171297
licenseType: Pro
TrueTypeFontImporter:
  serializedVersion: 2
  fontSize: 16
  forceTextureCase: -2
  characterSpacing: 1
  characterPadding: 0
  includeFontData: 1
  use2xBehaviour: 0
  fontNames: []
  fallbackFontReferences: []
  customCharacters:
  fontRenderingMode: 0
  userData:
  assetBundleName:
  assetBundleVariant:

```

So copying that second line into your new asset's .meta, and vice versa, will swap their IDs so that any reference that had pointed to one now points to the other.

You could also write an editor script that uses the `UnityEditor.AssetDatabase` class to iterate over all scenes/prefabs/etc. searching for font references to remap, which would be a more robust/less hacky solution. But for a one-off global replace, mucking with the files this way will probably save you hours of debugging such a script.
> 1 votes

---
Tags: unity, text-mesh-pro
---


title: LookRotation/object roll issue in Unity

text:
# Question
Title: LookRotation/object roll issue in Unity
I was hoping to get some help with a `LookRotation()` issue I've been having in Unity/C#.

In my project I have a target that attaches to the camera when clicked on (think of it like grabbing an object off a shelf with your hand and pulling it close). While the object is being pulled towards the camera it needs to remain facing the camera at all times including when the camera itself rotates; either horizontally or vertically. The object can also be dragged on screen with the mouse.

To ensure the object faces the camera I basically use the following code:

```
Vector3 direction = (target.transform.position - Camera.main.transform.position).normalized;
Quaternion lookTarget = Quaternion.LookRotation(direction, Vector3.up);
target.transform.rotation = lookTarget;

```

While this will ensure that the object remains facing the camera it also causes the target to roll in its forward axis when the camera rotates up or down. If the target is grabbed while the camera x rotation is off centre, the target will also have increased roll. The greater the camera rotation is in x, the greater the target will roll.

In the image below I've grabbed the left object and attached it to the left side of the screen; note the roll introduced in the 2nd image compared with the first. The rotation of the object in image 1 is what I would like to replicate in image 2.

I note that the following code can correctly adjust the roll as desired (10 degrees in this case):

```
lookTarget *= Quaternion.AngleAxis(10f, Vector3.forward);

```

However, I'm unsure how much to adjust the roll by as the roll amount will vary based on the camera's rotation in x. I'm not sure what the relationship is between the two or how to calculate it.

I've also tried other things like multiplying the `lookTarget` value by the camera rotation and using Vector3.right as the upwards parameter in the `LookRotation()` method (works but not for different y camera rotation values).

Any help would be great to hopefully understand this better and resolve the issue.

# Answer
Try this. At the moment you grab the object:

```
upInView = Camera.main.transform.InverseTransformDirection(pickedObject.transform.up);

```

This remembers how the object's "up" vector was tilted relative to the view orientation at the moment of the grab.

Then each frame the object is held:

```
Vector3 viewRelativeUp = Camera.main.transform.rotation * upInView;
pickedObject.transform.rotation = Quaternion.LookRotation(direction, viewRelativeUp);

```

This keeps the object's "up" direction relative to the camera view orientation fixed.
> 0 votes

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


# Question
Title: Why is Canvas used more than JPanel for making games in Java?
I saw many Ludum Dare games, which are written in Java (using its standard library). I checked the code of one or two of them and the thing that I saw is in their Game `class`, they extend `Canvas`.

So my question is why would they extend `Canvas`, not `JPanel`?

# Answer
Without seeing the actual code, it's difficult to say. However, I would guess that they are using both Canvas and JPanel somewhere (or at least some form of JPanel, e.g. JFrame or Applet etc..) and simply extending the game class from Canvas to make it more portable, i.e. so it can be added to a JPanel (or whatever) later.
> 1 votes

# Answer
Very interesting question. I developed a game with JPanel in Linux and at the end discovered that it was not functioning in Windows (`getBufferStrategy null`). Switching to canvas fixed the problem for me.
> 1 votes

# Answer
As mentioned in the API

## Canvas extends Component

**Component:**

> A component is an object having a graphical representation that can be displayed on the screen and that can interact with the user.

**Canvas**

> A Canvas component represents a blank rectangular area of the screen onto which the application can draw or from which the application can trap input events from the user.

## JPanel extends JComponent

**JComponent**

> The base class for all *Swing components* except top-level containers.

**JLabel**

> JPanel is a generic lightweight container.

## summary

if you do not implement a Swing Application then you forgo JComponents and stick with the basic Components.
> 1 votes

---
Tags: java
---


# Question
Title: Get component of velocity parallel to a normal
I would like to transform a rigidbody's world velocity into a local velocity based on a normal direction.

When the rigidbody is moving towards and within a range of a object, I use a raycast to determine the hit position and normal of the face it will collide with. I have the velocity of the RB in world space, but I would like to have it in the normal's reference frame.

I know a `Transform` component can do `InverseTransformDirection()`, but seeing as the normal is most likely not aligned to its transform, this is not going to work.

I want to know the velocity an object collided with a face, but only in the face's normal direction. The outcome of this is to apply a force to the rigidbody in the normal's direction and thus stopping the rigidbody from moving any closer to the hit point. The force will be calculated by looking at the component of the rigidbody's velocity that is in the same direction the normal. My thinking is, that if I can get the RB velocity into the reference frame of the normal, it will be just the UP component that I need to look at: the speed the RB is moving along the normal towards the hit point.

If you can imagine (all in world space) a ball dropping on the floor: when this ball is one radius away from the floor, there will be a contact point and the normal will be perpendicular to the floor. To arrest the fall of the ball, a force in the direction of the normal is applied (so UP). The strength of this force is the down component of the velocity. If the ball was moving horizontally while dropping, the DOWN component of the velocity that matches the normal direction in this case is what I am interested in.

Basically I want the velocity of the RB that as seen from the normal along its axis. Almost like saying I want to transform the world space velocity into a local mesh face space, but only the UP axis.

# Answer
If you just want to do something with the component of the velocity parallel to the normal, that's just a vector projection, and you don't need to do a full transformation into a local coordinate system with that ambiguous degree of freedom.

Assuming your normal has unit length, that's:

```
// Measure incoming speed along normal direction.
float normalSpeed = Vector3.Dot(rb.velocity, normal);

// Cancel out the velocity in that direction.
rb.AddForce(-normalSpeed * normal, ForceMode.VelocityChange);

```

This is also available as a built-in function in Unity:

```
rb.AddForce(
    -Vector3.Project(rb.velocity, normal),
    ForceMode.VelocityChange
);

```

This is why it's important to always frame questions in terms of the ultimate goal you want to achieve, not the stepping stone you thought of to get there. If you don't understand the problem well enough yet to fully solve it, then you might not be picking the right stepping stone, leading to something called the XY Problem. Here, asking to transform to local coordinates was a red herring, that made the solution more complicated than it needed to be.
> 2 votes

---
Tags: unity, physics, vector, transformation, linear-algebra
---


title: Setters and Getters in ECS?

text:
# Question
Title: Setters and Getters in ECS?
So I'm currently working on a Game Engine for my University and I came to the point of integrating an ECS.

Thing is, I'm currently a bit unsure if it's okay to have setters and getters for specific classes. Like implementing a setter for my transform that lets the system that accesses the transform component easily add relative rotation/movement. I also tried to outsource these functions into a separate util class. Especially in cases where I would call the component from multiple systems which would lead to duplicate code if I didn't have any sort of setter or util class.

Now what I'm wondering do I waste some of the efficiency of the ECS and Memory alignment by including those setters/getters or does that not matter? I'm a little confused here due to the statement "components should be pure data".

# Answer
Please keep in mind that there is no ECS police.

Typically, you'll want to have code that's easy to read first, then fully optimized second, because you know you need it fully optimized (because you profiled it and realized it was a bottleneck).

I doubt adding getter/setters to a component to ease the reading of the code and the interaction with the class will make any noticeable difference in performance.

Yes, components should be about data only, and having setters/getters that "massage" data still count as "data only" because your component will not *do* anything.

One point, though, I doubt the concept of "transform" is specific to a transformComponent, and so you could very well develop a Transform class and put all the utility functions you've developed in there. A Transform is still only data. Just a bit more complex than a `int healtPointsLeft;` variable.

So,

> I'm wondering do I waste some of the efficiency of the ECS and Memory alignment by including those setters/getters or does that not matter?

I would suggest you go with either the setters/getters, or with using a Utility class that allows you to deal with your data, what's the most appropriate for each component.
> 2 votes

---
Tags: entity-component-system
---


# Question
Title: How to calculate screen space UV coordinates from a specific camera
In Unreal Engine 4.27 I am currently trying to create a material (shader) that maps a texture onto a quad using the screen space coordinates from a specific camera. If I am using the current active camera ScreenAlignedUvs node works perfect. The problem however is that in my scene I have 2 cameras, one whose screen space uvs will be used when rendering the texture, and the other which will needs to use the UVs of the first camera. For illustration purposes you can picture the mesh this is applied to as a TV screen which looks like a normal TV to everyone except for one person which the TV appears to follow. To this special person the TV basically appears to be a portal. The picture below is a rough drawing of the example (Red is the special person and their view, Blue is a normal person, Black is the TV, Green are the u part of the uv coordinates).

I would also like to point out that I am aware there could be issues when the main camera is not viewing parts of the mesh that is visible to secondary cameras. In this case I think it is fair for the UVs to be undefined/random.

Here is an example of the current scripts I am using with @DMGregories hit about using the VP matrix of the camera.

Blueprint (Event Tick function)

Material

While debugging UE returned a projection view matrix of:

```
[-0.000002,  1.0,        0.0,       0.0]
[-1.0,      -0.000002,   0.0,       0.0]
[0.0,        0.0,        1.777778,  0.0]
[299.999969, 0.00067, -355.555573, 10.0]

```

For a camera located at: `(0, 300, 200)`

Facing a plane at: `(0, -300, 200)`

During this test the UVs are always `(1.0, 1.0)` for some reason.

# Answer
After a lot of testing/trial and error I was finally able to figure out the effect. Before I jump into it some credit goes to DMGregory for providing the original mapping algorithm and a bit of debugging advice, I am not sure why but his and my comment chain disappeared after I updated the original question with more information.

There were several issues with my original design: 1.) The first pin in a vector parameter are the RGB/XYZ channels (does not include A/W) 2.) The result of the dot product function in the material is a scalar number, not a vector. This means that they should not be added together but instead appended together to create a single vector. 3.) As DMGregory suggested, the matrix needed to be transposed. 4.) The W value of the plane needs to be written to the A value of the color (this was in the original image but I accidentally removed this while testing).

You can see the final result below (I realize this looks just like a normal UV map at the moment)

Blueprint Update

Blueprint Helper Functions

Shader
> 1 votes

---
Tags: shaders, camera, unreal-4, unreal, materials
---