【问题标题】:iOS+SceneKit: How to apply toon shader on texture?iOS+SceneKit:如何在纹理上应用卡通着色器?
【发布时间】:2016-02-02 08:21:04
【问题描述】:

我想在 iOS8+ 上使用带有 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);

【问题讨论】:

    标签: ios ios8 textures shader scenekit


    【解决方案1】:

    您拥有的着色器只是一个光照着色器。如果你想让地球被染色,你需要一个片段着色器。

    查看着色器文件,所有的数学运算都与光有关。您需要一些可以调整纹理像素颜色的东西。然后使用 SCNShaderModifierEntryPointFragment 入口点连接它。

    【讨论】:

    • 感谢您的提示。一些更多的信息或链接将不胜感激。我真的没有在互联网上找到关于这个主题的任何东西(场景工具包中纹理的卡通着色器)。
    • 另一种解决方案是在 Photoshop 中只为纹理制作效果,但如果结构更复杂,最好通过着色器来完成。
    • 对不起,我不能为你写着色器。可以在这里找到您可能想要的大致轮廓en.wikipedia.org/wiki/Cel_shading 专门查看流程。除非您精通着色器语言,否则 Photoshop 可能是您的最佳解决方案。
    • 好的,感谢您的帮助,我已接受您的回答。如果我找到合适的东西,我会更新问题。
    猜你喜欢
    • 2015-08-29
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多