私は webgl を使用しています。私がやりたいことは、最初にテクスチャにレンダリングし、次にそのテクスチャを使用して画面にレンダリングすることです。最初のステップのレンダリングで属性に問題が発生します。
私がやろうとしていることを少しの言葉で説明しようと思います。最初に、フラグメント シェーダーを使用して属性を使用するテクスチャにレンダリングし、次にそのテクスチャを使用して画面にレンダリングし、次のフレームの手順を繰り返します。しかし、属性 (pos) が無効な値を持つフレーム バッファ バウンドでレンダリングしようとすると、値がまったくありません。
私の問題を示す小さなデモを書きました:
var canvas = document.getElementById("c");
var gl = getWebGLContext(canvas);
var program_init, program_pers, tex, fb;
function init() {
var verts = [
1, 1,
-1, 1,
-1, -1,
1, 1,
-1, -1,
1, -1,
];
var vertBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(0);
tex = gl.createTexture();
fb = gl.createFramebuffer();
program_init = createProgramFromScripts(gl, ["vshader-init", "fshader-init"], ["pos"]);
program_pers = createProgramFromScripts(gl, ["vshader-pers", "fshader-pers"], ["a_position"]);
}
function renderToTexture(gl, time) {
gl.useProgram(program_init);
var timeLocation = gl.getUniformLocation(program_init, 'time');
gl.uniform1f(timeLocation, time);
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
};
function renderToScreen(gl) {
gl.useProgram(program_pers);
gl.drawArrays(gl.TRIANGLES, 0, 6);
};
init();
requestAnimationFrame(function(){
renderToTexture(gl, arguments[0]);
renderToScreen(gl);
requestAnimationFrame( arguments.callee );
});
canvas { border: 1px solid black; }
body { background-color: darkslategrey }
<script src="http://greggman.github.com/webgl-fundamentals/webgl/resources/webgl-utils.js"></script>
<script id="vshader-init" type="vs/shader">
attribute vec4 pos;
varying vec2 uv;
void main() {
gl_Position = pos;
uv = pos.xy * .5 + .5;
}
</script>
<script id="fshader-init" type="fs/shader">
precision mediump float;
varying vec2 uv;
uniform float time;
void main() {
float t = floor(time / 1000.);
vec3 color;
color.x = sin(t*uv.x);
color.y = tan(t*uv.y);
color.z = cos(t);
gl_FragColor = vec4(color, 1.);
}
</script>
<script id="vshader-pers" type="vs/shader">
attribute vec4 a_position;
varying vec2 v_texcoord;
void main() {
gl_Position = a_position;
v_texcoord = a_position.xy * .5 + .5;
}
</script>
<script id="fshader-pers" type="fs/sahder">
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_sampler;
void main() {
gl_FragColor = texture2D(u_sampler, v_texcoord);
}
</script>
<body>
<canvas id="c" width="400" height="400"></canvas>
</body>
javascript コードの 38,39 行目 (frameBuffer のバインディング) と 54 行目 (別のプログラムを実行するスクリーン コードへのレンダリング) にコメントを付けると、正しくレンダリングされ、「pos」という名前が付けられていることがわかります。適切な値。
var canvas = document.getElementById("c");
var gl = getWebGLContext(canvas);
var program_init, program_pers, tex, fb;
function init() {
var verts = [
1, 1,
-1, 1,
-1, -1,
1, 1,
-1, -1,
1, -1,
];
var vertBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(0);
tex = gl.createTexture();
fb = gl.createFramebuffer();
program_init = createProgramFromScripts(gl, ["vshader-init", "fshader-init"], ["pos"]);
program_pers = createProgramFromScripts(gl, ["vshader-pers", "fshader-pers"], ["a_position"]);
}
function renderToTexture(gl, time) {
gl.useProgram(program_init);
var timeLocation = gl.getUniformLocation(program_init, 'time');
gl.uniform1f(timeLocation, time);
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
//gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
//gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
};
function renderToScreen(gl) {
gl.useProgram(program_pers);
gl.drawArrays(gl.TRIANGLES, 0, 6);
};
init();
requestAnimationFrame(function(){
renderToTexture(gl, arguments[0]);
//renderToScreen(gl);
requestAnimationFrame( arguments.callee );
});
canvas { border: 1px solid black; }
body { background-color: darkslategrey }
<script src="http://greggman.github.com/webgl-fundamentals/webgl/resources/webgl-utils.js"></script>
<script id="vshader-init" type="vs/shader">
attribute vec4 pos;
varying vec2 uv;
void main() {
gl_Position = pos;
uv = pos.xy * .5 + .5;
}
</script>
<script id="fshader-init" type="fs/shader">
precision mediump float;
varying vec2 uv;
uniform float time;
void main() {
float t = floor(time / 1000.);
vec3 color;
color.x = sin(t*uv.x);
color.y = tan(t*uv.y);
color.z = cos(t);
gl_FragColor = vec4(color, 1.);
}
</script>
<script id="vshader-pers" type="vs/shader">
attribute vec4 a_position;
varying vec2 v_texcoord;
void main() {
gl_Position = a_position;
v_texcoord = a_position.xy * .5 + .5;
}
</script>
<script id="fshader-pers" type="fs/shader">
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_sampler;
void main() {
gl_FragColor = texture2D(u_sampler, v_texcoord);
}
</script>
<body>
<canvas id="c" width="400" height="400"></canvas>
</body>
私はそれがどのように機能するのかについてあまり知りません。私は少し暗闇の中にいます。何か重要なものが欠けていると確信していますが、どこにも何が見つかりません。どんな助けでも大歓迎です。