Hi! I'm Vilhelm and I am a game programmer.
I'm building a vulkan based game engine to learn vulkan, graphics, shaders and ECS. The 'ball' above is a 250mb .obj file where each 'hair' is separate, it renders without delay even on a laptop mac.
// global ubo
global_ubo ubo{};
ubo.projection = camera.getProjection();
ubo.view = camera.getView();
ubo.inv_view_mat = frame.camera.getInverseView();
ubo.ambient_light_color = {0.2f, .2f, .2f, 0.2f};
point_light_render_system.update(frame, ubo);
// physics
// physics_system.update(frame);
// write updates to buffer
ubo_buffers[frame_index]->writeToIndex(&ubo, frame_index);
ubo_buffers[frame_index]->flush();
// Render
renderer_.beginSwapChainRenderPass(command_buffer);
// rendering
point_light_render_system.render(frame);
simple_render_system.renderGameObjects(frame);
// END
renderer_.endSwapChainRenderPass(command_buffer);
renderer_.endFrame();
}
}
vkDeviceWaitIdle(device_.device());
In BEPPUS, a 'Oddworld meets Lemmings' puzzle platformer, you lead a group of Beppus with strange powers. Their world is harsh, and sacrificing some of them will be needed for the others’ salvation.
void AGP_PatrollingAIController::HandleMove(){
CurrentDirection.X = 0.f;
if ( !bIsPausing ){
Minion->HandleRightInput(CurrentDirection.Y);
FVector TraceStart = GetPawn()->GetPawnViewLocation() + CurrentDirection * 20.f;
FVector TraceEnd = TraceStart + CurrentDirection * TraceLength;
FHitResult Hit;
if ( GetWorld()->LineTraceSingleByObjectType(Hit, TraceStart, TraceEnd, COQP) ){
if ( Hit.bBlockingHit ){
AGP_PuzzlePiece_Portal* Portal = Cast<AGP_PuzzlePiece_Portal>(Hit.GetActor());
if ( Portal || Minion->IsTeleporting == true )
return;
TurnAround();
return;
}
}
else{
TraceStart.Z -= SecondTraceHeightOffset;
TraceEnd = TraceStart + CurrentDirection * (TraceLength * 0.4f);
if ( GetWorld()->LineTraceSingleByObjectType(Hit, TraceStart, TraceEnd, COQP) ){
if ( Hit.bBlockingHit ){
AGP_PuzzlePiece_Portal* Portal = Cast<AGP_PuzzlePiece_Portal>(Hit.GetActor());
if ( Portal )
return;
TurnAround();
return;
}
}
}
}
if ( !GetPawn<AGP_Minion>()->GetIsGrounded() && !bIsPausing ){
PauseMove(CurrentDirection);
return;
}
if
( GetPawn<AGP_Minion>()->GetIsGrounded() && bIsPausing ){
ResumeMove(CurrentDirection);
}
}
The Unseen is a first person horror/survival game. You enter an underground water treatment facility as a mechanic. Equipped with only the standard issue multi-tool you set out to fix the issues all over the plant. But something lurks in the shadows.
//This should only happen once per move;
if (Enemy->bHasRequestedLocation) { if (FVector::Dist(Enemy->GetActorLocation(), Enemy->RequestedLocation) < 5.f) { OnArrivedAtTargetDestination(); } }
//SCREEN DISTORTION EFFECT IF PLAYER IS CLOSE//
float DistanceToPlayer = Enemy->GetDistanceToPlayer();
Enemy->AggressionLevel = FMath::Clamp(Enemy->AggressionLevel, 0.001f, 1.f);
if (DistanceToPlayer <= AISightRadius) { ScreenPixelEffectAmount += FMath::Lerp(0.f, 1.f, Enemy->AggressionLevel); }
else { ScreenPixelEffectAmount -= FMath::Lerp(0.f, 1.0f, Enemy->AggressionLevel); }
ScreenPixelEffectAmount = FMath::Sin(ScreenPixelEffectAmount * DeltaSeconds);
UKismetMaterialLibrary::SetScalarParameterValue(this, PixelSortParameterCollection, FName("AlphaClamp"), ScreenPixelEffectAmount);
//CHECK IF IS IDLE//
if (StateMachine->GetState() == EEnemyState::IDLE) { IdleTimer += DeltaSeconds; }
if (IdleTimer >= MaxIdleTime) {
SetAILogicActive(true);
PlayerLastKnownPosition = GetPoint(true)->GetActorLocation();
StateMachine->SetState(EEnemyState::SEARCHING);
IdleTimer = 0.f;
}
SubOptimal is a point and click adventure taking place on a stranded submarine. A mysterious asteroid have crashed close by and weird energies have transformed the crew into strange animal like beings.
Space Shoot'Em Up mini-game with heavy inspiration from Super Hot in regard to time dilation and slow-motion. Developed as an assignment at Future Games, then ported to Mobile (iOS) through Unity as a side project.
public class BatchUpdateManager : MonoBehaviour {
[SerializeField] private EnemySpawnManager _enemySpawnManager;
[SerializeField] private SpaceJunkManager _spaceJunkManager;
[SerializeField] private TimeManager _timeManager;
[SerializeField] private PlayerBoundaries _playerBoundaries;
[SerializeField] private PlayerInput _playerInput;
[SerializeField] private PlayerController _playerController;
[SerializeField] private PlayerMovement _playerMovement;
[SerializeField] private ShieldControl _shieldControl;
[SerializeField] private BackgroundController _backgroundController;
private void Update(){
_enemySpawnManager.BatchUpdate();
_playerInput.BatchUpdate();
_playerController.BatchUpdate();
_shieldControl.BatchUpdate();
_backgroundController.BatchUpdate();
}
private void FixedUpdate(){
_spaceJunkManager.BatchFixedUpdate();
_timeManager.BatchFixedUpdate();
_playerBoundaries.BatchFixedUpdate();
}
}
Im learing vulkan, rendering and shaders by making a simple game engine.
Discord Bot for FutureGames Programmers. Simple but provides some useful links and laughs. Made for fun.
Repo for my personal website/portfolio. built on gatsby.js, react, deployed through cloudflare. Based on gatsby-theme-portfolio. vilhelmstokstad.com
SHMUPER HOT is a "2D-scroller" Shoot Em Up with basic 3d grapichs and physics where Time only moves when you move! (or shoot). Inspired by SuperHot.
DiceHammer was developed as a side project to explore networking and iOS development in a warhammer-themed way. The app lets you connect to another nearby person with the app, if both are accepting…
AStar async and sync interface to slap on basically any unreal actor that wants some fast pathfinding. Includes grid and node classes. Unreal Engine 4.26.2