Изменить значения Phong Shader с помощью ползунков

Я пытаюсь реализовать 3D-сцену с помощью WebGL и Javascript. Предполагается, что в финальной сцене будет показан кубоид с меньшими кубоидами, пирамидами и сферами со всех сторон. Меньшие сферы должны вращаться с большим кубом. Я реализовал Phong Shading, все работает отлично. Теперь я хочу изменить значения shininess, lightPos, а также lightIntensity с тремя ползунками справа от моего холста, который отображает сцену. Слайдер для блеска, очевидно, не работает, и я еще больше борюсь с двумя другими слайдерами, так как lightPos а также lightIntensity являются vec3 элементы, которые являются постоянными. Код для трех переменных выглядит следующим образом:

const vec3 lightPos = vec3(1.0,-1.0,1.0);
float shininess = 16.0;
const vec3 lightIntensity = vec3(1.0, 1.0, 1.0);

На данный момент слайдер для блеска выглядит так:

<input id="shininess" type="range" min="1" max="50"></input>
var shininessElement = document.getElementById("shininess");
shininessElement.onchange = function(){
shininess = shininessElement.value;
window.requestAnimationFrame(animate);

Я почти уверен, что сделал что-то ужасно неправильное, но исследование не привело ни к какому результату, и я не знаю, что делать дальше, поэтому я очень признателен за вашу помощь. Если вам нужен полный код, пожалуйста, дайте мне знать.

1 ответ

Вы, вероятно, должны прочитать некоторые другие учебные пособия по WebGL. В частности, вы не можете установить блеск, если вы не сделаете это uniform, затем найдите местоположение униформы и установите его с gl.uniform???,

Вот простой пример использования ползунка для установки значения, а затем отправки этого значения в шейдер путем установки единой переменной в шейдере.

const gl = document.querySelector("canvas").getContext('webgl');

const vs = `
 void main() {
   gl_Position = vec4(0, 0, 0, 1);
   gl_PointSize = 100.0;
 }
`;

const fs = `
  precision mediump float;
  uniform float shininess;
  void main() {
    gl_FragColor = vec4(shininess, 0, 0, 1);
  }
`;

// compiles shaders, links program
const prg = twgl.createProgram(gl, [vs, fs]);
const shininessLocation = gl.getUniformLocation(prg, "shininess");

let shininess = .5;

draw();

function draw() {
  gl.useProgram(prg);
  gl.uniform1f(shininessLocation, shininess);
  gl.drawArrays(gl.POINTS, 0, 1);
}

document.querySelector("input").addEventListener('input', (e) => {
  shininess = e.target.value / 100;
  draw();
});
<script src="https://twgljs.org/dist/3.x/twgl.min.js"></script>
<canvas></canvas>
<input type="range" min="0" max="100" value="50" />

Другие вопросы по тегам