gpt4 book ai didi

textures - 径向渐变 - cocos2d-x v3.15+ 的程序纹理

转载 作者:行者123 更新时间:2023-12-02 03:01:08 25 4
gpt4 key购买 nike

在 cocos2d-x there is already LayerRadialGradient .
效果很好,但我的游戏场景中还运行了其他着色器,因此现在性能出现问题。 It's using a shader .

我想用生成径向渐变纹理的 Sprite 替换它。

这是 LayerRadialGradient 的示例绘图结果:

LayerRadialGradient::create( 
Color4B(179, 232, 184, 89),
Color4B(0, 90, 128, 0),
620,
center,
0.0f);

enter image description here

我有一些代码建议,例如:
static Color4B Lerp(const Color4B& value1, const Color4B& value2, float amount)
{
amount = clampf(amount, 0.0f, 1.0f);
return Color4B(
(int)MathUtil::lerp(value1.r, value2.r, amount),
(int)MathUtil::lerp(value1.g, value2.g, amount),
(int)MathUtil::lerp(value1.b, value2.b, amount),
(int)MathUtil::lerp(value1.a, value2.a, amount)
);
}

static float Falloff(float distance, float maxDistance, float scalingFactor)
{
if (distance <= maxDistance / 3)
{
return scalingFactor * (1 - 3 * distance * distance / (maxDistance * maxDistance));
}
else if (distance <= maxDistance)
{
float x = 1 - distance / maxDistance;
return (3.f / 2.f) * scalingFactor * x * x;
}
else
return 0;
}

static float Falloff(float distance, float maxDistance)
{
return Falloff(distance, maxDistance, 1.f);
}

static Texture2D* generateRadialGradientTexture(int size) {
auto radius = size / 2;
auto colors = new (std::nothrow) GLubyte[size * size * 4];

Color4B centerColor(Color4B(179, 232, 184, 89));
Color4B borderColor(Color4B(0, 90, 128, 0));

for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
float distance = Vec2::ONE.distance(Vec2(x, y) / radius);
float alpha = Falloff(distance, 1, 1);

int idx = (y * size + x) * 4;
float innerGradient = Falloff(distance, 0.6f, 0.8f);
auto color = Lerp(borderColor, centerColor, innerGradient);

colors[idx + 0] = color.r;
colors[idx + 1] = color.g;
colors[idx + 2] = color.b;

//alpha
colors[idx + 3] = (GLbyte)clampf(alpha * 256.f + 0.5f, 0.f, 255.f);
}
}

auto txt = new Texture2D();
txt->initWithData(colors, size * size * 4, Texture2D::PixelFormat::RGBA8888, size, size, Size(size, size));

delete[] colors;
return txt;
}

并仅使用:
Sprite::createWithTexture(generateRadialGradientTexture(radius));

但结果真的不一样:

enter image description here

最佳答案

我调查了shader code的问题,并在 C++ 中开发了一个类似的算法。该算法在两种颜色之间进行线性插值,从中心点开始,使用内部颜色,径向向外到外部颜色。
C++ 算法生成大小由输入参数指定的纹理:

#include <vector>  // std::vector
#include <math.h> // sqrt

Texture2D * TextureRadialGradientCreate(
int widht,
int height,
const Color4B &startColor,
const Color4B &endColor,
float radius,
const Vec2 &center,
float expand )
{
Vec4 sCol( startColor.r / 255.0, startColor.g / 255.0, startColor.b / 255.0, startColor.a / 255.0 );
Vec4 eCol( endColor.r / 255.0, endColor.g / 255.0, endColor.b / 255.0, endColor.a / 255.0 );

std::vector<unsigned char> plane( widht * height * 4, 0 );
for ( int y = 0; y < height; ++ y )
{
for ( int x = 0; x < widht; ++ x )
{
float dx = x - center.x;
float dy = y - center.y;
float d = sqrt( dx*dx + dy*dy ) / radius;

Vec4 mixCol( 0.0f, 0.0f, 0.0f, 0.0f );
if ( expand < 1.0f && d < 1.0f )
{
float a = ( d - expand ) / ( 1.0 - expand );
mixCol = (d <= expand) ? sCol : ( 1.0 - a ) * sCol + a*eCol;
}

size_t i = ( y * widht + x ) * 4;
plane[i+0] = (unsigned char)(mixCol.x * 255.0f);
plane[i+1] = (unsigned char)(mixCol.y * 255.0f);
plane[i+2] = (unsigned char)(mixCol.z * 255.0f);
plane[i+3] = (unsigned char)(mixCol.w * 255.0f);
}
}

Texture2D *texture = new Texture2D();
if ( texture != nullptr )
texture->initWithData( plane.data(), plane.size() / 4, Texture2D::PixelFormat::RGBA8888, widht, height, cocos2d::Size(widht, height) );
return texture;
}

例如大小为 600*600 的二次纹理和纹理中心的渐变高光:
int w = 600;
int h = 600;
float rad = ( w < h ? w : h ) / 2.0f;
Vec2 cpt( w / 2.0f, h / 2.0f );
texture = TextureRadialGradientCreate( w, h, layer_startColor, layer_endColor, rad, cpt, layer_expand );

答案的延伸

I don't know, maybe radial shader can be optimized?



通过使用 GLSL clamp 可以避免条件分支函数,通过限制 mix 的插值参数函数到范围 (0, 1)。
我建议优化 fragment shader像这样:
#ifdef GL_ES
varying lowp vec4 v_position;
#else
varying vec4 v_position;
#endif

uniform vec4 u_startColor;
uniform vec4 u_endColor;
uniform vec2 u_center;
uniform float u_radius;
uniform float u_expand;

void main()
{
float d = distance(v_position.xy, u_center) / u_radius;
float a = (d - u_expand) / (1.0 - u_expand);
gl_FragColor = mix( u_startColor, u_endColor, clamp(0.0, 1.0, a) );
}

关于textures - 径向渐变 - cocos2d-x v3.15+ 的程序纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46165399/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com