Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am drawing a simple outline of the world using GL_LINE_STRIPs (in WebGL).

I want to not draw those lines that are on the other side of the spinning globe.

Using Nicol Bolas approach below I am trying to determine if a point is going away from the camera or not:

scene.map = {
    vbo: gl.createBuffer(),
    draw: function(pMatrix,mvMatrix,camera,t) {
        gl.useProgram(this.program);
        gl.uniformMatrix4fv(this.program.pMatrix,false,pMatrix);
        var spin = mat4_rotation(t,[0,1,0]);
        mvMatrix = mat4_multiply(mvMatrix,spin);
        gl.uniformMatrix4fv(this.program.mvMatrix,false,mvMatrix);
        var nMatrix = mat4_inverse(mat4_transpose(mvMatrix));
        gl.uniformMatrix4fv(this.program.nMatrix,false,nMatrix);
        gl.uniform3fv(this.program.camera,camera);
        gl.uniform4fv(this.program.colour,[0,1,0,1]);
        gl.enableVertexAttribArray(this.program.vertex);
        gl.bindBuffer(gl.ARRAY_BUFFER,this.vbo);
        gl.vertexAttribPointer(this.program.vertex,3,gl.FLOAT,false,3*4,0);
        var ofs = 0, parts = this.data.ofs;
        for(var part=0; part<parts.length; part++) {
            var start = ofs;
            ofs += parts[part];
            gl.drawArrays(gl.LINE_STRIP,start,ofs-start);
        }
        gl.disableVertexAttribArray(this.program.vertex);
        gl.bindBuffer(gl.ARRAY_BUFFER,null);
        gl.useProgram(null);
    },
    program: createProgram("precision mediump float;\n"+
            "attribute vec3 vertex;\n"+
            "uniform mat4 pMatrix, mvMatrix, nMatrix;\n"+
            "varying vec3 n;\n"+
            "void main() {\n"+
            "   gl_Position = pMatrix * mvMatrix * vec4(vertex,1.0);\n"+
            "   n = (nMatrix * vec4(vertex,1.0)).xyz;\n"+
            "}\n",
            "precision mediump float;\n"+
            "uniform vec4 colour;\n"+
            "uniform vec3 camera;\n"+
            "varying vec3 n;\n"+
            "void main() {\n"+
            "   if(dot(camera,n) < 0.0) discard;\n"+
            "   gl_FragColor = colour;\n"+
            "}\n",
            ["pMatrix","mvMatrix","colour","camera","nMatrix"],
            ["vertex"]),
    data: getFile("json","data/world.json"),
};
var pts = [], deg2rad = Math.PI/180;
for(var i=0; i<scene.map.data.pts.length; i+=2) {
    var lng = scene.map.data.pts[i] * deg2rad,
        lat = scene.map.data.pts[i+1] * deg2rad;
    pts.push(-Math.cos(lat)*Math.cos(lng),Math.sin(lat),Math.cos(lat)*Math.sin(lng));
}
pts.push(0,0,0); // centre of sphere, for sprite z-culling trick
gl.bindBuffer(gl.ARRAY_BUFFER,scene.map.vbo);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(pts),gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER,null);

and to draw it:

var pMatrix = createPerspective(60,canvas.width/canvas.height,0.1,4),
    eye = [-2,0,0],
    mvMatrix = createLookAt(eye,[0,0,0],[0,1,0]);
scene.map.draw(pMatrix,mvMatrix,eye,t); 

However, this is only drawing the left hemisphere rather than the front:

enter image description here

How can I correctly compute the normal of a point, and the position of the camera?

share|improve this question
2  
Where did you get the dataset for this? –  Nicol Bolas Feb 18 '13 at 23:26
1  
@NicolBolas its thematicmapping.org/downloads/world_borders.php –  Will Feb 19 '13 at 8:24

1 Answer 1

You can't compute the "Z" of this plane because the plane has no Z. If the sphere is not directly in front of the camera, the plane will be tilted relative to the camera. So there isn't a single Z coordinate that will work.

If you were using desktop OpenGL, I would suggest that you compute the plane equation and employ user-defined clip-planes. But that's not available in ES 2.0.

So the only answer that's left is to compute the dot-product between the view direction and the normal at that point. So your vertex shader is going to have to calculate the normal (in camera-space), pass it to the fragment shader, and let the fragment shader do the dot product. If the normal is negative, discard the fragment.

Computing the normal is a bit tricky. See, it's easy to compute it in model space, assuming your planet data set is centered at the origin in model space. You simply normalize the position of the vertex, since the vertex position in model space is a point on the sphere. The problem is transforming that into camera space.

If you can guarantee that mvMatrix does not have any non-uniform scaling applied, then you can simply use that. But otherwise, you need to use the inverse-transpose of the model-view matrix. So you'd need to compute that and pass it to your vertex shader.


As to the code you posted, the camera in camera space is at the origin. That's why it's called "camera space". You don't need to pass it to the shader.

Also, the dot product is between the direction from the camera to the fragment. So you need to compute that. It isn't something you can pass to the fragment shader. You either need to send the camera-space position as a per-vertex varying, or you need to reverse-transform gl_FragCoord to get the camera-space position.

share|improve this answer
    
You also need to know the point on the line-through the camera-to-sphere-centre that is the 'horizon' of the sphere, because that's what you need to compute the normal from. This whole question is superceeded by gamedev.stackexchange.com/questions/49791/… because even if this approach works for the line-art of globe itself, it fails for spites and things I draw on the sphere surface; see the missiles and icons on williame.github.com/ludum_dare_mini_40_MAD (ortho so ignore how I cheated at shading the lines on the back of the sphere) –  Will Feb 21 '13 at 21:00
    
"You also need to know the point on the line-through the camera-to-sphere-centre that is the 'horizon' of the sphere, because that's what you need to compute the normal from." Nonsense. The normal is just direction from the sphere's center to the point on the sphere's surface. This is a simple geometry problem. –  Nicol Bolas Feb 21 '13 at 21:13
    
I have tried to describe how a football looks as you move it closer to your face at gamedev.stackexchange.com/questions/49791/… and there's a diagram too; please give me a chance! –  Will Feb 21 '13 at 21:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.