You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

252 lines
6.1 KiB

2 years ago
/**
* `PackedPhongMaterial` inherited from THREE.MeshPhongMaterial
*
* @param {Object} parameters
*/
import {
MeshPhongMaterial,
ShaderChunk,
ShaderLib,
UniformsUtils,
} from 'three';
class PackedPhongMaterial extends MeshPhongMaterial {
constructor( parameters ) {
super();
this.defines = {};
this.type = 'PackedPhongMaterial';
this.uniforms = UniformsUtils.merge( [
ShaderLib.phong.uniforms,
{
quantizeMatPos: { value: null },
quantizeMatUV: { value: null }
}
] );
this.vertexShader = [
'#define PHONG',
'varying vec3 vViewPosition;',
ShaderChunk.common,
ShaderChunk.uv_pars_vertex,
ShaderChunk.uv2_pars_vertex,
ShaderChunk.displacementmap_pars_vertex,
ShaderChunk.envmap_pars_vertex,
ShaderChunk.color_pars_vertex,
ShaderChunk.fog_pars_vertex,
ShaderChunk.normal_pars_vertex,
ShaderChunk.morphtarget_pars_vertex,
ShaderChunk.skinning_pars_vertex,
ShaderChunk.shadowmap_pars_vertex,
ShaderChunk.logdepthbuf_pars_vertex,
ShaderChunk.clipping_planes_pars_vertex,
`#ifdef USE_PACKED_NORMAL
#if USE_PACKED_NORMAL == 0
vec3 decodeNormal(vec3 packedNormal)
{
float x = packedNormal.x * 2.0 - 1.0;
float y = packedNormal.y * 2.0 - 1.0;
vec2 scth = vec2(sin(x * PI), cos(x * PI));
vec2 scphi = vec2(sqrt(1.0 - y * y), y);
return normalize( vec3(scth.y * scphi.x, scth.x * scphi.x, scphi.y) );
}
#endif
#if USE_PACKED_NORMAL == 1
vec3 decodeNormal(vec3 packedNormal)
{
vec3 v = vec3(packedNormal.xy, 1.0 - abs(packedNormal.x) - abs(packedNormal.y));
if (v.z < 0.0)
{
v.xy = (1.0 - abs(v.yx)) * vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
}
return normalize(v);
}
#endif
#if USE_PACKED_NORMAL == 2
vec3 decodeNormal(vec3 packedNormal)
{
vec3 v = (packedNormal * 2.0) - 1.0;
return normalize(v);
}
#endif
#endif`,
`#ifdef USE_PACKED_POSITION
#if USE_PACKED_POSITION == 0
uniform mat4 quantizeMatPos;
#endif
#endif`,
`#ifdef USE_PACKED_UV
#if USE_PACKED_UV == 1
uniform mat3 quantizeMatUV;
#endif
#endif`,
`#ifdef USE_PACKED_UV
#if USE_PACKED_UV == 0
vec2 decodeUV(vec2 packedUV)
{
vec2 uv = (packedUV * 2.0) - 1.0;
return uv;
}
#endif
#if USE_PACKED_UV == 1
vec2 decodeUV(vec2 packedUV)
{
vec2 uv = ( vec3(packedUV, 1.0) * quantizeMatUV ).xy;
return uv;
}
#endif
#endif`,
'void main() {',
ShaderChunk.uv_vertex,
`#ifdef USE_UV
#ifdef USE_PACKED_UV
vUv = decodeUV(vUv);
#endif
#endif`,
ShaderChunk.uv2_vertex,
ShaderChunk.color_vertex,
ShaderChunk.beginnormal_vertex,
`#ifdef USE_PACKED_NORMAL
objectNormal = decodeNormal(objectNormal);
#endif
#ifdef USE_TANGENT
vec3 objectTangent = vec3( tangent.xyz );
#endif
`,
ShaderChunk.morphnormal_vertex,
ShaderChunk.skinbase_vertex,
ShaderChunk.skinnormal_vertex,
ShaderChunk.defaultnormal_vertex,
ShaderChunk.normal_vertex,
ShaderChunk.begin_vertex,
`#ifdef USE_PACKED_POSITION
#if USE_PACKED_POSITION == 0
transformed = ( vec4(transformed, 1.0) * quantizeMatPos ).xyz;
#endif
#endif`,
ShaderChunk.morphtarget_vertex,
ShaderChunk.skinning_vertex,
ShaderChunk.displacementmap_vertex,
ShaderChunk.project_vertex,
ShaderChunk.logdepthbuf_vertex,
ShaderChunk.clipping_planes_vertex,
'vViewPosition = - mvPosition.xyz;',
ShaderChunk.worldpos_vertex,
ShaderChunk.envmap_vertex,
ShaderChunk.shadowmap_vertex,
ShaderChunk.fog_vertex,
'}',
].join( '\n' );
// Use the original MeshPhongMaterial's fragmentShader.
this.fragmentShader = [
'#define PHONG',
'uniform vec3 diffuse;',
'uniform vec3 emissive;',
'uniform vec3 specular;',
'uniform float shininess;',
'uniform float opacity;',
ShaderChunk.common,
ShaderChunk.packing,
ShaderChunk.dithering_pars_fragment,
ShaderChunk.color_pars_fragment,
ShaderChunk.uv_pars_fragment,
ShaderChunk.uv2_pars_fragment,
ShaderChunk.map_pars_fragment,
ShaderChunk.alphamap_pars_fragment,
ShaderChunk.aomap_pars_fragment,
ShaderChunk.lightmap_pars_fragment,
ShaderChunk.emissivemap_pars_fragment,
ShaderChunk.envmap_common_pars_fragment,
ShaderChunk.envmap_pars_fragment,
ShaderChunk.fog_pars_fragment,
ShaderChunk.bsdfs,
ShaderChunk.lights_pars_begin,
ShaderChunk.normal_pars_fragment,
ShaderChunk.lights_phong_pars_fragment,
ShaderChunk.shadowmap_pars_fragment,
ShaderChunk.bumpmap_pars_fragment,
ShaderChunk.normalmap_pars_fragment,
ShaderChunk.specularmap_pars_fragment,
ShaderChunk.logdepthbuf_pars_fragment,
ShaderChunk.clipping_planes_pars_fragment,
'void main() {',
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;',
ShaderChunk.logdepthbuf_fragment,
ShaderChunk.map_fragment,
ShaderChunk.color_fragment,
ShaderChunk.alphamap_fragment,
ShaderChunk.alphatest_fragment,
ShaderChunk.specularmap_fragment,
ShaderChunk.normal_fragment_begin,
ShaderChunk.normal_fragment_maps,
ShaderChunk.emissivemap_fragment,
// accumulation
ShaderChunk.lights_phong_fragment,
ShaderChunk.lights_fragment_begin,
ShaderChunk.lights_fragment_maps,
ShaderChunk.lights_fragment_end,
// modulation
ShaderChunk.aomap_fragment,
'vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;',
ShaderChunk.envmap_fragment,
'gl_FragColor = vec4( outgoingLight, diffuseColor.a );',
ShaderChunk.tonemapping_fragment,
ShaderChunk.encodings_fragment,
ShaderChunk.fog_fragment,
ShaderChunk.premultiplied_alpha_fragment,
ShaderChunk.dithering_fragment,
'}',
].join( '\n' );
this.setValues( parameters );
}
}
export { PackedPhongMaterial };