TextureSample - MipValueMode Deriviate not working on mobile


Firstly not sure this is bug or not. Because I don’t have to much knowledge about shader/material.

DDX/DDY nodes is not supported on opengl es2 (just editor saying.) But I can use DDX/DDY in custom expressions and I think it is working. When I put result directly to BaseColor I’m getting close results like PC.

When I use TextureSample - MipValueMode Deriviate and put my DDX/DDY values, the material is not rendering anything on mobile. But it is working fine on PC and Mobile Preview. Which is weird. My android phone is supports opengl_es_standart_deriviates.

What I have to do. I’m trying to make a texture atlas. And I have a aircrafts because of “frac” (I think )

I’m just implementing this Material tiles cracks - Rendering - Epic Developer Community Forums

I’m on right way or I’m doing it wrong?

Phone Specifications

LG G3 - LG-D855TR

Android 5.0

Update 21.02.2016

I digged it into and I think I found the problem.

Note: I’m sure my DDX DDY custom nodes working fine in my mobile device. No problem here. But there is a problem with below code

// Source: http://oliverm-h.blogspot.com.tr/2014/12/ue4-quick-tip-removing-frac-artifacts.html
return Tex.SampleGrad(TexSampler, UV, DDX(UV2), DDY(UV2));

This code is running fine in editor and mobile preview perfectly. But it is not working in mobile device (LG G3).
Also same problem with TextureSample MipMapValueMode=Derivative. It is generating same GLSL code.

I looked generated GLSL codes and I think found the problem.

v28.xyz = texture2DGrad(ps0,v27,dFdx(v25),(-dFdy(v26))).xyz;

With this code I’m getting shader compiling error on my mobile device.

Fragment shader compilation failed.ERROR: 0:104: 'texture2DGrad' : no matching overloaded function found ERROR: 0:104: 'xyz' :  field selection requires structure, vector, or matrix on left hand side ERROR: 0:104: 'assign' :  cannot convert from 'const float' to '3-component vector of float'ERROR: 3 compilation errors.  No code generated.

But “texture2DGrad” not exist in OpenGL api. When I simply change to textureGrad it is compiling fine (Actually can’t test really working? because I need source build from GitHub but currently don’t have.).

I think it should be defined via #define texture2DGrad textureGrad ?

Here is a full generated GLSL code.

#version 300 es
#define HDR_32BPP_ENCODE_MODE 0.0
#extension GL_OES_standard_derivatives : enable
#define texture2D texture 
#define texture2DProj textureProj 
#define texture2DLod textureLod 
#define texture2DLodEXT textureLod 
#define texture2DProjLod textureProjLod 
#define textureCube texture 
#define textureCubeLod textureLod 
#define textureCubeLodEXT textureLod 

#define gl_FragColor out_FragColor 
out mediump vec4 out_FragColor; 

precision mediump float;
precision mediump int;

precision mediump sampler2D;
precision mediump samplerCube;


vec4 texture2DTexCoordPrecisionWorkaround(sampler2D p, vec2 tcoord)
	return texture2D(p, tcoord);
#define texture2D texture2DTexCoordPrecisionWorkaround

float intrinsic_GetHDR32bppEncodeModeES2() { return HDR_32BPP_ENCODE_MODE; }
uniform vec4 pu_m[13];
uniform highp vec4 pu_h[5];
uniform highp sampler2D ps1;
uniform highp sampler2D ps0;
uniform highp sampler2D ps2;
in highp vec2 var_TEXCOORD0;
in highp vec2 var_TEXCOORD1;
in highp vec4 var_TEXCOORD2;
in highp vec4 var_TEXCOORD3;
in highp vec2 var_TEXCOORD4;
in highp vec2 var_TEXCOORD5;
void main()
	highp vec4 v0;
	v0.xyzw = gl_FragCoord;
	v0.w = (1.0/(gl_FragCoord.w));
	vec4 v1;
	highp vec4 v2;
	v2.xy = var_TEXCOORD2.zw;
	v2.zw = var_TEXCOORD3.zw;
	highp vec2 v3;
	v3.xy = ((texture2D(ps1,var_TEXCOORD1).zw*vec2(2.000000e+00,2.000000e+00))+vec2(-1.000000e+00,-1.000000e+00));
	highp vec3 v4;
	v4.xy = v3;
	v4.z = sqrt(((1.000000e+00+(-dot(v3,v3))),0.000000e+00));
	highp vec4 v5;
	highp vec3 v6;
	highp vec2 v7;
	v7.xy = pu_m[2].xy;
	v6.xy = ((((gl_FragCoord.xy+(-v7))*pu_h[0].zw)+vec2(-5.000000e-01,-5.000000e-01))*vec2(2.000000e+00,-2.000000e+00));
	v6.z = gl_FragCoord.z;
	highp vec4 v8;
	v8.w = 1.000000e+00;
	v8.xyz = v6;
	v5.xyzw = (v8*v0.wwww);
	vec3 v9;
	vec3 v10;
	v10.xyz = ((v4.zzz*pu_h[3].xyz)+((v3.yyy*pu_h[2].xyz)+(v3.xxx*pu_h[1].xyz)));
	v9.xyz = normalize(v10);
	vec2 v11;
	highp vec2 v12;
	v12.xy = vec2(1.000000e+00,0.000000e+00);
	float h13;
	h13 = dot(var_TEXCOORD0,v12);
	v11.x = h13;
	highp vec2 v14;
	v14.xy = vec2(-0.000000e+00,1.000000e+00);
	float h15;
	h15 = dot(var_TEXCOORD0,v14);
	v11.y = h15;
	vec2 v16;
	highp vec2 v17;
	v17.xy = vec2(0.000000e+00,0.000000e+00);
	highp vec2 v18;
	v18.xy = v11;
	vec2 v19;
	v19.xy = (v18+(-floor(v17)));
	v16.xy = v19;
	vec2 v20;
	v20.xy = fract(v16);
	vec2 v21;
	v21.x = (v20.x*5.000000e-01);
	v21.y = (v20.y*5.000000e-01);
	vec3 v22;
	highp vec2 v23;
	v23.xy = vec2(5.000000e-01,0.000000e+00);
	highp vec2 v24;
	v24.xy = (v21*vec2(8.010000e-01,8.010000e-01));
	highp vec2 v25;
	v25.xy = v16;
	highp vec2 v26;
	v26.xy = v16;
	vec2 v27;
	v27.xy = (v24+(v23+vec2(9.950000e-02,9.950000e-02)));
	vec3 v28;
	v28.xyz = texture2DGrad(ps0,v27,dFdx(v25),(-dFdy(v26))).xyz;
	v22.xyz = (clamp((v28*pu_m[7].xyz),vec3(0.000000e+00,0.000000e+00,0.000000e+00),vec3(1.000000e+00,1.000000e+00,1.000000e+00))+vec3(1.800000e-02,1.800000e-02,1.800000e-02));
	vec3 v29;
	v29.xyz = ((texture2D(ps2,var_TEXCOORD4).xyz*pu_m[11].xyz)+pu_m[9].xyz);
	float h30;
	h30 = dot(v29,vec3(3.000000e-01,5.900000e-01,1.100000e-01));
	vec4 v31;
	v31.w = 1.000000e+00;
	v31.xyz = v9.yzx;
	vec4 v32;
	vec4 v33;
	v33.xyzw = v2;
	v32.xyzw = v33;
	highp float f34;
	f34 = 0.000000e+00;
	highp float f35;
	f35 = (0.000000e+00,dot(v9,pu_m[3].xyz));
	highp vec3 v36;
	v36.xyz = pu_m[0].xyz;
	highp vec3 v37;
	v37.xyz = v22;
	vec3 v38;
	v38.xyz = ((vec3((f34*f35))*v36)*v37);
	v1.xyz = ((((((v29*vec3((((exp2(((h30*1.600000e+01)+-8.000000e+00))+-3.906250e-03)*(0.000000e+00,dot(((texture2D(ps2,var_TEXCOORD5)*pu_m[12])+pu_m[10]),v31)))/h30)))*v22)+v38)+(pu_m[6].xyz,vec3(0.000000e+00,0.000000e+00,0.000000e+00)))*v32.www)+v32.xyz);
	v1.w = 0.000000e+00;
	highp float f39;
	float h40;
	h40 = intrinsic_GetHDR32bppEncodeModeES2();
	highp float f41;
	f41 = h40;
	f39 = f41;
	if ((f39==0.000000e+00))
		float h42;
		h42 = v5.w;
		v1.w = h42;
	v1.xyzw = (v1*pu_m[1]);
	highp float f43;
	float h44;
	h44 = intrinsic_GetHDR32bppEncodeModeES2();
	highp float f45;
	f45 = h44;
	f43 = f45;
	if ((f43!=0.000000e+00))
		if ((f43==2.000000e+00))
			v1.xyz = v1.xyz;
		vec2 v46;
		vec2 v47;
		v47.xy = gl_FragCoord.xy;
		v46.xy = v47;
		vec4 v48;
		highp float f49;
		float h50;
		h50 = intrinsic_GetHDR32bppEncodeModeES2();
		highp float f51;
		f51 = h50;
		f49 = f51;
		if ((f49==1.000000e+00))
			vec2 v52;
			vec2 v53;
			v53.xy = (v46*vec2(5.000000e-01,5.000000e-01));
			v52.xy = v53;
			v52.y = (v53.y+v53.x);
			vec2 v54;
			v54.xy = fract(v52);
			v52.xy = v54;
			vec2 v55;
			v55.xy = ((v54*vec2(-3.921569e-03,1.043529e+01))+vec2(-1.960784e-03,5.000000e-01));
			vec4 v56;
			v56.xyz = ((v1.xyz*v55.yyy)+v55.xxx);
			v56.w = v1.w;
			v48.xyzw = v56;
			if ((f49==2.000000e+00))
				vec4 v57;
				float h58;
				h58 = min(((v1.x,v1.y),(v1.z,1.000000e-06)),1.024000e+03);
				v57.w = ((1.000977e+00*h58)/(1.000000e+00+h58));
				v57.w = (ceil((v57.w*2.550000e+02))/2.550000e+02);
				v57.xyz = (v1.xyz*vec3((1.0/((v57.w/(1.000977e+00+(-v57.w)))))));
				v48.xyzw = v57;
				v48.xyzw = v1;
		v1.xyzw = v48;
	gl_FragColor.xyzw = v1;

Also I added sample project.


Note: Don’t forgot to change default material of Floor. Looks like it’s resetted.

79287-emptyproject1.zip (582 KB)


Could you show me your blueprints exactly, or are those blueprints by Hevedy on the forums you? I added DDX/DDY into a material and the areas with that material were greyscaled. I want to verify that I’m following your exact reproduction steps.


I attached my material setup.

Note: DDX/DDY nodes is just a custom expression (because internal node not allowing to compile correctly on opengl es2.)

This setup is working on PC and mobile preview perfectly. But on my device not working. But I’m sure and checked DDX/DDY is working fine on my device. I think there is a problem with TextureSample. When I change MipModeValue to None, texture appering but I need these DDX/DDY inputs.

So I’ve put together a similar material like you’ve displayed above. I was not able to recreate any gaps between the tiles. Have you tried using the DDX and DDY nodes instead of custom ones?

Also, going back to RyanB’s comment on the forums, have you tried this:

"This is caused by large jumps in the UV coordinates which the GPU hardware automatically assumes means there needs to be a mip map transition. Due to the frac. The GPU uses the slope of the UVs in screen space to determine mips, so when it sees the UVs go from 0 to 1 suddenly it thinks that pixel has a steep slope (ie, the same as a wall almost perpendicular to you).

You can work around this using ComputeMipLevel but thats a pain since you need to enter the texture size.

A better way is to use the code “SampleGrad”. First make a Custom expression node.

Add an input called “Tex” and hook up your texture there as a texture object. Also add an input called “UV”.

Then add this line:

return Tex.SampleGrad(TexSampler,UV,DDX(UV),DDY(UV));

I will probably make this a material function at some point but I have been trying to get the rendering guys to make it a proper code node first. It’s like a game of chicken “Do it right or I will do it crappy at which point you will have to do it”."

Thank you!

Hi ,

Thankyou for your fast replies.

I cannot use DDX/DDY nodes directly because editor saying “Error [ES2] (Node DDY) Node not supported in feature level ES2” and I don’t understand because opengl es2 supporting this. When I use this nodes with CustomExpression it is working :slight_smile:

The real problem is: When select texture sample MipValueMode to Derivative, nothing rendered on mobile device. But it is working on PC and Mobile Preview. (just rendering transparent on mobile device.)

I tried Your/RyanB’s suggestion and same problem here, working on PC and Mobile Preview but not working on mobile device. (just rendering transparent on device.)

BTW, TextureSample with MipValueMode=Deriviate and RyanB’s suggestion is not working on real mobile device. Both is working on only PC and Mobile Preview.

Thank you.

I had a similar error appear and I changed my rendering settings to Mobile/HTML5 and did not run into that error again. Have you attempted this?

If this does not work, would you please upload your sample project? It’s possible that some setting within my project compared to yours is different.

Looking forward to hearing back from you, thanks!


We have not heard back from you in a few days, so we are marking this post as Resolved for tracking purposes. If you are still experiencing the issue you reported, please respond to this message with additional information and we will offer further assistance.

Thank you!


Still having problem with 4.11. I added more details and also sample probject.

Thank you

The issue that we currently see in your project is that you’re using a Material Expression Custom node. You can’t call DDX (UV2) or DDY (UV2) on a mobile device. That does not work unfortunately.

Let me know once you fix this, if you run into more complications.