www.jpct.net

jPCT-AE - a 3d engine for Android => Support => Topic started by: kkl on August 10, 2015, 02:56:41 pm

Title: Object not shown and not rendered properly in some devices
Post by: kkl on August 10, 2015, 02:56:41 pm
Hi egon,

I tested my scene in Nexus 6 and some objects (opaque) do not show in the scene. The weirder part is, some objects (opaque) just disappear at a fixed position. Initially, I thought it's caused by other transparent objects overlapping them, but when I remove all transparent objects and render again with only opaque objects, and what I got is the objects are not render properly where they are cut off half way (see attachments). The cut off part only happen when another object is nearer to camera, overlapping it.

I checked from jpct log with debug mode, and it seems all normal. I do use custom shaders for those objects and some custom setSortOffset values. I tested on samsung s4, samsung note 10 and samsung trend plus, and they all work ok with no issue.

Do you have idea what might cause the issue?
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 10, 2015, 07:27:38 pm
Have you tried with the default shaders instead?
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 11, 2015, 12:18:06 pm
Hmm.. I tried using default shader and it seems ok. Did I miss anything in shader that might cause the problems? Have you had this issue before?
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 11, 2015, 12:50:54 pm
Can you post the shader sources here?
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 11, 2015, 01:03:44 pm
The first shaders:
vertex shader-
Code: [Select]
uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;

uniform vec4 ambientColor;
uniform vec4 additionalColor;

uniform vec3 myLightPosition;
uniform vec3 myLightDiffuseColor;
uniform float myAttenuation;

uniform mat4 skinPalette[17];

attribute vec4 position;
attribute vec3 normal;
attribute vec2 texture0;

attribute vec4 skinWeights;
attribute vec4 skinJointIndices;

varying vec2 texCoord[2];
varying vec4 vertexColor;

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

void main() {

texCoord[0] = texture0;
texCoord[1] = (textureMatrix * vec4(texture0, 0, 1)).xy;

vertexColor = ambientColor + additionalColor;

vec4 myPosition = vec4(0,0,0,0);
vec3 myNormal = vec3(0,0,0);

vec4 vertexTemp;
vec3 normalTemp;
mat4 mat;

mat = skinPalette[int(skinJointIndices[0])];
vertexTemp = mat * position;
vertexTemp *= skinWeights.x;
myPosition += vertexTemp;
normalTemp = mat3(mat) * normal;
normalTemp *= skinWeights.x;
myNormal += normalTemp;

mat = skinPalette[int(skinJointIndices[1])];
vertexTemp = mat * position;
vertexTemp *= skinWeights.y;
myPosition += vertexTemp;
normalTemp = mat3(mat) * normal;
normalTemp *= skinWeights.y;
myNormal += normalTemp;

myPosition.yz *= -1.0;
myNormal.yz *= -1.0;

vec4 vertexPos = modelViewMatrix * myPosition;

vec3 normalEye = normalize(modelViewMatrix * vec4(myNormal, 0.0)).xyz;
float angle = dot(normalEye, normalize(myLightPosition - vertexPos.xyz));
//if (angle > 0.0) {
vertexColor += vec4((myLightDiffuseColor * angle)*(1.0/(1.0+length(myLightPosition - vertexPos.xyz)*myAttenuation)), 1);
//}


gl_Position = modelViewProjectionMatrix * myPosition;
}

fragment shader-
Code: [Select]
precision mediump float;

uniform sampler2D textureUnit0;
uniform sampler2D textureUnit1;

varying vec2 texCoord[2];
varying vec4 vertexColor;

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

void main() {

vec4 col = texture2D(textureUnit0, texCoord[0]) * vertexColor;

vec4 blend = texture2D(textureUnit1, texCoord[1]) * 0.7;
col = min(col / (1.0 - blend), 1.0);

gl_FragColor = col;
}

The second shaders:
vertex shader-
Code: [Select]
uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;

uniform vec4 ambientColor;
uniform vec3 myLightPositions;

uniform mat4 skinPalette[17];

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


attribute vec4 position;
attribute vec3 normal;
attribute vec4 tangent;
attribute vec2 texture0;
attribute vec2 texture1;

attribute vec4 skinWeights;
attribute vec4 skinJointIndices;

varying vec2 texCoord[3];
varying vec3 lightVec[2];
varying vec3 eyeVec;

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

void main() {

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

vec4 myPosition = vec4(0,0,0,0);
vec3 myNormal = vec3(0,0,0);
vec4 myTangent = vec4(0,0,0,0);

vec4 vertexTemp;
vec3 normalTemp;
vec4 tangentTemp;
mat4 mat;

mat = skinPalette[int(skinJointIndices[0])];
vertexTemp = mat * position;
vertexTemp *= skinWeights.x;
myPosition += vertexTemp;
normalTemp = mat3(mat) * normal;
normalTemp *= skinWeights.x;
myNormal += normalTemp;
tangentTemp = mat * tangent;
tangentTemp *= skinWeights.x;
myTangent += tangentTemp;

mat = skinPalette[int(skinJointIndices[1])];
vertexTemp = mat * position;
vertexTemp *= skinWeights.y;
myPosition += vertexTemp;
normalTemp = mat3(mat) * normal;
normalTemp *= skinWeights.y;
myNormal += normalTemp;
tangentTemp = mat * tangent;
tangentTemp *= skinWeights.y;
myTangent += tangentTemp;

myPosition.yz *= -1.0;
myNormal.yz *= -1.0;
myTangent.yz *= -1.0;

vec3 vertexPos = vec3(modelViewMatrix * myPosition);

vec3 n   = normalize(modelViewMatrix * vec4(myNormal, 0.0)).xyz;
vec3 t = normalize(modelViewMatrix * vec4(myTangent.xyz, 0.0)).xyz;
vec3 b = myTangent.w*cross(n, t);

vec3 tmpVec = myLightPositions.xyz - vertexPos;

vec3 lv;
vec3 ev;

lv.x = dot(tmpVec, t);
lv.y = dot(tmpVec, b);
lv.z = dot(tmpVec, n);

lightVec[0]=lv;

tmpVec = vertexPos*-1.0;
eyeVec.x = dot(tmpVec, t);
eyeVec.y = dot(tmpVec, b);
eyeVec.z = dot(tmpVec, n);

gl_Position = modelViewProjectionMatrix * myPosition;
}

fragment shader (with bump map)-
Code: [Select]
precision mediump float;

uniform sampler2D textureUnit0;
uniform sampler2D textureUnit1;
uniform sampler2D textureUnit2;

uniform float shinyStrength;
uniform vec4 additionalColor;

uniform vec4 ambientColor;
uniform vec3 diffuseColors[8];
uniform vec3 specularColors[8];

varying vec2 texCoord[3];
varying vec3 lightVec[2];
varying vec3 eyeVec;

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

void main() {

vec4 vAmbient = ambientColor;
vec3 vVec = normalize(eyeVec);

//base == col
vec4 base = texture2D(textureUnit0, texCoord[0]);
vec3 bump = normalize(texture2D(textureUnit1, texCoord[0]).xyz * 2.0 - 1.0);

float invRadius = 0.0003;
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 * 0.1;

vec4 col = (vAmbient*base + vDiffuse*base + vSpecular ) * att*2.0;

vec4 blend = texture2D(textureUnit2, texCoord[2]);
col = min(col / (1.0 - blend), 1.0);
//if (additionalColor.x > 0.0)
// col = WHITE;
gl_FragColor = col;
}

The vertex shader is implemented with hardware skinning we talked about with raft in last few months.
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 11, 2015, 02:19:10 pm
If these objects are supposed to be transparent, do you actually enable transparency in jPCT as well even if you do it the shader anyway? Because if not, the Z-Buffer won't behave correctly. That might be a reason for this...
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 11, 2015, 03:06:14 pm
hmm.. the objects are not suppose to be transparent. Do we need to disable the transparency by giving -1 to setTransparency()? I did suspect that something wrong with zbuffer too.
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 11, 2015, 09:49:42 pm
Depends on the model. Some models contain transparency information in the file even if it's actually wrong. jPCT uses this information, so it might be worth a try to set everything to -1 in code. I actually don't think that this is the problem, but just to rule it out...
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 12, 2015, 12:57:03 pm
I tried setting all objects which are suppose opaque to -1 for their transparency, it's still the same. What are other stuffs that might affect zbuffer? vertex position? The shader does change the vertex positions too.
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 12, 2015, 02:57:26 pm
No, at least not in this way. However, I'm having problems to spot the actual problem exactly in the screen shots. They are very tiny and very...blue. Maybe you can post some larger ones, that make the problem more visible?
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 12, 2015, 04:47:29 pm
i've attached 2 more screenshots with green background and with red object at the most front of the screen. The round highlights are where objects are cut off. It only happen when red object appear at front of blue objects.

If I change the drawing order the other way around, the red object will disappear at some locations instead
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 12, 2015, 04:48:29 pm
The expected result is like this, tested on samsung device:
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 12, 2015, 10:19:12 pm
That's really strange. From the screen shots, it looks like a clean vertical or horizontal cut. Can you confirm that? If it is, it can't be related to the vertex shader...at least I fail to see how it should. In the fragment shader, you can cause such things by discarding fragments, but your shader doesn't do this. There also no conditional branch in it that could cause it...plus it works on other devices. The Nexus 6 uses an Adreno GPU...but so does the Samsung S4. It's not the exact same on, but they usually don't differ that much in behaviour.
Have you tried to use high precision in the fragment shader? I doubt that it will help anything, but it's worth a try anyway.
Also make sure that your mat4[17] array is really filled by a maximum of 17 matrices to rule out the possibility of some data overflow.
Apart from that, I'm clueless. If the default shaders work on it, my best shot would be to use a copy of the default shader and modify it step by step to reflect your actual shaders until it sstops working.
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 13, 2015, 12:41:40 pm
Quote
From the screen shots, it looks like a clean vertical or horizontal cut. Can you confirm that?
I just checked. they are not clean horizontal and vertical cut, but sometimes in different combination of triangle cut.

Quote
Also make sure that your mat4[17] array is really filled by a maximum of 17 matrices to rule out the possibility of some data overflow.
The blue object will send matrix data[6] and the red one will send matrix[8], so it won't have overflow problem. But strangely, I tried putting exact amount for the matrix array size in shader, then it's working alright.
But why? I tot we specify the larger matrix array size in shader should not affect anything, right? If that fixes the issue, I could just create different shader for each object with different matrix array size, but I kinda worry about the overhead of keeping switching multiple shaders since the shaders are shared with other objects too.
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 13, 2015, 02:36:06 pm
Might be driver issue then. I would expect the unfilled instances to be just undefined....anyway, why don't you use a fixed array size of 17 for all of them and fill the gap with some dummy data.
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 13, 2015, 04:23:20 pm
You were right! Adding dummy matrix works as well!

For opaque objects seems to be ok now. There's another issue, btw. When I add in additive transparent objects at the back, the cut off reappear again. Is it zbuffer causing the issue again? Default shader works fine.

The additive transparent objects at the back use default jpct shaders.
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 13, 2015, 04:24:57 pm
More screenshots:

1st screenshot is taken in Nexus 6
2nd is from samsung device, which is expected result

 
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 13, 2015, 05:56:57 pm
In shader, I changed the "myPosition"(hardware skinning) to normal "position" from JPCT, and everything works ok. I think there must be something wrong with hardware skinning part. I still wonder why it just doesn't work on Nexus 6. Can it be possible the device can't handle that many of attributes data?
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 13, 2015, 07:35:10 pm
I'm a bit confused about the usage of skinJointIndices. It's a vec4, but you are using a [.]-index on it. Is that a valid syntax to access the components? Have you tried .x and .y instead?
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 14, 2015, 03:48:14 pm
I think I was copying from raft code. I changed them to .x and .y, it still gives the same result with cut off. What could be wrong? I'll try and check if the skinJointIndices contains any value bigger than the skinPalette matrix array size. Does out-of-bound-index possibly cause the problem?
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 14, 2015, 05:40:51 pm
Does out-of-bound-index possibly cause the problem?
Maybe. Either that or a similar thing as with the mat[]-array. It might be driver bug as well. Just rule that out, try to re-order your uniforms in the shader to see if that changes something.
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 15, 2015, 07:52:35 pm
I got the first shader fixed by adding back the "if (angle > 0.0)" (this part was commented in first shader). It seems if the vector angle between vertex and light position is < 0, it will mess up the whole thing. I can't be sure if that's the root cause, but it's working fine now.

As for the second shader, bcoz I'm using the sample code from http://www.jpct.net/wiki/index.php?title=Shaders (http://www.jpct.net/wiki/index.php?title=Shaders) (with bump map), it doesn't have "angle" value. Is there any way we can control to avoid processing the light calculation if the angle vector < 0, like the one in default shader?
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 16, 2015, 03:17:07 pm
Strangely, for second shader, if I change final color to 0.0 in fragment shader, it doesn't have the cut off anymore. Initially I thought some calculation in fragment that give NaN value to variable and mess up the system, but I tried using sqrt(-1) to produce NaN value, then set final color to 0.0, to try to reproduce the cut-off issue, but it still seemed ok. I'm getting out of idea, do you have any clue on this?

I tried reordering the uniforms, doesn't seem to fix the issue. In what way should we order the uniforms?

* Nexus 6 is really a pain-in-the-ass device. Only it causes the problem so far.     
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 17, 2015, 08:32:59 am
It's most likely caused by negative values for alpha or color values. Try to add something like

Code: [Select]
col=max(col, vec4(0.0, 0.0, 0.0, 0.0));
to see if that helps.
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 18, 2015, 09:55:02 am
Code: [Select]
col=max(col, vec4(0.0, 0.0, 0.0, 0.0));Tried and it's still have the same issue.

I tried to reorder the way of adding objects to world. By adding the transparent object (suppose to be in background, further away from camera), then adding the blue objects (closer to camera) after that, and it works now! I'm just curious if the order of adding object to world will affect the rendering. Do you have any idea what's going there?
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 18, 2015, 11:20:30 am
Do you have any idea what's going there?
No, not quite. Ordering in jPCT-AE happens by state for opaque objects and by depth for transparent ones. Regardless of that, transparent objects will be drawn after all opaque objects. So I fail to see how reordering them in World can help, because they will be reordered anyway. Are you using setSortOffset()? Have you tried without it? Maybe you are giving it some values that screw up the sorting.
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 18, 2015, 12:58:43 pm
Yes I'm using setSortOffset. I tried to disable all setSortOffset and strangely, it has cut off for first few frames, then it becomes ok after that. But if I disable setSortOffset, it would tend to draw object further away from camera first, in which it does not take advantage of deferred rendering. If we are to take advantage and reduce overdrawing, we should draw the front object first, then follows the back objects, right? That's how I use setSortOffset to achieve that.
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 18, 2015, 01:09:01 pm
...deferred rendering....
...so you are doing something special here? What exactly?
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 18, 2015, 04:13:51 pm
Just something we discussed earlier http://www.jpct.net/forum2/index.php/topic,3956.msg27790.html#msg27790 (http://www.jpct.net/forum2/index.php/topic,3956.msg27790.html#msg27790). CMIIW, if one opaque object A overlaps another object B, the part of B overlapped by A can be deferred and not required to be rendered. So this way we can save more fill rate. That's what I intended to do by using setSoftOffset(). Does it mess up with rendering? Maybe I have overlooked other factors?
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 18, 2015, 11:14:51 pm
I don't think that this will work in combination with the engine's default behaviour.  setSortOffset has no effect on opaque objects and while it might be possible to move a transparent object behind an opaque one, this is more like a crude hack and can work only by accident. In Config, there's a switch called stateOrientedSorting. By setting it to false, all objects will be sorted based on their depth. This might help in this case.
Have you tried not to do this deferred thingy at all? I don't think that it will help on anything but Tegra chips anyway.
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 19, 2015, 03:27:25 am
Quote
In Config, there's a switch called stateOrientedSorting
What will actually happen if I disable this, other than it's sorting by depth? If enabled, in what state it will sort?

Quote
Have you tried not to do this deferred thingy at all? I don't think that it will help on anything but Tegra chips anyway.
Last time I had a custom fragment shader which process alot of stuff (opaque object) and it's at the background. For some reason, it is drawn first rather than other objects at the front and performance seems to slow down alot. Then I tried setSortOffset and it helps improve by 5-8fps. Tested on samsung s4, I think it's octa core with PowerVR chip.
Title: Re: Object not shown and not rendered properly in some devices
Post by: EgonOlsen on August 19, 2015, 07:28:15 am
What will actually happen if I disable this, other than it's sorting by depth? If enabled, in what state it will sort?
If you disable it, all sorting happens based on the depth. If you enable it, opaque objects will be sorted by state (i.e. textures, shaders,...) and transparent ones by depth. That's usually the faster way, but if want to reorder opaque and transparent ones by using setSortOffset(), it won't work well.

Anyway, I would try it without that deferred stuff just to see if that changes anything.
Title: Re: Object not shown and not rendered properly in some devices
Post by: kkl on August 20, 2015, 05:20:01 am
I think for now I'll just disable most setSortOffset. Seems like not much different as the object that fills up most screen is using simple fragment shader.

Thanks alot for your help ; )