如何使用GLSL在体渲染中进行混合
How to do the blending in Volume Rendering using GLSL?
介绍了使用OpenGL中过时的API进行体渲染的方法。但是现在,我想用GLSL完成体渲染,我已经完成了一部分。我的问题是如何进行混合。在上面的链接中,混合由以下代码完成:
glEnable(GL_BLEND);
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
但是我如何使用GLSL完成混合呢?
我试着用下面的公式:
C = Cs*As + Cd(1 - As)
Cs为源对象的颜色。Cd是目标对象的颜色。这是源对象的alpha。我的代码片段着色器如下:
......
vec3 dir = backPoint - frontPoint;
float len = length(dir);
float stepSize = 0.01;
vec3 deltaDir = normalize(dir)*stepSize;
float deltaLen = length(deltaDir);
float accLen = 0;
float accAlpha = 0;
float sampleAlpha = 0;
vec4 accColor = vec4(0.0);
vec3 samplePoint = frontPoint;
vec4 sampleColor;
while(accLen < len && accColor.a <= 1.0){
sampleColor = texture(texture3D, samplePoint);
accColor = sampleColor*sampleColor.a + accColor*(1-sampleColor.a);
accLen += deltaLen;
samplePoint += deltaDir;
}
color = accColor;
......
在我的项目中,我让3D纹理的r, g, b, a的值保持相同。但是我无法得到上面一个链接的结果。你能帮我用GLSL解决混合问题吗?
在预乘alpha颜色空间中进行计算是很自然的。它更符合体积现象的发射-吸收。对应方程为:
C = Cs + (1 - As)*Cd
A = 1 - (1 - As)*(1 - Ad) = As + (1 - As)*Ad
虽然可以在非预乘的alpha颜色空间中进行计算,但它需要除以alpha值,并且通常更复杂。(你的代码工作在非预乘和不考虑它…)
设置OpenGL混合,你可以使用:
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
在着色器中使用这个公式:
accColor = sampleColor + accColor*(1-sampleColor.a);
在生成3D纹理时,你也必须考虑到这一点。例如,一个纹理,其中所有像素R = G = B = A
对应于一个白色的雾状物质,所以你必须在黑暗的背景下看它。
相关文章:
- 是否可以混合使用SFINAE和模板专业化?
- 使用 Boost.Spirit 解析具有混合数据类型的 OBJ 文件?
- 使用英特尔内部函数 (AVX) 中的混合说明
- 错误:在 C++ 目标 c 混合'self'使用未声明的标识符
- 是否有一个版本的glCopyImageSubData在Openg GL中使用混合?
- 使用 pybind11 混合类型转换和不透明类型
- API 抽象层 - 避免混合使用 API 接口
- 将指向类对象的智能指针与类对象混合使用
- 如何处理使用不同类型索引的不同库(例如 stl 和 eigen3)的混合(size_t、int、..)
- 将C++容器与 C 语言结构混合使用
- 混合索引和指针算术时避免使用C4365,而无需铸造
- Firebase:混合使用C++和Objective-C SDK可以吗
- 在混合 c 和 c++ 代码中使用运算符 new
- 混合模板类型的模板参数包(std::使用可选参数重新创建函数)
- 在Visual Studio Express 2015中的同一项目中混合使用c ++和c#
- 使用d3d11_mapped_subresource和map/umap时,混合纹理输出
- 我可以在Apache Ignite计算中混合使用C++和Java吗?
- 在C++中的混合对象列表中使用相同的方法
- 如何使用libc libstdc 混合的链接库
- 将 boost::thread 与 C++11 std::mutex 混合使用是否安全?