在 raylib 中使用着色器时对象不根据鼠标位置移动

Object not moving according to mouse position when using shaders in raylib

我正在使用着色器在 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

如果你能给我指出正确的方向,那就太好了。

制服 particle 是类型 vec2[30]。统一数组可以需要设置 SetShaderValueV 而不是 SetShaderValue:

SetShaderValue(shader, particleLoc, particles, SHADER_UNIFORM_VEC2);

SetShaderValueV(shader, particleLoc, particles[0], SHADER_UNIFORM_VEC2, 30);