UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

64 lines (56 loc) 2.48 kB
import {RGBADepthPacking, BasicDepthPacking, DepthPackingStrategies} from 'three'; import {ShaderLib} from 'three'; import {ShaderAssemblerMaterial} from '../../_BaseMaterial'; import {ShaderName} from '../../../../../../utils/shaders/ShaderName'; import TemplateFragment from '../../../../templates/custom/mesh/CustomMeshDepth.frag.glsl'; import {MeshDepthMaterial} from 'three'; import {AssemblerGlControllerNode} from '../../../../Controller'; import {includeSSSDeclarations} from '../../common/SSS'; import {INSERT_DEFINE_AFTER_MAPF_FOR_MESH} from '../../_BaseMesh'; const INSERT_BODY_AFTER_MAP: Map<ShaderName, string> = new Map([ [ShaderName.VERTEX, '#include <begin_vertex>'], [ShaderName.FRAGMENT, '#include <alphamap_fragment>'], ]); export class ShaderAssemblerCustomMeshDepth extends ShaderAssemblerMaterial { constructor(protected override _gl_parent_node: AssemblerGlControllerNode) { super(_gl_parent_node); this._addFilterFragmentShaderCallback('MeshStandardBuilderMatNode', includeSSSDeclarations); } override templateShader() { const template = ShaderLib.depth; return { vertexShader: template.vertexShader, fragmentShader: TemplateFragment, uniforms: template.uniforms, }; } protected override insertDefineAfter(shaderName: ShaderName): string | undefined { return INSERT_DEFINE_AFTER_MAPF_FOR_MESH.get(shaderName); } protected override insertBodyAfter(shaderName: ShaderName) { return INSERT_BODY_AFTER_MAP.get(shaderName); } protected depthPacking(): DepthPackingStrategies { // surprisingly, even though the mesh depth material looks better with // BasicDepthPacking when used to be rendered, // it seems here we need to use RGBADepthPacking // to have proper shadows. // Also, it is even more surprising as the threejs docs mention // from https://threejs.org/docs/?q=mate#api/en/materials/MeshDepthMaterial // "Encoding for depth packing. Default is BasicDepthPacking." // // But the below ShaderAssemblerCustomMeshDepthForRender // which is used in MeshDepthBuilder (which is unlike this assembler is not used for shadow, but for direct render) // uses BasicDepthPacking return RGBADepthPacking; } override createMaterial() { const material = new MeshDepthMaterial({depthPacking: this.depthPacking()}); return material; } } export class ShaderAssemblerCustomMeshDepthForRender extends ShaderAssemblerCustomMeshDepth { protected override depthPacking() { return BasicDepthPacking; } }