<p>There are couple of ways this is usually done:</p>

<p>1) put the textures for the house to a single texture are just UV-map the object accordingly. If you would need to use different BRDF etc. for different parts of the object, you can use uber shader and switch in shader and use another texture to control which BRDF to use in which parts. The benefit is that you can render the entire object with a single draw call reducing CPU overhead with the expense of some GPU overhead due to the uber shader.</p>

<p>2) split the object to different sub-objects (at triangle level) based on the material and issue separate draw call for each. This keeps the shader simpler, but has higher CPU overhead due to more draw calls.</p>

CC BY-SA 3.0
2016-12-09T03:15:10.777Z
2016-12-09T03:15:10.777Z
JarkkoL
<p>In vertex, put  <code>vPos</code> as <code>varying</code>. Then instead of doing the height check in vertex, do it in fragment.</p>

<pre><code>if(outVPos.y &gt; 1.2) 
{
   textureColor = texture2D(urooftext, outTexCoords);
} 
else 
{
   discard;
}
</code></pre>

<p>By the way, <code>varying</code> qualifier is deprecated and replaced with <code>out</code> in vertex and <code>in</code> in fragment.</p>

CC BY-SA 3.0
2016-12-07T19:59:31.397Z
2016-12-07T19:59:31.397Z
mdkdy
<p>I tried passing a variable from the vertex shader to tell the fragment shader whether or not I wanted part of an object textured. That way I could write another shader for the other parts of the object. Unfortunately, what I have creates the undesirable effect seen here.</p>

<p><a href="https://i.sstatic.net/rQKtO.png" rel="noreferrer"><img src="https://i.sstatic.net/rQKtO.png" alt="enter image description here"></a></p>

<p>vertex shader for house</p>

<pre><code>&lt;script id="long_house-vs" type="x-shader/x-vertex"&gt;
    precision highp float;

    attribute vec3 vpos;
    attribute vec3 vnormal;
    attribute vec2 vtexCoords;

    varying vec3 outNormal;
    varying vec3 outPos;
    varying vec2 outTexCoords;
    // 1 if part of roof
    varying float roof;


    uniform mat4 view;
    uniform mat4 proj;
    uniform mat4 model;
    uniform vec3 lightdir;
    uniform vec3 long_housecolor;

    void main(void) {
        if(vpos.y &gt; 1.2) {
            roof = 1.0;
        } else {
            roof = 0.0;
        }
        gl_Position = proj * view * model * vec4(vpos, 1.0);
        outTexCoords = vtexCoords;
        outPos =  (view * model * vec4(vpos, 1.0)).xyz;
        outNormal = normalize(view * model * vec4(vnormal,0.0)).xyz;
    }
&lt;/script&gt;
</code></pre>

<p>fragment shader</p>

<pre><code>&lt;script id="long_house-fs" type="x-shader/x-fragment"&gt;
    precision highp float;
    varying vec3 outNormal;
    varying vec3 outPos;
    varying vec2 outTexCoords;
    varying float roof;

    uniform vec3 lightdir;
    uniform vec3 long_housecolor;
    uniform sampler2D usampler;
    uniform sampler2D urooftext;

    void main(void) {
        float diffuse = .5 + .5*abs(dot(outNormal, lightdir));
        vec3 outColor = long_housecolor * diffuse;
        vec4 textureColor;
        if(roof == 1.0) {
            textureColor = texture2D(urooftext, outTexCoords);
        } else {
            discard;
        }
        gl_FragColor = vec4(textureColor.rgb * diffuse, textureColor.a);
    }
&lt;/script&gt;
</code></pre>

<p>When I rearrange the code a bit so that the bottom half of the house is textured instead of the top I get this</p>

<p><a href="https://i.sstatic.net/Vkq46.png" rel="noreferrer"><img src="https://i.sstatic.net/Vkq46.png" alt="enter image description here"></a></p>

<p>So what would be the correct way to write a shader that only affects part of an object?</p>

CC BY-SA 3.0
2016-12-07T19:28:47.937Z
You mean the noise effect?
mdkdy
CC BY-SA 3.0
2016-12-07T19:44:13.763Z
@narthex I think so. How do I get rid of it?
Nebulous Ryan
CC BY-SA 3.0
2016-12-08T13:08:12.650Z
anything stopping you from just splitting the object?
ratchet freak
<shader><glsl>
What is the correct way to put different textures on different parts of an object?
Nebulous Ryan
# What is the correct way to put different textures on different parts of an object?

(Asked by: username_0 on 2016-12-07)

I tried passing a variable from the vertex shader to tell the fragment shader whether or not I wanted part of an object textured. That way I could write another shader for the other parts of the object. Unfortunately, what I have creates the undesirable effect seen here.

[![enter image description here](https://i.sstatic.net/rQKtO.png)](https://i.sstatic.net/rQKtO.png)

vertex shader for house

```
<script id="long_house-vs" type="x-shader/x-vertex">
    precision highp float;

    attribute vec3 vpos;
    attribute vec3 vnormal;
    attribute vec2 vtexCoords;

    varying vec3 outNormal;
    varying vec3 outPos;
    varying vec2 outTexCoords;
    // 1 if part of roof
    varying float roof;

    uniform mat4 view;
    uniform mat4 proj;
    uniform mat4 model;
    uniform vec3 lightdir;
    uniform vec3 long_housecolor;

    void main(void) {
        if(vpos.y > 1.2) {
            roof = 1.0;
        } else {
            roof = 0.0;
        }
        gl_Position = proj * view * model * vec4(vpos, 1.0);
        outTexCoords = vtexCoords;
        outPos =  (view * model * vec4(vpos, 1.0)).xyz;
        outNormal = normalize(view * model * vec4(vnormal,0.0)).xyz;
    }
</script>

```

fragment shader

```
<script id="long_house-fs" type="x-shader/x-fragment">
    precision highp float;
    varying vec3 outNormal;
    varying vec3 outPos;
    varying vec2 outTexCoords;
    varying float roof;

    uniform vec3 lightdir;
    uniform vec3 long_housecolor;
    uniform sampler2D usampler;
    uniform sampler2D urooftext;

    void main(void) {
        float diffuse = .5 + .5*abs(dot(outNormal, lightdir));
        vec3 outColor = long_housecolor * diffuse;
        vec4 textureColor;
        if(roof == 1.0) {
            textureColor = texture2D(urooftext, outTexCoords);
        } else {
            discard;
        }
        gl_FragColor = vec4(textureColor.rgb * diffuse, textureColor.a);
    }
</script>

```

When I rearrange the code a bit so that the bottom half of the house is textured instead of the top I get this

[![enter image description here](https://i.sstatic.net/Vkq46.png)](https://i.sstatic.net/Vkq46.png)

So what would be the correct way to write a shader that only affects part of an object?

**Tags:** shader, glsl

> **Comments:**
> **username_1**: You mean the noise effect?  
> **username_0**: @narthex I think so. How do I get rid of it?  
> **username_2**: anything stopping you from just splitting the object?  

---

## 2 answers

### Answer by username_1 on 2016-12-07. Score: 4 | Accepted answer

In vertex, put `vPos` as `varying`. Then instead of doing the height check in vertex, do it in fragment.

```
if(outVPos.y > 1.2) 
{
   textureColor = texture2D(urooftext, outTexCoords);
} 
else 
{
   discard;
}

```

By the way, `varying` qualifier is deprecated and replaced with `out` in vertex and `in` in fragment.


---

### Answer by username_3 on 2016-12-09. Score: 4

There are couple of ways this is usually done:

1) put the textures for the house to a single texture are just UV-map the object accordingly. If you would need to use different BRDF etc. for different parts of the object, you can use uber shader and switch in shader and use another texture to control which BRDF to use in which parts. The benefit is that you can render the entire object with a single draw call reducing CPU overhead with the expense of some GPU overhead due to the uber shader.

2) split the object to different sub-objects (at triangle level) based on the material and issue separate draw call for each. This keeps the shader simpler, but has higher CPU overhead due to more draw calls.


---

