片段着色器未在 ThreeJS 中显示
Fragment Shader not showing in ThreeJS
我不熟悉 threejs 并在其中实现着色器。我带来了一个有趣的着色器,但我在显示它时遇到了问题。我相信它与代码中的变量“len”有关,但我不确定。这是代码笔 https://codepen.io/Yerbs/pen/eYWgevO 的 link。任何帮助,将不胜感激
这是片段着色器
fragmentShader: `
uniform vec2 resolution;
uniform float time;
const int AMOUNT = 12;
void main() {
vec2 coord = 20.0 * (gl_FragCoord.xy - resolution / 2.0) / min(resolution.y, resolution.x);
float len;
for (int i = 0; i < AMOUNT; i++){
len = length(vec2(coord.x, coord.y));
coord.x = coord.x - cos(coord.y + sin(len)) + cos(time / 9.0);
coord.y = coord.y + sin(coord.x + cos(len)) + sin(time / 12.0);
}
gl_FragColor = vec4(cos(len * 2.0), cos(len * 3.0), cos(len * 1.0), 1.0);
}
`
});
我已经测试了之前的代码,所以我知道它与片段本身有关。
您需要设置统一变量 time
和 resolution
的值(参见 ShaderMaterial
)。例如:
const material = new THREE.ShaderMaterial({
uniforms: {
time: { type: "f", value: 0.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
},
// [...]
function animate(timestamp) {
requestAnimationFrame(animate);
material.uniforms.time.value = timestamp / 1000;
material.uniforms.resolution.value.x = renderer.domElement.width;
material.uniforms.resolution.value.y = renderer.domElement.height;
renderer.render(scene, camera);
}
完整示例:
const renderer = new THREE.WebGLRenderer({
antialias: false
});
renderer.setSize(window.innerWidth, window.innerHeight, 2);
document.body.appendChild(renderer.domElement);
window.addEventListener( 'resize', function(e) {
renderer.setSize(window.innerWidth, window.innerHeight, 2);
});
const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
const material = new THREE.ShaderMaterial({
uniforms: {
time: { type: "f", value: 0.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4( position, 1.0 );
}
`,
fragmentShader: `
uniform vec2 resolution;
uniform float time;
const int AMOUNT = 12;
void main() {
vec2 coord = 20.0 * (gl_FragCoord.xy - resolution / 2.0) / min(resolution.y, resolution.x);
float len;
for (int i = 0; i < AMOUNT; i++){
len = length(vec2(coord.x, coord.y));
coord.x = coord.x - cos(coord.y + sin(len)) + cos(time / 9.0);
coord.y = coord.y + sin(coord.x + cos(len)) + sin(time / 12.0);
}
gl_FragColor = vec4(1.0, cos(len * 3.0), cos(len * 1.0), 1.0);
}
`
});
const quad = new THREE.Mesh(new THREE.PlaneBufferGeometry( 2, 2, 1, 1 ), material);
scene.add(quad);
function animate(timestamp) {
requestAnimationFrame(animate);
material.uniforms.time.value = timestamp / 1000;
material.uniforms.resolution.value.x = renderer.domElement.width;
material.uniforms.resolution.value.y = renderer.domElement.height;
renderer.render(scene, camera);
}
animate();
<script src="https://cdn.jsdelivr.net/npm/three@0.137/build/three.js"></script>
我不熟悉 threejs 并在其中实现着色器。我带来了一个有趣的着色器,但我在显示它时遇到了问题。我相信它与代码中的变量“len”有关,但我不确定。这是代码笔 https://codepen.io/Yerbs/pen/eYWgevO 的 link。任何帮助,将不胜感激 这是片段着色器
fragmentShader: `
uniform vec2 resolution;
uniform float time;
const int AMOUNT = 12;
void main() {
vec2 coord = 20.0 * (gl_FragCoord.xy - resolution / 2.0) / min(resolution.y, resolution.x);
float len;
for (int i = 0; i < AMOUNT; i++){
len = length(vec2(coord.x, coord.y));
coord.x = coord.x - cos(coord.y + sin(len)) + cos(time / 9.0);
coord.y = coord.y + sin(coord.x + cos(len)) + sin(time / 12.0);
}
gl_FragColor = vec4(cos(len * 2.0), cos(len * 3.0), cos(len * 1.0), 1.0);
}
`
});
我已经测试了之前的代码,所以我知道它与片段本身有关。
您需要设置统一变量 time
和 resolution
的值(参见 ShaderMaterial
)。例如:
const material = new THREE.ShaderMaterial({
uniforms: {
time: { type: "f", value: 0.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
},
// [...]
function animate(timestamp) {
requestAnimationFrame(animate);
material.uniforms.time.value = timestamp / 1000;
material.uniforms.resolution.value.x = renderer.domElement.width;
material.uniforms.resolution.value.y = renderer.domElement.height;
renderer.render(scene, camera);
}
完整示例:
const renderer = new THREE.WebGLRenderer({
antialias: false
});
renderer.setSize(window.innerWidth, window.innerHeight, 2);
document.body.appendChild(renderer.domElement);
window.addEventListener( 'resize', function(e) {
renderer.setSize(window.innerWidth, window.innerHeight, 2);
});
const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
const material = new THREE.ShaderMaterial({
uniforms: {
time: { type: "f", value: 0.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4( position, 1.0 );
}
`,
fragmentShader: `
uniform vec2 resolution;
uniform float time;
const int AMOUNT = 12;
void main() {
vec2 coord = 20.0 * (gl_FragCoord.xy - resolution / 2.0) / min(resolution.y, resolution.x);
float len;
for (int i = 0; i < AMOUNT; i++){
len = length(vec2(coord.x, coord.y));
coord.x = coord.x - cos(coord.y + sin(len)) + cos(time / 9.0);
coord.y = coord.y + sin(coord.x + cos(len)) + sin(time / 12.0);
}
gl_FragColor = vec4(1.0, cos(len * 3.0), cos(len * 1.0), 1.0);
}
`
});
const quad = new THREE.Mesh(new THREE.PlaneBufferGeometry( 2, 2, 1, 1 ), material);
scene.add(quad);
function animate(timestamp) {
requestAnimationFrame(animate);
material.uniforms.time.value = timestamp / 1000;
material.uniforms.resolution.value.x = renderer.domElement.width;
material.uniforms.resolution.value.y = renderer.domElement.height;
renderer.render(scene, camera);
}
animate();
<script src="https://cdn.jsdelivr.net/npm/three@0.137/build/three.js"></script>