Custom shader with shadow?

materials
shaders
shadow

#1

I searched google , this SO https://stackoverflow.com/questions/43528748/threejs-r85-custom-shader-with-shadowmap
and this https://stackoverflow.com/questions/18962155/getting-shadows-to-work-in-three-js-custom-shader,
seem like I need add some predefined code in THREE.ShaderChunk, so I write this code

	<script id="fs" type="x-shader/x-fragment">
	uniform vec3 topColor;
	uniform vec3 bottomColor;
	varying vec2 vUv;


	void main(void) {
	THREE.ShaderChunk["shadowmap_pars_fragment"];
	THREE.ShaderChunk["shadowmap_fragment"];
		gl_FragColor = vec4(mix(topColor, bottomColor, vUv.y), 1.0);
	}
	</script>
	<script id="vs" type="x-shader/x-vertex">
	varying vec2 vUv;
	void main() {
		vUv = uv;
			THREE.ShaderChunk["shadowmap_pars_vertex"];
			THREE.ShaderChunk["shadowmap_vertex"];
		gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
	}
	</script>

and

				var vs = document.getElementById('vs').textContent;
			var fs = document.getElementById('fs').textContent;
			var uniforms = THREE.UniformsUtils.merge([
				THREE.UniformsLib["shadowmap"],
				{
					"topColor" : {
						type : "c",
						value : new THREE.Color(0xff0000)
					}, 
					"bottomColor" : {
						type : "c",
						value : new THREE.Color(0x00ff00)
					},
				}
			]);
				var material = new THREE.ShaderMaterial({
				// var material = new THREE.ShadowMaterial({
					uniforms : uniforms,
					vertexShader : vs,
					fragmentShader : fs
				});

but I get error:
https://imgur.com/4m1CkZ8https://imgur.com/4m1CkZ8
I could not find a particular wrong point, please give me some guide


#2

Someone correct me if I’m wrong, but I’m pretty sure the “pars” chunks need to be above the “void main” call.

Also, I think ‘shadowmap_vertex’ needs to be after the “gl_Position =”.

This is mine and it works (at least for receiving shadows):

	this.lambertVertex = [

	'#define LAMBERT',

	'varying vec3 vLightFront;',

	'#ifdef DOUBLE_SIDED',
		'varying vec3 vLightBack;',
	'#endif',

	this.pars_vertex_common,

	this.instancing ? this.instanced_pars_vertex : this.standard_pars_vertex,

	THREE.ShaderChunk[ "common" ],
	THREE.ShaderChunk[ "uv_pars_vertex" ],
	THREE.ShaderChunk[ "uv2_pars_vertex" ],
	//THREE.ShaderChunk[ "envmap_pars_vertex" ],
	THREE.ShaderChunk[ "bsdfs" ],
	THREE.ShaderChunk[ "lights_pars_begin" ],
	THREE.ShaderChunk[ "lights_pars_maps" ],
	THREE.ShaderChunk[ "color_pars_vertex" ],
	THREE.ShaderChunk[ "fog_pars_vertex" ],
	//THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
	//THREE.ShaderChunk[ "skinning_pars_vertex" ],
	THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
	//THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
	//THREE.ShaderChunk[ "clipping_planes_pars_vertex" ],

	'void main() {',

		THREE.ShaderChunk[ "uv_vertex" ],
		THREE.ShaderChunk[ "uv2_vertex" ],
		THREE.ShaderChunk[ "color_vertex" ],
		THREE.ShaderChunk[ "beginnormal_vertex" ],
		//THREE.ShaderChunk[ "morphnormal_vertex" ],
		//THREE.ShaderChunk[ "skinbase_vertex" ],
		//THREE.ShaderChunk[ "skinnormal_vertex" ],
		THREE.ShaderChunk[ "defaultnormal_vertex" ],
		THREE.ShaderChunk[ "begin_vertex" ],

		this.animation_vertex,

		this.instancing ? this.instanced_vertex : '',

		//THREE.ShaderChunk[ "morphtarget_vertex" ],
		//THREE.ShaderChunk[ "skinning_vertex" ],
		THREE.ShaderChunk[ "project_vertex" ],
		//THREE.ShaderChunk[ "logdepthbuf_vertex" ],
		//THREE.ShaderChunk[ "clipping_planes_vertex" ],
		THREE.ShaderChunk[ "worldpos_vertex" ],
		//THREE.ShaderChunk[ "envmap_vertex" ],
		THREE.ShaderChunk[ "lights_lambert_vertex" ],
		THREE.ShaderChunk[ "shadowmap_vertex" ],
		THREE.ShaderChunk[ "fog_vertex" ],

	'}'

].join('\n');

	this.lambertFragment = [

	'uniform vec3 diffuse;',
	'uniform vec3 emissive;',
	'uniform float opacity;',
	'varying vec3 vLightFront;',

	this.pars_fragment,

	'#ifdef DOUBLE_SIDED',
		'varying vec3 vLightBack;',
	'#endif',

	THREE.ShaderChunk[ "common" ],
	THREE.ShaderChunk[ "packing" ],
	THREE.ShaderChunk[ "dithering_pars_fragment" ],
	THREE.ShaderChunk[ "color_pars_fragment" ],
	THREE.ShaderChunk[ "uv_pars_fragment" ],
	THREE.ShaderChunk[ "uv2_pars_fragment" ],
	THREE.ShaderChunk[ "map_pars_fragment" ],
	//THREE.ShaderChunk[ "alphamap_pars_fragment" ],
	//THREE.ShaderChunk[ "aomap_pars_fragment" ],
	//THREE.ShaderChunk[ "lightmap_pars_fragment" ],
	//THREE.ShaderChunk[ "emissivemap_pars_fragment" ],
	//THREE.ShaderChunk[ "envmap_pars_fragment" ],
	THREE.ShaderChunk[ "bsdfs" ],
	THREE.ShaderChunk[ "lights_pars_begin" ],
	THREE.ShaderChunk[ "lights_pars_maps" ],
	THREE.ShaderChunk[ "fog_pars_fragment" ],
	THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
	THREE.ShaderChunk[ "shadowmask_pars_fragment" ],
	//THREE.ShaderChunk[ "specularmap_pars_fragment" ],
	//THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
	//THREE.ShaderChunk[ "clipping_planes_pars_fragment" ],

	'void main() {',

		//THREE.ShaderChunk[ "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;',

		//THREE.ShaderChunk[ "logdepthbuf_fragment" ],

		//THREE.ShaderChunk[ "map_fragment" ],

		this.map_fragment,

		'if (texelColor[0] < threshold && texelColor[1] < threshold && texelColor[2] < threshold) {',

			'discard;',

		'} else {',

			THREE.ShaderChunk[ "color_fragment" ],

			//THREE.ShaderChunk[ "alphamap_fragment" ],

			THREE.ShaderChunk[ "alphatest_fragment" ],

			//THREE.ShaderChunk[ "specularmap_fragment" ],

			//THREE.ShaderChunk[ "emissivemap_fragment" ],

			'reflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );',

			//THREE.ShaderChunk[ "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();',

			//THREE.ShaderChunk[ "aomap_fragment" ],

			'vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;',

			//THREE.ShaderChunk[ "envmap_fragment" ],

			'gl_FragColor = vec4( outgoingLight, diffuseColor.a );',

			//THREE.ShaderChunk[ "tonemapping_fragment" ],

			THREE.ShaderChunk[ "encodings_fragment" ],

			THREE.ShaderChunk[ "fog_fragment" ],

			THREE.ShaderChunk[ "premultiplied_alpha_fragment" ],

			THREE.ShaderChunk[ "dithering_fragment" ],

		'}',

	'}'

].join('\n');

#3

Thanks for you reply, I changed my code accroding to your instruction, it now compilers, but the there is still no shadows, It will be very helpful if there is an official example , unfortunately, there is not :disappointed_relieved:


#4

Do you have a Directional or Spotlight setup to cast shadows?

What does your javascript look like?

BTW, I want to mention… I stupidly replaced for example: #include <common> with THREE.ShaderChunk[ "common" ]. You do not need to do this. The includes work fine in ShaderMaterial.


#5
					var mat = new THREE.ShaderMaterial({
					uniforms: THREE.UniformsUtils.merge([
						THREE.UniformsLib["shadowmap"],
						{
							"topColor" : {
								type : "c",
								value : new THREE.Color(0xff0000)
							}, 
							"bottomColor" : {
								type : "c",
								value : new THREE.Color(0x00ff00)
							},
						},
						THREE.UniformsLib.lights
					]),
					vertexShader: [
						"varying vec2 vUv;",

						THREE.ShaderChunk[ "common" ],
						THREE.ShaderChunk[ "shadowmap_pars_vertex" ],

						"void main(){",
						THREE.ShaderChunk[ "begin_vertex" ],
							"vUv = uv;",
							"gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
							THREE.ShaderChunk[ "worldpos_vertex" ],
							THREE.ShaderChunk.shadowmap_vertex,
						"}"
					].join("\n"),
					fragmentShader: [
						THREE.ShaderChunk[ "common" ],
						THREE.ShaderChunk[ "packing" ],
						"uniform vec3 topColor;",
						"uniform vec3 bottomColor;",
						"varying vec2 vUv;",

						THREE.ShaderChunk.shadowmap_pars_fragment,
						"void main(){",
							"gl_FragColor = vec4(mix(topColor, bottomColor, vUv.y), 1.0);",
							THREE.ShaderChunk.shadowmap_fragment,
						"}"
					].join("\n")
				});

this is my code, also has another error: https://imgur.com/HOxQXAI
I have set my directionalLight to cast shadow