<p>If I'm guessing right, you are drawing a plane which is facing the camera, so your normals need to be 0,0,-1.</p>

<p>change</p>

<p>double[] N=normalize((new double[]{pos[0],pos[1],1}));</p>

<p>to</p>

<p>double[] N=normalize((new double[]{0,0,-1}));</p>

CC BY-SA 3.0
2016-07-20T09:52:53.937Z
Thanks for your reply. I try this but I only have the ambiant color
boykely
CC BY-SA 3.0
2016-07-20T09:55:40.323Z
Maybe flip the sign. I'm not sure what your intention for the normals is, but for a plane every pixel should have the same normal.
PaulHK
CC BY-SA 3.0
2016-07-20T09:57:18.407Z
Yes I try -1 and then 1. My purpose is to have a circular specular on the surface plane
boykely
CC BY-SA 3.0
2016-07-20T10:06:16.520Z
The half-vector takes care of this normally, this will vary across your image. It looks like you are close to what you are intending, just something is on the wrong axis, at a guess. I encountered this problem and had similar results several times, was almost always down to incorrectly working out the eye-space/half-vector.
PaulHK
CC BY-SA 3.0
2016-07-20T10:17:42.097Z
Looking a bit more at your code example, the L vector calculation looks wrong. Should that not just be the world-space light vector?(Lum). Your lambert calculation would be something like dot( N={0,0,-1}, L={0,0,1} ) for the whole surface, which should return an intensity of 1 for the diffuse component.
PaulHK
CC BY-SA 3.0
2016-07-28T10:12:28.170Z
I edited my post. I change the way to compute L and E vectors and I get some inverse specular lobe
boykely
CC BY-SA 3.0
2016-08-01T06:41:57.193Z
Getting close, maybe negate the half vector ?
PaulHK
CC BY-SA 3.0
2016-07-20T08:43:25.277Z
2016-07-20T08:43:25.277Z
PaulHK
<p>I am trying to render Blinn Phong as a BRDF model on a surface plane. I assume that every normal in every pixel is perpendicular with the plane.
I know that to do a rendering we have to use 3d programing API such as OpenGL or WebGL and so on.<br>
My purpose is to render the surface plane without those APIs. The steps that I take are, I create 2 spaces:</p>

<ol>
<li>image space: (0,0) is at the top left of the image.</li>
<li>camera space: (0,0) is at the middle of the image.</li>
</ol>

<p>For vector computation, I convert every pixel position of image space to camera space then to world space.</p>

<pre class="lang-cpp prettyprint-override"><code>double[] cam=((new double[]{0,0,1}));
double[] lum=((new double[]{0,0,1}));
double[] E=new double[3];
double[] L=new double[3];
double[] H=new double[3];
double D2;
Mat image=new Mat(rows,cols,CvType.CV_8UC3);
System.out.println("Start!!");
System.out.println("ok");
for(int i=0;i&lt;tileHNumber;i++)
{
    for(int j=0;j&lt;tileWNumber;j++)
    {
        for(int s=0;s&lt;192;s++)
        {
            for(int t=0;t&lt;192;t++)
            {
                originS=s+192*i;//ligne
                originT=t+192*j;//colonne
                double[] pos=(Image2Cam(new double[]{originT,originS,0}));
                E=normalize(XY(cam,pos));
                L=normalize(XY(lum, pos);
                double[] le=addXY(L,E);
                H=normalize(le);
                D2=dot(E,E);
                double blue=color(blueColor,pos,E,L,H,D2);
                double green=color(greenColor,pos,E,L,H,D2);
                double red=color(redColor,pos,E,L,H,D2);
                image.put(originS, originT, new byte[]{(byte)(blue),(byte)(green),(byte)(red)});
            }
        }
    }
}
public static double color(double col,double[] pos,double[] E,double[] L,double[] H,double D2)
{
    double value=0;
    double[] N=normalize((new double[]{pos[0],pos[1],1}));
    double diffuse=Math.max(0, dot(N,L));
    double specular=Math.pow(Math.max(0, dot(N,H)),60);
    value=d*diffuse*0.5+0.2*d+specular*255*0.3;
    return value;
}
</code></pre>

<p>The 2 images below show my results: the first one shows diffuse image only. The second one shows specular image only represented by the white color. </p>

<p>My question is why the lobe specular is not surrounding the center of the image.</p>

<p><a href="https://i.sstatic.net/7yBBh.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/7yBBh.jpg" alt="Diffuse image"></a>
<a href="https://i.sstatic.net/A1h2s.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/A1h2s.jpg" alt="Specular image"></a></p>

CC BY-SA 3.0
2016-07-20T07:01:38.030Z
To add, this is usually seen when the light direction is near parallel to the surface (like a sunset scene). When the light direction is perpendicular the specular highlight becomes much more circular. I would check your normal calculation in color(..), it looks like it is producing a normal that isn't perpendicular to your plane. Something like {0,0,-1} should be correct and facing towards your {0,0,1} light, not {pos.x,pos.y,1} like it currently is
PaulHK
CC BY-SA 3.0
2016-07-29T10:48:23.123Z
It appears that the new images that have replaced the old ones show a new and unrelated problem. Would this be better posted as a new question, so that the old problem is still here for future readers? There is some [discussion on meta](http://meta.computergraphics.stackexchange.com/a/182/231) about this general point.
trichoplax is on Codidact now
CC BY-SA 3.0
2016-08-29T02:53:07.970Z
Yeah, my comments make no sense now the question has been updated.
PaulHK
CC BY-SA 3.0
2016-09-02T19:59:30.123Z
I did not figure out how to resolve it.
boykely
<rendering><brdf>
Blinn Phong rendering
boykely
# Blinn Phong rendering

(Asked by: username_0 on 2016-07-19)

I am trying to render Blinn Phong as a BRDF model on a surface plane. I assume that every normal in every pixel is perpendicular with the plane.
I know that to do a rendering we have to use 3d programing API such as OpenGL or WebGL and so on.  
My purpose is to render the surface plane without those APIs. The steps that I take are, I create 2 spaces:

1. image space: (0,0) is at the top left of the image.
2. camera space: (0,0) is at the middle of the image.

For vector computation, I convert every pixel position of image space to camera space then to world space.

```cpp
double[] cam=((new double[]{0,0,1}));
double[] lum=((new double[]{0,0,1}));
double[] E=new double[3];
double[] L=new double[3];
double[] H=new double[3];
double D2;
Mat image=new Mat(rows,cols,CvType.CV_8UC3);
System.out.println("Start!!");
System.out.println("ok");
for(int i=0;i<tileHNumber;i++)
{
    for(int j=0;j<tileWNumber;j++)
    {
        for(int s=0;s<192;s++)
        {
            for(int t=0;t<192;t++)
            {
                originS=s+192*i;//ligne
                originT=t+192*j;//colonne
                double[] pos=(Image2Cam(new double[]{originT,originS,0}));
                E=normalize(XY(cam,pos));
                L=normalize(XY(lum, pos);
                double[] le=addXY(L,E);
                H=normalize(le);
                D2=dot(E,E);
                double blue=color(blueColor,pos,E,L,H,D2);
                double green=color(greenColor,pos,E,L,H,D2);
                double red=color(redColor,pos,E,L,H,D2);
                image.put(originS, originT, new byte[]{(byte)(blue),(byte)(green),(byte)(red)});
            }
        }
    }
}
public static double color(double col,double[] pos,double[] E,double[] L,double[] H,double D2)
{
    double value=0;
    double[] N=normalize((new double[]{pos[0],pos[1],1}));
    double diffuse=Math.max(0, dot(N,L));
    double specular=Math.pow(Math.max(0, dot(N,H)),60);
    value=d*diffuse*0.5+0.2*d+specular*255*0.3;
    return value;
}

```

The 2 images below show my results: the first one shows diffuse image only. The second one shows specular image only represented by the white color.

My question is why the lobe specular is not surrounding the center of the image.

[![Diffuse image](https://i.sstatic.net/7yBBh.jpg)](https://i.sstatic.net/7yBBh.jpg)
[![Specular image](https://i.sstatic.net/A1h2s.jpg)](https://i.sstatic.net/A1h2s.jpg)

**Tags:** rendering, brdf

> **Comments:**
> **username_1**: To add, this is usually seen when the light direction is near parallel to the surface (like a sunset scene). When the light direction is perpendicular the specular highlight becomes much more circular. I would check your normal calculation in color(..), it looks like it is producing a normal that isn't perpendicular to your plane. Something like {0,0,-1} should be correct and facing towards your {0,0,1} light, not {pos.x,pos.y,1} like it currently is  
> **username_2**: It appears that the new images that have replaced the old ones show a new and unrelated problem. Would this be better posted as a new question, so that the old problem is still here for future readers? There is some [discussion on meta](http://meta.computergraphics.stackexchange.com/a/182/231) about this general point.  
> **username_1**: Yeah, my comments make no sense now the question has been updated.  
> **username_0**: I did not figure out how to resolve it.  

---

## 1 answers

### Answer by username_1 on 2016-07-20. Score: 1

If I'm guessing right, you are drawing a plane which is facing the camera, so your normals need to be 0,0,-1.

change

double[] N=normalize((new double[]{pos[0],pos[1],1}));

to

double[] N=normalize((new double[]{0,0,-1}));

> **Comments:**
> **username_0**: Thanks for your reply. I try this but I only have the ambiant color  
> **username_1**: Maybe flip the sign. I'm not sure what your intention for the normals is, but for a plane every pixel should have the same normal.  
> **username_0**: Yes I try -1 and then 1. My purpose is to have a circular specular on the surface plane  
> **username_1**: The half-vector takes care of this normally, this will vary across your image. It looks like you are close to what you are intending, just something is on the wrong axis, at a guess. I encountered this problem and had similar results several times, was almost always down to incorrectly working out the eye-space/half-vector.  
> **username_1**: Looking a bit more at your code example, the L vector calculation looks wrong. Should that not just be the world-space light vector?(Lum). Your lambert calculation would be something like dot( N={0,0,-1}, L={0,0,1} ) for the whole surface, which should return an intensity of 1 for the diffuse component.  
> **username_0**: I edited my post. I change the way to compute L and E vectors and I get some inverse specular lobe  
> **username_1**: Getting close, maybe negate the half vector ?  

---

