instanceMesh实例模拟普通模型颜色算法(拆分贴图颜色与材质颜色)

three@126

InstanceMesh实例模拟普通模型颜色算法

 

如果instanceColor为默认值则计算结果为贴图颜色*inscaneColor*材质color如果不为默认值则混合结果为贴图颜色*inscaneColor

如果没有贴图的情况下,如果instanceColor不为默认值则取instanceColor,否则取材质的color

核心:在着色器中将材质颜色与贴图细节颜色拆分开 ,分别计算

<map_fragment> 
instanceMapColor instanceMaterialColor

  fragmentShader = fragmentShader.replace(
    '#include <map_fragment>',
    `
    vec4 instanceMaterialColor = diffuseColor;
    vec4 instanceMapColor = vec4( 1.0 );

    #ifdef USE_MAP

      vec4 texelColor = texture2D( map, vUv );

      texelColor = mapTexelToLinear( texelColor );
      instanceMapColor = texelColor;
      diffuseColor *= texelColor;

    #endif
    `
  );

着色器示例:

const _onMaterialBeforeCompile = function (parameters, renderer) {
  let vertexShader = parameters.vertexShader;

  //#region vertex color

  vertexShader = vertexShader.replace(
    '#include <color_pars_vertex>',
    `
    #ifdef USE_INSTANCING_COLOR

      attribute float instanceOpacity;
      varying vec4 vInstanceColor;

    #endif
    `
  );

  vertexShader = vertexShader.replace(
    '#include <color_vertex>',
    `
    #ifdef USE_INSTANCING_COLOR

      vInstanceColor = vec4( instanceColor.xyz, instanceOpacity );

    #endif
    `
  );

  //#endregion

  //#region vertex uvoffset

  vertexShader = vertexShader.replace(
    '#include <uv_pars_vertex>',
    `
    #ifdef USE_UV

      #ifdef UVS_VERTEX_ONLY

        vec2 vUv;

      #else

        varying vec2 vUv;

      #endif

      uniform mat3 uvTransform;

      attribute vec2 instanceUVOffset;

    #endif
    `
  );

  vertexShader = vertexShader.replace(
    '#include <uv_vertex>',
    `
    #ifdef USE_UV

      vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
      vUv += instanceUVOffset;

    #endif
    `
  );

  //#endregion

  parameters.vertexShader = vertexShader;

  let fragmentShader = parameters.fragmentShader;

  //#region fragment color

  fragmentShader = fragmentShader.replace(
    '#include <map_fragment>',
    `
    vec4 instanceMaterialColor = diffuseColor;
    vec4 instanceMapColor = vec4( 1.0 );

    #ifdef USE_MAP

      vec4 texelColor = texture2D( map, vUv );

      texelColor = mapTexelToLinear( texelColor );
      instanceMapColor = texelColor;
      diffuseColor *= texelColor;

    #endif
    `
  );

  fragmentShader = fragmentShader.replace(
    '#include <color_pars_fragment>',
    `
    #ifdef USE_COLOR

      varying vec4 vInstanceColor;

    #endif
    `
  );

  const epsilon = 0.00001;
  const useInstanceColor = `
  #ifdef USE_COLOR

    bool isDefaultInstanceColor =
      abs( vInstanceColor.r - 1.0 ) < ${epsilon} &&
      abs( vInstanceColor.g - 1.0 ) < ${epsilon} &&
      abs( vInstanceColor.b - 1.0 ) < ${epsilon};

    if ( isDefaultInstanceColor ) {

      #ifdef USE_MAP

        diffuseColor.rgb = instanceMapColor.rgb * vInstanceColor.rgb * instanceMaterialColor.rgb;

      #else

        diffuseColor.rgb = instanceMaterialColor.rgb;

      #endif

    } else {

      #ifdef USE_MAP

        diffuseColor.rgb = instanceMapColor.rgb * vInstanceColor.rgb;

      #else

        diffuseColor.rgb = vInstanceColor.rgb;

      #endif

    }

    diffuseColor.a *= vInstanceColor.a;

  #endif
  `;
  fragmentShader = fragmentShader.replace('#include <color_fragment>', ` ${useInstanceColor}`);

  //#endregion

  parameters.fragmentShader = fragmentShader;
};

 

posted @ 2026-04-16 15:29  SimoonJia  阅读(3)  评论(0)    收藏  举报