>

퐁 쉐이딩 알고리즘에 문제가 있습니다. 법선이 꺼져있는 것처럼 보이고 항상 평평한 음영 처리 된 표면을 얻습니다.

지연 렌더링을 구현하고 있으므로, 지오메트리 패스에서 정점의 위치와 노멀을 텍스처에 저장합니다. 조명 패스에서 "값"을 확인하기 위해 법선을 색상으로 출력합니다.
편집 1내 Gbuffer는 위치와 법선을 저장하기 위해 두 가지 텍스처를 사용합니다. 두 텍스처 모두 GL_RGB16F 형식을 사용합니다.

EDIT 5이 이미지에서 볼 수 있듯이 우아한 색상 전환이 이루어지지 않습니다. 왼쪽의 머리는 내 엔진의 결과이며 오른쪽의 경우 Blender에서 동일한 모델을 볼 수 있습니다. 블렌더에서 법선 (파란색)은 올바른 것처럼 보이지만 (중복 없음 등) 엔진에서는면 법선처럼 작동합니다 (4는 같은 방향으로 표시됨). Assimp를 사용하여 모델을로드하고 aiProcess_GenSmoothNormals 를 포함시킵니다.  가져올 때 플래그를 지정합니다.

지오메트리 패스 버텍스 쉐이더 :

#version 440 core
layout (location = 0) in vec4 positionOS;
layout (location = 1) in vec3 normalOS;
layout (location = 2) in vec2 uv;
out VertexData
{
    vec3 PositionVS;
    vec3 NormalVS;
    vec2 UV;
} vs_out;
uniform mat3 normalViewMatrix;
uniform mat4 modelViewMatrix;
struct Camera
{
    mat4 viewMatrix;
    mat4 projMatrix;
};
layout(std140, binding = 0) uniform CameraBlock
{
    Camera cam;
};
void main()
{
    vec4 positionVS = modelViewMatrix * positionOS;
    vs_out.PositionVS = positionVS.xyz;
    vs_out.NormalVS = normalViewMatrix * normalOS;
    vs_out.UV = uv;
    gl_Position = cam.projMatrix * positionVS;
}

지오메트리 패스 프래그먼트 셰이더 :

#version 440 core
layout (location = 0) out vec3 PositionVS;
layout (location = 1) out vec3 NormalVS;
in VertexData
{
    vec3 PositionVS;
    vec3 NormalVS;
    vec2 UV;
} vs_in;
void main()
{
    PositionVS = vs_in.PositionVS;
    NormalVS = normalize(vs_in.NormalVS);
}

편집 4Assimp (aiMesh)에서 정점 값 읽기

void MeshLoader::prepareMesh(const aiMesh & mesh)
{
    { // vertices
        for (int i = 0; i < mesh.mNumVertices; i++) {
            if (mesh.HasPositions()) {
                glm::vec3 position = glm::vec3(mesh.mVertices[i].x, mesh.mVertices[i].y, mesh.mVertices[i].z);
                positions.emplace_back(position.x, position.y, position.z, 1);
            }
            if (mesh.HasNormals()) {
                normals.emplace_back(mesh.mNormals[i].x, mesh.mNormals[i].y, mesh.mNormals[i].z);
            }
            if (mesh.HasTangentsAndBitangents()) {
                tangents.emplace_back(mesh.mTangents[i].x, mesh.mTangents[i].y, mesh.mTangents[i].z);
                bitangents.emplace_back(mesh.mBitangents[i].x, mesh.mBitangents[i].y, mesh.mBitangents[i].z);
            }
            if (mesh.HasTextureCoords(0)) {
                uvs.emplace_back(mesh.mTextureCoords[0][i].x, mesh.mTextureCoords[0][i].y);
            }
        }
    }
    { // polygons
        numFaces = mesh.mNumFaces;
        for (int i = 0; i < numFaces; i++) {
            indices.push_back(mesh.mFaces[i].mIndices[0]);
            indices.push_back(mesh.mFaces[i].mIndices[1]);
            indices.push_back(mesh.mFaces[i].mIndices[2]);
        }
    }
}

이 혼란에 대한 해결책을 찾고 싶습니다. 법선이 문제라는 것을 알고 있지만 그 이유를 알 수 없습니다.
편집 2구 모양으로 보간 문제처럼 보이므로 위의 셰이더 코드입니다. 셰이더가 올 바르면 수입 클래스가이 문제를 일으키는 것일 수 있습니까?
EDIT 3또한 포워드 렌더링 버전을 구현하고 법선을 색상으로 표시했지만 지연된 버전과 동일한 결과를 얻습니다.


  • 답변 # 1

    와이즈 비즈 와이즈 비즈  가져올 때 플래그를 지정합니다.

    문서에서 :

    와이즈 비즈

    따라서 평평한 법선으로 모델을 내 보낸 경우이 플래그는 아무 작업도 수행하지 않습니다. 따라서 두 가지 옵션이 있습니다 :

    <올>

    올 바르고 부드러운 노마로 모델을 내 보냅니다. (이 옵션을 사용하면 법선을 완벽하게 제어 할 수있어 원하는 가장자리 등을 보존 할 수 있습니다. 필요한 경우 계산량이 적습니다.)

    정규를 다시 계산하기 위해 강제합니다.

    I am using Assimp to load the models and I include the 를보십시오  깃발: 와이즈 비즈

  • 답변 # 2

    지연된 렌더링을 다루기 때문에 화면 공간 노멀 텍스처가 실제로 노멀 값을 올바르게 저장하는지 확인하는 것이 좋습니다. 우선, 일반 텍스처에 얼마나 많은 공간을 할당합니까? GL_RGBA16 텍스처가 작업을 수행해야합니다.

    두 번째로주의해야 할 점은 텍스처 버퍼에 부호가 없으므로 glsl에서 음수 값이 텍스처 버퍼에 기록 될 때 잘려진다는 것입니다. 컬러 데이터를 벡터 데이터로 변환하기 위해 어떤 종류의 변환기 방법을 사용하고 그 반대도 마찬가지입니다. 방법

    aiProcess_GenSmoothNormals
    
    

    그냥 잘 작동해야합니다. 이 두 가지 중 하나를 아직 수행하지 않은 경우 시도해보십시오. :)

    작동하지 않으면 프래그먼트 버퍼와 프래그먼트 버퍼 사이에서 일반 데이터를 쓰고 읽는 방식에 도움이 될 것입니다. :)

    This is ignored if normals are already thereat the time this flag is evaluated. Model importers try to load them from the source file, so they're usually already there.

  • 이전 Arduino - 아두 이노 - 버튼을 눌렀을 때 타이머를 시작하려면
  • 다음 ionic3 - Ionic 3의 부트 스트랩 앵커 HREF