[Shader / HLSL] RunTime Compile Shader / Shader Macro

2021. 12. 19. 01:58·Shader

RunTime Compile Shader

 

Binary File Load

- 해당 Shader File을 Compile 해둔 파일을 Binary로 읽어들여 사용하는 방식.

- 이미 Compile 된 Shader를 사용하기 때문에 원본 Shader는 필요가 없으며, Compile 된 파일만 필요하다.

- RunTime Compile시에 사용할 수 있는 Macro, EntryPoint, Shader Model Version 설정은 불가능.

- Shader File Compile 시 Shader Model Version, EntryPoint 설정 후 Compile 해야하는 불편함이 있다.

 

RunTime Compile

- 해당 Shader File을 RunTime에 Compile 하는 방식, Shader File을 Compile 해둘 필요가 없다.

- RunTime시 Compile을 할 경우 Macro, EntryPoint Shader Model Version을 설정 할 수 있다.

- 같은 Shader File이여도 다른 버전과 다른 코드의 방식으로 Compile이 가능하다.

 

Shader Macro

- RunTime Compile시에 사용되는 Shader Macro struct.- 해당 struct에 Define 하고싶은 Define Name과 Value를 넣어 Compile 시 해당 Shader에 Macro를 추가 할 수 있다.

 

float4 Light_PS(VertexIn pin) : SV_TARGET
{
    float4 albedo = gAlbedoRT.Sample(gSamWrapLinear, pin.Tex);
    float4 normal = gNormalRT.Sample(gSamWrapLinear, pin.Tex);
    float4 position = gPositionRT.Sample(gSamWrapLinear, pin.Tex);
    float4 shadow = gShadowRT.Sample(gSamWrapLinear, pin.Tex);
    float4 ssao = mul(gViewProjTex, float4(position.xyz, 1.0f));
	
    // Gamma Correction
    // Gamma Space -> Linear Space
    // 모든 라이팅 연산은 선형 공간에서 이루어져야 한다..
#ifdef GAMMA_CORRECTION
    albedo.rgb = pow(albedo.rgb, 2.2f);
#endif
    float4 litColor = albedo;
    
    // Start with a sum of zero.
    float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
    float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
    float4 spec = float4(0.0f, 0.0f, 0.0f, 0.0f);
    
    // View Direction
    float3 ViewDirection = gEyePosW - position.xyz;
    ViewDirection = normalize(ViewDirection);
    
    // 현재 픽셀의 Shadow 값..
    float shadows = 1.0f;
	
#ifdef SHADOW
    shadows = CalcShadowFactor(gSamBorderComparisonLinearPoint, gShadowMap, float3(shadow.xyz));
#endif	
	
    // 현재 픽셀의 SSAO 값..
    float ambientAccess = 1.0f;
	
#ifdef SSAO
    ssao /= ssao.w;
    ambientAccess = gSsaoMap.SampleLevel(gSamWrapLinear, ssao.xy, 0.0f).r;
#endif	
    
    // 현재 픽셀의 Material ID..
    uint matID = round(position.w);

    float4 A, D, S;
	
    if (shadow.w < 1.0f)
    {
		// Directional Light
        ComputeDirectionalLight(gMaterials[matID], gDirLights, float3(normal.xyz), ViewDirection,
			A, D, S);

        ambient += ambientAccess * A;
        diffuse += shadows * D;
        spec += shadows * S;
        
        // Point Light
        if (gPointLightCount > 0)
        {
            for (uint i = 0; i < gPointLightCount; ++i)
            {
                ComputePointLight(gMaterials[matID], gPointLights[i], float3(position.xyz), float3(normal.xyz), ViewDirection,
					A, D, S);

                ambient += A;
                diffuse += D;
                spec += S;
            }
        }
        
        // Spot Light
        if (gSpotLightCount > 0)
        {
			[unroll]
            for (uint i = 0; i < gSpotLightCount; ++i)
            {
                ComputeSpotLight(gMaterials[matID], gSpotLights[i], float3(position.xyz), float3(normal.xyz), ViewDirection,
					A, D, S);

                ambient += A;
                diffuse += D;
                spec += S;
            }
        }
		
        // Modulate with late add.
        litColor = albedo * (ambient + diffuse) + spec;
    }
    
    // Common to take alpha from diffuse material and texture.
    litColor.a = gMaterials[matID].Diffuse.a * albedo.a;
    
    // Gamma Correction
    // Normal Map은 선형공간에서 출력..
    // Diffuse Map은 감마공간에서 출력..
#ifdef GAMMA_CORRECTION
    if (normal.w < 1.0f)
        litColor.rgb = pow(litColor.rgb, 1.0f / 2.2f);
#endif
    
    return litColor;
}

위의 코드와 같이 #ifdef 로 코드 분기를 넣어 둘 수 있는데 이 Define은 Compile시 추가할 수 있으므로 여러개의 Shader File을

만들 필요가 없다.

 

// Shader Macro
D3D_SHADER_MACRO light0_macro[] = { {"GAMMA_CORRECTION"}, {"SHADOW"}, {"SSAO"}, {NULL, NULL} };
D3D_SHADER_MACRO light1_macro[] = { {"SHADOW"}, {"SSAO"}, {NULL, NULL} };
D3D_SHADER_MACRO light2_macro[] = { {"GAMMA_CORRECTION"}, {"SSAO"}, {NULL, NULL} };
D3D_SHADER_MACRO light3_macro[] = { {"GAMMA_CORRECTION"}, {"SHADOW"}, {NULL, NULL} };
D3D_SHADER_MACRO light4_macro[] = { {"GAMMA_CORRECTION"}, {NULL, NULL} };
D3D_SHADER_MACRO light5_macro[] = { {"SHADOW"}, {NULL, NULL} };
D3D_SHADER_MACRO light6_macro[] = { {"SSAO"}, {NULL, NULL} };

// Light Shader
LoadShader(SHADER_TYPE::VERTEX_SHADER, "LightVS.hlsl", "Light_VS", "Light_VS");
LoadShader(SHADER_TYPE::PIXEL_SHADER, "LightPS.hlsl", "Light_PS", "Light_PS_Option0" ,light0_macro);
LoadShader(SHADER_TYPE::PIXEL_SHADER, "LightPS.hlsl", "Light_PS", "Light_PS_Option1" ,light1_macro);
LoadShader(SHADER_TYPE::PIXEL_SHADER, "LightPS.hlsl", "Light_PS", "Light_PS_Option2" ,light2_macro);
LoadShader(SHADER_TYPE::PIXEL_SHADER, "LightPS.hlsl", "Light_PS", "Light_PS_Option3" ,light3_macro);
LoadShader(SHADER_TYPE::PIXEL_SHADER, "LightPS.hlsl", "Light_PS", "Light_PS_Option4" ,light4_macro);
LoadShader(SHADER_TYPE::PIXEL_SHADER, "LightPS.hlsl", "Light_PS", "Light_PS_Option5" ,light5_macro);
LoadShader(SHADER_TYPE::PIXEL_SHADER, "LightPS.hlsl", "Light_PS", "Light_PS_Option6" ,light6_macro);
LoadShader(SHADER_TYPE::PIXEL_SHADER, "LightPS.hlsl", "Light_PS", "Light_PS_Option7");

D3D_SHADER_MACRO terrain_macro[] = { {"TERRAIN_MESH"}, {NULL, NULL} };

// Object Shader
LoadShader(SHADER_TYPE::VERTEX_SHADER, "ObjectVS.hlsl", "Mesh_VS", "Mesh_VS");
LoadShader(SHADER_TYPE::VERTEX_SHADER, "ObjectVS.hlsl", "Skin_VS", "Skin_VS");
LoadShader(SHADER_TYPE::VERTEX_SHADER, "ObjectVS.hlsl", "Mesh_VS", "Terrain_VS", terrain_macro);

위의 코드에서 LightPS.hlsl 에서는 같은 진입점이지만 Define을 다르게 주어 여러가지 버전의 Shader File을 Compile

할 수 있으며, ObjectVS.hlsl 에서는 같은 진입점이지만 Define은 다르게하고 다른 진입점을 통해 Shader File을 Compile

할 수 있다는 이점이 있다.

'Shader' 카테고리의 다른 글

[Shader / HLSL] Shader Reflection & Define Macro Resource Hash Table 을 이용한 Resource 동기화  (0) 2022.01.17
[Shader / HLSL] Shader Reflection & Define Macro를 이용한 Resource 관리 (3)  (0) 2021.12.19
[Shader / HLSL] Shader Reflection & Define Macro를 이용한 Resource 관리 (2)  (0) 2021.12.19
[Shader / HLSL] Shader Reflection & Define Macro를 이용한 Resource 관리 (1)  (0) 2021.12.19
[Shader / HLSL] Shader Reflection  (0) 2021.12.18
'Shader' 카테고리의 다른 글
  • [Shader / HLSL] Shader Reflection & Define Macro를 이용한 Resource 관리 (3)
  • [Shader / HLSL] Shader Reflection & Define Macro를 이용한 Resource 관리 (2)
  • [Shader / HLSL] Shader Reflection & Define Macro를 이용한 Resource 관리 (1)
  • [Shader / HLSL] Shader Reflection
KyuHwang
KyuHwang
  • KyuHwang
    DirectX Engine
    KyuHwang
  • 전체
    오늘
    어제
    • 분류 전체보기 (50)
      • C++ (4)
      • CS (0)
      • Graphics (32)
      • DLL (2)
      • Shader (7)
      • Project (4)
      • ETC (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • YouTube
  • 공지사항

  • 인기 글

  • 태그

    std::enable_if
    Shader Resource 관리
    Define Macro
    rigging chain
    Project
    std::is_base_of
    Shader Macro
    Shader Reflection
    DirectX 2D
    Hash Code
    Return Type Operator
    Win API
    C ++
    animation retargeting
    Implicit Linking
    nvtt
    Explicit Linking
    animation constraint
    texture block compression
    hlsl
    Order Independent Transparency
    bc format
    shader
    dll
    Define Function
    Alpha Blending
    mobile format
    Directx11
    DLL Interface
    RunTime Compile Shader
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
KyuHwang
[Shader / HLSL] RunTime Compile Shader / Shader Macro
상단으로

티스토리툴바