2012-08-23 19 views
11

Sto lavorando alla creazione di uno shader per generare il terreno con le ombre.Three js - Clonazione di uno shader e modifica dei valori uniformi

Il mio punto di partenza è clonare lo shader lambert e utilizzare uno ShaderMaterial per eventualmente personalizzarlo con il mio script.

Il metodo standard funziona bene:

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

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

etc 

Il risultato: Result with standard lambert material

Tuttavia Vorrei utilizzare il materiale Lambert come base e lavorare su di esso, così ho provato questo :

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); 

Il risultato per questo uno: Result for cloning lambert shader and changing map uniforms

Sembra che lo shader non tenga conto della nuova texture che ho aggiunto, tuttavia guardando l'ispettore quando ho registrato le uniformi, l'oggetto della mappa ha i valori corretti.

Sono quasi nuovo a tre quindi potrei fare qualcosa di fondamentalmente sbagliato, se qualcuno potesse indicarmi la giusta direzione qui, sarebbe fantastico.

Posso anche aggiungere collegamenti dimostrativi se ciò sarebbe utile?

Grazie, Will

EDIT:

Ecco alcuni link demo.

demo con materiale Shader: http://dev.thinkjam.com/experiments/threejs/terrain/terrain-shader-material.html

Demo con il lavoro materiale Lambert: http://dev.thinkjam.com/experiments/threejs/terrain/terrain-lambert-material.html

+0

Sì, i collegamenti dimostrativi sarebbero davvero utili. – mrdoob

+0

Ciao mrdoob, evviva la risposta veloce. Ho aggiunto link dimostrativi al post. Se riesci a far luce su questo, sarebbe fantastico – WillDonohoe

+0

Ho notato alcune funzionalità all'interno del renderer webgl specifico di TRE.MeshLambertMaterial che non si verifica con THREE.ShaderMaterial. In particolare con uniformi rinfrescanti. https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L4858 Questa è solo una pugnalata al buio qui, ma è qualcosa che potrebbe causare problemi ? – WillDonohoe

risposta

8

La ragione per cui questo non funziona è lo shader di default Three.js Lambert utilizza il preprocessore macro direttiva #ifdef per determinare se utilizzare mappe, envmaps, mappe di luce, ecc.

Il WebGLRenderer Three.js imposta le direttive di preprocessore appropriate (#define) per abilitare queste parti degli shader in base alla presenza di determinate proprietà sul materiale oggetto.

Se si sta impostando l'approccio alla clonazione di & modificando gli shader predefiniti, sarà necessario impostare proprietà pertinenti sul materiale. Per le mappe di texture, il Three.js WebGLRenderer.js ha questa linea:

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

in modo da provare l'impostazione material.map = true; per il vostro materiale shader.

Naturalmente, se sai che stai scrivendo il tuo shader e non hai bisogno dell'inclusione dinamica di vari frammenti di shader, puoi semplicemente scrivere lo shader in modo esplicito e non dovrai preoccuparti di Questo.

+1

Grazie @fuzic! – WillDonohoe