SlideShare a Scribd company logo
1 of 23
Texture Array를 이용한 Cascaded
Shadow Maps
유영천
Microsoft Visual C++ MVP
tw:@dgtman
http://megayuchi.wordpress.com
• 현 시점에서 가장 대중적으로 사용되고 있는 그림자 렌더링 기법
• 구현하기 쉽다.
• Soft-shadow처리도 쉽다.
Shadow Maps
• 광원(그림자를 드리울)의 뷰공간에서 Shadow Caster가 될
오브젝트들(혹은 월드 전체)을 렌더링 -> Depth Buffer(Texture)를
구성
구현 – Pass 0 , Shadow Caster
구현 – Pass 1 , Shadow Receiver
• 광원(그림자를 드리운)의 View- Space로 변환.
• -1 ~ 1사이의 좌표공간을 0 – 1사이로 변환.
• 변환된 (0 – 1사이) 좌표로 Depth Buffer로부터 depth값을 샘플링
• Receiver의 depth값과 Depth Buffer의 depth값을 비교
• receiver_z > depth_value -> 그림자가 드리워짐
Shadow Map in Shadow Space On Rendering in Camera Space
Shadow Map applied
① ②
③
Shader Resource View
Sampling z-value from
Shadow Map
Compare z-value ① and ②
per pixel.
• 한 장의 Texture로 넓은 공간을 표현하기엔 해상도가 부족함.
• Texture 사이즈를 크게? -> 품질향상, But 성능 하락, GPU메모리
낭비
• PSM, TSM, LiPSM 등등 한 장의 Texture만을 사용하면서 최대한
낭비 없이 사용하는 기법들 등장
그냥 쓰기엔 약간 문제가…
• Shadow Map을 만들 때 한 장의 Texture가 아닌 여러 장의 Texture에
나눠 그리자.
• 뷰프러스텀 영역을 여러 개의 공간으로 잘라서 여러 장의 Shadow
Map Texture를 할당.
• 가까운 영역과 먼 영역에 따라 Shadow Map 정밀도 조절 가능.
• Shadow Map 해상도 증가에 따른 낭비가 적다.
Cascaded Shadow Maps
eye
Shadow Light
Shadow Map Texture – Size(Width x N , Height)
⓪ ① ② ③
⓪ ① ② ③
⓪ ① ② ③
• Shadow Map으로 사용할 Texture 준비
• N개의 Cascaded 단계를 사용한다면 Texture 사이즈는 Width x N, Height
• Width x N인 이유는 한 장의 Texture에 N단계의 Shadow Map을 담기
위함이다.
• 루프를 돌며 0 ~ N-1단계까지 Shadow Caster를 렌더링.
• 뷰포트 설정을 바꿔가며 한 장의 Texture에 모두 담는다.
• Shadow Receiver를 렌더링할때 픽셀이 어느 Cascaded단계에
들어가는지 찾아서 tex좌표의 u성분 offset조정
• 이후는 일반적인 Shadow Map과 똑같음.
구현
• Cascaded단계에 따라 Draw Call회수가 늘어남. CPU 자원 낭비.
• 코드 복잡해짐.
• 한방에 모든 Cascaded 단계를 처리할 수 없을까?
개선하고 싶은 점
• 말 그대로 Texture배열
• 배열이지만 단일 Texture처럼 다룰 수 있다.
• SRV, RTV로 사용 가능.
• CPU측 코드에서 API사용 방법은 일반 Texture와 똑같다.
• Texture로부터 샘플링시 좌표의 x,y,z성분중 z성분을 배열의
인덱스로 사용
Texture Array
Texture2DArray texDiffuseArray: register(t0);
SamplerState samplerDiffuse: register(s0);
float4 psArrayDiffuse(PS_INPUT input) : SV_Target
{
float3 texCoord = float3(input.TexCoord.xy,TexArrayIndex);
float4 texColor = texDiffuseArray.Sample(samplerDiffuse, texCoord);
float4 outColor = texColor;
return outColor;
}
Using Texture Array as SRV
Using Texture Array as RTV
struct PS_OUT_TEX_ARRAY
{
float4 Pos : SV_POSITION;
uint RTIndex : SV_RenderTargetArrayIndex;
};
[maxvertexcount(3)]
void gsDefault ( triangle GS_INPUT input[3], inout TriangleStream<PS_OUT_TEX_ARRAY> TriStream )
{
PS_OUT_TEX_ARRAY output;
for (uint i=0; i<3; i++)
{
output.Pos = mul(input[i].PosWorld,matViewProjList[i]);
output.RTIndex = N;
TriStream.Append(output[j]);
}
TriStream.RestartStrip();
}
• N개의 Cascaded단계가 있을 때 사이즈 Width , Height에 배열이
N개인 Texture 생성
• 일반 Texture와 마찬가지로 RTV와 SRV생성
• Shader안에서 어느 Cascaded 단계에 포함되는지 계산하고 그
인덱스 값을 텍스쳐 좌표의 z성분으로 사용
Texture Arrary를 Shadow Maps에 적용
UINT Width = DEFAULT_SHADOW_MAP_WIDTH;
UINT Height = DEFAULT_SHADOW_MAP_HEIGHT;
UINT ArrayCount = MAX_CASCADE_NUM;
D3D11_TEXTURE2D_DESC texDesc =
{
Width, Height, 1, ArrayCount, DXGI_FORMAT_R32_TYPELESS, 1, 0, D3D11_USAGE_DEFAULT, D3D11_BIND_DEPTH_STENCIL |
D3D11_BIND_SHADER_RESOURCE, 0, 0
};
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = { DXGI_FORMAT_D32_FLOAT, D3D11_DSV_DIMENSION_TEXTURE2DARRAY, 0 };
dsvDesc.Texture2DArray.FirstArraySlice = 0;
dsvDesc.Texture2DArray.ArraySize = ArrayCount;
dsvDesc.Texture2DArray.MipSlice = 0;
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = { DXGI_FORMAT_R32_FLOAT, D3D11_SRV_DIMENSION_TEXTURE2DARRAY, 0, 0 };
srvDesc.Texture2DArray.FirstArraySlice = 0;
srvDesc.Texture2DArray.ArraySize = ArrayCount;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.MostDetailedMip = 0;
ID3D11Texture2D* pTex = nullptr;
HRESULT hr = m_pD3DDevice->CreateTexture2D(&texDesc, NULL, &pTex);
if (FAILED(hr))
__debugbreak();
hr = m_pD3DDevice->CreateDepthStencilView(pTex, &dsvDesc, &m_pShadowMapDSV);
if (FAILED(hr))
__debugbreak();
hr = m_pD3DDevice->CreateShaderResourceView(pTex, &srvDesc, &m_pShadowMapSRV);
if (FAILED(hr))
__debugbreak();
pTex->Release();
Creating SRV,DSV from Texture Array
Texture Texture Array
// set matrix for shadow-space,
SetCascadedLightSpaceAll(N);
// Draw shadow casters to Depth Buffer
DrawShadowCasters();
for (DWORD i=0; i<N; i++)
{
// set matrix for shadow-space,
SetCascadedLightSpace(i);
// Draw shadow casters to Depth Buffer
DrawShadowCasters();
}
CPU Code – Shadow Caster 렌더링 비교
cbuffer ConstantBufferShadowMap : register( b0 )
{
matrix matWorld;
matrix matViewList[MAX_CASCADE_NUM];
matrix matProjList[MAX_CASCADE_NUM];
}
struct PS_OUT_TEX_ARRAY
{
float4 Pos : SV_POSITION;
uint RTIndex : SV_RenderTargetArrayIndex;
};
struct GS_INPUT
{
float4 PosWorld: POSITION;
};
Shader Code – Pass 0 , Shadow Caster
float4 vsShadowCaster( VS_INPUT_VL input ) : POSITION
{
float4 PosWorld = mul( input.Pos, matWorld );
return PosWorld;
}
[maxvertexcount(3*MAX_CASCADE_NUM)]
void gsShadowCaster( triangle GS_INPUT input[3], inout TriangleStream<PS_OUT_TEX_ARRAY> TriStream )
{
PS_OUT_TEX_ARRAY output[3];
for (uint i=0; i<MAX_CASCADE_NUM; i++ )
{
for (uint j=0; j<3; j++)
{
float4 PosView = mul(input[j].PosWorld,matViewList[i]);
PosView.z += 2.5f; // bias value
output[j].Pos = mul(PosView,matProjList[i]);
output[j].RTIndex = i;
TriStream.Append(output[j]);
}
TriStream.RestartStrip();
}
}
Shader Code – Pass 0 , Shadow Caster
cbuffer ConstantBufferGBufferShader : register (b0)
{
matrix ViewInv;
matrix matShadowViewProjCascade[MAX_CASCADE_NUM];
CASCADE_CONSTNAT CascadeConst[MAX_CASCADE_NUM];
};
Texture2DArray texShadowMap: register(t2);
SamplerComparisonState samplerComp : register(s2);
void CalcIndex(out float OutIndex, in float Dist)
{
uint index = MAX_CASCADE_NUM - 1;
for (uint i = 0; i < MAX_CASCADE_NUM; i++)
{
if (Dist <= CascadeConst[i].Dist)
{
index = i;
break;
}
}
OutIndex = index;
}
Shader Code – Pass 1 , Shadow Receiver
float3 CalcShadowColor3x3(Texture2DArray texShadowMap, SamplerComparisonState samplerComp, float4 PosWorld, float Dist)
{
float3 shadowColor = float3(1, 1, 1);
uint index;
CalcIndex(index, Dist);
float4 PosShadowSpace = mul(PosWorld, matShadowViewProjCascade[index]);
float4 texCoord = PosShadowSpace / PosShadowSpace.w;
float cmp_z = texCoord.z;
float litSum = 0;
int2 offset[9] = {-1,-1, 0,-1, 1,-1, -1,0, 0,0, 1,0, -1,1, 0,1, 1,1 };
for (int i = 0; i < 9; i++)
{
litSum += texShadowMap.SampleCmpLevelZero(samplerComp, float3(texCoord.xy,index), cmp_z, offset[i]);
}
float shadowValue = litSum / 9.0f;
shadowColor = lerp(float3(0,0,0), float3(1, 1, 1), shadowValue);
return shadowColor;
}
Shader Code – Pass 1 , Shadow Receiver
• Draw Call을 대폭 줄일 수 있다. CPU측 병목을 줄임
• 코드가 보다 간결해짐.
Texture Array사용의 장점
• 각각의 Light View Space 프러스텀에 대한 culling
• 프러스텀에 대한 culling을 먼저 수행한 후 Constant Buffer를 통해 bit
flags로 전달.
• Geometry Shader에서 0,1,2,3… 각 비트를 체크하며 0 – N까지의
Cascaded단계에 포함되는지를 검사. 비트가 0이면 그대로 폐기.
• GPU상에서 클리핑이 이루어지므로 CPU측에서 별도의 Culling작업에
필요한 시간을 감안하면 굳이 필요가 없을지도????
추가적인 최적화
Reference
• https://msdn.microsoft.com/en-
us/library/windows/desktop/ee416307(v=vs.85).aspx
• http://developer.download.nvidia.com/SDK/10.5/opengl/src/cascade
d_shadow_maps/doc/cascaded_shadow_maps.pdf

More Related Content

What's hot

Compute shader DX11
Compute shader DX11Compute shader DX11
Compute shader DX11민웅 이
 
[0107 박민근] 쉽게 배우는 hdr과 톤맵핑
[0107 박민근] 쉽게 배우는 hdr과 톤맵핑[0107 박민근] 쉽게 배우는 hdr과 톤맵핑
[0107 박민근] 쉽게 배우는 hdr과 톤맵핑MinGeun Park
 
Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)Bongseok Cho
 
[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shading[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shadingMinGeun Park
 
캐주얼 게임 배경에서 Vertex Color 활용법
캐주얼 게임 배경에서 Vertex Color 활용법캐주얼 게임 배경에서 Vertex Color 활용법
캐주얼 게임 배경에서 Vertex Color 활용법지영 신
 
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)Bongseok Cho
 
Brdf기반 사전정의 스킨 셰이더
Brdf기반 사전정의 스킨 셰이더Brdf기반 사전정의 스킨 셰이더
Brdf기반 사전정의 스킨 셰이더동석 김
 
2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑Sukwoo Lee
 
[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유Hwan Min
 
포인트 셰도우
포인트 셰도우포인트 셰도우
포인트 셰도우Sukwoo Lee
 
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근MinGeun Park
 
[IGC 2016] 넷게임즈 김영희 - Unreal4를 사용해 모바일 프로젝트 제작하기
[IGC 2016] 넷게임즈 김영희 - Unreal4를 사용해 모바일 프로젝트 제작하기[IGC 2016] 넷게임즈 김영희 - Unreal4를 사용해 모바일 프로젝트 제작하기
[IGC 2016] 넷게임즈 김영희 - Unreal4를 사용해 모바일 프로젝트 제작하기강 민우
 
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019devCAT Studio, NEXON
 
Ndc12 이창희 render_pipeline
Ndc12 이창희 render_pipelineNdc12 이창희 render_pipeline
Ndc12 이창희 render_pipelinechangehee lee
 
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14AMD Developer Central
 
빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술YEONG-CHEON YOU
 
191019 Forward / Deferred Rendering
191019 Forward / Deferred Rendering191019 Forward / Deferred Rendering
191019 Forward / Deferred RenderingKWANGIL KIM
 

What's hot (20)

Compute shader DX11
Compute shader DX11Compute shader DX11
Compute shader DX11
 
[0107 박민근] 쉽게 배우는 hdr과 톤맵핑
[0107 박민근] 쉽게 배우는 hdr과 톤맵핑[0107 박민근] 쉽게 배우는 hdr과 톤맵핑
[0107 박민근] 쉽게 배우는 hdr과 톤맵핑
 
Ndc11 이창희_hdr
Ndc11 이창희_hdrNdc11 이창희_hdr
Ndc11 이창희_hdr
 
Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)Precomputed atmospheric scattering(사전 계산 대기 산란)
Precomputed atmospheric scattering(사전 계산 대기 산란)
 
[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shading[Ndc11 박민근] deferred shading
[Ndc11 박민근] deferred shading
 
Ssao
SsaoSsao
Ssao
 
캐주얼 게임 배경에서 Vertex Color 활용법
캐주얼 게임 배경에서 Vertex Color 활용법캐주얼 게임 배경에서 Vertex Color 활용법
캐주얼 게임 배경에서 Vertex Color 활용법
 
멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)멀티스레드 렌더링 (Multithreaded rendering)
멀티스레드 렌더링 (Multithreaded rendering)
 
Brdf기반 사전정의 스킨 셰이더
Brdf기반 사전정의 스킨 셰이더Brdf기반 사전정의 스킨 셰이더
Brdf기반 사전정의 스킨 셰이더
 
2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑
 
[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유[KGC2014] DX9에서DX11로의이행경험공유
[KGC2014] DX9에서DX11로의이행경험공유
 
포인트 셰도우
포인트 셰도우포인트 셰도우
포인트 셰도우
 
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
 
DirectX 11 Rendering in Battlefield 3
DirectX 11 Rendering in Battlefield 3DirectX 11 Rendering in Battlefield 3
DirectX 11 Rendering in Battlefield 3
 
[IGC 2016] 넷게임즈 김영희 - Unreal4를 사용해 모바일 프로젝트 제작하기
[IGC 2016] 넷게임즈 김영희 - Unreal4를 사용해 모바일 프로젝트 제작하기[IGC 2016] 넷게임즈 김영희 - Unreal4를 사용해 모바일 프로젝트 제작하기
[IGC 2016] 넷게임즈 김영희 - Unreal4를 사용해 모바일 프로젝트 제작하기
 
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
김혁, <드래곤 하운드>의 PBR과 레이트레이싱 렌더링 기법, NDC2019
 
Ndc12 이창희 render_pipeline
Ndc12 이창희 render_pipelineNdc12 이창희 render_pipeline
Ndc12 이창희 render_pipeline
 
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
Vertex Shader Tricks by Bill Bilodeau - AMD at GDC14
 
빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술빠른 렌더링을 위한 오브젝트 제외 기술
빠른 렌더링을 위한 오브젝트 제외 기술
 
191019 Forward / Deferred Rendering
191019 Forward / Deferred Rendering191019 Forward / Deferred Rendering
191019 Forward / Deferred Rendering
 

Viewers also liked

프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~YEONG-CHEON YOU
 
Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .YEONG-CHEON YOU
 
[0122 구경원]게임에서의 충돌처리
[0122 구경원]게임에서의 충돌처리[0122 구경원]게임에서의 충돌처리
[0122 구경원]게임에서의 충돌처리KyeongWon Koo
 
Porting direct x 11 desktop game to uwp app
Porting direct x 11 desktop game to uwp appPorting direct x 11 desktop game to uwp app
Porting direct x 11 desktop game to uwp appYEONG-CHEON YOU
 
GPGPU(CUDA)를 이용한 MMOG 캐릭터 충돌처리
GPGPU(CUDA)를 이용한 MMOG 캐릭터 충돌처리GPGPU(CUDA)를 이용한 MMOG 캐릭터 충돌처리
GPGPU(CUDA)를 이용한 MMOG 캐릭터 충돌처리YEONG-CHEON YOU
 
게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPUYEONG-CHEON YOU
 
10_Raytracing Introduction
10_Raytracing Introduction10_Raytracing Introduction
10_Raytracing Introductionnoerror
 
Hierarchical z buffer occlusion culling
Hierarchical z buffer occlusion cullingHierarchical z buffer occlusion culling
Hierarchical z buffer occlusion cullingJaeyun Lee
 
DirectX + C++을 이용한 WindowsStore App과 Windows Phone용 게임 개발
DirectX + C++을 이용한  WindowsStore App과 Windows Phone용 게임 개발DirectX + C++을 이용한  WindowsStore App과 Windows Phone용 게임 개발
DirectX + C++을 이용한 WindowsStore App과 Windows Phone용 게임 개발YEONG-CHEON YOU
 
[0602 박민근] Direct2D
[0602 박민근] Direct2D[0602 박민근] Direct2D
[0602 박민근] Direct2D흥배 최
 
[스마트스터디] 재택근무 잘 하고 있어요
[스마트스터디] 재택근무 잘 하고 있어요[스마트스터디] 재택근무 잘 하고 있어요
[스마트스터디] 재택근무 잘 하고 있어요Hyekyoung Yun
 
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해종빈 오
 
스타트업에서 기술책임자로 살아가기
스타트업에서 기술책임자로 살아가기스타트업에서 기술책임자로 살아가기
스타트업에서 기술책임자로 살아가기Hyun-woo Park
 

Viewers also liked (13)

프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
 
Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .Tips and experience of DX12 Engine development .
Tips and experience of DX12 Engine development .
 
[0122 구경원]게임에서의 충돌처리
[0122 구경원]게임에서의 충돌처리[0122 구경원]게임에서의 충돌처리
[0122 구경원]게임에서의 충돌처리
 
Porting direct x 11 desktop game to uwp app
Porting direct x 11 desktop game to uwp appPorting direct x 11 desktop game to uwp app
Porting direct x 11 desktop game to uwp app
 
GPGPU(CUDA)를 이용한 MMOG 캐릭터 충돌처리
GPGPU(CUDA)를 이용한 MMOG 캐릭터 충돌처리GPGPU(CUDA)를 이용한 MMOG 캐릭터 충돌처리
GPGPU(CUDA)를 이용한 MMOG 캐릭터 충돌처리
 
게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU
 
10_Raytracing Introduction
10_Raytracing Introduction10_Raytracing Introduction
10_Raytracing Introduction
 
Hierarchical z buffer occlusion culling
Hierarchical z buffer occlusion cullingHierarchical z buffer occlusion culling
Hierarchical z buffer occlusion culling
 
DirectX + C++을 이용한 WindowsStore App과 Windows Phone용 게임 개발
DirectX + C++을 이용한  WindowsStore App과 Windows Phone용 게임 개발DirectX + C++을 이용한  WindowsStore App과 Windows Phone용 게임 개발
DirectX + C++을 이용한 WindowsStore App과 Windows Phone용 게임 개발
 
[0602 박민근] Direct2D
[0602 박민근] Direct2D[0602 박민근] Direct2D
[0602 박민근] Direct2D
 
[스마트스터디] 재택근무 잘 하고 있어요
[스마트스터디] 재택근무 잘 하고 있어요[스마트스터디] 재택근무 잘 하고 있어요
[스마트스터디] 재택근무 잘 하고 있어요
 
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
 
스타트업에서 기술책임자로 살아가기
스타트업에서 기술책임자로 살아가기스타트업에서 기술책임자로 살아가기
스타트업에서 기술책임자로 살아가기
 

Similar to Implements Cascaded Shadow Maps with using Texture Array

NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
[14.10.21] Far Cry and DX9 번역(shaderstudy)
[14.10.21] Far Cry and DX9 번역(shaderstudy)[14.10.21] Far Cry and DX9 번역(shaderstudy)
[14.10.21] Far Cry and DX9 번역(shaderstudy)해강
 
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...종빈 오
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9진현 조
 
Bs webgl소모임002
Bs webgl소모임002Bs webgl소모임002
Bs webgl소모임002Seonki Paik
 
Unity Surface Shader for Artist 01
Unity Surface Shader for Artist 01Unity Surface Shader for Artist 01
Unity Surface Shader for Artist 01SangYun Yi
 
NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스Sungik Kim
 
Reflective Shadow Maps
Reflective Shadow MapsReflective Shadow Maps
Reflective Shadow MapsBongseok Cho
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기Yongha Yoo
 
Modern gpu optimize blog
Modern gpu optimize blogModern gpu optimize blog
Modern gpu optimize blogozlael ozlael
 
Light in screen_space(Light Pre Pass)
Light in screen_space(Light Pre Pass)Light in screen_space(Light Pre Pass)
Light in screen_space(Light Pre Pass)민웅 이
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현noerror
 
5-1. html5 graphics
5-1. html5 graphics5-1. html5 graphics
5-1. html5 graphicsJinKyoungHeo
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택JinTaek Seo
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기jongho jeong
 
Voxel based game_optimazation_relelase
Voxel based game_optimazation_relelaseVoxel based game_optimazation_relelase
Voxel based game_optimazation_relelaseYEONG-CHEON YOU
 
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법강 민우
 

Similar to Implements Cascaded Shadow Maps with using Texture Array (20)

NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
[14.10.21] Far Cry and DX9 번역(shaderstudy)
[14.10.21] Far Cry and DX9 번역(shaderstudy)[14.10.21] Far Cry and DX9 번역(shaderstudy)
[14.10.21] Far Cry and DX9 번역(shaderstudy)
 
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9
 
Bs webgl소모임002
Bs webgl소모임002Bs webgl소모임002
Bs webgl소모임002
 
Unity Surface Shader for Artist 01
Unity Surface Shader for Artist 01Unity Surface Shader for Artist 01
Unity Surface Shader for Artist 01
 
NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스NDC11_김성익_슈퍼클래스
NDC11_김성익_슈퍼클래스
 
Reflective Shadow Maps
Reflective Shadow MapsReflective Shadow Maps
Reflective Shadow Maps
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기
 
D2 Rain (1/2)
D2 Rain (1/2)D2 Rain (1/2)
D2 Rain (1/2)
 
Modern gpu optimize blog
Modern gpu optimize blogModern gpu optimize blog
Modern gpu optimize blog
 
Modern gpu optimize
Modern gpu optimizeModern gpu optimize
Modern gpu optimize
 
Light in screen_space(Light Pre Pass)
Light in screen_space(Light Pre Pass)Light in screen_space(Light Pre Pass)
Light in screen_space(Light Pre Pass)
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
 
5-1. html5 graphics
5-1. html5 graphics5-1. html5 graphics
5-1. html5 graphics
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기
 
D2 Rain (2/2)
D2 Rain (2/2)D2 Rain (2/2)
D2 Rain (2/2)
 
Voxel based game_optimazation_relelase
Voxel based game_optimazation_relelaseVoxel based game_optimazation_relelase
Voxel based game_optimazation_relelase
 
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
[IGC2018] 유영천 개발자 - Voxel기반 네트워크 게임 최적화기법
 

More from YEONG-CHEON YOU

DirectStroage프로그래밍소개
DirectStroage프로그래밍소개DirectStroage프로그래밍소개
DirectStroage프로그래밍소개YEONG-CHEON YOU
 
CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트
CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트
CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트YEONG-CHEON YOU
 
Visual Studio를 이용한 어셈블리어 학습 part 2
Visual Studio를 이용한 어셈블리어 학습 part 2Visual Studio를 이용한 어셈블리어 학습 part 2
Visual Studio를 이용한 어셈블리어 학습 part 2YEONG-CHEON YOU
 
Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1YEONG-CHEON YOU
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기YEONG-CHEON YOU
 
XDK없이 XBOX게임 개발하기(UWP on XBOX)
XDK없이 XBOX게임 개발하기(UWP on XBOX)XDK없이 XBOX게임 개발하기(UWP on XBOX)
XDK없이 XBOX게임 개발하기(UWP on XBOX)YEONG-CHEON YOU
 
Introduction to DirectX 12 Programming , Ver 1.5
Introduction to DirectX 12 Programming , Ver 1.5Introduction to DirectX 12 Programming , Ver 1.5
Introduction to DirectX 12 Programming , Ver 1.5YEONG-CHEON YOU
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현YEONG-CHEON YOU
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략YEONG-CHEON YOU
 
CUDA를 게임 프로젝트에 적용하기
CUDA를 게임 프로젝트에 적용하기CUDA를 게임 프로젝트에 적용하기
CUDA를 게임 프로젝트에 적용하기YEONG-CHEON YOU
 
서버와 클라이언트 같은 엔진 사용하기
서버와 클라이언트 같은 엔진 사용하기서버와 클라이언트 같은 엔진 사용하기
서버와 클라이언트 같은 엔진 사용하기YEONG-CHEON YOU
 
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법YEONG-CHEON YOU
 
win32 app에서 UWP API호출하기
win32 app에서 UWP API호출하기win32 app에서 UWP API호출하기
win32 app에서 UWP API호출하기YEONG-CHEON YOU
 
Azure로 MMO게임 서비스하기
Azure로 MMO게임 서비스하기Azure로 MMO게임 서비스하기
Azure로 MMO게임 서비스하기YEONG-CHEON YOU
 
Development AR App with C++ and Windows Holographic API
Development AR App with C++ and Windows Holographic APIDevelopment AR App with C++ and Windows Holographic API
Development AR App with C++ and Windows Holographic APIYEONG-CHEON YOU
 
빌드관리 및 디버깅 (2010년 자료)
빌드관리 및 디버깅 (2010년 자료)빌드관리 및 디버깅 (2010년 자료)
빌드관리 및 디버깅 (2010년 자료)YEONG-CHEON YOU
 
Tips and experience_of_dx12_engine_development._ver_1.2
Tips and experience_of_dx12_engine_development._ver_1.2Tips and experience_of_dx12_engine_development._ver_1.2
Tips and experience_of_dx12_engine_development._ver_1.2YEONG-CHEON YOU
 

More from YEONG-CHEON YOU (19)

DirectStroage프로그래밍소개
DirectStroage프로그래밍소개DirectStroage프로그래밍소개
DirectStroage프로그래밍소개
 
CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트
CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트
CUDA Raytracing을 이용한 Voxel오브젝트 가시성 테스트
 
Visual Studio를 이용한 어셈블리어 학습 part 2
Visual Studio를 이용한 어셈블리어 학습 part 2Visual Studio를 이용한 어셈블리어 학습 part 2
Visual Studio를 이용한 어셈블리어 학습 part 2
 
Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1Visual Studio를 이용한 어셈블리어 학습 part 1
Visual Studio를 이용한 어셈블리어 학습 part 1
 
나만의 엔진 개발하기
나만의 엔진 개발하기나만의 엔진 개발하기
나만의 엔진 개발하기
 
XDK없이 XBOX게임 개발하기(UWP on XBOX)
XDK없이 XBOX게임 개발하기(UWP on XBOX)XDK없이 XBOX게임 개발하기(UWP on XBOX)
XDK없이 XBOX게임 개발하기(UWP on XBOX)
 
Introduction to DirectX 12 Programming , Ver 1.5
Introduction to DirectX 12 Programming , Ver 1.5Introduction to DirectX 12 Programming , Ver 1.5
Introduction to DirectX 12 Programming , Ver 1.5
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략
 
Voxelizaition with GPU
Voxelizaition with GPUVoxelizaition with GPU
Voxelizaition with GPU
 
Sw occlusion culling
Sw occlusion cullingSw occlusion culling
Sw occlusion culling
 
CUDA를 게임 프로젝트에 적용하기
CUDA를 게임 프로젝트에 적용하기CUDA를 게임 프로젝트에 적용하기
CUDA를 게임 프로젝트에 적용하기
 
서버와 클라이언트 같은 엔진 사용하기
서버와 클라이언트 같은 엔진 사용하기서버와 클라이언트 같은 엔진 사용하기
서버와 클라이언트 같은 엔진 사용하기
 
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
 
win32 app에서 UWP API호출하기
win32 app에서 UWP API호출하기win32 app에서 UWP API호출하기
win32 app에서 UWP API호출하기
 
Azure로 MMO게임 서비스하기
Azure로 MMO게임 서비스하기Azure로 MMO게임 서비스하기
Azure로 MMO게임 서비스하기
 
Development AR App with C++ and Windows Holographic API
Development AR App with C++ and Windows Holographic APIDevelopment AR App with C++ and Windows Holographic API
Development AR App with C++ and Windows Holographic API
 
빌드관리 및 디버깅 (2010년 자료)
빌드관리 및 디버깅 (2010년 자료)빌드관리 및 디버깅 (2010년 자료)
빌드관리 및 디버깅 (2010년 자료)
 
Tips and experience_of_dx12_engine_development._ver_1.2
Tips and experience_of_dx12_engine_development._ver_1.2Tips and experience_of_dx12_engine_development._ver_1.2
Tips and experience_of_dx12_engine_development._ver_1.2
 

Implements Cascaded Shadow Maps with using Texture Array

  • 1. Texture Array를 이용한 Cascaded Shadow Maps 유영천 Microsoft Visual C++ MVP tw:@dgtman http://megayuchi.wordpress.com
  • 2. • 현 시점에서 가장 대중적으로 사용되고 있는 그림자 렌더링 기법 • 구현하기 쉽다. • Soft-shadow처리도 쉽다. Shadow Maps
  • 3. • 광원(그림자를 드리울)의 뷰공간에서 Shadow Caster가 될 오브젝트들(혹은 월드 전체)을 렌더링 -> Depth Buffer(Texture)를 구성 구현 – Pass 0 , Shadow Caster
  • 4. 구현 – Pass 1 , Shadow Receiver • 광원(그림자를 드리운)의 View- Space로 변환. • -1 ~ 1사이의 좌표공간을 0 – 1사이로 변환. • 변환된 (0 – 1사이) 좌표로 Depth Buffer로부터 depth값을 샘플링 • Receiver의 depth값과 Depth Buffer의 depth값을 비교 • receiver_z > depth_value -> 그림자가 드리워짐
  • 5. Shadow Map in Shadow Space On Rendering in Camera Space Shadow Map applied ① ② ③ Shader Resource View Sampling z-value from Shadow Map Compare z-value ① and ② per pixel.
  • 6. • 한 장의 Texture로 넓은 공간을 표현하기엔 해상도가 부족함. • Texture 사이즈를 크게? -> 품질향상, But 성능 하락, GPU메모리 낭비 • PSM, TSM, LiPSM 등등 한 장의 Texture만을 사용하면서 최대한 낭비 없이 사용하는 기법들 등장 그냥 쓰기엔 약간 문제가…
  • 7. • Shadow Map을 만들 때 한 장의 Texture가 아닌 여러 장의 Texture에 나눠 그리자. • 뷰프러스텀 영역을 여러 개의 공간으로 잘라서 여러 장의 Shadow Map Texture를 할당. • 가까운 영역과 먼 영역에 따라 Shadow Map 정밀도 조절 가능. • Shadow Map 해상도 증가에 따른 낭비가 적다. Cascaded Shadow Maps
  • 8. eye Shadow Light Shadow Map Texture – Size(Width x N , Height) ⓪ ① ② ③ ⓪ ① ② ③ ⓪ ① ② ③
  • 9. • Shadow Map으로 사용할 Texture 준비 • N개의 Cascaded 단계를 사용한다면 Texture 사이즈는 Width x N, Height • Width x N인 이유는 한 장의 Texture에 N단계의 Shadow Map을 담기 위함이다. • 루프를 돌며 0 ~ N-1단계까지 Shadow Caster를 렌더링. • 뷰포트 설정을 바꿔가며 한 장의 Texture에 모두 담는다. • Shadow Receiver를 렌더링할때 픽셀이 어느 Cascaded단계에 들어가는지 찾아서 tex좌표의 u성분 offset조정 • 이후는 일반적인 Shadow Map과 똑같음. 구현
  • 10. • Cascaded단계에 따라 Draw Call회수가 늘어남. CPU 자원 낭비. • 코드 복잡해짐. • 한방에 모든 Cascaded 단계를 처리할 수 없을까? 개선하고 싶은 점
  • 11. • 말 그대로 Texture배열 • 배열이지만 단일 Texture처럼 다룰 수 있다. • SRV, RTV로 사용 가능. • CPU측 코드에서 API사용 방법은 일반 Texture와 똑같다. • Texture로부터 샘플링시 좌표의 x,y,z성분중 z성분을 배열의 인덱스로 사용 Texture Array
  • 12. Texture2DArray texDiffuseArray: register(t0); SamplerState samplerDiffuse: register(s0); float4 psArrayDiffuse(PS_INPUT input) : SV_Target { float3 texCoord = float3(input.TexCoord.xy,TexArrayIndex); float4 texColor = texDiffuseArray.Sample(samplerDiffuse, texCoord); float4 outColor = texColor; return outColor; } Using Texture Array as SRV
  • 13. Using Texture Array as RTV struct PS_OUT_TEX_ARRAY { float4 Pos : SV_POSITION; uint RTIndex : SV_RenderTargetArrayIndex; }; [maxvertexcount(3)] void gsDefault ( triangle GS_INPUT input[3], inout TriangleStream<PS_OUT_TEX_ARRAY> TriStream ) { PS_OUT_TEX_ARRAY output; for (uint i=0; i<3; i++) { output.Pos = mul(input[i].PosWorld,matViewProjList[i]); output.RTIndex = N; TriStream.Append(output[j]); } TriStream.RestartStrip(); }
  • 14. • N개의 Cascaded단계가 있을 때 사이즈 Width , Height에 배열이 N개인 Texture 생성 • 일반 Texture와 마찬가지로 RTV와 SRV생성 • Shader안에서 어느 Cascaded 단계에 포함되는지 계산하고 그 인덱스 값을 텍스쳐 좌표의 z성분으로 사용 Texture Arrary를 Shadow Maps에 적용
  • 15. UINT Width = DEFAULT_SHADOW_MAP_WIDTH; UINT Height = DEFAULT_SHADOW_MAP_HEIGHT; UINT ArrayCount = MAX_CASCADE_NUM; D3D11_TEXTURE2D_DESC texDesc = { Width, Height, 1, ArrayCount, DXGI_FORMAT_R32_TYPELESS, 1, 0, D3D11_USAGE_DEFAULT, D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE, 0, 0 }; D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = { DXGI_FORMAT_D32_FLOAT, D3D11_DSV_DIMENSION_TEXTURE2DARRAY, 0 }; dsvDesc.Texture2DArray.FirstArraySlice = 0; dsvDesc.Texture2DArray.ArraySize = ArrayCount; dsvDesc.Texture2DArray.MipSlice = 0; D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = { DXGI_FORMAT_R32_FLOAT, D3D11_SRV_DIMENSION_TEXTURE2DARRAY, 0, 0 }; srvDesc.Texture2DArray.FirstArraySlice = 0; srvDesc.Texture2DArray.ArraySize = ArrayCount; srvDesc.Texture2DArray.MipLevels = 1; srvDesc.Texture2DArray.MostDetailedMip = 0; ID3D11Texture2D* pTex = nullptr; HRESULT hr = m_pD3DDevice->CreateTexture2D(&texDesc, NULL, &pTex); if (FAILED(hr)) __debugbreak(); hr = m_pD3DDevice->CreateDepthStencilView(pTex, &dsvDesc, &m_pShadowMapDSV); if (FAILED(hr)) __debugbreak(); hr = m_pD3DDevice->CreateShaderResourceView(pTex, &srvDesc, &m_pShadowMapSRV); if (FAILED(hr)) __debugbreak(); pTex->Release(); Creating SRV,DSV from Texture Array
  • 16. Texture Texture Array // set matrix for shadow-space, SetCascadedLightSpaceAll(N); // Draw shadow casters to Depth Buffer DrawShadowCasters(); for (DWORD i=0; i<N; i++) { // set matrix for shadow-space, SetCascadedLightSpace(i); // Draw shadow casters to Depth Buffer DrawShadowCasters(); } CPU Code – Shadow Caster 렌더링 비교
  • 17. cbuffer ConstantBufferShadowMap : register( b0 ) { matrix matWorld; matrix matViewList[MAX_CASCADE_NUM]; matrix matProjList[MAX_CASCADE_NUM]; } struct PS_OUT_TEX_ARRAY { float4 Pos : SV_POSITION; uint RTIndex : SV_RenderTargetArrayIndex; }; struct GS_INPUT { float4 PosWorld: POSITION; }; Shader Code – Pass 0 , Shadow Caster
  • 18. float4 vsShadowCaster( VS_INPUT_VL input ) : POSITION { float4 PosWorld = mul( input.Pos, matWorld ); return PosWorld; } [maxvertexcount(3*MAX_CASCADE_NUM)] void gsShadowCaster( triangle GS_INPUT input[3], inout TriangleStream<PS_OUT_TEX_ARRAY> TriStream ) { PS_OUT_TEX_ARRAY output[3]; for (uint i=0; i<MAX_CASCADE_NUM; i++ ) { for (uint j=0; j<3; j++) { float4 PosView = mul(input[j].PosWorld,matViewList[i]); PosView.z += 2.5f; // bias value output[j].Pos = mul(PosView,matProjList[i]); output[j].RTIndex = i; TriStream.Append(output[j]); } TriStream.RestartStrip(); } } Shader Code – Pass 0 , Shadow Caster
  • 19. cbuffer ConstantBufferGBufferShader : register (b0) { matrix ViewInv; matrix matShadowViewProjCascade[MAX_CASCADE_NUM]; CASCADE_CONSTNAT CascadeConst[MAX_CASCADE_NUM]; }; Texture2DArray texShadowMap: register(t2); SamplerComparisonState samplerComp : register(s2); void CalcIndex(out float OutIndex, in float Dist) { uint index = MAX_CASCADE_NUM - 1; for (uint i = 0; i < MAX_CASCADE_NUM; i++) { if (Dist <= CascadeConst[i].Dist) { index = i; break; } } OutIndex = index; } Shader Code – Pass 1 , Shadow Receiver
  • 20. float3 CalcShadowColor3x3(Texture2DArray texShadowMap, SamplerComparisonState samplerComp, float4 PosWorld, float Dist) { float3 shadowColor = float3(1, 1, 1); uint index; CalcIndex(index, Dist); float4 PosShadowSpace = mul(PosWorld, matShadowViewProjCascade[index]); float4 texCoord = PosShadowSpace / PosShadowSpace.w; float cmp_z = texCoord.z; float litSum = 0; int2 offset[9] = {-1,-1, 0,-1, 1,-1, -1,0, 0,0, 1,0, -1,1, 0,1, 1,1 }; for (int i = 0; i < 9; i++) { litSum += texShadowMap.SampleCmpLevelZero(samplerComp, float3(texCoord.xy,index), cmp_z, offset[i]); } float shadowValue = litSum / 9.0f; shadowColor = lerp(float3(0,0,0), float3(1, 1, 1), shadowValue); return shadowColor; } Shader Code – Pass 1 , Shadow Receiver
  • 21. • Draw Call을 대폭 줄일 수 있다. CPU측 병목을 줄임 • 코드가 보다 간결해짐. Texture Array사용의 장점
  • 22. • 각각의 Light View Space 프러스텀에 대한 culling • 프러스텀에 대한 culling을 먼저 수행한 후 Constant Buffer를 통해 bit flags로 전달. • Geometry Shader에서 0,1,2,3… 각 비트를 체크하며 0 – N까지의 Cascaded단계에 포함되는지를 검사. 비트가 0이면 그대로 폐기. • GPU상에서 클리핑이 이루어지므로 CPU측에서 별도의 Culling작업에 필요한 시간을 감안하면 굳이 필요가 없을지도???? 추가적인 최적화