Last active
September 21, 2024 13:44
-
-
Save wmcmurray/6696fc95f25bbd2401d72a74e9493261 to your computer and use it in GitHub Desktop.
A basic example of a ThreeJS (r108) ShaderMaterial with shadows, fog and dithering support.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { mergeUniforms } from 'three/src/renderers/shaders/UniformsUtils.js' | |
import { UniformsLib } from 'three/src/renderers/shaders/UniformsLib.js' | |
export default { | |
uniforms: mergeUniforms([ | |
UniformsLib.lights, | |
UniformsLib.fog, | |
]), | |
vertexShader: ` | |
#include <common> | |
#include <fog_pars_vertex> | |
#include <shadowmap_pars_vertex> | |
void main() { | |
#include <begin_vertex> | |
#include <project_vertex> | |
#include <worldpos_vertex> | |
#include <shadowmap_vertex> | |
#include <fog_vertex> | |
} | |
`, | |
fragmentShader: ` | |
#include <common> | |
#include <packing> | |
#include <fog_pars_fragment> | |
#include <bsdfs> | |
#include <lights_pars_begin> | |
#include <shadowmap_pars_fragment> | |
#include <shadowmask_pars_fragment> | |
#include <dithering_pars_fragment> | |
void main() { | |
// CHANGE THAT TO YOUR NEEDS | |
// ------------------------------ | |
vec3 finalColor = vec3(0, 0.75, 0); | |
vec3 shadowColor = vec3(0, 0, 0); | |
float shadowPower = 0.5; | |
// ------------------------------ | |
// it just mixes the shadow color with the frag color | |
gl_FragColor = vec4( mix(finalColor, shadowColor, (1.0 - getShadowMask() ) * shadowPower), 1.0); | |
#include <fog_fragment> | |
#include <dithering_fragment> | |
} | |
` | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import BasicCustomShader from 'BasicCustomShader.js' | |
// and here is how to create the material | |
const material = new THREE.ShaderMaterial({ | |
...BasicCustomShader, | |
fog: true, | |
lights: true, | |
dithering: true, | |
}); | |
// PS : you should also set `receiveShadow = true` on your mesh ! |
thanks a lot this is super helpful!
i tried to run it with r147 and i get:
Shader Error 0 - VALIDATE_STATUS false
Program Info Log: Vertex shader is not compiled.
�
VERTEX
ERROR: 0:193: 'transformedNormal' : undeclared identifier
ERROR: 0:193: 'inverseTransformDirection' : no matching overloaded function found
ERROR: 0:193: '=' : dimension mismatch
ERROR: 0:193: '=' : cannot convert from 'const mediump float' to 'highp 3-component vector of float'
�
188: #endif
189: worldPosition = modelMatrix * worldPosition;
190: #endif
191: #if defined( USE_SHADOWMAP ) || ( 1 > 0 )
192: #if 0 > 0 || 1 > 0 || 0 > 0
> 193: vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
194: vec4 shadowWorldPosition;
195: #endif
196: #if 0 > 0
197:
198: #endif
199: #if 1 > 0
any advice?
add this includes to the vertex shader
#include <begin_vertex>
#include <beginnormal_vertex> // Defines objectNormal
#include <project_vertex>
#include <worldpos_vertex>
#include <defaultnormal_vertex> // Defines transformedNormal
#include <shadowmap_vertex>
This does not seem to work anymore
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, thanks for your example, that's good. I have another question...
When I try to write a multi-light support shader like that...
vec3 GetDiffuse(vec3 _normalWS)
{
vec3 normalWS = _normalWS;
vec3 diffuse = vec3(0,0,0);
#if NUM_DIR_LIGHTS > 0
diffuse = LightingLambert(directionalLights[0].color, vNormal, -directionalLights[0].direction);
#endif
#if NUM_POINT_LIGHTS > 0
for(int i=0; i<NUM_POINT_LIGHTS; i++)
{
PointLight light = pointLights[i];
vec3 dTmp = vec3(0,0,0);
float lightAffect = 1.0 - clamp(distance(vPos,light.position) / light.distance,0.0,1.0);
dTmp = LightingLambert(light.color, vNormal, normalize(vPos - light.position)) * lightAffect;
diffuse += dTmp;
}
#endif
diffuse *= getShadowMask();
return diffuse;
}
void main()
{
gl_FragColor = GetDiffuse(NORMAL_FROM_VERTEXSHADER);
}
It causes weird shadow...
How to let that support 2 or more lights with the correct shadow? thanks