How stencil buffer and masking work? - webgl - Stack Overflow
文章推薦指數: 80 %
Your program works absolute correctly, but you have to tell the getContext function to create a stencil buffer, when the context is created:
2022DeveloperSurveyisopen!Takesurvey.
Home
Public
Questions
Tags
Users
Companies
Collectives
ExploreCollectives
Teams
StackOverflowforTeams
–Startcollaboratingandsharingorganizationalknowledge.
CreateafreeTeam
WhyTeams?
Teams
CreatefreeTeam
Collectives™onStackOverflow
Findcentralized,trustedcontentandcollaboratearoundthetechnologiesyouusemost.
Learnmore
Teams
Q&Aforwork
Connectandshareknowledgewithinasinglelocationthatisstructuredandeasytosearch.
Learnmore
Howstencilbufferandmaskingwork?
AskQuestion
Asked
4years,7monthsago
Modified
1yearago
Viewed
4ktimes
8
3
Iwanttodrawobjectinjustspecificarea.Pleasetakealookthisimageforreference
The2triangles(pictureA)beingdrawjustintheareainsidethequad(pictureB),sotheresultwilllookclipped(pictureC).
Firstidrawthequadjustinstencilbuffer.
gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
gl.stencilFunc(gl.ALWAYS,1,0xff);
gl.stencilMask(0xff);
gl.depthMask(false);
gl.colorMask(false,false,false,false);
drawQuads();
inmyunderstanding,nowthestencilbufferhasvalue1sinthequadarea.Then,drawthetriangles.
gl.stencilFunc(gl.EQUAL,1,0xff);
gl.stencilMask(0x00);
gl.depthMask(true);
gl.colorMask(true,true,true,true);
drawTriagles();
Iwasexpecttheresultwillbelikeonthepicture(C),butit'snot.WhatIamdoingwrong?
Pleasefindthecompletecodeherehttps://jsfiddle.net/z11zhf01/1
webglwebgl2stencil-buffer
Share
Improvethisquestion
Follow
editedMay15,2021at10:14
Rabbid76
176k2525goldbadges101101silverbadges145145bronzebadges
askedOct18,2017at8:42
janucariajanucaria
19122silverbadges1212bronzebadges
Addacomment
|
1Answer
1
Sortedby:
Resettodefault
Highestscore(default)
Datemodified(newestfirst)
Datecreated(oldestfirst)
12
Yourprogramworksabsolutecorrectly,butyouhavetotellthegetContextfunctiontocreateastencilbuffer,whenthecontextiscreated:
gl=glcanvas.getContext("webgl",{stencil:true});
SeeKhronosWebGLSpecification-WebGLContextAttributes:
stencil
Ifthevalueistrue,thedrawingbufferhasastencilbufferofatleast8bits.Ifthevalueisfalse,nostencilbufferisavailable.
SeetheExample:
(function(){
vargl;
vargProgram;
vargVertexAttribLocation;
vargColorAttribLocation;
vargTriangleVertexBuffer;
vargTriangleColorBuffer;
vargQuadVertexBuffer;
vargQuadColorBuffer;
functioninitGL(){
varglcanvas=document.getElementById("glcanvas");
gl=glcanvas.getContext("webgl",{stencil:true});
}
functioncreateAndCompileShader(type,source){
varshader=gl.createShader(type);
gl.shaderSource(shader,source);
gl.compileShader(shader);
if(!gl.getShaderParameter(shader,gl.COMPILE_STATUS)){
thrownewError(gl.getShaderInfoLog(shader));
}
returnshader;
}
functioncreateAndLinkProgram(glVertexShader,glFragmentShader){
varglProgram=gl.createProgram();
gl.attachShader(glProgram,glVertexShader);
gl.attachShader(glProgram,glFragmentShader);
gl.linkProgram(glProgram);
if(!gl.getProgramParameter(glProgram,gl.LINK_STATUS)){
thrownewError("Couldnotinitialiseshaders");
}
returnglProgram;
}
functioninitShaderPrograms(){
vargVertexShader=createAndCompileShader(gl.VERTEX_SHADER,[
"attributevec3a_vertex;",
"attributevec4a_color;",
"varyingvec4v_color;",
"voidmain(void){",
"v_color=a_color;",
"gl_Position=vec4(a_vertex,1.0);",
"}"
].join("\n"));
vargFragmentShader=createAndCompileShader(gl.FRAGMENT_SHADER,[
"precisionmediumpfloat;",
"varyingvec4v_color;",
"voidmain(void){",
"gl_FragColor=v_color;",
"}"
].join("\n"));
gProgram=createAndLinkProgram(gVertexShader,gFragmentShader);
}
functioninitGLAttribLocations(){
gVertexAttribLocation=gl.getAttribLocation(gProgram,"a_vertex");
gColorAttribLocation=gl.getAttribLocation(gProgram,"a_color");
}
functioninitBuffers(){
gTriangleVertexBuffer=gl.createBuffer();
gTriangleColorBuffer=gl.createBuffer();
gQuadVertexBuffer=gl.createBuffer();
gQuadColorBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,gTriangleVertexBuffer);
varvertices=newFloat32Array([
0.0,1.0,0.0,
-1.0,-1.0,0.0,
1.0,-1.0,0.0,
0.0,-1.0,0.0,
-1.0,1.0,0.0,
1.0,1.0,0.0
]);
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER,gTriangleColorBuffer);
varcolors=newFloat32Array([
0.0,1.0,0.0,1.0,
0.0,1.0,0.0,1.0,
0.0,1.0,0.0,1.0,
0.0,0.0,1.0,1.0,
0.0,0.0,1.0,1.0,
0.0,0.0,1.0,1.0
]);
gl.bufferData(gl.ARRAY_BUFFER,colors,gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER,gQuadVertexBuffer);
varvertices=newFloat32Array([
-1.0,1.0,0.0,
-1.0,-1.0,0.0,
1.0,1.0,0.0,
1.0,-1.0,0.0
]);
for(leti=0,ii=vertices.length;i
延伸文章資訊
- 1WebGL绘制详解之五:Stencil Buffer | JZ's Blog
WebGL中的stencil buffer(模板缓冲区)的作用也是类似的,可以在Buffer中指定一个形状作为模板,接着通过stencil test(模板测试)过程让位于形状 ...
- 2WebGLRenderingContext.stencilFunc() - Web APIs | MDN
The WebGLRenderingContext.stencilFunc() method of the WebGL API sets the front and back function ...
- 3WebGLRenderingContext.stencilOp() - Web APIs | MDN
The WebGLRenderingContext.stencilOp() method of the WebGL API sets both the front and back-facing...
- 4How to use the stencil buffer - WebGL Fundamentals
How I can use to stencil buffer for my easiest program? ... To use the stencil buffer you have to...
- 5WebGL.Settings.StencilTest - Elm Packages
When you need to draw an intercection of two entities, e.g. a reflection in the mirror, you can t...