THREE. JS Getting Started Tutorial (3) Shader-Bottom _ basics

Source: Internet
Author: User
translation Sequence
Three.js is a great open source WebGL Library, WebGL allows JavaScript to manipulate the GPU, realizing the true meaning of 3D at the browser end. But at present this technology is still in the development stage, the material is extremely scarce, the amateur learns basically to through the demo source code and three.js own source code to study.

. Introduction
This is the second half of the WebGL shader tutorial, and if you haven't read the previous article, reading this tutorial may confuse you and suggest you go through the previous tutorial.

At the end of the last article, we drew a nice pink sphere in the middle of the screen. Now I'm going to start creating something more interesting.

In this tutorial, we'll take a moment to add an animation loop, then a vertex attributes variable and a uniform variable. We also need to add some varying variables so that the vertex shader can pass information to the chip shader. The final result is which Pink sphere will "ignite" from the top to the sides, and then do the regular movement. This is a bit psychedelic, but it will help you get a better idea of the three variables in the shader: they connect to each other and implement the entire set. Of course we will do this in the framework of three.js.
1. Simulated illumination
Let's update the color so that the ball doesn't look like a flat, dull circle. If we want to see how three.js handles Light, I'm sure you'll find it much more complicated than we need, so let's simulate the lighting first. You should browse through the wonderful shaders in three.js, and some of the WEBGL projects from the closest Chris Milk and Google, Rome.
Back to the shader, we want to update the vertex shader to pass the vertex's normal vector to the slice shader. Using a varying variable:
Copy Code code as follows:

Creates a varying variable vnormal that both the vertex shader and the slice shader contain
Varying VEC3 vnormal;
void Main () {
Set Vnormal to normal, which is an attribute variable that Three.js creates and passes to the shader
Vnormal = normal;
Gl_position = ProjectionMatrix *
Modelviewmatrix *
VEC4 (position, 1.0);
}

In the slice shader, we'll create a variable with the same variable name, multiply the normal vector and another vector that represents the light from the top right, and use the result for the color. The effect of the final result is a bit like parallel light.
Copy Code code as follows:

The same variable as the vertex shader vnormal
Varying VEC3 vnormal;
void Main () {
Define Ray vectors
VEC3 light = VEC3 (0.5,0.2,1.0);
Ensure that it is normalized
Light = normalize (light);
Calculate the dot product of the ray vector and normal vector, if the dot product is less than 0 (that is, the light is not able to shine), set to 0
float Dprod = max (0.0, dot (vnormal, light));
Fill slice element color
Gl_fragcolor = VEC4 (Dprod,//R
Dprod,//G
Dprod,//B
1.0); A
}

The reason for using dot product is that the dot product of two vectors shows how "similar" they are. If two vectors are normalized and they are in the same direction, the value of the dot product is 1, and if the direction of the two vectors happens to be exactly the opposite, the value of the dot product is-1. All we do is put the value of the dot product on the fiber, so if the point is at the top right of the sphere, the dot product's value is 1, which is completely illuminated, and on the other side, the dot product value is nearly 0, or even 1. Any negative values that we will get are set to 0. When you pass the data in, you will see the most basic lighting effects.

What's down there? We'll get the coordinates of the vertices in.
2.Attribut Variable
Next I'm going to pass a random number to each vertex by the attribute variable, which is used to push the vertices along the normal vector for a distance. The new result is a bit like a weird irregular object that randomly changes every time the page is refreshed. Now he won't move (I'll make him move later), but a few refreshes can be a good observation that his shape is random.
Let's start by adding attribute variables to the vertex shader:
Copy Code code as follows:

attribute float displacement;
Varying VEC3 vnormal;
void Main () {
Vnormal = normal;
Converts a random number displacement to a three-dimensional vector so that it can be multiplied by the normal
VEC3 newposition = position +
Normal * VEC3 (displacement);
Gl_position = ProjectionMatrix *
Modelviewmatrix *
VEC4 (newposition, 1.0);
}

You see nothing changed, because the attribute variable displacement has not been set you, so the shader uses 0 as the default value. At this point the displacement has not worked, but we are about to add attribute variables to the coloring material, and then three.js will automatically tie them together to run.

Also note the fact that I assign the updated position to a new three-dimensional vector variable, because the original position variable position, like all attribute variables, is read-only.
3. Update Coloring Equipment Quality
Now we're going to update the coloring device and pass in something to the attribute object displacement. Remember, the attribute object is corresponding to vertex one by one, so we have a value for each vertex of the sphere, like this:
Copy Code code as follows:

var attributes = {
Displacement: {
Type: ' F ',//floating-point number
Value: []//Empty array
}
};
var Vshader = $ (' #vertexshader ');
var Fshader = $ (' #fragmentshader ');
Create a color device quality containing attribute attributes
var shadermaterial =
New THREE. Meshshadermaterial ({
Attributes:attributes,
VertexShader:vShader.text (),
FragmentShader:fShader.text ()
});
To fill a random number in a displacement
var verts = sphere.geometry.vertices;
var values = Attributes.displacement.value;
for (var v = 0; v < verts.length; v++) {
Values.push (Math.random () * 30);
}

In this way, you can see a deformed sphere. The cool thing is: all of these variants are done on the GPU.
4. Move Up
What should we do to make this thing move? Well, you should do these two things.
A uniform variable amplitude how much displacement is actually caused by controlling displacement in each frame. We can use the sine or cosine function to generate it in each frame because the values range from 1 to 1 of these functions.
A frame loop.

We need to add this uniform variable to the shader and add it to the vertex shader. First look at the vertex shader:
Copy Code code as follows:

Uniform float amplitude;
attribute float displacement;
Varying VEC3 vnormal;
void Main () {
Vnormal = normal;
Multiply the displacement by amplitude, and when we change the amplitude in every frame, the screen moves.
VEC3 newposition =
Position +
Normal *
VEC3 (Displacement *
amplitude);
Gl_position = ProjectionMatrix *
Modelviewmatrix *
VEC4 (newposition, 1.0);
}

Then update the coloring device quality:
Copy Code code as follows:

var uniforms = {
Amplitude: {
Type: ' F ',//a float
value:0
}
};
var Vshader = $ (' #vertexshader ');
var Fshader = $ (' #fragmentshader ');
Create Final coloring device quality
var shadermaterial =
New THREE. Meshshadermaterial ({
Uniforms:uniforms,
Attributes:attributes,
VertexShader:vShader.text (),
FragmentShader:fShader.text ()
});

Our shader is also ready. But we seem to have a step backwards, and there is only a smooth ball left on the screen. Don't worry, this is because the amplitude value is set to 0 because we multiply the amplitude by the displacement, so we don't see any changes now. We haven't set the loop yet, so amplitude can only be 0.

In our JavaScript, we need to package the rendering process into a function, and then call the function with Requestanimationframe. In this function, we update the value of the uniform (Translator Note: amplitude).
Copy Code code as follows:

var frame = 0;
function Update () {
Amplitude from the sinusoidal value of the frame
Uniforms.amplitude.value =
Math.sin (frame);
Update global variable Frame
Frame + 0.1;
Renderer.render (scene, camera);
Specifies that the next time the screen is refreshed, call Update
Requestanimframe (update);
}
Requestanimframe (update);

5. Summary
That's it! You see that the sphere is pulsing strangely. There's too much to tell about shaders, but I hope this tutorial will help you a little. Now, when you see some other shaders, I want you to understand them, and you should have the confidence to create your own shader!

As usual, I packed the source code for this lesson.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.