- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要替换 Sprite 的颜色。
在谷歌建立的一些例子
这是我找到了一个看起来像 Unity 的工作解决方案 - [如何使用着色器动态交换 Sprite 的颜色][2]
如何将其移植到 cocos2d-x?有人可以帮忙提供代码示例吗?
我正在寻找 cocos2d-x v3 代码片段。真的很期待得到一些帮助。
最佳答案
文章中的算法How to Use a Shader to Dynamically Swap a Sprite's Colors很简单。它基于具有 256 个条目的一维查找表。这允许算法仅映射 256 种不同的颜色。
详细地说,新颜色(用于替换的颜色)存储在具有 256 个条目的一维纹理中。当从原始纹理中读取颜色时,会使用一个键来查找一维交换纹理中的新颜色。使用的关键是原始颜色的红色 channel ,这意味着原始文本中所有不同的颜色也必须具有不同的红色值。这是另一个限制。
原始文档( How to Use a Shader to Dynamically Swap a Sprite's Colors )说:
Note that this may not work as expected if two or more colors on the sprite texture share the same red value! When using this method, it's important to keep the red values of the colors in the sprite texture different.
uniform sampler2D u_spriteTexture; // sprite texture
uniform sampler1D u_swapTexture; // lookup texture with swap colors
vec4 SwapColor( vec2 textureCoord )
{
vec4 originalColor = texture( u_spriteTexture, textureCoord.st );
vec4 swapColor = texture( u_swapTexture, originalColor.r );
vec3 finalColor = mix( originalColor.rgb, swapColor.rgb, swapColor.a );
return vec4( finalColor.rgb, originalColor.a );
}
const float Epsilon = 1e-10;
vec3 RGBtoHCV( in vec3 RGB )
{
vec4 P = (RGB.g < RGB.b) ? vec4(RGB.bg, -1.0, 2.0/3.0) : vec4(RGB.gb, 0.0, -1.0/3.0);
vec4 Q = (RGB.r < P.x) ? vec4(P.xyw, RGB.r) : vec4(RGB.r, P.yzx);
float C = Q.x - min(Q.w, Q.y);
float H = abs((Q.w - Q.y) / (6.0 * C + Epsilon) + Q.z);
return vec3(H, C, Q.x);
}
vec3 RGBtoHSV(in vec3 RGB)
{
vec3 HCV = RGBtoHCV(RGB);
float S = HCV.y / (HCV.z + Epsilon);
return vec3(HCV.x, S, HCV.z);
}
vec3 HUEtoRGB(in float H)
{
float R = abs(H * 6.0 - 3.0) - 1.0;
float G = 2.0 - abs(H * 6.0 - 2.0);
float B = 2.0 - abs(H * 6.0 - 4.0);
return clamp( vec3(R,G,B), 0.0, 1.0 );
}
vec3 HSVtoRGB(in vec3 HSV)
{
vec3 RGB = HUEtoRGB(HSV.x);
return ((RGB - 1.0) * HSV.y + 1.0) * HSV.z;
}
RGBtoHSV
所示。和
RGBtoHSV
.然而,查找表必须包含在原始颜色的*色调*范围内线性分布的颜色分配。
uniform sampler2D u_spriteTexture; // sprite texture
uniform sampler1D u_swapTexture; // lookup texture with swap colors
// the texture coordinate is the hue of the original color
vec4 SwapColor( vec2 textureCoord )
{
vec4 originalColor = texture( u_spriteTexture, textureCoord.st );
vec3 originalHSV = RGBtoHSV( originalColor.rgb );
vec4 lookUpColor = texture( u_swapTexture, originalHSV.x );
vec3 swapHSV = RGBtoHSV( lookUpColor.rgb );
vec3 swapColor = HSVtoRGB( vec3( swapHSV.x, originalHSV.y, originalHSV.z ) );
vec3 finalColor = mix( originalColor.rgb, swapColor.rgb, lookUpColor.a );
return vec4( finalColor.rgb, originalColor.a );
}
vec3
的数组中。 .
x
组件包含原始颜色的色调,
y
组件包含交换颜色的色调,以及
z
组件包含一个 epsilon 值,它定义了颜色范围。
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
varying vec4 cc_FragColor;
varying vec2 cc_FragTexCoord1;
void main()
{
gl_Position = CC_PMatrix * a_position;
cc_FragColor = a_color;
cc_FragTexCoord1 = a_texCoord;
}
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 cc_FragColor;
varying vec2 cc_FragTexCoord1;
const float Epsilon = 1e-10;
vec3 RGBtoHCV( in vec3 RGB )
{
vec4 P = (RGB.g < RGB.b) ? vec4(RGB.bg, -1.0, 2.0/3.0) : vec4(RGB.gb, 0.0, -1.0/3.0);
vec4 Q = (RGB.r < P.x) ? vec4(P.xyw, RGB.r) : vec4(RGB.r, P.yzx);
float C = Q.x - min(Q.w, Q.y);
float H = abs((Q.w - Q.y) / (6.0 * C + Epsilon) + Q.z);
return vec3(H, C, Q.x);
}
vec3 RGBtoHSV(in vec3 RGB)
{
vec3 HCV = RGBtoHCV(RGB);
float S = HCV.y / (HCV.z + Epsilon);
return vec3(HCV.x, S, HCV.z);
}
vec3 HUEtoRGB(in float H)
{
float R = abs(H * 6.0 - 3.0) - 1.0;
float G = 2.0 - abs(H * 6.0 - 2.0);
float B = 2.0 - abs(H * 6.0 - 4.0);
return clamp( vec3(R,G,B), 0.0, 1.0 );
}
vec3 HSVtoRGB(in vec3 HSV)
{
vec3 RGB = HUEtoRGB(HSV.x);
return ((RGB - 1.0) * HSV.y + 1.0) * HSV.z;
}
#define MAX_SWAP 10
uniform vec3 u_swap[MAX_SWAP];
uniform int u_noSwap;
void main()
{
vec4 originalColor = texture2D(CC_Texture0, cc_FragTexCoord1);
vec3 originalHSV = RGBtoHSV( originalColor.rgb );
vec4 swapColor = vec4( originalColor.rgb, 1.0 );
for ( int i = 0; i < 10 ; ++ i )
{
if ( i >= u_noSwap )
break;
if ( abs( originalHSV.x - u_swap[i].x ) < u_swap[i].z )
{
swapColor.rgb = HSVtoRGB( vec3( u_swap[i].y, originalHSV.y, originalHSV.z ) );
break;
}
}
vec3 finalColor = mix( originalColor.rgb, swapColor.rgb, swapColor.a );
gl_FragColor = vec4( finalColor.rgb, originalColor.a );
}
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#define MAX_COLOR 10
class HelloWorld : public cocos2d::Scene
{
public:
virtual bool init() override;
static cocos2d::Scene* scene();
void menuCloseCallback(Ref* sender);
CREATE_FUNC(HelloWorld);
void InitSwapInfo( int i, const cocos2d::Color3B &sourceCol, const cocos2d::Color3B &swapCol, float deviation );
private:
cocos2d::GLProgram* mProgramExample;
cocos2d::Vec3 mSource[MAX_COLOR];
cocos2d::Vec3 mSwap[MAX_COLOR];
float mDeviation[MAX_COLOR];
cocos2d::Vec3 mSwapInfo[MAX_COLOR];
};
#endif // __HELLOWORLD_SCENE_H__
RGBtoHue
和 GLSL 函数
RGBtoHue
,应该实现完全相同的算法。
SwapInfo
RGB 颜色编码为
cocos2d::Vec3
.如果 RGB 颜色的源 channel 是字节(
unsigned char
),那么这可以很容易地转换为
cocos2d::Vec3
来自
cocos2d::Vec3( R / 255.0f, G / 255.0f, B / 255.0f )
.
#include "HelloWorldScene.h"
#include "AppMacros.h"
USING_NS_CC;
float RGBtoHue( const cocos2d::Vec3 &RGB )
{
const float Epsilon = 1e-10f;
cocos2d::Vec4 P = (RGB.y < RGB.z) ?
cocos2d::Vec4(RGB.y, RGB.z, -1.0f, 2.0f/3.0f) :
cocos2d::Vec4(RGB.y, RGB.z, 0.0f, -1.0f/3.0f);
cocos2d::Vec4 Q = (RGB.x < P.x) ?
cocos2d::Vec4(P.x, P.y, P.w, RGB.x) :
cocos2d::Vec4(RGB.x, P.y, P.z, P.x);
float C = Q.x - (Q.w < Q.y ? Q.w : Q.y);
float H = fabs((Q.w - Q.y) / (6.0f * C + Epsilon) + Q.z);
return H;
}
cocos2d::Vec3 SwapInfo( const cocos2d::Vec3 &sourceCol, const cocos2d::Vec3 &swapCol, float epsi )
{
return cocos2d::Vec3( RGBtoHue( sourceCol ), RGBtoHue( swapCol ), epsi );
}
void HelloWorld::InitSwapInfo( int i, const cocos2d::Color3B &sourceCol, const cocos2d::Color3B &swapCol, float deviation )
{
mSource[i] = cocos2d::Vec3( sourceCol.r/255.0, sourceCol.g/255.0, sourceCol.b/255.0 );
mSwap[i] = cocos2d::Vec3( swapCol.r/255.0, swapCol.g/255.0, swapCol.b/255.0 );
mDeviation[i] = deviation;
mSwapInfo[i] = SwapInfo( mSource[i], mSwap[i], mDeviation[i] );
}
Scene* HelloWorld::scene()
{
return HelloWorld::create();
}
bool HelloWorld::init()
{
if ( !Scene::init() ) return false;
auto visibleSize = Director::getInstance()->getVisibleSize();
auto origin = Director::getInstance()->getVisibleOrigin();
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
closeItem->setPosition(origin + Vec2(visibleSize) - Vec2(closeItem->getContentSize() / 2));
auto menu = Menu::create(closeItem, nullptr);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(Vec2(visibleSize / 2) + origin);
mProgramExample = new GLProgram();
mProgramExample->initWithFilenames("shader/colorswap.vert", "shader/colorswap.frag");
mProgramExample->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
mProgramExample->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
mProgramExample->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
mProgramExample->link();
mProgramExample->updateUniforms();
mProgramExample->use();
GLProgramState* state = GLProgramState::getOrCreateWithGLProgram(mProgramExample);
sprite->setGLProgram(mProgramExample);
sprite->setGLProgramState(state);
InitSwapInfo( 0, cocos2d::Color3B( 41, 201, 226 ), cocos2d::Color3B( 255, 0, 0 ), 0.1f );
InitSwapInfo( 1, cocos2d::Color3B( 249, 6, 6 ), cocos2d::Color3B( 255, 255, 0 ), 0.1f );
int noOfColors = 2;
state->setUniformVec3v("u_swap", noOfColors, mSwapInfo);
state->setUniformInt("u_noSwap", noOfColors);
this->addChild(sprite);
return true;
}
void HelloWorld::menuCloseCallback(Ref* sender)
{
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 cc_FragColor;
varying vec2 cc_FragTexCoord1;
const float Epsilon = 1e-10;
vec3 RGBtoHCV( in vec3 RGB )
{
vec4 P = (RGB.g < RGB.b) ? vec4(RGB.bg, -1.0, 2.0/3.0) : vec4(RGB.gb, 0.0, -1.0/3.0);
vec4 Q = (RGB.r < P.x) ? vec4(P.xyw, RGB.r) : vec4(RGB.r, P.yzx);
float C = Q.x - min(Q.w, Q.y);
float H = abs((Q.w - Q.y) / (6.0 * C + Epsilon) + Q.z);
return vec3(H, C, Q.x);
}
vec3 RGBtoHSV(in vec3 RGB)
{
vec3 HCV = RGBtoHCV(RGB);
float S = HCV.y / (HCV.z + Epsilon);
return vec3(HCV.x, S, HCV.z);
}
vec3 HUEtoRGB(in float H)
{
float R = abs(H * 6.0 - 3.0) - 1.0;
float G = 2.0 - abs(H * 6.0 - 2.0);
float B = 2.0 - abs(H * 6.0 - 4.0);
return clamp( vec3(R,G,B), 0.0, 1.0 );
}
vec3 HSVtoRGB(in vec3 HSV)
{
vec3 RGB = HUEtoRGB(HSV.x);
return ((RGB - 1.0) * HSV.y + 1.0) * HSV.z;
}
#define MAX_SWAP 10
uniform vec3 u_orig[MAX_SWAP];
uniform vec3 u_swap[MAX_SWAP];
uniform float u_deviation[MAX_SWAP];
uniform int u_noSwap;
void main()
{
vec4 originalColor = texture2D(CC_Texture0, cc_FragTexCoord1);
vec3 originalHSV = RGBtoHSV( originalColor.rgb );
vec4 swapColor = vec4( originalColor.rgb, 1.0 );
for ( int i = 0; i < 10 ; ++ i )
{
if ( i >= u_noSwap )
break;
if ( all( lessThanEqual( abs(originalColor.rgb - u_orig[i]), vec3(u_deviation[i]) ) ) )
{
vec3 swapHSV = RGBtoHSV( u_swap[i].rgb );
swapColor.rgb = HSVtoRGB( vec3( swapHSV.x, originalHSV.y, originalHSV.z ) );
break;
}
}
vec3 finalColor = mix( originalColor.rgb, swapColor.rgb, swapColor.a );
gl_FragColor = vec4( finalColor.rgb, originalColor.a );
}
int noOfColors = 2;
state->setUniformVec3v("u_orig", noOfColors, mSource);
state->setUniformVec3v("u_swap", noOfColors, mSwap);
state->setUniformFloatv("u_deviation", noOfColors, mDeviation);
state->setUniformInt("u_noSwap", noOfColors);
u_deviation
必须受到限制(例如
deviation = 0.02;
)。
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 cc_FragColor;
varying vec2 cc_FragTexCoord1;
#define MAX_SWAP 11
uniform vec3 u_orig[MAX_SWAP];
uniform vec3 u_swap[MAX_SWAP];
uniform float u_deviation[MAX_SWAP];
uniform int u_noSwap;
void main()
{
vec4 originalColor = texture2D(CC_Texture0, cc_FragTexCoord1);
vec4 swapColor = vec4( originalColor.rgb, 1.0 );
for ( int i = 0; i < MAX_SWAP ; ++ i )
{
vec3 deltaCol = abs( originalColor.rgb - u_orig[i] );
float hit = step( deltaCol.x + deltaCol.y + deltaCol.z, u_deviation[i] * 3.0 );
swapColor.rgb = mix( swapColor.rgb, u_swap[i].rgb, hit );
}
gl_FragColor = vec4( swapColor.rgb, originalColor.a );
}
void main()
{
vec4 originalColor = texture2D(CC_Texture0, cc_FragTexCoord1);
vec4 swapColor = vec4( originalColor.rgb, 1.0 );
for ( int i = 0; i < MAX_SWAP ; ++ i )
{
float hit = step( abs( originalColor.r - u_orig[i].r ), u_deviation[i] );
swapColor.rgb = mix( swapColor.rgb, u_swap[i].rgb, hit );
}
gl_FragColor = vec4( swapColor.rgb, originalColor.a );
}
mSwapTexture
必须添加到类中:
cocos2d::Texture2D* mSwapTexture;
#include <array>
.....
std::array< unsigned char, 256 * 4 > swapPlane{ 0 };
for ( int c = 0; c < noOfColors; ++ c )
{
size_t i = (size_t)( mSource[c].x * 255.0 ) * 4;
swapPlane[i+0] = (unsigned char)(mSwap[c].x*255.0);
swapPlane[i+1] = (unsigned char)(mSwap[c].y*255.0);
swapPlane[i+2] = (unsigned char)(mSwap[c].z*255.0);
swapPlane[i+3] = 255;
}
mSwapTexture = new Texture2D();
mSwapTexture->setAliasTexParameters();
cocos2d::Size contentSize;
mSwapTexture->initWithData( swapPlane.data(), swapPlane.size(), Texture2D::PixelFormat::RGBA8888, 256, 1, contentSize );
state->setUniformTexture( "u_swapTexture", mSwapTexture );
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 cc_FragColor;
varying vec2 cc_FragTexCoord1;
uniform sampler2D u_swapTexture; // lookup texture with 256 swap colors
void main()
{
vec4 originalColor = texture2D(CC_Texture0, cc_FragTexCoord1);
vec4 swapColor = texture2D(u_swapTexture, vec2(originalColor.r, 0.0));
vec3 finalColor = mix(originalColor.rgb, swapColor.rgb, swapColor.a);
gl_FragColor = vec4(finalColor.rgb, originalColor.a);
}
std::array< unsigned char, 1024 * 4 > swapPlane{ 0 };
for ( int c = 0; c < noOfColors; ++ c )
{
size_t ix = (size_t)( mSource[c].x * 255.0 );
size_t iy = (size_t)( mSource[c].y * 255.0 / 64.0 );
size_t i = ( iy * 256 + ix ) * 4;
swapPlane[i+0] = (unsigned char)(mSwap[c].x*255.0);
swapPlane[i+1] = (unsigned char)(mSwap[c].y*255.0);
swapPlane[i+2] = (unsigned char)(mSwap[c].z*255.0);
swapPlane[i+3] = 255;
}
mSwapTexture = new Texture2D();
mSwapTexture->setAliasTexParameters();
cocos2d::Size contentSize;
mSwapTexture->initWithData( swapPlane.data(), swapPlane.size(), Texture2D::PixelFormat::RGBA8888, 256, 4, contentSize );
void main()
{
vec4 originalColor = texture2D(CC_Texture0, cc_FragTexCoord1);
vec4 swapColor = texture2D(u_swapTexture, originalColor.rg);
vec3 finalColor = mix(originalColor.rgb, swapColor.rgb, swapColor.a);
gl_FragColor = vec4(finalColor.rgb, originalColor.a);
}
GL_LINEAR
使用上述方法,如果需要,必须模拟:
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 cc_FragColor;
varying vec2 cc_FragTexCoord1;
uniform sampler2D u_swapTexture; // lookup texture with 256 swap colors
uniform vec2 u_spriteSize;
void main()
{
vec2 texS = 1.0 / u_spriteSize;
vec2 texF = fract( cc_FragTexCoord1 * u_spriteSize + 0.5 );
vec2 texC = (cc_FragTexCoord1 * u_spriteSize + 0.5 - texF) / u_spriteSize;
vec4 originalColor = texture2D(CC_Texture0, texC);
vec4 swapColor = texture2D(u_swapTexture, originalColor.rg);
vec3 finalColor00 = mix(originalColor.rgb, swapColor.rgb, swapColor.a);
originalColor = texture2D(CC_Texture0, texC+vec2(texS.x, 0.0));
swapColor = texture2D(u_swapTexture, originalColor.rg);
vec3 finalColor10 = mix(originalColor.rgb, swapColor.rgb, swapColor.a);
originalColor = texture2D(CC_Texture0, texC+vec2(0.0,texS.y));
swapColor = texture2D(u_swapTexture, originalColor.rg);
vec3 finalColor01 = mix(originalColor.rgb, swapColor.rgb, swapColor.a);
originalColor = texture2D(CC_Texture0, texC+texS.xy);
swapColor = texture2D(u_swapTexture, originalColor.rg);
vec3 finalColor11 = mix(originalColor.rgb, swapColor.rgb, swapColor.a);
vec3 finalColor0 = mix( finalColor00, finalColor10, texF.x );
vec3 finalColor1 = mix( finalColor01, finalColor11, texF.x );
vec3 finalColor = mix( finalColor0, finalColor1, texF.y );
gl_FragColor = vec4(finalColor.rgb, originalColor.a);
}
u_spriteSize
必须像这样设置:
auto size = sprite->getTexture()->getContentSizeInPixels();
state->setUniformVec2( "u_spriteSize", Vec2( (float)size.width, (float)size.height ) );
Sprite * sprite = nullptr;
std::string imageFile = ....;
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(imageFile);
cocos2d::Image *img = !fullpath.empty() ? new Image() : nullptr;
if (img != nullptr && img->initWithImageFile(fullpath))
{
if ( img->getRenderFormat() == Texture2D::PixelFormat::RGBA8888 )
{
unsigned char *plane = img->getData();
for ( int y = 0; y < img->getHeight(); ++ y )
{
for ( int x = 0; x < img->getWidth(); ++ x )
{
size_t i = ( y * img->getWidth() + x ) * 4;
unsigned char t = plane[i];
for ( int c = 0; c < noOfColors; ++ c )
{
if ( fabs(mSource[c].x - plane[i+0]/255.0f) < mDeviation[c] &&
fabs(mSource[c].y - plane[i+1]/255.0f) < mDeviation[c] &&
fabs(mSource[c].z - plane[i+2]/255.0f) < mDeviation[c] )
{
plane[i+0] = (unsigned char)(mSwap[c].x*255.0);
plane[i+1] = (unsigned char)(mSwap[c].y*255.0);
plane[i+2] = (unsigned char)(mSwap[c].z*255.0);
}
}
}
}
}
std::string key = "my_swap_" + imageFile;
if ( Texture2D *texture = _director->getTextureCache()->addImage( img, key ) )
sprite = Sprite::createWithTexture( texture );
}
Sprite * sprite = nullptr;
std::string imageFile = ....;
std::string key = "my_swap_" + imageFile;
Texture2D *texture = _director->getTextureCache()->getTextureForKey( key );
if (texture == nullptr)
{
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(imageFile);
cocos2d::Image *img = !fullpath.empty() ? new Image() : nullptr;
if ( img->initWithImageFile(fullpath) &&
img->getRenderFormat() == Texture2D::PixelFormat::RGBA8888 )
{
unsigned char *plane = img->getData();
for ( int y = 0; y < img->getHeight(); ++ y )
{
for ( int x = 0; x < img->getWidth(); ++ x )
{
size_t i = ( y * img->getWidth() + x ) * 4;
unsigned char t = plane[i];
for ( int c = 0; c < noOfColors; ++ c )
{
if ( fabs(mSource[c].x - plane[i+0]/255.0f) < mDeviation[c] &&
fabs(mSource[c].y - plane[i+1]/255.0f) < mDeviation[c] &&
fabs(mSource[c].z - plane[i+2]/255.0f) < mDeviation[c] )
{
plane[i+3] = (unsigned char)(c+1);
}
}
}
}
texture = _director->getTextureCache()->addImage( img, key );
}
}
if ( texture != nullptr )
sprite = Sprite::createWithTexture( texture );
u_swap
和
u_noSwap
并且不必进行昂贵的搜索。
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 cc_FragColor;
varying vec2 cc_FragTexCoord1;
#define MAX_SWAP 11
uniform vec3 u_swap[MAX_SWAP];
uniform int u_noSwap;
void main()
{
vec4 originalColor = texture2D(CC_Texture0, cc_FragTexCoord1);
float fIndex = originalColor.a * 255.0 - 0.5;
float maxIndex = float(u_noSwap) + 0.5;
int iIndex = int( clamp( fIndex, 0.0, maxIndex ) );
float isSwap = step( 0.0, fIndex ) * step( fIndex, maxIndex );
vec3 swapColor = mix( originalColor.rgb, u_swap[iIndex], isSwap );
gl_FragColor = vec4( swapColor.rgb, max(originalColor.a, isSwap) );
}
关于c++ - 即时重新着色 Sprite ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45822889/
我必须在文本区域上绘制哪些选项? 我认识一些所见即所得的编辑器。我不确定他们使用的方法是什么,并且会看看他们以了解,但我知道像 tinymce 这样的事情已经存在了一段时间,所以我猜现在可能有更现代的
我在我的 woo commerce 商店页面中创建了一个子类别排序菜单。我想将链接到我现在所在页面的链接设置为红色。我对 css 没有问题,只是用 js 脚本。我怎样才能让它突出当前?这是我创建的排序
所以我使用 TextWrangler4.5.3 并主要使用 Python 编写脚本。当我编写 Python 时,我经常喜欢发表类似这样的评论:# BEGINS foo 然后是 # ENDS foo 我
我需要你的帮助! 我有一个表格,里面有行(姓名等)现在,当位于该行上的对象具有特定值时,我想为特定的 tableCells 背景着色。但我只得到它来读取这个单元格的值。但我需要阅读对象(在我的代码中称
有人知道在 uikit 中给 uiactionsheet 着色吗? 最佳答案 是的,因为它是一个 UIView(如 kmit 所述),您可以使用以下命令:addSubview,因此您可以添加自己的背景
在 vba 中,我想从工作表中的单元格中读取颜色来为条形图中的特定条形着色。我的问题是我的颜色格式为 4F9F92,但要在 makro 中读取它,我需要使用单元格中的 excel 颜色代码 40762
我正在尝试绘制一个 geom_histogram,其中条形图由渐变着色。 这就是我想要做的: library(ggplot2) set.seed(1) df <- data.frame(id=past
我正在构建一个带有 shiny 的应用程序,并使用与 Shiny gallery ( http://shiny.rstudio.com/gallery/slider-bar-and-slider-ra
在 iOS 6 和 xcode 4 中,我有这个: https://dl.dropboxusercontent.com/u/60718318/photo.PNG使用代码可以轻松创建 [editButt
我正在向我的 iPhone UI 添加自定义按钮,并希望使它们具有 Apple 应用程序中的玻璃外观。我有一个很好的默认玻璃图像,但我不想为我想要的每种色调(红色、绿色、蓝色等)都有一个单独的图像。
我到处寻找但没有找到解决方案。我有图像 1。如何以编程方式使用渐变对它们进行着色以获得图像 2 和 3?以下是这些图像: 我通过 Photoshop 应用到它们的色调是简单的 2 色线性渐变。 我的问
有没有办法告诉 OS X 自动设置 NSToolbarItem 的样式/色调? 我通过 IB/Xcode 添加了一个“图像工具栏项”,并将图标设置为黑色 PDF as described in the
我试图区分列范围图表上的多种类型的数据。问题是我希望能够按多个标准对它们进行分组。 我可以轻松地为不同的列着色,从而解决一个问题,但我希望能够根据我传递到图表的数据,为 xAxis 上的类别(图表是倒
有人在编译模式 Emacs 中添加了对 ansi-color 的支持吗?如果是这样,颜色写入程序必须检查什么属性/属性才能确保其事件终端支持 ANSI 转义着色。 最佳答案 已经有一个函数可以将颜色应
我正在尝试实现 Phong 着色模型,但我不确定如何选择光源。更具体地说,我不明白光源应该是什么样子。它应该是vec3吗?或者也许是我在 Java 代码中定义的矩阵?另外,如果我们假设我希望相机作为光
我有 2 个 dhtmlxSidebars,就像示例中一样 here如何为嵌套背景设置不同的背景颜色?如果我添加CSS .dhxsidebar_side { background-color:
我有一个 JTable,每行都根据最后一列中的值着色。 但是,当我单击标题对行进行排序时,颜色不会跟随行。 我尝试在 JTable 鼠标退出事件上调用我的“colourTable”方法(我知道 Hac
geom_hline 似乎忽略了美观,我错过了什么还是这是一个错误? df session 信息: R version 3.4.4 (2018-03-15) Platform: x86_64-pc-
这个问题已经有答案了: How to draw a BufferedImage with a color tint (1 个回答) 已关闭 8 年前。 如何将通过此处的图标着色为不同的颜色?假设我想拍
我想为除我点击的那个之外的所有 div 着色。在我的代码中它有效,但只有一次。如果我点击另一个 div,它不起作用。 http://jsfiddle.net/6VhK8/353/ id="1
我是一名优秀的程序员,十分优秀!