Transparent object not showing in some devices

Started by kkl, August 30, 2014, 12:40:06 PM

Previous topic - Next topic

kkl

Hi Egon,

Have you had this situation before? Tested on galaxy trend plus (I think the GPU is Broadcom VideoCore IV). However, other devices like S4 and note 10 are working fine. Previously, I removed some uniforms in shader and it worked fine. But after I'm adding more objects, the transparent object disappears again. Could this be possibly caused by the shader/hardware limitation?

EgonOlsen

If you fiddled around with the shaders, it might be a problem with the shader compiler or the driver. Any warning or error messages from the shader compiler in the log?

kkl

Yes, i'm using my custom shader. There is no warning or error for the shader. It seems like Broadcom is behaving different compared to PowerVR chip.

Here's my custom shader,
vertex shader:

uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;

uniform vec4 additionalColor;
uniform vec4 ambientColor;

uniform float shininess;

uniform int lightCount;

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 vec2 texture0;
attribute vec2 texture1;

attribute vec4 skinWeights;
attribute vec4 skinJointIndices;

varying vec2 texCoord[4];
varying vec4 vertexColor;

void main() {

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

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;

vec4 vertexPos = modelViewMatrix * myPosition;
vertexColor = ambientColor;

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(myNormal, 0.0)).xyz;

float angle = dot(normalEye, normalize(lightPositions[0] - vertexPos.xyz));

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[0] * angle + specularColors[0] * pow(angle, shininess))*(1.0/(1.0+length(lightPositions[0] - vertexPos.xyz)*attenuation[0])), 1) * additionalColor;
}
}

gl_Position = modelViewProjectionMatrix * myPosition;
}

skinPalette, skinWeights, skinJointIndices are the variables for hardware skinning.

fragment shader:

precision mediump float;

uniform sampler2D textureUnit0;
uniform sampler2D textureUnit1;

uniform int textureCount;

varying vec2 texCoord[4];
varying vec4 vertexColor;

void main() {
vec4 col = texture2D(textureUnit0, texCoord[0]) * vertexColor;
gl_FragColor=col;
}


In addition, I tried with this edited default vertex shader with fragment shader above:
vertex shader:

uniform mat4 modelViewMatrix;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 textureMatrix;

uniform vec4 additionalColor;
uniform vec4 ambientColor;
uniform float shininess;

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 vec2 texture0;
attribute vec2 texture1;

varying vec2 texCoord[4];
varying vec4 vertexColor;

void main() {

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

vec4 vertexPos = modelViewMatrix * position;
vertexColor = ambientColor;

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;

float angle = dot(normalEye, normalize(lightPositions[0] - vertexPos.xyz));

if (angle > 0.0) {
vertexColor += vec4((diffuseColors[0] * angle + specularColors[0] * pow(angle, shininess))*(1.0/(1.0+length(lightPositions[0] - vertexPos.xyz)*attenuation[0])), 1) * additionalColor;
}

}

gl_Position = modelViewProjectionMatrix * position;
}

The result is even more strange. The object shows only part of it, and the rest of polygons are not showed. But it looks fine in other devices.

EgonOlsen

Might be an issue with the driver or the hardware then. If it is, there's not much you can do except for trying to strip down the shader until and works and see if you can work around this. jPCT-AE's default shaders include several of these "hacks" to make them work on all devices that i could get my hands on.

kkl

What are the 'hacks'? Would love to listen more about it ;)

EgonOlsen


EgonOlsen

If this VideoCore thing is a deferred renderer, it might be a problem with binning, i.e. it can't handle that many polygons in one pass. You can try to render the world in multiple passes: The first one with all the opaque objects visible, the second one with all the transparent ones. If that works, it's a hardware limitation.

kkl

I tried reducing the number of uniforms, varying and attributes, and for some reasons, it's working fine! I'm not quite sure what actually fixed it.

btw, if we use the multi pass, does it reduce the cost performance for transparency?


kkl

I think I'll stick with current one since it's working now.. Thanks alot for your help egon. Really appreciate it