[three.js study notes] 02 Object material light and shadow

God said there was light, and there was light.
God said light was good, so he separated light from darkness.

In all 3D games or animations, light and shadow are very important parts. Shadows can affect many things. In a game, shadows can be said to distinguish the quality of a game screen.
This chapter covers:

  1. object material
  2. Add light source
  3. add shadow
  4. add shadow receptors

I have already introduced how to create a scene and add cameras and objects, so just paste the code to create the scene directly.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!--<script src="../three.min.js"></script>--><!--我发现我用的这个three.min.js本地版本没有辅助线-->
    <script src='https://threejs.org/build/three.js'></script>
    <title>场景</title>
    <style>
        body{
            margin:0;padding:0;
            overflow:hidden;
        }
    </style>
</head>
<body>
    <div id="WebGL-output"></div>
    <script>
        //初始化函数。在加载three之后调用,初始化所有的东西
        function init(){
            //创建场景。所有的物体对象都在场景上相当于是一个舞台
            var scene = new THREE.Scene();

            //创建透视相机
            var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
            //辅助线
            var axes = new THREE.AxesHelper(20);
            scene.add(axes);

            //渲染器
            var renderer = new THREE.WebGLRenderer();
            renderer.setClearColor(new THREE.Color(0xEEEEEE));

            renderer.setSize(window.innerWidth,window.innerHeight);
            //THREE.PCFSoftShadowMap  THREE.PCFShadowMap  BasicShadowMap
            //创建平面
            //材质种类:MeshLambertMaterial  MeshPhongMaterial MeshBasicMaterial
            var planeGeometry = new THREE.PlaneGeometry(60, 30);//框架
            var planeMaterial = new THREE.MeshBasicMaterial({color: 0xaaaaaa});//材质
            var planeMaterial1 = new THREE.MeshPhongMaterial( { color: 0xaaaaaa, dithering: true } );
            var plane = new THREE.Mesh(planeGeometry, planeMaterial);//填充


            //更改平面位置
            plane.rotation.x = -0.5 * Math.PI;
            plane.position.x = 15;
            plane.position.y = 0;
            plane.position.z = 0;

            scene.add(plane);

            //创建立方体
            var cubeGeometry = new THREE.BoxGeometry(4,4,4);
            var cubeMaterial = new THREE.MeshBasicMaterial({color: 0xdd4444,wireframe: true});
            //wireframe用于表现几何体的框架 默认为false
            var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);


            //立方体位置
            cube.position.x = -4;
            cube.position.y = 3;
            cube.position.z = 0;
            //将立方体添加进入场景
            scene.add(cube);
            //添加球体
            var sphereGeometry = new THREE.SphereGeometry(4, 20 ,20);
            var sphereMaterial = new THREE.MeshBasicMaterial({color:0xcc44cc});
            var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);


            //球体位置
            sphere.position.x = 18;
            sphere.position.y = 4;
            sphere.position.z = 2;
            //将球体加入到场景中
            scene.add(sphere);

            //柱体
            var cylinderGeometry = new THREE.CylinderGeometry( 4, 4, 5, 5);
            var material = new THREE.MeshBasicMaterial({color:0xcccc33});
            var cylinder = new THREE.Mesh(cylinderGeometry,material);

            //设定位置
            cylinder.position.x = 2;
            cylinder.position.y = 2.5;
            cylinder.position.z = 6;
            //添加柱体
            scene.add(cylinder);

            //变化相机位置以及方向
            camera.position.x = -30;
            camera.position.y = 40;
            camera.position.z = 30;
            camera.lookAt(scene.position);

            //创建canvas
            document.getElementById("WebGL-output").appendChild(renderer.domElement);
            //渲染
            renderer.render(scene,camera);
        }
        window.onload = init;
    </script>
</body>
</html>

Compared with the content of the previous chapter, I slightly enlarged the area of ​​the plane platform at the bottom, and removed the wireframe of the cylinder and sphere, so that the effect of the basic material can be seen, and the effect is as follows:
three.js basic material
emm This material looks very Slag, it is barely recognizable as a three-dimensional thing, the color of each surface is the same
THREE.MeshBasicMaterial This material does not react to the light source, so we need to modify the material first.
Modify of the plane and the material of all objects , turn it all into THREE.MeshLambertMaterial (Lambert material)
This material will react to light, it does not include any specular properties, it is very useful for rough objects, it does not reflect the surrounding environment

...
    var planeMaterial = new THREE.MeshLambertMaterial({color: 0xaaaaaa});//平面材质
...
    var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xdd4444});//立方体材质
...
    var sphereMaterial = new THREE.MeshLambertMaterial({color: 0xcc44cc});//球体材质
...
    var material = new THREE.MeshLambertMaterial({color:0xcccc33});//无棱柱材质

After the materials are changed, let's refresh the page again:
three.js matte state

Found it in total darkness –. From the part where the auxiliary line is hidden, you can vaguely see that there is something black. That's because there is no light-. -Add
light source

            var spotLight = new THREE.SpotLight(0xffffff);//白色光线
            spotLight.position.set(-40,80,-10);//位置
            spotLight.castShadow = true;//会产生影子
            scene.add(spotLight);//添加光源进入场景

The spot light source added here is a light source that starts from a point and spreads out at a certain angle. There are many types of light
sources . For example, the ambient light source, AmbientLight , is a light source that exists on objects in the scene. This light source is random on the surface of all objects. Distributed,
parallel light DirectionalLight sunlight is similar to parallel light to the earth,
point light source PointLight is similar to small light bulbs
, there are many other light sources, please find the light
source by yourself
three.js add light source
. There seems to be something going on, but why is there still no shadow?
The reason is that although the light source has been written to have the possibility of producing shadows, three more points are needed:

  1. Which objects can produce shadows (for example, vampires have no shadows because he is a vampire, and he has his own attributes)
  2. Where to put the generated shadow (where the shadow can be accepted)
  3. Renderer allows shadows

Why is it so complicated, because generating shadows is a very resource-intensive task, we have to know where to generate shadows and where to cast shadows.
Add the following code:

    renderer.shadowMap.enabled = true;//渲染器将会渲染影子
    plane.receiveShadow = true;//让平面能够接受影子
    //让物体们能够有自己的影子
    cube.castShadow = true;
    sphere.castShadow = true;
    cylinder.castShadow = true;

After completion found:
three.js shadow mosaic

There is a shadow, but this shadow is a mosaic shadow -, -, although you can't see it from a distance,
but I still hope that the shadow can be more real.
Actually: by default, in order to avoid too much shadow rendering, there are settings in the settings. Such a mosaic. At the same time, the size of the original geometry is set to be relatively small =. =
That's why this situation arises.
add code

    spotLight.shadow.mapSize.width = 2000;  // 默认512
    spotLight.shadow.mapSize.height = 2000; // 默认512

The degree of detail of the shadow in both directions, the higher the more detailed, the more it feels when it reaches 2000.
Effect :
three.js add shadow
I think it's okay. Well, the next chapter should talk about animation and the dat.GUI component library to test the impact of different values ​​on performance. Well,
(turn the book...)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325567900&siteId=291194637