2016-02-19 10 views
0

Я пытаюсь реализовать шейдер для травы в cocos2d-x. Шейдер работает нормально на текстуре загружены Sprite :: Create() и это выглядит следующим образом:Cocos2d-x shader использует недопустимое смещение на texturepacker импортированный spriteframe

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

Проблема заключается в том, что если я использую Sprite :: createWithSpriteFrameName() и применение тот же шейдер, похоже, смещения ошибаются при расчете высоты и потому, что она двигается в большей степени, как он использует высоту полной текстуры из Plist файла:

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

Вот код шейдера:

ВШ

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

Если то, что происходит, не ясно, что я могу предоставить некоторые видео. Спасибо.

EDIT

Вот код, который используется для создания травы спрайт

// 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 и передать их в шейдер.

I вычисляется смещение с помощью следующего кода:

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

Last, затенение с использованием смещения, как это:

#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

Трудно сказать, что происходит, не видя больше кода ...

If I должен угадать, я бы сказал, что проблема связана с обрезкой в ​​TexturePacker.

Если вы установили TrimMode = Trim, спрайт удаляется из прозрачности. Это делает спрайт меньше. Cocos2d-x также отображает меньшую часть спрайта, компенсируя разницу между исходным спрайтом и обрезанным спрайтом вектором смещения.

Я предлагаю вам либо попытаться обрезать спрайт, либо попробовать обрезку многоугольника.

+0

Да, действительно, это было частью проблемы. Без обрезки это выглядит нормально. Но есть и другая проблема. Поскольку эффект качания травы основан на высоте текстуры, и поскольку в сгенерированной текстуре один ниже другого, текстура, которая ниже, имеет менее размахивающий эффект. Так что я предполагаю, что высота в шейдере фрагмента вычисляется неправильно, используя всю высоту текстуры от texturepacker. Есть ли способ избежать этого? –

+0

Вы можете попробовать передать реальные размеры шейдеру. Они доступны из grass2-> getSpriteFrame(). При этом вы сможете компенсировать обрезанные пиксели. –