3D Programming: Diffuse lighting (diffuse reflection light)

Source: Internet
Author: User
Tags constant contains data structures header include mul reflection

Diffuse lighting (diffuse reflection light)

Different materials have different ways of reflecting light on the surface. The reflection angle of mirror glazing is equal to the angle of the body. When a strange glow is seen in the eyes of a cat, this is the reflection of light: This is because the cat's eyes reflect light in a direction parallel to the light source, but in opposite directions. The reflection of the diffuse surface is the same in all directions.

The simplest and most commonly used model for approximately calculating a diffuse light is Lambert's cosine law (Lambert's cosine). According to Lambert's cosine, the brightness of illumination to the surface of the material is proportional to the cosine of the angle between the direction vector and the normal of the light source. The light source vector describes the direction of illumination, and the normal vector determines the orientation of the surface. Figure 6.3 illustrates these terms.

Figure 6.3 An illustration of a surface normal, a light vector, and Lambert ' s cosine.

Recall the second chapter, "A 3d/math Primer", the vector operation discussed, the dot product of the vector can get the cosine of the angle between the light vector and the normal vector (both vectors are unit vectors). In general, the normal vector is provided by each vertex (or computed by the cross-product of the triangle two edges) when the 3D object is loaded.

Directional Lights

Three common sources of light are defined in 3D graphics: directional lights,point lights,spotlights (directional light, point Light, Spotlight). A directional light represents a light source that is away from the 3D objects infinity, meaning that there is no coordinate position relative to the objects. So the light that shines on the objects is parallel, coming from the same direction. A good example of directional light is the sun (though not the infinity in the strict sense). Figure 6.4 depicts the concept of direction light.

Figure 6.4 An illustration of a directional light.

To simulate a directional light, simply define the direction of the light with a three-dimensional vector. It can also be like ambient light, including the color and intensity of the light. Listing 6.2 lists a diffuse lighting effect code that uses a simple directional light. This book is very limited, it is recommended to copy the code to the Nvidia FX composer, step-by-step testing of the lighting effect. (You can also download the code from the companion website of this book)

List 6.2 diffuselighting.fx

#include "include\\common.fxh"/************* resources *************/cbuffer cbufferperframe {float4 Ambientcolor:
		Ambient < string uiname = "Ambient Light";
	String uiwidget = "Color";

	> = {1.0f, 1.0f, 1.0f, 0.0f};
		FLOAT4 Lightcolor:color < string Object = "LightColor0";
		String uiname = "Light Color";
	String uiwidget = "Color";

	> = {1.0f, 1.0f, 1.0f, 1.0f};
		FLOAT3 Lightdirection:direction < string Object = "DirectionalLight0";
		String uiname = "Light Direction";
	String space = "the World";
> = {0.0f, 0.0f, -1.0f};
	} cbuffer cbufferperobject {float4x4 worldviewprojection:worldviewprojection < string uiwidget= ' None '; >; float4x4 World:world < string uiwidget= "None";
>;
    } 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;

};
	
    /************* 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);
return out;
	
	/************* Pixel Shader *************/float4 pixel_shader (vs_output in): sv_target {float4 out = (float4) 0; FLOAT3 normal = normalize (in.
    Normal); FLOAT3 lightdirection = Normalize (in. LightdirectION);

	float n_dot_l = dot (lightdirection, normal); FLOAT4 color = colortexture.sample (Colorsampler, in.
	Texturecoordinate);

	FLOAT3 ambient = Ambientcolor.rgb * AMBIENTCOLOR.A * COLOR.RGB;
	
	FLOAT3 diffuse = (FLOAT3) 0;
	if (n_dot_l > 0) {diffuse = Lightcolor.rgb * LIGHTCOLOR.A * n_dot_l * COLOR.RGB;
	} Out.rgb = ambient + diffuse;
	
	OUT.A = COLOR.A;
return out; }/************* Techniques *************/technique10 Main10 {pass P0 {SetVertexShader (compileshader
		4_0, Vertex_shader ()));
        Setgeometryshader (NULL);                
			
		SetPixelShader (Compileshader (Ps_4_0, Pixel_shader ()));
    Setrasterizerstate (disableculling);
 }
}

Diffuse Lighting Effect Preamble

The first line of the DIFFUSELIGHTING.FX code uses a C-style #include method that contains a header file that provides common functions for increasingly rich effects. Listing 6.3 Lists the contents of the header file Common.fxh, the header file with the _COMMON_FXH macro definition, and the flip_texture_y macros and get_corrected_texture_ that were transferred from the previous code. Coordinate () function.

List 6.3 Common.fxh

 #ifndef _common_fxh #define _COMMON_FXH/************* Constants *************/#define FLIP_TEXTURE_Y 1/******* Utility functions *************/float2 get_corrected_texture_coordinate (float2 texturecoordinate) {#if flip_ 
    Texture_y return Float2 (texturecoordinate.x, 1.0-texturecoordinate.y); 
    #else return texturecoordinate; #endif} float3 Get_vector_color_contribution (float4 light, float3 color) {//color (. RGB) * intensity (. a) Retu
RN Light.rgb * LIGHT.A * color; FLOAT3 Get_scalar_color_contribution (float4 light, float color) {//color (. RGB) * intensity (. A) return light
. RGB * LIGHT.A * color; } #endif/* _common_fxh * * 

Additional attention is paid to the two new Cbufferperframe members: Lightcolor and Lightdirection. Lightcolor constants have the same functionality as Ambientcolor: used to represent the color and intensity of the directional light. Lightdirection stores the direction of the light source in world spaces. These two new shader constants have corresponding object annotations, which means that the variable can be bound to a oject in the scene in the Nvidia FX composer. Specifically, you can place the light source in the render panel of the Nvidia FX composer and associate these lights with the shader constants with the object annotation.

The last thing to note is the addition of the world variable in the cbufferperobject. The value of the variable is related to the newly added normal member variable in the VS_INPUT structure body. Like the vertices of object, the normals of faces are stored in object space. The diffuse color of the computed pixel is dot-product by the normal vector and the direction vector of the light, but because the direction of the light source is in world space, the normal vector is transformed into the Wrold space, and the world matrix is used for this transformation. The combination matrix world-view-projection is not used to transform because the matrix is transformed to homogeneous space and not just the world. The world matrix may contain scaling transformations, while the surface's normal vector must be a normalized vector; therefore, the normalizing (normalization) must be performed after the transformation.

Diffuse lighting Vertex Shader

Next, explain the two new member variables of the VS_OUTPUT structure: normal and lightdirection. Normal is used to pass the transformed surface normal vector from the CPU, and lightdirection is somewhat special because there is a shader constant called lightdirection. Lightdirection shader constant is a global variable that stores the direction of the light source, while the Lightdirection member in Vs_output represents the direction of light on the object surface. Therefore, the global lightdirection is reversed in the vertex shader and assigned to the corresponding output member lightdirection. Of course, you can compute the correct direction of light in the CPU and pass it to the vertex shader, so that you do not have to take a reverse operation in vertex shader. However, in the case of using Nvidia FX composer, this must be done because the data of the illumination is sent to the shader by the FX composer, and to get the correct preview effect in the render panel it is necessary to reverse the direction vector of the light in shader. On the lightdirection, also carried out normalize () operation, which is to ensure that the light direction vector is standardized, if you can ensure that the data passed from the CPU is already standardized, you can omit normalize ().

Diffuse lighting Pixel Shader

Although there are some similarities with the ambient lighting effect, diffuse lighting pixel (see listing 6.4) contains more new code.

List 6.4 The Pixel Shader from diffuselighting.fx

FLOAT4 Pixel_shader (Vs_output in): Sv_target
{
	float4 out = (float4) 0;
	
	FLOAT3 normal = normalize (in. Normal);
    FLOAT3 lightdirection = Normalize (in. lightdirection);
	float n_dot_l = dot (lightdirection, normal);

	FLOAT4 color = colortexture.sample (Colorsampler, in. Texturecoordinate);
	FLOAT3 ambient = Ambientcolor.rgb * AMBIENTCOLOR.A * COLOR.RGB;

	FLOAT3 diffuse = (FLOAT3) 0;
	
	if (n_dot_l > 0)
	{
		diffuse = Lightcolor.rgb * LIGHTCOLOR.A * n_dot_l * COLOR.RGB;
	}
	
	Out.rgb = ambient + diffuse;
	OUT.A = COLOR.A;
	
	return out;
}

First, two local variables color and ambient were introduced for textrue sampling and calculation of the ambient. Although there is a little improvement, it is basically the same as the previous steps; The ambient variables are separated to compute the final pixel color.

Next, introduce the member variables of the input parameters normal and lightdirection normalization. The data passed to the rasterizer phase is interpolated, and the operation causes the vectors to become non-standard. As with the corresponding visual effects, the errors caused by interpolation operations are small. Therefore, if the performance is more stringent requirements, simply omit these normalization operations can be.

Next, assign the dot product result of the light direction and surface normal vector to the local variable n_dot_l to compute the diffuse color below. where if-statement (if condition statement) ensures that the value of the variable n_dot_l is greater than 0. If dot product is negative, the light source is on the back of the surface, so no calculation is required. The correct dot product value should be between 0.0 and 1.0. A value of 0.0 indicates that the orientation of the light source is parallel to the surface (there is no illumination effect), and a value of 1.0 indicates that the light direction is perpendicular to the surface (the illumination is the most intense). The value of the local variable diffuse is multiplied by the sampled color and directional light color,intensity and the dot product previously computed.

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.