webgl glsl 改变投影

发布于 2025-01-16 19:00:20 字数 680 浏览 3 评论 0原文

我正在使用 webgl 在屏幕上绘制 2d 计划。我想稍微旋转一下平面图以给出 3D 效果。 当前的: 当前

想要: 想要

我的第一个方法是使用消失点,例如透视图,但我不知道如何更改 y 坐标,所以我没有到达终点。有没有更简单的方法来旋转输出?

这是我的代码:

uniform float scale;
uniform vec2 ratio;
uniform vec2 center;
in vec3 fillColor;
in vec2 position;

out vec3 color;

void main() {
  color = fillColor;
  gl_Position = vec4((position - center) * ratio, 0.0, scale);
}

I'm drawing a 2d plan on the screen using webgl. I would like to rotate the plan a bit to give a 3d impression.
current:
current

wanted:
wanted

My first approach was to use vanishing points like drawing in perspective but I didn't know how to change the y coordinate and I didn't get to the end. Is there an easier way to rotate the output?

Here is my code:

uniform float scale;
uniform vec2 ratio;
uniform vec2 center;
in vec3 fillColor;
in vec2 position;

out vec3 color;

void main() {
  color = fillColor;
  gl_Position = vec4((position - center) * ratio, 0.0, scale);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情话难免假 2025-01-23 19:00:20

如果您想构建整个游戏引擎或复杂的动画,您将需要深入研究透视投影矩阵。

但如果您只是想实现这个小效果并尝试了解它是如何工作的,您可以使用 gl_Positionw 坐标。例如,该坐标对于告诉 GPU 如何以有效的 3D 方式插值 UV 纹理至关重要。它将被分为xyz

因此,我们假设您要显示一个矩形。你将需要两个三角形。
如果您使用 TRIANGLE_STRIP 模式,4 个顶点就足够了。我们可以只使用一个属性,但为了教程的目的,我将使用两个:

Vertex #attPosattUV
0-1, +10, 0
1-1, +10, 1
2+1, +11, 0
3+1, -11, 1

所有逻辑都将在顶点着色器中:

uniform float uniScale;
uniform float uniAspectRatio;

attribute vec2 attPos;
attribute vec2 attUV;

varying vec2 varUV;

void main() {
    varUV = attUV;
    gl_Position = vec4( 
        attPos.x * uniScale, 
        attPos.y * uniAspectRatio, 
        1.0, 
        attUV.y < 0.5 ? uniScale : 1.0 
    );
}

attUV.y 行0.5? uniScale : 1.0 表示

  • 如果 attUV.y 为 0,则使用 uniScale
  • 否则使用 1.0

attUV 属性允许您使用纹理如果你想。在这个例子中,
我只是用这个片段着色器模拟一个棋盘:

precision mediump float;

const float MARGIN = 0.1;
const float CELLS = 8.0;
const vec3 ORANGE = vec3(1.0, 0.5, 0.0);
const vec3 BLUE = vec3(0.0, 0.6, 1.0);

varying vec2 varUV;

void main() {
    float u = fract(varUV.x * CELLS);
    float v = fract(varUV.y * CELLS);
    if (u > MARGIN && v > MARGIN) gl_FragColor = vec4(BLUE, 1.0);
    else gl_FragColor = vec4(ORANGE, 1.0);
}

您可以在这个 CopePen 中看到所有这些操作:
https://codepen.io/tolokoban/full/oNpBRyO

If you want to build a whole game engine or a complex animation, you will need to dig into perspective projection matrices.

But if you just want to achieve this little effect and try to understand how it works, you can just use the w coord of gl_Position. This coordinate is essential to tell the GPU how to interpolate UV textures in a valid 3D way, for example. And it will be divided to x, y and z.

So let's assume you want to display a rectangle. You will need two triangles.
4 vertices will suffice if you use TRIANGLE_STRIP mode. We could use only one attribute, but for the sake of tutorial, I will use two:

Vertex #attPosattUV
0-1, +10, 0
1-1, +10, 1
2+1, +11, 0
3+1, -11, 1

And all the logic will be in the vertex shader:

uniform float uniScale;
uniform float uniAspectRatio;

attribute vec2 attPos;
attribute vec2 attUV;

varying vec2 varUV;

void main() {
    varUV = attUV;
    gl_Position = vec4( 
        attPos.x * uniScale, 
        attPos.y * uniAspectRatio, 
        1.0, 
        attUV.y < 0.5 ? uniScale : 1.0 
    );
}

The line attUV.y < 0.5 ? uniScale : 1.0 means

  • If attUV.y is 0, then use uniScale
  • Otherwise use 1.0

The attUV attribute let's you use a texture if you want. In this example,
I just simulate a checkboard with this fragment shader:

precision mediump float;

const float MARGIN = 0.1;
const float CELLS = 8.0;
const vec3 ORANGE = vec3(1.0, 0.5, 0.0);
const vec3 BLUE = vec3(0.0, 0.6, 1.0);

varying vec2 varUV;

void main() {
    float u = fract(varUV.x * CELLS);
    float v = fract(varUV.y * CELLS);
    if (u > MARGIN && v > MARGIN) gl_FragColor = vec4(BLUE, 1.0);
    else gl_FragColor = vec4(ORANGE, 1.0);
}

You can see all this in action in this CopePen:
https://codepen.io/tolokoban/full/oNpBRyO

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文