본문 바로가기
UE5/이런저런_테스트_메모

[UE5] 기본적인 Diffuse, Normal 맵 처리했던 방식

by 도트월드 2023. 3. 6.

 

 언리얼에서는 아래와 같이 간단히 마스터 마테리얼에서 텍스쳐와 Output 연결하면,

Static Mesh, Skeletal Mesh ( Skinned Mesh ) 둘 다 사용할 수 있다.

 

 언리얼이 Material Editor 가 아닌 직접적인 구현은 아래와 같은 HLSL 코드를 사용하는 방식으로 예전에는 사용했었다.

HLSL 코드 이외에 HLSL 코드를 설정하고 부르는 부분이 C++ 혹은 C# 으로 설정하는 등 외부 설정요인들이 많지만, 핵심 HLSL 코드 개념을 알면 엔진이 바뀌거나 다른 플랫폼에서 그래픽스 코어 부분을 수정해봐야 할 때 처음부터 새로 배울 필요 없이 수정할 지식을 가지게 된다.

 

 아마, 언리얼 코어 부분을 계속 파고들면, HLSL을 사용하는 플랫폼에서는 아래와 유사한 HLSL 코드들이 포함되어 있게 된다. ( 엔진에서 그래픽스 API를 직접 만드는건 비효율적이기 때문에 ) DirectX, OpenGL 같은 그래픽스 API 를 사용하기에 결국 내부를 파고들면 HLSL, GLSL 같은 코드들이 존재하게 된다.

 

cbuffer SkinningConstants : register(b0)
{
    float4x4 Bones [96];
};

Texture2D DiffuseMap;
SamplerState DiffuseSampler;

Texture2D NormalMap;
SamplerState NormalSampler;

float4x4 World;
float4x4 View;
float4x4 Projection;

struct VS_INPUT
{
    float3 Position : POSITION;
    float3 Normal : NORMAL;
    float2 TexCoord : TEXCOORD0;
    float4 Tangent : TANGENT;
    uint4 BoneIndices : BLENDINDICES;
    float4 BoneWeights : BLENDWEIGHT;
};

struct PS_INPUT
{
    float4 Position : SV_POSITION;
    float3 Normal : NORMAL;
    float3 Tangent : TANGENT;
    float3 Binormal : BINORMAL;
    float2 TexCoord : TEXCOORD0;
};

PS_INPUT VS(VS_INPUT input)
{
    PS_INPUT output;
    
    float4x4 boneTransform = 0;
    boneTransform += Bones[input.BoneIndices.x] * input.BoneWeights.x;
    boneTransform += Bones[input.BoneIndices.y] * input.BoneWeights.y;
    boneTransform += Bones[input.BoneIndices.z] * input.BoneWeights.z;
    boneTransform += Bones[input.BoneIndices.w] * input.BoneWeights.w;

    float3 worldPosition = mul(float4(input.Position, 1.0), boneTransform).xyz;
    float3 worldNormal = mul(input.Normal, boneTransform);
    float3 worldTangent = mul(input.Tangent.xyz, boneTransform);
    float3 worldBinormal = cross(worldNormal, worldTangent) * input.Tangent.w;

    output.Position = mul(mul(mul(float4(input.Position, 1.0), boneTransform), World), View), Projection);
    output.Normal = mul(worldNormal, World);
    output.Tangent = mul(worldTangent, World);
    output.Binormal = mul(worldBinormal, World);
    output.TexCoord = input.TexCoord;
    
    return output;
}

float4 PS(PS_INPUT input) : SV_Target
{
    float3 ambient = float3(0.1, 0.1, 0.1);
    float3 lightDir = normalize(float3(1.0, 1.0, 1.0));
    float3 diffuse = DiffuseMap.Sample(DiffuseSampler, input.TexCoord).rgb;
    float3 normal = NormalMap.Sample(NormalSampler, input.TexCoord).rgb * 2.0 - 1.0;
    normal = normalize(mul(normal, input.Tangent.xyz));
    float3 binormal = cross(input.Normal, input.Tangent.xyz) * input.Tangent.w;
    float3 tangent = cross(binormal, input.Normal);
    float3x3 TBN = float3x3(tangent, binormal, input.Normal);
    TBN = mul(TBN, World);
    normal = mul(normal, TBN);

    float3 diffuseLight = max(dot(normal, lightDir), 0.0) * diffuse;
    return float4(ambient + diffuseLight, 1.0);
}

 

 

반응형

'UE5 > 이런저런_테스트_메모' 카테고리의 다른 글

[UE5] Cloth Animation - import & setting  (0) 2023.04.03
[UE5] Fracture obj - 적용  (0) 2023.03.20
[UE5] Fracture Obj - 기본준비  (0) 2023.03.17
[UE5] Reroute Node  (0) 2023.03.06
[UE5] Material. Named Reroute Node 기능  (1) 2023.03.05