Experiencing issues with deferred shading using three.js. Gl_fragData value not received properly. Seeking solutions.
a
Shader Code
//shader1
<script id="vshader1" type="x-shader/x-vertex">
#extension GL_EXT_draw_buffers : require
varying vec2 vUv;
void main(void){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<script id="fshader1" type="x-shader/x-fragment">
uniform sampler2D texture;
varying vec2 vUv;
void main(void) {
vec4 smpColor = texture2D(texture, vUv);
gl_FragData[0] = smpColor;
gl_FragData[1] = smpColor;
}
</script>
//shader2
<script id="vshader2" type="x-shader/x-vertex">
varying vec2 vUv;
void main(void){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>
<script id="fshader2" type="x-shader/x-fragment">
uniform sampler2D texture;
varying vec2 vUv;
void main(void) {
vec4 smpColor = texture2D(texture, vUv);
gl_FragColor = smpColor;
}
</script>
Main program. A fusion of three.js and WebGl code.
function init(){
var texture = THREE.ImageUtils.loadTexture('img/test.png');
var mat1 = new THREE.ShaderMaterial({
vertexShader: document.getElementById('vshader1').textContent,
fragmentShader: document.getElementById('fshader1').textContent,
uniforms: {
texture: {
type: 't', value: texture
}
},
transparent: true,
needsUpdate:true,
});
var geometry = new THREE.PlaneGeometry( 100, 100, 10, 10 );
plane = new THREE.Mesh( geometry, mat1 );
plane.rotation.x = 220 * ( Math.PI / 180 );
scene.add( plane );
}
var gl;
var bufs = [];
var plane;
var mat;
var ext;
var FBO = [];
var texture1;
var texture2;
function initBuffer(){
gl = renderer.context;
ext = gl.getExtension("WEBGL_draw_buffers");
gl.getExtension("OES_texture_float");
gl.getExtension("OES_texture_float_linear");
var maxDrawBuffers = gl.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL);
FBO[0] = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, FBO[0]);
var depthRenderBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthRenderBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1024, 1024);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRenderBuffer);
texture1 = createTexture( gl, 1024, 0 );
texture2 = createTexture( gl, 1024, 1 );
ext.drawBuffersWEBGL(bufs);
gl.framebufferTexture2D(gl.FRAMEBUFFER, bufs[0], gl.TEXTURE_2D, texture1.__webglTexture, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, bufs[1], gl.TEXTURE_2D, texture2.__webglTexture, 0);
var FBOstatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if(FBOstatus != gl.FRAMEBUFFER_COMPLETE) {
console.log("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO[0]\n");
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
texture1.needsUpdate = true;
texture2.needsUpdate = true;
texture1.image = new Image();
texture2.image = new Image();
new THREE.ImageLoader().load(
'img/color0.png',
function ( image ) {
texture1.image = image;
texture2.image = image;
});
mat = new THREE.ShaderMaterial({
vertexShader: document.getElementById('vshader2').textContent,
fragmentShader: document.getElementById('fshader2').textContent,
uniforms: {
texture: {
type: 't', value: texture1
}
},
transparent: true,
needsUpdate:true,
});
var geometry = new THREE.PlaneGeometry( 100, 100, 10, 10 );
plane = new THREE.Mesh( geometry, mat );
plane.position.x = 100;
plane.rotation.x = 220 * ( Math.PI / 180 );
scene.add( plane );
setInterval(function(){
renderBuffer();
}, 500 );
}
function createTexture( gl, size, buf ){
var texture = new THREE.Texture();
texture.__webglTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture.__webglTexture );
texture.__webglInit = true;
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
switch( buf ){
case 0:
bufs[0] = ext.COLOR_ATTACHMENT0_WEBGL;
break;
case 1:
bufs[1] = ext.COLOR_ATTACHMENT1_WEBGL;
break;
case 2:
bufs[2] = ext.COLOR_ATTACHMENT2_WEBGL;
break;
case 3:
bufs[3] = ext.COLOR_ATTACHMENT3_WEBGL;
break;
}
gl.bindTexture( gl.TEXTURE_2D, null );
return texture;
}
function renderBuffer(){
//pass1
gl.bindFramebuffer(gl.FRAMEBUFFER, FBO[0]);
gl.viewport(0, 0, size, size);
renderer.render( scene, camera );
renderer.setSize(window.innerWidth,window.innerHeight);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
//pass2
mat.uniforms.texture2.value = texture2;
plane.material = mat;
renderer.render( scene, camera );
}