Три 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;
для вашего материала шейдера.
Конечно, если вы знаете, что собираетесь писать свой собственный шейдер, и вам не нужно динамическое включение различных фрагментов шейдера, вы можете просто написать шейдер явно, и вам не нужно беспокоиться об этом.