OpenGL ES 2.0 Fixed Pipeline Emulation

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Re: Fixed pipeline emulation in OpenGL ES 2.0

Post by feelthat »

welcome!~

This Vertex shader for OGLES2

//the way to use

SLight spotLightData;
ILightSceneNode* scnode = smgr->addLightSceneNode(0, core::vector3df(0,5,20), video::SColorf(1.0f, 1.0f, 1.0f, 1.0f), 100.0f, -1);

spotLightData = scnode->getLightData();

spotLightData.Type = video::ELT_SPOT;
spotLightData.Direction = core::vector3df(-0.5,0.20,1);
spotLightData.Falloff = 60.0f;
spotLightData.OuterCone = 15;
scnode->setLightData(spotLightData);

//and I mark LightData.Direction in void CLightSceneNode::doLightRecalc()
if ((LightData.Type == video::ELT_SPOT) || (LightData.Type == video::ELT_DIRECTIONAL))
{
//LightData.Direction = core::vector3df(.0f,.0f,1.0f); //mark here
getAbsoluteTransformation().rotateVect(LightData.Direction);
LightData.Direction.normalize();
}
//

fixe the directnal light and add spotlight function

Work good if you want to use vertex shader.

If want to use inner cone for spot light, maybe we can add smoothstep GLSL API in spot light shader.


CuteAlien wrote:@feelthat: I appreciate that you post code. But please also talk and explain what this is about. Is this code to show what you are working at? Or is it something you want us to add to the engine? Or do you want us to replace an engine shader by it?
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Re: Fixed pipeline emulation in OpenGL ES 2.0

Post by feelthat »

core::vector3df COGLES2MaterialBaseCB::LightDirInView(core::matrix4 matrix, core::vector3df vec3_dir)
{
struct _Vec4_T
{
f32 x,y,z,w;
};
struct _Vec4_T vec4_dir;

vec4_dir.x = vec3_dir.X;
vec4_dir.y = vec3_dir.Y;
vec4_dir.z = vec3_dir.Z;
vec4_dir.w = 0.0;

vec4_dir.x = matrix[0]*vec4_dir.x + matrix[4]*vec4_dir.y + matrix[8]*vec4_dir.z; // + matrix[12]*vec4_dir.w;

vec4_dir.y = matrix[1]*vec4_dir.x + matrix[5]*vec4_dir.y + matrix[9]*vec4_dir.z; // + matrix[13]*vec4_dir.w;

vec4_dir.z = matrix[2]*vec4_dir.x + matrix[6]*vec4_dir.y + matrix[10]*vec4_dir.z; //+ matrix[14]*vec4_dir.w;

//vec4_dir.w = matrix[3]*vec4_dir.x + matrix[7]*vec4_dir.y + matrix[11]*vec4_dir.z + matrix[15]*vec4_dir.w;
return core::vector3df( vec4_dir.x, vec4_dir.y, vec4_dir.z);

}
///

//this can be simply to
return core::vector3df( Matrix_V[0]*CurrentLight.Direction.X + Matrix_V[4]*CurrentLight.Direction.Y + Matrix_V[8]* CurrentLight.Direction.Z,
Matrix_V[1]*CurrentLight.Direction.X + Matrix_V[5]*CurrentLight.Direction.Y + Matrix_V[9]* CurrentLight.Direction.Z,
Matrix_V[2]*CurrentLight.Direction.X + Matrix_V[6]*CurrentLight.Direction.Y + Matrix_V[10]*CurrentLight.Direction.Z);

so we can use this function instead
inline void CMatrix4<T>::rotateVect( vector3df& vect ) const
{
vector3df tmp = vect;
vect.X = tmp.X*M[0] + tmp.Y*M[4] + tmp.Z*M[8];
vect.Y = tmp.X*M[1] + tmp.Y*M[5] + tmp.Z*M[9];
vect.Z = tmp.X*M[2] + tmp.Y*M[6] + tmp.Z*M[10];
}
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Re: Fixed pipeline emulation in OpenGL ES 2.0

Post by feelthat »

Matrix_V.transformVect(CurrentLight.Position) = vce3( ViewMatrix * vec4(CurrentLight.Position,1)) -> get xyz

LightDirInView(Matrix_V, CurrentLight.Direction) = Matrix_V.rotateVect( CurrentLight.Direction )
=> vec3(ViewMatrix * vec4(CurrentLight.Direction, 0)) ->get xyz

Homogeneous coordinates

Until then, we only considered 3D vertices as a (x,y,z) triplet. Let’s introduce w. We will now have (x,y,z,w) vectors.

This will be more clear soon, but for now, just remember this :

If w == 1, then the vector (x,y,z,1) is a position in space.
If w == 0, then the vector (x,y,z,0) is a direction.

ref. http://www.opengl-tutorial.org/beginner ... -matrices/
Last edited by feelthat on Thu Feb 12, 2015 12:53 pm, edited 1 time in total.
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Re: Fixed pipeline emulation in OpenGL ES 2.0

Post by feelthat »

//faster for spot light in GLSL

void CLightSceneNode::setLightData(const video::SLight& light)
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();

LightData = light;

if( driver->getDriverType() == video::EDT_OGLES2 )
{
LightData.OuterCone = (float)cos(light.OuterCone * 3.141615926 / 180.0f);
LightData.InnerCone = (float)cos(light.InnerCone * 3.141615926 / 180.0f);
}
}

//then in vsh
//
//
void spotLight(in int index, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
vec3 L = uLightPosition[index] - position;
float D = length(L);
L = normalize(L);

//must do outside or become flashlight follow camera
//vec3 NSpotDir = (uViewMatrix * vec4(uLightDirection[index],0)).xyz;
vec3 NSpotDir = normalize(uLightDirection[index]);

//dot(NSpotDir and lightvector) = cos(angle)
float spotEffect = dot(NSpotDir, -L);

//if (spotEffect >= cos(radians(uLightOuterCone[index])))
if (spotEffect >= uLightOuterCone[index] ) //-->simplize
{
.
.
.
}

}
Last edited by feelthat on Thu Feb 12, 2015 1:48 pm, edited 2 times in total.
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Re: Fixed pipeline emulation in OpenGL ES 2.0

Post by feelthat »

for (s32 i = 0; i < LightCount; ++i)
{
SLight CurrentLight = driver->getDynamicLight(i);

//Matrix.transformVect(CurrentLight.Position);

//Matrix_V.transformVect-> vec3(Vmatrix*vec4(Position, 1))
//Matrix_V.rotateVect -> vec3(Vmatrix*vec4(Direction,0))
switch (CurrentLight.Type)
{
case ELT_DIRECTIONAL:
LightType = 2;
//put on Position, same as assignHardwareLight(u32 lightIndex)
Matrix_V.rotateVect(CurrentLight.Position, -CurrentLight.Direction);
break;
case ELT_SPOT:
LightType = 1;
Matrix_V.transformVect(CurrentLight.Position);
Matrix_V.rotateVect(CurrentLight.Direction);
break;
default: // ELT_POINT
LightType = 0;
Matrix_V.transformVect(CurrentLight.Position);
break;
}

LightPosition = CurrentLight.Position;
LightDirection = CurrentLight.Direction;
LightAttenuation = CurrentLight.Attenuation;
LightAmbient = CurrentLight.AmbientColor;
LightDiffuse = CurrentLight.DiffuseColor;
LightSpecular = CurrentLight.SpecularColor;
LightOuterCone = CurrentLight.OuterCone;
LightFallOff[i] = CurrentLight.Falloff;
}
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Blinn shading

Post by feelthat »

http://stackoverflow.com/questions/3744 ... odern-glsl
vec3 V = -out_Vertex;// really it is (eye - vertexPosition), so (0,0,0) - out_Vertex

//in our shading COGLES2Solid.vsh
vec3 E = normalize(-position);

another examples
http://en.wikipedia.org/wiki/Blinn%E2%8 ... ding_model
vec3 viewDir = normalize(-vertPos);

http://www.arcsynthesis.org/gltut/Illum ... Model.html
vec3 viewDirection = normalize(-cameraSpacePosition);
//////////////////////////////////////////////////
void pointLight(in int index, in vec3 position, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
vec3 L = uLightPosition[index] - position;
float D = length(L);
L = normalize(L);

float Attenuation = 1.0 / (uLightAttenuation[index].x + uLightAttenuation[index].y * D +
uLightAttenuation[index].z * D * D);

ambient += uLightAmbient[index] * Attenuation;

//dot(objnormal and lightvector) = cos(theta)
float NdotL = dot(normal, L);

if (NdotL > 0.0)
{
diffuse += uLightDiffuse[index] * (NdotL * Attenuation);

//Blinn shading, in camera space which the camera position is (0,0,0)
vec3 E = normalize(-position);
vec3 HalfVector = normalize(L + E);
float NdotH = dot(normal, HalfVector);

if (NdotH > 0.0)
{
float SpecularFactor = pow(NdotH, uMaterialShininess);
specular += uLightSpecular[index] * (SpecularFactor * Attenuation);
}
}
}


///////////////////////////////////////

in file OGLES2xxxxx.vsh we use Blinn shading and which one you feel good for proton 3d sdk??[/QUOTE]

feelthat wrote:Ref.
http://antonholmquist.com/blog/opengl-e ... -examples/
if (ecNormalDotLightHalfplane > 0.0)
{
specularLight = pow(ecNormalDotLightHalfplane, u_material.shininess) * u_directionalLight.specularColor *
u_material.specularFactor;
}

and ref.
https://github.com/kizzx2/irrlicht-ogl- ... peline.vsh

//////// suggest way
//////// COGLES2Solid.vsh and COGLES2Solid2.vsh
if (NdotL > 0.0)
{
diffuse += uLightDiffuse[index] * NdotL * Attenuation;

vec3 HalfVector = normalize(L + vec3(0.0, 0.0, 1.0));
float NdotH = max(0.0, dot(normal, HalfVector));

float SpecularFactor = pow(NdotH, uMaterialShininess);
specular += uLightSpecular[index] * SpecularFactor * Attenuation;
}
//to

if (NdotL > 0.0)
{
diffuse += uLightDiffuse[index] * NdotL * Attenuation;
}

vec3 HalfVector = normalize(L + vec3(0.0, 0.0, 1.0));
float NdotH = dot(normal, HalfVector);

if (NdotH > 0.0)
{
specular += pow(NdotH, uMaterialShininess) * uLightSpecular[index] * Attenuation;
}
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

PSP light shader

Post by feelthat »

Ref only

https://code.google.com/p/jpcsp/source/ ... ert?r=1639

attribute vec4 psp_weights1;
attribute vec4 psp_weights2;
uniform float psp_zPos;
uniform float psp_zScale;
uniform ivec3 psp_matFlags; // Ambient, Diffuse, Specular
uniform ivec4 psp_lightType;
uniform ivec4 psp_lightKind;
uniform ivec4 psp_lightEnabled;
uniform mat4 psp_boneMatrix[8];
uniform int psp_numberBones;
uniform bool texEnable;
uniform bool lightingEnable;

float calculateAttenuation(in int i, in float dist) {
return clamp(1.0 / (gl_LightSource.constantAttenuation +
gl_LightSource.linearAttenuation * dist +
gl_LightSource.quadraticAttenuation * dist * dist), 0.0, 1.0);
}

void directionalLight(in int i, in vec3 N, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) {
vec3 L = normalize(gl_LightSource.position.xyz);
float nDotL = dot(N, L);
if (nDotL > 0.0) {
vec3 H = gl_LightSource.halfVector.xyz;
float nDotH = dot(N,H);
if (nDotH > 0.0) {
float pf = pow(nDotH, gl_FrontMaterial.shininess);
specular += gl_LightSource.specular * pf;
}
diffuse += gl_LightSource.diffuse * nDotL;
}

ambient += gl_LightSource.ambient;
}

void pointLight(in int i, in vec3 N, in vec3 V, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) {
vec3 D = gl_LightSource.position.xyz - V;
vec3 L = normalize(D);

float dist = length(D);
float attenuation = calculateAttenuation(i, dist);

float nDotL = dot(N,L);

if (nDotL > 0.0) {
// TODO Which model is correct?
if (true) {
vec3 E = normalize(-V);
vec3 R = reflect(-L, N);

float rDotE = dot(R,E);
if (rDotE > 0.0) {
float pf = pow(rDotE, gl_FrontMaterial.shininess);
specular += gl_LightSource.specular * attenuation * pf;
}
} else {
vec3 H = normalize(L + vec3(0.0, 0.0, 1.0));
float nDotH = dot(N,H);
if (nDotH > 0.0) {
float pf = pow(nDotH, gl_FrontMaterial.shininess);
specular += gl_LightSource[i].specular * attenuation * pf;
}
}
diffuse += gl_LightSource[i].diffuse * attenuation * nDotL;
}

ambient += gl_LightSource[i].ambient * attenuation;
}

void spotLight(in int i, in vec3 N, in vec3 V, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) {
vec3 D = gl_LightSource[i].position.xyz - V;
vec3 L = normalize(D);

// Check if point on surface is inside cone of illumination
float spotEffect = dot(normalize(gl_LightSource[i].spotDirection), -L);

if (spotEffect >= gl_LightSource[i].spotCosCutoff) {
float dist = length(D);
float attenuation = calculateAttenuation(i, dist);

attenuation *= pow(spotEffect, gl_LightSource[i].spotExponent);

float nDotL = dot(N,L);
if (nDotL > 0.0) {
// TODO Which model is correct?
if (true) {
vec3 E = normalize(-V);
vec3 R = reflect(-L, N);

float rDotE = dot(R,E);
if (rDotE > 0.0) {
float pf = pow(rDotE, gl_FrontMaterial.shininess);
specular += gl_LightSource[i].specular * attenuation * pf;
}
} else {
vec3 H = normalize(L + vec3(0.0, 0.0, 1.0));
float nDotH = dot(N,H);
if (nDotH > 0.0) {
float pf = pow(nDotH, gl_FrontMaterial.shininess);
specular += gl_LightSource[i].specular * attenuation * pf;
}
}
diffuse += gl_LightSource[i].diffuse * attenuation * nDotL;
}

ambient += gl_LightSource[i].ambient * attenuation;
}
}

void calculateLighting(in vec3 N, in vec3 V, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) {
for (int i = 0; i < 4; i++) {
if (psp_lightEnabled[i] != 0) {
if(psp_lightType[i] == 0)
directionalLight(i, N, ambient, diffuse, specular);
else if(psp_lightType[i] == 1)
pointLight(i, N, V, ambient, diffuse, specular);
else if(psp_lightType[i] == 2)
spotLight(i, N, V, ambient, diffuse, specular);
}
}
}

vec4 getEyeCoordinatePosition() {
return gl_ModelViewMatrix * gl_Vertex;
}

vec3 getEyeCoordinatePosition3(in vec4 eyeCoordinatePosition) {
return vec3(eyeCoordinatePosition) / eyeCoordinatePosition.w;
}

vec4 doLight(in vec4 eyeCoordinatePosition, in vec4 matAmbient, in vec4 matDiffuse, in vec4 matSpecular, in vec3 normal) {
vec4 ambient = vec4(0.0);
vec4 diffuse = vec4(0.0);
vec4 specular = vec4(0.0);
vec3 n = normalize(gl_NormalMatrix * normal);

calculateLighting(n, getEyeCoordinatePosition3(eyeCoordinatePosition), ambient, diffuse, specular);

ambient += gl_LightModel.ambient;
vec4 color = (ambient * matAmbient) +
(diffuse * matDiffuse) +
(specular * matSpecular) +
gl_FrontMaterial.emission;

return clamp(color, 0.0, 1.0);
}

vec4 getFrontColor(in vec4 eyeCoordinatePosition, in vec3 normal) {
if (!lightingEnable) {
return gl_Color;
}

vec4 matAmbient = psp_matFlags[0] != 0 ? gl_Color : gl_FrontMaterial.ambient;
vec4 matDiffuse = psp_matFlags[1] != 0 ? gl_Color : gl_FrontMaterial.diffuse;
vec4 matSpecular = psp_matFlags[2] != 0 ? gl_Color : gl_FrontMaterial.specular;

return doLight(eyeCoordinatePosition, matAmbient, matDiffuse, matSpecular, normal);
}

vec4 getPosition(inout vec3 normal) {
if (psp_numberBones == 0) {
return gl_Vertex;
}

vec4 position = vec4(0.0, 0.0, 0.0, gl_Vertex.w);
vec4 vertex = vec4(gl_Vertex.xyz, 1.0);
normal = vec3(0.0, 0.0, 0.0);
for (int i = 0; i < psp_numberBones; i++) {
float weight = (i <= 3 ? psp_weights1[i] : psp_weights2[i - 4]);
if (weight != 0.0) {
position.xyz += vec3(psp_boneMatrix[i] * vertex) * weight;

// Normals shouldn't be translated :)
normal += mat3(psp_boneMatrix[i]) * gl_Normal * weight;
}
}

return position;
}

float getFogFragCoord(vec4 eyeCoordinatePosition) {
return abs(eyeCoordinatePosition.z);
}

void main() {
vec4 eyeCoordinatePosition = getEyeCoordinatePosition();
vec3 normal = gl_Normal;

gl_Position = gl_ModelViewProjectionMatrix * getPosition(normal);
gl_FrontColor = getFrontColor(eyeCoordinatePosition, normal);
gl_FogFragCoord = getFogFragCoord(eyeCoordinatePosition);
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;

// gl_Position = ftransform();
// gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// gl_Position.z = gl_Position.z * psp_zScale + psp_zPos * gl_Position.w;
}
Last edited by feelthat on Sat Feb 14, 2015 5:56 pm, edited 1 time in total.
CuteAlien
Admin
Posts: 9633
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Fixed pipeline emulation in OpenGL ES 2.0

Post by CuteAlien »

Sorry, we can't take code from jpcsp. That project is using the gpl license which is not compatible with the Irrlicht license.

I appreciate the other work on spot-lights, but unfortunately I have no time for working on that currently (trying to release a game which is running _very_ late already...).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
feelthat
Posts: 194
Joined: Sat Feb 02, 2013 5:27 am

Re: Fixed pipeline emulation in OpenGL ES 2.0

Post by feelthat »

Ok I want to see ur game in the future ~~~

If complete please let me know
CuteAlien wrote:Sorry, we can't take code from jpcsp. That project is using the gpl license which is not compatible with the Irrlicht license.

I appreciate the other work on spot-lights, but unfortunately I have no time for working on that currently (trying to release a game which is running _very_ late already...).
Post Reply