2012-08-23 5 views
11

Ich arbeite an der Erstellung eines Shaders, um Gelände mit Schatten zu erzeugen.Drei js - Einen Shader klonen und einheitliche Werte ändern

Mein Ausgangspunkt ist, den Lambert Shader zu klonen und ein ShaderMaterial zu verwenden, um es schließlich mit meinem eigenen Skript anzupassen.

Die Standard-Methode funktioniert gut:

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

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

etc 

Das Ergebnis: Result with standard lambert material

aber ich möchte das lambert Material als Basis und Arbeit auf es zu benutzen, so habe ich versucht, diese :

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

Das Ergebnis für diese: Result for cloning lambert shader and changing map uniforms

Es sieht so aus, als ob der Shader die neue Textur, die ich hinzugefügt habe, nicht berücksichtigt, aber wenn ich die Inspektoren anschaue, wenn ich die Uniformen protokolliert habe, hat das Map-Objekt die korrekten Werte.

Ich bin ziemlich neu zu drei, also könnte ich etwas fundamental falsch machen, wenn mir jemand hier in die richtige Richtung zeigen könnte, das wäre toll.

Ich kann auch Demo-Links aufstellen, wenn das hilfreich wäre?

Danke, Will

EDIT:

Hier sind einige Demo-Links.

Demo mit Shader Material: http://dev.thinkjam.com/experiments/threejs/terrain/terrain-shader-material.html

Demo mit Arbeits lambert Material: http://dev.thinkjam.com/experiments/threejs/terrain/terrain-lambert-material.html

+0

Yup, Demo-Links wäre in der Tat hilfreich. – mrdoob

+0

Hi mrdoob, Prost für die schnelle Antwort. Ich habe Demo-Links zum Beitrag hinzugefügt. Wenn Sie Licht darauf werfen können, wäre das erstaunlich. – WillDonohoe

+0

Ich habe bemerkt, einige Funktionen innerhalb der WebGL Renderer spezifisch für drei.MeshLambertMaterial, das nicht mit THREE.ShaderMaterial auftritt. Besonders mit erfrischenden Uniformen. https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L4858 Dies ist nur ein Stich im Dunkeln hier, aber das ist etwas, das Probleme verursachen könnte ? – WillDonohoe

Antwort

8

Der Grund dies nicht funktioniert, ist der Standard-Three.js lambert Shader verwendet die Präprozessormakro Richtlinie #ifdef, um festzustellen, ob Verwenden Sie Maps, Envmaps, Lightmaps usw. usw.

Der Three.js WebGLRenderer legt die entsprechenden Präprozessordirektiven (#define) fest, um diese Teile der Shader basierend darauf zu aktivieren, ob bestimmte Eigenschaften im Material vorhanden sind Objekt.

Wenn Sie den Ansatz des Klonens & modifizieren die Standard-Shader ändern, müssen Sie relevante Eigenschaften für das Material festlegen. Für Texturkarten, hat die Three.js WebGLRenderer.js diese Zeile:

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

versuchen So material.map = true; für Ihre Shader Material einstellen.

Natürlich, wenn Sie wissen, dass Sie Ihren eigenen Shader schreiben werden und Sie nicht die dynamische Einbindung verschiedener Shader-Snippets benötigen, können Sie den Shader explizit schreiben und Sie müssen sich keine Sorgen machen Dies.

+1

Danke @fuzic! – WillDonohoe