Texture mapping of non-rectangle textures - how to get the color of a specific texel - opengl-es

I'm trying to convert a shader wich is written using GLSL version 120 into OpenGl ES 2.0 and I came to a problem on how to map this shader correctly.
On the original shader, I'm using texture2DRect and this is not supported on OpenGL ES ( at least not on the target hardware I'm aming for).
The shader has two textures. One is a texture mapped to a quad, the other one is simply a kind of lookup I use to multiply the texel. The lookup is a 128x128 bitmap.
The original shader looks like this:
float xx = mod(gl_FragCoord.x, 5.0);
float yy = mod(gl_FragCoord.y, 15.0);
vec4 color = texture2DRect(tex0, coord0);
vec4 lookup1 = texture2DRect(tex1, vec2(xx, yy));
gl_FragColor = color * lookup1;
I've changed it to:
float xx = mod(gl_FragCoord.x, 5.0) * (1.0/textsize.x);
float yy = mod(gl_FragCoord.y, 15.0) * (1.0/textsize.y);
vec4 color = texture2D(tex0, coord0);
vec4 lookup1 = texture2D(tex1, vec2(xx, yy));
gl_FragColor = color * lookup1;
Where textsize is a vec2 containing the lookup texture size (128x128)
I need the exact value of the texel at let's say 50,127 on the lookup. I imagined that this should be (50/128, 127/128). This is however not working as I've expected. What am I missing here?
Additional Information:
Texture parameters:
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE)
Texture declarations:
uniform samplerExternalOES tex0;
uniform sampler2D tex1;
update 2013.03.13:
I've implemented now the following function:
vec4 texelFetch(sampler2D texsampler, vec2 coord) {
vec2 mult=(2.0*coord + 1.0)/(2.0* texWidth); // 128.0
vec4 texel = texture2D(texsampler,mult);
return texel;
}
And changed the code to:
float xx = mod(gl_FragCoord.x, 5.0);
float yy = mod(gl_FragCoord.y, 15.0);
vec4 lookup1 = texelFetch(tex1, vec2(xx, yy));
Still, it does not seems to be working.

Related

Using GL_TEXTURE_EXTERNAL_OES in OpenGLES 3.x for ArCore

I try to render the ArFrame into a render target using OpenGLES 3.2. The ArCore example shows the usage of GLES2 but inside GLES3 the extension is not available. Now I have found the extension GL_OES_EGL_image_external_essl3 to use samplerExternalOES. Therefore I have included gl3.h and the gl2ext.h.
The creation of the texture is similar to the ArCore example:
glGenTextures(1, &g_TextureID);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, g_TextureID);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
ArSession_setCameraTextureName(m_pARSession, g_TextureID);
Inside the rendering loop:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, g_TextureID);
My shaders look like this:
constexpr char kVertexShader[] = R"(
#version 320 es
layout(location = 0) in vec2 in_UV;
layout(location = 0) out vec2 out_UV;
void main()
{
vec2 Vertices[4];
Vertices[0] = vec2(-1.0f, -1.0f);
Vertices[1] = vec2( 1.0f, -1.0f);
Vertices[2] = vec2(-1.0f, 1.0f);
Vertices[3] = vec2( 1.0f, 1.0f);
out_UV = in_UV;
gl_Position = vec4(Vertices[gl_VertexID], 0.0f, 1.0f);
}
)";
constexpr char kFragmentShader[] = R"(
#version 320 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;
layout(location = 0) uniform samplerExternalOES in_ExtOESTexture;
layout(location = 0) in vec2 in_UV;
layout(location = 0) out vec4 out_Output;
void main()
{
out_Output = texture(in_ExtOESTexture, in_UV); //vec4(in_UV, 0, 1);
}
)";
Rendering only the in_UV with out_Output = vec4(in_UV, 0, 1);, the result is a perfectly looking UV texture on the screen.
But using the texture, everything is black. The size of the the texture (using textureSize(in_ExtOESTexture, 0)) is zero for both dimensions.
Any idea how to solve this problem?
The problem was that no "arcore-preview2.apk" was installed on the device. So, no error is raised if this APK is not installed. The screen remains just black. Moreover, the google examples on GitHub are working without this APK. I have created a new issue on GitHub because of this unexpected behavior.

Whats causing this artefacts?

I'm trying to map a 3D Texture to a Voxel Terrain, the pixel color from the texture should align with the terrain geometry and I don't want any gradients.
It's kinda working but depending on the camera angle I can see artefacts and I would like to know what's causing this and how to fix it.
Is it some kind of bleeding? I've already tried to change my texture as described here:
ogr3d tilemap but without success.
I think it's not a mipmapping bug because I turned it off and if I turn it on it looks way worse.
The geometry is grid aligned.
I set min and mag filtering to nearest and wrapping to clampToEdge.
fragment:
vec2 computeSliceOffset(float slice, float slicesPerRow, vec2 sliceSize) {
return sliceSize * vec2(mod(slice, slicesPerRow), floor(slice / slicesPerRow));
}
vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size, float numRows, float slicesPerRow) {
float slice = texCoord.z * size;
float sliceZ = floor(slice);
float zOffset = fract(slice);
vec2 sliceSize = vec2(1.0 / slicesPerRow, 1.0 / numRows);
vec2 sliceOffset = computeSliceOffset(sliceZ, slicesPerRow, sliceSize);
vec2 uv = texCoord.xy * sliceSize;
vec4 sliceColor = texture2D(tex, sliceOffset + uv);
return sliceColor;
}
vec3 texCoord = mod(worldPosition.xyz,128.0)/128.0;
vec4 myColor = sampleAs3DTexture(texture_0,texCoord,64.0,8.0,8.0);

GLSL webgl lerp normals from uv offset

I have a displacement map on a plane 512px* 512px (100x100 segments) , as the image for the displacement map scrolls left the vertices snap to position of height not blend smoothly, I have been looking at the mix() function and smooth-step() to morph the normals to their positions over time but i having a hard time implementing it.
uniform sampler2D heightText; //texture greyscale 512x512
uniform float displace;
uniform float time;
uniform float speed;
varying vec2 vUV;
varying float scaleDisplace;
void main() {
vUV = uv;
vec2 uvOffset = vUV + vec2( 0.1, 0.1)* time; // animates offset
vec2 uvCo = vUV + vec2( 0.0, 0.0);
vec2 texSize = vec2(-0.8, 0.8); // scales image larger
vec4 data = texture2D( heightText, uvOffset + fract(uvCo)*texSize.x);
scaleDisplace = data.r;
//vec3 possy = normal * displace * scaleDisplace;
vec3 morphPossy = mix( position, normal *displace , scaleDisplace)* time ;
gl_Position = projectionMatrix * modelViewMatrix * vec4(morphPossy, 1.0 );
}
Using Three.js 71 with vertex and pixel:
Illustration purpose:
Any help appreciated ...
Since you're using a texture as a height map, you should make sure that:
heightText.magFilter = THREE.LinearFilter; // This is the default value.
so that the values you receive are smoothed texel to texel.

How does sampler2DArrayShadow in glsl works

I am not able understand how to use sampler2DAprrayShadows and how it works. Got some part of it that we need to use depth texture values (GL_DEPTH_COMPONENT) to get the compare result with ref depth.
But then how to use the return float value to get the texel.
Got reference from :
http://www.khronos.org/opengles/sdk/docs/manglsl/xhtml/texture.xml
I have written a small code to test it as below:
My fragment shader as:
in highp vec2 texcoord;
in highp vec4 basecolor;
out highp vec4 myFragColor;
uniform highp sampler2DArrayShadow basetexture;
void main(void)
{
highp vec3 coords = (vec3(texcoord, 0.0) + vec3(1.0, 1.0, 1.0)) / 2.0;
highp float depth = texture(basetexture, vec4(coords.x, coords.y, coords.z, -0.5));
myFragColor = vec4(depth * basecolor);
}
Created 3D texture (texdata), and binding it as :
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT16, TEX_SIZE, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, texdata);
maybe this could help you:
depth cubemap make tutorial
And to be frank, you're supposed to make a frame buffer object which binds a 2D depth texture instead of a Cubemap one. If you want to use sampler: sampler2DArrayShadow, then you just need to overload the glsl function texture, which is texture( Sampler2DArrayShadow gSampler, Vec4 P, [float bias]) .P.z is the number of the 2D tex, and P.w is the reference depth value. The default bias is 0, you can ignore it if don't need one.

Aliassing when flipping a texture in fragment shader

I've created a multi-texture fragment shader in which I want to flip one of the textures but when doing this my texture gets all jaggy. Is there a solution to this problem?
This is my fragment shader code:
void main(void)
{
lowp vec4 camera = texture2D(texture0, destinationTexCoord);
lowp vec4 viewfinder = texture2D(texture1, vec2(destinationTexCoord.x, 1.0 - destinationTexCoord.y));
lowp vec4 result = mix(camera, viewfinder, viewfinder.a);
gl_FragColor = result;
}
Texture filtering I'm using:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Some background information: I'm blending these textures in my fragment shader (blending code stripped out) so I'm not looking for a solution where I rotate a second plane and merge them down on the framebuffer. I'm wondering if it is a good idea to flip/rotate around the texture coordinates in my fragment shader.
In the end I'll pass in a uniform saying: rotate or don't, resulting in that one texture getting rotated or not.
Using mediump instead of lowp for destinationTexCoord will improve the sampling rate for
the vec2(destinationTexCoord.x, 1.0 - destinationTexCoord.y) calculation. However, my recommendation is to use two varying vec2s instead of using a dependent texture read. i.e. cameraTexCoord and viewfinderTexCoord. You can avoid a mediump calculation in the fragment shader, and take advantage of the hardware's (hopefully) optimized vert-frag interpolation.
There's really no reason to use lowp for texture coordinates, unless they are dependent, in which case lowp may be better for the fragment shader calculations. Otherwise, lowp has not resulted in any gains, in my experience (I only know PowerVR hardware on iOS though).

Resources