Reputation: 371
Past weeks I have been experimenting with the three.js library & shaders and I’m stuck with implementing a shader on my model. I found this interesting example on pixelshaders.com that I want to implement on a threejs model.
http://pixelshaders.com/examples/noise.html
It's the last example at the bottom of the page and I’m trying to implement.
I'm trying to add it to the 3D model that can be found in the link below:
http://martinr.nl/lab/Speeltuin/webgl_shader2.html
The hard thing is when I add the code of the example the 3D model disappears. This makes it really hard to debug and find the error.
This is the shader code that works, but not with the right shader:
<script id="fragmentShader" type="x-shader/x-fragment">
varying vec2 vUv;
uniform float time;
uniform vec2 resolution;
precision mediump float;
void main( void ) {
vec2 position = 2.0 + 2.0 * vUv;
float red = abs( sin( position.x / position.y + time / 5.0 ) );
float green = abs( sin( position.x / position.y + time / 4.0 ) );
float blue = abs( sin( position.x / position.y + time / 3.0 ) );
gl_FragColor = vec4( red, green, blue, 1.0 );
}
</script>
<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vUv;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0);
gl_Position = projectionMatrix * mvPosition;
}
</script>
When I try to implement the shader of the above example the 3D model disappears.
Does anyone know how to implement the shader of the pixelshader.com example onto the model in my example?
Or does anyone have any tips what I could try to make it work?
Upvotes: 3
Views: 4540
Reputation: 1610
I replaced your fragment shader with the code from pixelshaders.com. Console reported the following error:
> THREE.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS false
> gl.getPRogramInfoLog Varyings with the same name but different type,
> or statically used varyings in fragment shader are not declared in
> vertex shader: position
A varying variable is essentially an interface between the vertex shader and the fragment shader. This error is telling us that position
is declared in the fragment shader, but not in the vertex shader.
You actually had the required variable in your vertex shader...except it was named vUv
. All I had to do was make the variable names consistent.
Full source (i took the scaling off the time
in the render()
function too):
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - materials - shaders [custom]</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #ffffff;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-color: #050505;
margin: 0px;
overflow: hidden;
}
a {
color: #ffffff;
}
#oldie a { color:#da0 }
</style>
</head>
<body>
<div id="container"></div>
<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - shader material demo. featuring <a href="http://www.pouet.net/prod.php?which=52761" target="_blank">Monjori by Mic</a></div>
<link rel="stylesheet" href="css/skeleton.css">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/codemirror.css">
<script src="js/lib/three.min.js"></script>
<script src="js/lib/Detector.js"></script>
<script src="js/geo.js"></script>
<script id="fragmentShader" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vUv;
uniform float time;
float random(float p) {
return fract(sin(p)*10000.);
}
float noise(vec2 p) {
return random(p.x + p.y*10000.);
}
vec2 sw(vec2 p) {return vec2( floor(p.x) , floor(p.y) );}
vec2 se(vec2 p) {return vec2( ceil(p.x) , floor(p.y) );}
vec2 nw(vec2 p) {return vec2( floor(p.x) , ceil(p.y) );}
vec2 ne(vec2 p) {return vec2( ceil(p.x) , ceil(p.y) );}
float smoothNoise(vec2 p) {
vec2 inter = smoothstep(0., 1., fract(p));
float s = mix(noise(sw(p)), noise(se(p)), inter.x);
float n = mix(noise(nw(p)), noise(ne(p)), inter.x);
return mix(s, n, inter.y);
return noise(nw(p));
}
float movingNoise(vec2 p) {
float total = 0.0;
total += smoothNoise(p - time);
total += smoothNoise(p*2. + time) / 2.;
total += smoothNoise(p*4. - time) / 4.;
total += smoothNoise(p*8. + time) / 8.;
total += smoothNoise(p*16. - time) / 16.;
total /= 1. + 1./2. + 1./4. + 1./8. + 1./16.;
return total;
}
float nestedNoise(vec2 p) {
float x = movingNoise(p);
float y = movingNoise(p + 100.);
return movingNoise(p + vec2(x, y));
}
void main() {
vec2 p = vUv * 6.;
float brightness = nestedNoise(p);
gl_FragColor.rgb = vec3(brightness);
gl_FragColor.a = 1.;
}
</script>
<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vUv;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0);
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container;
var camera, controls, scene, renderer;
var uniforms;
var clock = new THREE.Clock();
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 3000 );
camera.position.z = 2;
scene = new THREE.Scene();
var geometry = new THREE.BoxGeometry( 0.5, 0.5, 0.5 );
uniforms = {
time: { type: "f", value: 1.0 },
resolution: { type: "v2", value: new THREE.Vector3() }
};
var material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader').textContent
});
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize( event ) {
uniforms.resolution.value.x = window.innerWidth;
uniforms.resolution.value.y = window.innerHeight;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var delta = clock.getDelta();
uniforms.time.value += delta;
// for ( var i = 0; i < scene.children.length; i ++ ) {
//
// var object = scene.children[ i ];
//
// object.rotation.y += delta * 0.5 * ( i % 2 ? 1 : -1 );
// object.rotation.x += delta * 0.5 * ( i % 2 ? -1 : 1 );
//
// }
renderer.render( scene, camera );
}
</script>
</body>
</html>
Upvotes: 1