Отсроченный рендеринг и перемещение точки света - PullRequest
4 голосов
/ 28 августа 2011

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

Я рендеринг цветов, нормалей и глубины в пространстве видав текстуры.Во второй я связываю текстуры с полноэкранным квадратором и рассчитываю освещение.Направленный свет, кажется, работает нормально, но точечные источники света движутся вместе с камерой.

У меня есть соответствующий код шейдера:

Шаговый вершинный шейдер освещения

in vec2 inVertex;
in vec2 inTexCoord;
out vec2 texCoord;
void main() {
    gl_Position = vec4(inVertex, 0, 1.0);
    texCoord = inTexCoord;
}

Фрагмент шейдерного фрагмента освещения

float depth = texture2D(depthBuffer, texCoord).r;
vec3 normal = texture2D(normalBuffer, texCoord).rgb;
vec3 color = texture2D(colorBuffer, texCoord).rgb;

vec3 position;
position.z = -nearPlane / (farPlane - (depth * (farPlane - nearPlane))) * farPlane;
position.x = ((gl_FragCoord.x / width) * 2.0) - 1.0;
position.y = (((gl_FragCoord.y / height) * 2.0) - 1.0) * (height / width);
position.x *= -position.z;
position.y *= -position.z;

normal = normalize(normal);
vec3 lightVector = lightPosition.xyz - position;
float dist = length(lightVector);
lightVector = normalize(lightVector);

float nDotL = max(dot(normal, lightVector), 0.0);
vec3 halfVector = normalize(lightVector - position);
float nDotHV = max(dot(normal, halfVector), 0.0);

vec3 lightColor = lightAmbient;
vec3 diffuse =  lightDiffuse * nDotL;
vec3 specular = lightSpecular * pow(nDotHV, 1.0) * nDotL;
lightColor += diffuse + specular;
float attenuation = clamp(1.0 / (lightAttenuation.x + lightAttenuation.y * dist + lightAttenuation.z * dist * dist), 0.0, 1.0);

gl_FragColor =  vec4(vec3(color * lightColor * attenuation), 1.0);

Я посылаю световые атрибуты шейдерам в форме:

shader->set("lightPosition", (viewMatrix * modelMatrix).inverse().transpose() * vec4(0, 10, 0, 1.0));

viewmatrix - это матрица камеры, а modelmatrix здесь просто идентичность.

Почему точечные источники света переводятся вместе с камеройне с моделями?

Любые предложения приветствуются!

1 Ответ

3 голосов
/ 28 августа 2011

В дополнение к комментарию Никого о том, что все векторы, которые вы вычисляете, должны быть нормализованы, вы должны убедиться, что они все находятся в одном и том же пространстве. Если вы используете положение пространства вида в качестве вектора вида, вектор нормалей тоже должен быть в пространстве вида (должен быть преобразован с помощью матрицы обратного транспонирования модели, прежде чем записываться в G-буфер в первом проходе). И световой вектор тоже должен быть в пространстве зрения. Поэтому вам необходимо преобразовать положение источника света с помощью матрицы вида (или матрицы вида модели, если положение источника света не в мировом пространстве) вместо ее обратной транспонирования.

shader->set("lightPosition", viewMatrix * modelMatrix * vec4(0, 10, 0, 1.0));

РЕДАКТИРОВАТЬ: Для направленного света обратная транспонирование на самом деле хорошая идея, если вы указываете направление света в качестве направления на свет (например, vec4(0, 1, 0, 0) для света, указывающего в направлении -z) .

...