"DirectX11" Tenth other light type--point light source

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 light types
    • Point Light What is a dot source
      • 1 point Light Preamble source variable preparation
      • 2 Point Light Vertex and Pixel Shader vertex and pixel shader implementation
      • 3 point-light output source effect
      • 4 Point Light Modifications Modify the implementation


About light types

In the previous several articles about lighting model, we mainly introduce some basic illumination models. The calculations mentioned in this article are based on the assumption that there is only parallel light in the environment. Before we introduced, there are many types of lights, including point light, parallel light, Spotlight, etc... The following is a description of the lights except for the parallel light.


Dot Light: What is a point source

The effect of the point light is similar to that of a light bulb, which gives out evenly in all directions, and the point light in the scene is distinguished by its specific position. These are not the same as the light of peace, the parallel light does not have a specific location difference, he is the light from infinity, and there is a unified light direction. In general, the parallel light does not have the difference between moving the light source position, and the point light source does not rotate the light source.
When simulating the effect of a point light source, we can use the same lighting model (including diffuse illumination model and specular illumination model) as in parallel light calculations. But in the point light, we need to give the position of the light source and calculate the direction of the light. The light direction of the point light is also very simple, which is to take the coordinate of the coordinates of the world coordinate system and subtract the coordinates of the object. Represents the calculation process:

In addition, since the point light source has a specific location, you can adjust the light intensity of the surface of the object by distance. The farther away the point light is from the object, the darker the surface of the object. The following code implements the effect when there is only one point light in the scene:
Listing 7.1 pointlight.fx (refer to the eighth article for a reference to the include file common.fxh)

#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 Lightposition:position < String Object ="PointLight0"; String uiname ="Light Position"; String Space ="World"; > = {0.0F0.0F0.0f};floatLightradius < String uiname ="Light Radius"; String uiwidget ="Slider";floatUimin =0.0;floatUimax =100.0;floatUistep =1.0; > = {10.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;    FLOAT4 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); FLOAT3 worldposition = Mul (in.    Objectposition, World). XYZ;    FLOAT3 lightdirection = lightposition-worldposition; Out.    LIGHTDIRECTION.XYZ = normalize (lightdirection); Out. LIGHTDIRECTION.W = Saturate (1.0F-(Length (lightdirection)/lightradius));//attenuationOut. 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 (normal, lightdirection); FLOAT3 Halfvector = normalize (lightdirection + viewdirection);floatN_dot_h = dot (normal, halfvector); FLOAT4 color = colortexture.sample (Colorsampler, in.    Texturecoordinate);    Float4 lightcoefficients = Lit (n_dot_1, n_dot_h, specularpower);    FLOAT3 ambient = get_vector_color_contribution (Ambientcolor, COLOR.RGB); FLOAT3 diffuse = get_vector_color_contribution (Lightcolor, LIGHTCOEFFICIENTS.Y * color.rgb) * in.    LIGHTDIRECTION.W; FLOAT3 specular = get_scalar_color_contribution (Specularcolor, Min (lightcoefficients.z, COLOR.W)) * in.    LIGHTDIRECTION.W;    Out.rgb = ambient + diffuse + specular; OUT.A =1.0FreturnOut;}/*************** Techniques ***************/Technique10 main10{pass P0 {SetVertexShader (Compileshader (Vs_4_0, Vertex_shader ()));        Setgeometryshader (NULL);        SetPixelShader (Compileshader (Ps_4_0, Pixel_shader ()));    Setrasterizerstate (disableculling);    }}FLOAT3 specular = get_scalar_color_contribution (Specularcolor, Min (lightcoefficients.z, COLOR.W));    Out.rgb = ambient + diffuse + specular; OUT.A =1.0FreturnOut;}/*************** Techniques ***************/Technique10 main10{pass P0 {SetVertexShader (Compileshader (Vs_4_0, Vertex_shader ()));        Setgeometryshader (NULL);        SetPixelShader (Compileshader (Ps_4_0, Pixel_shader ()));    Setrasterizerstate (disableculling); }}
(1) Point Light preamble: source Variable Preparation

Most of the code in this code is copied from the code under the Blinn-phong model in the previous article, and if you have a code that you don't understand, you can turn to the previous article.
The lightposition in the Cbufferperframe code block represents the position of the point Light in the world coordinate system in the scene. Lightradius represents the distance at which a point light is acting, beyond which the point light source will have no effect.
Compared with the previous, the vertex shader output structure of the lightdirection from FLOAT3 to Float4, the extra fourth channel is used to store the intensity of light. This means that the intensity and direction of the light are calculated in the vertex shader.

Attention
Saving the light intensity in the W channel in Lightdirection is just to save performance, in which XYZ is sufficient to represent the direction of the light, and w is generally no longer used. Therefore, instead of taking a single variable in the output structure for this data, save it directly in W. But the intensity of light is not related to the direction of light.
(2) Point Light Vertex and Pixel Shader: implementation of vertex and pixel shader

In the vertex shader, the direction of the light is calculated and saved in XYZ of the lightdirection variable. The light intensity is calculated by the following formula:

The lightdirection in the formula is calculated directly from the vertex coordinates and the position of the light source, and is not yet flat, so the light intensity ratio can be obtained by dividing by Lightradius. The computed attenuation is guaranteed to be no less than 0 by the saturate function.
The pixel shader does not require special processing to directly add the light intensity calculated in the vertex shader to the calculation of diffuse and specular highlights.

(3) Point Light output: effect

The display of a scene with only a little light source is shown, and the sphere on the left is closer to the point, and farther from the right. The yellow wireframe in the figure represents the location of a point light:

(4) Point Light Modifications: the implementation of the modified spot lighting

You can see the difference in the highlight point effect from the left and right graphs below, because some of the flaws that occur when you use the vertex shader to calculate the point light. This flaw only occurs when the point light source is very close to the surface of the model, and this time the light vectors will be more different from the vertices when they are calculated from the vertices, and the pixels between the vertices will continue to use these light vector data computed on the vertices.

Code Snippet Listing 7.2 pointlight-imp.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 Lightposition:position < String Object ="PointLight0"; String uiname ="Light Position"; String Space ="World"; > = {0.0F0.0F0.0f};floatLightradius < String uiname ="Light Radius"; String uiwidget ="Slider";floatUimin =0.0;floatUimax =100.0;floatUistep =1.0; > = {10.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 Worldposition:texcoord1; FLOAT3 Attenuation:texcoord2;};/*************** Vertex Shader ***************/Vs_output Vertex_shader (Vs_input in) {vs_output out = (vs_output)0; Out. Position = Mul (in.    Objectposition, worldviewprojection); Out. Worldposition = Mul (in.    Objectposition, World). XYZ; Out. Texturecoordinate = Get_corrected_texture_coordinate (in.    Texturecoordinate); Out. Normal = Normalize (Mul (FLOAT4 (in. Normal,0), world). xyz); FLOAT3 lightdirection = lightposition-out.    Worldposition; Out. Attenuation = saturate (1.0F-(Length (lightdirection)/lightradius));returnOut;}/*************** Pixel Shader ***************/FLOAT4 Pixel_shader (Vs_output in): sv_target{float4 out = (FLOAT4)0; FLOAT3 normal = normalize (in.    Normal); FLOAT3 lightdirection = Normalize (lightposition-in.    Worldposition); FLOAT3 viewdirection = Normalize (cameraposition-in. Worldposition);floatN_dot_1 = dot (normal, lightdirection); FLOAT3 Halfvector = normalize (lightdirection + viewdirection);floatN_dot_h = dot (normal, halfvector); FLOAT4 color = colortexture.sample (Colorsampler, in.    Texturecoordinate);    Float4 lightcoefficients = Lit (n_dot_1, n_dot_h, specularpower);    FLOAT3 ambient = get_vector_color_contribution (Ambientcolor, COLOR.RGB); FLOAT3 diffuse = get_vector_color_contribution (Lightcolor, LIGHTCOEFFICIENTS.Y * color.rgb) * in.    attenuation; FLOAT3 specular = get_scalar_color_contribution (Specularcolor, Min (lightcoefficients.z, COLOR.W)) * in.    attenuation;    Out.rgb = ambient + diffuse + specular; OUT.A =1.0FreturnOut;}/*************** Techniques ***************/Technique10 main10{pass P0 {SetVertexShader (Compileshader (Vs_4_0, Vertex_shader ()));        Setgeometryshader (NULL);        SetPixelShader (Compileshader (Ps_4_0, Pixel_shader ()));    Setrasterizerstate (disableculling); }}

In this code, the light vector and line-of-sight vectors are computed in the pixel shader, which increases the amount of computation, but it also shows finer results. However, the light intensity is not added to the pixel shader because the intensity of the light between the two vertices is not much worse when the distance is close enough. Although this calculates the direction of the light two times, once in order to calculate the intensity of the light in the vertex shader, one time is to calculate the direction of light on each pixel in the pixel shader. But it also saves a bit more performance than moving all the calculations to the pixel shader.

"DirectX11" Tenth other light type--point light source

Related Article

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.