I’ve tried to write custom shader with sophisticated texture coordinates processing implementing some kind of texture atlas. I encountered very strange kind of error. glsl step function (built-in as well as manually wrote one via if statement) gives artefacts and seem to be discontinuous.

Here is the screenshot:http://rghost.ru/37964789.view

Here is all souece files packed in one archive: http://rghost.ru/37964811

Standart vertex shader:

uniform mat4 g_WorldViewProjectionMatrix;

uniform mat4 g_WorldViewMatrix;

uniform mat3 g_NormalMatrix;

uniform mat4 g_ViewMatrix;

uniform vec4 g_LightColor;

uniform vec4 g_LightPosition;

uniform vec4 g_AmbientLightColor;

varying vec2 texCoord;

attribute vec3 inPosition;

attribute vec2 inTexCoord;

attribute vec3 inNormal;

varying vec3 vLightDir;

varying vec3 wvNormal;

void lightComputeDir(in vec3 worldPos, in vec4 color, in vec3 position, out vec3 lightDir) {

float posLight = step(0.5, color.w);

vec3 tempVec = position * sign(posLight - 0.5) - (worldPos * posLight);

lightDir = normalize(tempVec);

}

void main() {

// Vertex transformation

vec4 pos = vec4(inPosition, 1.0);

gl_Position = g_WorldViewProjectionMatrix * pos;

texCoord = inTexCoord;

// direction transformations

vec3 wvPosition = (g_WorldViewMatrix * pos).xyz;

vec4 tmp_wvLightPos = (g_ViewMatrix * vec4(g_LightPosition.xyz, clamp(g_LightColor.w,0.0,1.0 )) );

lightComputeDir(wvPosition, g_LightColor, tmp_wvLightPos.xyz, vLightDir );

wvNormal = normalize(g_NormalMatrix * inNormal);

}

Custom frag shader, step function used unnatural to show effect

varying vec2 texCoord;

uniform vec4 g_LightDirection;

varying vec3 vLightDir;

varying vec3 wvNormal;

uniform sampler2D m_BaseTex;

float lightComputeDiffuse(in vec3 norm, in vec3 lightdir) {

return max(0.0, dot(norm, lightdir));

}

void main() {

vec2 realCoord = texCoord;

realCoord = step(0.6,realCoord)*realCoord;

vec4 data = texture2D(m_BaseTex, realCoord);

float spotFallOff=1.0;

if (g_LightDirection.w != 0.0) {

vec3 L = normalize(vLightDir);

vec3 spotDir = normalize(g_LightDirection.xyz);

float curAngleCos = dot(-L, spotDir);

float innerAngleCos = floor(g_LightDirection.w) * 0.001;

float outerAngleCos = fract(g_LightDirection.w);

float subInnerOuter = innerAngleCos - outerAngleCos;

spotFallOff = (curAngleCos - outerAngleCos) / subInnerOuter;

if (spotFallOff <= 0.0) {

gl_FragColor.rgb = vec3(0.0);

gl_FragColor.a = 1.0;

return;

} else {

spotFallOff = clamp(spotFallOff, 0.0, 1.0);

}

}

spotFallOff = clamp(spotFallOff, step(g_LightDirection.w, 0.001), 1.0);

vec3 lightdir = normalize(vLightDir);

vec3 normal = normalize(wvNormal);

gl_FragColor.a = 1.0;

gl_FragColor.rgb = data.rgb * lightComputeDiffuse(normal, lightdir) * spotFallOff;

}

I'm using nvidia card on ubuntu GNU/Linux. Is this behaviour standard or depend on OS and video card? I'm very confused with it and don't know what to do with such artefacts. All methods leads to the same result: step function, if statement, clamp function. I'm doubt if a workaround ever exist.