我创建了一个基于游戏模板的新项目,其中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是隐含的)。