Jam*_*res 13 opengl-es glsl ios opengl-es-2.0
看起来这应该很简单,但是使用点精灵的部分纹理我遇到了很多困难.我已经广泛搜索并提出了各种答案,但这些都没有解决我遇到的具体问题.
到目前为止我学到了什么:
这是我想要实现的图表

我在哪里:
码:
顶点着色器
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;
}
Run Code Online (Sandbox Code Playgroud)
片段着色器
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);
}
Run Code Online (Sandbox Code Playgroud)
我坚持的是:
gl_PointCoord在片段着色器中使用该变量.gl_PointCoord最初包含什么?为什么?它从何处获取数据?Jam*_*res 11
我的一位同事帮助解决了问题.事实证明,诀窍是利用点的大小(以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;
}
Run Code Online (Sandbox Code Playgroud)
片段着色器
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: http://stackoverflow.com/a/5985195/806988
if(fragColor.a == 0.0){
discard;
}
gl_FragColor = fragColor;
}
Run Code Online (Sandbox Code Playgroud)
点精灵由一个位置组成。因此,任何“可变”值实际上都不会变化,因为之间没有可插值的内容。
gl_PointCoord是vec2XY值介于[0,1]之间的值。它们代表该点的位置。(0,0)是该点的左下角,而(1,1)是该点的右上角。
因此,您想将(0,0)映射到精灵的左下角,并将(1,1)映射到右上角。要做到这一点,你需要知道的一些事情:精灵的尺寸(假设他们都是一样的大小),纹理的大小(因为纹理拾取功能,采取规范化的纹理坐标,而不是像素位置),以及其目前正在渲染精灵。
后者可以通过设置varying。它可以是作为每个顶点数据传递到varying顶点着色器中的值。
您可以使用该值加上子画面的大小来确定要在该纹理中提取该子画面数据的位置。拥有要使用的纹理像素坐标后,将其除以纹理大小即可生成标准化的纹理坐标。
无论如何,点精灵(尽管名称)实际上并不是用于精灵渲染的。为此,使用四边形/三角形会更容易,因为您可以更加准确地确定所有物体的位置。
| 归档时间: |
|
| 查看次数: |
8798 次 |
| 最近记录: |