【发布时间】:2019-09-22 17:49:33
【问题描述】:
我一直在玩弄一些 THREE.js 示例,并一直在尝试编译一些包含在示例中的着色器,具体来说:https://github.com/brunoimbrizi/interactive-particles
如果您导航到 src/shaders/,您会找到我正在尝试编译的着色器。我目前正在运行一个 React 应用程序,并且一直在更新此代码以满足我的个人项目需求,但在此过程中我遇到了这些问题:
No matching overloaded function found
THREE.WebGLRenderer 98
THREE.WebGLShader: Shader couldn't compile.
THREE.WebGLShader: gl.getShaderInfoLog() vertex WARNING: 0:1: 'glslify' : unrecognized pragma
ERROR: 0:40: 'snoise_1_2' : no matching overloaded function found
ERROR: 0:49: 'snoise_1_2' : no matching overloaded function found
我尝试以多种不同的方式重构顶点/片段着色器代码,但无论我尝试的解决方案如何,结果都是相同的。似乎在 React 中对此类东西的支持非常少,虽然 gl-react 似乎几乎很有帮助,但我不需要组件形式的着色器。
particleFrag.js
const glsl = require('glslify');
export const fragShader = glsl`precision highp float;
uniform sampler2D uTexture;
varying vec2 vPUv;
varying vec2 vUv;
void main() {
vec4 color = vec4(0.0);
vec2 uv = vUv;
vec2 puv = vPUv;
vec4 colA = texture2D(uTexture, puv);
float grey = colA.r * 0.21 + colA.g * 0.71 + colA.b * 0.07;
vec4 colB = vec4(grey, grey, grey, 1.0);
float border = 0.3;
float radius = 0.5;
float dist = radius - distance(uv, vec2(0.5));
float t = smoothstep(0.0, border, dist);
color = colB;
color.a = t;
gl_FragColor = color;
}`;
particleVert.js
const glsl = require('glslify');
export const vertShader = glsl`#pragma glslify: snoise2 = require(glsl-noise/simplex/2d)
precision highp float;
attribute float pindex;
attribute vec3 position;
attribute vec3 offset;
attribute vec2 uv;
attribute float angle;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform float uTime;
uniform float uRandom;
uniform float uDepth;
uniform float uSize;
uniform vec2 uTextureSize;
uniform sampler2D uTexture;
uniform sampler2D uTouch;
varying vec2 vPUv;
varying vec2 vUv;
float random(float n) {
return fract(sin(n) * 43758.5453123);
}
void main() {
vUv = uv;
vec2 puv = offset.xy / uTextureSize;
vPUv = puv;
vec4 colA = texture2D(uTexture, puv);
float grey = colA.r * 0.21 + colA.g * 0.71 + colA.b * 0.07;
vec3 displaced = offset;
displaced.xy += vec2(random(pindex) - 0.5, random(offset.x + pindex) - 0.5) * uRandom;
float rndz = (random(pindex) + snoise_1_2(vec2(pindex * 0.1, uTime * 0.1)));
displaced.z += rndz * (random(pindex) * 2.0 * uDepth);
displaced.xy -= uTextureSize * 0.5;
float t = texture2D(uTouch, puv).r;
displaced.z += t * 20.0 * rndz;
displaced.x += cos(angle) * t * 20.0 * rndz;
displaced.y += sin(angle) * t * 20.0 * rndz;
float psize = (snoise_1_2(vec2(uTime, pindex) * 0.5) + 2.0);
psize *= max(grey, 0.2);
psize *= uSize;
vec4 mvPosition = modelViewMatrix * vec4(displaced, 1.0);
mvPosition.xyz += position * psize;
vec4 finalPosition = projectionMatrix * mvPosition;
gl_Position = finalPosition;
}`;
定义材质:
const material = new THREE.RawShaderMaterial({
uniforms,
vertexShader: shaders.particle.vert,
fragmentShader: shaders.particle.frag,
depthTest: false,
transparent: true,
// blending: THREE.AdditiveBlending
});
一切都源于这个渲染调用:
draw() {
this.renderer.render(this.scene, this.camera);
}
我显然需要编译着色器,我对这类事情的缺乏经验使其难以在 React 项目中实现。
【问题讨论】:
-
嗨!欢迎来到 SO。在您的问题中将实际控制台输出作为文本添加比屏幕截图的链接更有帮助。如果您必须使用屏幕截图,使用图像标记嵌入图像比链接更有帮助。谢谢!
-
@GeneZ.Ragan 注意到。我会确保尽快完成!
-
glslify is a build time system。您使用其他工具对其进行设置,它会获取您的源代码并生成新代码。您运行新代码。当然你
snoise_1_2是未定义的,因为你的代码没有定义它。没有称为snoise_1_2的内置函数。谷歌搜索或查看您复制的示例代码。 -
@gman 我尝试将 snoise_1_2 重命名为 snoise2 无济于事。由于某种原因,它会抛出与后者相同的错误。我浏览了 glsl-noise 的文档并严格按照 gettinfg 开始,但没有运气。在这篇文章之前我已经这样做了。
-
也没有 snoise2 功能。响声??是用户编写的用户函数。它不是 webgl 的一部分。 glslify 是一个在构建时运行的程序,用于将
#pragma glslify ...替换为在构建时的其他文件的内容。 在构建时意味着它是您从命令行运行的程序,它处理您的源代码并将其输出到驱动器的其他位置。您在浏览器中运行该处理的结果,而不是原始代码。 Read the instructions on glslify 然后使用其中一种方法,webpack、babel 或 browserify。
标签: fragment-shader vertex-shader glslify