看起来这应该很简单,但是我使用点精灵的部分纹理有很多困难.我已经广泛浏览了各种各样的答案,但这些都没有处理我遇到的具体问题.
到目前为止我学到了什么
> Basics of point sprite drawing
> How to deal with point sprites rendering as solid squares
> How to alter orientation of a point sprite
> How to use multiple textures with a point sprite,越来越近了..
>这个sprite sprite sheet之前已经完成了,但只能在OpenGL ES 2.0(不是1.0)
这是我想要实现的图表
我在哪里
>我有一组工作点精灵都使用相同的单个方形图像.例如:一个16×16的圆形图像很棒.
>我有一个Objective-C方法,它生成一个含有多个图像的精灵图的600×600图像.我已经验证这是通过将整个sprite sheet图像应用于使用GL_TRIANGLES绘制的四元组.
>我已经使用上述方法成功地将精灵图的部分绘制到四边形.我只是不能让它与点精灵一起工作.
>目前,我正在生成纹理坐标,指向我所针对的精灵图片上精灵的中心.例如:使用底部的图像;星:0.166,0.5;云:0.5,0.5;心脏:0.833,0.5.
码:
顶点着色器
uniform mat4 Projection; uniform mat4 Modelview; uniform float PointSize; attribute vec4 Position; attribute vec2 TextureCoordIn; varying vec2 TextureCoord; void main(void) { gl_Position = Projection * Modelview * Position; TextureCoord = TextureCoordIn; gl_PointSize = PointSize; }
片段着色器
varying mediump vec2 TextureCoord; uniform sampler2D Sampler; void main(void) { // Using my TextureCoord just draws a grey square,so // I'm likely generating texture coords that texture2D doesn't like. gl_FragColor = texture2D(Sampler,TextureCoord); // Using gl_PointCoord just draws my whole sprite map // gl_FragColor = texture2D(Sampler,gl_PointCoord); }
我坚持的是什么
>我不明白如何在片段着色器中使用gl_PointCoord变量. gl_PointCoord最初包含什么?为什么?它在哪里获取其数据?
>我不明白要传递什么纹理坐标.例如,点精灵如何根据纹理坐标选择我的sprite sheet的哪一部分?我习惯于绘制有效的4组纹理坐标(每个顶点一个)的四边形,这有什么不同(显然是)?
解决方法
我的一位同事答复了.事实证明,诀窍是利用点的大小(在OpenGL单元中)和精灵的大小(以纹理单位,(0..1))结合一点向量数学,仅渲染一部分精灵片到每个点.
顶点着色器
uniform mat4 Projection; uniform mat4 Modelview; // The radius of the point in OpenGL units,eg: "20.0" uniform float PointSize; // The size of the sprite being rendered. My sprites are square // so I'm just passing in a float. For non-square sprites pass in // the width and height as a vec2. uniform float TextureCoordPointSize; attribute vec4 Position; attribute vec4 ObjectCenter; // The top left corner of a given sprite in the sprite-sheet attribute vec2 TextureCoordIn; varying vec2 TextureCoord; varying vec2 TextureSize; void main(void) { gl_Position = Projection * Modelview * Position; TextureCoord = TextureCoordIn; TextureSize = vec2(TextureCoordPointSize,TextureCoordPointSize); // This is optional,it is a quick and dirty way to make the points stay the same // size on the screen regardless of distance. gl_PointSize = PointSize / Position.w; }
片段着色器
varying mediump vec2 TextureCoord; varying mediump vec2 TextureSize; uniform sampler2D Sampler; void main(void) { // This is where the magic happens. Combine all three factors to render // just a portion of the sprite-sheet for this point mediump vec2 realTexCoord = TextureCoord + (gl_PointCoord * TextureSize); mediump vec4 fragColor = texture2D(Sampler,realTexCoord); // Optional,emulate GL_ALPHA_TEST to use transparent images with // point sprites without worrying about z-order. // see: https://stackoverflow.com/a/5985195/806988 if(fragColor.a == 0.0){ discard; } gl_FragColor = fragColor; }