[英]Move circle with Projection matrix
我需要一些幫助來嘗試使用視圖矩陣移動我的圓圈。 我可以 position 圓但不能移動它。 我怎樣才能做到這一點?
現在邊界矩形移動但不是圓。
我試圖將圓圈置於矩形的中心,但這不起作用。
任何幫助表示贊賞!
#include <glew.h>
#include "circle.h"
Circle::Circle()
{
const std::string vertexShaderSource = R"END(
#version 330 core
layout (location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords>
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
void main()
{
gl_Position = projection * view * model * vec4(vertex.xy, 0.0, 1.0);
}
)END";
const std::string fragmentShaderSource = R"END(
#version 330 core
out vec4 color;
uniform vec2 dim;
uniform vec2 pos;
/**
* Convert r, g, b to normalized vec3
*/
vec3 rgb(float r, float g, float b) {
return vec3(r / 255.0, g / 255.0, b / 255.0);
}
/**
* Draw a circle at vec2 `pos` with radius `rad` and
* color `color`.
*/
vec4 circle(vec2 uv, vec2 pos, float rad, vec3 color) {
float d = length(pos - uv) - rad;
float t = clamp(d, 0.0, 1.0);
return vec4(color, 1.0 - t);
}
void main() {
vec2 uv = gl_FragCoord.xy;
float radius = 60;
vec2 center = pos;
// Background layer
vec4 layer1 = vec4(rgb(210.0, 222.0, 228.0), 0.3);
// Circle
vec3 red = rgb(225.0, 95.0, 60.0);
vec4 layer2 = circle(uv, center, radius, red);
// Blend the two
color = mix(layer1, layer2, layer2.a);
}
)END";
shader.Compile(vertexShaderSource.c_str(), fragmentShaderSource.c_str());
// Configure VAO etc..
}
void Circle::Update(float deltaTime, int width, int height)
{
// Activate shader
shader.Activate();
auto camera = Services::Get<RenderService>()->camera;
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view;
if (skipPan == false)
{
view = camera.GetViewMatrix();
}
else
{
view = glm::mat4{1.0f};
}
projection = glm::ortho(0.0f, static_cast<float>(width),
static_cast<float>(height), 0.0f, -1.0f, 1.0f);
model = glm::translate(model, glm::vec3(transform.position.x, transform.position.y, 0.0f));
model = glm::scale(model, glm::vec3(transform.dimension.width, transform.dimension.height, 1.0f));
shader.setMat4("projection", projection);
shader.setMat4("model", model);
shader.setMat4("view", view);
shader.setVec2("dim", glm::vec2{transform.dimension.width, transform.dimension.height});
shader.setVec2("pos", glm::vec2{transform.position.x, transform.position.y});
shader.setVec4("spriteColor", glm::vec4{style.Background.r, style.Background.g, style.Background.b, style.Background.a});
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
這是我一段時間以來一直在努力解決的問題。 這也適用於使用 SDF 等渲染的其他形狀。
// configure VAO/VBO
const float vertices[] = {
0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f};
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
您說您正在嘗試使用view matrix移動圓圈。 您確實將該矩陣傳遞給頂點着色器,並在gl_Position
的計算中使用它。 但是,您的片段着色器計算基於gl_FragCoord
並且不以任何方式合並視圖矩陣。 請記住, gl_FragCoord
是相對於幀緩沖區左下角(通常)的片段坐標,因此不受模型/視圖/投影轉換的影響。
要解決此問題,您可以執行以下任一操作:
在Circle::Update
中計算圓心的片段坐標並將其傳遞給pos
制服:
glm::vec4 pos = view*glm::vec4{transform.position.x, transform.position.y, 0.0f, 1.0f}; shader.setVec2("pos", pos.xy);
在片段着色器中應用視口變換——與上面相同,但在着色器中完成。 這有點丑陋,因為您將應用view
而不是model
,因為后者已經計入pos
的值。 它還涉及片段着色器中的更多計算。
更改片段着色器以處理紋理坐標而不是gl_FragCoord
。 如果您在四邊形的頂點設置固定紋理坐標,則四邊形內的插值坐標將根據任何視圖/模型/投影正確變換,從而開箱即用地處理縮放甚至透視投影。 這可能是您的案例中最簡潔的解決方案。 (也就是說,基於gl_FragCoord
的光柵化有時是必要的,以避免四邊形的兩個三角形之間的接縫處出現偽影。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.