Need help about GLTF / shaders / normals

245 views
Skip to first unread message

Frédéric Trastour

unread,
Jun 2, 2016, 10:22:14 AM6/2/16
to cesium-dev
Hi All,

I'm trying to specify a simple shader set for displaying buildings - loaded from gltf file - to get something like in Cesium buildings demos (gray buildings).



I have tried to used same shaders as in Cesium demo (extracted from a gltb file), but result is very different... and I see two possibilities : either I failed in adapting the shaders (normals in these gltb file seems encoded on two values), or my normals are wrong.

Here is the code of my shaders after adaptation :

precision highp float;

uniform vec4 u_ambient;
uniform vec4 u_diffuse;
uniform vec4 u_emission;
uniform vec4 u_specular;
uniform float u_shininess;

varying vec3 v_normal;
varying vec3 v_positionEC;

void main(void) {
   vec3 normal = normalize(v_normal);
   vec4 color = vec4(0., 0., 0., 0.);
   
   float diffuseIntensity = 0.0;
   float specularIntensity = 0.0;
   vec4 diffuse = vec4(0., 0., 0., 1.);
   vec4 emission;
   vec4 ambient;
   vec4 specular;
   
   diffuse = u_diffuse;
   ambient = diffuse * 0.5;
   emission = u_emission;
   specular = u_specular;
   
   vec3 normalizedpositionToEyeEC = normalize(-v_positionEC);
   diffuseIntensity = czm_getLambertDiffuse(czm_sunDirectionEC, normal);
   specularIntensity = czm_getSpecular(czm_sunDirectionEC, normalizedpositionToEyeEC, normal, u_shininess) +
     0.25 * czm_getSpecular(czm_moonDirectionEC, normalizedpositionToEyeEC, normal, u_shininess);
   
   color.xyz += diffuse.xyz * diffuseIntensity;
   color.xyz += specular.xyz * specularIntensity;
   color = vec4(color.rgb * diffuse.a, diffuse.a);
   gl_FragColor = color;
}


precision highp float;

uniform vec4 u_ambient;
uniform vec4 u_diffuse;
uniform vec4 u_emission;
uniform vec4 u_specular;
uniform float u_shininess;

varying vec3 v_normal;
varying vec3 v_positionEC;

void main(void) {
   vec3 normal = normalize(v_normal);
   vec4 color = vec4(0., 0., 0., 0.);
   
   float diffuseIntensity = 0.0;
   float specularIntensity = 0.0;
   vec4 diffuse = vec4(0., 0., 0., 1.);
   vec4 emission;
   vec4 ambient;
   vec4 specular;
   
   diffuse = u_diffuse;
   ambient = diffuse * 0.5;
   emission = u_emission;
   specular = u_specular;
   
   vec3 normalizedpositionToEyeEC = normalize(-v_positionEC);
   diffuseIntensity = czm_getLambertDiffuse(czm_sunDirectionEC, normal);
   specularIntensity = czm_getSpecular(czm_sunDirectionEC, normalizedpositionToEyeEC, normal, u_shininess) +
     0.25 * czm_getSpecular(czm_moonDirectionEC, normalizedpositionToEyeEC, normal, u_shininess);
   
   color.xyz += diffuse.xyz * diffuseIntensity;
   color.xyz += specular.xyz * specularIntensity;
   color = vec4(color.rgb * diffuse.a, diffuse.a);
   gl_FragColor = color;
}

Note that the GLTF file use the CESIUM_RTC extension.

I saved my model as OBJ and normals seem good (in MeshLAB) :




But display in cesium is...not what I expected :



I would like to check if normals are good in the GLTF file & after loadig in Cesium.
I'm wondering if it is possible to use Cesium.createTangentSpaceDebugPrimitive on a gltf model loaded with something like :

    var model = scene.primitives.add(Cesium.Model.fromGltf({
        url : 'http://xxxx'
    }));

Any help appreciated,

Fred.

Hannah Pinkos

unread,
Jun 2, 2016, 11:46:28 AM6/2/16
to cesium-dev
Hi Fred,

It looks like the problem is with your normals.  It's hard to tell from the picture you posted, but make sure all normals are normalized (have a unit length)
Also, for corners, you need a separate normal vector for each face.  Otherwise the shader tries to round out the corners.  Here is an example of a box model that we use for testing.  You can see that each corner is duplicated so there is a normal for each face.



Best,

Hannah

Frédéric Trastour

unread,
Jun 2, 2016, 1:37:14 PM6/2/16
to cesium-dev
Hi Hannah,

thanks - I think the problem is definitively with the normals as they were calculated before I warp coordinates from cartographic system to ECEF - and normals are not warped.
I will try to convert them to.

Just a clarification : I have one normal for each triangle - but no normals for vertices; do you confirm that this is what is expected ?

Kr,
Fred.

Hannah Pinkos

unread,
Jun 2, 2016, 3:04:33 PM6/2/16
to cesium-dev
Hi Fred,

Having a normal for each triangle is probably okay.  I would guess the obj to gltf converter will put it in the correct format.

Best,

Hannah

Frédéric Trastour

unread,
Jun 3, 2016, 2:17:06 PM6/3/16
to cesium-dev
Hi,

I have triple checked my normals - OBJ version of my object (in ECEF system) displays fine with MeshLab and osgviewer.
If I reverse my normals ( to check that face winding is correct ), I got black face which is the expected behaviour in osgviewer for exemple.

At this point... I'm blocked. Maybe the problem comes from the shaders - my experience with GLSL is more than low.
I have just tried to copy and adapt shaders used in some buildings demos by analysis of gltb files - see at the end of history.

Maybe a shader gourou here could easily figure out if there is a problems in them.

Any help on how to :
- check normals of loaded GLTF files,
- writing basic shaders to display grey buildings,
- debug shaders
will be highly appreciated.

Thanks in advance;
Fred. 
Reply all
Reply to author
Forward
0 new messages