Adventure of 빠타박스
article thumbnail
728x90
728x90
SMALL

ImGui 활용한 DirectX 11 3D를 이용한 2D를 만드는 내용입니다.
본 내용은 똑같이 사용할 수 없음을 알립니다. (참고 및 공부자료로 만들어진 내용임을 밝힙니다.)
전 과정에 대해 이해를 해야 다음 이 부분에 대한 이해를 할 수 있음을 밝힙니다

이전 자료) https://ppatabox.tistory.com/33

 

 

 

1) sampler [각주:1]

 

 


 

저번 시간에 Uv이가 1이 넘어갈때 어떻게 처리될 것이냐 라는 옵션이 있다고 했는데

그 내용을 처리하는게 sampler이다.

 

쉐이더(Effect.hlsl)에서 sampler라는 게 들어갔는데

SamplerState Sampler : register(s0); //이기  밑에 
Texture2D Texture : register(t0);

float4 PS(PixelInput input) : SV_TARGET
{
    return Texture.Sample(Sampler, input.Uv); //여기에 들어간것 
}

 

샘플링이 하는 역할 

샘플러는 일단 샘플링을 하기 위한 옵션

 

예를들어 이미지가 50X50 이미지가 있다

그리고 정점이 렌더링 파이프라인에서 IA -> VS -> RS -> PS

에서 RS에서 PS올때 2D공간으로 바뀌면서 공간을 쫘악~ 채운다고 말했다.

 

 

채우고 난 사각형(공간)이 100X100이다 

그럼 이미지는 50이고 그려져야 할 공간의 크기가 100인데 

 

그렇다면 이미지는 2배가 늘어나서 확대가 돼야 한다.

 

 반대로 그려져야 할 공간이 25X25 공간이라고 쳐보자

그러면 이미지는 축소가 돼야 한다.

 

이때 확대 축소를 할 때 2D 이미지가 

작은 이미지를 키우려면 픽셀이 비워 보인다.

반대로 축소시킬 때는 픽셀을 버려야 한다.

 

이걸 어떻게 채울 것인가 없앨 것인가 라는 

옵션을 결정하는 게

샘플러의 역할이다.

 

MIN(Minification) 축소

MAG(Magnification) 확대

MIP-mapping 밉맵

Mipmap [각주:2]


게임은 퍼포먼스가 중요한데 CPU나 GPU연산량을 치면 일반 3D게임 은 연산량이 엄청나다 

다른것들은 아무리 써도 10%이네 쓰는데 요즘 게임은 50%이상 올라간다 

그정도로 퍼포먼스가 중요하다

그러다 보니 게임을 만들때는 엄청난 꼼수가 있다,

시스템에서 지원해주는 퍼포먼스를 올리는 지원이 있다.

 

옛날에는 램이 비쌋는데 이때는 잘 안썻는데

지금은 램이 싸서 램의 용량 공간의 용량을 늘려서 시간을 사는 

알고리즘에서 복잡도를 계산하는 게 있는데 

(시간 / 공간 복잡도) 지금 공간 복잡도는 의미가 없어서 빠짐

지금은 용량을 희생해서 시간을 사는

텍스쳐 이미지를 하나 부르면 2^n에 맞게 디자인됨

다른 일반이미지(포토샵)는 퍼포먼스보다 정밀도가 중요한데

513이라고 치면 513을 그대로 불러들인다

 

 

하지만 DX는  가장 근소한 승수를 찾는다

그러면 513-> 512 가 찾아진다.

그러고 나면 512로 부터 8장을 만든다.

512 -> 256 -> 128 -> 64 -> 32 -> ............................크기를 줄이면서 8장을 뽑아낸다(자동) 

 

그렇다면 512가 가장 정밀도가 높을 것이다.

그럼 플레이어가 가까이 있을때는 512를 보여주고 

점점 멀어질 수록 정밀도가 떨어지는 것을 보여준다.

그러면서 렌더링 양을 줄인다 이게 MIPMAPPING 

 

왠만하면 잘 안쓰는데 

진짜 극한의 퍼포먼스를 요구하는게임이 아니라면 

잘 안씀 그래도 그런 게임에서도 잘 사용은 안함 

 

요즘에는 이것도 무시할 만한 퍼포먼스가 됨 

 

우리는 이시간 다뤄도 mipmapping을  0으로 잡고 할것이다 ( 1장) 작업량 많아짐 

 


 

2pass연산(펄업)

 

 

이렇게 들어갈 수 있는게 있는데 

포인트샘플링(Point)[각주:3]

 

선형 필터링(Linear)[각주:4]

 

비등방성(Anistorpic)[각주:5]

 


 

anistropic은 이곳에 안쓸꺼임 (MSAA) 옵션 중에서 이런게 있음

안티에일리징? TXAA등등 왜곡된 픽셀을 좀 줄여주는 옵션 (비등방성 필터)

 

2개의 픽셀이 있다고 치자 

이게 2배가 늘어나야 한다고 하자

 

 

point는 그냥 기준에 있는 것을 가져다가 쓴다.

그럼 격자가 더 커진다 

 

리니어는 좌우의 값을 평균을 취한다. 

 

 

리니어 연산량 때문에 예전에는 포인트를 사용하다가

요즘에는 리니어로 만들고 있다.

 

 

-Graphic conferent-

Cgrapher 

GDC

anistopic으로 점점 넘어가고 있는데 

아직 좀 힘들 수 있다. 그래픽 카드가 엄청좋아지긴 했지만 그래도 엄청나게 연산처리때문에.. CPU나 GPU온도가 엄청나게 올라가는 걸 볼 수 있다. 

잡아야 할 것은 전력효율과 온도 , 효율적인 연산처리 방법이지 않을까?

 


 

항상 이런것을 만들때는 인터페이스가 필요하다.

 

인터페이스가 있으면 이런것을 생성할 때 항상 Description이 따라 붙는다고 했는데 

버텍스 버퍼 콘스탄스 버퍼도 description을 사용했었다.

0 초기화가 안되는 것들은 배열로 지정 되어 있으면 포인터 이기에 

0초기화가 안된다. 

예시로 

	D3D11_SAMPLER_DESC samplerDesc = { 0 };

저곳에 들어가 있는게 BorderColor 가 배열로 들어가 있다 그러면 포인터 인데

이러면 0초기화가 안된다. 

 

그러니 수정하면 

	D3D11_SAMPLER_DESC samplerDesc;

빼주고 

 

ZeroMemory로 해주자 

	D3D11_SAMPLER_DESC samplerDesc;
	ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC));

 

 

우리는 실시간으로 (좀 귀찮은 방식) 

 

어떤 자료형을 써야 하는지 잘 감이 안온다.

 

samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;

만약에 이러한게 있다고 하면 뒤에 저걸 어떻게 알았을까?

Filter에 F12누르면

 

이리 나오고 다음으로 

D3D11_FILTER //F12또 눌러보면

 

쭈루룩 뭐가 나오는 걸 볼 수 있다.

 

위에서 

 

 

 

 

 

 

D3D11_FILTER_MIN_MAG_MIP_POINT;

이것을 축소 확대 MIP을 포인트로 다 쓰겠다 라는 의미 

보통 같은거 많이 쓴다. 

축소, 확대, MIP리니어 같은 

 

처리하는 것?Min_Linear_Mag_Point_Mip_Linear

Min은 linear | Mag은 point | MipMap은 linear

 

ConstantBuffer는 16바이트 패딩

 

 

 

 

 

 

좌 우측 잘 보면 픽셀 깨짐정도가 다름 1) 0번이 포인트 선명한듯하지만 진하게 나옴 2) 1번이 리니어 부드럽게나옴

 

 

 

Texture.h 

#pragma once

class Texture
{
public:
	Texture(wstring file);
	~Texture();

	void Position(float x, float y, float z = 0);
	void Position(const D3DXVECTOR3& position);
	void Position(D3DXVECTOR3* position);

	void Scale(float x, float y, float z = 1);
	void Scale(const D3DXVECTOR3& scale);
	void Scale(D3DXVECTOR3* scale);

	void Render();

private:
	struct Vertex
	{
		D3DXVECTOR3 Location;
		D3DXVECTOR2 Uv;

		Vertex()
		{
			Location = D3DXVECTOR3();
			Uv = D3DXVECTOR2();
		}

		Vertex(D3DXVECTOR3 location, D3DXVECTOR2 uv)
		{
			Location = location;
			Uv = uv;
		}
	};

	struct WVP
	{
		D3DXMATRIX World;
		D3DXMATRIX View;
		D3DXMATRIX Projection;
	} wvp;

	struct PS_Constant //값 넘겨주기 
	{
		int Filter = 0; //이런식으로 초기화 해도됨 
		int Address = 0; 

		float Padding[2]; // 16바이트 맞춰주기 
	} sampler; //변수선언

private:
	D3DXVECTOR3 position;
	D3DXVECTOR3 scale;

private:
	Shader* shader;

	Vertex vertices[6];
	VertexBuffer* vertexBuffer;
	ConstantBuffer* wvpBuffer;
	ConstantBuffer* samplerBuffer; //샘플러버퍼 

	ID3D11ShaderResourceView* srv;
	
	ID3D11SamplerState* samplerFilter_Point; // 우리가 쓸 샘플러 
	ID3D11SamplerState* samplerFilter_Linear; // 우리가 쓸 샘플러
/*옵션 */
	ID3D11SamplerState* samplerAddress_Wrap;
	ID3D11SamplerState* samplerAddress_Mirror; 
	ID3D11SamplerState* samplerAddress_Clamp;
	ID3D11SamplerState* samplerAddress_Border;
	ID3D11SamplerState* samplerAddress_MirrorOnce;
};

 

 

Texture.cpp 

#include "stdafx.h"
#include "Texture.h"

Texture::Texture(wstring file)
{
	vertices[0] = Vertex(D3DXVECTOR3(-0.5f, -0.5f, 0), D3DXVECTOR2(0, 5));
	vertices[1] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXVECTOR2(0, 0));
	vertices[2] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXVECTOR2(5, 5));

	vertices[3] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXVECTOR2(5, 5));
	vertices[4] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXVECTOR2(0, 0));
	vertices[5] = Vertex(D3DXVECTOR3(+0.5f, +0.5f, 0), D3DXVECTOR2(5, 0));


	D3D11_INPUT_ELEMENT_DESC layoutDesc[] =
	{
		"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0,
		"UV", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0
	};
	UINT elementCount = ARRAYSIZE(layoutDesc);
 

	shader = new Shader(L"effect.hlsl");
	shader->CreateInputLayout(layoutDesc, elementCount);

	vertexBuffer = new VertexBuffer(vertices, 6, sizeof(Vertex)); 
	wvpBuffer = new ConstantBuffer(&wvp, sizeof(WVP));
	samplerBuffer = new ConstantBuffer(&sampler, sizeof(PS_Constant), 0, true); //slot 0 PS true


	D3DXMatrixIdentity(&wvp.World);
	D3DXMatrixIdentity(&wvp.View);
	D3DXMatrixIdentity(&wvp.Projection);


	D3DXVECTOR3 eye(0, 0, -1);
	D3DXVECTOR3 lookAt(0, 0, 0);
	D3DXVECTOR3 up(0, 1, 0);

	D3DXMatrixLookAtLH(&wvp.View, &eye, &lookAt, &up);
	D3DXMatrixTranspose(&wvp.View, &wvp.View);

	D3DXMatrixOrthoOffCenterLH(&wvp.Projection, 0, (float)Width, 0, (float)Height, -1, +1);
	D3DXMatrixTranspose(&wvp.Projection, &wvp.Projection);


	wstring textureFile = L"../_Textures/" + file;
	HRESULT hr = D3DX11CreateShaderResourceViewFromFile(Device, textureFile.c_str(), NULL, NULL, &srv, NULL);
	assert(SUCCEEDED(hr));


	D3D11_SAMPLER_DESC samplerDesc;
	ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC));
	
	samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; //U
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; //V
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; //W
	hr = Device->CreateSamplerState(&samplerDesc, &samplerFilter_Point); //&desc포인트 &2차포인트 
	assert(SUCCEEDED(hr));

	samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
	hr = Device->CreateSamplerState(&samplerDesc, &samplerFilter_Linear);
	assert(SUCCEEDED(hr));

    /*각각 옵션들*/
	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
	hr = Device->CreateSamplerState(&samplerDesc, &samplerAddress_Wrap);
	assert(SUCCEEDED(hr));

	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_MIRROR;
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_MIRROR;
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_MIRROR;
	hr = Device->CreateSamplerState(&samplerDesc, &samplerAddress_Mirror);
	assert(SUCCEEDED(hr));

	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
	hr = Device->CreateSamplerState(&samplerDesc, &samplerAddress_Clamp);
	assert(SUCCEEDED(hr));

	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
	
	float color[4] = { 1, 0, 0, 1 };
	memcpy(samplerDesc.BorderColor, color, sizeof(float) * 4);
	hr = Device->CreateSamplerState(&samplerDesc, &samplerAddress_Border);
	assert(SUCCEEDED(hr));

	samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;
	samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;
	samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE;
	hr = Device->CreateSamplerState(&samplerDesc, &samplerAddress_MirrorOnce);
	assert(SUCCEEDED(hr));
}

Texture::~Texture()
{
	SAFE_RELEASE(srv);

	SAFE_DELETE(vertexBuffer);
	SAFE_DELETE(wvpBuffer);

	SAFE_DELETE(shader);
}

void Texture::Position(float x, float y, float z)
{
	Position(D3DXVECTOR3(x, y, z));
}

void Texture::Position(const D3DXVECTOR3 & position)
{
	this->position = position;
}

void Texture::Position(D3DXVECTOR3 * position)
{
	memcpy(position, this->position, sizeof(D3DXVECTOR3));
}

void Texture::Scale(float x, float y, float z)
{
	Scale(D3DXVECTOR3(x, y, z));
}

void Texture::Scale(const D3DXVECTOR3 & scale)
{
	this->scale = scale;
}

void Texture::Scale(D3DXVECTOR3 * scale)
{
	memcpy(scale, this->scale, sizeof(D3DXVECTOR3));
}

void Texture::Render()
{
	ImGui::SliderInt("Fliter", &sampler.Filter, 0, 1); //
	ImGui::SliderInt("Address", &sampler.Address, 0, 4); //갯수 0~4까지 옵션들 


	D3DXMATRIX S, T;

	D3DXMatrixScaling(&S, scale.x, scale.y, scale.z);
	D3DXMatrixTranslation(&T, position.x, position.y, position.z); 

	wvp.World = S * T;
	D3DXMatrixTranspose(&wvp.World, &wvp.World);

	
	DeviceContext->PSSetSamplers(0, 1, &samplerFilter_Point); //PS그리는애  샘플러 넣어주고 
	DeviceContext->PSSetSamplers(1, 1, &samplerFilter_Linear); //1번에 리니어하나


	ID3D11SamplerState* samplerState[5]; //배열로 (2차포인터 5개 니까 ) 포인터 배열(포인터를 배열에 넣었다)
	samplerState[0] = samplerAddress_Wrap;
	samplerState[1] = samplerAddress_Mirror;
	samplerState[2] = samplerAddress_Clamp;
	samplerState[3] = samplerAddress_Border;
	samplerState[4] = samplerAddress_MirrorOnce;
	DeviceContext->PSSetSamplers(2, 5, samplerState);//2번에 넣고 5개 2차포인터(포인터에 포인터니까 이름만)


	DeviceContext->PSSetShaderResources(0, 1, &srv);
	DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	shader->Render();
	vertexBuffer->Render();
	
	wvpBuffer->Render();
	samplerBuffer->Render(); //샘플러 버퍼 밀어주기 PS에다가 컨스탄트 값밀어주기 

	DeviceContext->Draw(6, 0);
}

 

cbuffer PS_Constant : register(b0) //PS_Constant 밀어둔거 받기 
{
    int Filter;
    int Address;
}
.
.
float4 PS(PixelInput input) : SV_TARGET //리턴 타입이 float4 
{

이런 cbuffer 자기 쉐이더에 필요한 것들은 바로 위로 올려놓아 주자 (보기 편해짐) 

 

Effect.hlsl 

struct VertexInput
{
    float4 Position : POSITION0;
    float2 Uv : UV0;
};

struct PixelInput
{
    float4 Position : SV_POSITION;
    float2 Uv : UV0;
};


cbuffer VS_Wvp : register(b0)
{
    matrix World;
    matrix View;
    matrix Projection;
}

PixelInput VS(VertexInput input)
{
    PixelInput output;
    
    output.Position = mul(input.Position, World);
    output.Position = mul(output.Position, View);
    output.Position = mul(output.Position, Projection);
    output.Uv = input.Uv;

    return output;
}


cbuffer PS_Constant : register(b0) //PS_Constant 밀어둔거 받기 
{배열로 쓸경우가 아니라면 
    int Filter; //끝 패딩 안써도됨 이렇게 만들어줌 
    int Address; // 2개 이름 일치 안해도됨 형식만 
}

SamplerState Filter_Point : register(s0); //샘플러 포인트 0번 
SamplerState Filter_Linear : register(s1); // 1번으로 들어감 
SamplerState Sampler_Address[5] : register(s2); //옵션들 5개 2번 

Texture2D Texture : register(t0);

float4 PS(PixelInput input) : SV_TARGET //리턴 타입이 float4 
{
    if(Address == 0)//샘플의 리턴이 색상임 float4 0이랑 같으면 포인트 
        return Texture.Sample(Sampler_Address[0], input.Uv); 
    else if (Address == 1) 아니라면 리니어로 샘플링 
        return Texture.Sample(Sampler_Address[1], input.Uv);
    else if (Address == 2)
        return Texture.Sample(Sampler_Address[2], input.Uv);
    else if (Address == 3)
        return Texture.Sample(Sampler_Address[3], input.Uv);
    else if (Address == 4)
        return Texture.Sample(Sampler_Address[4], input.Uv);
    
    return float4(0, 0, 0, 1); //기본값 
}

 

 

샘플러에서는 FIlter랑 Address만 알면 되는데

 

Address모드는 1보다 클때 0.5 넣으면 반절만 나오게 됨 이때는 의미 없음

//Vector2 부분 0.5를 사용할때 1이 안넘어가서 Address모드 의미 없음 

vertices[0] = Vertex(D3DXVECTOR3(-0.5f, -0.5f, 0), D3DXVECTOR2(0, 0.5));
vertices[1] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXVECTOR2(0, 0));
vertices[2] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXVECTOR2(0.5, 0.5));

vertices[3] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXVECTOR2(0.5, 0.5));
vertices[4] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXVECTOR2(0, 0));
vertices[5] = Vertex(D3DXVECTOR3(+0.5f, +0.5f, 0), D3DXVECTOR2(0.5, 0));

 

 

2로 넣으면 반복됨 이게 어드레스 모드

vertices[0] = Vertex(D3DXVECTOR3(-0.5f, -0.5f, 0), D3DXVECTOR2(0, 2));
vertices[1] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXVECTOR2(0, 0));
vertices[2] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXVECTOR2(2, 2));

vertices[3] = Vertex(D3DXVECTOR3(+0.5f, -0.5f, 0), D3DXVECTOR2(2, 2));
vertices[4] = Vertex(D3DXVECTOR3(-0.5f, +0.5f, 0), D3DXVECTOR2(0, 0));
vertices[5] = Vertex(D3DXVECTOR3(+0.5f, +0.5f, 0), D3DXVECTOR2(2, 0));

 

이게 Address모드 이다

 

이게 1보다 클때 나머지 부분을 어떻게 채울 것이냐 라는 의미 

10 넣어도 10장 나옴 

 

 

D3D11_TEXTURE_ADDRESS

WRAP

WRAP[각주:6]

MIRROR

1번 반전

MIRROR [각주:7]

CLAMP

2번 끝에 대각선의 도장처럼 펼쳐둔거 (도장 찍고 펼친 느낌) 

CLAMP [각주:8]

 

 

BORDER

3번 선을 채우는 것인데 기본원래 검은색인데 빨간색으로 바꿔둠 

samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
	
float color[4] = { 1, 0, 0, 1 }; //border색상 
memcpy(samplerDesc.BorderColor, color, sizeof(float) * 4); 
//배열끼리는 직접안됨(memcpy) 직접적으로 배열끼리 하면 주소가 되서 안된다 그냥 데이터 복사해줌 
hr = Device->CreateSamplerState(&samplerDesc, &samplerAddress_Border);
assert(SUCCEEDED(hr));

BORDER [각주:9]

 

 

 

MIRROR_ONCE 이건 clamp랑 같이 동작하는데 옵션을 키지 않는한 (필요없음)

MIRROR_ONCE [각주:10]

 

 


Filter[각주:11]

 

 

 

추가참고링크)

 

DirectX, OpenGL 텍스처 필터링 ( Texture Filtering ) 관련

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 출처: https://m.blo..

202psj.tistory.com

 

 

 

 

 

 

다음내용 ) https://ppatabox.tistory.com/36

 

[C++] DirectX 원과 회전 Rotation

들어가기전sin과 cos의 대칭성을 알아야 한다.  KhanAcademy 회전이라는게 대칭성을 가져야 한다. 왜? 항상 사인과 코사인의 세타 값은 일치해야 한다. 직각삼각형을 보면 회전식을 얘기 할때 Y = sin *

ppatabox.tistory.com

 

 

 

 

 


각주)

1. 정점에 UV의 비율에 따라 이미지를 잘라주는 기능

2. 비율에 따라 확대 및 축소해주는 기능 [본문으로]
  • 렌더링 속도를 향상하고 연산을 줄이기 위한 목적, 기본 텍스쳐와 이를 연속적으로 미리 축소시킨 텍스쳐들로 이루어진 비트맵 이미지의 집합이다.

    텍스쳐 크기가 512x512라면, 그것의 절반 크기인 256, 218, 64 이런식으로 1x1이 될 때까지의 텍스쳐를 미리 가지고 있다가, 실제 텍셀보다 거리가 멀어져서 맵핑될 픽셀이 줄면 해상도가 더 낮은 텍스쳐를, 그 보다 멀어지면 더 작은 텍스쳐를 불러서 맵핑 시켜준다.

    밉맵 없이 Min/Mag 옵션으로 하는 것보다 미리 줄여놓은 텍스쳐를 가지고 있으면, 평균을 구하는 연산을 생략할 수 있다. 실제 밉맵을 사용하면 메모리는 30% 늘어난다고 한다. 런타임 성능은 좋아진다 [본문으로]

  • 이웃 픽셀을 그대로 복사함(모자이크) 필터링을 하지않고 텍스쳐 좌표에서 가장 가까운 정수 주소(address)를 가진 텍셀의 색을 카피함, 텍스쳐에서 문자를 표시하거나 외곽선이 뭉개지지 않을경우에 사용    [본문으로]
  • (1 - t) * A + t * B일때 t가 0일 경우 결과적으로는 A, point보다 더 부드럽게 나오며 연산량 높음, 텍스쳐 좌표에 가장 가까운 점의 상하 좌우에 있는 텍셀의 평균 가중치를 계산하여 보간함(일반적인 필터링) [본문으로]
  • 이방성 필터링, 이방성(물체의 물리적 성질이 방향에 따라 다름) 3D 개체의 표면이 스크린평면과 임의의 각을 이룰때 3D 개체의 텍셀에서 볼 수 있는 왜곡 현상, 텍스쳐도 이러한 성질을 가지고 있는데, Anistorpic필터링은 이 왜곡을 보정하도록 하는 필터링, 가장 깔끔하게 보이지만 성능은 안좋음, (*MSAA(multi-Sampling Anti-Aliasing:멀티샘플링) [본문으로]
  • 텍스쳐 좌표를 반복한다. [본문으로]
  • 인접한 이미지를 반복한다. [본문으로]
  • 텍스쳐 끝 부분의 픽셀이 늘어진다. [본문으로]
  • 경계색을 설정한다. [본문으로]
  • clamp+mirror모드 [본문으로]
  • 확대/축소를 실시했을때 중간 픽셀의 처리 방법을 실시한다

    비율이 늘어나고 줄어듬에 따라 빈 공간의 픽셀을 버릴것인지 채울것인지 [본문으로]

  • 728x90
    728x90
    LIST
    profile

    Adventure of 빠타박스

    @PPATABOX

    포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!