언리얼에서는 아래와 같이 간단히 마스터 마테리얼에서 텍스쳐와 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 |