"DirectX11" Nineth Light model--Highlights

Source: Internet
Author: User
Tags mul

This series of articles is mainly translated and referenced from "Real-time 3D Rendering with DirectX and HLSL" (thanks to the author of the original book), but also a bit of personal understanding and development, if there are errors in the article, please correct me.
Here is the code and resources in the book.

All of the environment and tools used in this article are based on previous articles, if you do not understand, please refer to the previous articles in this series first.

This article index:

    • About Lights
    • Specular Highlights High Gloss
      • 1 Phong Fengshi Illumination model
      • 2 Phong Preamble Fengshi illumination model variable preparation
      • 3 Phong Vertex Shader Fengshi model vertex shader
      • 4 Phong Pixel Shader Fengshi model pixel shader
      • 5 Phong output Fengshi illumination model effect outputs
      • 6 Blinn-phong improved Fengshi illumination model
      • 7 Blinn-phong Pixel Shader blinn-phong illumination model pixel shader
      • 8 Blinn-phong with intrinsics Blinn-phong illumination model implementation with inline functions
      • 9 Blinn-phong vs Phong Comparison of two kinds of high-gloss model calculations
    • Summarize
    • Reference links


About Lights

In the real world, without light we will not see anything, the object you see or the light that reflects the light or itself can be self-luminous. In the process of computer rendering, you will simulate the interaction of light with the object, and increase the detail of the surface of the 3D object. But the interplay of lights is a very complex process, and in current technology it is not possible to do such a large number of repetitive computations within an interactive frame rate range. As a result, an approximate algorithm is typically used to add more detail to your senses with a light model that describes how light interacts with the 3D model. Some basic lighting models will be introduced in this article.


Specular highlights: high-Gloss

When you simulate diffuse reflection, you can only provide a rough, matte surface feel. This is true for most cases, and this provides the basic illumination for the other parts of the highlight. But sometimes you also need to make a shiny surface simulation, such as polished metal and marble flooring. This part of the explanation is how to achieve this high-gloss effect.

(1) Phong Fengshi (Illumination model)

There are many ways to simulate specular reflection. The first high-light model we were going to look at was the Fengshi reflection model, which was named after its inventor, the Bui Tuong Phong from the University of Utah (University of Utah).
Unlike diffuse reflection, the calculation of highlights needs to be calculated based on the position and angle of the viewer (camera). You can observe in the real world that when you change the position and angle of a light object, its spot position changes. The Fengshi model illustrates that the calculation of high light depends on the angle between the observer's observation direction and the reflected light vector. The formula is as follows:

Here r is the reflected light vector, V is the viewing direction, and the exponent s is the size of the highlight. The smaller the highlight, the greater the value. The reflected light is calculated using the following formula:
The unit normal vector for the vertex is N and has the formula:
R + L = (2N?) L) N (here again, the direction of L is pointed to the light source by the vertex)
By this can be launched:

In this formula, n represents the surface normal, and L represents the ray vector.

The following code implements a Fengshi model:
Code Snippet Listing 6.5 phong.fx

#include"Include\\common.fxh"/*************** Resources ***************/Cbuffer cbufferperframe{float4 ambientcolor:ambient < string uiname ="Ambient Light"; String uiwidget ="Color"; > = {1.0F1.0F1.0F0.0f}; FLOAT4 Lightcolor:color < String Object ="LightColor0"; String uiname ="Light Color"; String uiwidget ="Color"; > = {1.0F1.0F1.0F1.0f}; FLOAT3 Lightdirection:direction < String Object ="DirectionalLight0"; String uiname ="Light Direction"; String Space ="World"; > = {0.0F,-1.0F,-1.0f}; FLOAT3 cameraposition:cameraposition<string uiwidget="None"N.; Cbuffer cbufferperobject{float4x4 worldviewprojection:worldviewprojection <string uiwidget="None";>; float4x4 World:world <string uiwidget="None";>; FLOAT4 Specularcolor:specular < String uiname ="Specular Color"; String Uiwidget ="Color"; > = {1.0F1.0F1.0F1.0f};floatSpecularpower:specularpower < String uiname ="Specular Power"; String uiwidget ="Slider";floatUimin =1.0;floatUimax =255.0;floatUistep =1.0; > = {25.0f};} Texture2d colortexture< String resourcename ="Default_color.dds"; String uiname ="Color Texture"; String resourcetype ="2D";>;    Samplerstate colorsampler{Filter = min_mag_mip_linear;    Addressu = WRAP; ADDRESSV = WRAP;};    Rasterizerstate disableculling{cullmode = NONE; };/*************** Data Structures ***************/struct vs_input{float4 objectposition:position;    FLOAT2 Texturecoordinate:texcoord; FLOAT3 Normal:normal;};    struct vs_output{float4 position:sv_position;    FLOAT3 Normal:normal;    FLOAT2 texturecoordinate:texcoord0;    FLOAT3 Lightdirection:texcoord1; FLOAT3 Viewdirection:texcoord2;};/*************** Vertex Shader ***************/Vs_output Vertex_shader (Vs_input in) {vs_output out = (vs_output)0; Out. Position = Mul (in.    Objectposition, worldviewprojection); Out. Texturecoordinate = Get_corrected_texture_coordinate (in.    Texturecoordinate); Out. Normal = Normalize (Mul (FLOAT4 (in. Normal,0), world). xyz); Out.    Lightdirection = normalize (-lightdirection); FLOAT3 worldposition = Mul (in.    Objectposition, World). XYZ; Out. Viewdirection = normalize (cameraposition-worldposition);returnOut;}/*************** Pixel Shader ***************/FLOAT4 Pixel_shader (Vs_output in): sv_target{float4 out = (FLOAT4)0; FLOAT3 normal = normalize (in.    Normal); FLOAT3 lightdirection = Normalize (in.    Lightdirection); FLOAT3 viewdirection = Normalize (in. Viewdirection);floatN_dot_1 = dot (lightdirection, normal); FLOAT4 color = colortexture.sample (Colorsampler, in.    Texturecoordinate);    FLOAT3 ambient = Ambientcolor.rgb * AMBIENTCOLOR.A * COLOR.RGB; FLOAT3 diffuse = (FLOAT3)0; FLOAT3 specular = (FLOAT3)0;if(N_dot_1 >0{diffuse = Lightcolor.rgb * LIGHTCOLOR.A * SATURATE (n_dot_1) * COLOR.RGB;//r = 2 * (N.L) * N-lFLOAT3 Reflectionvector = Normalize (2* n_dot_1 * normal-lightdirection);//specular = R.v^n with gloss map in color texture ' s alpha channelSpecular = Specularcolor.rgb * specularcolor.a * min (Pow (Saturate (dot (reflectionvector, viewdirection)), SpecularPower        ), COLOR.W);        Out.rgb = ambient + diffuse + specular; OUT.A =1.0FreturnOut;    } Out.rgb = ambient + diffuse; OUT.A = COLOR.A;returnOut;}/*************** Techniques ***************/Technique10 main10{pass P0 {SetVertexShader (Compileshader (Vs_4_0, Vertex_shader ()));        Setgeometryshader (NULL);        SetPixelShader (Compileshader (Ps_4_0, Pixel_shader ()));    Setrasterizerstate (disableculling); }}
(2) Phong preamble: Fengshi Illumination model Variable preparation

In contrast to the diffuse effect in the previous article, only one member was added to the cbufferperframe buffer: cameraposition. This constant stores the location of the camera and indirectly determines the direction of the line of sight. When you associate cameraposition semantics with this constant, NVIDIA FX composer automatically binds the camera position in the render panel to this constant.
Two members Specularcolor and Specularpower are added to the cbufferperobject buffer. Specularcolor and ambient light, parallel light have the same function body; he defines the color and intensity of the highlights. This extra part allows you to independently adjust the highlights without relying on the parallel light. Specularpower refers to the exponential portion of the Fengshi specular model used to adjust the intensity of the highlight.
There is also a viewdirection vector in the vs_output structure, which is used to pass the calculated line of sight to the grating stage for processing.

(3) Phong Vertex Shader: Fengshi model vertex shader

In the vertex shader, the line of sight direction is calculated. However, you must unify the coordinate system before you calculate it, so you need to convert it to the world coordinate system with the help of the global matrix.

(4) Phong Pixel Shader: Fengshi model Pixel shader

A new calculation for the highlight section is added to the pixel shader. This part of the light is only available when the light is facing the model surface, so it must be judged before n_dot_1>0 is executed.
In addition, the more complex pixel shader is the code that calculates the highlight, first the code is listed below:
Code snippet listing high-light calculation in 6.6 phong.fx

//specular = R.V^n with gloss map in color texture‘s alpha channelspecularmin(powcolor.w);

This code is written according to the formula of the Fengshi illumination model. Using the POW function, the base is the point multiplication of the reflected light vector and the line of sight vector, and the exponential part is the Speculiarpower constant. The saturate () function limits the calculation result from 0.0 to 1.0, and limits the angle must be between 0~90度.
The note also shows that the calculation of the highlight is also dependent on the Gloss map (gloss map), which is stored in the alpha channel of the texture map. Glossy maps, or specular maps (specular map) are either stored in a single texture (this texture has only one channel), or, as in this article, there is a part of the material map, such as the alpha channel. Specular mapping changes the results of a highlight based on the intent of the decal creator. In the Earth's surface texture used in this article, the ocean part should be reflected by high light because it is water, and the land part should be without specular reflection. The following diagram shows the content of the specular map, showing that the land portion is black, with a value of 0, and that the value of the highlight portion of the pixel that is calculated last is 0, so that only the diffuse portion of the light is retained, and the surface portion is added to the full specular effect.

(5) Phong output: Fengshi illumination model effect outputs

In the picture below, the left image shows the rendering of a map with a high-light channel, without a high-light channel in the texture on the right, and observe the difference in the reflected light effect on the land part:

(6) blinn-phong--improved Fengshi illumination model

In 1977, Jim Blinn proposed a simplified version of the Fengshi model, based on Half-vector to modify the illumination model, Half-vector is the intermediate vector of the incident light and eye, the formula is as follows:

As can be seen from this formula, the calculated H (half-vector) is the unit vector of the line of sight vector and the intermediate vector of the incident light. The Blinn-phong illumination model is calculated from the surface normal vectors and half-vector (different from the reflected and line of sight vectors of the Phong model), thus increasing the base in the formula, which is calculated as follows:

(7) Blinn-phong Pixel shader:blinn-phong illumination model pixel shader

Since the Blinn-phong illumination model is modified on the basis of the Phong illumination model, most of their code is similar, so only the different parts are listed here, the following is the pixel shader code:

Code snippet Listing pixel shader in 6.7 blinnphong.fx

FLOAT4 Pixel_shader (Vs_output in): sv_target{float4 out = (FLOAT4)0; Float3Normal=Normalize(In.    Normal); FLOAT3 lightdirection =Normalize(In.    Lightdirection); FLOAT3 viewdirection =Normalize(In. Viewdirection);floatN_dot_1 = dot (lightdirection,Normal); Float4Color= Colortexture.sample (Colorsampler, in.    Texturecoordinate); Float3Ambient= Ambientcolor.rgb * AMBIENTCOLOR.A *Color. RGB; Float3Diffuse= (FLOAT3)0; Float3Specular= (FLOAT3)0;if(N_dot_1 >0)    {Diffuse= Lightcolor.rgb * LIGHTCOLOR.A * SATURATE (n_dot_1) *Color. RGB; FLOAT3 Halfvector =Normalize(Lightdirection + viewdirection);//specular = N.h^s with gloss map in color texture ' s alpha channel        Specular= Specularcolor.rgb * SPECULARCOLOR.A *min(POW(Saturate (dot (Normal, Halfvector)), Specularpower),Color. W); Out.rgb =Ambient+Diffuse+Specular; OUT.A =1.0FreturnOut; } Out.rgb =Ambient+Diffuse+Specular; OUT.A =1.0FreturnOut;}

Blinn-phong illumination model and Phong illumination model are almost the same, but because of his base increase, it is necessary to adjust the exponent, that is, the high light intensity part can be the same as the Phong light model effect. As shown, the left image is the Blinn-phong illumination model rendering effect, the right image is the Phong Illumination model rendering effect, two material light intensity values are set to 25:

It can be seen that the light spot of blinn-phong illumination model is bigger than the Phong illumination model under the same illumination intensity parameter.

(8) Use of inline functions in blinn-phong with Intrinsics:blinn-phong illumination model implementation

For an explanation of the inline function (intrinsics), check out the Instrinsics section of the reference material "1".

Description of the original reference of the Intrinsics function
Inline functions are likely to be misunderstood as we usually think, mainly the word I translate incorrectly (intrinsics). Such functions can be called by C and C + + programs. There's not much difference between the other functions, At best, the name is more eccentric. But when this code is compiled by the compiler, It will be converted into an ordered low-level directive. These instructions are neon's instructions. So that's it. Use low-level languages at the high level of language. The main thing is that programmers don't have to touch the assembly, It can reduce the difficulty of optimization. Of course I can say that the optimization efficiency does not use the high of the Assembly.
For the above technology is actually the arm company itself gives you some functions, you call these functions directly, these functions can be compiled directly into the Neon assembly instructions. To support these inline functions, you must include the header file Arm_neon.h.

The important thing in this article is the intrinsics function in C, but the intrinsics function in HLSL is similar to what he should be.

The lit () function is provided in HLSL to help calculate the diffuse portion of the Lambertian model and the specular portion of the Blinn-phong model. A good way to improve performance is to use them whenever possible with intrinsics functions or built-in functions, as this type of function is optimized in hardware. Therefore, we will use the lit () function to rewrite the Blinn-phong model pixel shader listed below:

Code snippet Listing 6.8 overriding Blinn-phong illumination model pixel shader

FLOAT4 Pixel_shader (Vs_output in): sv_target{float4 out = (FLOAT4)0; Float3Normal=Normalize(In.    Normal); FLOAT3 lightdirection =Normalize(In.    Lightdirection); FLOAT3 viewdirection =Normalize(In. Viewdirection);floatN_dot_1 = Dot (Normal, lightdirection); FLOAT3 Halfvector =Normalize(Lightdirection + viewdirection);floatN_dot_h = Dot (Normal, Halfvector); Float4Color= Colortexture.sample (Colorsampler, in.    Texturecoordinate);    Float4 lightcoefficients = Lit (n_dot_1, n_dot_h, specularpower); Float3Ambient= Get_vector_color_contribution (Ambientcolor,Color. RGB); Float3Diffuse= Get_vector_color_contribution (Lightcolor, Lightcoefficients.y *Color. RGB); Float3Specular= Get_scalar_color_contribution (Specularcolor,min(Lightcoefficients.z,Color. W)); Out.rgb =Ambient+Diffuse+Specular; OUT.A =1.0FreturnOut;}

The rewrite of the above code is different from the pixel shader, and the function is encapsulated separately for calculating each light, and the encapsulated get_vector_color_contribution and Get_scalar_color_ The contribution function is already written in the Common.fxh file that is mentioned in the seventh article. And the conditional sentence is removed from the shader. The new add lit () call, which accepts n_dot_1 and n_dot_h, highlight intensity as input parameters, can achieve the same results as calculated by the diffuse and blinn-phong high-light models, the return value of Float4,x and W is always 1, The Y value represents the computed result of the diffuse illumination on this pixel, and the Z-value represents the Blinn-phong illumination calculation on this pixel.

(9) Blinn-phong vs. Phong: Comparison of two kinds of high-light model calculations

Blinn-phong and Phong two kinds of illumination models achieve similar effect, just need to adjust the intensity of the high light is not the same size, there should be the problem of rendering efficiency. Since blinn-phong involves the operation of the square root (this operation derives from the normalize computation of the half-vector vector). However, after we used the lit () function, the inline function made the blinn-phong slightly more computationally specific than the Phong model and reduced the amount of code. Therefore, you will use this function when you need to use a model with both diffuse and specular highlights later.


Summarize

In this article, we mainly explain the two kinds of high-light model algorithm and shader implementation. It is important to note that this article mainly describes the combination of high-light and diffuse reflection on the unified model, but in reality there are many models are single, that is, such as glass and purple teapot Such items their surface material is mostly unified. This is a relatively simple situation, just pay attention to the use of specular maps.

Reference links

The "1" inline function. (http://www.360doc.com/content/14/0428/15/9408846_372927783.shtml)

"DirectX11" Nineth Light model--Highlights

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.