Цвет только лицо красным, что перед камерой? - PullRequest
1 голос
/ 07 февраля 2020

Я довольно новичок ie для GLSL, и я изо всех сил пытался найти способ покрасить лицо моего вращающегося кубика в красный. Я добился рисования красного цвета на одной из граней, получая нормальное значение x, но моя цель - заставить куб нарисовать красное лицо к тому лицу, которое стоит перед камерой.

Фрагмент шейдера

#version 330

in vec3 normal;
out vec4 fragColor;
in vec4 color;

in vec4 vertexColor;

void main() { 

    vec3 nor = normalize(normal);
    fragColor = vec4(nor.x, 0.0, 0.0, 1.0);


 }

Vertex Shader

#version 330

uniform mat4 u_m_matrix;
uniform mat4 u_vp_matrix;

layout (location=0) in vec3 a_position;
layout (location=1) in vec3 a_normal;

out vec3 normal;
out vec4 fragColor;

out vec4 vertexColor;
out vec4 color;

void main()
{

  normal = a_normal;
    gl_Position = u_vp_matrix * u_m_matrix * vec4(a_position, 1.0);

}


Я пытался связать точечное произведение с нормалями и направлением, в котором смотрит камера (0, 0, 1 ) но я еще ничего не достиг.

Это был бы желаемый эффект:

Я действительно думаю, что это включает в себя немного математики (скалярное произведение), может быть, получить cosTetha и посмотреть, является ли вектор полностью перпендикулярным или нет, и в зависимости от того, что рисует грани, красные или черные? *

1 Ответ

1 голос
/ 07 февраля 2020

Я смотрю пространство, ось z указывает на порт просмотра. Когда сторона куба обращена к камере, вектор нормали в пространстве вида равен (0, 0, 1). Красный цвет может быть получен из z-компонента вектора нормалей.

Но вектор нормалей должен быть преобразован из пространства модели в пространство просмотра (в вершинном шейдере). Для этого вам нужно знать матрицу вида:

mat3 normalMat = inverse(transpose(mat3(u_v_matrix * u_m_matrix)));
normal = normalMat * a_normal;

В фрагментном шейдере канал красного цвета можно получить из компонента z:

vec3 nor = normalize(normal);
fragColor = vec4(nor.z, 0.0, 0.0, 1.0);

Вы можете аппроксимируйте нормальный вектор в нормализованном пространстве устройства, преобразовав mat3(u_vp_matrix * u_m_matrix). Это неточно, но оно также окрашивает грани в зависимости от его ориентации. В нормализованном пространстве устройства ось z указывает на область просмотра. Например:

Вершинный шейдер:

#version 330

uniform mat4 u_m_matrix;
uniform mat4 u_vp_matrix;

layout (location=0) in vec3 a_position;
layout (location=1) in vec3 a_normal;

out vec3 normal;

void main()
{
    normal = mat3(u_vp_matrix * u_m_matrix) * a_normal;
    gl_Position = u_vp_matrix * u_m_matrix * vec4(a_position, 1.0);
}

Фрагментный шейдер:

#version 330

in vec3 normal;
out vec4 fragColor;

void main() { 

    vec3 nor = normalize(normal);
    fragColor = vec4(-nor.z, 0.0, 0.0, 1.0);
}


Если вы просто хотите закрасить грань, которая обращена к камере, то вы должны сравнить косинус угла между вектором нормали к лицу и осью пространства z по косинусу 45 °. step сравнивает значение с ребром и возвращает 0.0 или 1.0, в зависимости от результата:

Вершинный шейдер:

mat3 normalMat = inverse(transpose(mat3(u_v_matrix * u_m_matrix)));
normal = normalMat * a_normal;

Фрагментный шейдер:

vec3 nor = normalize(normal);

//float red = step(0.707, abs(dot(nor, vec3(0.0, 0.0, 1.0))));
float red = step(0.707, dot(nor, vec3(0.0, 0.0, 1.0)));

fragColor = vec4(red, 0.0, 0.0, 1.0);

...