The calculation of illumination in GLSL

Source: Internet
Author: User
Tags cos reflector

Theoretical knowledge reprint Address: http://blog.csdn.net/ym19860303/article/details/25545933

1.Lambert model (Diffuse reflection)

Ambient light:

Iambdiff = Kd*ia

Wherein IA indicates ambient light intensity, Kd (0<k<1) is the reflective coefficient of the material to ambient light, and Iambdiff is the light intensity that the diffuse reflector interacts with the ambient light.

Directional Light:

Ildiff = Kd * Il * Cos (θ)

Where IL is the intensity of the point light source, θ is the angle of the incident light direction and the vertex normal, called the angle of incidence (0<=a<=90°), Ildiff is the diffuse reflector and direction light interactive reflection of the light intensity, if n is the vertex unit normal vector, L represents the unit vector from the vertex to the light source (note vertex points to the light), The cos (θ) is equivalent to dot (n,l), so there are:

Ildiff = Kd * Il * DOT (n,l)

Finally, the Lambert illumination model can be written as a combination of ambient light and directional light source:

Idiff = Iambdiff + Ildiff = kd * Ia + Kd * Il * DOT (n,l)

2.Phong model (Specular reflection)

The Phong model considers that specular light intensity is related to the angle of reflection light and line of sight:

Ispec = Ks * Il * (dot (v,r)) ^ns

Where KS is a specular reflection coefficient, NS is a high-light index, v represents the viewing direction from vertex to viewpoint, and R represents the direction of reflected light. Because the direction of the reflected light r can be obtained by the incident light Direction L (from the vertex point to the light source) and the object's normal vector,
r + L = 2 * DOT (n, L) * n i.e. R = 2 * DOT (n,l) * n-l

So the final formula is:

Ispec = Ks * Il * (dot (V, (2 * DOT (n,l) * n–l)) ^ns

3.blinn-phong Illumination model (fixed specular light)

Blinn-phong is a model modified based on the Phong model with the following formula:

Ispec = Ks * Il * (dot (n,h)) ^ns

where n is the unit normal vector of the entry, H is the intermediate vector of the light incident direction L and the direction V of the viewpoint, often referred to as the half-width vector (half-width vectors are widely used in various illumination models, not only because of the information value contained in the half-width vector, but also because the half-width vector is very simple:  L + v| )。

4.Rendering equation (global illumination model)

Rendering equation was proposed by Kajia in 1986,

Lo (x, wo) = Le (x, wo) +∫fr (x, WI, wo) Li (x, WI) dot (N, WI) dWi

where x represents entry, Lo (x, wo) is the light intensity reflected from the surface of the object x points along the direction of Wo, Le (x, wo) represents the intensity of the light emitted from the object surface x in the direction Wo, which is only valid for the self-luminous body, fr (x, WI, wo), the incident light direction is Wi And then from the wo direction emitted from the BRDF value, Li (X, WI) for the incident direction of Wi irradiation to the incident light on the X-ray intensity, n represents the normal vector at point X, and then to the incident direction of the integral (because the direction of the incident light is in all directions, the meaning of the integral is calculated after each direction), The result of the calculation is the radiation rate of the global illumination.

For a single point light to illuminate an object that does not emit self-illumination, the formula can be simplified into:

Lo (x, wo) = fr (x, WI, wo) Li (x, WI) dot (N, WI)

This formula is useful and usually decomposes the formula into the sum of the diffuse and specular expressions. For diffuse surfaces, BRDF can be ignored because it always returns a constant value, so it can be written as follows:

Lo (x, Wo) = Idiff + FRS (x, WI, wo) Li (x, WI) dot (N, WI)

Wherein the IDIFF represents diffuse reflection component, using the calculation method of the formula, FRS (X, Wi, Wo) represents the BRDF function of specular reflection, the front of the Phong high-light model, in fact, rendering equation in a single light source for the ideal specular reflection of the specific deduction, For Phong Highlights:

FRS (X, WI, Wo) = Ks (dot (n, H) ^ns/dot (n, WI)

GLSL-based implementations (all lighting and material parameters should be changed from constant to uniform and externally controlled) when applied in practice:

Processing lighting calculations in a vertex shader (ambient light + diffuse light + specular reflection)
Const char* CCPOSITIONTEXTURECOLORFORLIGHT1_V = "\
Uniform VEC2 translate; \n\
\n\
Attribute Vec4 a_position; \n\
Attribute Vec4 A_color; \n\
Attribute VEC2 A_texcoord; \n\
Attribute VEC3 A_normal; \n\
\n\
#ifdef Gl_es \n\
Varying mediump vec4 v_color; \n\
Varying mediump vec2 V_texcoord; \n\
#else \n\
Varying VEC4 v_color; \n\
Varying VEC2 V_texcoord; \n\
#endif \n\
\n\
Const VEC3 lightambient = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Lightdiffuse = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Lightspecular = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 materialambient = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Materialdiffuse = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Materialspecular = VEC3 (1.0, 1.0, 1.0); \n\
const int shininess = 8; 0-128 \n\
\n\
Const VEC3 eyeposition = VEC3 (512.0, 128.0, 442.0); \n\
Const VEC3 lightdirection = VEC3 (1.0, 1.0, 1.0); \n\
\n\
Voidmain () {\n\
VEC4 position = Cc_mvmatrix * a_position; \n\
Position.x + = translate.x; \n\
POSITION.Y + = Translate.y; \n\
gl_position = Cc_pmatrix * Position; \n\
\n\
VEC3 normal = (Cc_mvmatrix * VEC4 (A_normal, 1.0)). xyz; \n\
VEC3 N_normal = normalize (normal); \n\
VEC3 n_lightdirection = normalize (lightdirection); \n\
float COSNL = max (dot (n_normal, n_lightdirection), 0.0); \n\
VEC4 diffuse = VEC4 (Lightdiffuse * materialdiffuse, 1.0) * COSNL; \n\
\n\
VEC4 ambient = VEC4 (Lightambient * materialambient, 1.0); \n\
\n\
VEC3 n_eyeposition = normalize (EYEPOSITION-POSITION.XYZ); \n\
VEC3 reflection = 2 * MAX (dot (n_normal, n_lightdirection), 0.0) * n_normal-n_lightdirection; \n\
VEC4 specular = VEC4 (lightspecular * materialspecular * POW (max (dot (n_eyeposition, reflection), 0.0), shininess), 1.0); \n\
\n\
V_color = A_color * (diffuse + ambient + specular); \n\
V_texcoord = A_texcoord; \n\
} \n\
";
Const char* Ccpositiontexturecolorforlight1_f = "\
#ifdef Gl_es \n\
Precision LOWP float; \n\
#endif \n\
\n\
Varying VEC4 v_color; \n\
Varying VEC2 V_texcoord; \n\
\n\
void Main () {\n\
VEC4 color = V_color * TEXTURE2D (CC_TEXTURE0, V_texcoord); \n\
COLOR.A = 1.0; \n\
\n\
Gl_fragcolor = color; \n\
} \n\
";

Effect:

Working with light calculations in the fragment shader (ambient light + diffuse + specular reflection)
Const char* CCPOSITIONTEXTURECOLORFORLIGHT2_V = "\
Uniform VEC2 translate; \n\
\n\
Attribute Vec4 a_position; \n\
Attribute Vec4 A_color; \n\
Attribute VEC2 A_texcoord; \n\
Attribute VEC3 A_normal; \n\
\n\
#ifdef Gl_es \n\
Varying mediump vec4 v_position; \n\
Varying mediump vec4 v_color; \n\
Varying mediump vec2 V_texcoord; \n\
Varying mediump vec3 v_normal; \n\
#else \n\
Varying VEC4 v_position; \n\
Varying VEC4 v_color; \n\
Varying VEC2 V_texcoord; \n\
Varying VEC3 v_normal; \n\
#endif \n\
\n\
Voidmain () {\n\
VEC4 position = Cc_mvmatrix * a_position; \n\
Position.x + = translate.x; \n\
POSITION.Y + = Translate.y; \n\
gl_position = Cc_pmatrix * Position; \n\
\n\
V_position = position; \n\
V_color = A_color; \n\
V_texcoord = A_texcoord; \n\
V_normal = (Cc_mvmatrix * VEC4 (A_normal, 1.0)). xyz; \n\
} \n\
";
Const char* Ccpositiontexturecolorforlight2_f = "\
Const VEC3 lightambient = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Lightdiffuse = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Lightspecular = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 materialambient = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Materialdiffuse = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Materialspecular = VEC3 (1.0, 1.0, 1.0); \n\
const int shininess = 8; 0-128 \n\
\n\
Const VEC3 eyeposition = VEC3 (512.0, 128.0, 442.0); \n\
Const VEC3 lightdirection = VEC3 (1.0, 1.0, 1.0); \n\
\n\
#ifdef Gl_es \n\
Precision LOWP float; \n\
#endif \n\
\n\
Varying VEC4 v_position; \n\
Varying VEC4 v_color; \n\
Varying VEC2 V_texcoord; \n\
Varying VEC3 v_normal; \n\
\n\
void Main () {\n\
VEC4 color = V_color * TEXTURE2D (CC_TEXTURE0, V_texcoord); \n\
COLOR.A = 1.0; \n\
\n\
VEC3 normal = V_normal; \n\
VEC3 N_normal = normalize (normal); \n\
VEC3 n_lightdirection = normalize (lightdirection); \n\
float COSNL = max (dot (n_normal, n_lightdirection), 0.0); \n\
VEC4 diffuse = VEC4 (Lightdiffuse * materialdiffuse, 1.0) * COSNL; \n\
\n\
VEC4 ambient = VEC4 (Lightambient * materialambient, 1.0); \n\
\n\
VEC3 n_eyedirection = normalize (EYEPOSITION-V_POSITION.XYZ); \n\
VEC3 reflection = 2 * MAX (dot (n_normal, n_lightdirection), 0.0) * n_normal-n_lightdirection; \n\
VEC4 specular = VEC4 (lightspecular * materialspecular * POW (max (dot (n_eyedirection, reflection), 0.0), shininess), 1.0); \n\
VEC3 reflection = Normalize (n_eyedirection + n_lightdirection); \n\
VEC4 specular = VEC4 (lightspecular * materialspecular * POW (max (dot (N_normal, reflection), 0.0), shininess), 1.0); \n\
\n\
Gl_fragcolor = Color * (ambient + diffuse + specular); \n\
} \n\
";

Effect:

Processing light calculations in a fragment shader (ambient light + diffuse + specular + attenuation factor)
Const char* CCPOSITIONTEXTURECOLORFORLIGHT3_V = "\
Uniform VEC2 translate; \n\
\n\
Attribute Vec4 a_position; \n\
Attribute Vec4 A_color; \n\
Attribute VEC2 A_texcoord; \n\
Attribute VEC3 A_normal; \n\
\n\
#ifdef Gl_es \n\
Varying mediump vec4 v_position; \n\
Varying mediump vec4 v_color; \n\
Varying mediump vec2 V_texcoord; \n\
Varying mediump vec3 v_normal; \n\
varying float v_distance; \n\
#else \n\
Varying VEC4 v_position; \n\
Varying VEC4 v_color; \n\
Varying VEC2 V_texcoord; \n\
Varying VEC3 v_normal; \n\
varying float v_distance; \n\
#endif \n\
\n\
Voidmain () {\n\
VEC4 position = Cc_mvmatrix * a_position; \n\
Position.x + = translate.x; \n\
POSITION.Y + = Translate.y; \n\
gl_position = Cc_pmatrix * Position; \n\
\n\
V_position = position; \n\
V_color = A_color; \n\
V_texcoord = A_texcoord; \n\
V_normal = (Cc_mvmatrix * VEC4 (A_normal, 1.0)). xyz; \n\
} \n\
";
Const char* Ccpositiontexturecolorforlight3_f = "\
Const VEC3 lightambient = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Lightdiffuse = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Lightspecular = VEC3 (1.0, 1.0, 1.0); \n\
Const float LIGHTATTENUATIONCONST = 1.0; \n\
const float lightattenuationlinear = 0.0002; \n\
const float lightattenuationquadratic = 0.000001; \n\
Const VEC3 materialambient = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Materialdiffuse = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Materialspecular = VEC3 (1.0, 1.0, 1.0); \n\
const int shininess = 8; 0-128 \n\
\n\
Const VEC3 lightposition = VEC3 (1024.0, 512.0, 100.0); \n\
Const VEC3 eyeposition = VEC3 (512.0, 256.0, 442.0); \n\
\n\
#ifdef Gl_es \n\
Precision LOWP float; \n\
#endif \n\
\n\
Varying VEC4 v_position; \n\
Varying VEC4 v_color; \n\
Varying VEC2 V_texcoord; \n\
Varying VEC3 v_normal; \n\
varying float v_distance; \n\
\n\
void Main () {\n\
VEC4 color = V_color * TEXTURE2D (CC_TEXTURE0, V_texcoord); \n\
COLOR.A = 1.0; \n\
\n\
VEC3 lightdirection = lightposition-v_position.xyz; \n\
float distance = length (lightdirection); \n\
float Atten = 1.0/(Lightattenuationconst + lightattenuationlinear * distance + lightattenuationquadratic * distance * di Stance); \n\
\n\
VEC3 normal = V_normal; \n\
VEC3 N_normal = normalize (normal); \n\
VEC3 n_lightdirection = normalize (lightdirection); \n\
float COSNL = max (dot (n_normal, n_lightdirection), 0.0); \n\
VEC4 diffuse = VEC4 (Lightdiffuse * materialdiffuse, 1.0) * COSNL; \n\
\n\
VEC4 ambient = VEC4 (Lightambient * materialambient, 1.0); \n\
\n\
VEC3 n_eyedirection = normalize (EYEPOSITION-V_POSITION.XYZ); \n\
VEC3 reflection = 2 * MAX (dot (n_normal, n_lightdirection), 0.0) * n_normal-n_lightdirection; \n\
VEC4 specular = VEC4 (lightspecular * materialspecular * POW (max (dot (n_eyedirection, reflection), 0.0), shininess), 1.0); \n\
VEC3 reflection = Normalize (n_eyedirection + n_lightdirection); \n\
VEC4 specular = VEC4 (lightspecular * materialspecular * POW (max (dot (N_normal, reflection), 0.0), shininess), 1.0); \n\
\n\
float Colora = COLOR.A; \n\
Gl_fragcolor = VEC4 (Color.rgb * (ambient + diffuse + specular). XYZ * Atten, Colora); \n\
} \n\
";

Effect:

Processing light calculations in a fragment shader (ambient light + diffuse + specular + spotlight + attenuation factor)
Const char* CCPOSITIONTEXTURECOLORFORLIGHT4_V = "\
Uniform VEC2 translate; \n\
Const VEC3 spotlightposition = VEC3 (512.0, 256.0, 120.0); \n\
Const VEC3 lightposition = VEC3 (512.0, 256.0, 442.0); \n\
Const VEC3 eyeposition = VEC3 (512.0, 256.0, 442.0); \n\
\n\
Attribute Vec4 a_position; \n\
Attribute Vec4 A_color; \n\
Attribute VEC2 A_texcoord; \n\
Attribute VEC3 A_normal; \n\
\n\
#ifdef Gl_es \n\
Varying mediump vec4 v_position; \n\
Varying mediump vec4 v_color; \n\
Varying mediump vec2 V_texcoord; \n\
Varying mediump vec3 v_normal; \n\
Varying mediump float v_distance; \n\
Varying mediump vec3 v_lightdirection; \n\
Varying mediump vec3 v_spotlightdirection; \n\
#else \n\
Varying VEC4 v_position; \n\
Varying VEC4 v_color; \n\
Varying VEC2 V_texcoord; \n\
Varying VEC3 v_normal; \n\
varying float v_distance; \n\
Varying VEC3 v_lightdirection; \n\
Varying VEC3 v_spotlightdirection; \n\
#endif \n\
\n\
Voidmain () {\n\
VEC4 position = Cc_mvmatrix * a_position; \n\
Position.x + = translate.x; \n\
POSITION.Y + = Translate.y; \n\
gl_position = Cc_pmatrix * Position; \n\
\n\
V_position = position; \n\
V_color = A_color; \n\
V_texcoord = A_texcoord; \n\
V_normal = (Cc_mvmatrix * VEC4 (A_normal, 1.0)). xyz; \n\
\n\
VEC3 lightdirection = lightposition-position.xyz; \n\
VEC3 spotlightdirection = spotlightposition-position.xyz; \n\
v_distance = Length (lightdirection); \n\
V_lightdirection = normalize (lightdirection); \n\
V_spotlightdirection = normalize (spotlightdirection); \n\
} \n\
";
Const char* Ccpositiontexturecolorforlight4_f = "\
Const VEC3 lightambient = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Lightdiffuse = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Lightspecular = VEC3 (1.0, 1.0, 1.0); \n\
Const float LIGHTATTENUATIONCONST = 1.0; \n\
const float lightattenuationlinear = 0.001; \n\
const float lightattenuationquadratic = 0.000001; \n\
Const VEC3 materialambient = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Materialdiffuse = VEC3 (1.0, 1.0, 1.0); \n\
Const VEC3 Materialspecular = VEC3 (1.0, 1.0, 1.0); \n\
const int shininess = 8; 0-128 \n\
const int lightspotexponent = 1; \n\
const FLOAT lightspotcoscutoff = cos (45.0/180.0 * 3.1415926); \n\
\n\
Const VEC3 lightposition = VEC3 (512.0, 256.0, 442.0); \n\
Const VEC3 eyeposition = VEC3 (512.0, 256.0, 442.0); \n\
\n\
#ifdef Gl_es \n\
Precision LOWP float; \n\
#endif \n\
\n\
Varying VEC4 v_position; \n\
Varying VEC4 v_color; \n\
Varying VEC2 V_texcoord; \n\
Varying VEC3 v_normal; \n\
varying float v_distance; \n\
Varying VEC3 v_lightdirection; \n\
Varying VEC3 v_spotlightdirection; \n\
\n\
void Main () {\n\
VEC4 color = V_color * TEXTURE2D (CC_TEXTURE0, V_texcoord); \n\
COLOR.A = 1.0; \n\
\n\
VEC3 lightdirection = lightposition-v_position.xyz; \n\
VEC3 n_spotdirection = Normalize (LIGHTPOSITION-VEC3 (512.0, 256.0, 0.0)); \n\
VEC3 n_spotlightdirection = normalize (v_spotlightdirection); \n\
float distance = length (lightdirection); \n\
float Atten = 1.0/(lightattenuationconst + lightattenuationlinear * v_distance + lightattenuationquadratic * v_distance * v_distance); \n\
\n\
VEC3 normal = V_normal; \n\
VEC3 N_normal = normalize (normal); \n\
VEC3 n_lightdirection = normalize (v_lightdirection); \n\
float COSNL = max (dot (n_normal, n_lightdirection), 0.0); \n\
VEC4 diffuse = VEC4 (Lightdiffuse * materialdiffuse, 1.0) * COSNL; \n\
\n\
VEC4 ambient = VEC4 (Lightambient * materialambient, 1.0); \n\
\n\
VEC3 n_eyedirection = normalize (EYEPOSITION-V_POSITION.XYZ); \n\
VEC3 reflection = 2 * MAX (dot (n_normal, n_lightdirection), 0.0) * n_normal-n_lightdirection; \n\
VEC4 specular = VEC4 (lightspecular * materialspecular * POW (max (dot (n_eyedirection, reflection), 0.0), shininess), 1.0); \n\
VEC3 reflection = Normalize (n_eyedirection + n_lightdirection); \n\
VEC4 specular = VEC4 (lightspecular * materialspecular * POW (max (dot (N_normal, reflection), 0.0), shininess), 1.0); \n\
\n\
float Cosspot = dot ( -1 * n_spotdirection,-1 * n_spotlightdirection); \n\
if (Cosspot > Lightspotcoscutoff) \n\
{\n\
float Spoteffect = Pow (cosspot, lightspotexponent); \n\
Atten + = Spoteffect; \n\
} \n\
float Colora = COLOR.A; \n\
Gl_fragcolor = VEC4 (Color.rgb * (ambient + diffuse + specular). XYZ * Atten, Colora); \n\
} \n\
";

Effect:

The calculation of illumination in GLSL

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.