PDA

View Full Version : gl_FrontFacing



giuseppe500
09-04-2011, 04:26 AM
hello.
I'm trying to create a double face shader in opengl, i do test with this shader on a model .

#ifdef GL_ES
precision highp float;
#endif
uniform vec3 CameraModelPosition;
uniform vec3 ColorFront;
uniform vec3 ColorBack;
varying vec3 vLightWeighting;
varying vec3 vNormal;
varying vec3 transformedNormal;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {


gl_FragColor = vec4(ColorFront.xyz,1.0);
float Dir = dot(transformedNormal,CameraModelPosition);

if(gl_FrontFacing){
// vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s,vTextureCoord.t));
// gl_FragColor = vec4(textureColor.rgb, textureColor.a);
gl_FragColor = vec4(1.0, 1.0, 0.0,1.0);
}
else {
gl_FragColor = vec4(1.0, 0.0, 0.0,1.0);
}

}

but this is the result:
http://gferrari77.altervista.org/Immagine.jpg

how is possible that i look at a triangle that is in my camera space and gl_frontFacing returns false?
using the Dir and test if is >0 works, but when moves the camera some faces disappearing and reappear, there is a lot of instability.
But i think that i'm searching if a face is in front of the camera or not(the gl_Frontfacing is more complex and is related to the winding order), then is correct the Dir, so the formula must be correct , this is my complete shader:

<script id="Script2" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;

uniform vec3 uAmbientColor;
uniform vec3 uLightingDirection;
uniform vec3 uLightingDirection2;
uniform vec3 uColor;
//uniform vec3 uDirectionalColor;

varying vec3 vLightWeighting;

void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);

vec3 uDirectionalColor = vec3(1,1,1);
vec3 transformedNormal = uNMatrix * aVertexNormal;

float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0) ;
vLightWeighting = uDirectionalColor * directionalLightWeighting * uColor;

float directionalLightWeighting2 = max(dot(transformedNormal, uLightingDirection2), 0.0) ;
vLightWeighting += uDirectionalColor * directionalLightWeighting2 * uColor ;

}
</script>

<script id="DoubleColorf" type="x-shader/x-fragment">
#ifdef GL_ES
precision highp float;
#endif
uniform vec3 CameraModelPosition;
uniform vec3 ColorFront;
uniform vec3 ColorBack;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
varying vec3 vNormal;
varying vec3 transformedNormal;


void main(void) {
float Dir = dot(transformedNormal,CameraModelPosition);
//float Dir = -10.0;

if(Dir > (CameraModelPosition.z * 1.0)-100.0){
//gl_FragColor = vec4(1.0,0.0,0.0,1.0);
gl_FragColor = vec4(ColorFront.xyz,1.0);
}
else {
gl_FragColor = vec4(ColorBack.xyz,1.0);
}
}
and this is my formula :

float Dir = dot(transformedNormal,CameraModelPosition);


i trying
if(Dir > (CameraModelPosition.z -DELTA)
for correct, but how big must be the delta?
is corrct put the z of camera in the test?


thanks.
thanks.

malexander
09-04-2011, 05:42 PM
how is possible that i look at a triangle that is in my camera space and gl_frontFacing returns false?

To determine which way a triangle is facing, a cross product is done with two edges - cross(v1-v0, v2-v0). This is then tested against the view direction, and this determines whether you're looking at the front or back side of the triangle.
gl_FrontFacing contains the result of this test.

Since cross(v1-v0, v2-v0) = -cross(v2-v0, v1-v0), the order in which the vertices occur determine which side of the triangle is the front. This is why the vertex winding is important; it defines your front face.

You can set the vertex winding to be GL_CW or GL_CCW using glFrontFace(). However, you still need to be consistent with your vertex winding when drawing triangles (or quads/polys). Note that triangle strips automatically adjust for the fact that alternating triangles have opposite winding.

giuseppe500
09-05-2011, 04:31 AM
thanks.
But my problem is another , sorry if i'm explain bad.
I would know in the fragment shader if the face is in front of my camera or back.
I do not care of the winding order, only of the front / back, is for this that i wouldn't use gl_frontfacing but something like :
float Dir = dot(-transformedNormal,CameraModelPosition);
if(Dir > 0) draw as front face
if(Dir <0) draw back as back face

but i don't know how use it correctly , because some times this calculation is not correct , and some faces that should be front are drawed as back.
is possible to use a delta for correct the instruction?
how?

strattonbrazil
09-08-2011, 11:26 PM
float Dir = dot(-transformedNormal,CameraModelPosition);
if(Dir > 0) draw as front face
if(Dir <0) draw back as back face


What does this supposed to do? Is CameraModelPosition a poorly-named vector? If this is the camera you happen to be rendering from, you shouldn't be processing any fragments behind the camera at all because they never make it to the screen.

If this camera is not the one you're rendering from, you need to know if the fragment is in front of your camera? That doesn't require a normal. That's the dot of your camera look_dir against the vector of your camera to the fragment. Mind that those vectors are in the same space.

If you also want to check that the fragment is facing the camera, that's the dot of the normal against the look_dir similar to what you're doing.

giuseppe500
09-09-2011, 03:55 AM
thanks , but i'm not understand at all, what is look_dir and what is "the vector of your camera".
I post the shader and the matrix that i use for multiply the normal:


<script id="DoubleColorf" type="x-shader/x-fragment">
#ifdef GL_ES
precision highp float;
#endif
uniform vec3 CameraModelPosition;
uniform vec3 ColorFront;
uniform vec3 ColorBack;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
varying vec3 vNormal;
varying vec3 transformedNormal;


void main(void) {
float Dir = dot(transformedNormal,CameraModelPosition);

if(Dir >0.0){
gl_FragColor = vec4(ColorFront.xyz,1.0);
}
else {
gl_FragColor = vec4(ColorBack.xyz,1.0);
}
}
</script>

<script id="DoubleColorv" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;

uniform vec3 uAmbientColor;
uniform vec3 uLightingDirection;
uniform vec3 uLightingDirection2;
uniform vec3 CameraModelPosition;

uniform vec3 ColorFront;
uniform vec3 ColorBack;
varying vec3 transformedNormal;
varying vec3 vLightWeighting;
varying vec3 vLightWeightingback;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);

vec3 uDirectionalColor = vec3(1,1,1);

transformedNormal = uNMatrix * aVertexNormal;

float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0) ;
vLightWeighting = uDirectionalColor * directionalLightWeighting * ColorFront ;

float directionalLightWeighting2 = max(dot(transformedNormal, uLightingDirection2), 0.0) ;
vLightWeighting += uDirectionalColor * directionalLightWeighting2 * ColorFront ;

float directionalLightWeightingback = max(dot(transformedNormal, uLightingDirection), 0.0) ;
vLightWeightingback = uDirectionalColor * directionalLightWeightingback * ColorBack ;

float directionalLightWeighting2back = max(dot(transformedNormal, uLightingDirection2), 0.0) ;
vLightWeightingback += uDirectionalColor * directionalLightWeighting2back * ColorBack ;
}
</script>


uNMatrix is calculated from the modelview matrix(this.m_MVmatrix) like:


this.m_InvMatrix = mat3.create();
mat4.toInverseMat3(this.m_MVmatrix, this.m_InvMatrix);
mat3.transpose(this.m_InvMatrix);



the mesh is displayed uncorrectly , there are some change of front/back face when i move the camera .


sorry for my english and for my ignorance on the subject

thanks

strattonbrazil
09-09-2011, 05:34 AM
Okay, let's step back for a second and do some sanity checks.

If you set your outgoing fragment color to a flat color based only on gl_FrontFacing, do you get what you'd expect? That's important before you even start worrying about lighting.

giuseppe500
09-09-2011, 06:43 AM
thanks for the reply.
i'm expect that the faces that are in front of the camera are colored ColorFront and the faces that are back to the camera are invisible or colored backcolor when i rotates the camera after the dot product is -1.
Where I'm wrong?

_arts_
09-09-2011, 07:14 AM
malexander said you absolutely everything for you to understand why.

If you have a polygon (A,B,C), and draw it on screen. If you always keep the same camera and same position and orientation of your polygon, you'll have (A,B,C) visible or invisible regarding its winding. If you choose the order A,B and C for one render, then you'll have the polygon drawn or not drawn. If you change the order to C,B,A then you'll have the opposite (if it was drawn before, it won't now, and if it wasn't drawn before, it will be drawn now).

Alfonse Reinheart
09-09-2011, 02:33 PM
Note that _arts_ is assuming you have turned on face-culling. If you have not, then it will be draw either way. So make sure you have glDisable(GL_CULL_FACE); that's the default, but it never hurts to make sure.

strattonbrazil
09-09-2011, 02:41 PM
thanks for the reply.
i'm expect that the faces that are in front of the camera are colored ColorFront and the faces that are back to the camera are invisible or colored backcolor when i rotates the camera after the dot product is -1.
Where I'm wrong?

What are you using the dot product for? Just see if the polygons are facing the correct way using ONLY gl_FrontFacing. No lighting, no normals, nothing. Something like this:

gl_FragColor = vec4(gl_FrontFacing,0.0,0.0,1.0);

That will tell you if your polygons are being ordered correctly.