OpenGL tutorial (19) highlights

Source: Internet
Author: User

Original post http://ogldev.atspace.co.uk/www/tutorial19/tutorial19.html

When we first Calculated ambient light, the only thing that affected the light was the light intensity. Then, when we calculated the diffuse reflection light, we introduced the light source direction and the object vertex normal, in this tutorial, we will learn how to calculate the highlights. We will introduce a new parameter for the viewpoint position, because the highlights will change as the viewpoint moves. In some angles, the highlight looks brighter. Metal objects usually have high-gloss effects.

In the following highlight calculation, the viewpoint position will be introduced. First, let's look at the illumination diagram below:

Note the following five parameters:

  • 'I' is the incident light that illuminates the surface of an object.
  • 'N' is the normal direction of the object surface.
  • 'R' is the light emitting from the incident light after it is exposed to the surface of the object. The reflected light and the incident light are symmetric along the normal line.
  • 'V' is the point-to-point vector on the object surface.
  • Angle between the '''r' and 'v' Vectors

When the angle 'α 'is 0, R and V overlap. At this time, the intensity of the highlight is the maximum. When the observer's line of sight gradually leaves, α gradually increases, and the highlight effect gradually decreases. Based on this basis, we will use the dot product operation to obtain the Alpha cosine value, which will be used as a factor when we calculate the highlight. When α is greater than 90 degrees, the cosine value is negative, at this time, there is no highlight effect.

To calculate α, we need two vectors 'r' and 'V '. The 'V' vector can be obtained by using the vertex position of the camera (viewpoint) for illumination reduction. Note that these two positions are in the world coordinate system. For a camera, we need to input its location in the world coordinate system in the shader, and the calculation of the highlight is placed in the shader, which will be the location of the world coordinate system for each element (derived from interpolation) calculate the highlight.

Next let's take a look at how to calculate the light reflection vector 'r' based on the incident light vector I ':

We know that the vector does not have a starting point, and the only vector determines the direction and length. Therefore, as shown in, the incident vector I can be seen as the "copy" to-N direction, in this case, I + V = R. (Note that V here is not the vector from the viewpoint to the vertex, but the vector from the R, also known as V, which is a bit confusing ...), we know that V/2 = N * (-N * I) [that is, the V vector is in the same direction as the n vector, and its length is equal to (-N * I )], all of us have the following formula:

In glsl, a built-in function 'reflect 'is used to calculate the reflection vector. In the shader code below, we use this function.

Let's take a look at the final highlight function:

It is equal to the color of the light source multiplied by the color of the object surface, and then multiplied by the material highlight intensity ('M '), multiply by the cosin value between the reflected light and the vector angle that the camera points to the object to the power of P. If an object has no highlight effect, such as wood, M is 0, and P is called the highlight index, which is usually used as the material attribute of the object, its size determines the Display Effect of the edge of the highlight area. The following figure shows the highlight effect when P is 1:

The figure below shows the effect when P is set to 32:

Main Code:

Lighting_technique.h

class LightingTechnique : public Technique
{
public:
...
    void SetEyeWorldPos(const Vector3f& EyeWorldPos);
    void SetMatSpecularIntensity(float Intensity);
    void SetMatSpecularPower(float Power);
private:
...
    GLuint m_eyeWorldPosLocation;
    GLuint m_matSpecularIntensityLocation;
    GLuint m_matSpecularPowerLocation;

We added three new attributes to the lightingtechnique class: eye position, highlight intensity, and highlight index. These attributes are all set in the light source, but these settings are not very good, for example, different substances in the scenario may have the same highlight effect. We usually regard the highlight intensity and highlight index as the material property. We will see in the following tutorial that, these attributes are treated as vertex attributes.

Lighting_technique.cpp

out vec3 WorldPos0;
void main()
{
    gl_Position = gWVP * vec4(Position, 1.0);
    TexCoord0 = TexCoord;
    Normal0 = (gWorld * vec4(Normal, 0.0)).xyz;
    WorldPos0 = (gWorld * vec4(Position, 1.0)).xyz;
}

A line of code is added to the vertex shader to obtain the position in the vertex world coordinate system, so that it can be used to calculate the highlight in the multipart shader.

in vec3 WorldPos0;
.
.
.
uniform vec3 gEyeWorldPos;
uniform float gMatSpecularIntensity;
uniform float gSpecularPower;
void main()
{
    vec4 AmbientColor = vec4(gDirectionalLight.Color, 1.0f) * gDirectionalLight.AmbientIntensity;
    vec3 LightDirection = -gDirectionalLight.Direction;
    vec3 Normal = normalize(Normal0);
    float DiffuseFactor = dot(Normal, LightDirection);
    vec4 DiffuseColor = vec4(0, 0, 0, 0);
    vec4 SpecularColor = vec4(0, 0, 0, 0);
    if (DiffuseFactor > 0) {
        DiffuseColor = vec4(gDirectionalLight.Color, 1.0f) *
            gDirectionalLight.DiffuseIntensity *
            DiffuseFactor;
        vec3 VertexToEye = normalize(gEyeWorldPos - WorldPos0);
        vec3 LightReflect = normalize(reflect(gDirectionalLight.Direction, Normal));
        float SpecularFactor = dot(VertexToEye, LightReflect);
        SpecularFactor = pow(SpecularFactor, gSpecularPower);
        if (SpecularFactor > 0) {
            SpecularColor = vec4(gDirectionalLight.Color, 1.0f) * gMatSpecularIntensity * SpecularFactor;
        }
    }
    FragColor = texture2D(gSampler, TexCoord0.xy) * (AmbientColor + DiffuseColor + SpecularColor);
}

In the slice shader, we added three uniform variables, which saved the eye position, highlight intensity, and highlight index for calculating the highlight. The ambient light is the same as the method calculated in the previous tutorial. The diffuse light and highlight are initialized to 0. When the angle between the incident light and the object surface is less than 90 degrees, the diffuse light and highlight are calculated respectively. When calculating the highlight, we normalize the direction vector of the light and the vector from the camera to the pixel, and finally obtain the color of the highlight based on the formula. When the pixel color is output, the color of the texture sample and the color of the illumination are mixed to obtain the final color.

Tutorial19.cpp

m_pEffect->SetEyeWorldPos(m_pGameCamera->GetPos());
m_pEffect->SetMatSpecularIntensity(1.0f);
m_pEffect->SetMatSpecularPower(32);

In the render loop, we set the camera position, highlight intensity, and highlight index.

The following is the effect after the program runs. We can select an object to observe the highlight effect:

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.