퐁 쉐이딩 알고리즘에 문제가 있습니다. 법선이 꺼져있는 것처럼 보이고 항상 평평한 음영 처리 된 표면을 얻습니다.
지연 렌더링을 구현하고 있으므로, 지오메트리 패스에서 정점의 위치와 노멀을 텍스처에 저장합니다. 조명 패스에서 "값"을 확인하기 위해 법선을 색상으로 출력합니다.
편집 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
- 답변 # 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.
관련 자료
- What is the difference between |+ and | - kubernetes yaml 정의의 파일에서 구성 맵을 작성할 때 | +와 |-의 차이점은 무엇입니까?
- vb.net - O와 0 사이의 문자열 순열 만들기
- java - 두 ArrayList 객체 사이의 관계 만들기
- oracle - 값 사이의 보간을위한 SQL 쿼리
- 두 CSV 파일간에 비슷한 값을 가져오고 파이썬에서 원하는 출력으로 새 CSV 파일을 만드는 방법은 무엇입니까?
- java - LocalDateTime에서 DateTime을 만드는 두 가지 방법의 차이점은 무엇입니까?
- c++ : 이 정점 구성의 문제점
- c++ : GLSL 셰이더 유니폼 위치를 찾을 수 없습니다
- c++ : 제목 표시줄이 없는 glfw 창
- c++ : QT 작성자에 glfw를 포함하는 올바른 방법입니까?
- c++ : QT 예제 code의 QOpenGLWidget 링커 오류
- opengl : 프래그먼트 셰이더에서 루프를 실행할 때 EXC_BAD_ACCESS 오류
- opengl : 픽셀 스와핑 셰이더 최적화
- c++ : Emscripten이 셰이더를 컴파일하지 못함
- c++ : 삼각형을 그리는 간단한 프로그램에서 segfault의 알 수 없는 이유
- c++ : 프로그램이 컴파일되지만 존재하는 라이브러리가 없기 때문에 실행할 수 없습니다.
와이즈 비즈 와이즈 비즈 가져올 때 플래그를 지정합니다.
문서에서 :
와이즈 비즈따라서 평평한 법선으로 모델을 내 보낸 경우이 플래그는 아무 작업도 수행하지 않습니다. 따라서 두 가지 옵션이 있습니다 :
<올>올 바르고 부드러운 노마로 모델을 내 보냅니다. (이 옵션을 사용하면 법선을 완벽하게 제어 할 수있어 원하는 가장자리 등을 보존 할 수 있습니다. 필요한 경우 계산량이 적습니다.)
정규를 다시 계산하기 위해 강제합니다.