简体   繁体   English

IOS Metal Fragment shader文件编译

[英]IOS Metal Fragment shader file compilation

I have fragment shader "fsh" file and I am trying to compile it, it is originally taken from Shadertoy, and it is in GLSL, I am trying to port it to METAL, and I am getting the following error:我有片段着色器“fsh”文件,我正在尝试编译它,它最初取自 Shadertoy,它在 GLSL 中,我试图将它移植到 METAL,我收到以下错误:

program_source:129:12: error: program scope variable must reside in constant address space const vec3 ro, rd ;程序源:129:12:错误:程序 scope 变量必须驻留在常量地址空间const vec3 ro, rd

As far as I can understand, I can not define ro and rd in global scope like this, how can I fix this?据我所知,我无法像这样在全局 scope 中定义 ro 和 rd ,我该如何解决?

Thank you very much.非常感谢。

The code is below:代码如下:

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.);
}

The equivalent declaration in Metal Shading Language (MSL) would be金属着色语言 (MSL) 中的等效声明是

constant float3 ro, rd;

However, you should also initialize these variables with values, since your shader functions will not be allowed to mutate them.但是,您还应该使用值初始化这些变量,因为不允许您的着色器函数改变它们。 Something like就像是

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

A few more translation hints:还有一些翻译提示:

  • Metal doesn't have syntax for declaring uniforms. Metal 没有声明制服的语法。 Instead, you'll need to pass such values in via a buffer in the constant or device address space.相反,您需要通过constantdevice地址空间中的缓冲区传递这些值。 This includes things like your screen resolution and time variables.这包括您的屏幕分辨率和时间变量等内容。
  • Vector type names generally start with the name of their element type, followed by the number of elements ( half2 , float3 ).矢量类型名称通常以其元素类型的名称开头,后跟元素的数量( half2float3 )。 There are no explicit precision qualifiers in MSL. MSL 中没有明确的精度限定符。
  • Rather than writing to special values like gl_FragColor , basic fragment functions in Metal return a color value (which by convention is written to the first color attachment of the framebuffer, provided it passes the depth and stencil test). Metal 中的基本片段函数不是写入gl_FragColor类的特殊值,而是返回一个颜色值(按照惯例,它会写入帧缓冲区的第一个颜色附件,前提是它通过了深度和模板测试)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM