preface

In addition to creating models, setting colors and textures for models, lighting effects are also needed to better reflect the scenes in the real world. This example I think both beautiful and representative strong, so take out to share with you. The example address: Light Flowing

Example GIFs:

The main points from the above scene include: 3D lighting and the flow of 3D models.

1. Set up a scenario

The entire scene consists of 2D scenes (also known as the hawk-eye part) and 3D scenes:

dm = new ht.DataModel();
g3d = new ht.graph3d.Graph3dView(dm);
g3d.setGridVisible(true); // Specify whether to display grid g3d.setGridColor('#74AADA'); // Specify the grid color g3d.getView().classname ='main'; / / set the name of the class document. The body. The appendChild (g3d. GetView ()); // Add the 3D component to the body window.adDeventListener ('resize'.function(e) {
    g3d.invalidate();
}, false); g2d = new ht.graph.GraphView(dm); g2d.setAutoScrollZone(-1); G2d.getview ().className = if the mouse distance to the edge of the topology is less than this value, the topology automatically scrolls (adjust translateX or translateY)'g2d';
g2d.setEditable(true); / / set in the topology map can edit the document. The body. The appendChild (g2d. GetView ()); ht.Default.callLater(g2d.fitContent, g2d, [true, 50, true]); // Get the global next ID g3d.setheadLightrange (2000); // Lamp influence range. Default is 0, which means that the light can reach infinity. If this value is set, the light effect will decay as the object moves away from the shadowCopy the code

The root layer of all HT components is a div component, available through the component’s getView() function, which is used here to add 3D and 2D components to the body. As long as 3D and 2D share the same data container, the primitives in the data container are shared. That is to say, as long as we arrange the primitives in 2D or 3D well, the layout and style of primitives in the remaining component are arranged according to the arranged components.

2. Add lights

In addition to the rotating light, there are two stationary red lights and yellow lights in the scene, which can be seen more clearly when the rotating light shines on other places:

redLight = new ht.Light(); // redlight.p3 (0, 0, -175); // The location of the instance variable redlight.s ({'light.color': 'red'// Light color'light.range': 400 // Lamp range of influence, default is 0 means can be irradiated to infinity, if set to the value of the light effect as the object away from the shadow attenuation}); dm.add(redLight); RotateLight = new ht.light (); // Add the instance variable to the data capacity. rotateLight.s({'light.color': 'green'.'light.type': 'spot'});});});}); dm.add(rotateLight); yellowLight = new ht.Light(); yellowLight.p3(0, 0, 60); yellowLight.s({'light.color': 'yellow'.'light.range': 200}); dm.add(yellowLight);Copy the code

3. Model construction in the scene

The first is the creation of the floor. The floor is a round floor. Set the style shape3D to cylinder, and the rest just need to set the size, position and style.

floor = new ht.Node(); //Node Node class flores. s3(1100, 10, 1100); floor.p3(0, -100, -110); floor.s({'shape3d': 'cylinder'// Set the 3D model to a circle'shape3d.side': 100, // The default value is 0, which determines how many edges the 3D graphics should display. 0 is displayed as a smooth surface effect'shape3d.color': 'white'// The default value is#3498DB, overall color of 3D graphics
    '3d.selectable': false// The default value istrueControls whether the pixel is selectable on the Graph3dView'2d.visible': false// The default value istrue, controls whether the pixel is visible on the GraphView}); dm.add(floor);Copy the code

Then add 8 columns around the floor:

for(var i=0; i<8; i++){
    var angle = Math.PI*2*i/8;
          pillar = new ht.Node();
    pillar.s({
        'shape3d': 'cylinder'.'shape3d.color': 'white'.'shape': 'circle', // The polygon type element is displayed as a picture if it is empty'shape.background': 'gray'// Polygon type pixel background}); pillar.s3(50, 180, 50); pillar.p3(Math.cos(angle)*480, 0, -110+Math.sin(angle)*480); dm.add(pillar); }Copy the code

There are also various “arrows” used as texture models, and I will only parse one of them here. Please refer to the shape manual for the detailed description of polygons:




The image part is a map named arrow created by the hT.default. setImage function.

shape3 = new ht.Shape(); // Polygon dm.add(shape3); shape3.setTall(60); // Set the height shape3.setthickness (0); Shape3. s({// Set the style'shape.background': null,
    'shape.border.width': 10, // The width of the polygon type pixel border'shape.border.color': 'blue'.'all.visible': false// Whether the six sides are visible'front.visible': true.'front.blend': 'blue', // Color the front'front.reverse.flip': true// Whether the front side shows the front side'front.image': 'arrow'// Front texture'front.uv.scale': [16, 3] // Uv zoom of the front map, format is [3,2]}); Shape3. SetPoints ([/ / set points set {x: 0, y: 0}, {x: 25, y: 25}, {x: 50, y: 0}, {x: 75, y: 25}, {x: 100, y: 0}, {x: 125, y: -25}, {x: 150, y: 0}, {x: 175, y: 25}, {x: 200, y: 0} ]); Shape3. setSegments([// describe point join style 1, // moveTo 3, // quadraticCurveTo 3, // quadraticCurveTo 3, // quadraticCurveTo 3, // quadraticCurveTo 3, // // quadraticCurveTo 3 // quadraticCurveTo ]); shape3.p3(-100, 0, 100); shape3.setRotationZ(-Math.PI/2); // Set the rotation Angle of the pixel along the Z-axis in the 3D topology (in radians)Copy the code

4. Set the timer to make the pictures in each model “flow” and the rotation of the rotating light

offset = 0;
angle = 0;
setInterval(function(){ angle += Math.PI/50; rotateLight.p3(400*Math.cos(angle), 70, -110+400*Math.sin(angle)); // Set the coordinate of the rotating light offset += 0.1; uvOffset = [offset, 0]; shape1.s({'front.uv.offset': uvOffset // uvOffset // uvOffset in the format of [3,2]}); shape2.s({'front.uv.offset': uvOffset
    });
    shape3.s({
        'front.uv.offset': uvOffset
    });
    shape4.s({
        'front.uv.offset': uvOffset
    });
    shape5.s({
        'shape3d.uv.offset': uvOffset, // determines the uv scaling of the overall map of the 3d graphics in the format [3,2]'shape3d.top.uv.offset': uvOffset, // determines the uv scaling of the top map of the 3d graphics in the format [3,2]'shape3d.bottom.uv.offset': uvOffset // determines the uv scale of the bottom map of the 3d graphics, in the format of [3,2]}); cylinder.s({'shape3d.uv.offset': uvOffset
    });
    torus.s({
        'shape3d.uv.offset': uvOffset
    });
}, 200);Copy the code

conclusion

At the end of the whole example, the feeling is “small code big effect”, the code quantity is small and simple, and the effect is very good, you can go to the official website or the manual for other examples.