为什么iOS 8上的SceneKit无法编译我的自定义着色器?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么iOS 8上的SceneKit无法编译我的自定义着色器?相关的知识,希望对你有一定的参考价值。

我创建了一个基于游戏模板的新项目,其中SceneKit作为游戏技术,Swift作为语言。我尝试使用自定义着色器。这是设置代码:

var material = SCNMaterial()
var program = SCNProgram()

// Read the vertex shader file and set its content as our vertex shader
if let vertexShaderPath = NSBundle.mainBundle().pathForResource("VertexShader", ofType:"vsh") {
    let vertexShaderAsAString = NSString(contentsOfFile: vertexShaderPath, encoding: NSUTF8StringEncoding, error: nil)
    program.vertexShader = vertexShaderAsAString
}

// Read the fragment shader file and set its content as our fragment shader
if let fragmentShaderPath = NSBundle.mainBundle().pathForResource("FragmentShader", ofType:"fsh") {
    let fragmentShaderAsAString = NSString(contentsOfFile: fragmentShaderPath, encoding: NSUTF8StringEncoding, error: nil)
    program.fragmentShader = fragmentShaderAsAString
}

// Give a meaning to variables used in the shaders
program.setSemantic(SCNGeometrySourceSemanticVertex, forSymbol: "a_position", options: nil)
program.setSemantic(SCNModelViewProjectionTransform, forSymbol: "u_viewProjectionTransformMatrix", options: nil)

material.program = program

// retrieve the ship node
let ship = scene.rootNode.childNodeWithName("shipMesh", recursively: true)
ship.geometry.firstMaterial = material

我的顶点着色器的代码:

#version 300 es

uniform mat4 u_viewProjectionTransformMatrix;
in vec4 a_position;
out vec4 outPosition;

void main() {
   outPosition = u_viewProjectionTransformMatrix * a_position;
}

我的片段着色器的代码:

#version 300 es

out vec4 outColor;

void main() {
    outColor = vec4(1.0, 0.0, 0.0, 1.0)
}

很简单吧?但是当我执行此代码时,我收到以下错误:

SceneKit: error, failed to link program: ERROR: 0:1: '' :  version '300' is not supported
ERROR: 0:1: '' : syntax error: #version

我做错了什么?为了您的信息,#version 200 es产生相同的结果,因此它似乎与OpenGL本身的版本无关。

答案

SceneKit默认使用OpenGL ES 2.0上下文。

如果要使用ES3功能(如#version 300 es着色器),可以创建一个EAGLContext对象,指定OpenGL ES 3.0作为API版本,然后将其分配给视图的eaglContext属性。

但是,并非所有SceneKit的渲染器功能都支持ES3,因此您必须尝试查看要渲染的内容是否有效。另外请记住,ES3需要A7 GPU - 支持iPhone 4s / 5 / 5c,iPad 4及更早版本,iPad mini(非视网膜)和iPod touch,您需要一个ES2渲染路径。

如果您坚持使用ES2着色器,则会看到错误,因为没有#version 200 es。 ES2着色器使用#version 100,或者根本没有使用#version指令(在这种情况下100是隐含的)。

以上是关于为什么iOS 8上的SceneKit无法编译我的自定义着色器?的主要内容,如果未能解决你的问题,请参考以下文章

SceneKit 中的自定义动画属性

iOS 14 解决方法中的 SceneKit Metal 着色器编译性能错误

(C++) 我的自定义数组无法初始化(编译错误)

SceneKit - 在3D对象上绘图

iOS SceneKit:XCode“中断”导入的 DAE 材质颜色

iOS SceneKit 霓虹灯