Object not shown and not rendered properly in some devices

Started by kkl, August 10, 2015, 02:56:41 PM

Previous topic - Next topic

kkl

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?

EgonOlsen


kkl

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?

EgonOlsen


kkl

The first shaders:
vertex shader-

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-

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-

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)-

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.

EgonOlsen

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...

kkl

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.

EgonOlsen

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...

kkl

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.

EgonOlsen

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?

kkl

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

kkl

The expected result is like this, tested on samsung device:

EgonOlsen

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.

kkl

QuoteFrom 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.

QuoteAlso 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.

EgonOlsen

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.