내가 좋아하는 재료 시스템 어떻게 내 머리 주위에 포장하기 위해 노력하고있어 이는 , 이 구현됩니다. 이 강력하고 사용자 친화적 인 그래프 형 시스템은 프로그래머와 프로그래머가 아닌 사람이 모두 셰이더를 빠르게 만들 수있는 방법 으로 비교적 일반적 으로 보입니다 . 그러나 그래픽 프로그래밍에 대한 상대적으로 제한된 경험으로 인해 어떻게 작동하는지 확실하지 않습니다.
배경:
따라서 이전에 간단한 OpenGL 렌더링 시스템을 프로그래밍 한 경우 일반적으로 수동으로 만든 정적 GLSL 파일에서 셰이더를로드, 컴파일 및 링크하는 Material 클래스를 만듭니다. 또한 보통이 클래스를 GLSL 균일 변수에 액세스하기위한 간단한 래퍼로 만듭니다. 간단한 예로, 기본 정점 셰이더와 프래그먼트 셰이더가 있고 텍스처를 전달하기 위해 균일 한 Texture2D가 있다고 상상해보십시오. 내 머티리얼 클래스는 단순히이 두 쉐이더를 머티리얼에로드하고 컴파일하며, 그 시점부터 해당 쉐이더의 Texture2D 유니폼을 읽고 쓰는 간단한 인터페이스를 노출시킵니다.
이 시스템을 좀 더 융통성있게 만들기 위해, 나는 보통 어떤 이름 / 유형의 유니폼이라도 전달할 수있는 방식으로 작성합니다 . 이것은 AmbientColor 균일 성을 머티리얼에 존재하는 경우 "colorVec4"라는 특정 4d 벡터로 설정합니다.] .
class Material
{
private:
int shaderID;
string vertShaderPath;
string fragSahderPath;
void loadShaderFiles(); //load shaders from files at internal paths.
void buildMaterial(); //link, compile, buffer with OpenGL, etc.
public:
void SetGenericUniform( string uniformName, int param );
void SetGenericUniform( string uniformName, float param );
void SetGenericUniform( string uniformName, vec4 param );
//overrides for various types, etc...
int GetUniform( string uniformName );
float GetUniform( string uniformName );
vec4 GetUniform( string uniformName );
//etc...
//ctor, dtor, etc., omitted for clarity..
}
이것은 작동 하지만 Material 클래스의 클라이언트가 믿음으로 유니폼에 액세스해야한다는 사실 때문에 나쁜 시스템처럼 느껴집니다. 사용자는 각 머티리얼 객체에있는 유니폼을 알고 있어야합니다. GLSL 이름으로 전달하십시오. 시스템을 사용하는 사람이 1-2 명인 경우에는 큰 문제가되지 않지만이 시스템이 전혀 확장되지 않을 것이라고 생각할 수 없으며 OpenGL 렌더링 시스템을 프로그래밍하기 위해 다음 시도를하기 전에 레벨을 조정하고 싶습니다. 조금 위로.
질문:
그것이 지금까지의 위치이므로 다른 렌더링 엔진이 머티리얼 시스템을 처리하는 방법을 연구하려고 노력했습니다.
이 노드 기반 접근 방식은 훌륭 하며 현대 엔진 및 도구에서 사용자 친화적 인 재료 시스템을 생성하기위한 매우 일반적인 시스템 인 것 같습니다. 내가 말할 수 있는 것은 각 노드가 머티리얼의 일부 쉐이더 측면을 나타내고 각 경로는 그들 사이의 일종의 관계를 나타내는 그래프 데이터 구조를 기반으로한다는 것입니다.
내가 알 수 있듯이, 그러한 종류의 시스템을 구현하는 것은 다양한 서브 클래스 (TextureNode, FloatNode, LerpNode 등)를 가진 단순한 MaterialNode 클래스 일 것입니다. 각 MaterialNode 서브 클래스에 MaterialConnections가있는 곳.
class MaterialConnection
{
MatNode_Out * fromNode;
MatNode_In * toNode;
}
class LerpNode : MaterialNode
{
MatNode_In x;
MatNode_In y;
MatNode_In alpha;
MatNode_Out result;
}
이것이 가장 기본적인 아이디어이지만,이 시스템의 몇 가지 측면이 어떻게 작동하는지에 대해서는 조금 불확실합니다.
1.) Unreal Engine 4에서 사용 하는 다양한 'Material Expressions'(노드)를 보면 각각 다양한 유형의 입력 및 출력 연결이 있음을 알 수 있습니다. 일부 노드 출력 플로트, 일부 출력 벡터 2, 일부 출력 벡터 4 등 다양한 입력 및 출력 유형을 지원할 수 있도록 노드 및 연결을 개선하려면 어떻게해야합니까? MatNode_Out_Float 및 MatNode_Out_Vec4 등으로 MatNode_Out을 서브 클래 싱하는 것이 현명한 선택입니까?
2.) 마지막으로, 이런 종류의 시스템은 GLSL 쉐이더와 어떤 관련이 있습니까? UE4를 다시 살펴보면 (그리고 위에 링크 된 다른 시스템과 유사하게), 사용자는 쉐이더 매개 변수 (기본 색상, 금속성, 광택, 방사율 등)를 나타내는 다양한 매개 변수가있는 일부 노드를 큰 노드에 연결해야합니다. . 필자의 원래 가정은 UE4에 다양한 유니폼이있는 일종의 하드 코딩 된 '마스터 셰이더'가 있으며, '재료'에서 사용자가하는 모든 것은 노드를 '마스터 셰이더'에 전달하는 것입니다. 마스터 노드 '.
그러나 UE4 문서 에는 다음이 명시되어 있습니다.
"각 노드에는 특정 작업을 수행하도록 지정된 HLSL 코드가 포함되어 있습니다. 이는 머티리얼을 구성 할 때 시각적 스크립팅을 통해 HLSL 코드를 생성한다는 의미입니다."
그것이 사실이라면, 이 시스템은 실제 셰이더 스크립트를 생성합니까? 이것이 정확히 어떻게 작동합니까?