WebGL: добавление зеркального света без помощи THREE.JS - PullRequest
0 голосов
/ 28 декабря 2018

Я делаю первые шаги в программировании webgl.Создана простая установка, следующая этого урока .Удалось добавить несколько своих вещей, хотя и наткнулся на добавление света, особенно - зеркальный свет.Как я полагаю, большая часть этого будет реализована в моем фрагментном шейдере и, возможно, некоторые дополнения в вершинном шейдере и модуле Light.Вот код, который я приведу ниже.

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

attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
varying vec3 vNormal;
varying vec2 vUv;

void main() {
    vUv = uv;
    vNormal = (model * vec4(normal, 0.)).xyz;
    gl_Position = projection * view * model * vec4(position, 1.);
}

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

#ifdef GL_ES
precision highp float;
#endif

uniform vec3 lightDirection;
uniform float ambientLight;
uniform sampler2D diffuse;
varying vec3 vNormal;
varying vec2 vUv;

void main() {
    float lightness = -clamp(dot(normalize(vNormal), normalize(lightDirection)), -1., 0.);
    lightness = ambientLight + (1. - ambientLight) * lightness;
    gl_FragColor = vec4(texture2D(diffuse, vUv).rgb * lightness, 1.);
}

Модуль Light.js:

function Light () {
  this.lightDirection = new Vector3(-1, -1, -1)
  this.ambientLight = 0.3
}

Light.prototype.use = function (shaderProgram) {
  var dir = this.lightDirection
  var gl = shaderProgram.gl
  gl.uniform3f(shaderProgram.lightDirection, dir.x, dir.y, dir.z)
  gl.uniform1f(shaderProgram.ambientLight, this.ambientLight)
}

Буду очень признателен за ваши предложения здесь.Заранее спасибо!

1 Ответ

0 голосов
/ 28 декабря 2018

Наиболее распространенными и простыми моделями освещения являются модель отражения Фонга или модель Блинна – Фонга * модель 1004 *.

Следующий код шейдера основан на вашеморигинальный код и реализует модель Блинна – Фонга .По сравнению с вашим кодом, световые вычисления выполняются в пространстве вида, потому что зеркальное выделение зависит от положения вида, которое (0, 0, 0) в пространстве вида.Таким образом, направление света должно быть преобразовано для просмотра пространства.

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

attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

uniform vec3 lightDirection;

varying vec3 vPos;
varying vec3 vNormal;
varying vec2 vUv;
varying vec3 lightDirectionView;

void main() 
{
    lightDirectionView = (view * vec4(lightDirection, 0.)).xyz;

    mat4 modelView = view * model;
    vec4 viewPos   = modelView * vec4(position, 1.0)
    vPos           = viewPos.xyz;
    vUv            = uv;
    vNormal        = (modelView * vec4(normal, 0.)).xyz;
    gl_Position    = projection * viewPos;
}

Шейдер Fragemnt :

#ifdef GL_ES
precision highp float;
#endif

uniform float     shininess;
uniform float     ambientLight;
uniform sampler2D diffuse;

varying vec3 vPos;
varying vec3 vNormal;
varying vec2 vUv;
varying vec3 lightDirectionView;

void main()
{
    vec3  color     = texture2D(diffuse, vUv).rgb;

    vec3  N         = normalize( vNormal );
    vec3  L         = normalize( -lightDirectionView );
    vec3  V         = normalize( -vPos );
    vec3  H         = normalize( V + L );

    float NdotL     = dot(N, L);
    float NdotH     = dot(N, H);

    float kDiffuse  = max(0.0, NdotL);
    // float kSpecular = (shininess + 2.0) * pow(max(0.0, NdotH), shininess) / (2.0 * 3.14159265);
    float kSpecular = pow(max(0.0, NdotH), shininess);

    vec3 light_col  = color * (kDiffuse + kSpecular);
    gl_FragColor    = vec4(light_col, 1.0);
}

Значение униформы shininess должно быть положительным значением в диапазоне [1, 100].

См. Также Фонг и Gouraud Shading WebGL .

...