実現したいこと
three.jsで2つのモデル(planeGeometryとtextGeometry)が重なっている部分だけ色を変えたい。
前提
three.js、シェーダー初心者です。
planeGeometryにshaderMaterialを使用して波のような描画をしています。
そこに文字を重ねているイメージです。
参考のイメージとしては下記サイトになります。
https://stripe.com/sessions
モデル同士が重なっている部分だけ文字の色を変えたいですが、うまくいきません。
お見苦しいソースコードですが、
three.js、シェーダーに詳しい方お力を貸していただけないでしょうか?
該当のソースコード
Javascript // Geometry const geometry = new THREE.PlaneGeometry(2, 2, 256, 256); const vertexShader2 = ` attribute vec3 position1; varying vec3 position2; varying vec3 vPosition2; varying vec2 vUv; void main() { vec4 modelPosition = modelMatrix * vec4(position, 1.0); vec4 viewPosition = viewMatrix * modelPosition; vec4 projectionPosition = projectionMatrix * viewPosition; gl_Position = projectionPosition; vUv = uv; position2 = position1; vPosition2 = position; } ` const fragmentShader2 = ` uniform vec3 uColor; // uniform vec3 uPosition1; uniform sampler2D uTexture; uniform float uOpacity; varying vec3 position2; varying vec3 vPosition2; varying vec2 vUv; void main() { // vec3 textureColor = texture2D(uTexture, vUv).rgb; // gl_FragColor = vec4(textureColor, uOpacity); if (position2.x > vPosition2.x ) { gl_FragColor = vec4(1.0,0,0, 1.0); } else { // その他のピクセルは元の色を使用する gl_FragColor = vec4(1.0); } } ` // Material const material = new THREE.ShaderMaterial({ vertexShader: vertexShader1, fragmentShader: fragmentShader1, }); // Mesh const mesh = new THREE.Mesh(geometry, material); mesh.scale.x = 10 mesh.scale.y = 2 mesh.position.x = 3 mesh.position.y = windowWidth <= resizeWidth.sp ? 1 : windowWidth <= resizeWidth.tb ? 1.2 : windowWidth <= resizeWidth.lt ? 1.5 : windowWidth <= resizeWidth.pc ? 3 : 3 mesh.position.z = -5 mesh.rotation.z = -Math.PI / 3; scene.add(mesh); const poses = []; function getPoses() { for (let i = 0; i < mesh.geometry.attributes.position.array.length; i += 3) { poses.push( // new THREE.Vector3( mesh.geometry.attributes.position.array[i + 0], mesh.geometry.attributes.position.array[i + 1], mesh.geometry.attributes.position.array[i + 2]) // ); } } getPoses(); // TextMesh const loader = new THREE.FontLoader(); let textMesh; const txtTextureLoader = new THREE.TextureLoader(); const txtTexture = txtTextureLoader.load("./textures/sessions_texture.png"); const textMaterial = new THREE.ShaderMaterial({ vertexShader: vertexShader2, fragmentShader: fragmentShader2, uniforms: { uTexture: { value: txtTexture }, uOpacity: { value: 1.0 }, }, transparent: true, }); loader.load('./fonts/helvetiker_regular.typeface.json', function (font) { const geometry = new THREE.TextGeometry('Bond AI', { font: font, size: 0.15, height: 0, curveSegments: 24, }); ・・・・ textMesh = new THREE.Mesh(geometry, textMaterial); ・・・・ const positionAttribute1 = new THREE.Float32BufferAttribute(new Float32Array(poses), 3); textMesh.geometry.setAttribute('position1', positionAttribute1); scene.add(textMesh); });
試したこと
頂点座標同士を比較することで重なっている部分を検出できるのではと考えて、
planeGeometryのmeshから
for (let i = 0; i < mesh.geometry.attributes.position.array.length; i += 3) {
poses.push(
mesh.geometry.attributes.position.array[i + 0],
mesh.geometry.attributes.position.array[i + 1],
mesh.geometry.attributes.position.array[i + 2])
}
で頂点座標を抜き出して、textGeometryのシェーダーにuniform変数として渡しました。textGeometry側のfragmentShader2で頂点座標を比較して色を変えようとしましたが上手くいきませんでした。(ところどころ色変わって意図している動作ではありませんでした。)
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。

あなたの回答
tips
プレビュー