Я создал приведенный ниже пример, чтобы попрактиковаться в кодировании GLSL, используя Three.js.
Я ссылался на некоторые примеры кодов, поэтому не совсем уверен, как работают некоторые коды GLSL.
Я добавил комментарии (★) к двум кодам ниже, где я не понимаю, что происходит.
Короче говоря, я не понимаю, как создается этот белый круг и как изменяется его размер.
Я новичок в GLSL и чувствую, что это может быть математический вопрос, но я был бы очень признателен, если бы кто-то мог помочь мне точно понять, что происходит в приведенных ниже кодах GLSL.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.min.js"></script>
<title>shader01</title>
<style>
body {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
<script id="fragmentShader" type="x-shader/x-fragment">
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 mouse;
uniform float time;
uniform vec2 resolution;
void main(void){
vec2 st = gl_FragCoord.xy/resolution;
//★What exactly is this calculation for? Why is it using a length method?
float f = 0.1/ length(st - mouse);
vec3 colorA = vec3(0.14,0.14,0.90);
vec3 colorB = vec3(1.00,0.80,0.20);
float pct = abs(sin(time));
//★colorA is 'vec3' while f is 'float', so what kind of calculation is made here?
//How does using a mix method make it possible for the size of the white circle to change like this?
vec3 tmp = mix((colorA) + f, colorB, pct);
gl_FragColor = vec4(tmp, 1.0);
}
</script>
<script>
var container;
var camera, scene, renderer;
var uniforms;
init();
animate();
function init() {
container = document.getElementById('container');
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();
var geometry = new THREE.PlaneBufferGeometry(2, 2);
uniforms = {
time: { type: "f", value: 1.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
mouse: { type: "v2", value: new THREE.Vector2() }
};
var material = new THREE.ShaderMaterial({
uniforms: uniforms,
fragmentShader: document.getElementById('fragmentShader').textContent
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
container.appendChild(renderer.domElement);
onWindowResize();
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize(e) {
renderer.setSize(window.innerWidth, window.innerHeight);
uniforms.resolution.value.x = renderer.domElement.width;
uniforms.resolution.value.y = renderer.domElement.height;
}
function animate() {
requestAnimationFrame(animate);
render();
}
document.onmousemove = function (e) {
uniforms.mouse.value.x = e.pageX / window.innerWidth;
uniforms.mouse.value.y = 1 - (e.pageY / window.innerHeight);
}
function render() {
uniforms.time.value += 0.01;
renderer.render(scene, camera);
}
</script>
</body>
</html>