DirectX 9을 이용한 게임 개발 기본 코스 강의 내용 : blending
목 차 블랜딩 구현
실습 InitGeometryTexture() 함수 텍스처 이름을 tree1.bmp로 변경, 실행 DDS 파일 열어보기 DirectX Texture Tool 프로그램 실행 BMP와 DDS의 차이점 확인
블렌딩(Blending) 그려진 물체의 픽셀의 색에 그릴 물체의 픽셀의 색을 섞는(블렌딩) 기술 섞는 비율을 조절하면 반투명한 효과를 낼 수 있다. ex) 투명효과(알파블렌딩) 나무 상자를 배경으로 반투명한 주전자
투명도 투명도를 나타내기 위해, 색상에 투명도 채널을 추가하여 (r, g, b, a)로 쓰고, a를 알파라고 부르며, 픽셀의 불투명도를 나타낸다. 알파 채널에 8bit가 할당되었다면, 유효범위는 [0, 255]가 된다. 0(검정) 0% 불투명 투명 128(회색) 50% 불투명 255(흰색) 100% 불투명 알파 채널이 float형이면 유효범위는 [0, 1] material.diffuse.a
알파 블랜딩 예제 ? 위와 같은 인수일 때, 최종 픽셀의 색은? D3DXCOLOR(r,g,b,a) SourceColor = D3DXCOLOR( 0.0f, 1.0f, 0.0f, 0.6f ); DestColor = D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1.0f); OutputColor = ? 참고: 배경의 alpha는 항상 1(완전 불투명) ?
알파 채널이 포함된 텍스처 포토샵이나 DirectX Texture Tool을 통해서 제작할 수 있다. 32bit ARGB + = 32bit ARGB A8R8G8B8 24bit RGB 8bit Gray
알파 채널이 포함된 텍스처 (cont’) DirectX Texture Tool 이용하여 알파채널이 포함된 텍스처 만들기 1. 알파채널이 포함되지 않은 텍스처를 오픈 한다. 2. 포멧 변경 Format > Change Surface Format X8R8G8B8 A8R8G8B8
알파 채널이 포함된 텍스처 (cont’) 3. 알파 맵(8bit 그레이스케일)을 알파맵으로 오픈 4. 저장 File>Open Onto Alpha Channel Of This Texture 투명한 부분은 이 툴의 배경색이 보인다. (하늘색) 4. 저장 DirectX의 텍스처 포맷 dds로 저장
실습 Texture tool을 이용하여 tree1.bmp를 tree1.dds로 변경 Format 변경 (a8r8g8b8) 회색조 alpha영상을 그림판으로 생성하여 적용 Alpha 의 원리 확인
Alpha Blending 공식 – back to front C(color), A(alpha) C결과 = C물체 A물체 + C배경 (1-A물체) Color = Color1 x weight1 + Color2 x weight2 두 색상을 적절한 비율로 섞는 블랜딩(blending) 공식을 이용하여 다양하게 기능 확장 가능하다.
블렌딩 공식 Source Pixel : 앞으로 그릴 픽셀의 색 (r, g, b) Source Blend Factor : Source Pixel의 농도. [0, 1]범위 Dest Pixel : 이미 그려진 픽셀의 색 (r, g, b) Destination Blend Factor : Dest Pixel의 농도. [0, 1]범위 모든 성분 4D 벡터 ( r, g, b, a )
블렌딩 활성화 알파 블랜딩 관련 설정을 수행한다. 반투명한 물체를 그린다. Device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); 알파 블랜딩 관련 설정을 수행한다. 반투명한 물체를 그린다. 알파 블렌딩 관련 작업이 끝나면 블렌딩을 비활성화 해준다. Device->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
블렌딩 연산자 Device->SetRenderState( D3DRS_BLENDOP, value ); value D3DBLENDOP_ADD (기본값) Source + Destination D3DBLENDOP_SUBTRACT Source - Destination D3DBLENDOP_REVSUBTRACT Destination - Source D3DBLENDOP_MIN MIN(Source, Destination) D3DBLENDOP_MAX MAX(Source, Destination) D3DBLENDOP_FORCE_DWORD
블렌드 인수(Factor) Device->SetRenderState( D3DRS_SRCBLEND, Source Blend Factor ); Device->SetRenderState( D3DRS_DESTBLEND, Destination Blend Factor );
블렌드 인수(Factor) (cont’) Device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); // alpha Device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); // 1-alpha
블렌드 인수(Factor) Factors : ( r, g, b, a ) D3DBLEND_ZERO : (0, 0, 0, 0) D3DBLEND_ONE : (1, 1, 1, 1) D3DBLEND_SRCCOLOR : (rs, gs, bs, as) D3DBLEND_INVSRCCOLOR : (1-rs, 1-gs, 1-bs, 1-as) D3DBLEND_SRCALPHA : (as, as, as, as) (Source Blend 기본값) D3DBLEND_INVSRCALPHA : (1-as, 1-as, 1-as, 1-as) (Destination Blend 기본값) D3DBLEND_DESTALPHA : (ad, ad, ad, ad) D3DBLEND_INVDESTALPHA : (1-ad, 1-ad, 1-ad, 1-ad) D3DBLEND_DESTCOLOR : (rd, gd, bd, ad) D3DBLEND_INVDESTCCOLOR : (1-rd, 1-gd, 1-bd, 1-ad) D3DBLEND_SRCALPHASAT : (f, f, f, 1); f=min(as, 1-ad)
이용되는 알파 값의 소스 1. Texture의 알파 채널을 이용한 방법 2. Material 구조체의 Diffuse.a값을 이용한 방법 3. Texture + Material 동시 이용한 방법 m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTEXTUREOP ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTEXTUREOP ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); D3DTEXTUREOP = { D3DTOP_DISABLE, D3DTOP_SELECTARG1, D3DTOP_SELECTARG2, D3DTOP_MODULATE, D3DTOP_MODULATE2X, D3DTOP_MODULATE4X, D3DTOP_ADD, D3DTOP_ADDSIGNED, D3DTOP_ADDSIGNED2X, D3DTOP_SUBTRACT, D3DTOP_ADDSMOOTH ... };
실습 Render()함수에서 다음 부분 주석 해지 (4문장) g_pd3dDevice->SetTexture(0,0); 노란색 사각형은 어디서 나온 정보인가 반투명 정보는 어디서 나온 정보인가 InitGeometryTexture에서 color값 찾기 Alpha값을 변경하여 실행
실습 - 생각해보기 Render 함수의 주석을 다시 설정 Wood texture의 경우, 왜 alpha blend 설정이 없는가? DX Graphics documents에서 “D3DTSS_ALPHAOP”을 검색 D3DTEXTURESTAGESTATE TYPE DX 기본 설정 Texture-stage state is a texture alpha blending operation identified by one member of the D3DTEXTUREOP enumerated type. The default value for the first texture stage (stage 0) is D3DTOP_SELECTARG1, and for all other stages the default is D3DTOP_DISABLE.
알파블랜딩 예제 - Material 이용 1. 블렌드 인수 D3DRS_SRCBLEND와 D3DRS_DESTBLEND를 지정한다. 2. 알파 성분을 이용한다면 원본을 지정한다. 재질이나 택스처의 알파채널 3. 알파 블렌딩 렌더 상태를 활성화 한다.
알파블랜딩 예제 - Material 이용 // 배경 박스 렌더링 (텍스처를 갖고 있는 물체) m_pd3dDevice->SetTexture( 0, m_pTex ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(CUSTOMVERTEX) ); m_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
알파블랜딩 예제 - Material 이용 // 주전자 렌더링 (재질만 있는 물체) D3DMATERIAL9 mtrl; D3DUtil_InitMaterial( mtrl, 0.0f, 1.0f, 0.0f, 0.5f ); m_pd3dDevice->SetMaterial( &mtrl ); m_pd3dDevice->SetTexture( 0, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
알파블랜딩 예제 - Material 이용 m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); m_pd3dDevice- >SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); m_pd3dDevice- >SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); m_pD3DXMesh->DrawSubset(0); m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, false );
알파 블랜딩과 깊이 순서 블랜딩은 순서가 바뀌면 결과 색상이 달라짐 일단, 블랜딩 되고 나면 색을 원상태로 분리할 수 없음 혼합된 결과가 (1, 0.5, 0.7, 1) 이다. 어떤 두 색이 혼합된 것인가? 블랜딩은 순서가 바뀌면 결과 색상이 달라짐 (1, 0, 0, 0.5) over (0, 0, 1, 0.5) over (1,1,1,1) = ? (0, 0, 1, 0.5) over (1, 0, 0, 0.5) over (1,1,1,1) = ? 반투명한 물체는 눈에서 먼 거리 순서로 렌더링과 블랜딩을 수행해야 한다. 중간에 색상을 끼워 넣을 수 없다. 불투명한 물체를 그릴 때는 눈과의 거리 순서에 관계없이 그려도 좋다. DX가 물체와 눈과의 거리를 계산하여 가까운 물체만 선택하여 보여줌
불투명 물체 먼저 그린 후 반투명 물체를 그린다. 반투명 물체들은 카메라로부터 멀리 있는 물체부터 그려준다. 프로그래머가, 물체들을 거리 순으로 직접 정렬하여 순차적으로 Draw해야 한다.
실습 – 화염 애니메이션 다음과 같이 변경 후 실행 BOOL g_bWoodTexture = FALSE; InitGeometryTexture() 확인 Fire.bmp 를 탐색기로 열어 확인 Alpha 채널이 없음 어떻게 블랜딩을 구현했는가 어떻게 애니메이션을 구현했는가
화염 애니메이션 Render 함수 ChangeSpriteUV() 함수 Blend option이 “ONE”임 (0, 0, 0, 0) over (1, 0, 1, 1) = (1, 0, 1, 1) // 노란색 (0, 0, 0, 0) + (1, 0, 1, 1) = (1, 0, 1, 1) // 노란색 값이 매우 작으면 알파 블랜딩와 덧셈이 유사 ChangeSpriteUV() 함수 각 프레임마다 좌표 검사 SPRITE g_Fire = {15, 0, 0, 1}; 로 변경하고 실행 큰 텍스처의 일부를 연속적으로 표시함 텍스처 애니메이션 기법