ptitSeb / gl4es

GL4ES is a OpenGL 2.1/1.5 to GL ES 2.0/1.1 translation library, with support for Pandora, ODroid, OrangePI, CHIP, Raspberry PI, Android, Emscripten and AmigaOS4.
http://ptitseb.github.io/gl4es/
MIT License
691 stars 158 forks source link

Shaders after shadercov question #268

Open kas1e opened 3 years ago

kas1e commented 3 years ago

Another thing to discuss if you don't mind :)

Working on some games, and it has quite a big set of original OpenGL shaders. Now, when I run a game, it brings me from some shaders that:

Compiler message is
ERROR: 94:1: 'assign' :  cannot convert from ' const int' to ' temp highp float'
ERROR: 135:0: '' : compilation terminated 
ERROR: 2 compilation errors.  No code generated. 

I enabled LIBGL_LOGSHADERERROR, and that what I have:

original shader:

uniform sampler2D Texture0, Texture1, Texture2, Texture3;

varying vec3 Normal;
varying float fogFactor;
varying vec4 Position;

vec4 CelShading(int l)
{
    // Get texture color
    vec4 color = gl_LightModel.ambient * gl_Color * texture2D(Texture0, vec2(gl_TexCoord[0]));

    // Light orientation
    vec3 LightDir = vec3(gl_LightSource[l].position-Position);
    float dotProduct = max(dot(normalize(LightDir), normalize(Normal)), 0.0);

    // Light attenuation
    float dist = length(LightDir);
    float att = 1.0 / (gl_LightSource[l].constantAttenuation + gl_LightSource[l].quadraticAttenuation * dist * dist);
    att *= 500;

    // 'Tooning'
    float toonFactor = dotProduct;
    toonFactor *= att;
    if (toonFactor < 0.2) toonFactor = clamp(toonFactor, 0.0, 0.05);
    else if (toonFactor < 0.5) toonFactor = clamp(toonFactor, 0.2, 0.35);
    else if (toonFactor < 0.95) toonFactor = clamp(toonFactor, 0.5, 0.65);
    else toonFactor = clamp(toonFactor, 0.95, 1.0);

    // Final color
    vec4 diffuse = gl_LightSource[l].diffuse;
    diffuse /= vec4(128, 128, 128, 1.0);
    color += toonFactor * diffuse * gl_Color * texture2D(Texture0, vec2(gl_TexCoord[0]));

    return color;
}

void main()
{
    vec4 color = vec4(0.0, 0.0, 0.0, 0.0);

    for (int i = 0; i < gl_MaxLights; i++)
    {
        color += CelShading(i);
    }

    // Rim light
    vec3 eyePos = normalize(vec3(-Position));
    float fresnel = max(dot(normalize(Normal), eyePos), 0.0);
    if (fresnel < 0.4)
    {
        float rim = clamp((0.4 - fresnel) / 0.4, 0.0, 1.0);
        color += color * rim;
    }

    color = mix(gl_Fog.color, color, fogFactor);
    color.a = 0.5;
    gl_FragColor = color;
} 

ShaderConv one ready to use:

#version 100
precision highp float;
#define _gl4es_MaxLights 8
precision highp int;
varying lowp vec4 _gl4es_FrontColor;
varying mediump vec4 _gl4es_TexCoord_0;
struct _gl4es_LightSourceParameters
{
   vec4 ambient;
   vec4 diffuse;
   vec4 specular;
   vec4 position;
   vec4 halfVector;
   vec3 spotDirection;
   float spotExponent;
   float spotCutoff;
   float spotCosCutoff;
   float constantAttenuation;
   float linearAttenuation;
   float quadraticAttenuation;
};
uniform _gl4es_LightSourceParameters _gl4es_LightSource[_gl4es_MaxLights];
struct _gl4es_LightModelParameters {
  vec4 ambient;
};
uniform _gl4es_LightModelParameters _gl4es_LightModel;
struct _gl4es_FogParameters {
    lowp vec4 color;
    mediump float density;
    highp   float start;
    highp   float end;
    highp   float scale;
};
uniform _gl4es_FogParameters _gl4es_Fog;
float clamp(float f, int a, int b) {
 return clamp(f, float(a), float(b));
}
float clamp(float f, float a, int b) {
 return clamp(f, a, float(b));
}
float clamp(float f, int a, float b) {
 return clamp(f, float(a), b);
}
vec2 clamp(vec2 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec2 clamp(vec2 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec2 clamp(vec2 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec3 clamp(vec3 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec3 clamp(vec3 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec3 clamp(vec3 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec4 clamp(vec4 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec4 clamp(vec4 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec4 clamp(vec4 f, int a, float b) {
 return clamp(f, float(a), b);
}
float max(float a, int b) {
 return max(a, float(b));
}
float max(int a, float b) {
 return max(float(a), b);
}
uniform sampler2D Texture0, Texture1, Texture2, Texture3;

varying vec3 Normal;
varying float fogFactor;
varying vec4 Position;

vec4 CelShading(int l)
{

    vec4 color = _gl4es_LightModel.ambient * _gl4es_FrontColor * texture2D(Texture0, vec2(_gl4es_TexCoord_0));

    vec3 LightDir = vec3(_gl4es_LightSource[l].position-Position);
    float dotProduct = max(dot(normalize(LightDir), normalize(Normal)), 0.00000);

    float dist = length(LightDir);
    float att = 1.00000 / (_gl4es_LightSource[l].constantAttenuation + _gl4es_LightSource[l].quadraticAttenuation * dist * dist);
    att *= 500;

    float toonFactor = dotProduct;
    toonFactor *= att;
    if (toonFactor < 0.200000) toonFactor = clamp(toonFactor, 0.00000, 0.0500000);
    else if (toonFactor < 0.500000) toonFactor = clamp(toonFactor, 0.200000, 0.350000);
    else if (toonFactor < 0.950000) toonFactor = clamp(toonFactor, 0.500000, 0.650000);
    else toonFactor = clamp(toonFactor, 0.950000, 1.00000);

    vec4 diffuse = _gl4es_LightSource[l].diffuse;
    diffuse /= vec4(128, 128, 128, 1.00000);
    color += toonFactor * diffuse * _gl4es_FrontColor * texture2D(Texture0, vec2(_gl4es_TexCoord_0));

    return color;
}

void main()
{
    vec4 color = vec4(0.00000, 0.00000, 0.00000, 0.00000);

    for (int i = 0; i < _gl4es_MaxLights; i++)
    {
        color += CelShading(i);
    }

    vec3 eyePos = normalize(vec3(-Position));
    float fresnel = max(dot(normalize(Normal), eyePos), 0.00000);
    if (fresnel < 0.400000)
    {
        float rim = clamp((0.400000 - fresnel) / 0.400000, 0.00000, 1.00000);
        color += color * rim;
    }

    color = mix(_gl4es_Fog.color, color, fogFactor);
    color.a = 0.500000;
    gl_FragColor = color;
} 

I give it a go through GLSlangvalidator , and it brings the same error.

Next what I do, is set the version to 120. Error changes, says:

ERROR: 1:1: '' : syntax error, unexpected IDENTIFIER
ERROR: 1 compilation errors. No code generated

But then, I set version 150, and it works! Compiles fine, all fine.

So questions are:

1). Do we need to set the version to 100 in gl4es for generated shaders from OpenGL ones? Shouldn't we just set 150 by default and be it? Or it did for a purpose?

2). If version 100 is done for purpose, can i somehow hack the gl4es, so i just will have gl4es build just for this game with version 150 ? I just tried to change in shaderconv.c that line:

static const char* GLESHeader[] = {
  "#version 100\n%sprecision %s float;\nprecision %s int;\n",

on that:

static const char* GLESHeader[] = {
  "#version 150\n%sprecision %s float;\nprecision %s int;\n",

and it leads to the massive amount of new errors, all shaders fail to compiles, etc. So seems just such a simple change as a non-go, maybe somewhere else (if it will work at all?).

thanks!

kas1e commented 3 years ago

Btw, version 130 and version 140 also seem fine to compile that shader. Just not 100 or 120

ptitSeb commented 3 years ago

Yes, version 100 is on purpose, as it's the only one supported by gles2.

I think the issue is with att *= 500; that should be att *= 500.0; instead.

Also, this line diffuse /= vec4(128, 128, 128, 1.0); is suspicious and should probably be diffuse /= vec4(128.0, 128.0, 128.0, 1.0);

I can try to add that to the hack part of gl4es. What game is this?

kas1e commented 3 years ago

Its closed source game called "Worlds" , and it has quite lot of shaders .. But yeah, we can ad them as hacks, just how to check that this is "worlds" game ? Is your hacks based on the game's names ?

kas1e commented 3 years ago

The game there : https://store.steampowered.com/app/304850/Worlds/ , maybe it works on gl4es/wine/bx86 already so you can test if the shaders works ?

Error of this kind happens when we have "very low" details set. The more details level set, the more shaders used. So you firstly may try with "very low" details, then just set "very high" (and restart of course, as it irrlicht), and see if it will bring more errors or not. But i hope maybe in end it will be just 1-2 hacks for all of them ?

kas1e commented 3 years ago

Btw, just changing att *= 500; to att *= 500.0makes it works!

ptitSeb commented 3 years ago

The hack is not based on game name, only on part of shader, but I like to keep a track on what game need what hack.

kas1e commented 3 years ago

Aha got it, so it based just on the uniq sequence in hope that will never repeats anywhere. Uhm, but if we will have 10 different shaders with the same error, it should be 10 different hacks ?

ptitSeb commented 3 years ago

Depends on how long and unambiguous is the sequence. att *= 500; is a bit short, so I'll probably take previous line too.

kas1e commented 3 years ago

Yeah, let's try step by step, will see how many hacks it may needs.

But those things are fixable only by hacks, nothing like general solution in generated code can be done ?

ptitSeb commented 3 years ago

General solution need a complete GLSL "compiler" in gl4es. That would be nice, and open the door to many more things, but it's a huge work and not planed for now.

kas1e commented 3 years ago

Tested more shaders for the game: many of them have that error, but good for us it always seems att *= 500 stuf.

There is also another set of shaders brings different kind of errors:

ERROR: 73:1: '*' :  wrong operand types: no operation '*' exists that takes a left-hand operand of type ' global highp 4-component vector of float' and a right operand of type ' const int' (or there is no acceptable conversion)
ERROR: 100:0: '' : compilation terminated 
ERROR: 2 compilation errors.  No code generated.

That for this kind of shader:

#version 100
precision highp float;
precision highp int;
varying mediump vec4 _gl4es_TexCoord_0;
varying mediump vec4 _gl4es_TexCoord_1;
struct _gl4es_LightModelParameters {
  vec4 ambient;
};
uniform _gl4es_LightModelParameters _gl4es_LightModel;
struct _gl4es_FogParameters {
    lowp vec4 color;
    mediump float density;
    highp   float start;
    highp   float end;
    highp   float scale;
};
uniform _gl4es_FogParameters _gl4es_Fog;
float clamp(float f, int a, int b) {
 return clamp(f, float(a), float(b));
}
float clamp(float f, float a, int b) {
 return clamp(f, a, float(b));
}
float clamp(float f, int a, float b) {
 return clamp(f, float(a), b);
}
vec2 clamp(vec2 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec2 clamp(vec2 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec2 clamp(vec2 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec3 clamp(vec3 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec3 clamp(vec3 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec3 clamp(vec3 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec4 clamp(vec4 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec4 clamp(vec4 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec4 clamp(vec4 f, int a, float b) {
 return clamp(f, float(a), b);
}
float max(float a, int b) {
 return max(a, float(b));
}
float max(int a, float b) {
 return max(float(a), b);
}
uniform sampler2D Texture0, Texture1;
varying vec3 Normal;
varying float fogFactor;
varying vec4 Position;

float getLuminance(vec4 color)
{
    return dot(color, vec4(0.299000, 0.587000, 0.114000, 0.00000));
}

void main()
{
    vec4 texel0 = texture2D(Texture0, vec2(_gl4es_TexCoord_0));
    vec4 texel1 = texture2D(Texture1, vec2(_gl4es_TexCoord_1));
    texel1 = texel1 + _gl4es_LightModel.ambient * 2;
    float tmp = texel1.r + texel1.g + texel1.b;
    float factor = 0.00000;
    if (tmp > 0.300000) factor = 0.950000;
    else if (tmp > 0.200000) factor = 0.700000;
    else if (tmp > 0.100000) factor = 0.500000;
    else if (tmp > 0.0500000) factor = 0.300000;
    else if (tmp > 0.0250000) factor = 0.100000;
    else factor = 0.00000;

    texel1 *= 7.00000;
    vec4 color = texel0 * texel1 * factor;

    vec3 eyePos = normalize(vec3(-Position));
    float fresnel = max(dot(normalize(Normal), eyePos), 0.00000);
    if (fresnel < 0.400000)
    {
        float rim = clamp((0.400000 - fresnel) / 0.400000, 0.00000, 1.00000);
        float l = clamp(getLuminance(color), 0.00000, 1.00000);
        l = 1.00000 - l;
        color += color * rim * l;
    }

    color = mix(_gl4es_Fog.color, color, fogFactor);
    gl_FragColor = color;
} 

Issue there is line texel1 = texel1 + _gl4es_LightModel.ambient * 2;, once replaced on *2.0; then all compiles fine.

So far it seems we can just add 2 hacks, and it can be it.

Btw, adding of hack as it sees trivial: I just put one string (the original one), and then just "new" one in shader_hack.c, and no changes anywhere else need it ?

ptitSeb commented 3 years ago

Yep, it's that simple because I designed it to be easy to add more hack :)

kas1e commented 3 years ago

just tried at top that:

static const hack_t gl4es_hacks[] = {

// Worlds 

//1
{"att *= 500;",
1,
{"att *= 500.0;",}},
//2
{"texel1 = texel1 + _gl4es_LightModel.ambient * 2;",
1,
{"texel1 = texel1 + _gl4es_LightModel.ambient * 2.0;"}},

Didn't swaps :) Maybe something still need to be done somewhere else ?:)

kas1e commented 3 years ago

Spaces/tabs also taken into account I assume?

ptitSeb commented 3 years ago

Yes, sapce and Tabs are differents, and so are new line (not relevent here).

kas1e commented 3 years ago

Strange .. just copy+paste the line exactly from shader.. And from LIBGL_LOGSHADERERROR if it still spawns (because of other error for example) I should see that 2 changes on 2.0, right?

kas1e commented 3 years ago

Ah damn crap, we change ORIGINAL lines, not shaderconv generated :))

kas1e commented 3 years ago

Done with 3 hacks, now next shader which doesn't know how to fix (even version change dind't help):

ERROR: 56:1: 'texture2D' : no matching overloaded function found 
ERROR: 56:1: '=' :  cannot convert from ' const float' to ' temp highp 4-component vector of float'
ERROR: 108:0: '' : compilation terminated 
ERROR: 3 compilation errors.  No code generated. 

That is the shader:

#version 100
precision highp float;
precision highp int;
varying mediump vec4 _gl4es_TexCoord_0;
float clamp(float f, int a, int b) {
 return clamp(f, float(a), float(b));
}
float clamp(float f, float a, int b) {
 return clamp(f, a, float(b));
}
float clamp(float f, int a, float b) {
 return clamp(f, float(a), b);
}
vec2 clamp(vec2 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec2 clamp(vec2 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec2 clamp(vec2 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec3 clamp(vec3 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec3 clamp(vec3 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec3 clamp(vec3 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec4 clamp(vec4 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec4 clamp(vec4 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec4 clamp(vec4 f, int a, float b) {
 return clamp(f, float(a), b);
}
uniform sampler2D Texture0;
varying vec4 Position;

vec4 interpolate(vec4 c0, vec4 c1, float f)
{
    vec4 r = (c0 * (1.00000 - f)) + (c1 * f);
    return r;
}

float getLuminance(vec4 color)
{
    return dot(color, vec4(0.299000, 0.587000, 0.114000, 0.00000));
}

void main()
{
    vec4 color = texture2D(Texture0, _gl4es_TexCoord_0);
    color *= vec4(0.800000, 1.00000, 1.00000, 1.00000);

    vec4 bloom = vec4(0);
    vec4 bloomL = vec4(0);
    int pass = 0;
    int range = 5;
    float th = 0.700000;

    for (int j = -range; j <= range; j++)
    {
        for (int i = -range; i <= range; i++)
        {

            vec2 offset = vec2(i, j) * 0.00100000;
            offset += _gl4es_TexCoord_0;
            offset = clamp(offset, vec2(0.00000, 0.00000), vec2(1.00000, 1.00000));

            vec4 add = texture2D(Texture0, offset);
            bloom += add;

            offset = vec2(i, j) * 0.00250000;
            offset += _gl4es_TexCoord_0;
            offset = clamp(offset, vec2(0.00000, 0.00000), vec2(1.00000, 1.00000));

            add = texture2D(Texture0, offset);
            float lum = getLuminance(add);
            if (lum > th)
            {
                float factor = (lum - th) / (1.00000 - th);
                bloomL += add * factor;
            }

            pass++;
        }
    }

    bloom /= pass;
    bloom *= 0.250000;

    bloomL /= pass;
    bloomL *= 0.500000;

    float sFactor = (Position.y + 1.00000) / 2.00000;
    sFactor *= 0.400000;
    sFactor += 0.800000;

    color *= 0.750000;
    color *= sFactor;
    gl_FragColor = color + bloom + bloomL;
} 

Have a clue how to deal with this one ?

ptitSeb commented 3 years ago

Ah damn crap, we change ORIGINAL lines, not shaderconv generated :))

Ah yes, I should have mentionned it!

For the other shader, the issue is that transformed line vec4 color = texture2D(Texture0, _gl4es_TexCoord_0); it should be vec4 color = texture2D(Texture0, _gl4es_TexCoord_0.xy); but again, you need the original line...

kas1e commented 3 years ago

Yeah, replaced that line, but now for that shader still have those errors:

ERROR: 71:1: 'assign' :  cannot convert from ' smooth in mediump 4-component vector of float' to ' temp highp 2-component vector of float'
ERROR: 107:0: '' : compilation terminated 
ERROR: 2 compilation errors.  No code generated. 
kas1e commented 3 years ago

replaced in 2 other places on .xy at the end, and then it fails seems so on bloom/=pass, which seems related to issues that bloom are vec4, but the pass is int.

kas1e commented 3 years ago

Also find out, that when i add such hacks:

//4
{"  vec4 color = texture2D(Texture0, gl_TexCoord[0]);",
1,
{"  vec4 color = texture2D(Texture0, _gl4es_TexCoord_0.xy);"}},
//5
{"      offset += gl_TexCoord[0];",
1,
{"      offset += _gl4es_TexCoord_0.xy;"}},

In some generated shaders just disappear line varying medium vec4 _gl4es_TexCoord_0! Can be a bug in hack-insert stuff, or i just mess something ?

ptitSeb commented 3 years ago

then try bloom/=float(pass)

ptitSeb commented 3 years ago

//4 {" vec4 color = texture2D(Texture0, gl_TexCoord[0]);", 1, {" vec4 color = texture2D(Texture0, gl_TexCoord[0].xy);"}},

Why don't you use

//4
{"  vec4 color = texture2D(Texture0, gl_TexCoord[0]);",
1,
{"  vec4 color = texture2D(Texture0, gl_TexCoord[0].xy);"}},

Instead?

kas1e commented 3 years ago

dunno, just mimic shaderconv resutls :) will try that one now.

kas1e commented 3 years ago

Well, i do it because shaderconv do at top by default varying medium vec4 _gl4es_TexCoord_0, so if i put it as you wrote, then it will say that gl_TexCoord_0 undeclared identifier.

kas1e commented 3 years ago

for bloom/=float(pass) : sytax error, unexpected RIGHT_PAREN, expecting LEFT_PAREN

kas1e commented 3 years ago

Also if i just put everywhere gl_TexCoord[0].xy, it also says undeclared identifier, because in generated shaderconv shader there is no any varying medium vec4 gl_TexCoord or varying medium vec4 _gl4es_TexCoord_0. So it also fails.

ptitSeb commented 3 years ago

for bloom/=float(pass) : sytax error, unexpected RIGHT_PAREN, expecting LEFT_PAREN

This should be correct syntax (execpt for the missing ;), it shoud work

Also if i just put everywhere gl_TexCoord[0].xy, it also says undeclared identifier, because in generated shaderconv shader there is no any varying medium vec4 gl_TexCoord or varying medium vec4 _gl4es_TexCoord_0. So it also fails.

That's odd. Maybe there is a bug in shaderconv

kas1e commented 3 years ago

This should be correct syntax (execpt for the missing ;), it shoud work

Full line i have now are bloom/= (float)pass;, and bring that error. those are defined as : vec4 bloom = vec4(0); and int pass = 0;

That's odd. Maybe there is a bug in shaderconv

It seems so. At least when i just do that at the top:

static const hack_t gl4es_hacks[] = {

// Worlds 

//1
{"  att *= 500;",
1,
{"  att *= 500.0;"}},
//2
{"  texel1 = texel1 + gl_LightModel.ambient * 2;",
1,
{"  texel1 = texel1 + gl_LightModel.ambient * 2.0;"}},
//3
{"  vec4 ambient = gl_LightModel.ambient * 2;",
1,
{"  vec4 ambient = gl_LightModel.ambient * 2.0;"}},

//4
{"  vec4 color = texture2D(Texture0, gl_TexCoord[0]);",
1,
{"  vec4 color = texture2D(Texture0, _gl4es_TexCoord_0.xy);"}},

//5
{"      offset += gl_TexCoord[0];",
1,
{"      offset += _gl4es_TexCoord_0.xy;"}},

Then some compiled shaders just didn't have anymore varying medium vec4 _gl4es_TexCoord_0 at all. But if i change it like you say (to gl_TexCoord instead), then, this varying medium vec4 _gl4es_TexCoord_0 are in generated shaders, but then it should be gl_TexCoord instead.

And I specially choose _gl4es_TexCoord_0 there, because of that varying medium vec4 _gl4es_TexCoord_0 at the top. If it only not disappear randomly :)

kas1e commented 3 years ago

Yes, there seems indeed some issue with shaderconv , once I put those 2 entries about replacing on _gl4es_TexCoord_0.xy, then at the top line with varying medium vec4 _gl4es_TexCoord_0 just disappear.

ptitSeb commented 3 years ago

Full line i have now are bloom/= (float)pass;, and bring that error. those are defined as : vec4 bloom = vec4(0); and int pass = 0;

No, GLSL syntax is bloom/= float(pass); image (this is from the pdf of the glsl syntax for GLES2 shaders)

kas1e commented 3 years ago

Right, seems yesterday at night mess things, it works indeed. But issues with dissapeared varying line still here. Maybe buffers need to be increased somewhere ?

ptitSeb commented 3 years ago

no, it's something else, probably the . is messing up shaderconv detection function. I need to fix that.

kas1e commented 3 years ago

it's like it bug is vary depend how much of those texcoord.xy hacks i put. For example, for now for that game i have this block:

// Worlds 

//1
{"  att *= 500;",
1,
{"  att *= 500.0;"}},
//2
{"  texel1 = texel1 + gl_LightModel.ambient * 2;",
1,
{"  texel1 = texel1 + gl_LightModel.ambient * 2.0;"}},
//3
{"  vec4 ambient = gl_LightModel.ambient * 2;",
1,
{"  vec4 ambient = gl_LightModel.ambient * 2.0;"}},

//4
{"  vec4 color = texture2D(Texture0, gl_TexCoord[0]);",
1,
{"  vec4 color = texture2D(Texture0, _gl4es_TexCoord_0.xy);"}},
//5
{"      offset += gl_TexCoord[0];",
1,
{"      offset += _gl4es_TexCoord_0.xy;"}},

//6
{"  bloom /= pass;",
1,
{"  bloom /= float(pass);"}},

//7
{"  bloomL /= pass;",
1,
{"  bloomL /= float(pass);"}},

And for that original shader:

uniform sampler2D Texture0;
varying vec4 Position;

vec4 interpolate(vec4 c0, vec4 c1, float f)
{
    vec4 r = (c0 * (1.0 - f)) + (c1 * f);
    return r;
}

float getLuminance(vec4 color)
{
    return dot(color, vec4(0.299, 0.587, 0.114, 0.0));
}

void main()
{
    vec4 color = texture2D(Texture0, gl_TexCoord[0]);

    vec4 bloom = vec4(0);
    vec4 bloomL = vec4(0);
    int pass = 0;
    int range = 5;
    float th = 0.7;

    for (int j = -range; j <= range; j++)
    {
        for (int i = -range; i <= range; i++)
        {
            // Default bloom
            vec2 offset = vec2(i, j) * 0.001;
            offset += gl_TexCoord[0];
            offset = clamp(offset, vec2(0.0, 0.0), vec2(1.0, 1.0));

            vec4 add = texture2D(Texture0, offset);
            bloom += add;

            // Luminance bloom
            offset = vec2(i, j) * 0.0025;
            offset += gl_TexCoord[0];
            offset = clamp(offset, vec2(0.0, 0.0), vec2(1.0, 1.0));

            add = texture2D(Texture0, offset);
            float lum = getLuminance(add);
            if (lum > th)
            {
                float factor = (lum - th) / (1.0 - th);
                bloomL += add * factor;
            }

            pass++;
        }
    }

    bloom /= pass;
    bloom *= 0.1;

    bloomL /= pass;
    bloomL *= 0.25;

    float sFactor = (Position.y + 1.0) / 2.0;
    sFactor *= 0.4;
    sFactor += 0.8;

    color *= 0.9;
    color *= sFactor;
    gl_FragColor = color + bloom + bloomL;
}

I got that generated one:

#version 100
precision highp float;
precision highp int;
float clamp(float f, int a, int b) {
 return clamp(f, float(a), float(b));
}
float clamp(float f, float a, int b) {
 return clamp(f, a, float(b));
}
float clamp(float f, int a, float b) {
 return clamp(f, float(a), b);
}
vec2 clamp(vec2 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec2 clamp(vec2 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec2 clamp(vec2 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec3 clamp(vec3 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec3 clamp(vec3 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec3 clamp(vec3 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec4 clamp(vec4 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec4 clamp(vec4 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec4 clamp(vec4 f, int a, float b) {
 return clamp(f, float(a), b);
}
uniform sampler2D Texture0;
varying vec4 Position;

vec4 interpolate(vec4 c0, vec4 c1, float f)
{
    vec4 r = (c0 * (1.00000 - f)) + (c1 * f);
    return r;
}

float getLuminance(vec4 color)
{
    return dot(color, vec4(0.299000, 0.587000, 0.114000, 0.00000));
}

void main()
{
    vec4 color = texture2D(Texture0, _gl4es_TexCoord_0.xy);

    vec4 bloom = vec4(0);
    vec4 bloomL = vec4(0);
    int pass = 0;
    int range = 5;
    float th = 0.700000;

    for (int j = -range; j <= range; j++)
    {
        for (int i = -range; i <= range; i++)
        {

            vec2 offset = vec2(i, j) * 0.00100000;
            offset += _gl4es_TexCoord_0.xy;
            offset = clamp(offset, vec2(0.00000, 0.00000), vec2(1.00000, 1.00000));

            vec4 add = texture2D(Texture0, offset);
            bloom += add;

            offset = vec2(i, j) * 0.00250000;
            offset += _gl4es_TexCoord_0.xy;
            offset = clamp(offset, vec2(0.00000, 0.00000), vec2(1.00000, 1.00000));

            add = texture2D(Texture0, offset);
            float lum = getLuminance(add);
            if (lum > th)
            {
                float factor = (lum - th) / (1.00000 - th);
                bloomL += add * factor;
            }

            pass++;
        }
    }

    bloom /= float(pass);
    bloom *= 0.100000;

    bloomL /= float(pass);
    bloomL *= 0.250000;

    float sFactor = (Position.y + 1.00000) / 2.00000;
    sFactor *= 0.400000;
    sFactor += 0.800000;

    color *= 0.900000;
    color *= sFactor;
    gl_FragColor = color + bloom + bloomL;
} 

See, this time varying medium vec4 _gl4es_TexCoord_0 just disappear from the top.

kas1e commented 3 years ago

Another error about this original line:

vec2 coord = vec2(floor(gl_TexCoord[0].x * 640) / 640, floor(gl_TexCoord[0].y * 480) / 480);

which repalced by shaderconv on that one:

vec2 coord = vec2(floor(_gl4es_TexCoord_0.x * 640) / 640, floor(_gl4es_TexCoord_0.y * 480) / 480);

saying same ERROR: 56:1: '*' : wrong operand types: no operation '*' exists that takes a left-hand operand of type ' temp mediump float' and a right operand of type ' const int' (or there is no acceptable conversion)

ptitSeb commented 3 years ago

should be vec2 coord = vec2(floor(gl_TexCoord[0].x * 640.) / 640., floor(gl_TexCoord[0].y * 480.) / 480.);

kas1e commented 3 years ago

hm.. but we don't have gl_TexCoord varying at top of shaderconv shader, we have only _gl4es_TexCoord_0, and only when it not disappear :) gl_TexCoord[0] probably will not work, because there also no varying at the top about.

edit: ah, you just mean dot's at the end, ok, will check now.

kas1e commented 3 years ago

yeah, dots fixes it. Now probably (i hope) the last thing to deal with: why varying medium vec4 _gl4es_TexCoord_0 disappear from the top of generated shader once hacks in place.

That is a full set of hacks for that game at the moment:

// Worlds 

//1
{"  att *= 500;",
1,
{"  att *= 500.0;"}},

//2
{"  texel1 = texel1 + gl_LightModel.ambient * 2;",
1,
{"  texel1 = texel1 + gl_LightModel.ambient * 2.0;"}},
//3
{"  vec4 ambient = gl_LightModel.ambient * 2;",
1,
{"  vec4 ambient = gl_LightModel.ambient * 2.0;"}},

//4
{"  vec4 color = texture2D(Texture0, gl_TexCoord[0]);",
1,
{"  vec4 color = texture2D(Texture0, _gl4es_TexCoord_0.xy);"}},
//5
{"      offset += gl_TexCoord[0];",
1,
{"      offset += _gl4es_TexCoord_0.xy;"}},

//6
{"  bloom /= pass;",
1,
{"  bloom /= float(pass);"}},

//7
{"  bloomL /= pass;",
1,
{"  bloomL /= float(pass);"}},

//8

{"  vec2 coord = vec2(floor(gl_TexCoord[0].x * 640) / 640, floor(gl_TexCoord[0].y * 480) / 480);",
1,
{"  vec2 coord = vec2(floor(_gl4es_TexCoord_0.x * 640.) / 640., floor(_gl4es_TexCoord_0.y * 480.) / 480.);
ptitSeb commented 3 years ago

yeah, dots fixes it. Now probably (i hope) the last thing to deal with: why varying medium vec4 _gl4es_TexCoord_0 disappear from the top of generated shader once hacks in place.

Don't use _gl4es_TexCoord_0, only gl_TexCoord[0] because if there is no gl_TexCoord[0] then shaderconv will never define _gl4es_TexCoord_0 as it will not be needed.

kas1e commented 3 years ago

ah ok, will try now

kas1e commented 3 years ago

yes, it works! another error:

float vel = timer / 50.0000;
vec3 normalColor = texture2D(Texture1, vec2(gl_TexCoord[0].x + vel, gl_TexCoord[0].y + vel));

Shaderconv doing from it that:

float vel = timer / 50.0000;
vec3 normalColor = texture2D(Texture1, vec2(_gl4es_TexCoord_0.x + vel, _gl4es_TexCoord_0.y + vel)); 

Bring same errors about "cannot convert" etc. Tried to replace it on a float(vel) - no luck.

ptitSeb commented 3 years ago

I guess the issue is here: float vel = timer / 50.0000; probably need to be float vel = float(timer) / 50.0000;

kas1e commented 3 years ago

Sadly nope :( timer surely declared like uniform float timer, but making it as you say didn't fix error... Even if I just do: float vel = 50.00000;, and then the next big string, it still fails with that error.

kas1e commented 3 years ago

funny that just this one also fail: vec3 normalColor = texture2D(Texture1, vec2(0.0)); , but if i replace it on vec4 then it compiles. Maybe should be vec4 indeed ?

kas1e commented 3 years ago

Ok, in meantime to compile replaced vec3 normalColor on vec4 normalColor, not sure how right is it, but it compiles.

Now, all fragment shaders compiles (even on maximum possible settings), and the last one (i hope) comes from vertex shaders now.

The error we got now is:

ERROR: 78:1: 'gl_VertexID' : undeclared identifier 
ERROR: 108:0: '' : compilation terminated 
ERROR: 2 compilation errors.  No code generated. 

There is the original:

uniform sampler2D Texture0, Texture1, Texture2, Texture3;

varying vec3 Normal;
varying vec4 Position;
varying float fogFactor;

void main(void)
{
        Position = gl_ModelViewMatrix * gl_Vertex;
        gl_FrontColor = gl_Color;
        Normal = gl_NormalMatrix * gl_Normal;
        gl_TexCoord[0] = gl_MultiTexCoord0;
        gl_Position = ftransform();

        vec4 bloodColor = texture2D(Texture1, vec2(47.5 / 48.0, 47.5 / 48.0));
        bool breakLoop = false;

        int y = gl_VertexID / 48;
        for (int x = 0; x < 48; x++)
        {
                float xx = x + 0.5;
                float yy = y + 0.5;
                vec4 pixelcolor = texture2D(Texture1, vec2(xx / 48.0, yy / 48.0));
                if (pixelcolor != vec4(0.0, 0.0, 0.0, 1.0))
                {
                        bool ref = false;
                        if (x == 47 && y == 47) ref = true;
                        if (ref == false)
                        {
                                int id = y * 48 + x;
                                if (gl_VertexID == id)
                                {
                                        gl_FrontColor = bloodColor;
                                }
                        }
                }
        }

        const float LOG2 = 1.442695;
        gl_FogFragCoord = length(vec3(Position));
        fogFactor = exp2(-gl_Fog.density *
                                gl_Fog.density *
                                gl_FogFragCoord *
                                gl_FogFragCoord *
                                LOG2);
        fogFactor = clamp(fogFactor, 0.0, 1.0);
} 

There is one shaderconv build for us:

#version 100
precision highp float;
precision highp int;
attribute highp vec4 _gl4es_Vertex;
attribute lowp vec4 _gl4es_Color;
attribute highp vec4 _gl4es_MultiTexCoord0;
attribute highp vec3 _gl4es_Normal;
varying lowp vec4 _gl4es_FrontColor;
varying mediump float _gl4es_FogFragCoord;
varying mediump vec4 _gl4es_TexCoord[1];
uniform highp mat4 _gl4es_ModelViewMatrix;
uniform highp mat4 _gl4es_ModelViewProjectionMatrix;
uniform highp mat3 _gl4es_NormalMatrix;
struct _gl4es_FogParameters {
    lowp vec4 color;
    mediump float density;
    highp   float start;
    highp   float end;
    highp   float scale;
};
uniform _gl4es_FogParameters _gl4es_Fog;

highp vec4 ftransform() {
 return _gl4es_ModelViewProjectionMatrix * _gl4es_Vertex;
}
float clamp(float f, int a, int b) {
 return clamp(f, float(a), float(b));
}
float clamp(float f, float a, int b) {
 return clamp(f, a, float(b));
}
float clamp(float f, int a, float b) {
 return clamp(f, float(a), b);
}
vec2 clamp(vec2 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec2 clamp(vec2 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec2 clamp(vec2 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec3 clamp(vec3 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec3 clamp(vec3 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec3 clamp(vec3 f, int a, float b) {
 return clamp(f, float(a), b);
}
vec4 clamp(vec4 f, int a, int b) {
 return clamp(f, float(a), float(b));
}
vec4 clamp(vec4 f, float a, int b) {
 return clamp(f, a, float(b));
}
vec4 clamp(vec4 f, int a, float b) {
 return clamp(f, float(a), b);
}
uniform sampler2D Texture0, Texture1, Texture2, Texture3;

varying vec3 Normal;
varying vec4 Position;
varying float fogFactor;

void main(void)
{
        Position = _gl4es_ModelViewMatrix * _gl4es_Vertex;
        _gl4es_FrontColor = _gl4es_Color;
        Normal = _gl4es_NormalMatrix * _gl4es_Normal;
        _gl4es_TexCoord[0] = _gl4es_MultiTexCoord0;
        gl_Position = ftransform();

        vec4 bloodColor = texture2D(Texture1, vec2(47.5000 / 48.0000, 47.5000 / 48.0000));
        bool breakLoop = false;

        int y = gl_VertexID / 48;
        for (int x = 0; x < 48; x++)
        {
                float xx = x + 0.500000;
                float yy = y + 0.500000;
                vec4 pixelcolor = texture2D(Texture1, vec2(xx / 48.0000, yy / 48.0000));
                if (pixelcolor != vec4(0.00000, 0.00000, 0.00000, 1.00000))
                {
                        bool ref = false;
                        if (x == 47 && y == 47) ref = true;
                        if (ref == false)
                        {
                                int id = y * 48 + x;
                                if (gl_VertexID == id)
                                {
                                        _gl4es_FrontColor = bloodColor;
                                }
                        }
                }
        }

        const float LOG2 = 1.44269;
        _gl4es_FogFragCoord = length(vec3(Position));
        fogFactor = exp2(-_gl4es_Fog.density *
                                _gl4es_Fog.density *
                                _gl4es_FogFragCoord *
                                _gl4es_FogFragCoord *
                                LOG2);
        fogFactor = clamp(fogFactor, 0.00000, 1.00000);
}
ptitSeb commented 3 years ago

unny that just this one also fail: vec3 normalColor = texture2D(Texture1, vec2(0.0)); , but if i replace it on vec4 then it compiles. Maybe should be vec4 indeed ?

Maybe it just need vec3 normalColor = texture2D(Texture1, vec2(0.0)).rgb; ?

ptitSeb commented 3 years ago

gl_VertexID is not supported by shaderconv. This is OpenGL 3.x stuff, I need to check if I can support it.

kas1e commented 3 years ago

Maybe it just need vec3 normalColor = texture2D(Texture1, vec2(0.0)).rgb; ?

Yes! Did the trick too!

gl_VertexID is not supported by shaderconv. This is OpenGL 3.x stuff, I need to check if I can support it.

Will be very handy for sure. I read that for this one we need to create and pass additional data ourselves. But for me it all black wood :)

kas1e commented 3 years ago

Maybe we can also add it via hacks? Like scan for gl_VertexI, and if found, inject the appropriate shader attribute definition on top of the shader and prepare an additional VA. Injection on top probably is less of issues, and the issue is "prepare an additional VA"?