我想将this着色器与three.js一起使用。此示例中的顶点着色器使用属性surfacePosAttrib
,该属性通过我认为的以下调用在托管javascript中设置:
surface.positionAttribute = gl.getAttribLocation(currentProgram, "surfacePosAttrib");
gl.enableVertexAttribArray(surface.positionAttribute);
在webglrenderer
搜索three.js
来源时,我找不到这些来电,因此我认为这些缓冲区未在three.js
中设置。
是否支持在three.js
中为自定义着色器设置这些缓冲区的方法?
答案 0 :(得分:1)
我在源代码中看到了这个顶点着色器:
<script id="surfaceVertexShader" type="x-shader/x-vertex">
attribute vec3 position;
attribute vec2 surfacePosAttrib;
varying vec2 surfacePosition;
void main() {
surfacePosition = surfacePosAttrib;
gl_Position = vec4( position, 1.0 );
}
</script>
您提供的第一行代码会在surfacePosAttrib
内的顶点着色器中找到索引绑定属性current program
,并在javascript中将其分配给positionAttribute
surface
。第二行就是启用它。 Javascript缓冲区名称是任意的。它们在不同的程序中有不同的名称,所以可以预测你在three.js
中找不到这样的缓冲区。
我猜测(不确定)几乎所有的工作都是在片段着色器中完成的(就像IñigoQuílez完成的大部分类似作品都可以在his shadertoy page中找到)和顶点着色器仅为片段着色器提供绘制的表面。
下面的简单示例使用three.js
中的自定义着色器。它定义了一个具有相机可见的2D平面几何体的网格,并定义了一个自定义着色器,其顶点着色器和片段着色器由用户提供。请注意,projectionMatrix
和modelViewMatrix
由three.js
在顶点着色器中自动提供,因此您无需手动传递它们。
<!DOCTYPE html>
<html>
<head>
<title>Shading #1</title>
<style>canvas { width: 100%; height: 100% ;}</style>
<style>
body {
margin: 0px;
}
</style>
</head>
<body>
<script src="https://rawgithub.com/mrdoob/three.js/master/build/three.min.js"></script>
<script id="vs" type="x-shader/x-vertex">
void main()
{
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
</script>
<script id="fs" type="x-shader/x-fragment">
uniform float time;
uniform vec2 resolution;
void main()
{
gl_FragColor = vec4(0.3, 0.0, 0.0 , 1.0);
}
</script>
<script type="text/javascript">
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer({ antialias: true});
var startTime = Date.now();
//assignings happen here
//more info on https://github.com/mrdoob/three.js/wiki/Uniforms-types
var uniforms = {
time: {
type: 'f',
value: 0
},
resolution: {
type: "v2",
value: new THREE.Vector2( window.innerWidth, window.innerHeight )
}
};
var myMaterial = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: document.getElementById( 'vs' ).textContent,
fragmentShader: document.getElementById( 'fs' ).textContent
});
camera.position.z = 0.40;
var itemGeometry = new THREE.PlaneGeometry( window.innerWidth / (window.innerWidth+window.innerHeight), window.innerHeight / (window.innerWidth+window.innerHeight), 0);
var itemCube = new THREE.Mesh( itemGeometry, myMaterial );
scene.add( itemCube );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
function render() {
requestAnimationFrame(render);
uniforms.time.value = (Date.now() - startTime)/1000;
renderer.render(scene, camera);
}
render();
</script>
</body>
</html>