24-01

Sandy·2024년 3월 6일

[Today I Learned]

목록 보기
13/18

240101SEngine필요기능

1_0_Math


2_0_Renderer


3_0_Engine

GameEngine

Scene

GameObject : ObjectName / Tag / Layer

3_1_Managers

DataManager

InputManager

PoolManager

ResourceManager

ScneneManager

SoundManager

UIManager

3_2_Components

Transform

Rigidbody

CapsuleCollider

SphereCollider

BoxCollider

Camera

AudioListender

Light

MeshFilter

MeshRenderer

NavMeshAgent

Material

Animator

Poolable

3_3_UIComponents

RectTransform

CanvasRenderer

Image

Text

Button

DefaultUIMaterial

3_4_Assets

AnimationController

Animation


4_0_DemoApp

4_1_EntryPoint

EntryPoint

GameProcess

240108_SEngine_Lifecycle

void GameEngine::Process()
{
	// Time TimeManager deltaTime 계산
	m_timeManager->ProcessDeltaTime();
	float deltaTime = m_timeManager->GetDeltaTime();

	// Input InputManger 유저 키입력 체크
	m_inputManager->ProcessUserInput();

	// Physics SceneManager FIXED_DELTATIME FixedUpdate() 처리
	constexpr float PHYSICS_DELTATIME = 0.02f;
	m_elapsedPhysicsTime += deltaTime;

	while (m_elapsedPhysicsTime >= PHYSICS_DELTATIME)
	{
		m_sceneManager->FixedUpdate(PHYSICS_DELTATIME);
		m_elapsedPhysicsTime -= PHYSICS_DELTATIME;
	}
	
	// Update - Object 현재 Scene GameObject Update()
	m_sceneManager->Update(deltaTime);

	// Update - Collision 현재 충돌 상태 CollisionManager 처리
	m_collisionManager->ProcessCollision(deltaTime);

	// UI UI Event 처리
	m_UIManager->ProcessUIEvent();

	// Camera Camera이동
	m_cameraManager->ProcessCamera();

	// Render Renderer에서 BeginRender
	m_renderer->BeginRender();

	// GameObject Render 현재 씬에 있는 GameObject에 있는 Render 대상인 Component MeshRenderer
	m_sceneManager->Render(m_renderer);

	m_renderer->EndRender();

	// DebugRender Time/Scene/Camera

}
// 2957번 이진 탐색 트리
/* 
그 시점에서 만들어진 BT의 height 누적 합
set 입력받는 수
map 입력받는수, BT에서 height

X의 높이: max(X보다 작으면서 가장 큰 값 높이 / X보다 크면서 가장 작은 값 높이) + 1

https://everenew.tistory.com/102
*/

240109_SSAO

SSAO Screen Space Ambient Occulsion

deffered rendering 할 때 사용한다

어두운 곳을 더 어둡게 한다

음영이 생길 확률을 계산 → blur로 부드럽게 하기

// 2812번 크게 만들기
/*
앞자리 가장 큰 수 유지 -> 앞에서부터 뺄 수 있을만큼 빼면서 크게 만들기
현재 수보다 작은 수가 앞에 있으면 지우기
끝까지 갔는데 cnt 남았으면 뒤에서 빼서 맞춰주기

결과 string 이여서 char로 넣기

시간초과 난다! 
string (+) 연산 -> 벡터에 넣기

*/

LUT Look Up Table

톤을 다르게 할 수 있다 → 씬의 시간대, 분위기를 만들 수 있다

Color Grading으로 라이트 변화 X

240110_UE_GraphicsPipeline

Animation Pipeline

FBX File

Hair and Fur Simulation / Cloth Simulation

Sequences

Anim Curves / Anim Notifies

Pose Assets

Skeletal Mesh

Skeleton

AnimGraph

State Machine / Event Graph

Gameplay Framework

Controller / Pawn

Performance

LODs / Multi-Threaded Update


Materials Pipeline

Textures

Render Target / Texture / Compression / Derived Data Cache

Core Authoring Tools

Shading Model / Per Pixel Shading / Material Node

Material Editor

Compilation Stage

Shader Permutations

Rendered in the world

Render Target

UI / Post Processing / Surface

Performance


Rendering Pipeline

Frame 0 CPU

All Logic

Frame 1 CPU - Visibility

Distance Culling / Frustrum Culling / Mesh LODs / Visibility Culling / Occlusion Visibility Processes

Frame 2 CPU - Start of Rendering

Early Z Pass

Scan Depth

Base pass

Static Meshes / Instanced Static Meshes / Skeletal Meshes / Landscapes / Procedural Meshes / Geometry Collection

Drawcalls / Lightmaps

Static Lighting / Shadows

Global Illumination Radiosity

GBuffer

Buffer A / B / C / D / E

Dyn Lighting / Shadows

Dynamic Shadows

Raytraced GI

Capsule Shadows

PostProcessing

Tone mapper / Bloom / Screen Space Ambient Occlusion / Screen Space Sub Surface Scattering / Screen Space Global Illumination / Depth of Field / Exposure

240103_InvSqrt

InvSqrt : 고속 역제곱근 공식

Normalize 해서 벡터 크기 1만들어서 사용하기 때문에 한다

float long으로 바꾼다

u인 매직 넘버 뺀다

뉴턴 미적분으로 근사치 정확도 높힌다

static float InvSqrt(float InFloat)
{
	// Performs two passes of Newton-Raphson iteration on the hardware estimate
	//    v^-0.5 = x
	// => x^2 = v^-1
	// => 1/(x^2) = v
	// => F(x) = x^-2 - v
	//    F'(x) = -2x^-3

	//    x1 = x0 - F(x0)/F'(x0)
	// => x1 = x0 + 0.5 * (x0^-2 - Vec) * x0^3
	// => x1 = x0 + 0.5 * (x0 - Vec * x0^3)
	// => x1 = x0 + x0 * (0.5 - 0.5 * Vec * x0^2)
	//
	// This final form has one more operation than the legacy factorization (X1 = 0.5*X0*(3-(Y*X0)*X0)
	// but retains better accuracy (namely InvSqrt(1) = 1 exactly).

	const __m128 fOneHalf = _mm_set_ss(0.5f);
	__m128 Y0, X0, X1, X2, FOver2;
	float temp;

	Y0 = _mm_set_ss(InFloat);
	X0 = _mm_rsqrt_ss(Y0);	// 1/sqrt estimate (12 bits)
	FOver2 = _mm_mul_ss(Y0, fOneHalf);

	// 1st Newton-Raphson iteration
	X1 = _mm_mul_ss(X0, X0);
	X1 = _mm_sub_ss(fOneHalf, _mm_mul_ss(FOver2, X1));
	X1 = _mm_add_ss(X0, _mm_mul_ss(X0, X1));

	// 2nd Newton-Raphson iteration
	X2 = _mm_mul_ss(X1, X1);
	X2 = _mm_sub_ss(fOneHalf, _mm_mul_ss(FOver2, X2));
	X2 = _mm_add_ss(X1, _mm_mul_ss(X1, X2));

	_mm_store_ss(&temp, X2);
	return temp;
}

240104_FModuler

FModuler

FORCEINLINE static float FMod(float X, float Y)
{
	if (fabsf(Y) <= SMALL_NUMBER)
	{
		return 0.f;
	}

	const float quotient = (float)TruncToInt(X / Y);
	float intPortion = Y * quotient;
	if (fabsf(intPortion) > fabsf(X))
	{
		intPortion = X;
	}

	return (X - intPortion);
}

Rotator → Quaternion

/// <summary>
/// Euler Angle를 가지고 있는 Rotator를 쿼터니언으로 변환
/// </summary>
/// <param name="inRotator"></param>
Quaternion::Quaternion(const Rotator& inRotator)
{
	float sinPitch = 0.f, sinYaw = 0.f, sinRoll = 0.f;
	float cosPitch = 0.f, cosYaw = 0.f, cosRoll = 0.f;

	sinPitch = sinf(inRotator.pitch * 0.5f);
	sinYaw = sinf(inRotator.yaw * 0.5f);
	sinRoll = sinf(inRotator.roll * 0.5f);

	cosPitch = cosf(inRotator.pitch * 0.5f);
	cosYaw = cosf(inRotator.yaw * 0.5f);
	cosRoll = cosf(inRotator.roll * 0.5f);

	w = sinYaw * sinPitch * sinRoll + cosYaw * cosPitch * cosRoll;
	x = sinYaw * sinRoll * cosPitch + sinPitch * cosRoll * cosYaw;
	y = sinYaw * cosPitch * cosRoll - sinPitch * sinRoll * cosYaw;
	z = -sinYaw * sinPitch * cosRoll + sinRoll * cosYaw * cosPitch;
}

240105_PBR

Physically based rendering

Reflection Model

표면에서 빛이 산란하는 방식을 설명하는 모델

BRDF : 표면에서 빛 반사 Bidirectional Reflectance Distribution function

BTDF : 표면에서 빛 투과 Bidirectional Transmittance Distribution function

BSDF : 반사 + 투과

Roughness Using Microfacet Theory

Masking / Shadowing

The Fresnel Equations

표면에서 반사할 때 빛 각도에 대한 각 재질의 수치

// 모든 점들 중 가장 먼 점 찾기
Vector3 farthestPoint = (*std::max_element(points.begin(), points.end(),
	[&](Vector3 const& lhs, Vector3 const& rhs)
	{
		return (center - lhs).SizeSquared() < (center - rhs).SizeSquared();
	}));

240111_UE_Pipeline

Character Pipeline

Character

Character Movement Component / Movement Component

Nev Mesh

Navigation Mesh

Pawn

Controller

Camera

Camera Manager / Camera / Springarm Component / Camera Component

Gameplay Framework

GameMode / PlayerState

Player Controller

Input

Actions / Axis / Input Component

AI Controller

Behavior Tree

Replication

Network Framework

Skeletal Mesh Component / AnimBP / Event Graph / Anim Graph


World Building Pipeline

A Level

Placeable 3D Mesh Actors

Static Meshes / Skeletal Meshes / Geometry / Procedural Mesh / Landscapes / Skies

Placeable Actors Excluding 3D

Audio Actors / Reflection Captures / Light Actors / BP Actors / Gameplay

Controls the Level

Sequencer / World Properties / Level Blueprint

Rebuilding

Navmesh Agent / Navmesh / Lightmaps / Volumetric Lightmaps / Lighting / Hierachical LODs

Performance

Stats / GPU Profiler / Statistics Panels / View Modes / Cull Max Draw Distance


Blueprint Pipeline

C++

Inheritance / Framework / Events Functions Variables / Function Libraries

Engine & Project Folders

Replication / Actor / GameMode / Pawn / Controller / GameState / PlayerState / Character/ AI Controller / PlayerController

Optional Data Features

Data Tables / Data Assets / Curves

Core Features of BP

Components / Event Graph

Variables / Function / Macro

Additional Features

Performance & Debugging Tools

Parts of the Engine Using BP

Actor BP / Level BP / Anim BP / Sequencer / Niagara

Blueprint Communication

Direct References / Casting / C++


Engine Structure Pipeline

The Engine → The Project → Shipped Project

Build → Cooking → Staging → Saved & Cooked → Packaging

Config Files

Source Code

Asset Loading

Engine / Referenced Assets / DLL Modules / Game Level

Engine & Project Folders

Folder Structure / UProject

Editor

Material / Skeletal Mesh / Blueprint / Sequencer / Niagara

Assets

AssetManager / Primary Assets / UAssets / Derived Data Cache / Assets / Import


Programming Pipeline

Unreal Build Tool → Source Code → Unreal Automation Tool → Shipped Project

Replication

Network Framework

Memory

Loading Assets / Garbage Collector / Memory Management

Delegates & Events / Async Tasking

Gameplay Framework

GameInstance / Ticking / Subsystems

GameState / GameMode

Player State / PlayerController / Input Component / Pawn & Character

Base Types - Base Data Types

Enum / Strings / Structs / Collections / Transform Types

Fstring / FName / FText

TMap / TArray / TSet

FVector / FRotator / FQuat / FTransform

Base Types - Life Cycle

UObject / Actor / Components / Life Cycle / Smart Pointers

TWeakPtr / TSharedPtr / TSharedRef/ TUniquePtr

Creation / Destruction

Specifiers / Data Objects / Data Tables / Data Assets / Curves

240115_Unity_CollisionLayer

Layers

Player

Monster

NPC

Item

Projectile

Background


Dynamic : Collider + Rigidbody

Player, Monster, NPC

→ Static O / Kinematic O / Static O

Kinematic : Collider + RigidBody + kinematic

움직이는 플랫폼, 중력 X

→ Dynamic O / Kinematic X / Static X

Static : Collider

Background

→ Dynamic X / Kinematic X / Static X

Collider 만 붙힌다

Trigger : Collider + isTrigger

Projectile / Item

Collision Layer

PlayerMonsterNPCItemProjectileGround
PlayerOOOOO
MonsterXXOO
NPCXXO
ItemXX
ProjectileX
Ground
Player

UpdateIdle()
{
// #[SPACE]키
→ State.Jumping
→ rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}

UpdateMoving()
{
// #[SPACE]키
→ State.Jumping
→ rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}

OnCollisionEnter(Collision)
{
// #몬스터 && (State.Idle || State.Moving || State.Jumping)
→ 플레이어 피 깎고 플레이어 보던 반대 방향으로 밀기

// #Ground
→ State.Idle
}

OnCollisoinStay()
{
// #NPC && [ALT]키 
→ NPC에 맞는 대화 시작하기
}

OnTriggerEnger(Collider)
{
// #Item 
→ 각 아이템에 맞는 처리 하고 아이템 삭제하기

// #Projectile 
→ 플레이어 피 깎기
}

240116_Unity_Lifecycle

SingleThread GameLoop

while (1)
{
	// 입력 처리
	g_hidManager->Poll();

	// 애니메이션 엔진 업데이트
	g_gameObjectManager->PreAnimationUpdate(dt);
	g_animationEngine->UpdateAnimations(dt);
	g_gameObjectManager->PostAnimationUpdate(dt);

	// 물리 엔진 업데이트
	g_physicsWorld->Step(dt);
	// 랙돌 피직스 업데이트
	g_animationEngine->UpdateRagDolls(dt);

	// 물리 엔진 업데이트 이후 처리
	g_gameObjectManager->postPhysicsUpdate(dt);
	// 애니메이션 엔진 업데이트 이후 처리
	g_animationEngine->finalize();

	// 이펙트 엔진 업데이트
	g_effectManager->Update(dt);

	// 오디오 엔진 업데이트
	g_audioEngine->Update(dt);

	// 렌더링 엔진 업데이트
	g_renderManager->Render(dt);

	// dt 계산
	dt = CalculateDeltaTime();
}

Unity Lifecycle

/// <summary>
/// Start 스크립트 인스턴스가 활성화된 경우에만 첫 번째 프레임 업데이트 전에 호출됩니다
/// </summary>
void Initialize()
{
	AWake();
	OnEnable();
	Reset();
	Start();
}

/// <summary>
/// FixedUpdate는 종종 Update보다 더 자주 호출됩니다. 
/// 프레임 속도가 낮은 경우 프레임당 여러 번 호출될 수 있으며, 
/// 프레임 속도가 높은 경우 프레임 사이에 전혀 호출되지 않을 수도 있습니다. 
/// 모든 피직스 계산과 업데이트는 FixedUpdate 직후에 발생합니다. 
/// FixedUpdate 내에서 이동 계산을 적용할 때 값에 Time.deltaTime을 곱할 필요가 없습니다. 
/// 이는 FixedUpdate가 프레임 속도와 무관하게 안정적인 타이머에 호출되기 때문입니다.
/// </summary>
void Physics()
{
	FixedUpdate();
	// === Internal Animation Update ===
	StateMachineUpdate();
	OnStateMachineEnterExit();
	ProcessGraph();
	FireAnimationEvents();
	StateMachineBehaviourCallbacks();
	OnAnimatorMove();

	InternalPhysicsUpdate();

	// === Internal Animation Update ===
	ProcessAnimation();
	OnAnimatorIK();
	WriteTransform();
	WriteProperties();

	OnTriggerXXX();
	OnCollisionXXX();
}

void InputEvents()
{
	OnMouseXXX();
}

/// <summary>
/// Update는 프레임당 한 번 호출됩니다. 프레임 Update의 주요 핵심 기능입니다.
/// 
/// LateUpdate는 업데이트가 완료된 후 프레임당 한 번 호출됩니다. 
/// Update에서 수행되는 모든 계산은 LateUpdate가 시작될 때 완료됩니다. 
/// LateUpdate의 일반적인 용도는 3인칭 카메라 팔로잉입니다. 
/// Update 안에서 캐릭터를 움직이고 회전하게 하면 LateUpdate에서 모든 카메라 이동 및 회전 계산을 수행할 수 있습니다. 
/// 이렇게 하면 카메라가 위치를 추적하기 전에 캐릭터가 완전히 이동했는지 확인할 수 있습니다
/// </summary>
void GameLogic()
{
	Update();

	// === Internal Animation Update ===
	StateMachineUpdate();
	OnStateMachineEnterExit();
	ProcessGraph();
	FireAnimationEvents();
	StateMachineBehaviourCallbacks();
	OnAnimatorMove();
	ProcessAnimation();
	OnAnimatorIK();
	WriteTransform();
	WriteProperties();

	LateUpdate();
}

/// <summary>
/// OnPreCull: 카메라가 씬을 컬링하기 전에 호출됩니다. 컬링은 카메라에 표시되는 오브젝트를 결정합니다. OnPreCull은 컬링이 발생하기 직전에 호출됩니다.
/// OnBecomeVisible / OnBecomeInvisible: 오브젝트가 카메라에 표시 / 비표시될 때 호출됩니다.
/// OnWillRenderObject : 오브젝트가 보이는 경우 각 카메라에 대해 한 번씩 호출됩니다.
/// OnPreRender : 카메라가 씬 렌더링을 시작하기 전에 호출됩니다.
/// OnRenderObject : 모든 일반 씬 렌더링이 완료된 후 호출됩니다.이 시점에서 GL 클래스 또는 Graphics.DrawMeshNow를 사용하여 커스텀 지오메트리를 그릴 수 있습니다.
/// OnPostRender : 카메라가 씬 렌더링을 완료한 후에 호출됩니다.
/// OnRenderImage : 이미지의 포스트 프로세싱을 허용하기 위해 씬 렌더링이 완료된 후 호출됩니다.
/// </summary>
void SceneRendering()
{
	OnPreCull();
	OnWillRenderObject();
	OnBecameVisible();
	OnBecameInvisible();
	OnPreRender();
	OnRenderObject();
	OnPostRender();
	OnRenderImage();
}

void GUIRendering()
{
	OnGUI();
}

/// <summary>
/// 일시 정지가 감지된 프레임이 끝날 때 호출되며, 
/// 사실상 일반 프레임 업데이트 사이에 호출됩니다. 
/// OnApplicationPause가 호출된 후 한 프레임이 추가로 발행되어 게임에서 일시 중지 상태를 나타내는 그래픽을 표시할 수 있습니다.
/// </summary>
void Pausing()
{
	OnApplicationPause();
}

void Decommisioning()
{
	OnApplicationQuit();
	OnDisable();
	OnDestroy();
}

int main()
{
	Initialize();

	while (true)
	{
		Physics();
		InputEvents();
		GameLogic();
		SceneRendering();
		GizmoRendering();
		GUIRendering();
		EndOfFrame();

		if (Paused)
		{
			Pausing();
		}
	}
	Decommisioning();

}

Parent-Child

Transform에서 Parent-Child구조를 갖고 있는다

Scene에서 전부 갖고있기 X

Parent → Child로 Update / FixedUpdate / Render 등 전체 루프 재귀적으로 돌려준다

ComponentOrder

하나의 Entity안에 있는 Component는 Define에 있는 Component Order대로 실행한다

CollisionLayer

Collision Layer에서 설정한 Layer들끼리만 충돌한다


Tonemapping operator == HDR

HDR 데이터 → LDR : float → byte

Perlin Noise

지형 만들 때 쓴다

QuadTree Culling + Frustm Culling

공간 4분할 트리구조 + 6면 모두 안쪽에 있는 것 그리기

BSP Binary Spatial Partition Tree

충돌처리 X

갈 수 있는 영역인지 아닌지 판단

240119_shared_from_this

class Scene : public std::enable_shared_from_this

entity.lock()->SetScene(shared_from_this());

this로 shared를 만들어서 넘겨줄 수 있다

240120_프로젝트 후 할 일

240120-240228

Transform

Collider / BoxCollider / Collision / Rigidbody / CollisionManager / PhysicsManager

끝나고 해야 할 일

언리얼 강의 듣던 내용 마저 듣기

DX강의 보기

모던 C++ 챌린지 따라 치고 정리하기

이득우의 게임수학 책 읽기

리얼타임 렌더링 책 읽기

게임엔진 책 읽기

나중에 볼 영상 다 보기

공부 폴더 유튜브 다 보기

면접 질문 다시 쭉 쓰기

1Q2Q4Q 내용 정리하기

모든 Collider들을 CollisionManager에 등록시킬까…?

240122_Transform Reflection

Transform Quaternion 값 Reflection

처음에 그냥 float 값 get set이 필요한 줄 알았다. float GetYaw / AddYawRotation(float)로 회전값을 float 값으로 변경이 가능했다

변수로 Vector3 프로퍼티를 가져야 한다고 해서 Rotator에 ToVector3를 추가, Quarternion에 ToVector3를 추가 했다. 그래서 Vector3 m_eulerAngle에 Quarternion이 수정되면 값이 바뀌게 두었다.

m_eulerAngle 값 에디터에서 조절해서 값 바꿔야 한다

현재 m_rotation을 바꾸면 m_eulerAngle을 바꾸게는 했다.

m_eulerAngle 바꾸면 어떻게 m_rotation 바꿔주지…?

X pitch Y yaw Z roll

Add()함수 호출…? 에디터에서 변경할 때 값만 바꾸는거 아닌가…?

값을 바꿀 때 원하는 함수를 호출할 수 있다!

reflection으로 에디터에서 값을 변경할 때

AddPitchRotation() / AddYawRotation() / AddRollRotation() 불러 주기로 했다.

240123_Transform 의존성역전

abstract 키워드

표준이 아니다 c++에서는 = 0 만 표준이다
MS에서 만든 내용이여서 당연하게 썼고 이게 표준인 줄 알았다.

Transform

Entity들의 부모자식관계를 갖고있다. 그래서 자식 Entity e의 Component 하나를 업데이트 하기 위해서 Entity parent Transform에서 갖고와야한다.

Parent component update 후에 본인의 트랜스폼에서 자식의 트랜스폼을 전부 갖고온다. 그래서 자식 오브젝트로 접근해서 자식 오브젝트의 해당 컴포넌트를 업데이트 한다.

오브젝트에서 컴포넌트들을 업데이트 할 때 중간에 트랜스폼을 왔다갔다 하는 것이 적합한지에 대한 의문이다. 기능을 제공해 Component이지만 Entity의 Component를 Update 하기 위해서는 필수적으로 존재한다. 의존성이 역전이 된 것 같다.

240129_DX장치초기화

Constant Buffer

CPU → GPU로 버텍스 데이터를 다시 넘기기 X

offset 정보만 넣어서 SRT 조정하기 O

RS 레스터라이저 단계

뒷면 컬링 해주기, 뒷면 결정 방향 정하기

IA → VS → RS → PS → OM

SamplerState / BlendState

역행렬 구하기

Scale → Rotation → Translate → Rotation → Parent

scale이 다른 연산에 영향을 안 미친다

0개의 댓글