Issue with splatmap shader?

hi all! what am I doing wrong with the shader code in this splatmap terrain demo i found that i’m upgrading to r116?

Here’s the error :

FBXLoader.js:3261 THREE.FBXLoader: FBX binary version: 7400
three.js:18459 THREE.WebGLProgram: shader error:  0 35715 false gl.getProgramInfoLog No compiled fragment shader when at least one graphics shader is attached.
THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:1044: 'perturbNormal2Arb' : no matching overloaded function found
ERROR: 0:1044: '=' : dimension mismatch
ERROR: 0:1044: 'assign' : cannot convert from 'const mediump float' to 'highp 3-component vector of float'

Here’s the demo :

Here’s the source :

<!DOCTYPE html>


	<meta charset="UTF-8">

		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">


			<title>Shader - Height Map (Three.js)</title>
			<link rel=stylesheet href="css/main.css">




			ANDERE AANPAK: OnBeforeCompile

			We gaan enkele chunks vervangen op het moment dat de shader van een standaardmateriaal door de compiler wordt gehaald.
			- maps
			- bumpmaps


		<div id="ThreeJS" style="position: absolute; left:0px; top:0px"></div>

		<script id="tileblend_pars_fragment" type="x-shader/x-vertex">

			#define USE_MAP 
			uniform sampler2D texBlendMap;
			uniform sampler2D texBaseColor;
			uniform sampler2D texTile1Color;
			uniform sampler2D texTile2Color;
			uniform sampler2D texTile3Color;
			//uniform sampler2D texTile4Color;

			uniform float repeatBase;
			uniform float repeatTile1;
			uniform float repeatTile2;
			uniform float repeatTile3;
			//uniform float repeatTile4;


		<script id="tileblend_fragment" type="x-shader/x-vertex"> 

			vec4 tbBlend=texture2D( texBlendMap, vUv );
			float tbBaseWeight=1.0 - max(tbBlend.r, max(tbBlend.g, tbBlend.b));

			vec4 base =  tbBaseWeight * texture2D( texBaseColor, vUv * repeatBase );
			vec4 color1 = tbBlend.r * texture2D( texTile1Color, vUv * repeatTile1 );
			vec4 color2 = tbBlend.g * texture2D( texTile2Color, vUv * repeatTile2 );
			vec4 color3 = tbBlend.b * texture2D( texTile3Color, vUv * repeatTile3 );
			vec4 newColor = (vec4(0.0, 0.0, 0.0, 1.0) + base + color1 + color2 + color3) / (tbBaseWeight+tbBlend.r+tbBlend.g+tbBlend.b);

			diffuseColor = newColor; 


		<script id="normalmap_pars_fragment" type="x-shader/x-vertex"> 

			uniform sampler2D normalMap;
			uniform vec2 normalScale;

			uniform sampler2D texBaseBump;
			uniform sampler2D texTile1Bump;
			uniform sampler2D texTile2Bump;
			uniform sampler2D texTile3Bump;
			uniform sampler2D texTile4Bump;

			uniform mat3 normalMatrix;
			// Per-Pixel Tangent Space Normal Mapping
			vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {
			// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
			vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );
			vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );
			vec2 st0 = dFdx( );
			vec2 st1 = dFdy( );
			float scale = sign( st1.t * st0.s - st0.t * st1.s ); // we do not care about the magnitude
			vec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );
			vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );
			vec3 N = normalize( surf_norm );
			mat3 tsn = mat3( S, T, N );

			vec4 tbBlend=texture2D( texBlendMap, vUv );
			float tbBaseWeight=1.0 - max(tbBlend.r, max(tbBlend.g, tbBlend.b));

			float foundIdx=0.0; 
			float foundVal=tbBaseWeight;

			if (tbBlend.r>foundVal) { foundIdx=1.0; foundVal=tbBlend.r;}
			if (tbBlend.g>foundVal) { foundIdx=2.0; foundVal=tbBlend.g;}
			if (tbBlend.b>foundVal) { foundIdx=3.0; foundVal=tbBlend.b;}

			vec3 mapN = texture2D( texBaseBump, vUv * repeatBase ).xyz * 2.0 - 1.0;
			if (foundIdx==1.0) mapN = texture2D( texTile1Bump, vUv * repeatTile1 ).xyz * 2.0 - 1.0;	
			else if (foundIdx==2.0) mapN = texture2D( texTile2Bump, vUv * repeatTile2 ).xyz * 3.0 - 1.0;
			else if (foundIdx==3.0) mapN = texture2D( texTile3Bump, vUv * repeatTile3 ).xyz * 3.0 - 1.0;

			mapN.xy *= normalScale;
			mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );
			return normalize( tsn * mapN );


		<script src="js/libs/three-r116/build/three.js"></script>
		<script src="js/libs/utils/Detector.js"></script>
		<script src="js/libs/controls/OrbitControls.js"></script>
		<script src="js/libs/libs/inflate.min.js"></script>
		<script src="js/libs/loaders/FBXLoader.js"></script>
		<script src="js/libs/effects/OutlineEffect.js"></script>
		<script src="js/plugins/stemkoski-keyboardstate.js"></script>
		<script src="js/main.js"></script>



Any help is GREATLY appreciated!

Thank You! <3

It seems the code overwrites the perturbNormal2Arb() function which is used for tangent-space normal mapping. This function was refactored in the past so it has now three parameters, not two. The actual implementation looks like so:

So the get things works, it seems you have to apply the splat map related code to the new version of perturbNormal2Arb().


@Mugen87 : What is wrong with this shader? Why is it putting black lines all over the terrain? And I’m not talking about the shader outline effect. Also, how can I remove the outline effect?

Compare to :

You are asking a question that you do not seem to understand fully.

Your question is not related to three.js, it is related to GLSL (GL Shader Language). @Mugen87 has provided a fairly exhaustive answer your question. Now your problem is to understand what the question is, it may sound harsh - but you have all the tools at your disposal to do that.

My guess is that you do not understand how materials/shaders work, I would start there, learn about shaders first. Or, you can look for another implementation of what you have been using, an implementation that has been properly updated for recent versions of three.js.

1 Like

… I’m trying to learn…

have a look for articles introducing shaders. I also recommend looking through shader code of three.js, try to figure out how the most basic “MeshBasicMaterial” shader is implemented - it can teach you a lot.

1 Like