Three.js 中的简单片段着色器
Simple Fragment shader in Three.js
我正在 Three.JS 中探索着色器并尝试创建简单的电视静态效果。据我了解,我需要使用片段着色器作为网格中的 material。
我很难从教程切换到 Three.js 环境,因为事情是未定义的。我的问题似乎是位置变量没有被设置为统一,但我不确定该怎么做。
控制台错误:.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS true gl.getProgramInfoLog Varying 'position' has static-use in the frag shader, but is undeclared in the vert shader.
着色器:
<script type="x-shader/x-fragment" id="static">
uniform float time;
varying vec2 position;
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main()
{
vec2 uv = position.xy;
float r = floor(rand(uv * time / 2.0) + 0.5);
gl_FragColor = vec4(r, r, r, 1.0);
}
</script>
JS:
var camera, scene, renderer, geometry, material, mesh, uniforms;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);
geometry = new THREE.CylinderGeometry(100, 100, 20, 32);
debugMaterial = new THREE.MeshNormalMaterial();
uniforms = {
time: { type: 'f', value: 0 }
};
var shaderMaterial = new THREE.ShaderMaterial({
uniforms: uniforms,
fragmentShader: document.getElementById('static').innerHTML
});
mesh = new THREE.Mesh(geometry, shaderMaterial);
/* toggle the mesh variable to see the object */
//mesh = new THREE.Mesh(geometry, debugMaterial);
scene.add(mesh);
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render(delta) {
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
uniforms.time += delta * 10;
renderer.render(scene, camera);
}
render();
所需效果:圆柱体几何体上的以下像素着色器。
Fiddle(输出为空白,尽管我包含了一个 debugMaterial,因此您只需切换 mesh =
行即可按预期查看几何图形):https://jsfiddle.net/z688644L/2/
您似乎没有顶点着色器。通过将 position
声明为 varying
,您告诉系统该向量来自顶点着色器。您需要一个简单的顶点着色器来设置一个变量(您必须重命名它,因为 position
已经在顶点着色器中定义)以便您的片段着色器可以选择它:
<script id="vertShader" type="shader">
varying vec2 vPosition;
void main() {
vPosition = position.xy;
gl_Position = projectionMatrix *
modelViewMatrix * vec4(position, 1.0 );
}
</script>
我已将 position
重命名为 vPosition
,因此相应地调整片段着色器。另外,我还没有对此进行测试,所以 买者慎入。它绝对不能处理灯光或类似的东西。这只是让您入门的东西。
我正在 Three.JS 中探索着色器并尝试创建简单的电视静态效果。据我了解,我需要使用片段着色器作为网格中的 material。
我很难从教程切换到 Three.js 环境,因为事情是未定义的。我的问题似乎是位置变量没有被设置为统一,但我不确定该怎么做。
控制台错误:.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS true gl.getProgramInfoLog Varying 'position' has static-use in the frag shader, but is undeclared in the vert shader.
着色器:
<script type="x-shader/x-fragment" id="static">
uniform float time;
varying vec2 position;
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main()
{
vec2 uv = position.xy;
float r = floor(rand(uv * time / 2.0) + 0.5);
gl_FragColor = vec4(r, r, r, 1.0);
}
</script>
JS:
var camera, scene, renderer, geometry, material, mesh, uniforms;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);
geometry = new THREE.CylinderGeometry(100, 100, 20, 32);
debugMaterial = new THREE.MeshNormalMaterial();
uniforms = {
time: { type: 'f', value: 0 }
};
var shaderMaterial = new THREE.ShaderMaterial({
uniforms: uniforms,
fragmentShader: document.getElementById('static').innerHTML
});
mesh = new THREE.Mesh(geometry, shaderMaterial);
/* toggle the mesh variable to see the object */
//mesh = new THREE.Mesh(geometry, debugMaterial);
scene.add(mesh);
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render(delta) {
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
uniforms.time += delta * 10;
renderer.render(scene, camera);
}
render();
所需效果:圆柱体几何体上的以下像素着色器。
Fiddle(输出为空白,尽管我包含了一个 debugMaterial,因此您只需切换 mesh =
行即可按预期查看几何图形):https://jsfiddle.net/z688644L/2/
您似乎没有顶点着色器。通过将 position
声明为 varying
,您告诉系统该向量来自顶点着色器。您需要一个简单的顶点着色器来设置一个变量(您必须重命名它,因为 position
已经在顶点着色器中定义)以便您的片段着色器可以选择它:
<script id="vertShader" type="shader">
varying vec2 vPosition;
void main() {
vPosition = position.xy;
gl_Position = projectionMatrix *
modelViewMatrix * vec4(position, 1.0 );
}
</script>
我已将 position
重命名为 vPosition
,因此相应地调整片段着色器。另外,我还没有对此进行测试,所以 买者慎入。它绝对不能处理灯光或类似的东西。这只是让您入门的东西。