Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - jaychang0917

#1
My model has around 8000 polygons, I use the following code to rotate a joint, but I found the call animatedModel.applySkeletonPose() cause around 800 ms, which is too slow, have any idea to improve the performance? The method is called in game loop. Thanks.


void updateModel() {
    leftEyeRotateMatrix.setIdentity();
    leftEyeRotateMatrix.rotateX(eulerX);
    skeletonHelper.transformJoint("left_eye_sk", leftEyeRotateMatrix);
    skeletonHelper.pose.setToBindPose();
    skeletonHelper.pose.updateTransforms();
    animatedGroup.applySkeletonPose();
    animatedGroup.applyAnimation();
}
#2
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?
#3
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;
}
#4
Does jpct-ae support directional light? And how to set the light euler angle? Thanks!
#5
Quote from: EgonOlsen on April 12, 2017, 01:08:25 PM
Thank, I'll have a look later. But looking at your screen shot again...this is the model rendered on top of a camera view? If so, make sure that the gl context that you are creating actually has a depth buffer. You have to specify this somehow, or you might end up with one without. That would explain the results as well.

The root cause is that the opengl depth buffer is not created, thanks EgonOlsen!
#6
Quote from: EgonOlsen on April 12, 2017, 12:40:09 PM
Can you provide me with the model?

I sent you the model via pm.
#7
Quote from: EgonOlsen on April 12, 2017, 07:37:59 AM
jPCT-AE doesn't care about the number of polygons/vertices. Speaking of which...how many are there in this model?
It might be worth a try to call Object3D.setFixedPointMode(false); before calling build() on the model as well.

The model contains around 8000 polygons. I tried Object3D.setFixedPointMode(false);, but no luck.
#8
Quote from: AeroShark333 on April 11, 2017, 08:50:24 PM
Maybe you could try to increase the amount of maximum polygons visible...

Change this:

if (frameBuffer != null) {
      frameBuffer.dispose();
}


into:

if (frameBuffer != null) {
      frameBuffer.dispose();
}
Config.maxPolysVisible = 2*Config.maxPolysVisible;


And maybe it has some effects :)

(in case I do correctly see that some polygons are missing..)

I tried, but no luck, same result. I even tried

Config.maxPolysVisible = 10*Config.maxPolysVisible;


#9
Quote from: EgonOlsen on April 11, 2017, 08:18:36 PM
Have you tried it on another device? It might be a driver issue, because the model seems pretty high poly...

I tried on three devices, the result are same. Is the reason that jpct-ae can't handle such amount of polygons? then can I use jpct in android?
#10
Bones / Re: How to set texture to object material
April 11, 2017, 12:41:09 PM
Quote from: raft on April 11, 2017, 11:28:48 AM
may be ask in jpct-AE forum? :)

I post a new thread in jpct-AE forum, see if you have any idea :)
http://www.jpct.net/forum2/index.php/topic,4878.msg33311.html#msg33311
#11
I found a weird issue that the model (.bones) is not rendered correctly in Android using jpct-ae, but it is rendered correctly in desktop using jpct. The code are almost identical except the FrameBuffer object creation.

For android (jpct-ae)

frameBuffer = new FrameBuffer(width, height);


For desktop (jpct)

frameBuffer = new FrameBuffer(width, height, FrameBuffer.SAMPLINGMODE_NORMAL);


The following code is used to render model in Android

    if (frameBuffer != null) {
      frameBuffer.dispose();
    }

    frameBuffer = new FrameBuffer(width, height);

    if (world == null) {
      world = new World();
     
      // load model
      // mode.bones, which is exported using bones script (dae -> bones)
      InputStream stream = context.getResources().openRawResource(R.raw.model);
      try {
  animatedModel = BonesIO.loadGroup(stream);
  model = animatedModel.getRoot();

  Texture blueHead = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.blue_head))));
  Texture blue = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.blue))));
  Texture eye = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.eye))));
  Texture face = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.face))));
  Texture headTop = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.head_top))));
  Texture side = new Texture((BitmapHelper.convert(context.getResources().getDrawable(R.drawable.side))));
  Texture metalLightGrey = new Texture(8, 8, new RGBColor(61, 61, 61));
  Texture metalDark = new Texture(8, 8, new RGBColor(16, 16, 16));
  Texture metalGrey = new Texture(8, 8, new RGBColor(41, 41, 41));
  Texture metalBlue = new Texture(8, 8, new RGBColor(0, 52, 112));
  Texture metal = new Texture(8, 8, new RGBColor(102, 102, 102));
  Texture black = new Texture(8, 8, new RGBColor(0, 0, 0));
  // image
  TextureManager.getInstance().addTexture("blueHead", blueHead);
  TextureManager.getInstance().addTexture("blue", blue);
  TextureManager.getInstance().addTexture("eye", eye);
  TextureManager.getInstance().addTexture("face", face);
  TextureManager.getInstance().addTexture("headTop", headTop);
  TextureManager.getInstance().addTexture("side", side);
  // color
  TextureManager.getInstance().addTexture("metalLightGrey", metalLightGrey);
  TextureManager.getInstance().addTexture("metalDark", metalDark);
  TextureManager.getInstance().addTexture("metalGrey", metalGrey);
  TextureManager.getInstance().addTexture("metalBlue", metalBlue);
  TextureManager.getInstance().addTexture("metal", metal);
  TextureManager.getInstance().addTexture("black", black);

  for (Animated3D o : animatedModel) {
    o.build();
    o.discardMeshData();
  }
  // set texture
  animatedModel.get(0).setTexture("blueHead");
  animatedModel.get(1).setTexture("headTop");
  animatedModel.get(2).setTexture("metalLightGrey");
  animatedModel.get(3).setTexture("metalDark");
  animatedModel.get(4).setTexture("eye");
  animatedModel.get(5).setTexture("face");
  ....
   
          animatedModel.addToWorld(world);
} catch (Exception e) {
  e.printStackTrace();
} finally {
  try {
    stream.close();
  } catch (IOException e) {
    e.printStackTrace();
  }
}

      // camera
      com.threed.jpct.Camera cam = world.getCamera();
      cam.moveCamera(com.threed.jpct.Camera.CAMERA_MOVEOUT, 80);
      cam.lookAt(model.getTransformedCenter());

      // light
      world.setAmbientLight(20, 20, 20);
      sun = new Light(world);
      sun.setIntensity(250, 250, 250);
      SimpleVector sv = new SimpleVector();
      sv.set(model.getTransformedCenter());
      sv.y -= 100;
      sv.z -= 100;
      sun.setPosition(sv);
   }
}



@Override
  public void draw() {
    super.draw();
    frameBuffer.clear();
    world.renderScene(frameBuffer);
    world.draw(frameBuffer);
    frameBuffer.display();
  }



I have no idea why this happens. Thanks!
#12
Bones / Re: How to set texture to object material
April 11, 2017, 11:24:23 AM
Quote from: raft on April 11, 2017, 11:05:11 AM
interesting, might be jpct-ae

Almost all code are the same for desktop and android version except the FrameBuffer object creation.

For android (jpct-ae)

frameBuffer = new FrameBuffer(width, height);


For desktop (jpct)

frameBuffer = new FrameBuffer(width, height, FrameBuffer.SAMPLINGMODE_NORMAL);


So what approach can i take to solve this problem?
#13
Bones / Re: How to set texture to object material
April 11, 2017, 10:20:26 AM
Quote from: raft on April 11, 2017, 10:10:29 AM
which pipeline are you using, Collada or Ogre3D?

are you sure it's exported correctly?

I am using Collada.

I found that the model is rendered correctly using the ProceduralAnimationBonesSample, is it the jpct-ae problem?
#14
Bones / Re: How to set texture to object material
April 11, 2017, 07:09:19 AM
raft, I found that the imported model is not rendered correctly. If the geometry contains multiple elements, it seems only render the first element. Do you have any idea?
#15
Bones / Re: How to set texture to object material
April 07, 2017, 03:56:27 PM
Quote from: raft on April 06, 2017, 02:59:45 PM
video not appearing part may also related to a thread synchronization issue. in particular if you dont consume a video frame new update never arrives (as far as I remember)

?? you are answering my qestion? :)