Как заштриховать Гуро при рассеянном освещении в WebGl? - PullRequest
1 голос
/ 11 апреля 2019

Я придерживался реализации плавного затенения Гуро.Мне чего-то не хватает, и мне нужна помощь.

Сначала о диффузном освещении.Чтобы получить рассеянный свет, я использую эту формулу:

Id * Kd * max (точка (N, L), 0,0)

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

Следующая заливка.Затенение Гуро - это затенение на вершину.Я нашел алгоритм затенения Гуро в этих лекциях

Как я понял этот алгоритм:

  1. Определение нормали в каждой вершине многоугольника
vec3 N = mat3(normalMatrix) * normals;
Применение модели освещения к каждой вершине для расчета интенсивности вершины
float labertian = max(dot(N, L), 0.0);
vec4 color = vec4(intensityAmbientColor * ambientColor
                 + intensityDiffuseColor * diffuseColor * labertian, 1.0);
Линейная интерполяция интенсивностей вершин по поверхности многоугольника
v_color = color;

Это выходное изображение

output image

Чего мне здесь не хватает?вершинный шейдер:

attribute vec3 coordinates;
attribute vec3 normals;

/** MVP */
uniform mat4 modelMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 normalMatrix;
// uniform mat4 viewModelMatrixl

/** LIGHT */
uniform vec3 ambientColor;
uniform float intensityAmbientColor;

uniform vec3 diffuseColor;
uniform float intensityDiffuseColor;

uniform vec3 cameraCoordinates;
uniform vec3 lightCoordinates;

varying vec4 v_color;

void main() {

  gl_Position = projectionMatrix *
    viewMatrix *
    modelMatrix *
    vec4(coordinates, 1.0);

  vec3 surfaceWorldPosition = (
    viewMatrix
    * modelMatrix
    * vec4(coordinates, 1.0)
  ).xyz;

  vec3 L = lightCoordinates - surfaceWorldPosition;
  vec3 V = cameraCoordinates - surfaceWorldPosition;
  vec3 N = mat3(normalMatrix) * normals;

  float labertian = max(dot(N, L), 0.0);
  v_color = vec4(intensityAmbientColor * ambientColor
                 + intensityDiffuseColor * diffuseColor * labertian, 1.0);
}

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

precision mediump float;

varying vec4 v_color;

void main() {
  gl_FragColor = v_color;
}

1 Ответ

1 голос
/ 11 апреля 2019

Затенение по методу Гуро представляет собой не что иное, как усреднение ваших нормалей вершин, обычно это часть импортеров / экспортеров / конвертеров сетки, вы можете сделать это вручную, однако, если ваша сетка не проиндексирована, вам нужно сначала переиндексировать ее, чтобы найти общие вершины, затем усредните нормали по ним. Прямо сейчас вы, кажется, визуализируете неиндексированный меш, в котором каждая вершина уникальна по отношению к one face.

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

https://en.wikipedia.org/wiki/Gouraud_shading

...