wglb

01-26-2011, 12:42 PM

Hi,

I'm in the middle of creating a game which uses lighting (1 light, per fragment, ambient + diffuse for now) (I follow giles' lessons: http://learningwebgl.com/blog/?page_id=1217).

I have camera which is set in well known way in every frame:

var lightPos = [50, 100, 0];

var frame = function() {

...

loadIdentityMV();

camera.lookAt(cameraPos, cameraTarget, cameraUp);

// light

gl.uniform3fv(ambientColorLoc, ambientColor);

gl.uniform3fv(lightColorLoc, lightColor);

gl.uniform3fv(lightPosLoc, lightPos));

...

}

Here are shaders' code

/* vertex shader */

uniform mat4 uMVMatrix;

uniform mat4 uProjMatrix;

uniform mat4 uNormalMatrix;

attribute vec3 aVertexPosition;

attribute vec3 aVertexNormal;

attribute vec2 aTextureCoord;

varying vec2 vTextureCoord;

varying vec4 vPosition;

varying vec4 vNormal;

void main(void) {

vPosition = uMVMatrix * vec4(aVertexPosition, 1.0);

gl_Position = uProjMatrix * vPosition;

vTextureCoord = aTextureCoord;

vNormal = uNormalMatrix * vec4(aVertexNormal, 1.0);

}

/* fragment shader */

#ifdef GL_ES

precision highp float;

#endif

uniform vec3 uAmbientColor;

uniform vec3 uLightPos;

uniform vec3 uLightColor;

uniform sampler2D uSampler;

varying vec2 vTextureCoord;

varying vec4 vPosition;

varying vec4 vNormal;

void main(void) {

vec3 lightDirection = normalize(uLightPos - vPosition.xyz);

float diffuseFactor = max(dot(normalize(vNormal.xyz), lightDirection), 0.0);

vec3 lightFactor = uAmbientColor + uLightColor * diffuseFactor;

vec4 texColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));

gl_FragColor = vec4(texColor.rgb * lightFactor, texColor.a);

}

I don't change light's position, so it's always expressed in eyes coordinates, right (or am I wrong)? Therefore when camera moves / rotates then the light follows the camera what is not what I want - in my case (and in 99% other games / apps) light should stay in one place (in world coordinates) independently to the camera.

So how (and when) to transform light's position to have it in the world coordinates?

Is it multiplying lightPos by mvMatrix just after camera.lookAt(pos, target, up) ?

Thanks,

wglb (gliniak)

I'm in the middle of creating a game which uses lighting (1 light, per fragment, ambient + diffuse for now) (I follow giles' lessons: http://learningwebgl.com/blog/?page_id=1217).

I have camera which is set in well known way in every frame:

var lightPos = [50, 100, 0];

var frame = function() {

...

loadIdentityMV();

camera.lookAt(cameraPos, cameraTarget, cameraUp);

// light

gl.uniform3fv(ambientColorLoc, ambientColor);

gl.uniform3fv(lightColorLoc, lightColor);

gl.uniform3fv(lightPosLoc, lightPos));

...

}

Here are shaders' code

/* vertex shader */

uniform mat4 uMVMatrix;

uniform mat4 uProjMatrix;

uniform mat4 uNormalMatrix;

attribute vec3 aVertexPosition;

attribute vec3 aVertexNormal;

attribute vec2 aTextureCoord;

varying vec2 vTextureCoord;

varying vec4 vPosition;

varying vec4 vNormal;

void main(void) {

vPosition = uMVMatrix * vec4(aVertexPosition, 1.0);

gl_Position = uProjMatrix * vPosition;

vTextureCoord = aTextureCoord;

vNormal = uNormalMatrix * vec4(aVertexNormal, 1.0);

}

/* fragment shader */

#ifdef GL_ES

precision highp float;

#endif

uniform vec3 uAmbientColor;

uniform vec3 uLightPos;

uniform vec3 uLightColor;

uniform sampler2D uSampler;

varying vec2 vTextureCoord;

varying vec4 vPosition;

varying vec4 vNormal;

void main(void) {

vec3 lightDirection = normalize(uLightPos - vPosition.xyz);

float diffuseFactor = max(dot(normalize(vNormal.xyz), lightDirection), 0.0);

vec3 lightFactor = uAmbientColor + uLightColor * diffuseFactor;

vec4 texColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));

gl_FragColor = vec4(texColor.rgb * lightFactor, texColor.a);

}

I don't change light's position, so it's always expressed in eyes coordinates, right (or am I wrong)? Therefore when camera moves / rotates then the light follows the camera what is not what I want - in my case (and in 99% other games / apps) light should stay in one place (in world coordinates) independently to the camera.

So how (and when) to transform light's position to have it in the world coordinates?

Is it multiplying lightPos by mvMatrix just after camera.lookAt(pos, target, up) ?

Thanks,

wglb (gliniak)