Я попытался реализовать нормальное отображение в моем приложении opengl, но я не могу заставить его работать.Нормальное сопоставление было ужасно неправильным
This - это диффузная карта (в которую я добавляю коричневый цвет), а this - это нормальная карта. (? В других местах, называемая бинормаль)
Для того, чтобы получить касательную и бикасательную векторы, я запускаю эту функцию для каждого треугольника в моей сетке:
void getTangent(const glm::vec3 &v0, const glm::vec3 &v1, const glm::vec3 &v2,
const glm::vec2 &uv0, const glm::vec2 &uv1, const glm::vec2 &uv2,
std::vector<glm::vec3> &vTangents, std::vector<glm::vec3> &vBiangents)
{
// Edges of the triangle : postion delta
glm::vec3 deltaPos1 = v1-v0;
glm::vec3 deltaPos2 = v2-v0;
// UV delta
glm::vec2 deltaUV1 = uv1-uv0;
glm::vec2 deltaUV2 = uv2-uv0;
float r = 1.0f/(deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x);
glm::vec3 tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y)*r;
glm::vec3 bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x)*r;
for(int i = 0; i < 3; i++) {
vTangents.push_back(tangent);
vBiangents.push_back(bitangent);
}
}
После этого, я называю glBufferData загрузить вершины , нормали, uvs, касательные и бинагентны к графическому процессору. вершинный шейдер:
#version 430
uniform mat4 ProjectionMatrix;
uniform mat4 CameraMatrix;
uniform mat4 ModelMatrix;
in vec3 vertex;
in vec3 normal;
in vec2 uv;
in vec3 tangent;
in vec3 bitangent;
out vec2 fsCoords;
out vec3 fsVertex;
out mat3 TBNMatrix;
void main()
{
gl_Position = ProjectionMatrix * CameraMatrix * ModelMatrix * vec4(vertex, 1.0);
fsCoords = uv;
fsVertex = vertex;
TBNMatrix = mat3(tangent, bitangent, normal);
}
Фрагмент шейдеры:
#version 430
uniform sampler2D diffuseMap;
uniform sampler2D normalMap;
uniform mat4 ModelMatrix;
uniform vec3 CameraPosition;
uniform struct Light {
float ambient;
vec3 position;
} light;
uniform float shininess;
in vec2 fsCoords;
in vec3 fsVertex;
in mat3 TBNMatrix;
out vec4 color;
void main()
{
//base color
const vec3 brownColor = vec3(153.0/255.0, 102.0/255.0, 51.0/255.0);
color = vec4(brownColor * (texture(diffuseMap, fsCoords).rgb + 0.25), 1.0);//add a fixed base color (0.25), because its dark as hell
//general vars
vec3 normal = texture(normalMap, fsCoords).rgb * 2.0 - 1.0;
vec3 surfacePos = vec3(ModelMatrix * vec4(fsVertex, 1.0));
vec3 surfaceToLight = normalize(TBNMatrix * (light.position - surfacePos)); //unit vector
vec3 eyePos = TBNMatrix * CameraPosition;
//diffuse
float diffuse = max(0.0, dot(normal, surfaceToLight));
//specular
float specular;
vec3 incidentVector = -surfaceToLight; //unit
vec3 reflectionVector = reflect(incidentVector, normal); //unit vector
vec3 surfaceToCamera = normalize(eyePos - surfacePos); //unit vector
float cosAngle = max(0.0, dot(surfaceToCamera, reflectionVector));
if(diffuse > 0.0)
specular = pow(cosAngle, shininess);
//add lighting to the fragment color (no attenuation for now)
color.rgb *= light.ambient;
color.rgb += diffuse + specular;
}
Изображение я совершенно неправильно. (свет, расположенный на камере)
Что я здесь делаю неправильно?
Моя ставка на установке цвета/смешивания в пиксельный шейдер ... 1. Вы устанавливаете цвет вывода более чем один раз (если я правильно помню, на некоторых водителей GFX, что делать большие проблемы). 2. Вы добавляете «цвет» и «интенсивность» вместо «интенсивности цвета», но я мог упускать из виду. 3. Сначала попробуйте только обычное/ударное затенение (игнорируйте окружающее, отражайте, зеркально ...), а затем, если он работает, добавьте остальные по одному ...всегда проверяйте журналы компиляции шейдеров – Spektre
Что касается 3, вы имеете в виду, что я должен использовать только диффузное освещение? Также как проверить журналы компиляции шейдеров? Мой компилятор не знаком с glsl, но только с C++. – Pilpel
Да, вы должны установить переменную цвета только один раз и для начала с чем-то вроде этого: 'color.rgb = browncolor.rgb * fabs (dot (surface_normal, light_direction));' также добавил ответ с моими шейдерами, которые делают что-то похожее чего вы хотите достичь. Если вы не проверяете журналы, вы можете легко пропустить некоторые вещи, такие как оптимизированные переменные ввода/вывода, синтаксические ошибки и т. Д. – Spektre