Измените значения 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);

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


person Phil    schedule 17.08.2017    source источник


Ответы (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" />

person gman    schedule 18.08.2017