Die Methode zum Übergeben einer Farbe an den in MeshLambertMaterial verwendeten Fragment-Shader-Code bestand darin, die diffuseColor-Variable zu ändern. Sie können also die Farbe im Fragment-Shader mit diffuseColor.rgb * = aVec3 festlegen. Hier ist, was mein Shader-Code wie folgt aussieht:
// vertex
#define LAMBERT
varying vec3 vLightFront;
#ifdef DOUBLE_SIDED
varying vec3 vLightBack;
#endif
#include <common>
#include <uv_pars_vertex>
#include <uv2_pars_vertex>
#include <envmap_pars_vertex>
#include <bsdfs>
#include <lights_pars>
#include <color_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
varying vec3 vertexColor;
varying vec2 vUv;
varying vec4 worldPosition;
void main() {
vertexColor = vec3(255, 100, 0);
vUv = uv;
worldPosition = modelMatrix * vec4(position, 1.0);
#include <uv_vertex>
#include <uv2_vertex>
#include <color_vertex>
#include <beginnormal_vertex>
#include <morphnormal_vertex>
#include <skinbase_vertex>
#include <skinnormal_vertex>
#include <defaultnormal_vertex>
#include <begin_vertex>
#include <morphtarget_vertex>
#include <skinning_vertex>
#include <project_vertex>
#include <logdepthbuf_vertex>
#include <clipping_planes_vertex>
#include <worldpos_vertex>
#include <envmap_vertex>
#include <lights_lambert_vertex>
#include <shadowmap_vertex>
}
// fragment
uniform float time;
varying vec2 vUv;
vec4 permute(vec4 x) {
return mod(((x * 34.0) + 1.0) * x, 289.0);
}
vec4 taylorInvSqrt(vec4 r) {
return 1.79284291400159 - 0.85373472095314 * r;
}
float snoise(vec3 v) {
const vec2 C = vec2(1.0/6.0, 1.0/3.0);
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
// First corner
vec3 i = floor(v + dot(v, C.yyy));
vec3 x0 = v - i + dot(i, C.xxx);
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min(g.xyz, l.zxy);
vec3 i2 = max(g.xyz, l.zxy);
vec3 x1 = x0 - i1 + 1.0 * C.xxx;
vec3 x2 = x0 - i2 + 2.0 * C.xxx;
vec3 x3 = x0 - 1. + 3.0 * C.xxx;
// Permutations
i = mod(i, 289.0);
vec4 p = permute(permute(permute(
i.z + vec4(0.0, i1.z, i2.z, 1.0))
+ i.y + vec4(0.0, i1.y, i2.y, 1.0))
+ i.x + vec4(0.0, i1.x, i2.x, 1.0));
// Gradients
// (N*N points uniformly over a square, mapped onto an octahedron.)
float n_ = 1.0/7.0; // N=7
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_); // mod(j,N)
vec4 x = x_ *ns.x + ns.yyyy;
vec4 y = y_ *ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4(x.xy, y.xy);
vec4 b1 = vec4(x.zw, y.zw);
vec4 s0 = floor(b0) * 2.0 + 1.0;
vec4 s1 = floor(b1) * 2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
vec3 p0 = vec3(a0.xy, h.x);
vec3 p1 = vec3(a0.zw, h.y);
vec3 p2 = vec3(a1.xy, h.z);
vec3 p3 = vec3(a1.zw, h.w);
// Normalise gradients
vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
m = m * m;
return 42.0 * dot(m*m, vec4(dot(p0, x0), dot(p1, x1),
dot(p2, x2), dot(p3, x3)));
}
varying vec4 worldPosition;
uniform vec3 diffuse;
uniform vec3 emissive;
uniform float opacity;
varying vec3 vLightFront;
#ifdef DOUBLE_SIDED
varying vec3 vLightBack;
#endif
#include <common>
#include <packing>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <uv2_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <envmap_pars_fragment>
#include <bsdfs>
#include <lights_pars>
#include <fog_pars_fragment>
#include <shadowmap_pars_fragment>
#include <shadowmask_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
float sigmoid(float x) {
return x/(1.0 + abs(x));
}
varying vec3 vertexColor;
void main() {
#include <clipping_planes_fragment>
vec4 diffuseColor = vec4(diffuse, opacity);
ReflectedLight reflectedLight = ReflectedLight(vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0));
vec3 totalEmissiveRadiance = emissive;
#include <logdepthbuf_fragment>
#include <map_fragment>
if(worldPosition.y > 300.0) { //snow
float noise = snoise(vec3(worldPosition.x * 4.0, worldPosition.y * 4.0, worldPosition.z * 4.0))/20.0;
diffuseColor.rgb *= vec3(1.0 - noise, 1.0 - noise, 1.0 - noise);
}
else if (worldPosition.y > 100.0) { // dirt
float scale = 5.0;
float effectscale = 0.2;
float noise = (snoise(vec3(worldPosition.x * scale, worldPosition.y * scale, worldPosition.z * scale)) - 0.2) * effectscale;
noise = sigmoid(noise);
diffuseColor.rgb *= vec3(0.54 + noise, 0.27 + noise, 0.07 + noise);
}
else { // grass
float scale = 4.0;
float effectscale = 0.08;
float noise = (snoise(vec3(worldPosition.x * scale, worldPosition.y * scale, worldPosition.z * scale)) - 0.2) * effectscale;
diffuseColor.rgb *= vec3(0, 0.48 + noise, 0.05 + noise);
}
#include <color_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <specularmap_fragment>
#include <emissivemap_fragment>
// accumulation
reflectedLight.indirectDiffuse = getAmbientLightIrradiance(ambientLightColor);
#include <lightmap_fragment>
reflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert(diffuseColor.rgb);
#ifdef DOUBLE_SIDED
reflectedLight.directDiffuse = (gl_FrontFacing) ? vLightFront : vLightBack;
#else
reflectedLight.directDiffuse = vLightFront;
#endif
reflectedLight.directDiffuse *= BRDF_Diffuse_Lambert(diffuseColor.rgb) * getShadowMask();
// modulation
#include <aomap_fragment>
vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;
#include <normal_flip>
#include <envmap_fragment>
gl_FragColor = vec4(outgoingLight, diffuseColor.a);
#include <premultiplied_alpha_fragment>
#include <tonemapping_fragment>
#include <encodings_fragment>
#include <fog_fragment>
}
Das Ergebnis nicht so toll sieht aber das Konzept einen benutzerdefinierten Shader mit Beleuchtung zu haben, ist es. Alles, was Sie tun müssen, ist über den Code in der MeshLambertShader kopieren und ändern diffuseColor.rgb
. Um die Menge an Code in Ihrem Shader zu reduzieren, könnten Sie Shader-Chunks (unter Verwendung des THREE.ShaderChunk-Arrays) des MeshLambert-Shader-Codes hinzufügen. Dann könntest du #includes in deinem Shader hinzufügen, die den Namen der Shader-Chunks entsprechen, die du gerade gedrückt hast.
THREE.ShaderChunk["meshlambert_premain_fragment"] = `
uniform vec3 diffuse;
uniform vec3 emissive;
uniform float opacity;
varying vec3 vLightFront;
#ifdef DOUBLE_SIDED
varying vec3 vLightBack;
#endif
#include <common>
#include <packing>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <uv2_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <envmap_pars_fragment>
#include <bsdfs>
#include <lights_pars>
#include <fog_pars_fragment>
#include <shadowmap_pars_fragment>
#include <shadowmask_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
`;
Und später, im Shader, dass Sie die MeshLambert Beleuchtung verwenden mögen, können Sie die folgenden, sehr zur Verringerung der Menge an Code in Ihren Shader schreiben: Zum Beispiel könnten Sie die folgende in der JavaScript-Datei hinzufügen Datei:
#include <meshlambert_premain_fragment>
einige [ShaderMaterial Beispiele hier] (http://blog.2pha.com/experimenting-threejs-shaders-and-shadermaterial), darunter einige mit [Beleuchtung] (http: //blog.2pha. com/demos/threejs/shaders/single_color_point_lights.html) – 2pha
@ 2pha Das sind einige gute Beispiele, aber die Beleuchtung, die du verlinkt hast, war veraltet, da die Variable MAX_POINT_LIGHTS nicht mehr existiert benutzt. Zusätzlich unterstützt es nur Punktlichter, im Gegensatz zu MeshLambertMaterial, das alle three.js-Lichter unterstützt. – epitaque
Oh, ich habe mir gerade das aktuelle MechLambertMaterial angesehen, die Materialien sind etwas komplizierter als früher. – 2pha