SpecularMIPLevelNode.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { TempNode } from '../core/TempNode.js';
  2. import { FunctionNode } from '../core/FunctionNode.js';
  3. import { MaxMIPLevelNode } from './MaxMIPLevelNode.js';
  4. class SpecularMIPLevelNode extends TempNode {
  5. constructor( roughness, texture ) {
  6. super( 'f' );
  7. this.roughness = roughness;
  8. this.texture = texture;
  9. this.maxMIPLevel = undefined;
  10. }
  11. setTexture( texture ) {
  12. this.texture = texture;
  13. return this;
  14. }
  15. generate( builder, output ) {
  16. if ( builder.isShader( 'fragment' ) ) {
  17. this.maxMIPLevel = this.maxMIPLevel || new MaxMIPLevelNode();
  18. this.maxMIPLevel.texture = this.texture;
  19. const getSpecularMIPLevel = builder.include( SpecularMIPLevelNode.Nodes.getSpecularMIPLevel );
  20. return builder.format( getSpecularMIPLevel + '( ' + this.roughness.build( builder, 'f' ) + ', ' + this.maxMIPLevel.build( builder, 'f' ) + ' )', this.type, output );
  21. } else {
  22. console.warn( 'THREE.SpecularMIPLevelNode is not compatible with ' + builder.shader + ' shader.' );
  23. return builder.format( '0.0', this.type, output );
  24. }
  25. }
  26. copy( source ) {
  27. super.copy( source );
  28. this.texture = source.texture;
  29. this.roughness = source.roughness;
  30. return this;
  31. }
  32. toJSON( meta ) {
  33. let data = this.getJSONNode( meta );
  34. if ( ! data ) {
  35. data = this.createJSONNode( meta );
  36. data.texture = this.texture;
  37. data.roughness = this.roughness;
  38. }
  39. return data;
  40. }
  41. }
  42. SpecularMIPLevelNode.Nodes = ( function () {
  43. // taken from here: http://casual-effects.blogspot.ca/2011/08/plausible-environment-lighting-in-two.html
  44. const getSpecularMIPLevel = new FunctionNode( /* glsl */`
  45. float getSpecularMIPLevel( const in float roughness, const in float maxMIPLevelScalar ) {
  46. float sigma = PI * roughness * roughness / ( 1.0 + roughness );
  47. float desiredMIPLevel = maxMIPLevelScalar + log2( sigma );
  48. return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );
  49. }`
  50. );
  51. return {
  52. getSpecularMIPLevel: getSpecularMIPLevel
  53. };
  54. } )();
  55. SpecularMIPLevelNode.prototype.nodeType = 'SpecularMIPLevel';
  56. export { SpecularMIPLevelNode };