在 raylib 中使用着色器时,对象不会根据鼠标位置移动
Posted
技术标签:
【中文标题】在 raylib 中使用着色器时,对象不会根据鼠标位置移动【英文标题】:Object not moving according to mouse position when using shaders in raylib 【发布时间】:2021-05-18 11:06:46 【问题描述】:我正在使用着色器在 raylib 中创建一些发光粒子,这些粒子应该随着鼠标一起移动,但是在编译时它会卡在左下角并且粒子不要动。
How it Looks
c++代码
#include <raylib.h>
#include <vector>
const int W = 400;
const int H = 400;
std::vector<Vector2> particle;
float remap(float value, float low1, float high1, float low2, float high2)
return low2 + (value - low1) * (high2 - low2) / (high1 - low1);
int main()
SetConfigFlags( FLAG_WINDOW_RESIZABLE );
InitWindow(W, H, "FireWorks");
Shader shader = LoadShader("../assets/vert.glsl", "../assets/frag.glsl");
Texture2D texture = LoadTextureFromImage(GenImageColor(W, H, BLUE));
int resolLoc = GetShaderLocation(shader, "resolution");
int particleLoc = GetShaderLocation(shader, "particle");
int particleCountLoc = GetShaderLocation(shader, "particleCount");
float res[2] = (float)W, (float)H;
SetShaderValue(shader, resolLoc, res, SHADER_UNIFORM_VEC2);
SetTargetFPS(60);
while (!WindowShouldClose())
BeginDrawing();
ClearBackground(BLACK);
particle.push_back(Vector2(float)GetMouseX(), (float)GetMouseY());
int removeCount = 1;
for (int i = 0; i < removeCount; i++)
if (particle.size() == 0) break;
if (particle.size() > 30)
particle.erase(particle.begin() + i);
BeginShaderMode(shader);
float particles[30][2];
for ( int i = 0; i < particle.size(); i++)
particles[i][0] = remap(particle[i].x, 0, W, 0.0, 1.0);
particles[i][1] = remap(particle[i].y, 0, H, 1.0, 0.0);
int pSize = particle.size();
SetShaderValue(shader, particleCountLoc, &pSize, SHADER_UNIFORM_INT);
SetShaderValue(shader, particleLoc, particles, SHADER_UNIFORM_VEC2);
DrawTextureRec(texture, (Rectangle) 0, 0, (float)texture.width, (float) -texture.height , (Vector2) 0, 0, RAYWHITE);
DrawRectangle(0, 0, W, H, BLACK);
EndShaderMode();
EndDrawing();
UnloadTexture(texture);
UnloadShader(shader);
CloseWindow();
return 0;
顶点着色器
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
in vec4 vertexColor;
// Input uniform values
uniform mat4 mvp;
// Output vertex attributes (to fragment shader)
out vec2 fragTexCoord;
out vec4 fragColor;
// NOTE: Add here your custom variables
void main()
// Send vertex attributes to fragment shader
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
// Calculate final vertex position
gl_Position = mvp * vec4(vertexPosition, 1.0);
片段着色器
#version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
uniform vec2 resolution;
uniform int particleCount;
uniform vec2 particle[30];
void main()
// Texel color fetching from texture sampler
vec4 texelColor = texture(texture0, fragTexCoord);
vec2 st = gl_FragCoord.xy / resolution.xy;
float r = 0.0;
float g = 0.0;
float b = 0.0;
for (int i = 0; i < 30; i++)
if (i < particleCount)
vec2 particlePos = particle[i];
float value = float(i) / distance(st, particlePos.xy) * 0.00015;
g += value * 0.5;
b += value;
finalColor = vec4(r, g, b, 1.0) * texelColor * colDiffuse;
代码的 JS 版本(有效)是here。
如果你能指出我正确的方向,那就太好了。
【问题讨论】:
【参考方案1】:制服particle
是vec2[30]
类型。一个统一的数组可能需要用SetShaderValueV
而不是SetShaderValue
来设置:
SetShaderValue(shader, particleLoc, particles, SHADER_UNIFORM_VEC2);
SetShaderValueV(shader, particleLoc, particles[0], SHADER_UNIFORM_VEC2, 30);
【讨论】:
@kr3ypt0n 我明白了。你是对的。无论如何,我已经更正了答案。以上是关于在 raylib 中使用着色器时,对象不会根据鼠标位置移动的主要内容,如果未能解决你的问题,请参考以下文章