2016-02-19 13 views
0

我正在尝试为cocos2d-x中的草实现着色器。着色器适用于质地OK装有雪碧::创建(),它看起来像这样:Cocos2d-x着色器在纹理包导入的精灵帧上使用无效偏移

http://i.stack.imgur.com/Rv4rd.png

的问题是,如果我使用雪碧:: createWithSpriteFrameName()和应用计算高度时,也它看起来像偏移量相同的着色器是错误的,因为它是移动在更大的程度就像是使用了质感十足的高度,从plist文件:

http://i.stack.imgur.com/of6Ku.png

下面是shader代码:

VSH

attribute vec4 a_position; 
attribute vec2 a_texCoord; 
attribute vec4 a_color; 

#ifdef GL_ES 
varying lowp vec4 v_fragmentColor; 
varying mediump vec2 v_texCoord; 
#else 
varying vec4 v_fragmentColor; 
varying vec2 v_texCoord; 
#endif 

void main() 
{ 
    gl_Position = CC_PMatrix * a_position; 
    v_fragmentColor = a_color; 
    v_texCoord = a_texCoord; 
} 

FSH

#ifdef GL_ES 
precision mediump float; 
#endif 

varying vec2 v_texCoord; 

uniform float speed; 
uniform float bendFactor; 

void main() 
{ 
    float height = 1.0 - v_texCoord.y; 
    float offset = pow(height, 2.5); 

    offset *= (sin(CC_Time[1] * speed) * bendFactor); 

    gl_FragColor = texture2D(CC_Texture0, fract(vec2(v_texCoord.x + offset, v_texCoord.y))).rgba; 
} 

如果发生了什么并不清楚,我可以提供一些视频。谢谢。

编辑

这里是用来生成草精灵代码:

// Smaller grass 
auto grass2 = Sprite::createWithSpriteFrameName("grass2.png"); 
grass2->setAnchorPoint(Vec2(0.5f, 0)); 
grass2->setPosition(Vec2(230, footer1->getContentSize().height * 0.25f)); 
// Apply "grass" shader 
grass2->setGLProgramState(mat->getTechniqueByName("grass")->getPassByIndex(0)->getGLProgramState()->clone()); 
grass2->getGLProgramState()->setUniformFloat("speed", RandomHelper::random_real(0.5f, 3.0f)); 
grass2->getGLProgramState()->setUniformFloat("bendFactor", RandomHelper::random_real(0.1f, 0.2f)); 

回答

0

问题在于TexturePacker修剪,而且还有v_texCoord中的偏移。

解决方案是计算cocos2d-x中的偏移量并将它们传递给着色器。使用以下代码

我计算偏移:

Rect grass2Offset(
    grass2->getTextureRect().origin.x/grass2->getTexture()->getContentSize().width, 
    grass2->getTextureRect().origin.y/grass2->getTexture()->getContentSize().height, 
    grass2->getTextureRect().size.width/grass2->getTexture()->getContentSize().width, 
    grass2->getTextureRect().size.height/grass2->getTexture()->getContentSize().height 
); 

接着我通过高度偏移和比例来使用如制服着色器:

grass2->getGLProgramState()->setUniformFloat("heightOffset", grass2Offset.origin.y); 
grass2->getGLProgramState()->setUniformFloat("heightScale", 1/grass2Offset.size.height); 

最后,着色器是使用偏移这样的:

#ifdef GL_ES 
precision mediump float; 
#endif 

varying vec2 v_texCoord; 

uniform float speed; 
uniform float bendFactor; 
uniform float heightOffset; 
uniform float heightScale; 

void main() 
{ 
    float height = 1.0 - (v_texCoord.y - heightOffset) * heightScale; 
    float offset = pow(height, 2.5); 

    offset *= (sin(CC_Time[1] * speed) * bendFactor); 

    gl_FragColor = texture2D(CC_Texture0, fract(vec2(v_texCoord.x + offset, v_texCoord.y))).rgba; 
} 
0

这很难说发生了什么,没有看到更多的代码的...

如果我应该猜想我会说这个问题与TexturePacker中的修剪有关。

如果您设置TrimMode = Trim,则精灵将从透明度中删除。这使精灵更小。 Cocos2d-x也只渲染精灵的较小部分,用偏移矢量补偿原始精灵和修剪精灵之间的差异。

我建议你不要修剪精灵或尝试多边形修剪。

+0

的确是这是问题的一部分。没有修剪它看起来没问题。 但也有另一个问题。 由于草摆效果是基于纹理高度,并且因为在生成的纹理中一个低于另一个纹理,所以下面的纹理具有较小的摆动效果。 所以我猜测片段着色器中的高度计算错误,通过使用texturepacker中的整个纹理高度。有没有办法避免这种情况? –

+0

您可以尝试将实际大小传递给着色器。它们可以从grass2-> getSpriteFrame()获得。有了这个,你应该能够补偿修剪的像素。 –