在 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】:

制服particlevec2[30] 类型。一个统一的数组可能需要用SetShaderValueV而不是SetShaderValue来设置:

SetShaderValue(shader, particleLoc, particles, SHADER_UNIFORM_VEC2);

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

【讨论】:

@kr3ypt0n 我明白了。你是对的。无论如何,我已经更正了答案。

以上是关于在 raylib 中使用着色器时,对象不会根据鼠标位置移动的主要内容,如果未能解决你的问题,请参考以下文章

为啥在使用 OpenGL 编译顶点着色器时会出现着色器编译器错误 #143、#160 和 #216?

GGplot 对象不会根据数据框中指定的颜色对条形进行着色

使用两个着色器时的opengl奇怪行为

运行可执行文件时编译着色器时出错

未绑定着色器时,制服集和顶点属性值是不是保留

传递给片段着色器的纹理坐标全部为 0