使用 ShaderMaterial 的 Alpha 颜色
Alpha color with ShaderMaterial
我正在尝试编写一个着色器 material 来显示带有圆点的 THREE.Points() 对象。我通过控制片段着色器中的 alpha 值来做到这一点。
下面是我的代码的完整工作版本。我得到了只给圆圈内的像素着色的预期效果。然而,在外面,我变白了而不是背景色。
这个question和我的有关。我尝试设置 material.transparent = true
但没有任何效果。
<html>
<head>
<title>THREEJS alpha shader</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
<script type="text/javascript" src="http://threejs.org/build/three.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<!-- Shaders -->
<script type="x-shader/x-vertex" id="vertexshader">
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
gl_PointSize = 40.0; // pixels
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
varying vec4 color;
void main() {
// radius
float r = length(gl_PointCoord - vec2(0.5, 0.5));
if(r < 0.5) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
} else {
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
}
}
</script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var buffer = new Float32Array(3); // single point located at (0, 0, 0)
var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(buffer,3) );
// create shader material
var material = new THREE.ShaderMaterial({
vertexShader : $('#vertexshader').text(),
fragmentShader : $('#fragmentshader').text(),
});
var point = new THREE.Points(geometry, material);
scene.add(point);
camera.position.z = 2;
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
您需要在 OpenGL 上下文中启用 alpha 混合。我不确定是否有办法使用 three.js 执行此操作,但将这些 GL 命令添加到您的 render() 函数就足够了:
var render = function () {
var gl = renderer.context;
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
requestAnimationFrame( render );
renderer.render(scene, camera);
};
有关这方面的更多信息,请参阅 blendFunc 上的 MDN 文档。
我正在尝试编写一个着色器 material 来显示带有圆点的 THREE.Points() 对象。我通过控制片段着色器中的 alpha 值来做到这一点。
下面是我的代码的完整工作版本。我得到了只给圆圈内的像素着色的预期效果。然而,在外面,我变白了而不是背景色。
这个question和我的有关。我尝试设置 material.transparent = true
但没有任何效果。
<html>
<head>
<title>THREEJS alpha shader</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
<script type="text/javascript" src="http://threejs.org/build/three.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<!-- Shaders -->
<script type="x-shader/x-vertex" id="vertexshader">
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
gl_PointSize = 40.0; // pixels
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
varying vec4 color;
void main() {
// radius
float r = length(gl_PointCoord - vec2(0.5, 0.5));
if(r < 0.5) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
} else {
gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
}
}
</script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var buffer = new Float32Array(3); // single point located at (0, 0, 0)
var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(buffer,3) );
// create shader material
var material = new THREE.ShaderMaterial({
vertexShader : $('#vertexshader').text(),
fragmentShader : $('#fragmentshader').text(),
});
var point = new THREE.Points(geometry, material);
scene.add(point);
camera.position.z = 2;
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
您需要在 OpenGL 上下文中启用 alpha 混合。我不确定是否有办法使用 three.js 执行此操作,但将这些 GL 命令添加到您的 render() 函数就足够了:
var render = function () {
var gl = renderer.context;
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
requestAnimationFrame( render );
renderer.render(scene, camera);
};
有关这方面的更多信息,请参阅 blendFunc 上的 MDN 文档。