Repeat a Shader material texture?

i want to repeat my shader texture lets say 8x8 how can i do this within this frag below? i tried setting the normal way repeat.set( 4, 4 ); etc that didnt work tho

  const _FS = `
  uniform vec3 topColor;
  uniform vec3 bottomColor;
  uniform float offset;
  uniform float exponent;
  
  uniform vec3 fogColor;
  uniform float fogNear;
  uniform float fogFar;
  uniform float fogDensity;
  uniform samplerCube background;
  
  varying vec3 vWorldPosition;
  
  void main() {
    vec3 viewDirection = normalize(vWorldPosition - cameraPosition);
    vec3 stars = textureCube(background, viewDirection).xyz;
  
    float h = normalize(vWorldPosition + offset).y;
    float t = max(pow(max(h, 0.0), exponent), 0.0);
  
    float f = exp(min(0.0, -vWorldPosition.y * 0.00125));
  
    vec3 sky = mix(stars, bottomColor, f);


    gl_FragColor = vec4(sky, 1.0);
  }`;

js:

  const texture0 = loaderSprite.load("./resources/terrain/ski.jpg");
      texture0.encoding = THREE.sRGBEncoding;
  
      const uniforms = {
		  
        "topColor": { value: new THREE.Color(0x0b152b) },
        "bottomColor": { value: new THREE.Color(0x0b152b) },
        "offset": { value: -30 },
        "exponent": { value: 1.0 },
		"fogColor": { type: "c", value: scene.fog.color },
		"fogNear": { type: "f", value: scene.fog.near },
		"fogFar": { type: "f", value: scene.fog.far },
		"fogDensity": { type: "f", value: 1.75 },
		 "background": { value: texture0 },
      };
     uniforms["topColor"].value.copy(hemiLight.color);
    this.scene_.fog.color.copy(uniforms["bottomColor"].value);
  
      const skyGeo = new THREE.SphereBufferGeometry(4000, 40, 40);
      const skyMat = new THREE.ShaderMaterial({
          uniforms: uniforms,
          vertexShader: _VS,
          fragmentShader: _FS,
          side: THREE.DoubleSide,
		 fog: true,
		 // glslVersion: THREE.GLSL3
      });
  
      const sky = new THREE.Mesh(skyGeo, skyMat);
      this.scene_.add(sky);

repeat is not an internal property of a texture, it’s a command to THREE to add an extra custom code to the fragment shader that tiles the texture. If you write your own shader, you need to implement tiling yourself.

Try this:

JS

uniforms: {
   tex: { value: new THREE.TextureLoader().load('....', ) },
   repeat: { value: [2, 3] }
},

GLSL

uniform sampler2D tex;
uniform vec2 repeat;

void main() {

   vec2 uv = vuv;
   uv = fract(uv * repeat);
   vec2 smooth_uv = repeat * vuv;
   vec4 duv = vec4(dFdx(smooth_uv), dFdy(smooth_uv));
   vec3 txl = textureGrad(tex, uv, duv.xy, duv.zw).rgb;

   gl_FragColor = vec4(txl, 1.0);
}

And both .wrapS and .wrapT are set to THREE.RepeatWrapping?

don’t you have to set that on the uniform ? like this?
uniforms.background.value.wrapS = uniforms.background.value.wrapT = THREE.RepeatWrapping;
I’ll try the above soon when I get on my laptop thanks for your reply !

1 Like

Wrapping mode is set by the WebGL function gl.texParameteri(), you cannot set it from within the shader (as far as I know).

However, you can do texture repeating and wrapping manually by juggling with texture coordinates in the shader (for example, scaling texture coordinates makes the repeat, while modding coordinates with fract to interval [0,1) makes the wrap).

So i’ve attempted to apply this to my code but i can not get it to work something about `

‘textureGrad’ : no matching overloaded function found

`How can I apply this to my code?
thanks

uv is normally available in vertex shader and passed to fragment as vuv, here’s the complete exampe of how to tile a texture using shader material:

1 Like