depth peeling实现半透明

Posted redips

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了depth peeling实现半透明相关的知识,希望对你有一定的参考价值。

技术分享图片技术分享图片技术分享图片

最近忙着找实习做毕设出差,好久没有记东西,现在记录一下带学弟写的一个用depth-peeling实现的半透明。

----------------------------------------------------------------------------------------------------------------------------------------------

1. 把两张纹理[color和depth]打包成一个FrameBufferObject.

2. for i = 0...n

    (a) 渲染第i层到default fbo.

         (b) 将color-attachment和depth-attachment拷贝到(1)中的fbo.

    (c) 清空default fbo‘s 深度缓存

    end for

----------------------------------------------------------------------------------------------------------------------------------------------

2.(a)渲染的时候需要用到(1)中的颜色和深度纹理,深度纹理用来discard前一层的片元,颜色纹理用来blend。

2.(c)一定要清空depth,如果不清空的话,depth里面还是放的上一层的深度值,这时候虽然在片元着色器里面discard掉上一层的片元,但是留下来的片元却通过不了深度测试。

 

贴一下片元着色器的代码

#version 430 core
out vec4 color;

uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 cameraPos;

in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoord;

uniform float texWid,texHet;
uniform float blendCoef;

//0:no texture,1:ambientTexture,2:diffuseTexture,3:two textures
uniform int surfaceType;
uniform vec3 diffuseColor;
uniform vec3 ambientColor;

uniform sampler2D diffuseTexture;
uniform sampler2D ambientTexture;
uniform sampler2D depthTexture;
uniform sampler2D colorTexture;

const float M = 16.0f;
const float SpecularStrength = 0.5f;
const float SC = 1.0f;
const float SL = 0.000000004;
const float SQ = 0.0000000001;

const float Bias = 1e-4;

void main(){
    //Depth peeling
    vec2 deptc = vec2(gl_FragCoord.x/texWid,gl_FragCoord.y/texHet);
    if(gl_FragCoord.z<=texture(depthTexture,deptc).r+Bias)
        discard;

    // Attenuation
    float distance = length(lightPos - FragPos);
    float attenuation = 1.0 / (SC + SL * distance + SQ * distance * distance);

    // Diffuse
    vec3 N = normalize(Normal);
    vec3 L = normalize(lightPos - FragPos);
      vec3 diffuse = max(dot(N, L), 0.0) * attenuation * lightColor;

    // Specular
    vec3 H = normalize(cameraPos - FragPos + lightPos - FragPos);
    vec3 specular = SpecularStrength * pow(max(dot(H, N), 0.0), M) * attenuation * lightColor;

    // Sum up
    vec3 ambient;
    if((surfaceType&1u)>0)
        ambient = (texture(ambientTexture,TexCoord).bgr * ambientColor);
    else ambient = ambientColor;

    if((surfaceType&2u)>0)
        diffuse *= (texture(diffuseTexture,TexCoord).bgr * diffuseColor);
    else diffuse *= diffuseColor;

//blend color
= vec4((ambient+diffuse+specular)*(1.0f-blendCoef)+texture(colorTexture,deptc).rgb*blendCoef,1.0f); }

 


以上是关于depth peeling实现半透明的主要内容,如果未能解决你的问题,请参考以下文章

活动接收全屏半透明DialogFragment背后的触摸事件

CSS实现父元素半透明,子元素不透明

CSS实现父元素半透明,子元素不透明

CSS实现父元素半透明,子元素不透明

CSS实现父元素半透明,子元素不透明

半透明/透明状态栏 + CoordinatorLayout + Toolbar + Fragment