Cocos2d v3 在子节点上应用着色器

3

目前我正在使用Cocos2d中的着色器进行实验。我的目标是对整个屏幕(除了一个节点及其子节点)应用着色器,以便在游戏模糊时有一个叠加菜单。

现在我找到了这个教程来使用Cocos2D中的着色器,并得到了以下代码:

CCSprite *aSprite = [CCSprite spriteWithImageNamed:@"Default.png"];
aSprite.contentSizeType = CCSizeTypeNormalized;
aSprite.contentSize = CGSizeMake(0.5,0.5);

NSString *fullPath = [[NSBundle mainBundle] pathForResource:@"CSEEmboss" ofType:@"fsh"];
const GLchar * fragmentSource = (GLchar*) [[NSString stringWithContentsOfFile:fullPath encoding:NSUTF8StringEncoding error:nil] UTF8String];
aSprite.shaderProgram = [[CCGLProgram alloc] initWithVertexShaderByteArray:ccPositionTextureA8Color_vert
                                                  fragmentShaderByteArray:fragmentSource];
[aSprite.shaderProgram addAttribute:kCCAttributeNamePosition index:kCCVertexAttrib_Position];
[aSprite.shaderProgram addAttribute:kCCAttributeNameTexCoord index:kCCVertexAttrib_TexCoords];
[aSprite.shaderProgram link];
[aSprite.shaderProgram updateUniforms];

[aSprite.shaderProgram use];

[self.scene addChild:aSprite];

确实可以将浮雕应用于精灵,但是当我向该精灵添加子元素时,着色器不会应用于那里,我该怎么做?我的场景包含许多子元素,使用循环为每个子元素添加和删除着色器似乎不正确。

2个回答

1

下面是一个类似于http://saeedoo.com/?p=644(Cocos2d-x)的Cocos-2D Obj-C友好实现。

ShaderNode的所有子节点都将使用给定的着色器进行渲染。

首先将所有子节点渲染到CCTextureNode中,然后使用给定的着色器渲染该纹理。

ShaderNode.h

#import "CCNode.h"

@interface ShaderNode : CCNode
-(id)initWithShader:(CCShader*)shader;
@end

ShaderNode.m

#import "ShaderNode.h"
#import "cocos2d.h"

@implementation TRShaderNode
{
    CCShader *_shader;
    CCRenderTexture *_renderTexture;
    CCSprite *_sprite;
}

- (id)initWithShader:(CCShader*)shader {
    self = [super init];
    if (self) {
        NSAssert(shader, @"Shader cannot be nil.");
        _shader = shader;
        CGSize size = [[CCDirector sharedDirector] viewSize];
        _renderTexture = [[CCRenderTexture alloc] initWithWidth:size.width height:size.height pixelFormat:CCTexturePixelFormat_RGBA8888];

        _sprite = [[CCSprite alloc] initWithTexture:_renderTexture.texture rect:CGRectMake(0, 0, _renderTexture.texture.contentSize.width, _renderTexture.texture.contentSize.height)];
        _sprite.position = CGPointZero;
        _sprite.anchorPoint = CGPointZero;
        _sprite.shader = _shader;
    }
    return self;
}

-(void)visit:(CCRenderer *)renderer parentTransform:(const GLKMatrix4 *)parentTransform {
    CCRenderer *textureRenderer = [_renderTexture beginWithClear:0 g:0 b:0 a:0];
    for (CCNode *node in self.children){
        [node visit:textureRenderer parentTransform:parentTransform];
    }
    [_renderTexture end];
    [_sprite visit:renderer parentTransform:parentTransform];
}

@end

1
通过自己的一些研究,我认为实现这个最好的方法是使用CCRenderTexture并截取其余界面的屏幕截图。然后在由渲染纹理生成的CCSprite上使用模糊着色器。接下来,您可以将菜单界面放置在渲染纹理上方。

1
是的,那就是我们采取的方式。只使用iOS库来捕获屏幕并使用核心图形(Core Graphics)进行模糊处理。 - Matthijn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接