threejs物理材质的透明效果

287 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

上篇说到 ,vec4 transimisson 是由getIBLVolumeRefraction 计算得到的。 我们深挖下去,最后发现

alpha取决于transmittedLight,

transmittedLight 又是getTransmissionSample 计算得到,但是这个getTransmissionSample 就是去取纹理色值。

return vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );
//
vec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );
//

vec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {
    float framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );
    #ifdef texture2DLodEXT // 这个关系到结果的地方居然是返回贴图  texture2DLodEXT 这个只有 RawShaderMaterial 才会有,所以走下面
    return texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );
	#else
		return texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );
	#endif
	}

texture2DLodEXT 只有在wengl2和shadermaterial时才会定义,所以,走下面的

texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );

image.png

image.png

transmissionSamplerMap 这个贴图从哪来

到这里,不知道大家注意没有, 以往的声明贴图变量,都是用条件编译包裹起来的,但是这里却没有。 这说明什么,说明这个贴图肯定存在,还不是用户设置的。

又到了全局搜索回溯的时候了。

image.png

image.png

image.png

image.png

image.png

image.png

image.png

追溯到这里,可以发现,这个纹理实际上就是rendererTarget的texture。 好,接着看他的构造函数

const image = { width: width, height: height, depth: 1 }; 这个img是用来糊弄编译的吧。

然后,经过一番各种可能的搜索。。。。。。

找不到了,我猜可能是下面的copy方法在其他的地方调用了,打log吧

image.png

打印出来的东西还是那个东西,感觉怪怪的,还是百度(google)吧。 于是,我发现这个issue里面,大概有我想要的东西。

image.png

有用的东西

image.png

我猜,那1234的意思大概是,

1 把不透明物体渲染到帧缓冲区

2 把不透明物体渲染到transmissionSamplerMap ,意思大概是把渲染的结果做成一张纹理贴图,帧缓冲区常见的用法就是这样。

3 把开启了transimission的物体渲染到帧缓冲区

4 把开启了transparent的物体渲染到帧缓冲区。

先来简单提一下渲染目标 rendertarget, 默认我们的绘制操作是会直接呈现在画布上的,实际上就是渲染到了颜色缓冲区里。 我们也可也可以把渲染目标设置为一个帧缓冲区, 这样绘制操作虽然完成,却不会立即在画布上呈现出来, 实际上也没法在画布上呈现出来。

再来说一下,渲染的结果,渲染的结果其实就是一张图,就是每个像素点都有自己的颜色。 从顶点数据到像素,就是渲染。

结论

那么,按上面的说法(我的猜测),其实这个transmissionmap就是不透明物体的的渲染结果,所以,才会有透明穿透问题,因为这个渲染没有包含透明物体。

今日份水文,暂且结束。 好像有点文不对题啊,明天补上透明问题的处理。