jPCT-AE - a 3d engine for Android > Support

Moving spot light

(1/2) > >>

iblis:
I need to create spot light (It will be car's light). I want it to look like here http://www.youtube.com/watch?v=7Xx_Rk6wXqU .
I think I should calculate the modelViewMatrix for light (light moves with carBody, so it would be the same matrix), save it as lightMatrix0 and transform light position in each vertex transformation.. but it doesn't work. I've found here http://www.jpct.net/forum2/index.php/topic,2368.0.html how calculate model view matrix:
--- Code: ---mo.setTo(transBuffer);
mat.setTo(cam.getBack());
mat.transformToGL();
mo.translate(-cam.backBx, -cam.backBy, -cam.backBz);
mo.matMul(mat);
--- End code ---
Is it correct? Maybe I do sth wrong?

Vertex Shader:

--- Code: ---uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;

uniform mat4 lightMatrix0; //in my opinion here should be light's model view matrix
uniform vec3 lightPos[2];
uniform vec3 lightDir[2];

attribute vec4 position;
attribute vec3 normal;

varying vec3 eyeMV;
varying vec3 normalMV;
//I want to use 2 lights, but one is easier to test
varying vec3 lightPosMV[2];
varying vec3 lightDirMV[2];

void main(void)
{
normalMV = normalize(modelViewMatrix * vec4(normal, 0.0)).xyz;

vec3 vertex = (modelViewMatrix * position).xyz;
eyeMV = -vertex;

mat4 lightMatrix[2];
lightMatrix[0] = lightMatrix0;

for(int i = 0; i < 1; i++){
    lightDirMV[i] = normalize(lightMatrix[i]* vec4(lightDir[i], 0.0)).xyz;
    vec3 light =normalize( lightMatrix[i] * vec4(lightPos[i], 0.0)).xyz;
    lightPosMV[i] = normalize(light - vertex);
}
gl_Position = modelViewProjectionMatrix * position;
}
--- End code ---
Fragment Shader

--- Code: ---precision mediump float;

uniform vec3 lightDir[2];
varying vec3 eyeMV;
varying vec3 normalMV;
varying vec3 lightPosMV[2];
varying vec3 lightDirMV[2];

const float outerSpot = 0.6;
const float specExp = 64.0;
const vec3 ambient = vec3(0.3, 0.3, 0.3);
const vec3 diffuse = vec3(0.7, 0.7, 0.7);
const vec3 specular = vec3(1.0, 1.0, 1.0);

void main(void)
{
    vec4 color = vec4(ambient, 1.0);
    vec3 eyeN = normalize(eyeMV);
    vec3 normalN = normalize(normalMV);

    for(int i = 0; i < 1; i++){
    vec3 lightPosN = normalize(lightPosMV[i]);
    vec3 lightDirN = normalize(lightDirMV[i]);
    float diff = dot(normalN, lightPosN);

    if(diff >= 0.0){
        float spot = dot(-lightPosN, lightDirN);
        if(spot > outerSpot){
            color += vec4(diff * diffuse, 0.0);
            vec3 ref = normalize(reflect(-lightPosN, normalN));
            float spec = max(0.0, dot(eyeN, ref));
            float buf = pow(spec, specExp);
            color +=  vec4(specular * buf, 0.0);
        }
    }
    }
    gl_FragColor =clamp(color, 0.0, 1.0);
}
--- End code ---
Java

--- Code: ---Matrix light2[] = new Matrix[]{
new Matrix(), new Matrix()
};

Matrix matrixBuf = new Matrix();

private void setUpLights(Car cars[]) {
GLSLShader phong = this.shaders.get("phong");
this.world.setGlobalShader(phong);

Camera camera = world.getCamera();
camera.getPosition(buf);
for (int i = 0; i < 1; i++) {
// I've relied on http://www.jpct.net/forum2/index.php/topic,2368.0.html Is it really create the model view matrix correctly?

cars[i].carBody.object3d.getWorldTransformation(matrixBuf);
light2[i].setTo(matrixBuf);
mat.setTo(camera.getBack());
mat.transformToGL();

light2[i].translate(-buf.x, -buf.y, -buf.z);
light2[i].matMul(mat);

phong.setUniform("lightMatrix"+i, light2[i]);
}
phong.setUniform("lightPos", new SimpleVector[]
{ SimpleVector.create(0.0f, 0.5f, 0.0f), SimpleVector.create(0.0f, 0.5f, 0.0f)});
phong.setUniform("lightDir", new SimpleVector[]
{ SimpleVector.create(0.0f, 0.0f, -1.0f), SimpleVector.create(0.0f, 0.0f, -1.0f)});

}
--- End code ---

Thomas.:
Model view matrix in shader is not needed, you should calculate direction one time when camera or light direction is changed. You can inspire by this example of spot light shader. But take into account per-pixel lighting on mobile devices is not very fast. I am using it in my game, but with 8 spot lights it is running only about 18fps on SGS3 (without post-processing effects).

iblis:
I just need 2-3 lights.
Could you explain me how to calculate camera direction. I can't multiply camera's position and direction by modelViewMatrix because it contains object's transformation.

Thomas.:
If you do it by this way, your game will be only for high-end devices. Anyway you need direction in camera space, by code below you can get it. Probably will be faster if you project "light texture" on the ground. It uses many games, for example GTA...


--- Code: --- public static void vectorWorldToCameraSpace(World world, SimpleVector vector, SimpleVector toFill) {
Camera cam = world.getCamera();
toFill.set(vector);
Matrix back = cam.getBack();
toFill.matMul(back);
}
--- End code ---

iblis:
 Sth is wrong all the time. The problem is connected with the position of the light (or vector to the light).

Java

--- Code: ---public void vectorWorldToCameraSpace(SimpleVector vector,
SimpleVector toFill) {

Camera cam = world.getCamera();
toFill.set(vector);
Matrix back = cam.getBack();
toFill.matMul(back);
}

private void setUpLights() {
GLSLShader phong = this.shaders.get("phong");
this.world.setGlobalShader(phong);

SimpleVector dir[] = new SimpleVector[] {
SimpleVector.create(0.0f, 0.0f, 1.0f),
SimpleVector.create(0.0f, 0.0f, 1.0f) };

for (int i = 0; i < 2; i++) {

box.getTransformedCenter(pos[i]); //So light should be in the center of box (0, 0, 0)
vectorWorldToCameraSpace(pos[i], posBuf[i]);
vectorWorldToCameraSpace(dir[i], dirBuf[i]);
}
phong.setUniform("lightPos", posBuf);
phong.setUniform("lightDir", dirBuf);

}
--- End code ---
Vertex Shader

--- Code: ---uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;


uniform vec3 lightPos[2];
uniform vec3 lightDir[2];

attribute vec4 position;
attribute vec3 normal;

varying vec3 eyeMV;
varying vec3 normalMV;
//I want to use 2 lights, but one is easier to test
varying vec3 lightPosMV[2];
varying vec3 lightDirMV[2];

void main(void)
{
normalMV = normalize(modelViewMatrix * vec4(normal, 0.0)).xyz;

vec3 vertex = (modelViewMatrix * position).xyz;
eyeMV = -vertex;

for(int i = 0; i < 2; i++){
    lightDirMV[i] = normalize(lightDir[i]);
    vec3 light = lightPos[i];
    lightPosMV[i] = normalize(light - vertex);
}
gl_Position = modelViewProjectionMatrix * position;
}
--- End code ---
Fragment Shader

--- Code: ---precision mediump float;

varying vec3 normalMV;
varying vec3 lightPosMV[2];
varying vec3 lightDirMV[2];

const float outerSpot = 0.6;
const vec3 ambient = vec3(0.2, 0.2, 0.2);
const vec3 diffuse = vec3(0.7, 0.7, 0.7);

void main(void)
{
    vec4 color = vec4(ambient, 1.0);
    vec3 normalN = normalize(normalMV);

    for(int i = 0; i < 1; i++){
    vec3 lightPosN = normalize(lightPosMV[i]);
    vec3 lightDirN = normalize(lightDirMV[i]);
    float diff = dot(normalN, lightPosN);

    if(diff >= 0.0){
        float spot = dot(-lightPosN, lightDirN);
        if(spot > outerSpot){
            color += vec4(diff * diffuse, 0.0);
        }
    }
    }
    gl_FragColor =clamp(color, 0.0, 1.0);
}
--- End code ---

Navigation

[0] Message Index

[#] Next page

Go to full version