title: How to apply transparency from mtl file for particular texture in the obj file using opengl android?
body: <p>I am working on a augment reality project with ar-core and OpenGL. I have an issue while rendering objects in OpenGL, the transparency is not applying to the particular texture. I am rendering the texture for the 3d object from mtl using an obj loader library.</p>
  
  <h2>The rendered 3D object should look like this:</h2>
  
  <p><a href="https://i.stack.imgur.com/8koFI.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8koFI.jpg" alt="enter image description here"></a></p>
  
  <h2>But my 3D object looks like this:</h2>
  
  <p><a href="https://i.stack.imgur.com/6Caoh.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/6Caoh.jpg" alt="enter image description here"></a></p>
  
  <p>The transparency at the head of the object is missing.</p>
  
  <p>My mtl file is:
       # Blender MTL File: 'Bacteriophage_new.blend'
      # Material Count: 7</p>
  
  <pre><code>newmtl Material_008_001
  Ns 94.117647
  Ka 1.000000 1.000000 1.000000
  Kd 0.640000 0.640000 0.640000
  Ks 0.125000 0.125000 0.125000
  Ke 0.000000 0.000000 0.000000
  Ni 1.000000
  d 1.000000
  illum 2
  map_Kd Green.png.001.png
  
  newmtl Material_010_001
  Ns 94.117647
  Ka 1.000000 1.000000 1.000000
  Kd 0.640000 0.640000 0.640000
  Ks 0.125000 0.125000 0.125000
  Ke 0.000000 0.000000 0.000000
  Ni 1.000000
  d 1.000000
  illum 2
  map_Kd Green.png.004.png
  
  newmtl Material_011_001
  Ns 94.117647
  Ka 1.000000 1.000000 1.000000
  Kd 0.640000 0.640000 0.640000
  Ks 0.125000 0.125000 0.125000
  Ke 0.000000 0.000000 0.000000
  Ni 1.000000
  d 1.000000
  illum 2
  map_Kd pink.jpg.002.jpg
  
  newmtl Material_012_001
  Ns 94.117647
  Ka 1.000000 1.000000 1.000000
  Kd 0.640000 0.640000 0.640000
  Ks 0.125000 0.125000 0.125000
  Ke 0.000000 0.000000 0.000000
  Ni 1.000000
  d 1.000000
  illum 2
  map_Kd blue.png.002.png
  
  newmtl Material_013_001
  Ns 94.117647
  Ka 1.000000 1.000000 1.000000
  Kd 0.640000 0.640000 0.640000
  Ks 0.125000 0.125000 0.125000
  Ke 0.000000 0.000000 0.000000
  Ni 1.000000
  d 1.000000
  illum 2
  map_Kd dark.png.002.png
  
  newmtl Material_014_001
  Ns 94.117647
  Ka 1.000000 1.000000 1.000000
  Kd 0.640000 0.640000 0.640000
  Ks 0.125000 0.125000 0.125000
  Ke 0.000000 0.000000 0.000000
  Ni 1.000000
  d 1.000000
  illum 2
  map_Kd Green.png.004.png
  
  newmtl Material_015_001
  Ns 94.117647
  Ka 1.000000 1.000000 1.000000
  Kd 0.640000 0.640000 0.640000
  Ks 0.125000 0.125000 0.125000
  Ke 0.000000 0.000000 0.000000
  Ni 1.000000
  d 0.800000
  illum 2
  map_Kd Green.png.004.png
  </code></pre>
  
  <h2>My Main Actity class:</h2>
  
  <p>In OnSurfaceCreated preparing objects for draw by calling createOnGlThread Method:</p>
  
  <pre><code>renderObject.createOnGlThread(HelloArActivity.this,str + ".obj", str + ".png",ObjPath);
  </code></pre>
  
  <p>In OnDrawFrame Method draw a object by calling draw method</p>
  
  <pre><code>renderObject.draw(viewmtx,projmtx,lightIntensity,mAnchorMatrix,scaleFactor);
  </code></pre>
  
  <h2>RenderObject class:</h2>
  
  <pre><code>package com.google.ar.core.examples.java.helloar.rendering;
  import android.content.Context;
  import android.util.Log;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  import java.util.Objects;
  import de.javagl.obj.Mtl;
  import de.javagl.obj.MtlReader;
  import de.javagl.obj.Obj;
  import de.javagl.obj.ObjReader;
  import de.javagl.obj.ObjSplitting;
  import de.javagl.obj.ObjUtils;
  
  public class RenderObject
  {
      private static final String TAG =
              RenderObject.class.getSimpleName();
  
      private final List&lt;ObjectRenderer&gt; materialGroupObjectRenderers;
  
  
      public RenderObject()
      {
          this.materialGroupObjectRenderers = new ArrayList&lt;&gt;();
      }
  
  
             public void createOnGlThread(Context context, String objAssetName,
                                   String defaultTextureFileName,String ObjPath) throws IOException
      {
  
          // Read the obj file.
          Log.d("ObjPathPlus",ObjPath+objAssetName);
  
          try {
              InputStream objInputStream = context.getAssets().open(ObjPath + objAssetName);
              Log.d("GetInputStream",""+objInputStream);
              Obj obj = ObjReader.read(objInputStream);
  
  
              /            Obj renderableObj = ObjUtils.convertToRenderable(obj);
  
              // When there are no material groups, then just render the object
              // using the default texture
              Log.d("HowManyVertices", "" + renderableObj.getNumVertices());
              Log.d("GetTMatG", "" + renderableObj.getNumMaterialGroups());
              if (renderableObj.getNumMaterialGroups() == 0) {
                  createRenderers(context, renderableObj, defaultTextureFileName);
              } else {
                  // Otherwise, create one renderer for each material
                  createMaterialBasedRenderers(context, renderableObj,
                          defaultTextureFileName,ObjPath);
              }
          }catch (Exception e)
          {
              Log.d("GetPatheE",""+e.toString());
          }
      }
  
              private void createRenderers(Context context, Obj obj,
                                   String textureFileName) throws IOException
      {
  
          if (obj.getNumVertices() &lt;= 65000)
          {
              createRenderer(context, obj, textureFileName);
          }
          else
          {
              Log.d("ObjectVertextG","Greater");
              // If there are more than 65k vertices, then the object has to be
              // split into multiple parts, each having at most 65k vertices
              List&lt;Obj&gt; objParts = ObjSplitting.splitByMaxNumVertices(obj, 65000);
              for (int j = 0; j &lt; objParts.size(); j++)
              {
                  Obj objPart = objParts.get(j);
                  createRenderer(context, objPart, textureFileName);
              }
          }
      }
  
              private void createMaterialBasedRenderers(Context context, Obj obj,
                                                String defaultTextureFileName,String ObjPath) throws IOException
      {
  
          List&lt;String&gt; mtlFileNames = obj.getMtlFileNames();
          List&lt;Mtl&gt; allMtls = new ArrayList&lt;&gt;();
          for (String mtlFileName : mtlFileNames)
          {
              InputStream mtlInputStream = context.getAssets().open(ObjPath+mtlFileName);
              List&lt;Mtl&gt; mtls = MtlReader.read(mtlInputStream);
              allMtls.addAll(mtls);
          }
  
          // Obtain the material groups from the OBJ, and create renderers for
          // each of them
          Map&lt;String, Obj&gt; materialGroupObjs =
                  ObjSplitting.splitByMaterialGroups(obj);
          for (Map.Entry&lt;String, Obj&gt; entry : materialGroupObjs.entrySet())
          {
              String materialName = entry.getKey();
              String textureFileName = findTextureFileName(materialName, allMtls,
                      defaultTextureFileName);
              Log.d("GtTexture",textureFileName);
              Obj materialGroupObj = entry.getValue();
              createRenderers(context, materialGroupObj, ObjPath+textureFileName);
          }
      }
  
          private String findTextureFileName(String materialName,
                                         Iterable&lt;? extends Mtl&gt; mtls, String defaultTextureFileName)
      {
          for (Mtl mtl : mtls)
          {
              if (Objects.equals(materialName, mtl.getName()))
              {
                  if(mtl.getName().equals("Material_015_001"))
                  {
                      Log.d("GetDissolve",""+mtl.getD());
                  }
                  Log.d("ObjectsARe",materialName+"="+mtl.getName());
  
                  return mtl.getMapKd();
  
              }
          }
          return defaultTextureFileName;
      }
  
          private void createRenderer(Context context, Obj obj,
                                  String textureFileName) throws IOException
      {
  
          Log.i(TAG, "Rendering part with " + obj.getNumVertices()
                  + " vertices and " + textureFileName);
  
          ObjectRenderer objectRenderer = new ObjectRenderer();
          objectRenderer.createOnGlThread(context, obj, textureFileName);
  
          materialGroupObjectRenderers.add(objectRenderer);
      }
  
      /**
       * Draws the model.
       *
       * @param cameraView A 4x4 view matrix, in column-major order.
       * @param cameraPerspective A 4x4 projection matrix, in column-major order.
       * @param lightIntensity Illumination intensity. Combined with diffuse and
       *        specular material properties.
       */
      public void draw(float[] cameraView, float[] cameraPerspective,
                       float lightIntensity,float[] AnchorMatrix,float scalfactor)
      {
          Log.d("ObjRenSize",""+materialGroupObjectRenderers.size()+"And ScaleFactor"+"="+scalfactor);
          for (ObjectRenderer renderer : materialGroupObjectRenderers)
          {
              renderer.updateModelMatrix(AnchorMatrix,scalfactor);
              renderer.draw(cameraView, cameraPerspective, lightIntensity);
          }
  //        ObjectRenderer objectRenderer=new ObjectRenderer();
  //        objectRenderer.updateModelMatrix(AnchorMatrix,scalfactor);
  
      }
  
  }
  </code></pre>
  
  <h2>ObjectRenderer class:</h2>
  
  <pre><code>package com.google.ar.core.examples.java.helloar.rendering;
   import android.content.Context;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.opengl.GLES20;
  import android.opengl.GLES30;
  import android.opengl.GLUtils;
  import android.opengl.Matrix;
  import android.util.Log;
  import com.google.ar.core.examples.java.helloar.R;
  import com.google.ar.core.examples.java.helloar.TGAReader;
  import de.javagl.obj.Mtl;
  import de.javagl.obj.MtlReader;
  import de.javagl.obj.Obj;
  import de.javagl.obj.ObjData;
  import de.javagl.obj.ObjFace;
  import de.javagl.obj.ObjGroup;
  import de.javagl.obj.ObjReader;
  import de.javagl.obj.ObjSplitting;
  import de.javagl.obj.ObjUtils;
  import java.io.IOException;
  import java.io.InputStream;
  import java.nio.ByteBuffer;
  import java.nio.ByteOrder;
  import java.nio.FloatBuffer;
  import java.nio.IntBuffer;
  import java.nio.ShortBuffer;
  import java.util.List;
  
      public class ObjectRenderer {
      private static final String TAG = ObjectRenderer.class.getSimpleName();
  
              public enum BlendMode {
          Shadow,
          Grid
      }
  
      private static final int COORDS_PER_VERTEX = 3;
  
      private static final float[] LIGHT_DIRECTION = new float[] { 0.250f, 0.866f, 0.433f, 0.0f };
      private float[] mViewLightDirection = new float[4];
        private int mVertexBufferId;
      private int mVerticesBaseAddress;
      private int mTexCoordsBaseAddress;
      private int mNormalsBaseAddress;
      private int mIndexBufferId;
      private int mIndexCount;
  
      private int mProgram;
      private int[] mTextures = new int[1];
  
      private int mModelViewUniform;
      private int mModelViewProjectionUniform;
  
      private int mPositionAttribute;
      private int mNormalAttribute;
      private int mTexCoordAttribute;
  
      private int mTextureUniform;
  
      private int mLightingParametersUniform;
  
      private int mMaterialParametersUniform;
  
      private BlendMode mBlendMode = null;
  
      private float mAmbient = 0.3f;
      private float mDiffuse = 1.0f;
      private float mSpecular = 1.0f;
      private float mSpecularPower = 6.0f;
  
      private int[] vectorArrayObjectIds;
      private  String OBJ_PATH;
  
      private Obj mObj;
  
      public ObjectRenderer() {
      }
  
      public ObjectRenderer(String ObjPath)
      {
          OBJ_PATH=ObjPath;
      }
  
      public void createOnGlThread(Context context, Obj obj,
                                   String diffuseTextureAssetName) throws IOException {
          Log.d("TextureAssName",diffuseTextureAssetName);
          Bitmap textureBitmap = BitmapFactory.decodeStream(
              context.getAssets().open(diffuseTextureAssetName));
          GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
          GLES20.glGenTextures(mTextures.length, mTextures, 0);
          GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
          GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
              GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR_MIPMAP_LINEAR);
          GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
              GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
          GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, textureBitmap, 0);
          GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
          GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
  
          textureBitmap.recycle();
  
          ShaderUtil.checkGLError(TAG, "Texture loading");
  
                          IntBuffer wideIndices = ObjData.getFaceVertexIndices(obj, 3);
              FloatBuffer vertices = ObjData.getVertices(obj);
              FloatBuffer texCoords = ObjData.getTexCoords(obj, 2);
              FloatBuffer normals = ObjData.getNormals(obj);
  
              ShortBuffer indices = ByteBuffer.allocateDirect(2 * wideIndices.limit())
                      .order(ByteOrder.nativeOrder()).asShortBuffer();
              while (wideIndices.hasRemaining()) {
                  indices.put((short) wideIndices.get());
              }
              indices.rewind();
  
              int[] buffers = new int[2];
              GLES20.glGenBuffers(2, buffers, 0);
              mVertexBufferId = buffers[0];
              mIndexBufferId = buffers[1];
  
              mVerticesBaseAddress = 0;
              mTexCoordsBaseAddress = mVerticesBaseAddress + 4 * vertices.limit();
              mNormalsBaseAddress = mTexCoordsBaseAddress + 4 * texCoords.limit();
              final int totalBytes = mNormalsBaseAddress + 4 * normals.limit();
  
              GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferId);
              GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, totalBytes, null, GLES20.GL_STATIC_DRAW);
              GLES20.glBufferSubData(
                      GLES20.GL_ARRAY_BUFFER, mVerticesBaseAddress, 4 * vertices.limit(), vertices);
              GLES20.glBufferSubData(
                      GLES20.GL_ARRAY_BUFFER, mTexCoordsBaseAddress, 4 * texCoords.limit(), texCoords);
              GLES20.glBufferSubData(
                      GLES20.GL_ARRAY_BUFFER, mNormalsBaseAddress, 4 * normals.limit(), normals);
              GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
  
              GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndexBufferId);
              mIndexCount = indices.limit();
              GLES20.glBufferData(
                      GLES20.GL_ELEMENT_ARRAY_BUFFER, 2 * mIndexCount, indices, GLES20.GL_STATIC_DRAW);
              GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
  
              ShaderUtil.checkGLError(TAG, "OBJ buffer load");
  
              final int vertexShader = ShaderUtil.loadGLShader(TAG, context,
                      GLES20.GL_VERTEX_SHADER, R.raw.object_vertex);
              final int fragmentShader = ShaderUtil.loadGLShader(TAG, context,
                      GLES20.GL_FRAGMENT_SHADER, R.raw.object_fragment);
  
              mProgram = GLES20.glCreateProgram();
              GLES20.glAttachShader(mProgram, vertexShader);
              GLES20.glAttachShader(mProgram, fragmentShader);
              GLES20.glLinkProgram(mProgram);
              GLES20.glUseProgram(mProgram);
  
              ShaderUtil.checkGLError(TAG, "Program creation");
  
              mModelViewUniform = GLES20.glGetUniformLocation(mProgram, "u_ModelView");
              mModelViewProjectionUniform =
                      GLES20.glGetUniformLocation(mProgram, "u_ModelViewProjection");
  
              mPositionAttribute = GLES20.glGetAttribLocation(mProgram, "a_Position");
              mNormalAttribute = GLES20.glGetAttribLocation(mProgram, "a_Normal");
              mTexCoordAttribute = GLES20.glGetAttribLocation(mProgram, "a_TexCoord");
  
              mTextureUniform = GLES20.glGetUniformLocation(mProgram, "u_Texture");
  
              mLightingParametersUniform = GLES20.glGetUniformLocation(mProgram, "u_LightingParameters");
              mMaterialParametersUniform = GLES20.glGetUniformLocation(mProgram, "u_MaterialParameters");
  
              ShaderUtil.checkGLError(TAG, "Program parameters");
  
              Matrix.setIdentityM(mModelMatrix, 0);
          }
  //    }
  
              public void setBlendMode(BlendMode blendMode) {
          mBlendMode = blendMode;
      }
  
              public void updateModelMatrix(float[] modelMatrix, float scaleFactor) {
          float[] scaleMatrix = new float[16];
          Matrix.setIdentityM(scaleMatrix, 0);
          scaleMatrix[0] = scaleFactor;
          scaleMatrix[5] = scaleFactor;
          scaleMatrix[10] = scaleFactor;
          Matrix.multiplyMM(mModelMatrix, 0, modelMatrix, 0, scaleMatrix, 0);
      }
  
              public void setMaterialProperties(
              float ambient, float diffuse, float specular, float specularPower) {
          mAmbient = ambient;
          mDiffuse = diffuse;
          mSpecular = specular;
          mSpecularPower = specularPower;
      }
  
             public void draw(float[] cameraView, float[] cameraPerspective, float lightIntensity) {
  
          ShaderUtil.checkGLError(TAG, "Before draw");
  
          // Build the ModelView and ModelViewProjection matrices
          // for calculating object position and light.
          Matrix.multiplyMM(mModelViewMatrix, 0, cameraView, 0, mModelMatrix, 0);
          Matrix.multiplyMM(mModelViewProjectionMatrix, 0, cameraPerspective, 0, mModelViewMatrix, 0);
  
          GLES20.glUseProgram(mProgram);
  
          // Set the lighting environment properties.
          Matrix.multiplyMV(mViewLightDirection, 0, mModelViewMatrix, 0, LIGHT_DIRECTION, 0);
          normalizeVec3(mViewLightDirection);
          GLES20.glUniform4f(mLightingParametersUniform,
              mViewLightDirection[0], mViewLightDirection[1], mViewLightDirection[2], lightIntensity);
  
          // Set the object material properties.
          GLES20.glUniform4f(mMaterialParametersUniform, mAmbient, mDiffuse, mSpecular,
              mSpecularPower);
  
          // Attach the object texture.
          GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
          GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
          GLES20.glUniform1i(mTextureUniform, 0);
  
          // Set the vertex attributes.
          GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferId);
  
          GLES20.glVertexAttribPointer(
              mPositionAttribute, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, mVerticesBaseAddress);
          GLES20.glVertexAttribPointer(
              mNormalAttribute, 3, GLES20.GL_FLOAT, false, 0, mNormalsBaseAddress);
          GLES20.glVertexAttribPointer(
              mTexCoordAttribute, 2, GLES20.GL_FLOAT, false, 0, mTexCoordsBaseAddress);
  
          GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
  
          // Set the ModelViewProjection matrix in the shader.
          GLES20.glUniformMatrix4fv(
              mModelViewUniform, 1, false, mModelViewMatrix, 0);
          GLES20.glUniformMatrix4fv(
              mModelViewProjectionUniform, 1, false, mModelViewProjectionMatrix, 0);
  
          // Enable vertex arrays
          GLES20.glEnableVertexAttribArray(mPositionAttribute);
          GLES20.glEnableVertexAttribArray(mNormalAttribute);
          GLES20.glEnableVertexAttribArray(mTexCoordAttribute);
          if (mBlendMode != null) {
              GLES20.glDepthMask(false);
              GLES20.glEnable(GLES20.GL_BLEND);
              switch (mBlendMode) {
                  case Shadow:
                      // Multiplicative blending function for Shadow.
                      GLES20.glBlendFunc(GLES20.GL_ZERO, GLES20.GL_ONE_MINUS_SRC_ALPHA);
                      break;
                  case Grid:
                      // Grid, additive blending function.
                      GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
                      break;
              }
          }
  
          GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndexBufferId);
          GLES20.glDrawElements(GLES20.GL_TRIANGLES, mIndexCount, GLES20.GL_UNSIGNED_SHORT, 0);
          GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
  
          if (mBlendMode != null) {
              GLES20.glDisable(GLES20.GL_BLEND);
              GLES20.glDepthMask(true);
          }
  
          // Disable vertex arrays
          GLES20.glDisableVertexAttribArray(mPositionAttribute);
          GLES20.glDisableVertexAttribArray(mNormalAttribute);
          GLES20.glDisableVertexAttribArray(mTexCoordAttribute);
  
          GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
  
          ShaderUtil.checkGLError(TAG, "After draw");
      }
  
  private static void normalizeVec3(float[] v) {
      float reciprocalLength = 1.0f / (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
      v[0] *= reciprocalLength;
      v[1] *= reciprocalLength;
      v[2] *= reciprocalLength;
  }
  
             }
  </code></pre>
  
  <h2>object_fragment.shader</h2>
  
  <pre><code>precision mediump float;
  
  uniform sampler2D u_Texture;
  
  uniform vec4 u_LightingParameters;
  uniform vec4 u_MaterialParameters;
  
  varying vec3 v_ViewPosition;
  varying vec3 v_ViewNormal;
  varying vec2 v_TexCoord;
  
  void main() {
      // We support approximate sRGB gamma.
      const float kGamma = 0.4545454;
      const float kInverseGamma = 2.2;
  
      // Unpack lighting and material parameters for better naming.
      vec3 viewLightDirection = u_LightingParameters.xyz;
      float lightIntensity = u_LightingParameters.w;
  
      float materialAmbient = u_MaterialParameters.x;
      float materialDiffuse = u_MaterialParameters.y;
      float materialSpecular = u_MaterialParameters.z;
      float materialSpecularPower = u_MaterialParameters.w;
  
      // Normalize varying parameters, because they are linearly interpolated in the vertex shader.
      vec3 viewFragmentDirection = normalize(v_ViewPosition);
      vec3 viewNormal = normalize(v_ViewNormal);
  
      // Apply inverse SRGB gamma to the texture before making lighting calculations.
      // Flip the y-texture coordinate to address the texture from top-left.
      vec4 objectColor = texture2D(u_Texture, vec2(v_TexCoord.x, 1.0 - v_TexCoord.y));
      objectColor.rgb = pow(objectColor.rgb, vec3(kInverseGamma));
  
      // Ambient light is unaffected by the light intensity.
      float ambient = materialAmbient;
  
      // Approximate a hemisphere light (not a harsh directional light).
      float diffuse = lightIntensity * materialDiffuse *
              0.5 * (dot(viewNormal, viewLightDirection) + 1.0);
  
      // Compute specular light.
      vec3 reflectedLightDirection = reflect(viewLightDirection, viewNormal);
      float specularStrength = max(0.0, dot(viewFragmentDirection, reflectedLightDirection));
      float specular = lightIntensity * materialSpecular *
              pow(specularStrength, materialSpecularPower);
  
      // Apply SRGB gamma before writing the fragment color.
      gl_FragColor.a = objectColor.a;
      gl_FragColor.rgb = pow(objectColor.rgb * (ambient + diffuse) + specular, vec3(kGamma));
  }
  </code></pre>
  
  <h2>object_vertex.shader</h2>
  
  <pre><code>uniform mat4 u_ModelView;
  uniform mat4 u_ModelViewProjection;
  
  attribute vec4 a_Position;
  attribute vec3 a_Normal;
  attribute vec2 a_TexCoord;
  
  varying vec3 v_ViewPosition;
  varying vec3 v_ViewNormal;
  varying vec2 v_TexCoord;
  
  void main() {
      v_ViewPosition = (u_ModelView * a_Position).xyz;
      v_ViewNormal = normalize((u_ModelView * vec4(a_Normal, 0.0)).xyz);
      v_TexCoord = a_TexCoord;
      gl_Position = u_ModelViewProjection * a_Position;
  }
  </code></pre>
  
  <p>Please help me to solve this issue</p>