Three.js: Objects intersected and shader material

匿名 (未验证) 提交于 2019-12-03 01:39:01

问题:

I have a scene with objects intersected using Lambert material, like in this jsFiddle.

Now I need/want to switch the material of that plane to a Shader material and the plane turns into a background thing, like here.

The question is, can I use different materials in objects and still preserve the intersection effect? Is this a Three.js limitation or this is how shaders works? Or am I missing a parameter in the renderer/material?

At the moment is not an option no switch all my work to shader materials in order to take advantage of shaders.

This is how I set up the material:

var material1 = new THREE.ShaderMaterial( {      uniforms: {         color: { type: "c", value: new THREE.Color( 0x22A8E7 ) }     },     vertexShader: document.getElementById( 'vertexShader' ).textContent,      fragmentShader: document.getElementById( 'fragmentShader' ).textContent,      opacity: 0.5,      transparent: true,  } ); 

Thanks!

回答1:

With ShaderMaterial you control the shader glsl; so in order for logarithmicDepthBuffer to work you need to add four sets of code to your shaders.

The code is in:

Vertex shader declares

https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl

#ifdef USE_LOGDEPTHBUF      #ifdef USE_LOGDEPTHBUF_EXT          varying float vFragDepth;      #endif      uniform float logDepthBufFC;  #endif 

Vertex shader body

https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl

#ifdef USE_LOGDEPTHBUF      gl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;      #ifdef USE_LOGDEPTHBUF_EXT          vFragDepth = 1.0 + gl_Position.w;      #else          gl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;      #endif  #endif 

Fragment shader declares

https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl

#ifdef USE_LOGDEPTHBUF      uniform float logDepthBufFC;      #ifdef USE_LOGDEPTHBUF_EXT          #extension GL_EXT_frag_depth : enable         varying float vFragDepth;      #endif  #endif 

Fragment shader body

https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl

#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)      gl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;  #endif 

If you are building the shaders in js, rather than pulling directly from the HTML then you can include these with ShaderChunks e.g. THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ]

See https://github.com/mrdoob/three.js/blob/master/src/renderers/shaders/ShaderLib.js for examples of this.



回答2:

Ok, looking for another subject, I've found this example http://stemkoski.github.io/Three.js/Shader-Glow.html.

The "problem" in my tests was the logarithmic depth buffer in this line:

var renderer = new THREE.WebGLRenderer({logarithmicDepthBuffer: true}); 

Without that option, worked as expected.

Now, I don't know if that is a bug in THREE or in order to use logarithmic depth buffer I must write the shader in another way, or it just the way it is.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!