【问题标题】:Cocos2d v3 Apply shader on childnodesCocos2d v3 在子节点上应用着色器
【发布时间】:2014-02-26 13:15:28
【问题描述】:

目前我正在使用 Cocos2d 中的着色器。我的目标是将着色器应用于整个屏幕(一个节点及其子节点除外),以便在游戏模糊时有一个覆盖菜单。

现在我发现 this tutorial 可以在 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];

这确实将浮雕应用于精灵,但是当我将孩子添加到该精灵时,着色器并未应用在那里,我应该怎么做?我的场景包含许多孩子,并且对每个孩子都使用循环添加和删除着色器似乎不太合适。

【问题讨论】:

    标签: ios opengl-es cocos2d-iphone shader


    【解决方案1】:

    经过我自己的一些研究,我认为完成此任务的最佳方法是使用 CCRenderTexture 并对界面的其余部分进行屏幕截图。然后在渲染纹理生成的 CCSprite 上使用模糊着色器。然后,您可以将菜单界面放在渲染纹理上方。

    【讨论】:

    • 是的,我们就是这样做的。仅使用 iOS 库捕获屏幕和使用 Core Graphics 进行模糊。
    【解决方案2】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多