2015-11-02 148 views
0

我想在iOS8 +上使用帶有SceneKit的香椿着色器來渲染帶有地球紋理的球體。我也想添加一個渲染地球的香椿着色器。到目前爲止,着色器對光照起作用,但紋理不會被着色器着色(對於下面的圖像,紋理也應該「tooned」)。iOS + SceneKit:如何將紋理着色器應用於紋理?

有人有什麼想法嗎?

enter image description here

這裏是我的視圖控制器代碼(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); 

回答

2

着色器你只有一個照明着色器。如果你想要地球被創造出來,你需要一個片段着色器。

看着色器文件所有的數學都與光有關。你需要一些能夠調整紋理的像素顏色的東西。然後使用SCNShaderModifierEntryPointFragment入口點連接它。

+1

感謝您的提示。一些更多的信息或鏈接將受到高度讚賞。我真的沒有在互聯網上找到關於這個主題的東西(在場景工具包中爲紋理着色)。 – salocinx

+0

另一種解決方案是在Photoshop中僅對紋理進行效果處理,但如果結構更復雜,則最好使用着色器進行處理。 – salocinx

+0

對不起,我無法爲你寫着色器。您可能需要的大致輪廓可以在這裏找到https://en.wikipedia.org/wiki/Cel_shading特別注意過程。除非你熟練掌握着色語言,Photoshop可能是你最好的解決方案。 – beyowulf