Reputation: 110
I created a new project based on the Game template with SceneKit as game technology and Swift for the language. And I tried to use a custom shader. Here is the setup code:
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
The code of my vertex shader:
#version 300 es
uniform mat4 u_viewProjectionTransformMatrix;
in vec4 a_position;
out vec4 outPosition;
void main() {
outPosition = u_viewProjectionTransformMatrix * a_position;
}
And the code of my fragment shader:
#version 300 es
out vec4 outColor;
void main() {
outColor = vec4(1.0, 0.0, 0.0, 1.0)
}
Pretty simple, right? But when I execute this code, I get the following error:
SceneKit: error, failed to link program: ERROR: 0:1: '' : version '300' is not supported
ERROR: 0:1: '' : syntax error: #version
What did I do wrong? For your information, #version 200 es
yields the same result so it does not seem to be related to the version of OpenGL per se.
Upvotes: 2
Views: 2324
Reputation: 126117
SceneKit uses an OpenGL ES 2.0 context by default.
If you want to use ES3 features (like #version 300 es
shaders) you can create an EAGLContext
object specifying OpenGL ES 3.0 as the API version, then assign it to your view's eaglContext property.
However, not all of SceneKit's renderer features support ES3, so you'll have to experiment to see if what you want to render works. Also keep in mind that ES3 requires an A7 GPU -- to support iPhone 4s/5/5c, iPad 4 and earlier, iPad mini (non-retina) and iPod touch, you'll need an ES2 rendering path.
If you're sticking to ES2 shaders, you're seeing an error because there's no #version 200 es
. ES2 shaders use #version 100
, or no #version
directive at all (in which case 100 is implicit).
Upvotes: 5