Skip to content

Something wrong with this shader (unexpected result) #3

@danilw

Description

@danilw

(not just this shader, my large shaders (200+Kb of SPV) result some very broken in SPIRV-VM)
this shader as an example
(spv file used in SPIRV-VM in attachment)

expected result and shader source (copy to shadertoy.com)

uvec4 decodeval32(uint varz) {
    return uvec4(varz>>24,(varz>>16)&0xffu,(varz>>8)&0xffu,(varz>>0)&0xffu);
}

uint encodeval32(uvec4 colz) {
    return uint((colz[0]<<24)&0xff000000u|(colz[1]<< 16)&0x00ff0000u|(colz[2]<< 8)&0x0000ff00u|(colz[3]<< 0)&0x000000ffu);
}


uint packSnorm3x10(vec3 x) {
    x = clamp(x,-1., 1.) * 511.;
    uvec3 sig = uvec3(mix(vec3(0), vec3(1), greaterThanEqual(sign(x),vec3(0))));
    uvec3 mag = uvec3(abs(x));
    uvec3 r = sig.xyz << 9 | mag.xyz;
    return r.x << 22 | r.y << 12 | r.z << 2;
}

vec3 unpackSnorm3x10(uint x) {
    uvec3 r = (uvec3(x) >> uvec3(22, 12, 2)) & uvec3(0x3FF);
    uvec3 sig = r >> 9;
    uvec3 mag = r & uvec3(0x1FF);
    vec3 fsig = mix(vec3(-1), vec3(1), greaterThanEqual(sig, uvec3(1)));
    vec3 fmag = vec3(mag) / 511.;
    return fsig * fmag;
}

uint my_packSnorm4x8(vec4 x) {
    x = clamp(x,-1.0, 1.0) * 127.0;
    uvec4 sig = uvec4(mix(vec4(0), vec4(1), greaterThanEqual(sign(x),vec4(0))));
    uvec4 mag = uvec4(abs(x));
    uvec4 r = sig << 7 | mag;
    return r.x << 24 | r.y << 16 | r.z << 8 | r.w;
}

vec4 my_unpackSnorm4x8(uint x) {
    uvec4 r = (uvec4(x) >> uvec4(24, 16, 8, 0)) & uvec4(0xFF);
    uvec4 sig = r >> 7;
    uvec4 mag = r & uvec4(0x7F);
    vec4 fsig = mix(vec4(-1), vec4(1), greaterThanEqual(sig,uvec4(1)));
    vec4 fmag = vec4(mag) / 127.0;
    return fsig * fmag;
}

int bits2int8(int map[8]){
    int ret = 0;
    int nBits=8;
    int ncv = 1;
    for(int i=nBits-1; i>=0; i--){
        int eval=map[nBits-i-1];
        if(eval == 1)
            ret+=ncv;
        ncv *= 2;
    }
    return ret;
}

void int2bits8(int n, out int map[8]){
    int nBits=8;
    for(int i = 0; i < nBits; i++) {
      if (n % 2==0)map[i]=0;
      else map[i]=1;
      n/=2;
   }
}

#define load_data32(val) decodeval32(floatBitsToUint(val))
#define pack_udata32(data) uintBitsToFloat(encodeval32(data))
#define pack_udata32x4(data1,data2,data3,data4) uintBitsToFloat(uvec4(encodeval32(data1),encodeval32(data2),encodeval32(data3),encodeval32(data4)))

#define pack_float3x10(x) uintBitsToFloat(packSnorm3x10(x))
#define unpack_float3x10(x) unpackSnorm3x10(floatBitsToUint(x))
#define pack_float4x8(x) uintBitsToFloat(my_packSnorm4x8(x))
#define unpack_float4x8(x) my_unpackSnorm4x8(floatBitsToUint(x))

float print_num(vec2, float, int);
float printBits(vec2, int[8]);

#define r vec3(0.9,0.4,0.4)
#define g vec3(0.4,0.9,0.4)
#define b vec3(0.4,0.4,0.9)
#define a vec3(0.9,0.9,0.4)

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 res = iResolution.xy/iResolution.y;
    vec2 uv = fragCoord/iResolution.y-0.5*res;

    vec4 data = vec4(uintBitsToFloat(0xaabbccddu),uintBitsToFloat(0xf1f2f3f4u),
    uintBitsToFloat(0x010f0a0du),uintBitsToFloat(0x010f0a0du));
    
    uvec4 udata32 = load_data32(data.x);
    vec4 fdata4x8 = unpack_float4x8(data.y);
    vec3 fdata3x10 = unpack_float3x10(data.z);
    
    int bits[8];
    int2bits8(int(udata32.x),bits);
    int int_value=bits2int8(bits);
    
    float t=iTime;
    t=0.;

    float timer1=fract((t+0.)/20.)*2.-1.;
    float timer2=fract((t+1.)/20.)*2.-1.;
    float timer3=fract((t+2.)/20.)*2.-1.;
    float timer4=fract((t+3.)/20.)*2.-1.;
    
    vec3 col = vec3(0.);
    float d = 0.;
    uv+= vec2(0.7,-0.4);
    d = step(abs(uv.y*20.),1.);
    if(d>0.){col=r*print_num(uv*20.,float(udata32.x),0);
             col+=r*print_num((uv+vec2(-0.2,0.))*20.,fdata4x8.x,6);
             col+=r*print_num((uv+vec2(-0.7,0.))*20.,fdata3x10.x,6);
             col+=r*print_num((uv+vec2(-1.18,0.))*20.,timer1,6);}
    uv+= vec2(0.0,0.1);
    d = step(abs(uv.y*20.),1.);
    if(d>0.){col=g*print_num(uv*20.,float(udata32.y),0);
             col+=g*print_num((uv+vec2(-0.2,0.))*20.,fdata4x8.y,6);
             col+=g*print_num((uv+vec2(-0.7,0.))*20.,fdata3x10.y,6);
             col+=g*print_num((uv+vec2(-1.18,0.))*20.,timer2,6);}
    uv+= vec2(0.0,0.1);
    d = step(abs(uv.y*20.),1.);
    if(d>0.){col=b*print_num(uv*20.,float(udata32.z),0);
             col+=b*print_num((uv+vec2(-0.2,0.))*20.,fdata4x8.z,6);
             col+=b*print_num((uv+vec2(-0.7,0.))*20.,fdata3x10.z,6);
             col+=b*print_num((uv+vec2(-1.18,0.))*20.,timer3,6);}
    uv+= vec2(0.0,0.1);
    d = step(abs(uv.y*20.),1.);
    if(d>0.){col=a*print_num(uv*20.,float(udata32.w),0);
             col+=a*print_num((uv+vec2(-0.2,0.))*20.,fdata4x8.w,6);
             col+=a*print_num((uv+vec2(-1.18,0.))*20.,timer4,6);}
    
    uv+= vec2(-0.7,0.1);
    d = step(abs(uv.y*20.),.5);
    if(d>0.)col=r*step(2.*uv.x/res.x,fdata4x8.x);
    uv+= vec2(0.0,0.05);
    d = step(abs(uv.y*20.),.5);
    if(d>0.)col=g*step(2.*uv.x/res.x,fdata4x8.y);
    uv+= vec2(0.0,0.05);
    d = step(abs(uv.y*20.),.5);
    if(d>0.)col=b*step(2.*uv.x/res.x,fdata4x8.z);
    uv+= vec2(0.0,0.05);
    d = step(abs(uv.y*20.),.5);
    if(d>0.)col=a*step(2.*uv.x/res.x,fdata4x8.w);
    
    uv+= vec2(0.0,0.15);
    d = step(abs(uv.y*20.),.5);
    if(d>0.)col=r*step(2.*uv.x/res.x,fdata3x10.x);
    uv+= vec2(0.0,0.05);
    d = step(abs(uv.y*20.),.5);
    if(d>0.)col=g*step(2.*uv.x/res.x,fdata3x10.y);
    uv+= vec2(0.0,0.05);
    d = step(abs(uv.y*20.),.5);
    if(d>0.)col=b*step(2.*uv.x/res.x,fdata3x10.z);
    
    uv+= vec2(0.0,0.06);
    d = step(abs(uv.y*20.),.5);
    if(d>0.){col=vec3(1.)*printBits(uv*20.+0.5,bits);
             col+=print_num((uv+vec2(-0.3,0.))*20.+0.5,float(int_value),0);}
    
    
    
    fragColor = vec4(col,1.0);
}



float printBits(vec2 p, int map[8]){
    float di=0.;
    int nBits=8;
    for(int i = 0; i < nBits; i++) {
      di=max(di,print_num(p,float(map[i]),0));
      p.x+=1.;
   }
   return di;
}

const mat3 fontb=mat3(vec3(480599.0,139810.0,476951.0),vec3(476999.0,350020.0,464711.0),vec3(464727.0,476228.0,481111.0));

int get_fvalue(float val, int idx){
    for(int i=0;i<idx+1;i++){
        val=(val-floor(val/10.)*10.)*10.;
    }
    return int(val/10.);
}

float print_num(vec2 uv, float value, int num) {
  if(uv.y < 0.0 || uv.y >= 1.0) return 0.0;
    if(uv.x < -4.0 || uv.x >= 10.0) return 0.0;
  float bits = 0.0;
  int di = - int(floor(uv.x))+ 1;
  if(-di <= num) {
    float pw = pow(10.0, float(di));
    float val = abs(value);
    float pivot = max(val, 1.5) * 10.0;
    if(pivot < pw) {
      if(value < 0.0 && pivot >= pw * 0.1) bits = 1792.0;
    } else {
            if(di == 0) {
                if(num > 0) bits = 2.0;
            } else {
                int idx=0;
                if(di < 0)idx=get_fvalue(val,int(-di));else idx=int(mod((val*10.) / pw, 10.0));
                if(idx<=9 && idx>=0)bits = idx<9?fontb[idx/3][idx%3]:481095.0;
            }
        }
  } else return 0.;
  return floor(mod(bits / pow(2.0, floor(fract(uv.x) * 4.0) + floor(uv.y * 5.0) * 4.0), 2.0));
}

Correct/expected result image:
1

Result from SPIRV-VM:
2

C code to launch same as in #2

I do not want to continue any testing, maybe I'm doing something wrong in C code because I see way too many incorrect results.

shader2.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions