How to set directional light and light euler angle?

Started by jaychang0917, April 13, 2017, 12:29:18 PM

Previous topic - Next topic

jaychang0917

Does jpct-ae support directional light? And how to set the light euler angle? Thanks!

EgonOlsen

No, not by default. If you want that, you have to write your own shader for it.

jaychang0917

Quote from: EgonOlsen on April 13, 2017, 02:02:38 PM
No, not by default. If you want that, you have to write your own shader for it.

oh... i found the shader code for directional light (from http://www.lighthouse3d.com/tutorials/glsl-12-tutorial/directional-lights-i/), but i don't know where i can change the light intensity and light euler angle. can u give me some hint?

vertex shader

void main()
{
vec3 normal, lightDir;
vec4 diffuse, ambient, globalAmbient;
float NdotL;

normal = normalize(gl_NormalMatrix * gl_Normal);
lightDir = normalize(vec3(gl_LightSource[0].position));
NdotL = max(dot(normal, lightDir), 0.0);
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
/* Compute the ambient and globalAmbient terms */

ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
globalAmbient = gl_LightModel.ambient * gl_FrontMaterial.ambient;
gl_FrontColor =  NdotL * diffuse + globalAmbient + ambient;

gl_Position = ftransform();
}


fragment shader

void main()
{
gl_FragColor = gl_Color;
}

EgonOlsen

That's not an OpenGL ES shader...It's not really worth it to convert it to ES. You might want to extract jpct-ae's jar and have a look at the default shaders. It might be easier to add some directional lighting code to one of these and use that instead.

jaychang0917

#4
Quote from: EgonOlsen on April 14, 2017, 12:42:28 AM
That's not an OpenGL ES shader...It's not really worth it to convert it to ES. You might want to extract jpct-ae's jar and have a look at the default shaders. It might be easier to add some directional lighting code to one of these and use that instead.
I changed the defaultVertexShader.src as follow:

uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;

uniform vec4 additionalColor;
uniform vec4 ambientColor;

uniform float alpha;
uniform float shininess;
uniform bool useColors;

uniform float fogStart;
uniform float fogEnd;
uniform vec3 fogColor;

uniform int lightCount;

uniform vec3 lightPositions[8];
uniform vec3 diffuseColors[8];
uniform vec3 specularColors[8];
uniform float attenuation[8];

attribute vec4 position;
attribute vec3 normal;
attribute vec4 color;
attribute vec2 texture0;
attribute vec2 texture1;
attribute vec2 texture2;
attribute vec2 texture3;

varying vec2 texCoord[4];
varying vec4 vertexColor;
varying vec3 fogVertexColor;
varying float fogWeight;

const vec4 WHITE = vec4(1,1,1,1);

void main() {

texCoord[0] = (textureMatrix * vec4(texture0, 0, 1)).xy;
texCoord[1] = texture1;
texCoord[2] = texture2;
texCoord[3] = texture3;

vec4 vertexPos = modelViewMatrix * position;
vertexColor = ambientColor + additionalColor;

if (lightCount>0) {
// This is correct only if the modelview matrix is orthogonal. In jPCT-AE, it always is...unless you fiddle around with it.
vec3 normalEye   = normalize(modelViewMatrix * vec4(normal, 0.0)).xyz;

vec3 surface2Light=normalize(lightPositions[0]  - vertexPos.xyz);
float angle = dot(normalEye, surface2Light);

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[0] * angle + specularColors[0] * pow(max(0.0, dot(normalize(-vertexPos.xyz), reflect(-surface2Light, normalEye))), shininess))*(1.0/(1.0+length(lightPositions[0] - vertexPos.xyz)*attenuation[0])), 1);
}

// Freaky Adreno shader compiler can't handle loops without locking or creating garbage results....this is why the
// loop has been unrolled here. It's faster this way on PowerVR SGX540 too, even if PVRUniSCoEditor says otherwise...

if (lightCount>1) {
surface2Light=normalize(lightPositions[1]  - vertexPos.xyz);
angle = dot(normalEye, surface2Light);

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[1] * angle + specularColors[1] * pow(max(0.0, dot(normalize(-vertexPos.xyz), reflect(-surface2Light, normalEye))), shininess))*(1.0/(1.0+length(lightPositions[1] - vertexPos.xyz)*attenuation[1])), 1);
}

if (lightCount>2) {
surface2Light=normalize(lightPositions[2]  - vertexPos.xyz);
angle = dot(normalEye, surface2Light);

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[2] * angle + specularColors[2] * pow(max(0.0, dot(normalize(-vertexPos.xyz), reflect(-surface2Light, normalEye))), shininess))*(1.0/(1.0+length(lightPositions[2] - vertexPos.xyz)*attenuation[2])), 1);
}

if (lightCount>3) {
surface2Light=normalize(lightPositions[3]  - vertexPos.xyz);
angle = dot(normalEye, surface2Light);

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[3] * angle + specularColors[3] * pow(max(0.0, dot(normalize(-vertexPos.xyz), reflect(-surface2Light, normalEye))), shininess))*(1.0/(1.0+length(lightPositions[3] - vertexPos.xyz)*attenuation[3])), 1);
}

if (lightCount>4) {
surface2Light=normalize(lightPositions[4]  - vertexPos.xyz);
angle = dot(normalEye, surface2Light);

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[4] * angle + specularColors[4] * pow(max(0.0, dot(normalize(-vertexPos.xyz), reflect(-surface2Light, normalEye))), shininess))*(1.0/(1.0+length(lightPositions[4] - vertexPos.xyz)*attenuation[4])), 1);
}

if (lightCount>5) {
surface2Light=normalize(lightPositions[5]  - vertexPos.xyz);
angle = dot(normalEye, surface2Light);

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[5] * angle + specularColors[5] * pow(max(0.0, dot(normalize(-vertexPos.xyz), reflect(-surface2Light, normalEye))), shininess))*(1.0/(1.0+length(lightPositions[5] - vertexPos.xyz)*attenuation[5])), 1);
}

if (lightCount>6) {
surface2Light=normalize(lightPositions[6]  - vertexPos.xyz);
angle = dot(normalEye, surface2Light);

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[6] * angle + specularColors[6] * pow(max(0.0, dot(normalize(-vertexPos.xyz), reflect(-surface2Light, normalEye))), shininess))*(1.0/(1.0+length(lightPositions[6] - vertexPos.xyz)*attenuation[6])), 1);
}
if (lightCount>7) {
surface2Light=normalize(lightPositions[7]  - vertexPos.xyz);
angle = dot(normalEye, surface2Light);

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[7] * angle + specularColors[7] * pow(max(0.0, dot(normalize(-vertexPos.xyz), reflect(-surface2Light, normalEye))), shininess))*(1.0/(1.0+length(lightPositions[7] - vertexPos.xyz)*attenuation[7])), 1);
}
}
}
}
}
}
}
}
}


if (fogStart != -1.0) {
fogWeight = clamp((-vertexPos.z - fogStart) / (fogEnd - fogStart), 0.0, 1.0);
fogVertexColor = fogColor * fogWeight;
} else {
fogWeight = -1.0;
}

vertexColor=vec4(min(WHITE, vertexColor).xyz, alpha);

if (useColors) {
vertexColor *= color;
}

        // add directional light
vec3 normal, lightDir;
vec4 diffuse, ambient, globalAmbient;
float NdotL;

normal = normalize(gl_NormalMatrix * gl_Normal);
lightDir = normalize(vec3(gl_LightSource[0].position));
NdotL = max(dot(normal, lightDir), 0.0);
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;

ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
globalAmbient = gl_LightModel.ambient * gl_FrontMaterial.ambient;
gl_FrontColor =  NdotL * diffuse + globalAmbient + ambient;

gl_Position = modelViewProjectionMatrix * position;
}

Is this correct? Do I need to change the defaultFragmentShader? After changes, how can i use the shader?

Btw, writing a shader is quite a hard task for a library user, will jpct-ae support it in the future?

EgonOlsen

As long as you limit yourself to vertex lighting, there should be no need to modify the fragment shader. To use your shader, create an instance of GLSLShader that uses it and assign it to your objects.
I don't think that I'll add support for this to the core. The default shaders' purpose is to mimic the fixed function pipeline's functionality. Directional lighting is supported by the fixed function pipeline in theory, but it doesn't work properly on some devices, so I didn't add it. I don't think that it looks very good when using vertex lighting anyway, so I would have to provide a complete set of shaders for per-pixel lighting, but that somehow feels like opening pandora's box to me. I see your point and I actually think that you are right, but given the great flexibility that shaders provide, I fail to see how I could provide a set that works well for everybody. So I decided to limit myself to the lowest common set of options instead and leave everything else to the user (with shadow support being a kind of exception).