взвешенная-смешанная-порядок-независимая-прозрачность в webgl1 - PullRequest
0 голосов
/ 11 декабря 2018

Я работаю над проектом webgl, используя пакет узлов three.Я рендерил много 3D моделей с пользовательскими текстурами и цветами.Теперь мне нужно реализовать взвешенный смешанный порядок, независимый от прозрачности.Поэтому я переопределяю фрагментный шейдер для `meshphysical_frag.glsl

#extension GL_EXT_draw_buffers: enable
#define PHYSICAL

uniform vec3 diffuse;
uniform vec3 emissive;
uniform float roughness;
uniform float metalness;
uniform float opacity;
varying vec4 fragColor0;
varying vec4 fragColor1;

#ifndef STANDARD
    uniform float clearCoat;
    uniform float clearCoatRoughness;
#endif

varying vec3 vViewPosition;

#ifndef FLAT_SHADED

    varying vec3 vNormal;

#endif

#include <common>
#include <packing>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <uv2_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
#include <bsdfs>
#include <cube_uv_reflection_fragment>
#include <envmap_pars_fragment>
#include <envmap_physical_pars_fragment>
#include <fog_pars_fragment>
#include <lights_pars_begin>
#include <lights_physical_pars_fragment>
#include <shadowmap_pars_fragment>
#include <bumpmap_pars_fragment>
#include <normalmap_pars_fragment>
#include <roughnessmap_pars_fragment>
#include <metalnessmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>

void main() {

  #include <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;

  #include <logdepthbuf_fragment>
  #include <map_fragment>   
  #include <color_fragment>
  #include <alphamap_fragment>
  #include <alphatest_fragment>
  #include <roughnessmap_fragment>
  #include <metalnessmap_fragment>
  #include <normal_fragment_begin>
  #include <normal_fragment_maps>
  #include <emissivemap_fragment>

  // accumulation
  #include <lights_physical_fragment>
  #include <lights_fragment_begin>
  #include <lights_fragment_maps>
  #include <lights_fragment_end>

  // modulation
  #include <aomap_fragment>

    vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;

    vec4 color = vec4( outgoingLight, diffuseColor.a ); 
  gl_FragData[0] = color;

    //#include <tonemapping_fragment>
  #if defined( TONE_MAPPING )

  gl_FragData[0].rgb = toneMapping( gl_FragData[0].rgb );

  #endif
    //#include <encodings_fragment>
  gl_FragData[0] = linearToOutputTexel( gl_FragData[0] );
    //#include <fog_fragment>
  #ifdef USE_FOG
    #ifdef FOG_EXP2
      float fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );

    #else
      float fogFactor = smoothstep( fogNear, fogFar, fogDepth );

    #endif
      gl_FragData[0].rgb = mix( gl_FragData[0].rgb, fogColor, fogFactor );
    #endif

    //#include <premultiplied_alpha_fragment>
  #ifdef PREMULTIPLIED_ALPHA

    // Get get normal blending with premultipled, use with CustomBlending, OneFactor, OneMinusSrcAlphaFactor, AddEquation.
    //gl_FragData[0].rgb *= gl_FragData[0].a;

  #endif
    //#include <dithering_fragment>
  #if defined( DITHERING )

    gl_FragData[0].rgb = dithering( gl_FragData[0].rgb );

  #endif

  // ******** modified part begin
  float alpha = gl_FragData[0].a;
  float weight = pow(alpha + 0.01, 4.0) + max(0.01, min(3000.0, 0.3 / (0.00001 + pow(abs(gl_FragCoord.z) / 200.0, 4.0))));
  gl_FragData[0] = vec4(gl_FragData[0].rgb * alpha * weight, alpha);
  gl_FragData[1].r = alpha * weight;   
  // ******** end
}

const material = new MeshPhysicalMaterial({
  color: new Color(0x555555),
  roughness: 1,
  envMap: true,
  reflectivity: 0.5,
  envMapIntensity: 0.5,
  clearCoat: 1,
  clearCoatRoughness: 0.5,
  blending: THREE.CustomBlending,
  blendEquation: THREE.AddEquation,
  blendSrc: THREE.OneFactor,
  blendSrcAlpha: THREE.ZeroFactor,
  blendDst: THREE.OneFactor,
  blendDstAlpha: THREE.OneMinusSrcAlphaFactor,
  depthTest: false,
  depthWrite: false
  // transparent: false
});

И вот мой lastShader.

export default {
  uniforms: {
    accumTexture: { value: null },
    accumAlphaTexture: { value: null }
  },
  vertexShader: [
    "void main() {",
    "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
    "}"
  ].join("\n"),
  fragmentShader: [
    "uniform sampler2D accumTexture;",
    "uniform sampler2D accumAlphaTexture;",
    "void main() {",
    "vec4 accum = texture2D(accumTexture, gl_FragCoord.xy);",
    "float alpha = accum.a;",
    "accum.a = texture2D(accumAlphaTexture, gl_FragCoord.xy).r;",
    "gl_FragColor = vec4(accum.rgb/clamp(accum.a, 0.001, 50000.0), 1.0-alpha);",
    "}"
  ].join("\n")
};

  const EffectComposer = effectcomposer(THREE);
  const { RenderPass, ShaderPass } = EffectComposer;
  const renderer = new THREE.WebGLRenderer();
  /**
  *.... add meshes with geometry and physicalmaterial to the scens(I skipped)
  */
  const effectComposer = new EffectComposer(renderer);


  const quadPass = new ShaderPass(quadShader);
  this.quadPass = quadPass;
  effectComposer.addPass(quadPass);
  quadPass.renderToScreen = true;


  let gl = renderer.context;
  gl.getExtension("WEBGL_draw_buffers");
  //gl.enable(renderer.context.BLEND);
  //renderer.context.depthMask(false);

  const accumTarget = new THREE.WebGLRenderTarget(
    width,
    height,
    pars
  );

  accumTarget.texture.format = THREE.RGBAFormat;
  renderer.properties.get(
    accumTarget.texture
  ).__webglTexture = gl.createTexture();

  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(
    gl.TEXTURE_2D,
    renderer.properties.get(accumTarget.texture).__webglTexture
  );
  const accumBuffer = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, accumBuffer);
  gl.framebufferTexture2D(
    gl.FRAMEBUFFER,
    gl.getExtension("WEBGL_draw_buffers").COLOR_ATTACHMENT0_WEBGL,
    gl.TEXTURE_2D,
    renderer.properties.get(accumTarget.texture).__webglTexture,
    0
  );

  const accumAlphaTarget = new THREE.WebGLRenderTarget(
    width,
    height,
    pars
  );

  accumAlphaTarget.texture.format = THREE.RGBFormat;
  gl.activeTexture(gl.TEXTURE1);
  renderer.properties.get(
    accumAlphaTarget.texture
  ).__webglTexture = gl.createTexture();
  gl.bindTexture(
    gl.TEXTURE_2D,
    renderer.properties.get(accumAlphaTarget.texture).__webglTexture
  );
  const accumAlphaBuffer = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, accumAlphaBuffer);
  gl.framebufferTexture2D(
    gl.FRAMEBUFFER,
    gl.getExtension("WEBGL_draw_buffers").COLOR_ATTACHMENT0_WEBGL,
    gl.TEXTURE_2D,
    renderer.properties.get(accumAlphaTarget.texture).__webglTexture,
    0
  );

  gl.getExtension("WEBGL_draw_buffers").drawBuffersWEBGL([
    gl.getExtension("WEBGL_draw_buffers").COLOR_ATTACHMENT0_WEBGL,
    gl.getExtension("WEBGL_draw_buffers").COLOR_ATTACHMENT1_WEBGL
  ]);

  // Assign to object
  quadShader.uniforms.accumTexture.value = accumTarget.texture;
  quadShader.uniforms.accumAlphaTexture.value =
    accumAlphaTarget.texture;

но после запуска effectComposer.render() он просто показывает черный экран.Я сделал ошибку в связывании текстур.Как я могу исправить эту проблему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...