使用滑块更改 Phong 着色器的值

Posted

技术标签:

【中文标题】使用滑块更改 Phong 着色器的值【英文标题】:Change values of Phong Shader with sliders 【发布时间】:2017-08-17 16:36:47 【问题描述】:

我正在尝试使用 WebGL 和 javascript 实现 3D 场景。最后一个场景应该显示一个长方体,四面都是较小的长方体、金字塔和球体。较小的球体必须与大长方体一起旋转。我实现了 Phong Shading,效果很好。现在我想用显示场景的画布右侧的三个滑块更改shininesslightPoslightIntensity 的值。闪亮的滑块显然不起作用,我更加挣扎于其他两个滑块,因为lightPoslightIntensityvec3 常量元素。三个变量的代码如下所示:

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】:

您可能应该read some other tutorials on 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" />

【讨论】:

以上是关于使用滑块更改 Phong 着色器的值的主要内容,如果未能解决你的问题,请参考以下文章

在我的着色器中实现 phong 着色(过度纹理)的错误

顶点着色器中的 Phong 光照

Phong 和 Gouraud 着色 WebGL

为啥 glDrawElments() 在不使用任何着色器的情况下工作?

带有 Blinn-Phong GLSL 着色器、点光源的奇怪结果

片段着色器是不是处理来自顶点着色器的所有像素?