6

J'ai créé un shader personnalisé pour pouvoir utiliser un BlendMap avec 4 textures différentes mais je n'arrive pas à faire fonctionner les effets d'ombre/foudre.ThreeJS [r85]: Shader personnalisé avec Shadowmap

Qu'est-ce qui me manque ici? Ou existe-t-il un autre moyen de réaliser la même fonctionnalité?

Méthode de création de maillage ci-dessous qui affiche toutes les textures correctement.

// Creates the ground 
function CreateGround() { 
    var uniforms = THREE.UniformsUtils.merge([ 
     THREE.UniformsLib["lights"], 
     THREE.UniformsLib["shadowmap"], 
    { 
     TextureBackground: { type: "t", value: null }, 
     TextureR: { type: "t", value: null }, 
     TextureG: { type: "t", value: null }, 
     TextureB: { type: "t", value: null }, 
     TextureBlendMap: { type: "t", value: null } 
    }]); 

    var shaderMaterial; 
    try { 
     shaderMaterial = new THREE.ShaderMaterial({ 
      lights: true, 
      uniforms: uniforms, 
      vertexShader: BlendMapVertexShader, 
      fragmentShader: BlendMapFragmentShader 
     }); 
    } catch (e) { 
     alert("Error 'CreateGround' : GPU Shader couldn't compile"); 
    } 


    shaderMaterial.uniforms.TextureBlendMap.value = _TextureBlendMap; 
    shaderMaterial.uniforms.TextureBackground.value = _TextureSand; 
    shaderMaterial.uniforms.TextureR.value = _TextureClay; 
    shaderMaterial.uniforms.TextureG.value = _TextureClay; 
    shaderMaterial.uniforms.TextureB.value = _TextureRock; 

    var geometry = new THREE.BoxGeometry(GROUND_SIZE, GROUND_HEIGHT, GROUND_SIZE); 
    var mesh = new THREE.Mesh(geometry, shaderMaterial); 

    mesh.castShadow = false; 
    mesh.receiveShadow = true; 

    return mesh; 
} 

Et ceci est mon shaders actuel:

BlendMapVertexShader = [ 
THREE.ShaderChunk["shadowmap_pars_vertex"], 
"varying vec2 vUv;", 
"varying vec3 vPosition;", 

"void main(void) {", 
    "vUv = uv;", 
    "vPosition = position;", 
    "gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1);", 

    THREE.ShaderChunk["begin_vertex"], 
    THREE.ShaderChunk["worldpos_vertex"], 
    THREE.ShaderChunk["shadowmap_vertex"], 
"}", 
].join("\n"); 

BlendMapFragmentShader = [ 
THREE.ShaderChunk["common"], 
THREE.ShaderChunk["packing"], 
THREE.ShaderChunk["shadowmap_pars_fragment"], 

"varying vec2 vUv;", 
"varying vec3 vPosition;", 
"uniform sampler2D TextureBlendMap;", 
"uniform sampler2D TextureBackground;", 
"uniform sampler2D TextureR;", 
"uniform sampler2D TextureG;", 
"uniform sampler2D TextureB;", 

"void main() {", 

    "vec4 cBlend = texture2D(TextureBlendMap, vUv);", 
    "float bText = 1.0 - (cBlend.r + cBlend.g + cBlend.b);", 
    "vec2 tiledCoords = vUv * 40.0;", 
    "vec4 cBack = texture2D(TextureBackground, tiledCoords) * bText;", 
    "vec4 cR = texture2D(TextureR, tiledCoords) * cBlend.r;", 
    "vec4 cG = texture2D(TextureG, tiledCoords) * cBlend.g;", 
    "vec4 cB = texture2D(TextureB, tiledCoords) * cBlend.b;", 
    "vec4 cTot = cBack + cR + cG + cB;", 
    "gl_FragColor = cTot;", 
    THREE.ShaderChunk["shadowmap_fragment"], 
"}", 
].join("\n"); 

Je n'ai pas d'erreurs ni avertissements dans le navigateur.

Three.js r85Dev

Répondre

0

D'accord. J'ai fini par copier le shader PHONG, puis remplacer l'entrée de couleur diffuse. Solution ci-dessous.

Ceci est la méthode pour créer le maillage avec blendmapshader

// Creates the ground 
function CreateGround(material) { 
    var uniforms = THREE.UniformsUtils.merge([ 
     THREE.UniformsLib["common"], 
     THREE.UniformsLib["aomap"], 
     THREE.UniformsLib["lightmap"], 
     THREE.UniformsLib["emissivemap"], 
     THREE.UniformsLib["bumpmap"], 
     THREE.UniformsLib["normalmap"], 
     THREE.UniformsLib["displacementmap"], 
     THREE.UniformsLib["gradientmap"], 
     THREE.UniformsLib["fog"], 
     THREE.UniformsLib["lights"], 
    { 
     emissive: { type: "c", value: new THREE.Color(0x000000) }, 
     specular: { type: "c", value: new THREE.Color(0x111111) }, 
     shininess: { type: "f", value: 30 }, 

     TextureBackground: { type: "t", value: null }, 
     TextureR: { type: "t", value: null }, 
     TextureG: { type: "t", value: null }, 
     TextureB: { type: "t", value: null }, 
     TextureBlendMap: { type: "t", value: null }, 
    }]); 

    var shaderMaterial; 
    try { 
     shaderMaterial = new THREE.ShaderMaterial({ 
      lights: true, 
      uniforms: uniforms, 
      vertexShader: BlendMapVertexShader, 
      fragmentShader: BlendMapFragmentShader 
     }); 
    } catch (e) { 
     alert("Error 'CreateGround' : GPU Shader couldn't compile"); 
    } 

    shaderMaterial.uniforms.TextureBlendMap.value = _TextureBlendMap; 
    shaderMaterial.uniforms.TextureBackground.value = _TextureSand; 
    shaderMaterial.uniforms.TextureR.value = _TextureClay; 
    shaderMaterial.uniforms.TextureG.value = _TextureGrass; 
    shaderMaterial.uniforms.TextureB.value = _TextureSandRock; 

    var geometry = new THREE.BoxGeometry(GROUND_SIZE, GROUND_HEIGHT, GROUND_SIZE); 
    var mesh = new THREE.Mesh(geometry, shaderMaterial); 

    mesh.castShadow = false; 
    mesh.receiveShadow = true; 

    return mesh; 
} 

Et c'est le shader PHONG modifié:

BlendMapVertexShader = [ 
"#define PHONG", 

"varying vec3 vViewPosition;", 
"varying vec2 vUv;", 

"#ifndef FLAT_SHADED", 

"varying vec3 vNormal;", 

"#endif", 


THREE.ShaderChunk["common"], 
THREE.ShaderChunk["uv_pars_vertex"], 
THREE.ShaderChunk["uv2_pars_vertex"], 
THREE.ShaderChunk["displacementmap_pars_vertex"], 
THREE.ShaderChunk["envmap_pars_vertex"], 
THREE.ShaderChunk["color_pars_vertex"], 
THREE.ShaderChunk["morphtarget_pars_vertex"], 
THREE.ShaderChunk["skinning_pars_vertex"], 
THREE.ShaderChunk["shadowmap_pars_vertex"], 
THREE.ShaderChunk["logdepthbuf_pars_vertex"], 
THREE.ShaderChunk["clipping_planes_pars_vertex"], 

"void main() {", 
    THREE.ShaderChunk["uv_vertex"], 
    THREE.ShaderChunk["uv2_vertex"], 
    THREE.ShaderChunk["color_vertex"], 

    THREE.ShaderChunk["beginnormal_vertex"], 
    THREE.ShaderChunk["morphnormal_vertex"], 
    THREE.ShaderChunk["skinbase_vertex"], 
    THREE.ShaderChunk["skinnormal_vertex"], 
    THREE.ShaderChunk["defaultnormal_vertex"], 

    "#ifndef FLAT_SHADED // Normal computed with derivatives when FLAT_SHADED", 

     "vNormal = normalize(transformedNormal);", 

    "#endif", 
    THREE.ShaderChunk["begin_vertex"], 
    THREE.ShaderChunk["displacementmap_vertex"], 
    THREE.ShaderChunk["morphtarget_vertex"], 
    THREE.ShaderChunk["skinning_vertex"], 
    THREE.ShaderChunk["project_vertex"], 
    THREE.ShaderChunk["logdepthbuf_vertex"], 
    THREE.ShaderChunk["clipping_planes_vertex"], 

    "vUv = uv;", 
    "vViewPosition = - mvPosition.xyz;", 

    THREE.ShaderChunk["worldpos_vertex"], 
    THREE.ShaderChunk["envmap_vertex"], 
    THREE.ShaderChunk["shadowmap_vertex"], 

"}", 
].join("\n"); 

BlendMapFragmentShader = [ 
"#define PHONG", 

"varying vec2 vUv;", 

"uniform vec3 diffuse;", 
"uniform vec3 emissive;", 
"uniform vec3 specular;", 
"uniform float shininess;", 
"uniform float opacity;", 

"uniform sampler2D TextureBlendMap;", 
"uniform sampler2D TextureBackground;", 
"uniform sampler2D TextureR;", 
"uniform sampler2D TextureG;", 
"uniform sampler2D TextureB;", 

THREE.ShaderChunk["common"], 
THREE.ShaderChunk["packing"], 
THREE.ShaderChunk["color_pars_fragment"], 
THREE.ShaderChunk["uv_pars_fragment"], 
THREE.ShaderChunk["uv2_pars_fragment"], 
THREE.ShaderChunk["map_pars_fragment"], 
THREE.ShaderChunk["alphamap_pars_fragment"], 
THREE.ShaderChunk["aomap_pars_fragment"], 
THREE.ShaderChunk["lightmap_pars_fragment"], 
THREE.ShaderChunk["emissivemap_pars_fragment"], 
THREE.ShaderChunk["envmap_pars_fragment"], 
THREE.ShaderChunk["fog_pars_fragment"], 
THREE.ShaderChunk["bsdfs"], 
THREE.ShaderChunk["lights_pars"], 
THREE.ShaderChunk["lights_phong_pars_fragment"], 
THREE.ShaderChunk["shadowmap_pars_fragment"], 
THREE.ShaderChunk["bumpmap_pars_fragment"], 
THREE.ShaderChunk["normalmap_pars_fragment"], 
THREE.ShaderChunk["specularmap_pars_fragment"], 
THREE.ShaderChunk["logdepthbuf_pars_fragment"], 
THREE.ShaderChunk["clipping_planes_pars_fragment"], 

"void main() {", 

    THREE.ShaderChunk["clipping_planes_fragment"], 
    "// THIS IS CUSTOM CODE TO OVERRIDE THE DIFFUSE COLOR WITH BLENDMAP TEXTURES", 
    "vec4 cBlend = texture2D(TextureBlendMap, vUv);", 
    "float bText = 1.0 - (cBlend.r + cBlend.g + cBlend.b);", 
    "vec2 tiledCoords = vUv * 40.0;", 
    "vec4 cBack = texture2D(TextureBackground, tiledCoords) * bText;", 
    "vec4 cR = texture2D(TextureR, tiledCoords) * cBlend.r;", 
    "vec4 cG = texture2D(TextureG, tiledCoords) * cBlend.g;", 
    "vec4 cB = texture2D(TextureB, tiledCoords) * cBlend.b;", 
    "vec4 cTot = cBack + cR + cG + cB;", 

    "vec4 diffuseColor = vec4(diffuse, opacity);", 
    "diffuseColor.r = cTot.r;", 
    "diffuseColor.g = cTot.g;", 
    "diffuseColor.b = cTot.b;", 
    "ReflectedLight reflectedLight = ReflectedLight(vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));", 
    "vec3 totalEmissiveRadiance = emissive;", 

    THREE.ShaderChunk["logdepthbuf_fragment"], 
    THREE.ShaderChunk["map_fragment"], 
    THREE.ShaderChunk["color_fragment"], 
    THREE.ShaderChunk["alphamap_fragment"], 
    THREE.ShaderChunk["alphatest_fragment"], 
    THREE.ShaderChunk["specularmap_fragment"], 
    THREE.ShaderChunk["normal_flip"], 
    THREE.ShaderChunk["normal_fragment"], 
    THREE.ShaderChunk["emissivemap_fragment"], 

    "// accumulation", 
    THREE.ShaderChunk["lights_phong_fragment"], 
    THREE.ShaderChunk["lights_template"], 

    "// modulation", 
    THREE.ShaderChunk["aomap_fragment"], 

    "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;", 

    THREE.ShaderChunk["envmap_fragment"], 

    "gl_FragColor = vec4(outgoingLight, diffuseColor.a);", 

    THREE.ShaderChunk["premultiplied_alpha_fragment"], 
    THREE.ShaderChunk["tonemapping_fragment"], 
    THREE.ShaderChunk["encodings_fragment"], 
    THREE.ShaderChunk["fog_fragment"], 
"}", 
].join("\n"); 
0

C'est un peu un long shot, mais si tous les objets de votre scène utilisent ce matériel, alors il ne devrait pas y avoir de l'ombre parce que rien ne jette des ombres.

mesh.castShadow = false; 
mesh.receiveShadow = true; 

Mais je devine que dans le reste de votre code que vous avez des Meshes mis à projeter des ombres.

Je ne sais pas si je comprends parfaitement les méthodes ShaderChunk, mais il semble que c'est juste une série de chaînes définies que vous laissez tomber au milieu de votre texte, cette partie était un peu suspect:

"gl_FragColor = cTot;", 
THREE.ShaderChunk["shadowmap_fragment"], 

Mais je ne vois pas comment le shadowmap_fragment peut mélanger avec notre valeur existante pour gl_FragColor. Dans le shadowmap_fragment src il fonctionne:

void main() { 

    gl_FragColor = vec4(0.0, 0.0, 0.0, opacity * (1.0 - getShadowMask())); 

} 

où getShadowMask() fait beaucoup de magie avec des lumières pour revenir un flotteur. Je ne vois donc pas comment votre attribut gl_FragColor est mélangé avec ce que renvoie shadowmap_fragment. Qu'en est-il changer l'ordre:

THREE.ShaderChunk["shadowmap_fragment"], 
"gl_FragColor = cTot*gl_FragColor.a;" 

ne sais pas si cela va aider, mais vous pouvez vérifier le src de shadowmap_pars_frag pour voir ce qui se passe dans les coulisses. Peut-être qu'il nous manque quelque chose. Une dernière chose: essayez de faire juste les ombres sans le mélange de texture, pour isoler le problème. Il se peut que vous utilisiez une limite GLSL pour le nombre d'échantillons de texture, car le bloc d'ombre utilise également l'échantillonnage de texture.

+0

Hey! Désolé pour l'attente d'une réponse mais oui, cet objet est un terrain plat donc il ne devrait que recevoir. je suivais ce post sur la façon de jour faire: https://github.com/mrdoob/three.js/issues/1135 J'ai essayé tant de façons d'obtenir ces morceaux de travailler, mais il semble comme si je manquais un morceau quelque part. J'ai même enlevé tous les morceaux et fait une copie de l'ombre et l'ai envoyé en tant que matrice et texture mais ce n'est même pas proche de comment il devrait ressembler xx " – Yenza

+0

J'ai également essayé la ligne avec" gl_FragColor = cTot * gl_FragColor.a ; "mais cela a juste rendu l'objet noirci – Yenza

1

juste ajouter shaderMaterial.lights = true;, je l'avais rencontré le même problème que vous.voici une classe complète dactylographiée écrit par moi-même: threejs git issue

c'est le code complet:

import * as THREE from 'three'; 

export class TerrainMaterial extends THREE.ShaderMaterial { 

    public constructor() { 

     super({ 
      uniforms: THREE.UniformsUtils.merge([ 
       THREE.UniformsLib.fog, 
       THREE.UniformsLib.lights, 
       { 
        diffuse: { value: new THREE.Color(0xeeeeee) }, 
        opacity: { value: 1.0 }, 
        emissive: { value: new THREE.Color(0x000000) }, 
        specular: { value: new THREE.Color(0x111111) }, 
        shininess: { value: 0 }, 

        offsetRepeat: { value: new THREE.Vector4(0, 0, 1, 1) }, 

        map1: { value: null }, 
        map2: { value: null }, 
        map3: { value: null }, 
        map1Normal: { value: null }, 
        map2Normal: { value: null }, 
        map3Normal: { value: null }, 
        map1HeightRange: { value: 0 }, 
        map2HeightRange: { value: 0 }, 
        map3HeightRange: { value: 0 } 
       } 
      ]), 
      vertexShader: [ 
       "varying vec3 vNormal;", 
       "varying vec3 vViewPosition;", 
       "varying vec3 fPosition;", 

       "varying vec2 vUv;", 
       "uniform vec4 offsetRepeat;", 

       THREE.ShaderChunk.shadowmap_pars_vertex, 
       //THREE.ShaderChunk.logdepthbuf_pars_vertex, 
       THREE.ShaderChunk.fog_pars_vertex, 

       "void main(){", 
        THREE.ShaderChunk.beginnormal_vertex, 
        THREE.ShaderChunk.defaultnormal_vertex, 
        "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;", 
        "vNormal = normalize(transformedNormal);", 
        THREE.ShaderChunk.begin_vertex, 
        THREE.ShaderChunk.project_vertex, 
        //THREE.ShaderChunk.logdepthbuf_vertex, 
        "fPosition = position;", 
        "vViewPosition = - mvPosition.xyz;", 
        THREE.ShaderChunk.worldpos_vertex, 
        THREE.ShaderChunk.shadowmap_vertex, 
        THREE.ShaderChunk.fog_vertex, 
       "}" 
      ].join("\n"), 
      fragmentShader: [ 
       "uniform vec3 diffuse;", 
       "uniform vec3 emissive;", 
       "uniform vec3 specular;", 
       "uniform float shininess;", 
       "uniform float opacity;", 

       "uniform sampler2D map1;", 
       "uniform sampler2D map2;", 
       "uniform sampler2D map3;", 
       "uniform sampler2D map1Normal;", 
       "uniform sampler2D map2Normal;", 
       "uniform sampler2D map3Normal;", 
       "uniform float map1HeightRange;", 
       "uniform float map2HeightRange;", 
       "uniform float map3HeightRange;", 

       "varying vec2 vUv;", 
       "varying vec3 fPosition;", 

       THREE.ShaderChunk.common, 
       THREE.ShaderChunk.packing, 
       THREE.ShaderChunk.dithering_pars_fragment, 
       THREE.ShaderChunk.emissivemap_pars_fragment, 
       THREE.ShaderChunk.fog_pars_fragment, 
       THREE.ShaderChunk.bsdfs, 
       THREE.ShaderChunk.lights_pars, 
       THREE.ShaderChunk.lights_phong_pars_fragment, 
       THREE.ShaderChunk.shadowmap_pars_fragment, 
       THREE.ShaderChunk.specularmap_pars_fragment, 
       //THREE.ShaderChunk.logdepthbuf_pars_fragment, 
       "vec3 perturbNormal2Arb(vec3 normalColor, vec3 eye_pos, vec3 surf_norm) {", 
        "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(vUv.st);", 
        "vec2 st1 = dFdy(vUv.st);", 
        "vec3 S = normalize(q0 * st1.t - q1 * st0.t);", 
        "vec3 T = normalize(-q0 * st1.s + q1 * st0.s);", 
        "vec3 N = normalize(surf_norm);", 
        "vec3 mapN = normalColor * 2.0 - 1.0;", 
        //"mapN.xy = normalScale * mapN.xy;", 
        "mat3 tsn = mat3(S, T, N);", 
        "return normalize(tsn * mapN);", 
       "}", 
       "void main(){", 
        "vec4 diffuseColor = vec4(diffuse, opacity);", 
        "ReflectedLight reflectedLight = ReflectedLight(vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));", 
        "vec3 totalEmissiveRadiance = emissive;", 
        //THREE.ShaderChunk.logdepthbuf_fragment, 

        "vec3 texel;", 
        "vec3 texelNormal;", 
        "float amount;", 

        //need to optimize here, let's say remove if else if else? 
        "if(fPosition.y < map1HeightRange){", 
         "texel = texture2D(map1, vUv).rgb;", 
         "texelNormal = texture2D(map1Normal, vUv).rgb;", 
        "}", 
        "else if(fPosition.y < map2HeightRange){", 
         "amount = (fPosition.y - map1HeightRange)/map1HeightRange;", 
         "texel = mix(texture2D(map1, vUv), texture2D(map2, vUv), amount).rgb;", 
         "texelNormal = mix(texture2D(map1Normal, vUv), texture2D(map2Normal, vUv), amount).rgb;", 
        "}", 
        "else if(fPosition.y < map3HeightRange){", 
         "float hStep = map3HeightRange - map2HeightRange;", 
         "amount = (fPosition.y - hStep)/hStep;", 
         "texel = mix(texture2D(map2, vUv), texture2D(map3, vUv), amount).rgb;", 
         "texelNormal = mix(texture2D(map2Normal, vUv), texture2D(map3Normal, vUv), amount).rgb;", 
        "} else {", 
         "texel = texture2D(map3, vUv).rgb;", 
         "texelNormal = texture2D(map3Normal, vUv).rgb;", 
        "}", 

        "vec4 texelColor = vec4(texel, 1.0);", 
        "texelColor = mapTexelToLinear(texelColor);", 

        "diffuseColor *= texelColor;", 

        THREE.ShaderChunk.specularmap_fragment, 
        "vec3 normal = normalize(vNormal);", 
        "normal = perturbNormal2Arb(texelNormal.rgb, -vViewPosition, normal);", 

        THREE.ShaderChunk.emissivemap_fragment, 
        THREE.ShaderChunk.lights_phong_fragment, 
        THREE.ShaderChunk.lights_template, 
        "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;", 
        "gl_FragColor = vec4(outgoingLight, diffuseColor.a);", 
        THREE.ShaderChunk.tonemapping_fragment, 
        THREE.ShaderChunk.encodings_fragment, 
        THREE.ShaderChunk.fog_fragment, 
        THREE.ShaderChunk.premultiplied_alpha_fragment, 
        THREE.ShaderChunk.dithering_fragment, 
       "}" 
      ].join("\n") 
     }); 

     this.defaultAttributeValues = null; 

     this.fog = true; 
     this.lights = true; 

     this.extensions.derivatives = true; 
     this.extensions.shaderTextureLOD = true; 
    } 

    public setOffsetRepeat(ofX: number, ofY: number, rpX: number, rpY: number):void { 
     this.uniforms["offsetRepeat"].value.set(ofX, ofY, rpX, rpY); 
     this.setRepeat(this.uniforms["map1"].value, this.uniforms["map1Normal"].value); 
     this.setRepeat(this.uniforms["map2"].value, this.uniforms["map2Normal"].value); 
     this.setRepeat(this.uniforms["map3"].value, this.uniforms["map3Normal"].value); 
     this.needsUpdate = true; 
    } 

    private setRepeat(map: THREE.Texture, normal: THREE.Texture): void { 
     let v4: THREE.Vector4 = this.uniforms["offsetRepeat"].value; 
     if (v4.y != 1 || v4.z != 1) { 
      if (map) map.wrapS = map.wrapT = THREE.RepeatWrapping; 
      if (normal) normal.wrapS = normal.wrapT = THREE.RepeatWrapping; 
     } 
    } 

    public setMap1(map: THREE.Texture, normal: THREE.Texture, heightRange: number) { 
     this.setRepeat(map, normal); 
     this.uniforms["map1"].value = map; 
     this.uniforms["map1Normal"].value = normal; 
     this.uniforms["map1HeightRange"].value = heightRange; 
     this.needsUpdate = true; 
    } 

    public setMap2(map: THREE.Texture, normal: THREE.Texture, heightRange: number) { 
     this.setRepeat(map, normal); 
     this.uniforms["map2"].value = map; 
     this.uniforms["map2Normal"].value = normal; 
     this.uniforms["map2HeightRange"].value = heightRange; 
     this.needsUpdate = true; 
    } 

    public setMap3(map: THREE.Texture, normal: THREE.Texture, heightRange: number) { 
     this.setRepeat(map, normal); 
     this.uniforms["map3"].value = map; 
     this.uniforms["map3Normal"].value = normal; 
     this.uniforms["map3HeightRange"].value = heightRange; 
     this.needsUpdate = true; 
    } 
} 

et l'utilisation:

let loader = new THREE.TextureLoader(); 
let terrainMat = new TerrainMaterial(); 
terrainMat.dithering = Config.DITHERING; 
terrainMat.setOffsetRepeat(0, 0, 80, 80); 
let map1 = loader.load("images/maps/ground/shatter.jpg"); 
let map1Normal = loader.load("images/maps/ground/shatter_normal.png"); 
map1.anisotropy = map1Normal.anisotropy = anisotropy; 
let map2 = loader.load("images/maps/ground/earth.jpg"); 
let map2Normal = loader.load("images/maps/ground/earth_normal.png"); 
map2.anisotropy = map2Normal.anisotropy = anisotropy; 
let map3 = loader.load("images/maps/ground/moss.jpg"); 
let map3Normal = loader.load("images/maps/ground/moss_normal.png"); 
map3.anisotropy = map3Normal.anisotropy = anisotropy; 
let hStep = GroundGeometry.MAX_HEIGHT/4; 
terrainMat.setMap1(map1, map1Normal, hStep); 
terrainMat.setMap2(map2, map2Normal, hStep * 2); 
terrainMat.setMap3(map3, map3Normal, hStep * 4); 

//note: replace new THREE.PlaneGeometry with your terrain geometry so the mateiral can detect height change. otherise the plane will be filled full with the same 1 map. 
let p = new THREE.Mesh(new THREE.PlaneGeometry(900, 900, 257, 257), terrainMat); 
p.geometry.rotateX(-NumberConsts.PI_2); 
scene.add(p); 

et le résultat: click to see image (i don't have the privilege to embed images yet)

+0

Oui, j'ai fait la même chose quand je l'ai finalement résolu! Vérifiez ma réponse ci-dessous: " shaderMaterial = new THREE.ShaderMaterial ({ lights: true, " – Yenza