5

I could not load texture to my shader material, only what I see are just black dot. This is my shader.js

THREE.ShaderLib['cloud'] = {

    uniforms: {
        texture: { type: "t", value: THREE.ImageUtils.loadTexture("img/cloud.png") }
    },

    vertexShader: [
        "varying vec2 vUv;",
        "void main() {",
            "vUv = uv;",
            "gl_PointSize = 8.0;",
            "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
        "}",
    ].join("\n"),

    fragmentShader: [
            "varying vec2 vUv;",
            "uniform sampler2D texture;",
            "void main() {",
                "gl_FragColor = texture2D(texture, vUv);",
            "}",
    ].join("\n")
};

and this is how I'm trying to load and use it:

var cloudShader = THREE.ShaderLib["cloud"];
var uniforms = THREE.UniformsUtils.clone(cloudShader.uniforms);

var texture = THREE.ImageUtils.loadTexture("img/cloud.png", undefined, function () {

   uniforms.texture.value = texture;
   texture.needsUpdate = true;

   var _material = new THREE.ShaderMaterial({
      fragmentShader: cloudShader.fragmentShader,
      vertexShader: cloudShader.vertexShader,
      uniforms: uniforms                   
   });                    
   _material.uniforms.texture.value.needsUpdate = true;
   var _geometry = new THREE.Geometry();
   _geometry.vertices.push(new THREE.Vector3(0, 0, 0));
   var _mesh = new THREE.Points(_geometry, _material);
   scene.add(_mesh);

 });

As You can see I'm trying to set update texture value two times, before and after material is created. It's really simpy example but I have no idea why it is not working in the way that I'm using it. There is no errors in debug console.

I'm using THREE.Points class, because I'm using it to generate clouds as a particle groups.

Thanks in advance for any help.

4
  • Are you sure you are able to access local file on your browser? Commented Oct 21, 2015 at 9:00
  • what local file ? You mean cloud.png ?, yes I'm sure :) Commented Oct 21, 2015 at 9:37
  • Why are you calling loadTexture twice? Commented Oct 22, 2015 at 11:06
  • just to test, I've already try to load in only one place, nothing change Commented Oct 22, 2015 at 12:20

3 Answers 3

4

So, after some time I have found a solution for this specific problem. I need to move my uniforms from shader.js directly to place where i'm creating shader material. This is enough to fix problem with my texture, but still I don't know why previous code doesn't work. Working shader material looks like this:

 var _material = new THREE.ShaderMaterial({
      fragmentShader: cloudShader.fragmentShader,
      vertexShader: cloudShader.vertexShader,
      uniforms: uniforms: {
        texture: { type: "t", value: THREE.ImageUtils.loadTexture("img/cloud.png") }
      },
 });   
Sign up to request clarification or add additional context in comments.

2 Comments

These days one should use TextureLoader instead
i think uniforms: uniforms: { should be just uniforms: {
1

So if anyone having the same issue now. The reason this doesn't work is not only because of the texture being a reserved keyword in GLSL 4.

When using particles in ThreeJS, and particurarly THREE.Points class, you should always pass gl_PointCoord to the texture2D as a second argument instead of the uv coordinates.

The working example would be:

THREE.ShaderLib['cloud'] = {
  uniforms: {
    uTexture: { type: "t", value: THREE.ImageUtils.loadTexture("img/cloud.png") }
  },   
  vertexShader: [
    "void main() {",
    "gl_PointSize = 8.0;",
    "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
    "}",
  ].join("\n"),
        
  fragmentShader: [
    "uniform sampler2D uTexture;",
    "void main() {",
    "gl_FragColor = texture2D(uTexture, gl_PointCoord);",
    "}",
  ].join("\n")
};

Comments

0
   "varying vec2 vUv;",
        "uniform sampler2D texture;",
        "void main() {",
            "gl_FragColor = texture2D(texture, vUv);", // this line
        "}",

As of 2024, this line right there causes an error, because the name texture is reserved by another function in the fragment in threejs's shader material.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.