在 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,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,W,0.0,1.0);
            particles[i][1] = remap(particle[i].y,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,(float)texture.width,(float) -texture.height },(Vector2) { 0,0},RAYWHITE);
        DrawRectangle(0,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,particles[0],SHADER_UNIFORM_VEC2,30);