Can two SCNNodes with different textures share the same shader?

At first glance the question seems trivial: Can two SCNNodes, which use geometries with materials using different textures, share the same shader?


One would think that the answer would be an obvious yes, but I'm not sure how this is accomplished.


In order to have two SCNNode objects that have a SCNGeometry object each, with different textures, one needs to create an SCNMaterial object to define these two textures, and give them to the SCNGeometry objects.


Two different SCNMaterial objects, two separate shaders (even if their source code is identical). I see no way of making them share the same shader.


One would think that creating a single SCNProgram object and assigning it to both materials would do the trick, but besides this being an exceedingly complicated solution (because AFAIK SCNProgram does not offer anything readymade, and you need to implement every single detail manually; all attributes, all uniforms... everything must be done by the programmer), there's a blog post that claims that the shader doesn't actually get shared, and instead each material will take its own copy of the shader, thus effectively having multiple shaders rather than one.


As for the easier solution, using shader modifier snippets on the material, unless SceneKit performs some really smart optimizations (which isn't, of course, documented at all), every single material will get its own shader instance.


This means that if you use 100 different textures in your game (even if they are part of one single texture atlas), each applied to its own SCNGeometry object, you will have 100 distinct shaders, one for each texture, even if every single one of those shaders is completely identical to each other.


Please correct me if I'm wrong. I can't believe that eg. SpriteKit is doing this. I can't believe that if you have a thousand different sprites (with different textures), then you have a thousand instances of the same shader, one for each sprite. This would be horrendously inefficient.


If it's not like this, then how does this work? How can I create different SCNMaterials with different textures, assigned to different SCNGeometry objects, and have them all share the one and same shader (preferably using shader modifier snippets)?

A node has a geometry, the geometry has materials and the materials have textures.


If you want to change textures, you can either swap textures on the material (which will reflect on all models using the same material) or swap the material.


From the Apple documentation:


You can easily copy geometries and change their materials. A geometry object manages the association between immutable vertex data and a mutable assignment of materials. To make a geometry appear more than once in the same scene with a different set of materials, use its inherited

copy
method. The copy shares the underlying vertex data of the original, but can be assigned materials independently. You can thus make many copies of a geometry without incurring a significant cost to rendering performance.


>>> This is similar to what happens in the SceneKit Editor in XCode when you hit the Unshare button (Sharing section of the Material inspector) to detach the material for the instance, in effect creating a copy of it.

I was going to say the same thing. Share the materials ( shaders ).

Vertex shaders (for meshes) and fragment shaders (for textures) modify the vertices / fragments over time to create effects (mesh deformation, color distortion etc...). Materials are different . They give a geometry its surface properties which in turn determine what the object looks like when lit. You can either set colors or textures for the diffuse, specular, ambient etc...

I don't want to "change textures". Maybe you didn't understand my question?


I want two polygons with different textures (more specifically, different SKTextures), but using the same shader.


If I have a thousand polygons, each with their own texture (or part of a texture from a texture atlas), it would be insane to have a thousand separate instances of the same fragment shader for them. Obviously they should all use the same shader, even if their texture is different. (This is, for example, what SpriteKit does, AFAIK. If you have a thousand sprites, each with its own texture, they will all share the same fragment shader nevertheless. It would be insane if they all had separate instances of the shader.)


If I simply assign the same material to all the polygons, they will all have the same texture. I need different textures for different polygons, but without the shaders being duplicated for each one. That would be amazingly inefficient.

Cant you have one base material + shader, the override the other settings of the material ? Then you have the instance of the shader only once ( in theory ). If you are after how the renderer pipeline of scenekit itself does it, then you need to ask the Apple devs. Maybe at WWDC if you can get a ticket or through the developer support.

"Cant you have one base material + shader, the override the other settings of the material?"


I don't understand what you mean.


It's ridiculous if you can't share the same shader with multiple materials with different textures. That's like one of the most basic things to do in rendering. It would be ridiculous to re-compile the same shader for every single texture used in the scene. AFAIK that would even decrease rendering performance (because essentially the graphics chip could only render one polygon at a time with each rendering pipeline).

Someone at stackoverflow claimed that SceneKit will detect if two shaders use the exact same source code, and will automatically make all objects using them share the one and same shader instance. Is this accurate?

Who was the "someone"? If it's one of the French guys that make Scene Kit, he may well have a very good point.

Why is this something that nobody has an answer to? Apparently not even Apple staff has answers to things like this. How is this even possible? Don't they know their own software? Do they, like, buy the development from somewhere, and then get an undocumented black box that just works, but they have no idea how? Why is this not documented anywhere? This is just ridiculous.

There are very few users of Scene Kit. This seems to be hidden. A dirty secret. Most of the Scene Kit team (which is probably about 4 people) seem to spend most of their time on PlayGounds. Notice that the new GamePlayKit features of components etc has not been brought to Scene Kit. I don't think they have time to do much, and probably have to deal with the paper work and rules of being in a huge company in any spare time. That would keep them busy.

Can two SCNNodes with different textures share the same shader?
 
 
Q