iOS+SceneKit: How to apply toon shader on texture?


I want to use a toon-shader with SceneKit on iOS8+ to render a sphere with an Earth texture on it. I also want to add a toon shader for rendering the Earth. So far the shader works on the lighting, but the texture isn't shaded by the toon-shader (cp. to the image below, the texture should also be "tooned").

Someone any ideas?

enter image description here

Here's my view controller code (self.sceneKitView is an instance of SCNView):

@implementation ToonViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    SCNScene *scene = [SCNScene scene];

    // create and add a camera to the scene
    SCNNode *cameraNode = [SCNNode node]; = [SCNCamera camera];
    [scene.rootNode addChildNode:cameraNode];
    // place the camera
    cameraNode.position = SCNVector3Make(0, 0, 15);

    // create and add a light to the scene
    SCNNode *lightNode = [SCNNode node];
    lightNode.light = [SCNLight light];
    lightNode.light.type = SCNLightTypeOmni;
    lightNode.position = SCNVector3Make(0, 10, 10);
    [scene.rootNode addChildNode:lightNode];

    // create and add an ambient light to the scene
    SCNNode *ambientLightNode = [SCNNode node];
    ambientLightNode.light = [SCNLight light];
    ambientLightNode.light.type = SCNLightTypeAmbient;
    ambientLightNode.light.color = [UIColor darkGrayColor];
    [scene.rootNode addChildNode:ambientLightNode];

    // set up the scene
    self.sceneKitView.scene = scene;
    self.sceneKitView.allowsCameraControl = YES;
    self.sceneKitView.showsStatistics = NO;
    self.sceneKitView.backgroundColor = [UIColor clearColor];

    NSMutableDictionary* shaders = [[NSMutableDictionary alloc] init];
    shaders[SCNShaderModifierEntryPointLightingModel] = [[NSString alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"fixed_toon" withExtension:@"shader"]

    SCNNode* earth = [SCNNode nodeWithGeometry:[SCNSphere sphereWithRadius:5.0]];
    earth.position = SCNVector3Make(0.0, 0.0, 0.0);
    [scene.rootNode addChildNode:earth];

    [earth runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0.0 y:0.25 z:0.0 duration:1.0]]];

    SCNMaterial* earthMaterial = [SCNMaterial material];
    earthMaterial.diffuse.contents = [UIImage imageNamed:@"Earth.png"];
    earthMaterial.specular.contents = [UIColor whiteColor];
    earthMaterial.specular.intensity = 0.2;
    earthMaterial.locksAmbientWithDiffuse = NO;
    earthMaterial.shaderModifiers = shaders;

    earth.geometry.firstMaterial = earthMaterial;



And this is the fixed_toon.shader file:

vec3 lDir = normalize(vec3(0.1, 1.0, 1.0));
float dotProduct = dot(_surface.normal, lDir);

_lightingContribution.diffuse += (dotProduct*dotProduct*_light.intensity.rgb);
_lightingContribution.diffuse = floor(_lightingContribution.diffuse*4.0)/3.0;

vec3 halfVector = normalize(lDir + _surface.view);

dotProduct = max(0.0, pow(max(0.0, dot(_surface.normal, halfVector)), _surface.shininess));
dotProduct = floor(dotProduct*3.0)/3.0;

//_lightingContribution.specular += (dotProduct*_light.intensity.rgb);
_lightingContribution.specular = vec3(0,0,0);

The shader you have is only a lighting shader. If you want the earth to be tooned, you need a fragment shader.

Look at the shader file all of the math is related to light. You need something that will adjust the pixel color of the texture. Then connect it using the SCNShaderModifierEntryPointFragment entry point.

Collected from the Internet

Please contact javaer1[email protected] to delete if infringement.

edited at


Login to comment


How to render a SceneKit shader at a lower resolution?

How to write a sceneKit shader modifier for a dissolve in effect

How to programmatically wrap png texture around cube in SceneKit

Using shader modifiers to animate texture in SceneKit leads to jittery textures over time

Using a Metal shader in SceneKit

How to apply a transformation matrix to a vector in SceneKit

Want to add Image as texture in scenekit ios

Metal Shader with SceneKit SCNProgram

Scenekit: recolor diffuse texture with shader

How to pass texture buffer data to Shader with Metal?

Implementing toon effect with Metal shader and SceneKit

How can I map a texture image onto a shader geometry?

Unity: Apply shader to object to curve its texture

Exporting toon shader maya

How to stop a Shader from distorting a texture

Texture coordinates shift when apply Y rotation in vertex shader

OpenGL : How can I pass multiple texture to a shader with one variable?

How I can draw a tile from a texture tilemap in an OpenGL shader?

How to correctly draw other texture in fragment shader?

How to store an array into a texture and sampler the texture in vertex shader correctly?

Toon.shader not finding _light var

How to apply a texture to part of a face?

How to apply texture to text with a shadow

SceneKit shader modifier for geometry entry points works in iOS but not OS X

How to modify a Texture pixels from a compute shader in unity?

Toon shader shadow

How to apply multiple shader effects to a DrawingVisual?

SceneKIt - how to assign ARSCNView video feed as a texture to a SCNGeometry

how to get the texture of a shader in p5js