## Recommended Posts

Posted (edited)

I am trying to get the time stepping working consistently in an asteroids project.  The application runs fairly smoothly but when really looked at there are some pretty slight variances in motion.  I have looked at http://www.koonsolo.com/news/dewitters-gameloop/  and https://gafferongames.com/post/fix_your_timestep/.  I tried to write something similar to the first link but did not really notice a difference.

Here is the first article:

 const int FRAMES_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;

DWORD next_game_tick = GetTickCount();
// GetTickCount() returns the current number of milliseconds
// that have elapsed since the system was started

int sleep_time = 0;

bool game_is_running = true;

while( game_is_running ) {
update_game();
display_game();

next_game_tick += SKIP_TICKS;
sleep_time = next_game_tick - GetTickCount();
if( sleep_time >= 0 ) {
Sleep( sleep_time );
}
else {
// we are running behind!
}
}

This article said there would be no problems on computer's that are fast enough, and this does not seem to be true.  Perhaps the slight variations are as good as it is going to get?

Here is the second article:

double t = 0.0;
double dt = 0.01;

double currentTime = hires_time_in_seconds();
double accumulator = 0.0;

State previous;
State current;

while ( !quit )
{
double newTime = time();
double frameTime = newTime - currentTime;
if ( frameTime > 0.25 )
frameTime = 0.25;
currentTime = newTime;

accumulator += frameTime;

while ( accumulator >= dt )
{
previousState = currentState;
integrate( currentState, t, dt );
t += dt;
accumulator -= dt;
}

const double alpha = accumulator / dt;

State state = currentState * alpha +
previousState * ( 1.0 - alpha );

render( state );
}

As I understand it this program takes whats left over in the accumulator and blends it with an interpolation.  I have read that this is a pretty famous article.  I am wondering about the variables previousState and currentState.  I assume the passed in variable to integrate is a reference to hold the value for next time?  And in the final line before the render, the 2 states that are being multiplied by the 2 alphas are what, maybe my x and y?

The variable Previous is previousState and current is currentState?

Will this be even any better though as my understanding is I would need a previous and current x and y for every object and there is a function call for each draw.

I would also have to run the while over and over again and and than the two lines below it over and over again.  These two procedures in themselves would seem to slow the game down more than what it is now.

I could really use some help, please.

Thank you,

Josheir

Edited by Josheir

##### Share on other sites
Posted (edited)

This comes down to preference depending on your requirements. I personally run my logic and input at a fixed tick rate, then render as many times as possible until the next tick is due. If the ticks take too long, I just force a draw and let the program slow down. This would rarely happen as those rates are normally under 30 per second. Interpolation becomes a requirement with this method because your render rate is not fixed.

I handle interpolation like this (You need a Prev Position, Current Position, and Draw Position - in this case spritePrevPos, spritePos, and testSprite):

In your logic update you need to have your spritePrevPos = spritePos before any updates happen to track. Then when you move your object you're updating your spritePos. In the draw phase you would interpolate the visual spot the sprite should be at to smooth out motions base on the time passed.

(This happens outside of of your logic and update loop)

interpolation = float(((mainClock.getElapsedTime().asMilliseconds() + skipTicks) - nextTick)) / (skipTicks);

testSprite.setPosition(spritePrevPos.x + ((spritePos .x - spritePrevPos.x) * interpolation), spritePrevPos.y + ((spritePos .y - spritePrevPos.y) * interpolation));

gameWindow.draw(testSprite);

Then draw testSprite to the screen. All your main collision calculations are with spritePos, while testSprite is just for interpolation of your sprite graphic.

I hope this helps! I'm also using deWitters by preference with the added interpolation.

*Edit: I corrected the formula! Sorry I was copying and pasting mine from my test source code, but mixed up the example variables in the post! Fixed!

Edited by Rutin

##### Share on other sites

Okay I'm having problems.

This is what I have :

interpolation = float(((float)(GetTickCount() - firstTime) + SKIP_TICKS  - (nextTime)) / (SKIP_TICKS));

shipObject.GetShipImage().setPosition(sf::Vector2f ((shipObject.prevx  + ((shipObject.GetX() - shipObject.prevx)* interpolation)),
(shipObject.prevy + ((shipObject.GetY() - shipObject.prevy) * interpolation))));

I am having trouble understanding what nextTime is.  I tried different solutions and I can't understand the relationship of the first interpolation statement with the second statement that uses the interpolation variable.

I can't really understand how an interpolation variable can work if it is seemingly always just increases or decreases with an extremely small value or just gets bigger and bigger.  That's why I think nextTime is not being correctly used by me.  To work it seems necessary that the interpolation formula should be able to give values that aren't just always increasing or always decreasing.

So I don't understand how to get this working, is NextTime always increasing by SKIP_TICKS each loop, and does it start with the same value as     (GetTickCount() - firstTime)     plus the first iteration of SKIP_TICKS?  And what is the range of the interpolation variable?

I can't really seem to get it working hopefully it's "nextTime"   If it's not could you help me too please?

Thank you all,

Josheir

Secondly, where is the sleep_Time condition located as compares to the rest of the code use by Rutin's preference?

##### Share on other sites
Posted (edited)

Hello @Josheir you have to take into context what those variables mean within the loop.

I'll break it down so you understand what values are being placed and how they're associated.

For the above:

interpolation = float(((mainClock.getElapsedTime().asMilliseconds() + skipTicks) - nextTick)) / (skipTicks);

testSprite.setPosition(spritePrevPos.x + ((spritePos .x - spritePrevPos.x) * interpolation), spritePrevPos.y + ((spritePos .y - spritePrevPos.y) * interpolation));

gameWindow.draw(testSprite);

My code is as follows before the loop even starts:

const float ticksPerSecond = 30.f;
const float skipTicks = 1000.f / ticksPerSecond;

sf::Clock mainClock;
double nextTick = mainClock.restart().asMilliseconds();

float interpolation = 0.f;

The actual loop simplified (I'm not posting everything here just enough for the example) - I do not include the loops for max frame skips for catching up in this example.

// Logic and Input
while (mainClock.getElapsedTime().asMilliseconds() > nextTick)
{
spritePrevPos = spritePos;

if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{
spritePos.y -= spriteSpeed;
}

nextTick += skipTicks;
}

// Draw
interpolation = float(((mainClock.getElapsedTime().asMilliseconds() + skipTicks) - nextTick)) / (skipTicks);

testSprite.setPosition(spritePrevPos.x + ((spritePos .x - spritePrevPos.x) * interpolation), spritePrevPos.y + ((spritePos .y - spritePrevPos.y) * interpolation));

gameWindow.draw(testSprite);

The nextTick and skipTicks is so the loop will run one time per 0.0333 seconds, then wait until nextTick equals enough time for the next tick to be due after applying the skipTicks (time between each update call), ect... before calling the loop again, while drawing the rest of the time. (I didn't include the max update part which handles moments if you get trapped in the logic updates for too long, it will force your draw).

This will make sure the graphics are moving at a smooth rate by taking into account your Time Step variables. You can see the difference just by making a toggle (just make an event for F1 or something to toggle the boolean):

if (toggleInterpolation == true) {
testSprite.setPosition(spritePrevPos.x + ((spritePos .x - spritePrevPos.x) * interpolation), spritePrevPos.y + ((spritePos .y - spritePrevPos.y) * interpolation));
}
else {
testSprite.setPosition(spritePos.x, spritePos.y);
}

Quote

Secondly, where is the sleep_Time condition located as compares to the rest of the code use by Rutin's preference?

I don't want to say 'never' but I truly believe you should never ever use sleep commands in game loops. You can only guarantee the sleep will be called, but there is no guarantee it will come back within (x) time. Also, using any form of sleep command to wait until your loop is ready for an update goes against letting your logic run at (x) updates per second, and freeing your draw step by keeping it variable. The Time Step should be Fixed Logic/Input, Variable Draw. If you run your logic/input/draw in the same update "locked at 60 FPS" then you don't need to really worry about interpolation.

Edited by Rutin

##### Share on other sites

My honest advice to you, at this stage, is just to use a variable timestep. The awkwardness of getting a fixed update timestep to work with interpolation and all of the associated issues is probably not worth the effort.

I think Rutin has correctly covered most of the specific issues already. I concur that you shouldn't be using Sleep().

It's also very important to keep in mind that the interpolation is merely a visual improvement. You mustn't change the state of your actual game objects based on that interpolation - you just need to render them in a slightly different place.

I'd also advise you use a function like:

sf::Vector2 Lerp(const sf::Vector2& In, const sf::Vector2& Out, float alpha)
{
return In + ((Out - In) * alpha);
}

And this lets you simplify those complex expressions where you're having to break apart vectors, lerp the components, and then form new vectors from them.

##### Share on other sites

Well I decided to start with Rutin's advice to start with for now.  I created a fixed step with interpolation.  I benefited from the structure of the non sleep usage because there is no longer a slight variation in speed with the ship.  However after all the work when I tried the game with the ship uninterpolated I saw no difference in the now acquired smoothness.  The ship is just as smooth now using interpolation as not interpolated!  I don't know how to feel about this because I spent a while and achieved the desired effect, but it is not because of the interpolation.  I'm wondering if I should leave the interpolation in the program.

As far as Kylotan's advice I suppose I could now start reading up on Lerp and using Alpha with a variable timestep, but I doubt it's necessary with the movement now looking okay?

The Lerp is another way to interpolate and each vector is an x and y  position?  Why are they called in and out?

The problem was the sleep really, so perhaps I've done what I need to do with your help.  Or maybe I need to use the Lerp to complete the project more polished in your opinion?

What I did was put the input and the changed the values of the x and y in the input/logic half and in the second half I checked for collisions, applied the interpolation, and drew and displayed.  The first screen has about 14 images including the bullets and there all moving fine now.

I still haven't learned how this works too which I think is important enough to know.  How should I learn what these two formulas and the Lerp are actually doing?  They're not terribly difficult and I have taken some college mathematics so how should I go about this?  I suppose I start by googling interpolation.  Any help would be greatly appreciated!

I didn't expect the program to work right without the interpolation so I'm still pretty surprised,

Josheir

##### Share on other sites
46 minutes ago, Josheir said:

Well I decided to start with Rutin's advice to start with for now.  I created a fixed step with interpolation.  I benefited from the structure of the non sleep usage because there is no longer a slight variation in speed with the ship.  However after all the work when I tried the game with the ship uninterpolated I saw no difference in the now acquired smoothness.  The ship is just as smooth now using interpolation as not interpolated!  I don't know how to feel about this because I spent a while and achieved the desired effect, but it is not because of the interpolation.  I'm wondering if I should leave the interpolation in the program.

As far as Kylotan's advice I suppose I could now start reading up on Lerp and using Alpha with a variable timestep, but I doubt it's necessary with the movement now looking okay?

The Lerp is another way to interpolate and each vector is an x and y  position?  Why are they called in and out?

The problem was the sleep really, so perhaps I've done what I need to do with your help.  Or maybe I need to use the Lerp to complete the project more polished in your opinion?

What I did was put the input and the changed the values of the x and y in the input/logic half and in the second half I checked for collisions, applied the interpolation, and drew and displayed.  The first screen has about 14 images including the bullets and there all moving fine now.

I still haven't learned how this works too which I think is important enough to know.  How should I learn what these two formulas and the Lerp are actually doing?  They're not terribly difficult and I have taken some college mathematics so how should I go about this?  I suppose I start by googling interpolation.  Any help would be greatly appreciated!

I didn't expect the program to work right without the interpolation so I'm still pretty surprised,

Josheir

Do you mind sharing the code? It's extremely unlikely to have a limitless frame rate running at the max possible fps with smooth moving graphics, and interpolation showing no difference.

It might only be smooth if you've matched your draw step to the logic and input loop at the same refresh rate as your monitor while keeping it fixed.

Please post your entire game loop so I can break down what is happening. Or, if you can provide a project file for me to run to see. I've never seen draw rates that run as fast as possible on today's machines with smooth graphics unless you're using interpolation, or extrapolation. You normally need to run with vsync, or render graphics at the same refresh rate to get that smooth look otherwise.

Edited by Rutin

##### Share on other sites

From what I understand VSYNC is about double buffering and it is on by default with SFML.  Here is the address for the project:     https://github.com/Joshei/asteroids

The asteroids and bullets were smooth.  The Ship graphic had some very slight variation with it's motion.  This is just a simple game, but changing things around I think I now have an acceptable experience.

I tried changing the ticks per second to 50.f and it was also working well.

Look forward to hearing from you,

Josheir

Edited by Josheir

##### Share on other sites
52 minutes ago, Josheir said:

From what I understand VSYNC is about double buffering and it is on automatically with SFML.  Here is the address for the project:     https://github.com/Joshei/asteroids

The asteroids and bullets were pretty smooth.  The Ship graphic had some very slight variation with it's motion.  This is just a simple game, but changing things around I think I now have an acceptable experience.

I tried changing the ticks per second to 50.f and it was also working well.

Look forward to hearing from you,

Josheir

I use SFML a lot, and it's not on by default unless you call it. I've looked through your code and do not see it turned on unless I missed it. To turn VSYNC on you would use: window.setVerticalSyncEnabled(true); Keep in mind that your Video Card settings will override this if you have it to run all applications with VSYNC, or not.

What I've noticed so far is this:

When using pollEvent, do not use it within your logic/input update. You should be checking for events outside of that loop, and only using (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) inside the input loop. The event manager is not meant to be handled this way.

Do this:

while (mainWindow.isOpen()) {

// Event Processing
sf::Event event;

while (mainWindow.pollEvent(event)) {
// Closing Window
if (event.type == sf::Event::Closed) {
mainWindow.close();
}
}

while (mainClock.getElapsedTime().asMilliseconds() > nextTick) {

testSpritePosPrev = testSpritePos;

if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
testSpritePos.y -= testSpriteSpeed;
}

nextTick += skipTicks;
}

// Clear Window
mainWindow.clear();

// Draw to Window
mainWindow.draw();

// Display
mainWindow.display();
}

After your input/logic loop you're calling checkCollisionsShipWithAsteroids(); on line 1213, and again more checks after. This should never be outside of the loop handling input and logic checks. You're also checking a lot of other logic outside of this, put it all under your input/logic loop.

Based on what I've seen if it's running smooth (I cannot fully test) it's because interpolation is already running on the draw side. I want you to try this as a test to see if you notice a difference. You'll have to use a test graphic to run it (get something 50x50 and name it a.png). You can alter the testSpriteSpeed variable to see more examples.

#include <SFML/Graphics.hpp>

void main(int argc, char** agrv[]) {

// Create Main Window
sf::RenderWindow mainWindow(sf::VideoMode(1024, 768), "Test Game", sf::Style::Close);

// Timer for 30 INPUT LOGIC UPDATES PER SECOND
const float ticksPerSecond = 30.f;
const float skipTicks = 1000.f / ticksPerSecond;

sf::Clock mainClock;
double nextTick = mainClock.restart().asMilliseconds();

float interpolation = 0.f;

bool toggleInterpolation = false;

// Sprite
sf::Sprite testSprite;
sf::Texture testTexture;
testSprite.setTexture(testTexture);
sf::Vector2f testSpritePos;
sf::Vector2f testSpritePosPrev;
int testSpriteSpeed = 5;

// SET POS
testSpritePos.x = 0;
testSpritePos.y = 0;

while (mainWindow.isOpen()) {

// Event Processing
sf::Event event;

while (mainWindow.pollEvent(event)) {
// Closing Window
if (event.type == sf::Event::Closed) {
mainWindow.close();
}

if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Space) {
toggleInterpolation = !toggleInterpolation;
}
}
}

while (mainClock.getElapsedTime().asMilliseconds() > nextTick) {

testSpritePosPrev = testSpritePos;

if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
testSpritePos.y -= testSpriteSpeed;
}

if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
testSpritePos.y += testSpriteSpeed;
}

if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
testSpritePos.x -= testSpriteSpeed;
}

if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
testSpritePos.x += testSpriteSpeed;
}

nextTick += skipTicks;
}

interpolation = float(((mainClock.getElapsedTime().asMilliseconds() + skipTicks) - nextTick)) / (skipTicks);

if (toggleInterpolation == true) {
testSprite.setPosition(testSpritePosPrev.x + ((testSpritePos.x - testSpritePosPrev.x) * interpolation), testSpritePosPrev.y + ((testSpritePos.y - testSpritePosPrev.y) * interpolation));
}
else {
testSprite.setPosition(testSpritePos.x, testSpritePos.y);
}

// Clear Window
mainWindow.clear();

// Draw to Window
mainWindow.draw(testSprite);

// Display
mainWindow.display();
}
}

You can toggle interpolation with the 'SPACE BAR'. You should see a clear difference. Let me know.

Edited by Rutin

##### Share on other sites
Just now, Rutin said:

Based on what I've seen if it's running smooth (I cannot fully test) it's because interpolation is already running on the draw side. I want you to try this as a test to see if you notice a difference. You'll have to use a test graphic to run it (get something 50x50 and name it a.png). You can alter the testSpriteSpeed variable to see more examples.

Well it's interesting I think.  Both programs (mine and your sample) work smoothly.  I'm interested in why (more feedback from you.)  By running on the draw side you mean that their code for SFML drawing already uses interpolation?  Thanks also for those  great tips and the excellent code sample.

Have a super Labor Day weekend,

Josheir

Edited by Josheir

##### Share on other sites
1 hour ago, Josheir said:

Well it's interesting I think.  Both programs (mine and your sample) work smoothly.  I'm interested in why (more feedback from you.)  By running on the draw side you mean that their code for SFML drawing already uses interpolation?  Thanks also for those  great tips and the excellent code sample.

Have a super Labor Day weekend,

Josheir

Hello Josheir,

What I meant was that you're seeing smooth motion on your program because you're using interpolation in your code, otherwise you're running the render frames very close to your refresh rate. Video cards can lock applications to run in VSYNC so I don't have enough information to go on, but in most cases when you run any game loop with a variable frame rate not locked down, you will never get smooth motion unless you use interpolation, or extrapolation without locked rates.

If you toggle off all your interpolation code (only draw based on actual positions), run something like FRAPS so you can report back the FPS you're getting. It's extremely odd to get smooth motion unless something is capping your FPS close to your refresh rate.

Other methods people use to get smooth fps in their loops would be rendering at same rate as your refresh rate, example 60 FPS for 60 hertz, or just use VSYNC so it matches your monitor refresh.

SFML does not handle interpolation by default.

Have a great long weekend as well, let me know what FRAPS shows.

Edited by Rutin

##### Share on other sites

Just understood what you meant when I changed the ticks per second to 10.f on your sample!

Thank you so much,

Josheir

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628686
• Total Posts
2984237
• ### Similar Content

• It comes that time again when I try and get my PC build working on Android via Android Studio. All was going swimmingly, it ran in the emulator fine, but on my first actual test device (Google Nexus 7 2012 tablet (32 bit ARM Cortex-A9, ARM v7A architecture)) I was getting a 'SIGBUS illegal alignment' crash.
My little research has indicated that while x86 is fine with loading 16 / 32 / 64 bit values from any byte address in memory, the earlier ARM chips may need data to be aligned to the data size. This isn't a massive problem, and I see the reason for it (probably faster, like SIMD aligned loads, and simpler for the CPU). I probably have quite a few of these, particular in my own byte packed file formats. I can adjust the exporter / formats so that they are using the required alignment.
Just to confirm, if anyone knows this, is it all 16 / 32 / 64 bit accesses that need to be data size aligned on early android devices? Or e.g. just 64 bit size access?
And is there any easy way to get the compiler to spit out some kind of useful information as to the alignment of each member of a struct / class, so I can quickly pin down the culprits?
The ARM docs (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html) suggest another alternative is using a __packed qualifier. Anyone used this, is this practical?
• By Josheir
In the following code:

Point p = a[1]; center of rotation for (int i = 0; I<4; i++) { int x = a[i].x - p.x; int y = a[i].y - p.y; a[i].x = y + p.x; a[i].y = - x + p.y; }
I am understanding that a 90 degree shift results in a change like:
xNew = -y
yNew = x

Could someone please explain how the two additions and subtractions of the p.x and p.y works?

Thank you,
Josheir
• By alex1997
Hey, I've a minor problem that prevents me from moving forward with development and looking to find a way that could solve it. Overall, I'm having a sf::VertexArray object and looking to reander a shader inside its area. The problem is that the shader takes the window as canvas and only becomes visible in the object range which is not what I'm looking for..
Here's a stackoverflow links that shows the expected behaviour image. Any tips or help is really appreciated. I would have accepted that answer, but currently it does not work with #version 330 ...

• I just finished up my 1st iteration of my sprite renderer and I'm sort of questioning its performance.
Currently, I am trying to render 10K worth of 64x64 textured sprites in a 800x600 window. These sprites all using the same texture, vertex shader, and pixel shader. There is basically no state changes. The sprite renderer itself is dynamic using the D3D11_MAP_WRITE_NO_OVERWRITE then D3D11_MAP_WRITE_DISCARD when the vertex buffer is full. The buffer is large enough to hold all 10K sprites and execute them in a single draw call. Cutting the buffer size down to only being able to fit 1000 sprites before a draw call is executed does not seem to matter / improve performance.  When I clock the time it takes to complete the render method for my sprite renderer (the only renderer that is running) I'm getting about 40ms. Aside from trying to adjust the size of the vertex buffer, I have tried using 1x1 texture and making the window smaller (640x480) as quick and dirty check to see if the GPU was the bottleneck, but I still get 40ms with both of those cases.

I'm kind of at a loss. What are some of the ways that I could figure out where my bottleneck is?
I feel like only being able to render 10K sprites is really low, but I'm not sure. I'm not sure if I coded a poor renderer and there is a bottleneck somewhere or I'm being limited by my hardware

Just some other info:
Dev PC specs: GPU: Intel HD Graphics 4600 / Nvidia GTX 850M (Nvidia is set to be the preferred GPU in the Nvida control panel. Vsync is set to off) CPU: Intel Core i7-4710HQ @ 2.5GHz Renderer:
//The renderer has a working depth buffer //Sprites have matrices that are precomputed. These pretransformed vertices are placed into the buffer Matrix4 model = sprite->getModelMatrix(); verts[0].position = model * verts[0].position; verts[1].position = model * verts[1].position; verts[2].position = model * verts[2].position; verts[3].position = model * verts[3].position; verts[4].position = model * verts[4].position; verts[5].position = model * verts[5].position; //Vertex buffer is flaged for dynamic use vertexBuffer = BufferModule::createVertexBuffer(D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE, sizeof(SpriteVertex) * MAX_VERTEX_COUNT_FOR_BUFFER); //The vertex buffer is mapped to when adding a sprite to the buffer //vertexBufferMapType could be D3D11_MAP_WRITE_NO_OVERWRITE or D3D11_MAP_WRITE_DISCARD depending on the data already in the vertex buffer D3D11_MAPPED_SUBRESOURCE resource = vertexBuffer->map(vertexBufferMapType); memcpy(((SpriteVertex*)resource.pData) + vertexCountInBuffer, verts, BYTES_PER_SPRITE); vertexBuffer->unmap(); //The constant buffer used for the MVP matrix is updated once per draw call D3D11_MAPPED_SUBRESOURCE resource = mvpConstBuffer->map(D3D11_MAP_WRITE_DISCARD); memcpy(resource.pData, projectionMatrix.getData(), sizeof(Matrix4)); mvpConstBuffer->unmap(); Vertex / Pixel Shader:
cbuffer mvpBuffer : register(b0) { matrix mvp; } struct VertexInput { float4 position : POSITION; float2 texCoords : TEXCOORD0; float4 color : COLOR; }; struct PixelInput { float4 position : SV_POSITION; float2 texCoords : TEXCOORD0; float4 color : COLOR; }; PixelInput VSMain(VertexInput input) { input.position.w = 1.0f; PixelInput output; output.position = mul(mvp, input.position); output.texCoords = input.texCoords; output.color = input.color; return output; } Texture2D shaderTexture; SamplerState samplerType; float4 PSMain(PixelInput input) : SV_TARGET { float4 textureColor = shaderTexture.Sample(samplerType, input.texCoords); return textureColor; }
If anymore info is needed feel free to ask, I would really like to know how I can improve this assuming I'm not hardware limited

• My short-term  goal right now is a job as a Junior Programmer in any game company, just to get my foot int the door and start earning some income.
My long term goal is to Programme for bigger more established  game companies and help games that interest me.
Im in semi-fortunate position where i don't have to work a full time job so i have the  learn how to programme.
i did my research into whats a good beginner way to start,  Unity and C# came up a lot, so i threw my hat in.
For the past 5 months i've been learning C# and Unity using the udemy tutorials at a slow but steady pace as i come from a 0 maths/ programming background.
Right now  getting the hang of things , understanding most code and the  unity engine to a point where i feel comfortable at my current level around Beginner/ Intermediate.
Although im still keen to continue with Unity, I cant help this nagging feeling that(lets say for arguments sake i do actually get a job) if i do peruse this path and end up with a job as a developer for a company that uses Unity or whatever else uses C# . There is going to be a point at however many X years down the line i am, im still using unity,  im going to be in a position where i want to work on bigger more mainstream games that use C++.
I want to get a job ASAP, i know it will take at the very least another 7 months probably, learning more code, making a portfolio and all the rest, so i dont really want to change and start from scratch again.
Im not bashing unity but it looks like its main use is mobile games, which would be perfectly fine as a starting point, but not as a long term career.
Hypothetically  If i continue to focus on learning C# / Unity to reach my goal, and at some-point i want to move into bigger prospects and learn C++, how screwed would i be if i wanted to transition over.
Im by no means a  smart guy that picks up things fast, im just willing to put in the time/effort.
Should i scrap learning C# and unity for C++ / Unreal  or just power on through and transition later down the line after i get some experience first.
Time is a factor, but i want to make sure im not condemning myself to a path i wont like later down the line...

• 16
• 13
• 13
• 10
• 10