Shader not working in safari

Hello to the forum!
I do have a little issue with a ‘thinInstancing’ shader and safari. The ‘thinInstancing’ shader works fine in all other browsers, but unfortunately not in safari (not even in safari 14.0). Hence my question if this is a known issue and what would be ways to work around it. Following I attached the shader and the safari errors. The main problem is that ‘gl_InstanceID’ is an undeclared identifier. Why is undeclared in safari and not in all the other browsers. Thank you for any advice…

// VERTEX SHADER
precision highp float;

attribute vec3 position;
attribute vec4 world0;
attribute vec4 world1;
attribute vec4 world2;
attribute vec4 world3;

uniform mat4 world;
uniform mat4 viewProjection;

uniform float u_instanceSize;
uniform float u_noiseDirection;
uniform float u_Time;
uniform float u_waveSpeed;
uniform float u_waveLength;
uniform float u_waveHeight;
uniform float u_waveAmplitude;

varying float v_sinWave;

float u_PI = 3.14;

void main() {
    #ifdef INSTANCES
        mat4 instanceWorldMatrix1 = mat4(world0, world1, world2, world3);
    #ifdef THIN_INSTANCES
        instanceWorldMatrix1 = world * instanceWorldMatrix1;
    #endif
        float instanceID1 = float(gl_InstanceID);
    #else
        mat4 instanceWorldMatrix1 = world;
        float instanceID1 = 0.0;
    #endif

    vec3 instancePos = vec3(instanceID1);
    float direction = u_PI * u_noiseDirection;
    vec4 instanceOrientation = vec4(instancePos.x * sin(direction), instancePos.y, instancePos.z * cos(direction), 0.0);
    float sinWave = sin((instanceOrientation.x - u_Time * u_waveSpeed) / u_waveLength) * u_waveHeight + u_waveAmplitude;
    vec4 instanceScaleVector = vec4(u_instanceSize);
    vec4 instanceScale0 = world0 * instanceScaleVector;
    vec4 instanceScale1 = world1 * instanceScaleVector;
    vec4 instanceScale2 = world2 * instanceScaleVector;

    #ifdef INSTANCES
        mat4 instanceWorldMatrix2 = mat4(instanceScale0, instanceScale1, instanceScale2, world3);
    #ifdef THIN_INSTANCES
        instanceWorldMatrix2 = world * instanceWorldMatrix2;
    #endif
        float instanceID0 = float(gl_InstanceID);
    #else
        mat4 instanceWorldMatrix2 = world;
        float instanceID0 = 0.0;
    #endif

    gl_Position = viewProjection * instanceWorldMatrix2 * vec4(position, 1.0);
    v_sinWave = sinWave;
}

// FRAGMENT SHADER
precision highp float;

uniform float u_instanceSize;
uniform float u_noiseDirection;
uniform float u_Time;
uniform float u_waveSpeed;
uniform float u_waveLength;
uniform float u_waveHeight;
uniform float u_waveAmplitude;
            
varying float v_sinWave;

//#include<helperFunctions>

float u_PI = 3.14;

void main() {
    vec3 rgb = vec3(v_sinWave, 0.0, 0.0);
    //vec3 rgb = vec3(1.0,0.0,0.0);
    gl_FragColor = vec4(rgb, 1.0);
    #ifdef CONVERTTOLINEAR0
    gl_FragColor = toLinearSpace(gl_FragColor);
    #endif
    #ifdef CONVERTTOGAMMA0
    gl_FragColor = toGammaSpace(gl_FragColor);
    #endif
}



gl instance id is not available on ios, have a look at Compiling Node Materials with Instances on Safari - #17 by peterimg

Maybe @Evgeni_Popov has a workaround trick ?

1 Like

Hey Sebavan!
Thank you for providing this link.
I will give this a try first, before asking Evgeni.

1 Like

I think Safari on iOS 14 is WebGL1 only and not WebGL2? That would explain the problem.

A workaround is to use an instance attribute to pass the instance ID. See Thin Instances | Babylon.js Documentation

1 Like

Hey Evgeni!
Thanks for your reply. I checked for webgl2 support, but for now it is only an experimental feature.
Just a quick question regarding the attribute pass. Would position and rotation be two different attributes?
Thank you…!

Nothing would change in your shader except for an additional attribute attribute float instanceID; and something like that in javascript:

const numInstances = ...;
const bufferInstanceID = new Float32Array(numInstances);

for (let i = 0; i < numInstances; ++i) {
    bufferInstanceID[i] = i;
}

mesh.thinInstanceSetBuffer("instanceID", bufferInstanceID, 1);

Hey Evgeni!
Thanks so much for this snippet. :slightly_smiling_face: I have already been looking at how to do matrix rotations and stuff related to it. :nerd_face: I will try it out and see what it does. Let you know…

Hi @virtuos just checking in, did the workaround… work (:rofl: ) for you?

Hey Carol!
It does work if you activate WebGL2 in Safari (Developer mode). Yet, since I would like it to work also for the non developer user, I am still trying to get the shader to work in WebGL1. Unfortunately, I didn’t have time to investigate it further, yet. Will get back to it in January and let you know in this post.
Cheers, Kay

1 Like