作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
用three.js,我想延迟着色,但是效果不好。它不接收 gl_fragData 的值。你要么知道有人解决方案。
一个
着色器代码
//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>
主程序。它是three.js和webgl代码的结合。
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 );
}
最佳答案
必须启用 WEBGL_draw_buffers
扩展才能使用执行延迟着色所需的多个渲染目标。否则帧缓冲区只能有一种颜色附件。
关于javascript - three.js 上的延迟着色。使用 gl_fragData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31769959/
我在尝试编译片段着色器时遇到问题。我不断收到此错误: Uncaught Error: Fragment Shader Compiler Error: ERROR: 0:21: '[' : array
从我在网上看到的几个例子来看,gl_FragData[0] 被假定为一个颜色缓冲区。我试图找到gl_FragData中每个索引的含义,并从OpenGL Shading language book(橙皮
正如 jar 头上所说:是否有任何理由使用 gl_FragColor 而不是 gl_FragData[0]?如果不是,那么为什么gl_FragColor存在呢?它仅仅是 gl_FragData 不存在
用three.js,我想延迟着色,但是效果不好。它不接收 gl_fragData 的值。你要么知道有人解决方案。 一个 着色器代码 //shader1 #extension GL_EXT_draw_
我是一名优秀的程序员,十分优秀!