• Skip to main content
  • Skip to primary sidebar

Anastasios Chondrogiannis

Software developer with a focus on iOS

Android OpenGL ES – Part 10: Specular lighting

March 25, 2020 by Anastasios Chondrogiannis Leave a Comment

In order to apply specular lighting you will need 4 additional pieces of information:

  1. The fragment position.
  2. The camera position.
  3. The specular intensity of the pyramid material.
  4. The shininess of the pyramid material.

1. Add the fragment position

1.1. Modify the vertex shader

  • Open the main.cpp file.
  • Modify the fragment shader source code as follows:
static const GLchar vertexShaderSource[] =
   "#version 310 es\n"
   "layout (location = 0) in vec3 pos;\n"
   "layout (location = 1) in vec2 texCoords;\n"
   "layout (location = 2) in vec3 norm;\n"
   "out vec4 vColor;\n"
   "out vec2 vTexCoords;\n"
   "out vec3 vNorm;\n"
   "out vec3 vFragPos;\n"
   "uniform mat4 model;\n"
   "uniform mat4 projection;\n"
   "uniform mat4 view;\n"
   "void main()\n"
   "{\n"
   "gl_Position = projection * view * model * vec4(pos, 1.0);\n"
   "vColor = vec4(clamp(pos, 0.0, 1.0), 1.0);\n"
   "vTexCoords = texCoords;\n"
   "vNorm = mat3(transpose(inverse(model))) * norm;\n"
   "vFragPos = (model * vec4(pos, 1.0)).xyz;\n"
   "}\n";

1.2. Modify the fragment shader

static const GLchar fragmentShaderSource[] =
   "#version 310 es\n"
   "precision mediump float;\n"
   "in vec4 vColor;\n"
   "in vec2 vTexCoords;\n"
   "in vec3 vNorm;\n"
   "in vec3 vFragPos;\n"
   "out vec4 color;\n"
   "struct DirectionalLight\n"
   "{\n"
   "vec3 color;\n"
   "float intensity;\n"
   "vec3 direction;\n"
   "float diffuseIntensity;\n"
   "};\n"
   "uniform sampler2D textureSampler;\n"
   "uniform DirectionalLight directionalLight;\n"
   "void main()\n"
   "{\n"
   "vec4 ambientColor = vec4(directionalLight.color, 1.0f) * directionalLight.intensity;\n"
   "float diffuseFactor = max(dot(normalize(vNorm), normalize(directionalLight.direction)), 0.0f);\n"
   "vec4 diffuseColor = vec4(directionalLight.color, 1.0f) * directionalLight.diffuseIntensity * diffuseFactor;\n"
   "color = texture(textureSampler, vTexCoords) * (ambientColor + diffuseColor);\n"
   "}\n";

2. Add the material

2.1. Modify the fragment shader

  • Modify the fragment shader source code as follows:
static const GLchar fragmentShaderSource[] =
   "#version 310 es\n"
   "precision mediump float;\n"
   "in vec4 vColor;\n"
   "in vec2 vTexCoords;\n"
   "in vec3 vNorm;\n"
   "in vec3 vFragPos;\n"
   "out vec4 color;\n"
   "struct DirectionalLight\n"
   "{\n"
   "vec3 color;\n"
   "float intensity;\n"
   "vec3 direction;\n"
   "float diffuseIntensity;\n"
   "};\n"
   "struct Material\n"
   "{\n"
   "float specularIntensity;\n"
   "float shininess;\n"
   "};\n"
   "uniform sampler2D textureSampler;\n"
   "uniform DirectionalLight directionalLight;\n"
   "uniform Material material;\n"
   "void main()\n"
   "{\n"
   "vec4 ambientColor = vec4(directionalLight.color, 1.0f) * directionalLight.intensity;\n"
   "float diffuseFactor = max(dot(normalize(vNorm), normalize(directionalLight.direction)), 0.0f);\n"
   "vec4 diffuseColor = vec4(directionalLight.color, 1.0f) * directionalLight.diffuseIntensity * diffuseFactor;\n"
   "color = texture(textureSampler, vTexCoords) * (ambientColor + diffuseColor);\n"
   "}\n";

2.2. Set the uniform variables

  • Declare the following global variables:
/* code */

GLint uniformLightColor, uniformLightIntensity, uniformLightDirection, uniformDiffuseLightIntensity;
GLint uniformMaterialSpecularIntensity, uniformMaterialShininess;
glm::mat4 projectionMatrix;

/* code */
  • Modify the createProgram function as follows:
/* code */

uniformDiffuseLightIntensity = glGetUniformLocation(program, "directionalLight.diffuseIntensity");

uniformMaterialSpecularIntensity = glGetUniformLocation(program, "material.specularIntensity");
uniformMaterialShininess = glGetUniformLocation(program, "material.shininess");

return;

/* code */
  • Modify the Java_dev_anastasioscho_glestriangle_NativeLibrary_nOnDrawFrame function as follows:
/* code */

glm::mat4 viewMatrix = glm::lookAt(cameraPosition, cameraTarget, worldUp);
glUniformMatrix4fv(uniformView, 1, GL_FALSE, glm::value_ptr(viewMatrix));
    
glUniform1f(uniformMaterialSpecularIntensity, 1.0f);
glUniform1f(uniformMaterialShininess, 32.0f);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);

/* code */

3. Add the camera position

3.1. Modify the fragment shader

  • Modify the fragment shader source code as follows:
static const GLchar fragmentShaderSource[] =
   "#version 310 es\n"
   "precision mediump float;\n"
   "in vec4 vColor;\n"
   "in vec2 vTexCoords;\n"
   "in vec3 vNorm;\n"
   "in vec3 vFragPos;\n"
   "out vec4 color;\n"
   "struct DirectionalLight\n"
   "{\n"
   "vec3 color;\n"
   "float intensity;\n"
   "vec3 direction;\n"
   "float diffuseIntensity;\n"
   "};\n"
   "struct Material\n"
   "{\n"
   "float specularIntensity;\n"
   "float shininess;\n"
   "};\n"
   "uniform sampler2D textureSampler;\n"
   "uniform DirectionalLight directionalLight;\n"
   "uniform Material material;\n"
   "uniform vec3 cameraPosition;\n"
   "void main()\n"
   "{\n"
   "vec4 ambientColor = vec4(directionalLight.color, 1.0f) * directionalLight.intensity;\n"
   "float diffuseFactor = max(dot(normalize(vNorm), normalize(directionalLight.direction)), 0.0f);\n"
   "vec4 diffuseColor = vec4(directionalLight.color, 1.0f) * directionalLight.diffuseIntensity * diffuseFactor;\n"
   "color = texture(textureSampler, vTexCoords) * (ambientColor + diffuseColor);\n"
   "}\n";

3.2. Set the uniform variable

  • Declare the following global variable:
/* code */

GLint uniformLightColor, uniformLightIntensity, uniformLightDirection, uniformDiffuseLightIntensity;
GLint uniformMaterialSpecularIntensity, uniformMaterialShininess, uniformCameraPosition;
glm::mat4 projectionMatrix;

/* code */
  • Modify the createProgram function as follows:
/* code */

uniformDiffuseLightIntensity = glGetUniformLocation(program, "directionalLight.diffuseIntensity");

uniformMaterialSpecularIntensity = glGetUniformLocation(program, "material.specularIntensity");
uniformMaterialShininess = glGetUniformLocation(program, "material.shininess");
uniformCameraPosition = glGetUniformLocation(program, "cameraPosition");

return;

/* code */
  • Modify the Java_dev_anastasioscho_glestriangle_NativeLibrary_nOnDrawFrame function as follows:
/* code */

glm::mat4 viewMatrix = glm::lookAt(cameraPosition, cameraTarget, worldUp);
glUniformMatrix4fv(uniformView, 1, GL_FALSE, glm::value_ptr(viewMatrix));
    
glUniform1f(uniformMaterialSpecularIntensity, 1.0f);
glUniform1f(uniformMaterialShininess, 32.0f);
glUniform3f(uniformCameraPosition, cameraPosition.x, cameraPosition.y, cameraPosition.z);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);

/* code */

4. Apply specular lighting

  • Modify the fragment shader source code as follows:
static const GLchar fragmentShaderSource[] =
   "#version 310 es\n"
   "precision mediump float;\n"
   "in vec4 vColor;\n"
   "in vec2 vTexCoords;\n"
   "in vec3 vNorm;\n"
   "in vec3 vFragPos;\n"
   "out vec4 color;\n"
   "struct DirectionalLight\n"
   "{\n"
   "vec3 color;\n"
   "float intensity;\n"
   "vec3 direction;\n"
   "float diffuseIntensity;\n"
   "};\n"
   "struct Material\n"
   "{\n"
   "float specularIntensity;\n"
   "float shininess;\n"
   "};\n"
   "uniform sampler2D textureSampler;\n"
   "uniform DirectionalLight directionalLight;\n"
   "uniform Material material;\n"
   "uniform vec3 cameraPosition;\n"
   "void main()\n"
   "{\n"
   "vec4 ambientColor = vec4(directionalLight.color, 1.0f) * directionalLight.intensity;\n"
   "float diffuseFactor = max(dot(normalize(vNorm), normalize(directionalLight.direction)), 0.0f);\n"
   "vec4 diffuseColor = vec4(directionalLight.color, 1.0f) * directionalLight.diffuseIntensity * diffuseFactor;\n"
   "vec4 specularColor = vec4(0.0f, 0.0f, 0.0f, 0.0f);\n"
   "if (diffuseFactor > 0.0f) {\n"
   "vec3 fragToEye = normalize(cameraPosition - vFragPos);\n"
   "vec3 reflectedVertex = normalize(reflect(directionalLight.direction, normalize(vNorm)));\n"
   "float specularFactor = dot(fragToEye, reflectedVertex);\n"
   "if (specularFactor > 0.0f) {\n"
   "specularFactor = pow(specularFactor, material.shininess);"
   "specularColor = vec4(directionalLight.color * material.specularIntensity * specularFactor, 1.0f);\n"
   "}\n"
   "}\n"
   "color = texture(textureSampler, vTexCoords) * (ambientColor + diffuseColor + specularColor);\n"
   "}\n";

Filed Under: Android Development

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

Let’s connect!

  • Facebook
  • Instagram
  • LinkedIn
  • Twitter

Recent Posts

  • Android OpenGL ES – Part 10: Specular lighting
  • Android OpenGL ES – Part 9: Diffuse lighting
  • Android OpenGL ES – Part 8: Ambient Lighting
  • Android OpenGL ES – Part 7: Textures
  • Android OpenGL ES – Part 6: Camera View

Archives

  • March 2020
  • February 2020
  • November 2019
  • October 2019
  • July 2019

Categories

  • Android Development
  • Machine Learning

Copyright © 2025 · Genesis Sample on Genesis Framework · WordPress · Log in