<p>I'm having a problem with my model here. I draw an icosahedron using GLUT, and the radius is set to 0.8. The info of the coordinates are listed below: (X and Z are calculated since our radius is 0.8)</p>

<pre><code> private static final float X = .4205912828f;
 private static final float Z = .6805166955f;
 private static final float[][] idata =
{
   {-X, 0, Z},
   {X, 0, Z},
   {-X, 0, -Z},
   {X, 0, -Z},
   {0, Z, X},
   {0, Z, -X},
   {0, -Z, X},
   {0, -Z, -X},
   {Z, X, 0},
   {-Z, X, 0},
   {Z, -X, 0},
   {-Z, -X, 0}
 };

private static final int[][] index =
 {
         {0, 4, 1},
            {0, 9, 4},
            {9, 5, 4},
            {4, 5, 8},
            {4, 8, 1},
            {8, 10, 1},
            {8, 3, 10},
            {5, 3, 8},
            {5, 2, 3},
            {2, 7, 3},
            {7, 10, 3},
            {7, 6, 10},
            {7, 11, 6},
            {11, 0, 6},
            {0, 1, 6},
            {6, 1, 10},
            {9, 0, 11},
            {9, 11, 2},
            {9, 2, 5},
            {7, 2, 11},
 };
</code></pre>

<p>I calculate the vertex normal using the glut method as well: </p>

<pre><code>private static void icosahedron(final GL2 gl) {
   int i;
   for (i = 0; i &lt;= 19; i++) {
     drawtriangle(gl, i, idata, index);
   }
 }
 private static void diff3(final float[] a, final float[] b, final float[] c) {
        c[0] = a[0] - b[0];
        c[1] = a[1] - b[1];
        c[2] = a[2] - b[2];
      }

 private static void crossprod(final float[] v1, final float[] v2, final float[] prod) {
        final float[] p = new float[3];         /* in case prod == v1 or v2 */

        p[0] = v1[1] * v2[2] - v2[1] * v1[2];
        p[1] = v1[2] * v2[0] - v2[2] * v1[0];
        p[2] = v1[0] * v2[1] - v2[0] * v1[1];
        prod[0] = p[0];
        prod[1] = p[1];
        prod[2] = p[2];
      }

 private static void normalize(final float[] v) {
        float d;

        d = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
        if (d == 0.0) {
          v[0] = d = 1.0f;
        }
        d = 1 / d;
        v[0] *= d;
        v[1] *= d;
        v[2] *= d;
      }


 private static void recorditem(final GL2 gl, final float[] n1, final float[] n2, final float[] n3) {
        final float[] q0 = new float[3];
        final float[] q1 = new float[3];
        final float[] q2 = new float[3];
        diff3(n1, n2, q0);
        diff3(n2, n3, q1);
        crossprod(q0, q1, q2);
        normalize(q2);
        System.out.format("%.5f, %.5f, %.5f",q2[0],q2[1],q2[2]);
        gl.glBegin(GL.GL_TRIANGLES);
        gl.glNormal3fv(q2,0);
        gl.glVertex3fv(n1, 0);
        gl.glVertex3fv(n2, 0);
        gl.glVertex3fv(n3, 0);
        gl.glEnd();
      }

 private static void subdivide(final GL2 gl, final float[] v0, final float[] v1, final float[] v2) {
        int depth;
        final float[] w0 = new float[3];
        final float[] w1 = new float[3];
        final float[] w2 = new float[3];
        float l;
        int i, j, k, n;

        depth = 1;
        for (i = 0; i &lt; depth; i++) {
          for (j = 0; i + j &lt; depth; j++) {
            k = depth - i - j;
            for (n = 0; n &lt; 3; n++) {
              w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
              w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
                / depth;
              w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
                / depth;
            }
            l = (float) Math.sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
            w0[0] /= l;
            w0[1] /= l;
            w0[2] /= l;
            l = (float) Math.sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
            w1[0] /= l;
            w1[1] /= l;
            w1[2] /= l;
            l = (float) Math.sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
            w2[0] /= l;
            w2[1] /= l;
            w2[2] /= l;
            recorditem(gl, w0, w1, w2);
          }
        }
      }  

 private static void drawtriangle(final GL2 gl, final int i, final float[][] data, final int[][] ndx) {
       final float[] x0 = data[ndx[i][0]];
       final float[] x1 = data[ndx[i][1]];
       final float[] x2 = data[ndx[i][2]];
       subdivide(gl, x0, x1, x2);
     }
</code></pre>

<p>However, the reflection of the light does not look right on the icosahedron. </p>

<p>My vertex shader: </p>

<pre><code>attribute vec3 inposition;//in vec3 position;          //for #version 130
attribute vec4 incolor;
attribute vec3 innormal;
attribute vec2 intexcoord0;
varying vec3 normal;
varying vec4 color;
varying vec2 texcoord;
varying vec3 pos;        
uniform mat4 mat[4];

void main(void)
{
  normal = normalize((mat[3]*vec4(innormal,0.0)).xyz);
  color = incolor;
  texcoord = intexcoord0;
  gl_Position = mat[0]*mat[1]*vec4(inposition, 1.0);
//  gl_Position = vec4(inposition, 1.0);
  pos = gl_Position.xyz; 
}
</code></pre>

<p>Here innormal is the vertex normal, and inposition are the coordinates of the vertices. </p>

<p>And my frag shader is : </p>

<pre><code>uniform sampler2D texture0;
uniform vec3 lightpos;
uniform vec3 lightColor;
uniform vec3 objectColor;
varying vec3 normal;
varying vec4 color;
varying vec2 texcoord;
varying vec3 pos; 

void main (void){
//  gl_FragColor = max(texture2D(texture0, texcoord),color.xyzw);
//  gl_FragColor = texture2D(texture0, texcoord);
//  gl_FragColor = vec4(0.3, 0.8, 0.2, 1.0);
//  vec2 dfdx = abs(dFdx(texcoord));
//  vec2 dfdy = abs(dFdy(texcoord));
//  float d = max(max(dfdx.x,dfdx.y),max(dfdy.x,dfdy.y));
//  gl_FragColor = vec4(d*20,0,0,1);

vec3 light = lightpos- pos;
    //light = lightpos;

vec3 norm = normalize(normal);
vec3 eye_vector = vec3(0.0);
vec3 viewDir = normalize(eye_vector - pos);
vec3 lightDir = normalize(light);
vec3 reflectDir = reflect(lightDir,norm);
float spec = pow(dot(viewDir,reflectDir), 100.0);
float specularStrength = 0.5;
vec3 lightColor = vec3(1.0);
vec3 spect = spec*specularStrength*lightColor; 

gl_FragColor = vec4((0.9*max(dot(normal, normalize(light)),0.0)+0.1)*color.xyz,1.0) + vec4(vec3(spect),1.0);
</code></pre>

<p>The lightpos is the position of the light which is (0,0,10);</p>

<p>Somehow the result looks like this: </p>

<p><a href="https://i.sstatic.net/YwDWN.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/YwDWN.png" alt="enter image description here"></a></p>

<p>which doesn't look right. Could anyone give me some hints please? </p>

<p><a href="https://i.sstatic.net/Cnp5F.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/Cnp5F.png" alt="enter image description here"></a></p>

<p>This is the vertex data and </p>

<p><a href="https://i.sstatic.net/PKtgA.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/PKtgA.png" alt="enter image description here"></a></p>

<p><a href="https://i.sstatic.net/ocB8L.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ocB8L.png" alt="enter image description here"></a></p>

<p>This is how mat<a href="https://i.sstatic.net/ocB8L.png" rel="nofollow noreferrer">4</a> produced. And the following is the normal output by @PaulHK 's idea, and it is broken. </p>

<p><a href="https://i.sstatic.net/VtaWY.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/VtaWY.png" alt="enter image description here"></a></p>

CC BY-SA 4.0
2019-02-01T08:16:35.247Z
How is mat[3] calculated ? I notice your diffuse shading is also broken so I would start by looking at your normals. Maybe outputting the 'norm' variable as your fragment shader output so you can visualise if they are correct.
PaulHK
CC BY-SA 4.0
2019-02-04T13:10:32.417Z
Please copy and paste the text into the question instead of adding screenshots of text. Screenshots aren't searchable so it's harder for people to find and answer your question. They're also not useful to blind people who use a screen-reader to use the site.
Dan Hulme
<opengl><lighting>
Specular/Diffuse light on an icosahedron opengl
NoobInJava
# Specular/Diffuse light on an icosahedron opengl

(Asked by: username_0 on 2019-02-01)

I'm having a problem with my model here. I draw an icosahedron using GLUT, and the radius is set to 0.8. The info of the coordinates are listed below: (X and Z are calculated since our radius is 0.8)

```
 private static final float X = .4205912828f;
 private static final float Z = .6805166955f;
 private static final float[][] idata =
{
   {-X, 0, Z},
   {X, 0, Z},
   {-X, 0, -Z},
   {X, 0, -Z},
   {0, Z, X},
   {0, Z, -X},
   {0, -Z, X},
   {0, -Z, -X},
   {Z, X, 0},
   {-Z, X, 0},
   {Z, -X, 0},
   {-Z, -X, 0}
 };

private static final int[][] index =
 {
         {0, 4, 1},
            {0, 9, 4},
            {9, 5, 4},
            {4, 5, 8},
            {4, 8, 1},
            {8, 10, 1},
            {8, 3, 10},
            {5, 3, 8},
            {5, 2, 3},
            {2, 7, 3},
            {7, 10, 3},
            {7, 6, 10},
            {7, 11, 6},
            {11, 0, 6},
            {0, 1, 6},
            {6, 1, 10},
            {9, 0, 11},
            {9, 11, 2},
            {9, 2, 5},
            {7, 2, 11},
 };

```

I calculate the vertex normal using the glut method as well:

```
private static void icosahedron(final GL2 gl) {
   int i;
   for (i = 0; i <= 19; i++) {
     drawtriangle(gl, i, idata, index);
   }
 }
 private static void diff3(final float[] a, final float[] b, final float[] c) {
        c[0] = a[0] - b[0];
        c[1] = a[1] - b[1];
        c[2] = a[2] - b[2];
      }

 private static void crossprod(final float[] v1, final float[] v2, final float[] prod) {
        final float[] p = new float[3];         /* in case prod == v1 or v2 */

        p[0] = v1[1] * v2[2] - v2[1] * v1[2];
        p[1] = v1[2] * v2[0] - v2[2] * v1[0];
        p[2] = v1[0] * v2[1] - v2[0] * v1[1];
        prod[0] = p[0];
        prod[1] = p[1];
        prod[2] = p[2];
      }

 private static void normalize(final float[] v) {
        float d;

        d = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
        if (d == 0.0) {
          v[0] = d = 1.0f;
        }
        d = 1 / d;
        v[0] *= d;
        v[1] *= d;
        v[2] *= d;
      }

 private static void recorditem(final GL2 gl, final float[] n1, final float[] n2, final float[] n3) {
        final float[] q0 = new float[3];
        final float[] q1 = new float[3];
        final float[] q2 = new float[3];
        diff3(n1, n2, q0);
        diff3(n2, n3, q1);
        crossprod(q0, q1, q2);
        normalize(q2);
        System.out.format("%.5f, %.5f, %.5f",q2[0],q2[1],q2[2]);
        gl.glBegin(GL.GL_TRIANGLES);
        gl.glNormal3fv(q2,0);
        gl.glVertex3fv(n1, 0);
        gl.glVertex3fv(n2, 0);
        gl.glVertex3fv(n3, 0);
        gl.glEnd();
      }

 private static void subdivide(final GL2 gl, final float[] v0, final float[] v1, final float[] v2) {
        int depth;
        final float[] w0 = new float[3];
        final float[] w1 = new float[3];
        final float[] w2 = new float[3];
        float l;
        int i, j, k, n;

        depth = 1;
        for (i = 0; i < depth; i++) {
          for (j = 0; i + j < depth; j++) {
            k = depth - i - j;
            for (n = 0; n < 3; n++) {
              w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
              w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
                / depth;
              w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
                / depth;
            }
            l = (float) Math.sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
            w0[0] /= l;
            w0[1] /= l;
            w0[2] /= l;
            l = (float) Math.sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
            w1[0] /= l;
            w1[1] /= l;
            w1[2] /= l;
            l = (float) Math.sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
            w2[0] /= l;
            w2[1] /= l;
            w2[2] /= l;
            recorditem(gl, w0, w1, w2);
          }
        }
      }  

 private static void drawtriangle(final GL2 gl, final int i, final float[][] data, final int[][] ndx) {
       final float[] x0 = data[ndx[i][0]];
       final float[] x1 = data[ndx[i][1]];
       final float[] x2 = data[ndx[i][2]];
       subdivide(gl, x0, x1, x2);
     }

```

However, the reflection of the light does not look right on the icosahedron.

My vertex shader:

```
attribute vec3 inposition;//in vec3 position;          //for #version 130
attribute vec4 incolor;
attribute vec3 innormal;
attribute vec2 intexcoord0;
varying vec3 normal;
varying vec4 color;
varying vec2 texcoord;
varying vec3 pos;        
uniform mat4 mat[4];

void main(void)
{
  normal = normalize((mat[3]*vec4(innormal,0.0)).xyz);
  color = incolor;
  texcoord = intexcoord0;
  gl_Position = mat[0]*mat[1]*vec4(inposition, 1.0);
//  gl_Position = vec4(inposition, 1.0);
  pos = gl_Position.xyz; 
}

```

Here innormal is the vertex normal, and inposition are the coordinates of the vertices.

And my frag shader is :

```
uniform sampler2D texture0;
uniform vec3 lightpos;
uniform vec3 lightColor;
uniform vec3 objectColor;
varying vec3 normal;
varying vec4 color;
varying vec2 texcoord;
varying vec3 pos; 

void main (void){
//  gl_FragColor = max(texture2D(texture0, texcoord),color.xyzw);
//  gl_FragColor = texture2D(texture0, texcoord);
//  gl_FragColor = vec4(0.3, 0.8, 0.2, 1.0);
//  vec2 dfdx = abs(dFdx(texcoord));
//  vec2 dfdy = abs(dFdy(texcoord));
//  float d = max(max(dfdx.x,dfdx.y),max(dfdy.x,dfdy.y));
//  gl_FragColor = vec4(d*20,0,0,1);

vec3 light = lightpos- pos;
    //light = lightpos;

vec3 norm = normalize(normal);
vec3 eye_vector = vec3(0.0);
vec3 viewDir = normalize(eye_vector - pos);
vec3 lightDir = normalize(light);
vec3 reflectDir = reflect(lightDir,norm);
float spec = pow(dot(viewDir,reflectDir), 100.0);
float specularStrength = 0.5;
vec3 lightColor = vec3(1.0);
vec3 spect = spec*specularStrength*lightColor; 

gl_FragColor = vec4((0.9*max(dot(normal, normalize(light)),0.0)+0.1)*color.xyz,1.0) + vec4(vec3(spect),1.0);

```

The lightpos is the position of the light which is (0,0,10);

Somehow the result looks like this:

[![enter image description here](https://i.sstatic.net/YwDWN.png)](https://i.sstatic.net/YwDWN.png)

which doesn't look right. Could anyone give me some hints please?

[![enter image description here](https://i.sstatic.net/Cnp5F.png)](https://i.sstatic.net/Cnp5F.png)

This is the vertex data and

[![enter image description here](https://i.sstatic.net/PKtgA.png)](https://i.sstatic.net/PKtgA.png)

[![enter image description here](https://i.sstatic.net/ocB8L.png)](https://i.sstatic.net/ocB8L.png)

This is how mat[4](https://i.sstatic.net/ocB8L.png) produced. And the following is the normal output by @username_1 's idea, and it is broken.

[![enter image description here](https://i.sstatic.net/VtaWY.png)](https://i.sstatic.net/VtaWY.png)

**Tags:** opengl, lighting

> **Comments:**
> **username_1**: How is mat[3] calculated ? I notice your diffuse shading is also broken so I would start by looking at your normals. Maybe outputting the 'norm' variable as your fragment shader output so you can visualise if they are correct.  
> **username_2**: Please copy and paste the text into the question instead of adding screenshots of text. Screenshots aren't searchable so it's harder for people to find and answer your question. They're also not useful to blind people who use a screen-reader to use the site.  

---

## 0 answers

