IOS Metal Fragment着色器文件编译
IOS Metal Fragment shader file compilation
我有片段着色器 "fsh" 文件,我正在尝试编译它,它最初取自 Shadertoy,它在 GLSL 中,我正在尝试将它移植到 METAL,我得到了以下错误:
program_source:129:12: error: program scope variable must reside in constant address space
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.);
}
金属着色语言 (MSL) 中的等效声明为
constant float3 ro, rd;
但是,您还应该使用值来初始化这些变量,因为不允许您的着色器函数改变它们。像
constant float3 ro(0, 0, 0), rd(1, 1, 1);
更多翻译提示:
- Metal 没有声明制服的语法。相反,您需要通过
constant
或 device
地址 space 中的缓冲区传递此类值。这包括屏幕分辨率和时间变量等内容。
- 向量类型名称通常以其元素类型的名称开头,后跟元素的数量(
half2
、float3
)。 MSL 中没有明确的精度限定符。
- Metal 中的基本片段函数 return 不是写入像
gl_FragColor
这样的特殊值,而是一个颜色值(按照惯例写入第一个帧缓冲区的颜色附件,前提是它通过了深度和模板测试)。
我有片段着色器 "fsh" 文件,我正在尝试编译它,它最初取自 Shadertoy,它在 GLSL 中,我正在尝试将它移植到 METAL,我得到了以下错误:
program_source:129:12: error: program scope variable must reside in constant address space 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.);
}
金属着色语言 (MSL) 中的等效声明为
constant float3 ro, rd;
但是,您还应该使用值来初始化这些变量,因为不允许您的着色器函数改变它们。像
constant float3 ro(0, 0, 0), rd(1, 1, 1);
更多翻译提示:
- Metal 没有声明制服的语法。相反,您需要通过
constant
或device
地址 space 中的缓冲区传递此类值。这包括屏幕分辨率和时间变量等内容。 - 向量类型名称通常以其元素类型的名称开头,后跟元素的数量(
half2
、float3
)。 MSL 中没有明确的精度限定符。 - Metal 中的基本片段函数 return 不是写入像
gl_FragColor
这样的特殊值,而是一个颜色值(按照惯例写入第一个帧缓冲区的颜色附件,前提是它通过了深度和模板测试)。