Cocos2d-x着色器在texturepacker导入的spriteframe上使用无效偏移量

时间:2016-02-19 22:52:34

标签: opengl cocos2d-x shader texturepacker

我正在尝试在cocos2d-x中实现草的着色器。着色器在使用 Sprite :: create()加载的纹理上正常工作,它看起来像这样:

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

问题在于,如果我使用 Sprite :: createWithSpriteFrameName()并应用相同的着色器,在计算高度时看起来偏移是错误的,因为它在更大程度上移动,就像它使用plist文件中的完整纹理的高度:

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

以下是着色器代码:

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));

2 个答案:

答案 0 :(得分:0)

如果没有看到更多代码,很难说出发生了什么......

如果我猜我会说问题与TexturePacker中的修剪有关。

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

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

答案 1 :(得分: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;
}