@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
154 lines (137 loc) • 4.99 kB
text/typescript
// import {UniformsUtils} from 'three';
// import {ShaderMaterial} from 'three';
import {ShaderLib} from 'three';
import {ShaderAssemblerMesh} from './_BaseMesh';
import {BaseGlShaderAssembler} from '../_Base';
import {ShaderConfig} from '../../configs/ShaderConfig';
import {VariableConfig} from '../../configs/VariableConfig';
import metalnessmapFragment from '../../../gl/ShaderLib/ShaderChunk/metalnessmap_fragment.glsl';
import roughnessmapFragment from '../../../gl/ShaderLib/ShaderChunk/roughnessmap_fragment.glsl';
import {OutputGlNode} from '../../../Output';
import {ShaderName} from '../../../../utils/shaders/ShaderName';
import {GlConnectionPoint, GlConnectionPointType} from '../../../../utils/io/connections/Gl';
import sss_default from '../../../gl/sss/init.glsl';
import {AssemblerGlControllerNode} from '../../Controller';
import {VaryingWriteGlNode} from '../../../VaryingWrite';
import {MeshStandardMaterial} from 'three';
import {includeSSSDeclarations} from './common/SSS';
export class ShaderAssemblerStandard extends ShaderAssemblerMesh {
static USE_SSS: Readonly<boolean> = true;
isPhysical() {
return false;
}
constructor(protected override _gl_parent_node: AssemblerGlControllerNode) {
super(_gl_parent_node);
this._addFilterFragmentShaderCallback(
'MeshStandardBuilderMatNode',
ShaderAssemblerStandard.filterFragmentShader
);
}
override templateShader() {
const template = this.isPhysical() ? ShaderLib.physical : ShaderLib.standard;
return {
vertexShader: template.vertexShader,
fragmentShader: template.fragmentShader,
uniforms: template.uniforms,
};
}
static filterFragmentShader(fragmentShader: string) {
fragmentShader = fragmentShader.replace('#include <metalnessmap_fragment>', metalnessmapFragment);
fragmentShader = fragmentShader.replace('#include <roughnessmap_fragment>', roughnessmapFragment);
fragmentShader = fragmentShader.replace(
'vec3 totalEmissiveRadiance = emissive;',
'vec3 totalEmissiveRadiance = emissive * POLY_emissive;'
);
fragmentShader = includeSSSDeclarations(fragmentShader);
return fragmentShader;
}
override createMaterial() {
// const template_shader = this.templateShader();
// const options = {
// lights: true,
// extensions: {
// derivatives: true,
// },
// uniforms: UniformsUtils.clone(template_shader.uniforms),
// vertexShader: template_shader.vertexShader,
// fragmentShader: template_shader.fragmentShader,
// };
// const material = new ShaderMaterial(options);
const material = new MeshStandardMaterial() as any;
// if (this.isPhysical()) {
// material.defines.PHYSICAL = true;
// }
this._addCustomMaterials(material);
return material;
}
override add_output_inputs(output_child: OutputGlNode) {
// BaseGlShaderAssembler.add_output_inputs(output_child);
const list = BaseGlShaderAssembler.output_input_connection_points();
list.push(new GlConnectionPoint('metalness', GlConnectionPointType.FLOAT, 1));
list.push(new GlConnectionPoint('roughness', GlConnectionPointType.FLOAT, 1));
list.push(new GlConnectionPoint('emissive', GlConnectionPointType.VEC3, [1, 1, 1]));
if (ShaderAssemblerStandard.USE_SSS) {
list.push(new GlConnectionPoint('SSSModel', GlConnectionPointType.SSS_MODEL, sss_default));
}
if (this.isPhysical()) {
list.push(new GlConnectionPoint('transmission', GlConnectionPointType.FLOAT, 1));
list.push(new GlConnectionPoint('thickness', GlConnectionPointType.FLOAT, 1));
}
output_child.io.inputs.setNamedInputConnectionPoints(list);
}
override create_shader_configs() {
const fragmentInputNames = ['color', 'alpha', 'metalness', 'roughness', 'emissive', 'SSSModel'];
if (this.isPhysical()) {
fragmentInputNames.push('transmission');
fragmentInputNames.push('thickness');
}
return [
new ShaderConfig(ShaderName.VERTEX, ['position', 'normal', 'uv', VaryingWriteGlNode.INPUT_NAME], []),
new ShaderConfig(ShaderName.FRAGMENT, fragmentInputNames, [ShaderName.VERTEX]),
];
}
override create_variable_configs() {
const list = BaseGlShaderAssembler.create_variable_configs();
list.push(
new VariableConfig('metalness', {
default: '1.0',
prefix: 'float POLY_metalness = ',
})
);
list.push(
new VariableConfig('roughness', {
default: '1.0',
prefix: 'float POLY_roughness = ',
})
);
list.push(
new VariableConfig('emissive', {
default: 'vec3(1.0, 1.0, 1.0)',
prefix: 'vec3 POLY_emissive = ',
})
);
if (ShaderAssemblerStandard.USE_SSS) {
list.push(
new VariableConfig('SSSModel', {
default: sss_default,
prefix: 'SSSModel POLY_SSSModel = ',
})
);
}
if (this.isPhysical()) {
list.push(
new VariableConfig('transmission', {
default: '1.0',
prefix: 'float POLY_transmission = ',
})
);
list.push(
new VariableConfig('thickness', {
default: '1.0',
prefix: 'float POLY_thickness = ',
})
);
}
return list;
}
}