- WebGL Hotshot
- Mitch Williams
- 561字
- 2021-07-16 11:43:29
Lighting a scene and shading 3D objects with normals
One of the great effects in 3D graphics is to create surfaces such as a weathered brick wall, the bumpy skin of an orange, or ripples on the surface of water. Often, these surfaces are flat, but we can blend images together or paint the texture with these bumps. They can even be animated so that water appears to be flowing, such as in a waterfall. To create this realistic, weathered, and irregular look, we use vertex normals. A normal is simply a three-dimensional vector usually at a right angle to the polygon and often generated by 3D modeling tools.

Engage thrusters
Each of the images in the preceding screenshot of the dog uses the same lighting, texture maps, and polygons. They only differ by their normals. In the upper-left image, the normals are all set to (0, 0, 1), which means that they point right back at the light and thus each corner is fully lit. However, the lower-left image has its normals randomly set and thus does not point back at the light source. The image on the upper-right-hand side has the normal in the top-right corner set 90 degrees away; therefore, this corner appears as a dark spot. Finally, the lower-right image has its normal pointing at an angle to the light and thus the entire image is dark. The following code contains four <Transform>
nodes with identical shapes and texture maps, and only differs by the vector values in the <Normal>
nodes (thus, much of the repeated code has been left out):
<Transform translation="-2.25 2.25 -2"> <Shape> <Appearance DEF='bassetHoundImage' > <Material diffuseColor='1 1 1' /> <ImageTexture url='textureMaps/bassethound.jpg' /> </Appearance> <IndexedFaceSet coordIndex='0 1 2 -1 3 2 1 -1' normalIndex='0 1 2 -1 3 2 1 -1' texCoordIndex='0 1 2 -1 3 2 1 -1' > <Coordinate DEF="coords" point='-2 -2 0, 2 -2 0,-2 2 0, 2 2 0'/> <Normal vector='0 0 1, 0 0 1, 0 0 1, 0 0 1'/> <TextureCoordinate DEF="textureCoord"point='0 0, 1 0, 0 1, 1 1' /> </IndexedFaceSet> </Shape> </Transform> <Transform translation="-2.25 -2.25 -2"> <Shape> <Appearance USE='bassetHoundImage' /> <IndexedFaceSet coordIndex='0 1 2 -1 3 2 1 -1' normalIndex='0 1 2 -1 3 2 1 -1' texCoordIndex='0 1 2 -1 3 2 1 -1' > <Coordinate USE="coords" /> <Normal vector='-.707 -.5 .5, 0 0 1,-.707 .707 0, 0 .8 .6'/> <TextureCoordinate USE="textureCoord" /> </IndexedFaceSet> </Shape> </Transform> <Transform translation="-2.25 -2.25 -2"> … <Normal vector='0 0 1, 0 0 1, 0 0 1, 1 0 0'/> … </Transform> <Transform translation="2.25 -2.25 -2"> … <Normal vector='.63 .63 .48, .63 .63 .48, .63 .63 .48, .63 .63 .48'/> </Transform>
Objective complete – mini debriefing
Only the X3D code for the first two images is shown. Using the DEF
and USE
properties allows us to share the same <Appearance>
, <Coordinate>
, and <TextureCoordinate>
nodes for each shape. Only the <Normal>
node within each <Transform>
node for the two textured 3D meshes on the right are shown. Note that the <Normal>
vector is a unit value, which means that it has a length of 1; its three-dimensional (x, y, z) values have the property x2 + y2 + z2 = 1.
Normals play a major role in shader languages; they allow you to create a realistic look for complex lighting. We shall visit normals later, but let's see one small piece of math here. The amount of light on a polygon at each vertex is calculated by multiplying the (opposite direction of the) light vector and the normal vector. Both values must be unit values, which means that they should have a length of 1 unit before you multiply the two vectors. The light vector L
can be multiplied with the normal vector N
(known as the dot product) as (Lx, Ly, Lz) * (Nx, Ny, Nz) = Lx * Nx + Ly * Ny + Lz * Nz. The value will be between -1 and 1 (inclusive of both), but for any value less than zero, the light will come from behind the object, leaving the vertex in the dark. Incidentally, this amount of light at a vertex is equal to the cosine of the angle between the two vectors. For example, if the angle between the light vector and the normal vector is 30 degrees, then the dot product will equal cosine (30) = 0.866, or about 86.6 percent of the entire amount of light will reach this vertex.
- Learning SQL Server Reporting Services 2012
- 辦公通信設備維修
- Deep Learning with PyTorch
- 電腦常見故障現場處理
- The Applied AI and Natural Language Processing Workshop
- Apple Motion 5 Cookbook
- Building 3D Models with modo 701
- 微型計算機系統原理及應用:國產龍芯處理器的軟件和硬件集成(基礎篇)
- Java Deep Learning Cookbook
- 圖解計算機組裝與維護
- 3D Printing Blueprints
- FreeSWITCH Cookbook
- Mastering Machine Learning on AWS
- Arduino項目案例:游戲開發
- 單片機原理及應用