opengl on ios & osx - nathanael beisiegelbeisiegel.me/files/scenekitshaders.pdf · opengl on...
TRANSCRIPT
OpenGL
• OpenGL and GLKit bundled with Xcode• GLView and GLViewController available
• Works like any other views
OpenGL
• OpenGL and GLKit bundled with Xcode• GLView and GLViewController available
• Works like any other views • Gestures easily added
OpenGL
• OpenGL and GLKit bundled with Xcode• GLView and GLViewController available
• Works like any other views • Gestures easily added• GLView manages frame rate, frame,
coordinates, rotation
OpenGL
GLView
GLViewController
UIButton
GLKView
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
OpenGL
GLView
GLViewController
UIButton
GLKViewOutlet / Action
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
OpenGL
GLView
GLViewController
UIButton
GLKViewOutlet / Action
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
- (IBAction)toggleAnimation
OpenGL
GLViewController
GLKViewOutlet / Action
self.preferredFramesPerSecond = 60; // Start context and initialize color EAGLContext *context = [[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES3]; [EAGLContext setCurrentContext:context]; GLKView *glkView = (GLKView *)self.view; glkView.context = context;
glClearColor(0.95f, 0.95f, 0.95f, 1.0f); glEnable(GL_CULL_FACE);
OpenGL
GLViewController
GLKViewOutlet / Action
self.preferredFramesPerSecond = 60; // Start context and initialize color EAGLContext *context = [[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES3]; [EAGLContext setCurrentContext:context]; GLKView *glkView = (GLKView *)self.view; glkView.context = context;
glClearColor(0.95f, 0.95f, 0.95f, 1.0f); glEnable(GL_CULL_FACE);
OpenGL
GLViewController
GLKViewOutlet / Action
self.preferredFramesPerSecond = 60; // Start context and initialize color EAGLContext *context = [[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES3]; [EAGLContext setCurrentContext:context]; GLKView *glkView = (GLKView *)self.view; glkView.context = context;
glClearColor(0.95f, 0.95f, 0.95f, 1.0f); glEnable(GL_CULL_FACE);
OpenGL
GLViewController
GLKViewOutlet / Action
self.preferredFramesPerSecond = 60; // Start context and initialize color EAGLContext *context = [[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES3]; [EAGLContext setCurrentContext:context]; GLKView *glkView = (GLKView *)self.view; glkView.context = context;
glClearColor(0.95f, 0.95f, 0.95f, 1.0f); glEnable(GL_CULL_FACE);
OpenGL
GLViewController
GLKViewOutlet / Action
self.preferredFramesPerSecond = 60; // Start context and initialize color EAGLContext *context = [[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES3]; [EAGLContext setCurrentContext:context]; GLKView *glkView = (GLKView *)self.view; glkView.context = context;
glClearColor(0.95f, 0.95f, 0.95f, 1.0f); glEnable(GL_CULL_FACE);
OpenGL
GLViewController
GLKViewOutlet / Action
self.preferredFramesPerSecond = 60; // Start context and initialize color EAGLContext *context = [[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES3]; [EAGLContext setCurrentContext:context]; GLKView *glkView = (GLKView *)self.view; glkView.context = context;
Still Low Level
• GLKit like glu.h—adds utility but little else• GLKBaseEffect to emulate GL v1
• self.effect = [[GLKBaseEffect alloc] init]; [self.effect prepareToDraw];
Still Low Level
• GLKit like glu.h—adds utility but little else• GLKBaseEffect to emulate GL v1
• self.effect = [[[self
• Lighting similar to “Beads” in Final Exam
Still Low Level
• GLKit like glu.h—adds utility but little else• GLKBaseEffect to emulate GL v1
• self.effect = [[[self
• Lighting similar to “Beads” in Final Exam• self.effect.light0.enabled = GL_TRUE;
self.effect.light0.position = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f); self.effect.lightingType = GLKLightingTypePerPixel;// Boost light intensity self.effect.light0.constantAttenuation = 0.7;
Still Low Level
• GLKit like glu.h—adds utility but little else• GLKBaseEffect to emulate GL v1
• self.effect = [[[self
• Lighting similar to “Beads” in Final Exam• self.
self. GLKVector4Makeself.// Boost light intensityself.
• This is still way simpler than GL v2+
You are responsible for• Binding all Buffers with vertex data (also normals, textures)
glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
You are responsible for• Binding all Buffers with vertex data (also normals, textures)• Set up shader variables including…
glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
You are responsible for• Binding all Buffers with vertex data (also normals, textures)• Set up shader variables including…
• Projection Matrix
glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height); GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f),
aspect, 0.1f, 100.0f); self.effect.transform.projectionMatrix = projectionMatrix;
You are responsible for• Binding all Buffers with vertex data (also normals, textures)• Set up shader variables including…
• Projection Matrix• ModelView Matrix
glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height); GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f),
aspect, 0.1f, 100.0f); self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); // Compute the model view matrix for the object rendered with GLKit GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
You are responsible for• Binding all Buffers with vertex data (also normals, textures)• Set up shader variables including…
• Projection Matrix• ModelView Matrix• Whatever else you want to use in the shader
glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height); GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f),
aspect, 0.1f, 100.0f); self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); // Compute the model view matrix for the object rendered with GLKit GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// Compute the model view matrix for the object rendered with ES2 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); _rotation += self.timeSinceLastUpdate * 0.5f;
You are responsible for• Binding all Buffers with vertex data (also normals, textures)• Set up shader variables including…
• Projection Matrix• ModelView Matrix• Whatever else you want to use in the shader
• Compiling Shader Programs
glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height); GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f),
aspect, 0.1f, 100.0f); self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); // Compute the model view matrix for the object rendered with GLKit GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// Compute the model view matrix for the object rendered with ES2 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); _rotation += self.timeSinceLastUpdate * 0.5f;
source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
*shader = glCreateShader(type); glShaderSource(*shader, 1, &source, NULL); glCompileShader(*shader);
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); if (status == 0) { glDeleteShader(*shader); }
You are responsible for• Binding all Buffers with vertex data (also normals, textures)• Set up shader variables including…
• Projection Matrix• ModelView Matrix• Whatever else you want to use in the shader
• Compiling Shader Programs• Validating and Linking Shader Programs
glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height); GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f),
aspect, 0.1f, 100.0f); self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); // Compute the model view matrix for the object rendered with GLKit GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// Compute the model view matrix for the object rendered with ES2 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); _rotation += self.timeSinceLastUpdate * 0.5f;
source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
*shader = glCreateShader(type); glShaderSource(*shader, 1, &source, NULL); glCompileShader(*shader);
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); if (status == 0) { glDeleteShader(*shader); }
glValidateProgram(prog); // Check Status After
glLinkProgram(prog); // Check Status After
// Attach vertex shader to program. glAttachShader(_program, vertShader); // Attach fragment shader to program. glAttachShader(_program, fragShader); // Bind attribute locations. // This needs to be done prior to linking. glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); glBindAttribLocation(_program, GLKVertexAttribNormal, “normal”); ...
You are responsible for• Binding all Buffers with vertex data (also normals, textures)• Set up shader variables including…
• Projection Matrix• ModelView Matrix• Whatever else you want to use in the shader
• Compiling Shader Programs• Validating and Linking Shader Programs• Cleaning up after yourself
glGenBuffers(1, &_vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height); GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f),
aspect, 0.1f, 100.0f); self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f); // Compute the model view matrix for the object rendered with GLKit GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// Compute the model view matrix for the object rendered with ES2 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f); modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); _normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); _modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); _rotation += self.timeSinceLastUpdate * 0.5f;
source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
*shader = glCreateShader(type); glShaderSource(*shader, 1, &source, NULL); glCompileShader(*shader);
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); if (status == 0) { glDeleteShader(*shader); }
glValidateProgram(prog); // Check Status After
glLinkProgram(prog); // Check Status After
// Attach vertex shader to program. glAttachShader(_program, vertShader); // Attach fragment shader to program. glAttachShader(_program, fragShader); // Bind attribute locations. // This needs to be done prior to linking. glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); glBindAttribLocation(_program, GLKVertexAttribNormal, “normal”); ...
glDeleteBuffers(1, &_vertexBuffer); glDeleteVertexArraysOES(1, &_vertexArray); self.effect = nil; if (_program) { glDeleteProgram(_program); _program = 0; }
Shaders (Vertex)attribute vec4 position; attribute vec3 normal;
varying lowp vec4 colorVarying;
uniform mat4 modelViewProjectionMatrix; uniform mat3 normalMatrix;
void main() { vec3 eyeNormal = normalize(normalMatrix * normal); vec3 lightPosition = vec3(0.0, 0.0, 1.0); vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0); float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); colorVarying = diffuseColor * nDotVP; gl_Position = modelViewProjectionMatrix * position; }
Shaders (Vertex)attribute vec4 position; attribute vec3 normal;
varying lowp vec4 colorVarying;
uniform mat4 modelViewProjectionMatrix; uniform mat3 normalMatrix;
void main() { vec3 eyeNormal = normalize(normalMatrix * normal); vec3 lightPosition = vec3(0.0, 0.0, 1.0); vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0); float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); colorVarying = diffuseColor * nDotVP; gl_Position = modelViewProjectionMatrix * position; }
Shaders (Vertex)attribute vec4 position; attribute vec3 normal;
varying lowp vec4 colorVarying;
uniform mat4 modelViewProjectionMatrix; uniform mat3 normalMatrix;
void main() { vec3 eyeNormal = normalize(normalMatrix * normal); vec3 lightPosition = vec3(0.0, 0.0, 1.0); vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0); float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); colorVarying = diffuseColor * nDotVP; gl_Position = modelViewProjectionMatrix * position; }
Shaders (Vertex)attribute vec4 position; attribute vec3 normal;
varying lowp vec4 colorVarying;
uniform mat4 modelViewProjectionMatrix; uniform mat3 normalMatrix;
void main() { vec3 eyeNormal = normalize(normalMatrix * normal); vec3 lightPosition = vec3(0.0, 0.0, 1.0); vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0); float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition))); colorVarying = diffuseColor * nDotVP; gl_Position = modelViewProjectionMatrix * position; }
Still Low Level
• Still using GL v1 style lights• These snippets didn’t even factor in
materials, textures, and lighting
Still Low Level
• Still using GL v1 style lights• These snippets didn’t even factor in
materials, textures, and lighting• Also no model import
Still Low Level
• Still using GL v1 style lights• These snippets didn’t even factor in
materials, textures, and lighting• Also no model import
• Plugins to convert .obj format to source arrays (.h & .c files)
#include "cube.h"
const int cubeVertices = 36;
const float cubePositions[108] = { 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -0.999999, -1, 1, -1, -1, 1, 1,
...
Still Low Level
• Still using GL v1 style lights• These snippets didn’t even factor in
materials, textures, and lighting• Also no model import
• Plugins to convert .obj format to source arrays (.h & .c files)
• Arrays for vertices, positions, texture coordinates, normals
#include "cube.h"
const int cubeVertices = 36;
const float cubePositions[108] = { 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -0.999999, -1, 1, -1, -1, 1, 1,
...
SceneKit
• Apple’s 3D Framework• Easy animations, physics• Tree-based node system for
geometry, cameras, and lights
SceneKit
• Apple’s 3D Framework• Easy animations, physics• Tree-based node system for
geometry, cameras, and lights• Import of COLLADA (.cae) files
SceneKit
• Apple’s 3D Framework• Easy animations, physics• Tree-based node system for
geometry, cameras, and lights• Import of COLLADA (.cae) files
• Much higher level, like Unity3D
SceneKit
• Apple’s 3D Framework• Easy animations, physics• Tree-based node system for
geometry, cameras, and lights• Import of COLLADA (.cae) files
• Much higher level, like Unity3D• But, OpenGL underneath with
built in shader programs
SCNScenerootNode
http://www.raywenderlich.com/83748/beginning-scene-kit-tutorial
SCNScenerootNode
SCNNodeparent Camera Light Geometry
childNodes[]
http://www.raywenderlich.com/83748/beginning-scene-kit-tutorial
SCNScenerootNode
SCNNodeparent Camera Light Geometry
childNodes[]
SCNCameraxFov / yFov zNear, zFar orthographic ...
http://www.raywenderlich.com/83748/beginning-scene-kit-tutorial
SCNScenerootNode
SCNNodeparent Camera Light Geometry
childNodes[]SCNLightType Color Shadow
SCNCameraxFov / yFov zNear, zFar orthographic ...
http://www.raywenderlich.com/83748/beginning-scene-kit-tutorial
SCNScenerootNode
SCNNodeparent Camera Light Geometry
childNodes[]SCNLightType Color Shadow
SCNCameraxFov / yFov zNear, zFar orthographic ...
SCNGeometry
Materials[] Mesh
http://www.raywenderlich.com/83748/beginning-scene-kit-tutorial
SCNScenerootNode
SCNNodeparent Camera Light Geometry
childNodes[]SCNLightType Color Shadow
SCNCameraxFov / yFov zNear, zFar orthographic ...
SCNMaterial
Diffuse Ambient Specular Emission Transparent Reflective
SCNGeometry
Materials[] Mesh
http://www.raywenderlich.com/83748/beginning-scene-kit-tutorial
SCNScenerootNode
SCNNodeparent Camera Light Geometry
childNodes[]
SCNNode
SCNNode
SCNNode
SCNLightType Color Shadow
SCNCameraxFov / yFov zNear, zFar orthographic ...
SCNMaterial
Diffuse Ambient Specular Emission Transparent Reflective
SCNGeometry
Materials[] Mesh
http://www.raywenderlich.com/83748/beginning-scene-kit-tutorial
SCNScenerootNode
SCNNodeparent Camera Light Geometry
childNodes[]
SCNNode
SCNNode
SCNNode
Animations on parent apply to all children
SCNScenerootNode
SCNNodeparent Camera Light Geometry
childNodes[]
SCNNode
SCNNode
SCNNode
Animations on parent apply to all children
sunNode.runAction(SCNAction.repeatActionForever(SCNAction.rotateByX(0, y: 2, z: 0, duration: 1))) moonNode.runAction(SCNAction.repeatActionForever(SCNAction.rotateByX(0, y: 4, z: 0, duration: 1)))
SceneKit Exposes Shaders
• Two methods1. Completely substitute node render with SCNProgram
Shader.fsh
Shader.vshSCNGeometry
Materials[] Mesh Program
SCNProgramvertexShader fragmentShader
SceneKit Exposes Shaders
• Two methods1. Completely substitute node render with
• Both vertex and fragment shaders
Shader.fsh
Shader.vshSCNGeometry
Materials[] Mesh Program
SCNProgramvertexShader fragmentShader
SceneKit Exposes Shaders
• Two methods1. Completely substitute node render with
• Both vertex and fragment shaders2. Attach shader modifiers into node’s default program
SCNGeometryMaterials[] Mesh ShaderModifiers{
SCNShaderModifierEntryPointGeometry
SCNShaderModifierEntryPointSurface
SCNShaderModifierEntryPointLightingModel
SCNShaderModifierEntryPointFragment
SceneKit Exposes Shaders
• Two methods1. Completely substitute node render with
• Both vertex and fragment shaders2. Attach shader modifiers into node’s default program
• 4 injection points exposed with structs and variables
SCNGeometryMaterials[] Mesh ShaderModifiers{
SCNShaderModifierEntryPointGeometry
SCNShaderModifierEntryPointSurface
SCNShaderModifierEntryPointLightingModel
SCNShaderModifierEntryPointFragment
Sample Geometry Shader Fragment
const float normalScaling = 1.5; const float timeScale = 3.0;
_geometry.position += vec4(_geometry.normal, 0.0) * sin(u_time * timeScale) * normalScaling;
Sample Geometry Shader Fragment
const float normalScaling = 1.5; const float timeScale = 3.0;
_geometry.position += vec4(_geometry.normal, 0.0) * sin(u_time * timeScale) * normalScaling;