IceCreamYou/THREE.Terrain

Using flat shading

MauJFernandezUVR opened this issue · 5 comments

Hi, I'm trying to use 'shading: THREE.FlatShading' but it's not working, have you got it to work on you example?

Thanks and awesome library, it really helped me a lot.

Can you provide more details on what you're doing? What kind of material are you using? Providing the code you're using to instantiate the material would be helpful.

Note that THREE.FlatShading has been removed from THREE.MeshLambertMaterial in r72, if you are using the latter you need to use THREE.MeshPhongMaterial. It may be back later. mrdoob/three.js#7130

@IceCreamYou Hi, for now I was just using the same code as you have in the demo for testing purposes, I even tried modifying it but still no results. In the terrain params I added the shading: THREE.FlatShading to test it.

@Astrak As in the demo, I'm using generateBlendedMaterial for the textures, which internally returns a THREE.ShaderMaterial, if mrdoob just removed it from THREE.MeshLambertMaterial it should be there for THREE.ShaderMaterial.

Here's the code:

'use strict';

define(['Three', 'Scenes', 'World'], function(THREE, scenes, world) {
    var heightmapImage = new Image();
    heightmapImage.src = 'client/assets/img/heightmap.png';

    var blend;
    var init = function() {

        THREE.ImageUtils.loadTexture('client/assets/img/sand1.jpg', undefined, function(t1) {
            t1.wrapS = t1.wrapT = THREE.RepeatWrapping;
            var sand = new THREE.Mesh(
                new THREE.PlaneBufferGeometry(1024, 1024, 64, 64),
                new THREE.MeshLambertMaterial({map: t1})
            );

            sand.position.y = -101;
            sand.rotation.x = -0.5 * Math.PI;
            //scene.getScene().add(sand);
            THREE.ImageUtils.loadTexture('client/assets/img/grass1.jpg', undefined, function(t2) {
                t2.wrapS = t2.wrapT = THREE.RepeatWrapping;
                THREE.ImageUtils.loadTexture('client/assets/img/stone1.jpg', undefined, function(t3) {
                    t3.wrapS = t3.wrapT = THREE.RepeatWrapping;
                    THREE.ImageUtils.loadTexture('client/assets/img/snow1.jpg', undefined, function(t4) {
                        t4.wrapS = t4.wrapT = THREE.RepeatWrapping;

                        // t2.repeat.x = t2.repeat.y = 2;
                        blend = THREE.Terrain.generateBlendedMaterial([
                            {texture: t1},
                            {texture: t2, levels: [-80, -35, 20, 50]},
                            {texture: t3, levels: [20, 50, 60, 85]},
                            {texture: t4, glsl: '1.0 - smoothstep(65.0 + smoothstep(-256.0, 256.0, vPosition.x) * 10.0, 80.0, vPosition.z)'},

                            // between 27 and 45 degrees
                            {texture: t3, glsl: 'slope > 0.7853981633974483 ? 0.2 : 1.0 - smoothstep(0.47123889803846897, 0.7853981633974483, slope) + 0.2'}

                        ]);

                        regenerate();
                    });
                });
            });
        });
    };

    var regenerate = function() {
        var terrainSettings = {
            easing: THREE.Terrain.EaseInOut,
            heightmap: heightmapImage,
            material: blend,
            texture: 'Blended',
            maxHeight: 100,
            minHeight: -100,
            shading: THREE.FlatShading,
            steps: 1,
            stretch: true,
            turbulent: false,
            useBufferGeometry: false,
            xSize: 1024,
            ySize: 1024,
            xSegments: 20,
            ySegments: 20,
        };

        var terrain = THREE.Terrain(terrainSettings);

        terrain.scale.set(2, 2, 2);
        terrain.position.set(0, -1000, 0);

        scenes.getScene().add(terrain);
    };

    world.onInit(init);

});

A few things

  • The THREE.ShaderMaterial that generateBlendedMaterial returns is effectively a THREE.MeshLambertMaterial with an unusual texture. It uses the same common shader snippets. So if something was removed from Lambert materials in Three.js r72, it is probably also gone from the blended material. And there is not really anything I can do to put it back, because the code in question was removed from the renderer, not from the material itself.
  • Adding a shading parameter to the options you pass to the THREE.Terrain function does not affect the material that the terrain uses. If you want to change the material, you need to do it directly, by changing the shading attribute of the blend object.
  • I would like to add the ability to generate a blended Phong material, and Phong materials still have flat shading. So at some point that will help.

Awesome, thanks for the info!