Hi, I'm currently in the process of applying a normal map to an Object3D and followed the tutorial at:
http://www.jpct.net/wiki/index.php/Shaders, and also the post regarding using shaders at:
http://www.jpct.net/forum2/index.php/topic,2153.msg15838/topicseen.html#msg15838. However, I have a few questions.
I don't know how to send the color texture and normal texture to the fragment shader for processing. I have tried to implement the solution given in the aforementioned links but it doesn't seem to help. I know I'm missing a few parts but the documentation for JPCT-AE regarding shaders is quite limited.
I would like to thank anyone who can help me and maybe after this problem is solved I can help to write a more detailed tutorial on using Shaders with JPCT-AE as I feel this is a very important topic. Anyway, this so far is the only real problem I have had with JPCT-AE and think it's a really good 3D engine for Android.
Thanks!
Below you will find the code and the screenshots explaining my particular situation.
I load the 3D object with the following code:
InputStream totemOBJFile = mActivity.getResources().getAssets().open("totemLowPolyFixed.obj");
// Totem's texture files
InputStream totemTextureFile = mActivity.getResources().getAssets().open("TOTEM_Textura.jpg");
InputStream totemNormalFile = mActivity.getResources().getAssets().open("totem_normal.jpg");
textureManager.addTexture("totem_material", new Texture(totemTextureFile));
textureManager.addTexture("totem_normal.jpg", new Texture(totemNormalFile));
totem = Object3D.mergeAll(Loader.loadOBJ(totemOBJFile, null, scale));
TextureInfo ti=new TextureInfo(TextureManager.getInstance().getTextureID("totem_material"));
ti.add(TextureManager.getInstance().getTextureID("totem_normal.jpg"), TextureInfo.MODE_MODULATE);
totem.setTexture(ti);
totem.build();
totem.compile();
totem.setSpecularLighting(true);
totem.strip();
world.addObject(totem);
SimpleVector sv = new SimpleVector();
sv.set(totem.getTransformedCenter());
sv.y = -150;
sv.z = 0;
sun.setPosition(sv);
cam = world.getCamera();
cam.setPosition(0f, -150f, 0f);
cam.lookAt(totem.getTransformedCenter());
String vertex = null;
String fragment = null;
// Load the vertex and fragment shaders
try {
vertex = Loader.loadTextFile(mActivity.getResources().getAssets().open("glsl/normalmapping/vertexshader.glsl"));
fragment = Loader.loadTextFile(mActivity.getResources().getAssets().open("glsl/normalmapping/fragmentshader.glsl"));
GLSLShader shader=new GLSLShader(vertex, fragment);
shader.setStaticUniform("textureMap", 0);
shader.setStaticUniform("normalMap", 1);
shader.setStaticUniform("invRadius", 0.0005f);
totem.setShader(shader);
} catch (IOException e) {
e.printStackTrace();
}
MemoryHelper.compact();
The vertex shader:
uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform vec4 additionalColor;
uniform vec4 ambientColor;
uniform vec3 lightPositions[8];
attribute vec4 position;
attribute vec3 normal;
attribute vec4 tangent;
attribute vec2 texture0;
varying vec3 lightVec[2];
varying vec3 eyeVec;
varying vec2 texCoord;
void main(void)
{
texCoord = texture0.xy;
vec3 n = normalize(modelViewMatrix * vec4(normal,0.0)).xyz;
vec3 t = normalize(modelViewMatrix * vec4(tangent.xyz, 0.0)).xyz;
vec3 b = tangent.w*cross(n, t);
vec3 vVertex = vec3(modelViewMatrix * position);
vec3 tmpVec = lightPositions[0].xyz - vVertex;
vec3 lv;
vec3 ev;
lv.x = dot(tmpVec, t);
lv.y = dot(tmpVec, b);
lv.z = dot(tmpVec, n);
lightVec[0]=lv;
tmpVec = vVertex*-1.0;
eyeVec.x = dot(tmpVec, t);
eyeVec.y = dot(tmpVec, b);
eyeVec.z = dot(tmpVec, n);
gl_Position = modelViewProjectionMatrix * position;
}
The fragment shader:
precision mediump float;
varying vec3 lightVec[2];
varying vec3 eyeVec;
varying vec2 texCoord;
uniform sampler2D textureMap;
uniform sampler2D normalMap;
uniform vec3 diffuseColors[8];
uniform vec3 specularColors[8];
uniform vec4 ambientColor;
uniform float invRadius;
void main ()
{
vec4 vAmbient = ambientColor;
vec3 vVec = normalize(eyeVec);
vec2 newTexCoord = texCoord;
vec4 base = texture2D(textureMap, newTexCoord);
vec3 bump = normalize(texture2D(normalMap, newTexCoord).xyz * 2.0 - 1.0);
float distSqr = dot(lightVec[0], lightVec[0]);
float att = clamp(1.0 - invRadius * sqrt(distSqr), 0.0, 1.0);
vec3 lVec = lightVec[0] * inversesqrt(distSqr);
float diffuse = max(dot(lVec, bump), 0.0);
vec4 vDiffuse = vec4(diffuseColors[0],0) * diffuse;
float specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0, 1.0), 0.85);
vec4 vSpecular = vec4(specularColors[0],0) * specular;
gl_FragColor = (vAmbient*base + vDiffuse*base + vSpecular) * att*2.0;
}
The object without shaders:
The object with shaders: