将纹理应用于四边形的一半
Apply texture to half of quad
我正在用 threejs 处理一个渲染 an image of a cat.
的场景
具体来说,我想渲染一个矩形,我希望该矩形的右半部分为红色,而该矩形的左半部分包含猫的完整图像(图像将被拉伸,这很好。
这是我的场景:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 2;
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BufferGeometry();
var imageSize = {width: 3, height: 2};
// add verts
var coords = {x: -1.5, y: -1, z: 0};
var vertices = new Float32Array([
coords.x, coords.y, coords.z,
coords.x+imageSize.width, coords.y, coords.z,
coords.x+imageSize.width, coords.y+imageSize.height, coords.z,
coords.x, coords.y+imageSize.height, coords.z,
])
var uvs = new Float32Array([
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
])
geometry.setIndex([0,1,2, 2,3,0])
geometry.setAttribute('position', new THREE.BufferAttribute( vertices, 3 ));
geometry.setAttribute('uv', new THREE.BufferAttribute( uvs, 2) )
var loader = new THREE.TextureLoader();
var url = 'https://s3.amazonaws.com/duhaime/blog/tsne-webgl/assets/cat.jpg';
var material = new THREE.RawShaderMaterial({
uniforms: {
texture: {
type: 't',
value: loader.load(url)
},
},
vertexShader: document.getElementById('vertex-shader').textContent,
fragmentShader: document.getElementById('fragment-shader').textContent
});
var mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0,0,0)
scene.add(mesh);
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
console.clear();
};
render();
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js'></script>
<script type='x-shader/x-vertex' id='vertex-shader'>
precision mediump float;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform vec3 cameraPosition;
attribute vec3 position;
attribute vec3 translation;
attribute vec2 uv;
varying vec2 vUv;
varying vec3 vPosition;
void main() {
vUv = uv;
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<script type='x-shader/x-fragment' id='fragment-shader'>
precision highp float;
uniform sampler2D texture;
varying vec2 vUv;
varying vec3 vPosition;
void main() {
vec2 uv = vUv;
if (vPosition.x > 0.0) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
} else {
gl_FragColor = texture2D(texture, uv);
}
}
</script>
如您所见,只有一半的猫图像显示在矩形的左侧。我不确定如何在矩形的左侧显示完整的猫图像。有人知道吗?任何指点将不胜感激!
[...] I'd like for the right half of that rectangle to be red, and for the left half of that rectangle to contain the full image [...]
纹理坐标在[0.0, 1.0]范围内。纹理的中心位于 (0.5, 0.5)。因此,在纹理的右半部分,纹理坐标的 x 分量 > 0.5。左边需要将纹理坐标的x分量缩放2.0:
gl_FragColor = vUv.x > 0.5
? vec4(1.0, 0.0, 0.0, 1.0)
: texture2D(texture, vec2(vUv.x*2.0, vUv.y));
我正在用 threejs 处理一个渲染 an image of a cat.
的场景具体来说,我想渲染一个矩形,我希望该矩形的右半部分为红色,而该矩形的左半部分包含猫的完整图像(图像将被拉伸,这很好。
这是我的场景:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 2;
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BufferGeometry();
var imageSize = {width: 3, height: 2};
// add verts
var coords = {x: -1.5, y: -1, z: 0};
var vertices = new Float32Array([
coords.x, coords.y, coords.z,
coords.x+imageSize.width, coords.y, coords.z,
coords.x+imageSize.width, coords.y+imageSize.height, coords.z,
coords.x, coords.y+imageSize.height, coords.z,
])
var uvs = new Float32Array([
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
])
geometry.setIndex([0,1,2, 2,3,0])
geometry.setAttribute('position', new THREE.BufferAttribute( vertices, 3 ));
geometry.setAttribute('uv', new THREE.BufferAttribute( uvs, 2) )
var loader = new THREE.TextureLoader();
var url = 'https://s3.amazonaws.com/duhaime/blog/tsne-webgl/assets/cat.jpg';
var material = new THREE.RawShaderMaterial({
uniforms: {
texture: {
type: 't',
value: loader.load(url)
},
},
vertexShader: document.getElementById('vertex-shader').textContent,
fragmentShader: document.getElementById('fragment-shader').textContent
});
var mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0,0,0)
scene.add(mesh);
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
console.clear();
};
render();
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js'></script>
<script type='x-shader/x-vertex' id='vertex-shader'>
precision mediump float;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform vec3 cameraPosition;
attribute vec3 position;
attribute vec3 translation;
attribute vec2 uv;
varying vec2 vUv;
varying vec3 vPosition;
void main() {
vUv = uv;
vPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<script type='x-shader/x-fragment' id='fragment-shader'>
precision highp float;
uniform sampler2D texture;
varying vec2 vUv;
varying vec3 vPosition;
void main() {
vec2 uv = vUv;
if (vPosition.x > 0.0) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
} else {
gl_FragColor = texture2D(texture, uv);
}
}
</script>
如您所见,只有一半的猫图像显示在矩形的左侧。我不确定如何在矩形的左侧显示完整的猫图像。有人知道吗?任何指点将不胜感激!
[...] I'd like for the right half of that rectangle to be red, and for the left half of that rectangle to contain the full image [...]
纹理坐标在[0.0, 1.0]范围内。纹理的中心位于 (0.5, 0.5)。因此,在纹理的右半部分,纹理坐标的 x 分量 > 0.5。左边需要将纹理坐标的x分量缩放2.0:
gl_FragColor = vUv.x > 0.5
? vec4(1.0, 0.0, 0.0, 1.0)
: texture2D(texture, vec2(vUv.x*2.0, vUv.y));