简体   繁体   English

WebGL代码说明-为什么这样工作

[英]Explanation of WebGL code - why does it work that way

I'm trying to make a lightbulb that glows a little and then it becomes less intense. 我正在尝试制作一个发光的灯泡,然后变得不那么强烈。 Also at the edges to be a little bit dimmer. 同样在边缘要有点暗淡。 I found the a code, that I think creates the effect I want to create, but I don't seem to understand it very well. 我找到了一个代码,我认为它可以创建我想创建的效果,但是我似乎不太了解它。 Here's the code: 这是代码:

mat2 rotate2d(float angle){
return mat2(cos(angle),-sin(angle),
            sin(angle),cos(angle));
    }

float variation(vec2 v1, vec2 v2, float strength, float speed) {
    return sin(
        dot(normalize(v1), normalize(v2)) * strength + iGlobalTime * speed
    ) / 100.0;
}

vec3 paintCircle (vec2 uv, vec2 center, float rad, float width) {

    vec2 diff = center-uv;
    float len = length(diff);

    len += variation(diff, vec2(0.0, 1.0), 5.0, 2.0);
    len -= variation(diff, vec2(1.0, 0.0), 5.0, 2.0);

    float circle = smoothstep(rad-width, rad, len) - smoothstep(rad, rad+width, len);
    return vec3(circle);
}


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord.xy / iResolution.xy;
    uv.x *= 1.5;
    uv.x -= 0.25;

    vec3 color;
    float radius = 0.35;
    vec2 center = vec2(0.5);


    //paint color circle
    color = paintCircle(uv, center, radius, 0.1);

    //color with gradient
    vec2 v = rotate2d(iGlobalTime) * uv;
    color *= vec3(v.x, v.y, 0.7-v.y*v.x);

    //paint white circle
    color += paintCircle(uv, center, radius, 0.01);


    fragColor = vec4(color, 1.0);
}

I don't understand why we need the dot product of the normalized vectors and how it's chosen exacly: 我不明白为什么我们需要归一化向量的点积以及如何精确选择它:

len += variation(diff, vec2(0.0, 1.0), 5.0, 2.0);
len -= variation(diff, vec2(1.0, 0.0), 5.0, 2.0);

I mean - why is there first adding, then subtraction? 我的意思是-为什么先加法,然后减法? Then why is that: 那为什么呢:

vec2 uv = fragCoord.xy / iResolution.xy;
uv.x *= 1.5;
uv.x -= 0.25;

and how does this vec2 v = rotate2d(iGlobalTime) * uv; color *= vec3(vx, vy, 0.7-vy*vx); 以及vec2 v = rotate2d(iGlobalTime) * uv; color *= vec3(vx, vy, 0.7-vy*vx); vec2 v = rotate2d(iGlobalTime) * uv; color *= vec3(vx, vy, 0.7-vy*vx);

make the color gradient? 使颜色渐变? Here's a link of the code if someone prefers watching it there and what it does: https://www.shadertoy.com/view/ltBXRc . 如果有人喜欢在此处观看代码及其作用,则这里是代码的链接: https : //www.shadertoy.com/view/ltBXRc I'm obviously not very good at geometry. 我显然不太擅长几何。 If someone could help me, I'd appreciate it :) 如果有人可以帮助我,我将不胜感激:)

If we wanted to draw a perfect circle, we would simply plot all points lying a certain distance from the center of the scene. 如果要绘制一个完美的圆,则只需绘制与场景中心相距一定距离的所有点即可。 Speaking procedurally, we would start from the center, pick any random direction, go some distance r in that direction, and plot a point. 从程序上来说,我们将从中心开始,选择任意随机方向,在该方向上走一段距离r ,然后绘制一个点。 Then return to the center, pick some other direction, go the same distance r , and plot another point. 然后返回中心,选择其他方向,走相同的距离r ,并绘制另一个点。 And so on, until we have a smooth circle: r = 1 依此类推,直到我们有一个光滑的圆: r = 1

To plot a distorted circle we can vary the distance r depending on the direction we're facing. 要绘制变形的圆,我们可以根据面对的方向改变距离r If we express the direction as an angle in radians ( theta ), then r will be some function of that angle. 如果我们将方向表示为以弧度( theta )为单位的角度,则r将是该角度的某个函数。 What function exactly? 到底有什么功能? Let's try something simple first: r = theta 首先让我们尝试一些简单的事情: r = theta

Not quiet what we want, it should be more like a circle (r = 1), but with a bit of waviness (r = 1 + waviness). 不是我们想要的安静,它应该更像一个圆(r = 1),但是有点波纹(r = 1 +波纹)。 The simplest wavy function is sin(x) . 最简单的波浪函数是sin(x) Let's try to add it: r = 1 + 0.1 * sin(5 * theta) 让我们尝试添加它: r = 1 + 0.1 * sin(5 * theta)

By changing the numbers we can manipulate the amplitude and the frequency of the waves. 通过更改数字,我们可以控制波的振幅和频率。 But there's too much symmetry, to break it we need something more complex than a sine wave. 但是对称太多了,要打破它,我们需要比正弦波更复杂的东西。

How about this monster sin(5 * sin(x)) - sin(5 * cos(x)) 这个怪物sin(5 * sin(x))-sin(5 * cos(x))怎么样

Let's add it to the circle r = 1 + 0.1 * sin(5 * sin(theta)) - 0.1 * sin(5 * cos(theta)) 让我们将其添加到圆中r = 1 + 0.1 * sin(5 * sin(theta))-0.1 * sin(5 * cos(theta))

Looks pretty good to me. 对我来说看起来不错。

The shader performs exactly this distortion, but in a different manner. 着色器恰好执行此变形,但方式不同。 Taking a dot product with a standard basis vector simply gives you the X or Y coordinate of the vector. 将点积与标准基础向量相乘即可简单地获得向量的X或Y坐标。 We can rewrite that bit as: 我们可以将该位重写为:

len += 0.02 * sin(normalize(diff).y * 5.0 + 2.0 * iGlobalTime);
len -= 0.02 * sin(normalize(diff).x * 5.0 + 2.0 * iGlobalTime);

X and Y coordinates of a normalized vector are just sin and cos of an angle represented by that vector. 归一化向量的X和Y坐标只是该向量表示的角度的sincos So, normalize(diff).y gives you the sine of an angle, and normalize(diff).x gives you the cosine. 因此, normalize(diff).y给您一个角度的正弦,而normalize(diff).x给您一个余弦。

Hopefully this clears things up a bit. 希望这可以使事情顺利进行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM