IOS Компиляция файла шейдера Metal Fragment - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть файл фрагмента шейдера "f sh", и я пытаюсь скомпилировать его, он изначально взят из Shadertoy, и он находится в GLSL, я пытаюсь перенести его в METAL, и я получаю следующее ошибка:

источник_программы: 129: 12: ошибка: переменная области действия программы должна находиться в постоянном адресном пространстве const vec3 ro, rd ;

Насколько я понимаю, я не могу определить ro и rd в глобальной области видимости, как это, как я могу это исправить?

Большое спасибо.

Код ниже:

const vec3 ro, rd;

....

void main(void)
{
    float t = u_time;
    vec3 col = vec3(0.);
    vec2 uv = gl_FragCoord.xy / iResolution.xy; // 0 <> 1

    uv -= .5;
    uv.x *= iResolution.x/iResolution.y;

    vec2 mouse = gl_FragCoord.xy/iResolution.xy;

    vec3 pos = vec3(.3, .15, 0.);

    float bt = t * 5.;
    float h1 = N(floor(bt));
    float h2 = N(floor(bt+1.));
    float bumps = mix(h1, h2, fract(bt))*.1;
    bumps = bumps*bumps*bumps*CAM_SHAKE;

    pos.y += bumps;
    float lookatY = pos.y+bumps;
    vec3 lookat = vec3(0.3, lookatY, 1.);
    vec3 lookat2 = vec3(0., lookatY, .7);
    lookat = mix(lookat, lookat2, sin(t*.1)*.5+.5);

    uv.y += bumps*4.;
    CameraSetup(uv, pos, lookat, 2., mouse.x);

    t *= .03;
    t += mouse.x;

    // fix for GLES devices by MacroMachines
    #ifdef GL_ES
    const float stp = 1./8.;
    #else
    float stp = 1./8.;
    #endif

    for(float i=0.; i<1.; i+=stp) {
       col += StreetLights(i, t);
    }

    for(float i=0.; i<1.; i+=stp) {
        float n = N(i+floor(t));
        col += HeadLights(i+n*stp*.7, t);
    }

    #ifndef GL_ES
    #ifdef HIGH_QUALITY
    stp = 1./32.;
    #else
    stp = 1./16.;
    #endif
    #endif

    for(float i=0.; i<1.; i+=stp) {
       col += EnvironmentLights(i, t);
    }

    col += TailLights(0., t);
    col += TailLights(.5, t);

    col += sat(rd.y)*vec3(.6, .5, .9);

    gl_FragColor = vec4(col, 0.);
}

1 Ответ

1 голос
/ 16 апреля 2020

Эквивалентное объявление в Metal Shading Language (MSL) будет

constant float3 ro, rd;

Однако вы должны также инициализировать эти переменные значениями, так как вашим функциям шейдера не разрешается их изменять. Что-то вроде

constant float3 ro(0, 0, 0), rd(1, 1, 1);

Еще несколько подсказок по переводу:

  • У металла нет синтаксиса для объявления униформы. Вместо этого вам нужно будет передать такие значения через буфер в адресном пространстве constant или device. Это включает в себя такие вещи, как разрешение экрана и переменные времени.
  • Имена векторных типов обычно начинаются с имени их типа элемента, за которым следует количество элементов (half2, float3). В MSL нет явных квалификаторов точности.
  • Вместо записи в специальные значения, такие как gl_FragColor, основные функции фрагмента c в Metal возвращают значение цвета (которое по соглашению записывается к первому цветному прикреплению кадрового буфера, если он проходит проверку глубины и трафарета).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...