Три js - клонирование шейдера и изменение равномерных значений

Я работаю над созданием шейдера для создания ландшафта с тенями.

Моя начальная точка - клонировать шейдер lambert и использовать ShaderMaterial, чтобы в конечном итоге настроить его со своим собственным script.

Стандартный метод работает хорошо:

var material = new MeshLambertMaterial({map:THREE.ImageUtils.loadTexture('images/texture.jpg')});

var mesh = new THREE.Mesh(geometry, material);

etc

Результат: Result with standard lambert material

Однако я хотел бы использовать материал lambert в качестве основы и работать над ним, поэтому я попробовал это:

var lambertShader = THREE.ShaderLib['lambert'];
var uniforms = THREE.UniformsUtils.clone(lambertShader.uniforms);

var texture = THREE.ImageUtils.loadTexture('images/texture.jpg');
uniforms['map'].texture = texture;

var material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: lambertShader.vertexShader,
    fragmentShader: lambertShader.fragmentShader,
    lights:true,
    fog: true
});

var mesh = new THREE.Mesh(geometry, material);

Результат для этого: Result for cloning lambert shader and changing map uniforms

Похоже, что шейдер не учитывает новую текстуру, которую я добавил, однако, глядя на инспектора, когда я регистрировал униформу, объект карты имеет правильные значения.

Я новичок в трех, поэтому я мог бы сделать что-то принципиально неправильное, если бы кто-то мог указать мне в правильном направлении здесь, это было бы здорово.

Я также могу разместить демонстрационные ссылки, если это было бы полезно?

Спасибо, Будет ли

EDIT:

Вот несколько демонстрационных ссылок.

Демо с шейдерным материалом: http://dev.thinkjam.com/experiments/threejs/terrain/terrain-shader-material.html

Демо с рабочим материалом lambert: http://dev.thinkjam.com/experiments/threejs/terrain/terrain-lambert-material.html

Ответ 1

Причина, по которой это не работает, заключается в том, что по умолчанию тэг..s.s.s.s.sys использует макрокоманду препроцессора #ifdef, чтобы определить, следует ли использовать карты, envmaps, lightmaps и т.д. и т.д.

TheThere.js WebGLRenderer устанавливает соответствующие директивы препроцессора (#define), чтобы включить эти части шейдеров на основе того, существуют ли определенные свойства на материальном объекте.

Если вы настроились на подход клонирования и изменение шейдеров по умолчанию, вам нужно будет установить соответствующие свойства на материале. Для текстурных карт у Three.js WebGLRenderer.js есть эта строка:

parameters.map ? "#define USE_MAP" : ""

Итак, попробуйте установить material.map = true; для вашего материала шейдера.

Конечно, если вы знаете, что собираетесь писать свой собственный шейдер, и вам не нужно динамическое включение различных фрагментов шейдера, вы можете просто написать шейдер явно, и вам не нужно беспокоиться об этом.