<p>You probably need to calculate the reflection vector per pixel, not per vertex. The calculation is non-linear, so doing it per vertex and interpolating will not give good results unless the model is finely tesselated.</p>

<p>Send <code>norm</code> and <code>toCameraVector</code> down to the pixel shader, normalize them both and move all your calculations under <code>// Reflection Map</code> to the pixel shader. That should give you some better results.</p>

CC BY-SA 3.0
2017-05-11T04:36:00.023Z
If the normals are varying between vertices, why should the tesselation be so important?
Jack
CC BY-SA 3.0
2017-05-11T04:53:13.783Z
@Jackalope Tessellating more finely means the normals will be evaluated correctly at each tessellated vertex, and interpolated over a shorter distance between vertices, so the error due to using linear interpolation will be reduced.
Nathan Reed
CC BY-SA 3.0
2016-03-14T21:29:39.643Z
2016-03-14T21:29:39.643Z
Nathan Reed
<p>I'm trying to achieve the same effect in OpenGL/GLSL as what Blender does when you add a texture, set to "Reflection"</p>

<p>This ultimately is a way to fake specularity, or "metallicness" if I get it right.</p>

<p>I followed this tutorial (Mid-page, "Sphere Mapping" section):
<a href="http://www.ozone3d.net/tutorials/glsl_texturing_p04.php" rel="nofollow">http://www.ozone3d.net/tutorials/glsl_texturing_p04.php</a></p>

<p>Here's the problem(some serious artifacts):
<a href="https://www.youtube.com/watch?v=hx66_xWhVu4&amp;feature=youtu.be" rel="nofollow">https://www.youtube.com/watch?v=hx66_xWhVu4&amp;feature=youtu.be</a></p>

<p>Everything's happening at the bottom of the Vertex Sahder:</p>

<pre><code>#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;
layout(location = 2) in vec3 vertexNormal_modelspace;
layout(location = 3) in vec3 vertexTangent_modelspace;

out vec2 uv;
out vec3 toLightVector[4];
out vec3 toCameraVector;
out float fog_Visibility;

uniform mat4 FTM;
uniform mat4 P;
uniform mat4 V;
uniform vec3 LP[4];

const float fog_Density = 0.2;
const float fog_Gradient = 0.9;

void main(){

    vec4 worldPosition = FTM * vec4(vertexPosition_modelspace, 1.0);
    uv = vertexUV;

    vec3 surfaceNormal = (FTM * vec4(vertexNormal_modelspace, 0.0)).xyz;

    vec3 norm = normalize(surfaceNormal);
    vec3 tang = normalize((FTM * vec4(vertexTangent_modelspace, 0.0)).xyz);
    vec3 bitang = normalize(cross(norm, tang));

    mat3 toTangentSpace = mat3(tang.x, bitang.x, norm.x, tang.y, bitang.y, norm.y, tang.z, bitang.z, norm.z);

    for (int i = 0; i &lt; 4; i++) {
        toLightVector[i] = toTangentSpace * (LP[i] - worldPosition.xyz);
    }

    toCameraVector = toTangentSpace * ((inverse(V) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz);

    vec4 positionRelativeToCam = V * worldPosition;
    gl_Position = P * positionRelativeToCam;

    // Fog
    float fog_Distance = length(positionRelativeToCam.xyz);
    fog_Visibility = exp(-pow((fog_Distance * fog_Density), fog_Gradient));
    fog_Visibility = clamp(fog_Visibility, 0.0, 1.0);

    // Reflection Map
    vec3 u = normalize(toCameraVector);
    vec3 r = reflect(u, norm);
    float m = 2.0 * sqrt(r.x*r.x + r.y*r.y + (r.z + 1.0)*(r.z + 1.0));

    gl_TexCoord[0].s = r.x / m + 0.5;
    gl_TexCoord[0].t = r.y / m + 0.5;
}
</code></pre>

<p>And in the Fragment Shader, all I do is:</p>

<pre><code>out_color = texture(reflectionSampler, gl_TexCoord[0].st);
</code></pre>

<p>The reflection map seems to do it's thing similarly to the way it's seen in Blender, but not quite.</p>

<p>I need to be able to do this without calculating lights. Thats how Blender does it, it works Shadeless mode so all it should take is the camera's vector...</p>

<opengl><shader><glsl>
Guidance with Sphere-Map calculation in GLSL
GDN9
# Guidance with Sphere-Map calculation in GLSL

(Asked by: username_0 on 2016-03-14)

I'm trying to achieve the same effect in OpenGL/GLSL as what Blender does when you add a texture, set to "Reflection"

This ultimately is a way to fake specularity, or "metallicness" if I get it right.

I followed this tutorial (Mid-page, "Sphere Mapping" section):
<http://www.ozone3d.net/tutorials/glsl_texturing_p04.php>

Here's the problem(some serious artifacts):
<https://www.youtube.com/watch?v=hx66_xWhVu4&feature=youtu.be>

Everything's happening at the bottom of the Vertex Sahder:

```
#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;
layout(location = 2) in vec3 vertexNormal_modelspace;
layout(location = 3) in vec3 vertexTangent_modelspace;

out vec2 uv;
out vec3 toLightVector[4];
out vec3 toCameraVector;
out float fog_Visibility;

uniform mat4 FTM;
uniform mat4 P;
uniform mat4 V;
uniform vec3 LP[4];

const float fog_Density = 0.2;
const float fog_Gradient = 0.9;

void main(){

    vec4 worldPosition = FTM * vec4(vertexPosition_modelspace, 1.0);
    uv = vertexUV;

    vec3 surfaceNormal = (FTM * vec4(vertexNormal_modelspace, 0.0)).xyz;

    vec3 norm = normalize(surfaceNormal);
    vec3 tang = normalize((FTM * vec4(vertexTangent_modelspace, 0.0)).xyz);
    vec3 bitang = normalize(cross(norm, tang));

    mat3 toTangentSpace = mat3(tang.x, bitang.x, norm.x, tang.y, bitang.y, norm.y, tang.z, bitang.z, norm.z);

    for (int i = 0; i < 4; i++) {
        toLightVector[i] = toTangentSpace * (LP[i] - worldPosition.xyz);
    }

    toCameraVector = toTangentSpace * ((inverse(V) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz);

    vec4 positionRelativeToCam = V * worldPosition;
    gl_Position = P * positionRelativeToCam;

    // Fog
    float fog_Distance = length(positionRelativeToCam.xyz);
    fog_Visibility = exp(-pow((fog_Distance * fog_Density), fog_Gradient));
    fog_Visibility = clamp(fog_Visibility, 0.0, 1.0);

    // Reflection Map
    vec3 u = normalize(toCameraVector);
    vec3 r = reflect(u, norm);
    float m = 2.0 * sqrt(r.x*r.x + r.y*r.y + (r.z + 1.0)*(r.z + 1.0));

    gl_TexCoord[0].s = r.x / m + 0.5;
    gl_TexCoord[0].t = r.y / m + 0.5;
}

```

And in the Fragment Shader, all I do is:

```
out_color = texture(reflectionSampler, gl_TexCoord[0].st);

```

The reflection map seems to do it's thing similarly to the way it's seen in Blender, but not quite.

I need to be able to do this without calculating lights. Thats how Blender does it, it works Shadeless mode so all it should take is the camera's vector...

**Tags:** opengl, shader, glsl


---

## 1 answers

### Answer by username_1 on 2016-03-14. Score: 3

You probably need to calculate the reflection vector per pixel, not per vertex. The calculation is non-linear, so doing it per vertex and interpolating will not give good results unless the model is finely tesselated.

Send `norm` and `toCameraVector` down to the pixel shader, normalize them both and move all your calculations under `// Reflection Map` to the pixel shader. That should give you some better results.

> **Comments:**
> **username_2**: If the normals are varying between vertices, why should the tesselation be so important?  
> **username_1**: @Jackalope Tessellating more finely means the normals will be evaluated correctly at each tessellated vertex, and interpolated over a shorter distance between vertices, so the error due to using linear interpolation will be reduced.  

---

