Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在THREE.js中的自定义着色器中将图像作为纹理映射到平面_Javascript_Three.js_Shader - Fatal编程技术网

Javascript 在THREE.js中的自定义着色器中将图像作为纹理映射到平面

Javascript 在THREE.js中的自定义着色器中将图像作为纹理映射到平面,javascript,three.js,shader,Javascript,Three.js,Shader,我尝试加载2个图像作为纹理,在片段着色器中在它们之间插值,并将颜色应用到平面。不幸的是,我甚至不能显示一个纹理 我正在创建平面并加载图像,如下所示: const planeGeometry = new THREE.PlaneBufferGeometry(imageSize * screenRatio, imageSize); loader.load( "textures/IMG_6831.jpeg", (image) => { texture1 = new

我尝试加载2个图像作为纹理,在片段着色器中在它们之间插值,并将颜色应用到平面。不幸的是,我甚至不能显示一个纹理

我正在创建平面并加载图像,如下所示:

const planeGeometry = new THREE.PlaneBufferGeometry(imageSize * screenRatio, imageSize);

loader.load(
    "textures/IMG_6831.jpeg",
    (image) => {
        texture1 = new THREE.MeshBasicMaterial({ map: image });
        //texture1 = new THREE.Texture({ image: image });
    }
)
当我直接使用MeshBasicMaterial作为Mesh as normal的材质时,它正确地显示了平面上的图像。在自定义着色器中尝试执行相同操作时,我只得到黑色:

const uniforms = {
    texture1: { type: "sampler2D", value: texture1 },
    texture2: { type: "sampler2D", value: texture2 }
};

const planeMaterial = new THREE.ShaderMaterial({
    uniforms: uniforms,
    fragmentShader: fragmentShader(),
    vertexShader: vertexShader()
});

const plane = new THREE.Mesh(planeGeometry, planeMaterial);
scene.add(plane);
着色器:

const vertexShader = () => {
    return `
        varying vec2 vUv; 

        void main() {
            vUv = uv; 

            vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
            gl_Position = projectionMatrix * modelViewPosition; 
        }
    `;
}

const fragmentShader = () => {
    return `
        uniform sampler2D texture1; 
        uniform sampler2D texture2; 
        varying vec2 vUv;

        void main() {
            vec4 color1 = texture2D(texture1, vUv);
            vec4 color2 = texture2D(texture2, vUv);
            //vec4 fColor = mix(color1, color2, vUv.y);
            //fColor.a = 1.0;
            gl_FragColor = color1;
        }
    `;
}
为了解决这个问题,我试着:

  • 通过使用简单的颜色对平面进行着色,确保该平面可见
  • 通过将uv坐标可视化为颜色,确保将其传递给着色器
  • 确保将
    texture1
    texture2
    传递到着色器之前已定义
  • 使用
    THREE.Texture
    代替
    THREE.MeshBasicMaterial
  • 更改js中的统一类型
    texture1:{type:“t”,value:texture1},

我认为问题可能在于将纹理作为均匀纹理传递给着色器的部分。我可能在某处使用了错误的类型。。我将感谢任何帮助

假设
加载程序
纹理加载程序
,那么它会使用纹理调用您,所以

loader.load(
    "textures/IMG_6831.jpeg",
    (texture) => {
        texture1 = texture;
    }
)
否则,虽然它不是bug,
type
不再用于three.js制服

const planeGeometry=新的三个。PlaneBufferGeometry(1,1);
const loader=new THREE.TextureLoader();
让纹理1;
装载机(
"https://i.imgur.com/KjUybBD.png",
(纹理)=>{
纹理1=纹理;
start();
}
);
常量顶点着色器=()=>{
返回`
可变vec2 vUv;
void main(){
vUv=紫外线;
vec4模型视图位置=模型视图矩阵*vec4(位置,1.0);
gl_位置=投影矩阵*模型视图位置;
}
`;
}
常量碎片着色器=()=>{
返回`
均匀的二维纹理1;
均匀的2D纹理2;
可变vec2 vUv;
void main(){
vec4 color1=纹理2D(纹理1,vUv);
vec4 color2=纹理2D(纹理2,vUv);
//vec4 fColor=mix(color1、color2、vUv.y);
//F颜色a=1.0;
gl_FragColor=颜色1;
}
`;
}
函数start(){
const renderer=new THREE.WebGLRenderer();
document.body.appendChild(renderer.doElement);
const scene=new THREE.scene();
const-camera=新的三个摄像头();
警察制服={
纹理1:{value:texture1},
texture2:{value:texture1},
};
const planeMaterial=新的3.ShaderMaterial({
制服:制服,
fragmentShader:fragmentShader(),
vertexShader:vertexShader()
});
const plane=新的三个网格(平面几何体、平面材质);
场景。添加(平面);
渲染器。渲染(场景、摄影机);
}

是的,问题在于从加载程序分配纹理。我改变了:
texture1=newthree.MeshBasicMaterial({map:image})到:
texture1=图像成功了。谢谢