2017-10-19 4 views
1

스텐실을 사용하여 오브젝트를 그리려하고 모든 것이 정상적으로 작동합니다. 아래는 내가 기대했던 작업 결과의 애니메이션 프레임 (왼쪽에서 오른쪽)의 그림입니다. expected resultWebGL : 심도 스텐실 텍스처 첨부 파일이있는 프레임 버퍼에서 색상이 지워지지 않았습니다.

프레임 버퍼를 사용할 때 문제가 발생합니다. 내가 아는 바로는, WebGL 1.0은 깊이와 렌더링 버퍼 나 텍스처의 스텐실을 따로 따로 붙이는 것을 지원하지 않습니다. 스텐실과 깊이를 WEBGL_depth_texture 확장자를 통해 서로 붙여서 수행 할 수 있습니다. 나는 그 확장을 사용하고 있으며, 프레임 버퍼를 사용하고, 객체를 그리지 만, 그 결과는 색깔이 분명하지 않은 것처럼 보입니다. 아래는 결과의 애니메이션 프레임 사진입니다.

enter image description here

은 누군가가 일어나고 무엇을 설명 할 수 있습니까?

아래의 전체 코드를 찾아보십시오.

(function() { 
 
var gl; 
 
var dtExt; 
 

 
var gProgram; 
 
var gRectShader; 
 

 
var gVertexAttribLocation; 
 
var gColorAttribLocation; 
 

 
var gRectVertexAttribLocation; 
 
var gRectTexcoordAttribLocation; 
 

 
var gModelViewMatrixUniform; 
 

 
var gTriangleVertexBuffer; 
 
var gTriangleColorBuffer; 
 
var gQuadVertexBuffer; 
 
var gQuadColorBuffer; 
 
var gQuadTexcoordBuffer; 
 

 
var gFramebuffer; 
 

 
var gColorTexture; 
 
var gDepthStencilTexture; 
 

 
var rotationMatrix = mat4.create(); 
 

 
function initGL() { 
 
\t var glcanvas = document.getElementById("glcanvas"); 
 
\t gl = glcanvas.getContext("webgl", {stencil:true}); 
 
\t dtExt = gl.getExtension('WEBGL_depth_texture') || gl.getExtension('WEBKIT_WEBGL_depth_texture') || gl.getExtension('MOZ_WEBGL_depth_texture'); 
 
} 
 

 
function initFramebuffers() { 
 
\t gFramebuffer = gl.createFramebuffer(); 
 

 
\t gl.bindFramebuffer(gl.FRAMEBUFFER, gFramebuffer); 
 

 
\t gl.bindTexture(gl.TEXTURE_2D, gColorTexture); 
 
\t gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, gColorTexture, 0); 
 

 
\t gl.bindTexture(gl.TEXTURE_2D, gDepthStencilTexture); 
 
\t gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, gDepthStencilTexture, 0); 
 

 
\t gl.bindTexture(gl.TEXTURE_2D, null); 
 
\t gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
 
} 
 

 
function createTexture() { 
 
\t var texture = gl.createTexture(); 
 

 
\t gl.bindTexture(gl.TEXTURE_2D, texture); 
 
\t gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
 
\t gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 
 
\t gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 
 
\t gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 
 
\t gl.bindTexture(gl.TEXTURE_2D, null); 
 

 
\t return texture; 
 
} 
 

 
function initTextures() { 
 
\t gColorTexture = createTexture(); 
 
\t gl.bindTexture(gl.TEXTURE_2D, gColorTexture); 
 
\t gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 
 

 
\t gDepthStencilTexture = createTexture(); 
 
\t gl.bindTexture(gl.TEXTURE_2D, gDepthStencilTexture); 
 
\t gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_STENCIL, gl.drawingBufferWidth, gl.drawingBufferHeight, 0, gl.DEPTH_STENCIL, dtExt.UNSIGNED_INT_24_8_WEBGL, null); 
 
\t 
 
\t gl.bindTexture(gl.TEXTURE_2D, null); 
 
} 
 

 
function createAndCompileShader(type, source) { 
 
\t var shader = gl.createShader(type); 
 

 
\t gl.shaderSource(shader, source); 
 
\t gl.compileShader(shader); 
 

 
\t if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 
 
\t \t throw new Error(gl.getShaderInfoLog(shader)); 
 
\t } 
 

 
\t return shader; 
 
} 
 

 
function createAndLinkProgram(glVertexShader, glFragmentShader) { 
 
\t var glProgram = gl.createProgram(); 
 

 
\t gl.attachShader(glProgram, glVertexShader); 
 
\t gl.attachShader(glProgram, glFragmentShader); 
 
\t gl.linkProgram(glProgram); 
 

 
\t if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) { 
 
\t  throw new Error("Could not initialise shaders"); 
 
\t } 
 

 
\t return glProgram; 
 
} 
 

 
function initShaderPrograms() { 
 
\t var gVertexShader = createAndCompileShader(gl.VERTEX_SHADER, [ 
 
\t \t "attribute vec3 a_vertex;", 
 
\t \t "attribute vec4 a_color;", 
 

 
\t \t "uniform mat4 u_modelViewMatrix;", 
 

 
\t \t "varying vec4 v_color;", 
 

 
\t \t "void main(void) {", 
 
\t \t \t "v_color = a_color;", 
 
\t \t \t "gl_Position = u_modelViewMatrix * vec4(a_vertex, 1.0);", 
 
\t \t "}" 
 
\t ].join("\n")); 
 

 
\t var gFragmentShader = createAndCompileShader(gl.FRAGMENT_SHADER, [ 
 
\t \t "precision mediump float;", 
 

 
\t \t "varying vec4 v_color;", 
 
\t \t "void main(void) {", 
 
\t \t \t "gl_FragColor = v_color;", 
 
\t \t "}" 
 
\t ].join("\n")); 
 

 
\t gProgram = createAndLinkProgram(gVertexShader, gFragmentShader); 
 

 
\t var gVertexShader = createAndCompileShader(gl.VERTEX_SHADER, [ 
 
\t \t "attribute vec3 a_vertex;", 
 
\t \t "attribute vec2 a_texcoord;", 
 

 
\t \t "varying vec2 v_texcoord;", 
 

 
\t \t "void main(void) {", 
 
\t \t \t "v_texcoord = a_texcoord;", 
 
\t \t \t "gl_Position = vec4(a_vertex, 1.0);", 
 
\t \t "}" 
 
\t ].join("\n")); 
 

 
\t var gFragmentShader = createAndCompileShader(gl.FRAGMENT_SHADER, [ 
 
\t \t "precision mediump float;", 
 

 
\t  "uniform sampler2D u_sampler0;", 
 

 
\t \t "varying vec2 v_texcoord;", 
 
\t \t "void main(void) {", 
 
\t \t \t "gl_FragColor = texture2D(u_sampler0, v_texcoord);", 
 
\t \t "}" 
 
\t ].join("\n")); 
 

 
\t gRectShader = createAndLinkProgram(gVertexShader, gFragmentShader); 
 
} 
 

 
function initAttribAndUniformLocations() { 
 
\t gVertexAttribLocation = gl.getAttribLocation(gProgram, "a_vertex"); 
 
\t gColorAttribLocation = gl.getAttribLocation(gProgram, "a_color"); 
 
\t gModelViewMatrixUniform = gl.getUniformLocation(gProgram, 'u_modelViewMatrix'); 
 

 
\t gRectVertexAttribLocation = gl.getAttribLocation(gRectShader, "a_vertex"); 
 
\t gRectTexcoordAttribLocation = gl.getAttribLocation(gRectShader, "a_texcoord"); 
 
} 
 

 
function initBuffers() { 
 
\t gTriangleVertexBuffer = gl.createBuffer(); 
 
\t gTriangleColorBuffer = gl.createBuffer(); 
 
\t gQuadVertexBuffer = gl.createBuffer(); 
 
\t gQuadColorBuffer = gl.createBuffer(); 
 
\t gQuadTexcoordBuffer = gl.createBuffer(); 
 

 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gTriangleVertexBuffer); 
 
\t var vertices = new Float32Array([ 
 

 
\t  0.0, -1.0, 0.0, 
 
\t  -1.0, 1.0, 0.0, 
 
\t  1.0, 1.0, 0.0, 
 

 
\t  0.0, 1.0, 0.0, 
 
\t  -1.0, -1.0, 0.0, 
 
\t  1.0, -1.0, 0.0, 
 
\t ]); 
 
\t gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); 
 

 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gTriangleColorBuffer); 
 
\t var colors = new Float32Array([ 
 
\t  0.0, 1.0, 0.0, 1.0, 
 
\t  0.0, 1.0, 0.0, 1.0, 
 
\t  0.0, 1.0, 0.0, 1.0, 
 

 
\t  0.0, 0.0, 1.0, 1.0, 
 
\t  0.0, 0.0, 1.0, 1.0, 
 
\t  0.0, 0.0, 1.0, 1.0 
 
\t ]); 
 
\t gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); 
 

 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gQuadVertexBuffer); 
 
\t var vertices = new Float32Array([ 
 
\t  -1.0, 1.0, 0.0, 
 
\t  -1.0, -1.0, 0.0, 
 
\t  1.0, 1.0, 0.0, 
 
\t  1.0, -1.0, 0.0 
 
\t ]); 
 
\t gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); 
 

 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gQuadColorBuffer); 
 
\t var colors = new Float32Array([ 
 
\t  1.0, 0.0, 0.0, 1.0, 
 
\t  1.0, 0.0, 0.0, 1.0, 
 
\t  1.0, 0.0, 0.0, 1.0, 
 
\t  1.0, 0.0, 0.0, 1.0 
 
\t ]); 
 
\t gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); 
 

 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gQuadTexcoordBuffer); 
 
\t var texcoords = new Float32Array([ 
 
\t  0.0, 1.0, 
 
\t  0.0, 0.0, 
 
\t  1.0, 1.0, 
 
\t  1.0, 0.0 
 
\t ]); 
 
\t gl.bufferData(gl.ARRAY_BUFFER, texcoords, gl.STATIC_DRAW); 
 

 
} 
 

 
function drawQuads() { 
 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gQuadVertexBuffer); 
 
\t gl.vertexAttribPointer(gVertexAttribLocation, 3, gl.FLOAT, false, 0, 0); 
 

 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gQuadColorBuffer); 
 
\t gl.vertexAttribPointer(gColorAttribLocation, 4, gl.FLOAT, false, 0, 0); 
 

 
\t gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 
 
} 
 

 
function drawRectQuads() { 
 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gQuadVertexBuffer); 
 
\t gl.vertexAttribPointer(gRectVertexAttribLocation, 3, gl.FLOAT, false, 0, 0); 
 

 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gQuadTexcoordBuffer); 
 
\t gl.vertexAttribPointer(gRectTexcoordAttribLocation, 2, gl.FLOAT, false, 0, 0); 
 

 
\t gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 
 
} 
 

 
function drawTriagles() { 
 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gTriangleVertexBuffer); 
 
\t gl.vertexAttribPointer(gVertexAttribLocation, 3, gl.FLOAT, false, 0, 0); 
 

 
\t gl.bindBuffer(gl.ARRAY_BUFFER, gTriangleColorBuffer); 
 
\t gl.vertexAttribPointer(gColorAttribLocation, 4, gl.FLOAT, false, 0, 0); 
 

 
\t gl.drawArrays(gl.TRIANGLES, 0, 6); 
 
} 
 

 

 
function renderScene() { 
 
\t var mvMatrix = mat4.create(); 
 

 
\t gl.clearColor(0.5, 0.5, 0.5, 1.0); 
 

 
\t gl.bindFramebuffer(gl.FRAMEBUFFER, gFramebuffer); 
 
\t gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 
 
\t gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 
 

 
\t gl.enable(gl.STENCIL_TEST); 
 
\t gl.enable(gl.DEPTH_TEST); 
 
\t gl.enable(gl.CULL_FACE); 
 

 
\t gl.clear(gl.STENCIL_BUFFER_BIT); 
 

 
\t gl.useProgram(gProgram); 
 

 
\t gl.enableVertexAttribArray(gVertexAttribLocation); 
 
\t gl.enableVertexAttribArray(gColorAttribLocation); 
 

 
\t gl.disable(gl.DEPTH_TEST); 
 
\t gl.colorMask(false, false, false, false); 
 

 
\t gl.stencilFunc(gl.ALWAYS, 0, 0xff); 
 
\t gl.stencilMask(0xff); 
 
\t gl.stencilOpSeparate(gl.BACK, gl.KEEP, gl.KEEP, gl.INCR); 
 
\t gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.KEEP, gl.DECR); 
 

 
\t mat4.identity(mvMatrix); 
 
\t mat4.scale(mvMatrix, mvMatrix, [0.5, 0.5, 0.5]); 
 
\t mat4.multiply(mvMatrix, mvMatrix, rotationMatrix); 
 

 
\t gl.uniformMatrix4fv(gModelViewMatrixUniform, false, mvMatrix); 
 

 
\t gl.cullFace(gl.FRONT); 
 
\t drawTriagles(); 
 

 
\t gl.cullFace(gl.BACK); 
 
\t drawTriagles(); 
 

 
\t gl.stencilMask(0x00); 
 
\t gl.stencilFunc(gl.NOTEQUAL, 0, 0xff); 
 

 
\t gl.enable(gl.DEPTH_TEST); 
 
\t gl.colorMask(true, true, true, true); 
 

 
\t mat4.identity(mvMatrix); 
 
\t mat4.scale(mvMatrix, mvMatrix, [0.75, 0.75, 0.75]); 
 

 
\t gl.uniformMatrix4fv(gModelViewMatrixUniform, false, mvMatrix); 
 

 
\t drawQuads(); 
 

 
\t gl.disableVertexAttribArray(gVertexAttribLocation); 
 
\t gl.disableVertexAttribArray(gColorAttribLocation); 
 

 
\t gl.flush(); 
 

 
\t gl.disable(gl.STENCIL_TEST); 
 

 
\t gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
 
\t gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); 
 
\t gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); 
 

 
\t gl.enable(gl.DEPTH_TEST); 
 

 
\t gl.bindTexture(gl.TEXTURE_2D, gColorTexture); 
 

 
\t gl.useProgram(gRectShader); 
 

 
\t gl.enableVertexAttribArray(gRectVertexAttribLocation); 
 
\t gl.enableVertexAttribArray(gRectTexcoordAttribLocation); 
 

 
\t drawRectQuads(); 
 

 
\t gl.disableVertexAttribArray(gRectVertexAttribLocation); 
 
\t gl.disableVertexAttribArray(gRectTexcoordAttribLocation); 
 

 
\t gl.flush(); 
 
} 
 

 
function step(timestamp) { 
 
\t renderScene(); 
 

 
\t mat4.rotate(rotationMatrix, rotationMatrix, Math.PI/360, [0, 0, 1]) 
 

 
    window.requestAnimationFrame(step); 
 
} 
 

 
initGL(); 
 
initShaderPrograms(); 
 
initAttribAndUniformLocations(); 
 
initTextures(); 
 
initFramebuffers(); 
 
initBuffers(); 
 
window.requestAnimationFrame(step); 
 

 
}());
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.4.0/gl-matrix-min.js"></script> 
 

 
<canvas id="glcanvas" width="480" height="360"> 
 
\t \t WebGL not supported! 
 
</canvas>

답변

1

당신은 당신이 스텐실 버퍼를

gl.stencilMask(0xff); 

을 취소하기 전에 또한, 당신은 단지 프레임 버퍼에 대한 깊이 + 스텐실 첨부 파일을 만들 WEBGL_depth_texture 필요하지 않습니다 스텐실 마스크를 설정해야합니다. 당신은 아마 당신에게 많은 시간을 절약 할 수 또한

const rb = gl.createRenderbuffer(); 
gl.bindRenderbuffer(gl.RENDERBUFFER, rb); 
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); 
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rb); 

multiline template literals renderbuffer DEPTH_STENCIL를 사용할 수 있습니다.

또한 gl.flush에는 코드가 없습니다.