WebGL: WebGL: Vertex ShaderCopy the code
Last time, we started with the sine of theta over one period, and then we drew the sine of theta over two periods. However, we changed the Vertex Shader code directly. It would be nice if we had a slider on the page that we could use to drag the changes and reflect them on the graph.
Based on the above requirements, we first added a slider Input control to the page, and the whole code changes are as follows:
<! doctype html> <html> <head> <style> canvas { border: 1px solid #000000; </style> </head> <body> <input ID ="slider" type="range" min="0" Max ="100" value="50" step="1" οnchange=" sliderFunc ()" /> <canvas id="point" style="width:300px; height:300px"> </canvas> <script id="vertex_shader" type="myshader"> // Vertex Shader precision mediump int; precision mediump float; attribute vec2 a_PointVertex; Void main() {gl_Position = vec4(a_PointVertex, 0.0, 1.0); Y = sin(gl_position. x * 3.14); Gl_PointSize = 3.0; } </script> <script id="fragment_shader" type="myshader"> // Fragment shader precision mediump int; precision mediump float; Void main() {gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); } </script> <script type="text/javascript"> var pointCanvas = document.getElementById('point'); Var gl = pointCanvas. GetContext ('webgl', {preserveDrawingBuffer: true}); Var pointCount = 0; var pointData = []; for (var idx = -500; idx <= 500; idx++) { pointCount++; pointData.push(idx / 500); pointData.push(0); } // var pointArray = new Float32Array(pointData); var buffer_id; buffer_id = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, buffer_id); gl.bufferData(gl.ARRAY_BUFFER, pointArray, gl.STATIC_DRAW); // var vertex_shader_code = document.getElementById('vertex_shader').textContent; console.log(vertex_shader_code); var vertex_shader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertex_shader, vertex_shader_code); gl.compileShader(vertex_shader); // var fragment_shader_code = document.getElementById('fragment_shader').textContent; var fragment_shader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragment_shader, fragment_shader_code); gl.compileShader(fragment_shader); // var program = gl.createProgram(); gl.attachShader(program, vertex_shader); gl.attachShader(program, fragment_shader); gl.linkProgram(program); gl.useProgram(program); // var a_PointVertex = gl.getAttribLocation(program, 'a_PointVertex'); gl.vertexAttribPointer(a_PointVertex, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(a_PointVertex); // // gl.drawArrays(gl.POINTS, 0, pointCount); </script> <script> var sliderDom = document.getElementById("slider"); function sliderfunc() { } sliderDom.addEventListener("change", sliderfunc); </script> </script> </body> </html>Copy the code
We added a slider Input control in the first place, and at the end we bound the control to an event. When the value of the control changes, we can do something in the sliderFunc function.
var sliderDom = document.getElementById("slider"); Function sliderfunc () {/ / should be here to change the drawings of} sliderDom. AddEventListener (" change ", sliderfunc);Copy the code
Key new concept: uniform variables
uniform
The variables can be written invertex shader
和fragment shader
The variables in the- You can go through at any time
gl
theapi
Change,uniform
The value of the variable
We changed our Vertex shader as follows:
<script id="vertex_shader" type="myshader"> // Vertex Shader precision mediump int; precision mediump float; uniform float u_x_offset; attribute vec2 a_PointVertex; Void main() {gl_Position = vec4(a_PointVertex, 0.0, 1.0); Y = sin(gl_position. x * 3.14 * u_x_offset); Gl_PointSize = 3.0; } </script>Copy the code
- Notice that one is declared
float
The type ofuniform
variableu_x_offset
; - Notice that the parameter that we pass in to sine theta, theta, becomes theta
X * 3.14 * u_x_offset
- In other words, we can take
u_x_offset
As a regulator.
That’s not enough. We need to write some code in SliderFunc to change the u_X_offset variable in the Vertex Shader from the outside.
The final code changes are as follows:
<script>
var u_x_offset_loc = gl.getUniformLocation(program, "u_x_offset");
var sliderDom = document.getElementById("slider");
function sliderfunc() {
gl.uniform1f(u_x_offset_loc, parseFloat(sliderDom.value) / 10);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, pointCount);
}
sliderDom.addEventListener("change", sliderfunc);
</script>
Copy the code
A:
- Gl. getUniformLocation: used to obtain
vertex shader
The location of the uniform variable in - Gl. Uniform1f change
vertex shader
The uniform variable value in - Gl.clear (gl.color_buffer_bit) Clears the entire image, otherwise it will be drawn repeatedly and become more and more messy
- Gl.drawarrays (gl.points, 0, pointCount) are redrawn
The effect is as follows:
As we drag the slider, sin images of different periods will be drawn on the page.
At the end of the text, questions are answeredCopy the code
Duck duck said: since you can change the value of the uniform variable in THE JS code, so I make a timer, is it animation?
- A: Exactly ✔️!!!!! Class is over ~