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;

}
相关推荐
郑寿昌2 天前
UE5与UE6在Lumen和Nanite的差异解析
游戏引擎·图形渲染·着色器
threelab2 天前
Three.js 动态旋转同心圆着色器 | 三维可视化效果
开发语言·javascript·着色器
♡すぎ♡3 天前
ShaderLab:海面——顶点变换,程序化生成无需贴图
计算机图形学·opengl·着色器
UTwelve10 天前
【UE】Gerstner Waves 水体模拟 4 :[颜色构成阶段3、4] - 实现NAP+CDOM
ue5·着色器
Yasin Chen10 天前
Unity TMP_SDF 分析(五)片元着色器
unity·游戏引擎·着色器
AIminminHu12 天前
OpenGL渲染与几何内核那点事-项目实践理论补充(一-3-(10):从“像素画师”到“硅基神明”:一个CAD开发者穿越GPU着色器管线的十年进化史)
着色器·片段着色器·顶点着色器·opengl 1.0·顶点/片段着色器
AIminminHu15 天前
OpenGL渲染与几何内核那点事-项目实践理论补充(一-3-(7):从“显卡不听话”到“GPU秒懂你”:一个CAD老兵的着色器驯服史))
着色器·编译流程·着色器语言 glsl·创建着色器对象·glcreateshader·gluseprogram·glcreateprogram
♡すぎ♡15 天前
ShaderLab:线条几何体旋转
unity·计算机图形学·着色器·shaderlab
AIminminHu17 天前
OpenGL渲染与几何内核那点事-项目实践理论补充(一-3-(3):GPU 着色器进化史:从傻瓜相机到 AI 画师,你的显卡里藏着一场战争)
人工智能·着色器
UQ_rookie21 天前
【Unity3D】在URP渲染管线下使用liltoon插件出现粉色无法渲染情况的解决方案
unity·游戏引擎·shader·urp·着色器·vrchat·liltoon