我只是对使用c ++的opengl进行的游戏有一个想法:当玩家赢得某些东西时,我希望在多个重叠的物体上有一个大轮廓(5-6像素)。
我以为最好的方法是使用模板缓冲区,但是尝试在屏幕外渲染模板缓冲区需要几个小时,而且我无法获得任何结果。还有其他一些技巧!
这就是我想要得到的:
有任何想法吗?
我只是对使用c ++的opengl进行的游戏有一个想法:当玩家赢得某些东西时,我希望在多个重叠的物体上有一个大轮廓(5-6像素)。
我以为最好的方法是使用模板缓冲区,但是尝试在屏幕外渲染模板缓冲区需要几个小时,而且我无法获得任何结果。还有其他一些技巧!
这就是我想要得到的:
有任何想法吗?
Answers:
这是从我正在使用的一些webGL模具代码改编而成的代码:
// drawing will set stencil stencil
gl.enable(gl.STENCIL_TEST);
gl.stencilFunc(gl.ALWAYS,1,1);
gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
gl.stencilMask(1);
gl.clearStencil(0);
gl.clear(gl.STENCIL_BUFFER_BIT);
// draw objects
for(var object in objects)
objects[object].draw();
// set stencil mode to only draw those not previous drawn
gl.stencilFunc(gl.EQUAL,0,1);
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
gl.stencilMask(0x00);
// draw object halo
for(var object in objects)
objects[object].drawHalo(1.1,red); // each mesh should be individually scaled e.g. by 1.1
// done
gl.disable(gl.STENCIL_TEST);
我想我已经在RTS游戏中使用了这种方法来在选定的单位周围绘制光晕,但是那是很久以前的事了,我不记得是否有任何陷阱和所有细微差别。
首先找到所有对象组,其中一组对象是重叠的对象的集合。标准碰撞检测应能胜任。为每个组分配唯一的颜色。任何颜色都可以。
使用组色将所有对象渲染为纯色,以形成纹理。
创建一个具有与渲染目标相同尺寸的新轮廓纹理。扫描渲染目标的每个纹理像素,并确定其颜色是否与周围的任何纹理像素不同。如果是这样,请将轮廓纹理中的相应纹理像素更改为所需的线条颜色。
最后,获取轮廓纹理并将其渲染到要在屏幕上绘制的图像上方(您当然可以在片段着色器中进行边缘检测的同时进行此操作,避免在第一个着色器中创建边缘纹理地点)。
如果您通过使用for循环在渲染目标上执行texel在cpu上执行此步骤,那么这将非常慢,但可能足以测试甚至在某些情况下使用。要实时使用它,最好在着色器中处理它。
用于执行边缘检测的片段着色器可能如下所示:
precision mediump float;
uniform sampler2D s_texture;
varying vec2 v_texCoord;
void main()
{
gl_FragColor = vec4(0.0);
vec4 baseColor = texture2D(s_texture, v_texCoord);
gl_FragColor += baseColor - texture2D(s_texture, top);
gl_FragColor += baseColor - texture2D(s_texture, topRight);
gl_FragColor += baseColor - texture2D(s_texture, right);
gl_FragColor += baseColor - texture2D(s_texture, bottomRight);
gl_FragColor += baseColor - texture2D(s_texture, bottom);
gl_FragColor += baseColor - texture2D(s_texture, bottomLeft);
gl_FragColor += baseColor - texture2D(s_texture, left);
gl_FragColor += baseColor - texture2D(s_texture, topLeft);
}
在texture2D中查找的第二个值是相对于v_texCoord的2d坐标。您可以通过在全屏四边形上将第一个渲染目标渲染为纹理来应用此效果。这类似于您应用全屏模糊效果(如高斯模糊)的方式。
将第一个渲染目标使用纯色的原因只是为了确保重叠的不同对象之间没有可察觉的边缘。如果仅在屏幕图像上执行边缘检测,则可能会发现它也检测重叠处的边缘(假设对象具有不同的颜色/纹理/照明)。