Processing vertices-convex ing: Fixed normal

Source: Internet
Author: User
Tags mul
Problem

The main problem with a triangle is that it is flat. If you use two triangles to draw a huge wall and attach a beautiful texture to the wall, the result is disappointing.

You can divide a triangle into smaller triangles to add details. This requires defining the 3D position of each vertex, but this consumes too much resources.

Solution

You can replace this ugly method with concave-convex ing. The concave-convex ing changes the color of each pixel of the triangle to give the observer the impression of high and low fluctuations on the surface of the triangle.

If you look at a smooth picture of a red plastic board, you will find that all pixels are almost one color. However, if it is a rough surface image, for example, a red brick, the pixel will have a different red color, let the observer know that the surface of the brick is rough.

This is what you want to simulate. On a rough surface, different pixel reflection results in different colors. This is because you can divide a brick into thousands of small surfaces, each of which has a different direction or a different normal, as shown on the left of 5-29. You can obtain different illumination conditions for each normal (See Chapter 6th ).

Figure 5-29 a brick with thousands of planes, each of which has a different normal

You can draw bricks with only two triangles on the right, instead of using the hundreds of triangles shown on the left of 5-29. On each pixel of the two triangles, you will slightly change the default normal, which will give different illumination to all pixels and lead to different colors. In this way, many details can be added to the concave-convex ing if the brick position or light direction changes.

To achieve the best effect, you should not randomly change the direction of the normal, but in the correct way, as shown in the right image. Note that the normal of the right image is the same as that of the left image. Generally, the X, Y, and Z coordinates of each normal are stored in the R, G, and B channels of an image. This is called texture concave-convex ing (or normal ing ).

Therefore, instead of dividing bricks into thousands of triangles, draw a rectangle with two triangles using two textures: One texture contains the color of the bricks and the other contains information about the normal deviation. You need to use pixel shader to query the color and normal offset of each pixel, and use this normal to calculate the illumination to further adjust the brightness of the color.

In this tutorial, the concave-convex ing is a plane, and the plane is a simplified example because its normal vector remains unchanged.

Working Principle

First, you need to define a new triangle to represent the plane. The followingCodeDefine two triangles with textures, which is enough to draw a large rectangle:

 
Private vertexpositiontexture [] initvertices () {vertexpositiontexture [] vertices = new vertexpositiontexture [6]; vertices [0] = new vertexpositiontexture (New vector3 (-5, 0, 10 ), new vector2 (0, 2); vertices [1] = new vertexpositiontexture (New vector3 (-5, 0,-10), new vector2 (0, 0 )); vertices [2] = new vertexpositiontexture (New vector3 (5, 0, 10), new vector2 (1, 2 )); vertices [3] = new vertexpositiontexture (New vector3 (-5, 0,-10), new vector2 (0, 0 )); vertices [4] = new vertexpositiontexture (New vector3 (5, 0,-10), new vector2 (1, 0 )); vertices [5] = new vertexpositiontexture (New vector3 (5, 0, 10), new vector2 (1, 2); Return vertices ;}

Because you want to sample the texture, You need to specify the texture coordinates (see tutorial 5-2 ). Because Y coordinates are all 0, you define the plane on the xz plane, so you know that the default normal vector is facing up.

Note:This assumption is correct only in this case. The next tutorial will introduce a more general method.

After the vertex is defined, you can write the FX code.

XNa-to-HLSL variable

All 3D effects require passing the world matrix, observation matrix, and projection matrix so that vertex shader can convert the 3D position of the vertex to the 2D screen position. To display the concave-convex ing effect, you should be able to change the light direction.

As mentioned above, you need to input two textures: one for color sampling and the other for querying the normal of each pixel.

 
Float4x4 xworld; float4x4 xview; float4x4 xprojection; float3 xlightdirection; texture xtexture; sampler labels = plain {texture = <xtexture>; magfilter = Linear; minfilter = Linear; mipfilter = Linear; addressu = wrap; addressv = wrap;}; texture xbumpmap; sampler region = sampler_state {texture = <strong>; magfilter = Linear; minfilter = Linear; mipfilter = Linear; addressu = wrap; addressv = wrap;}; struct sbmvertextopixel {float4 position: position; float2 texcoord: texcoord0 ;}; struct sbmpixeltoframe {float4 color: color0 ;};

Vertex shader outputs the 2D screen position and texture coordinates of each vertex. pixel shader calculates the final color.

Vertex shader

Vertex shader is very simple, because it only needs to convert 3D coordinates to 2D screen space and pass texture coordinates to pixel shader:

 
Partition partition (float4 inpos: position0, float2 intexcoord: equal) {partition output = (partition) 0; float4x4 previewprojection = MUL (xview, xprojection); float4x4 preworldviewprojection = MUL (xworld, previewprojection); output. position = MUL (inpos, preworldviewprojection); output. texcoord = intexcoord; return output ;}

3d positions are converted to 2D screen space by combining world matrix, view matrix, and projection matrix. texture coordinates are directly transmitted to pixel shader.

Pixel shader

For each pixel of a triangle, pixel shader queries the color value from the color texture. However, this time, pixel shader also needs to sample the concave and convex textures to query the direction of the specified pixel from the default normal.

A normal vector is a 3D vector defined by three coordinate axes. For more information about the normal, see tutorial 5-7. To learn how the normal affects the light, see tutorial 6-1.

For each pixel of the concave-convex ing, the regular line coordinates are stored in three color channels. However, the three coordinate ranges must be between-1 and 1 (that is, it can be in the ± x, ± y, and ± Z directions, however, the color range is only in the range of [0, 1. Therefore, you need to map the value in the range [0.5] to [-0.5], which can first subtract 0.5 (ing to the range) multiply by 2 (ing to the range ). This step is performed in the third line of code in pixel shader:

 
Sbmpixeltoframe sbmpixelshader (sbmvertextopixel pSIN): color0 {sbmpixeltoframe output = (sbmpixeltoframe) 0; float3 bumpmapcolor = tex2d (bumpmapsampler, pSIN. texcoord ). rbg; float3 cursor = (bumpmapcolor-0.5f) * 2.0f; float lightfactor = dot (-Normalize (inflow), normalize (xlightdirection); float4 texcolor = tex2d (texturesampler, pSIN. texcoord); output. color = lightfactor * texcolor; return output ;}

In the concave-convex ing, three color channels indicate the offset of the default normal. When the default normal is not deviated, the corresponding pixel color is light blue (r = 0.5, G = 0.5, B = 1). Note: See the preceding figure.Algorithm, Read the color in rbg order, and then use the formula to multiply by 2 minus 1, that is, r = 0.5, G = 0.5, B = 1, and the result is (, 0 )). In this example, the two triangles are in the xz plane, so the normal is facing up (0, 1, 0.

In the concave-convex ing, the pixel color is not (r = 0.5, G = 0.5, B = 1) and the line must deviate from (, 0. In this example, you want to make the normal line deviate from X or Z. We can see that the next tutorial will learn a common method.

This is also why the blue channel corresponds to the Y coordinate of the normal, the red and green channels correspond to the X and Z coordinates (this is also the reason for using rbg swizzle) in this example: swizzle is a method that specifies the input channel, such as float4 B (1, 2, 3, 4); then float4 A = B. XXXX (); // A is now 1, 1, 1, 1; A = B. wwwz (); // A is now 4, 4, 4, 3; A = B. yzzw (); // A is now 2, 3, 3, 4; A = B. wzyx (); // A is now 4, 3, 2, 1; you can also use float4 A = B. RRRR. rryy ();). If the color of the sample from the concave-convex ing is equal to (0.5, 0.5, 1), normalfrombumpmap is (, 0), which means that the normal is not deviated (both face up ). If bumpmapcolor = (0.145, 0.5, 0.855), normalfrombumpmap is (-0.71, 0.71, 0), which means the normal will deviate 45 degrees from the left.

Once you know the normal of each pixel, You can normalize the normal and light direction of the two before the dot multiplication line and the light direction (so that the length is 1. As explained in tutorial 5-6, the result of dot multiplication indicates the brightness of the current pixel, and then multiply the brightness by the color.

Define Technique

Add the technique definition to the FX file:

 
Technique simplebumpmapping {pass pass0 {vertexshader = compile vs_2_0 sbmvertexshader (); pixelshader = compile ps_2_0 sbmpixelshader ();}}
Code

Adding the above three parts to the FX file is the complete code. The xNa code for setting parameters draws two triangles:

 protected override void draw (gametime) {Device. clear (clearoptions. target | clearoptions. depthbuffer, color. black, 1, 0); // set effect parameters effect. currenttechnique = effect. techniques ["simplebumpmapping"]; effect. parameters ["xworld"]. setvalue (matrix. identity); effect. parameters ["xview"]. setvalue (fpscam. viewmatrix); effect. parameters ["xprojection"]. setvalue (fpscam. projectionmatrix); effect. parameters ["xtexture"]. setvalue (mytexture); effect. parameters ["xbumpmap"]. setvalue (mybumpmap); effect. parameters ["xlightdirection"]. setvalue (lightdirection); // render two triangles effect. begin (); foreach (effectpass pass in effect. currenttechnique. passes) {pass. begin (); device. vertexdeclaration = myvertexdeclaration; device. drawuserprimitives 
  
    (primitivetype. trianglelist, vertices, 0, 2); pass. end ();} effect. end (); base. draw (gametime) ;}
  

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.