7、基于osg引擎实现读取vtk数据通过着色器实现简单体渲染(1)

1、顶点着色器代码

c 复制代码
#version 110
/* GLSL 1.10需要显式声明精度 (OpenGL ES要求) */
#ifdef GL_ES
precision highp  float;
#endif
// 体数据采样步长
uniform float xStepSize,yStepSize,zStepSize;
// 体数据纹理和颜色纹理
uniform sampler3D baseTexture;
uniform sampler1D tfTexture;
// 体数据包围盒边界
uniform vec3 minBound,maxBound;
varying vec3 vDirection;//模型空间下的光线方向
varying vec3 vCameraModelPosition;//模型空间下的相机位置
void main(void)
{
    // 计算裁剪空间的位置
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

    vec4 cameraPos = (gl_ModelViewMatrixInverse * vec4(0, 0, 0, 1));
    vCameraModelPosition = cameraPos.xyz/cameraPos.w;
    vDirection = gl_Vertex.xyz/gl_Vertex.w- vCameraModelPosition;
    
}

2、片元着色器代码

c 复制代码
#version 110
/* GLSL 1.10需要显式声明精度 (OpenGL ES要求) */
#ifdef GL_ES
precision highp  float;
precision highp sampler3D;
precision highp sampler1D;
#endif
#define EPSILON 1e-3

// 体数据纹理和颜色纹理
uniform sampler3D baseTexture;
uniform sampler1D tfTexture;

uniform int steps;//采样步长,值越大,采样次数越多,效果越小,但性能越差
uniform float densityFactor;//值越大,颜色变化剧烈,细节边界变得锐利,可能出现不平滑的锯齿状过渡;值越小,颜色变化缓慢,叠加的颜色较多,导致整体视觉上更加柔和、模糊,增强了雾气感
// 体数据包围盒边界
uniform vec3 minBound,maxBound;

varying vec3 vDirection;//模型空间下的光线方向
varying vec3 vCameraModelPosition;//模型空间下的相机位置

const int maxSamples = 256;
vec2 hitBox(vec3 orig, vec3 dir) {
	vec3 inv_dir = 1.0 / dir;// 光线方向倒数(处理正负方向)
	vec3 tmin_tmp = (minBound - orig) * inv_dir;// 沿光线方向到达包围盒各轴最小边界的距离
	vec3 tmax_tmp = (maxBound - orig) * inv_dir; // 沿光线方向到达包围盒各轴最大边界的距离
	vec3 tmin = min(tmin_tmp, tmax_tmp);// 各轴向的最近交点
	vec3 tmax = max(tmin_tmp, tmax_tmp);// 各轴向的最远交点
	float near = max(max(tmin.x, max(tmin.y, tmin.z)),0.0);// 光线最终进入包围盒的距离
	float far = min(tmax.x, min( tmax.y, tmax.z)); // 光线最终离开包围盒的距离
	return vec2( near, far );
}

void main(void)
{
    vec3 rayDir = normalize(vDirection);

    vec2 bounds = hitBox( vCameraModelPosition, rayDir );
    bounds.x -= 0.000001;
	if ( bounds.x >= bounds.y) discard;//光线与包围盒无交点。

	vec3 sampleStart = vCameraModelPosition + bounds.x * rayDir;
        
    // 初始化颜色累积
    vec4 finalColor = vec4(0.0);
    const float opacityThreshold = 0.99;   // 不透明度阈值

    float T = 1.0;
    // 光线步进采样
    float delta = sqrt(3.0) / float(steps);             // 均匀步长
    vec3 voxelSizeInv = 1.0 / (maxBound - minBound); 
    for (float t = bounds.x; t < bounds.y; t += delta) {
        sampleStart = vCameraModelPosition + t * rayDir;
        vec3 texCoord = (sampleStart - minBound) * voxelSizeInv;
        
        float density = texture3D(baseTexture, texCoord).r;
        vec4 color = texture1D(tfTexture, density);
        color.rbg = pow(color.rbg, vec3(2.2));//从gamma空间转换到线性空间
        color *= densityFactor * delta;
        finalColor += T*color;
        T*=1.0-color.a;
        
        if (T<0.01) break;
    }

    // 丢弃完全透明的片元
    if (finalColor.a < EPSILON) discard;
    finalColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2));
    gl_FragColor = finalColor;

}
相关推荐
指掀涛澜天下惊3 天前
DirectX12(D3D12)基础教程六 计算着色器通用计算
着色器·计算着色器·gpu计算
Forest_101010 天前
GLSL(OpenGL 着色器语言)基础语法
着色器
滴水成川17 天前
Metal 着色器与渲染管线
着色器·metal
stevenzqzq17 天前
openGl片段着色器的含义
opengl·着色器
Allen747418 天前
往期项目shader着色器实践效果应用合集
着色器·ta
不收藏找不到我25 天前
10、基于osg引擎生成热力图高度图实现3D热力图可视化、3D热力图实时更新(带过渡效果)
3d·数据可视化·着色器
MessiGo1 个月前
OpenGL(4)着色器
apache·着色器
太妃糖耶1 个月前
Shader中着色器的编译目标级别
unity·shader·着色器
HELLOMILI1 个月前
[Unity3D] 动态立方体贴图系统
游戏·unity·游戏引擎·图形渲染·着色器