iOS + SceneKit:如何将纹理着色器应用于纹理?
问题描述:
我想在iOS8 +上使用带有SceneKit的香椿着色器来渲染带有地球纹理的球体。我也想添加一个渲染地球的香椿着色器。到目前为止,着色器对光照起作用,但纹理不会被着色器着色(对于下面的图像,纹理也应该“tooned”)。iOS + SceneKit:如何将纹理着色器应用于纹理?
有人有什么想法吗?
这里是我的视图控制器代码(self.sceneKitView是SCNView的一个实例):
@implementation ToonViewController
- (void)viewDidLoad {
[super viewDidLoad];
SCNScene *scene = [SCNScene scene];
// create and add a camera to the scene
SCNNode *cameraNode = [SCNNode node];
cameraNode.camera = [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"]
encoding:NSUTF8StringEncoding
error:nil];
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;
}
@end
这是fixed_toon.shader文件:
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);
答
着色器你只有一个照明着色器。如果你想要地球被创造出来,你需要一个片段着色器。
看着色器文件所有的数学都与光有关。你需要一些能够调整纹理的像素颜色的东西。然后使用SCNShaderModifierEntryPointFragment入口点连接它。
感谢您的提示。一些更多的信息或链接将受到高度赞赏。我真的没有在互联网上找到关于这个主题的东西(在场景工具包中为纹理着色)。 – salocinx
另一种解决方案是在Photoshop中仅对纹理进行效果处理,但如果结构更复杂,则最好使用着色器进行处理。 – salocinx
对不起,我无法为你写着色器。您可能需要的大致轮廓可以在这里找到https://en.wikipedia.org/wiki/Cel_shading特别注意过程。除非你熟练掌握着色语言,Photoshop可能是你最好的解决方案。 – beyowulf