THREE. JS getting started tutorial (3) shadow-bottom _ basics-js tutorial

Source: Internet
Author: User
Three. javaScript is a great open-source WebGL library. WebGL allows JavaScript to operate on GPUs, this article describes how to implement true 3D on the browser side. This article will introduce how to simulate the light Attribut variable update the color palette material and so on. Translation
Three. js is a great open-source WebGL library. WebGL allows JavaScript to operate on GPUs and implement 3D in the browser. However, this technology is still in its development stage, and there is a shortage of materials. Fans should learn it through the Demo source code and the source code of Three. js.

. Overview
This is the second half of the WebGL shader tutorial. If you haven't read the previous one, reading this tutorial may confuse you. We recommend that you read the previous tutorial.

At the end of the previous article, we drew a nice pink sphere in the center of the screen. Now I want to create something more interesting.

In this tutorial, we will spend some time adding an animation loop, then the vertex attributes variable and an uniform variable. We also need to add some varying variables so that the vertex coloring tool can pass information to the Cell Coloring tool. The final result is the pink sphere that starts from the top to "ignment" on both sides and then performs regular motion. This is a bit of a phantom, but it will help you better understand the three variables in the shader: they interact with each other and implement the entire collection. Of course we will do this in the Three. js framework.
1. Simulate illumination
Let's update the color so that the sphere won't look like a flat, dark circle. If we want to see how Three. js handles the light, I am sure you will find it much more complicated than we need, so let's simulate the light first. You should take a look at Three. js's amazing pasters and some recent WebGL projects from Chris Milk and Google and Rome.
Back to the coloring tool, We need to update the vertex coloring tool to pass the vertex's normal vector to the chip coloring tool. Use a varying variable:

The Code is as follows:


// Create a varying variable vNormal, which is included in both the vertex coloring tool and the object meta coloring tool.
Varying vec3 vNormal;
Void main (){
// Set vNormal to normal. The latter is the attribute variable created by Three. js and passed to the shader.
VNormal = normal;
Gl_Position = projectionMatrix *
ModelViewMatrix *
Vec4 (position, 1.0 );
}


In the Cell Coloring tool, we will create a variable with the same variable name, then multiply the normal vector with another vector that represents the light from the top right, and apply the result to the color. The final result is a bit like parallel light.

The Code is as follows:


// VNormal, the same variable as that in the vertex coloring Machine
Varying vec3 vNormal;
Void main (){
// Define the Ray Vector
Vec3 light = vec3 (0.5, 0.2, 1.0 );
// Ensure its normalization
Light = normalize (light );
// Calculate the dot product of the Light vector and the normal vector. If the dot product is smaller than 0 (that is, the light cannot be illuminated), it is set to 0.
Float dProd = max (0.0, dot (vNormal, light ));
// Fill part element color
Gl_FragColor = vec4 (dProd, // R
DProd, // G
DProd, // B
(1.0); //
}


The reason for using dot product is that the dot product of two vectors shows how "similar" they are ". If both vectors are normalized and their directions are the same, the point product value is 1. If the directions of the two vectors are exactly the opposite, the point product value is-1. What we do is to apply the dot product value to the optical fiber. Therefore, if this point is located in the upper right corner of the sphere, the dot product value is 1, which is completely illuminated; on the other side, the point product value obtained is close to 0, or even to-1. We set any negative value to 0. After you pass in the data, you will see the most basic illumination effect.

What is the following? We will merge the coordinates of the vertex.
2. Attribut variable
Next, I will pass a random number for each vertex through the Attribute variable. This random number is used to push the vertex along the normal vector for a certain distance. The new result is a bit like a weird irregular object. Every time you refresh the page, the object changes randomly. Now, he still does not move (I will let him move later), but several refreshes can be well observed, his shape is random.
Let's start adding the attribute variable to the vertex shader:

The Code is as follows:


Attribute float displacement;
Varying vec3 vNormal;
Void main (){
VNormal = normal;
// Convert the random number displacement to a three-dimensional Vector so that the random number can be multiplied by the normal number.
Vec3 newPosition = position +
Normal * vec3 (displacement );
Gl_Position = projectionMatrix *
ModelViewMatrix *
Vec4 (newPosition, 1.0 );
}


Everything you see remains unchanged, because the attribute variable displacement has not been set for you, so the coloring tool uses 0 as the default value. At this time, displacement does not work yet, but we are about to add the attribute variable to the coloring material, and Three. js will automatically bind them together for running.

At the same time, pay attention to the fact that I have assigned the updated position to a New Three-dimensional vector variable, because the original position variable is like all attribute variables, all are read-only.
3. Update the shadow material.
Now let's update the color palette material and input something to the attribute object displacement. Remember, attribute objects correspond to vertices one by one, so we have a value for each vertex of the sphere, like this:

The Code is as follows:


Var attributes = {
Displacement :{
Type: 'F', // floating point number
Value: [] // empty array
}
};
Var vShader = $ ('# vertexshader ');
Var fShader = $ ('# fragmentshader ');
// Create a shadow material containing the attribute
Var shaderMaterial =
New THREE. MeshShaderMaterial ({
Attributes: attributes,
VertexShader: vShader. text (),
FragmentShader: fShader. text ()
});
// Fill in the displacement with a random number
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 most Cool is that all these variants are completed in the GPU.
4. Get started
What should I do to make this thing dynamic? Well, we should do these two things.
An uniform variable amplement controls the actual displacement caused by displacement at each frame. We can use the sine or cosine function to generate it in each frame, because the values of these two functions range from-1 to 1.
A frame loop.

We need to add this uniform variable to the shader material and also to the vertex shader. Let's first look at the vertex shader:

The Code is as follows:


Uniform float amplitude;
Attribute float displacement;
Varying vec3 vNormal;
Void main (){
VNormal = normal;
// Multiply displacement by amplicate. When we smoothly change amplicate in each frame, the screen starts to work.
Vec3 newPosition =
Position +
Normal *
Vec3 (displacement *
Amplitude );
Gl_Position = projectionMatrix *
ModelViewMatrix *
Vec4 (newPosition, 1.0 );
}


Then update the shadow material:

The Code is as follows:


Var uniforms = {
Amplitude :{
Type: 'F', // a float
Value: 0
}
};
Var vShader = $ ('# vertexshader ');
Var fShader = $ ('# fragmentshader ');
// Create the final shadow Material
Var shaderMaterial =
New THREE. MeshShaderMaterial ({
Uniforms: uniforms,
Attributes: attributes,
VertexShader: vShader. text (),
FragmentShader: fShader. text ()
});


Our coloring tool is ready. But we seem to have gone backwards, and there is only a smooth ball on the screen. Don't worry, this is because the amplicate value is set to 0, because we multiply amplicate with displacement, so no change is visible now. We have not set a loop, so amplicate can only be 0.

In our JavaScript, We need to package the rendering process into a function, and then use requestAnimationFrame to call this function. In this function, we update the value of uniform (Translator's note: amplm.

The Code is as follows:


Var frame = 0;
Function update (){
// Ampl comes from the sine of the frame.
Uniforms. amplms. value =
Math. sin (frame );
// Update the global Variable frame
Frame + = 0.1;
Renderer. render (scene, camera );
// Call update when the next screen refreshing is specified
RequestAnimFrame (update );
}
RequestAnimFrame (update );


5. Summary
That's it! You can see that the sphere is fluctuating strangely. I still haven't mentioned much about the coloring tool, but I hope this tutorial will help you. Now, when you see some other pasters, I hope you can understand them and you should be confident in creating your own pasters!

As usual, I packed the source code for this lesson
Related Article

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.