/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright (c) 2004-2013 HUBzero Foundation, LLC * * Authors: * Wei Qiao * Leif Delgass */ #include "common.cg" //#define LIGHT_TWO_SIDE /* * render one volume * * material: * x: ambient coefficient * y: diffuse coefficient * z: specular level/coefficient * w: specular exponent * renderParams: * x: sample distance ratio (0 = single slice) * y: isosurface flag (opacity scaling on/off) * z: opacity scale * w: two-sided lighting */ PixelOut main(v2f IN, uniform sampler3D volume, uniform sampler1D tf, uniform float4 material, uniform float4 renderParams) { PixelOut OUT; float4 sample = tex3D(volume, IN.TexCoord.xyz); //sample the transfer function texture float4 color = tex1D(tf, sample.x); if (renderParams.x == 0.0) { //If single slice render, only flat shading, completely opaque. color.w = 1; } else { //regular volume rendering, we do PHONG SHADING //lighting parameters float3 normal; float diffuse, specular; if (dot(sample.yzw, sample.yzw) < 5.0e-5) { diffuse = 0; specular = 0; } else { normal = normalize(sample.yzw * 2.0 - 1.0); float3 light_vector = normalize(IN.Light); float3 eye_vector = normalize(IN.EyeVector); float3 half_vector = normalize(eye_vector+light_vector); //lighting computation #ifndef LIGHT_TWO_SIDE float normal_dot_light = dot(normal, light_vector); float normal_dot_half = dot(normal, half_vector); if (renderParams.w > 0.5) { normal_dot_light = abs(normal_dot_light); normal_dot_half = abs(normal_dot_half); } else { normal_dot_light = max(normal_dot_light, 0); normal_dot_half = max(normal_dot_half, 0); } #else float normal_dot_light = abs(dot(normal, light_vector)); float normal_dot_half = abs(dot(normal, half_vector)); #endif diffuse = normal_dot_light * material.y; if (diffuse > 1.0e-6) specular = pow(normal_dot_half, material.w) * material.z; else specular = 0.0; } float ambient = material.x; color.xyz = color.xyz * (ambient + diffuse) + float3(specular); if (renderParams.y < 0.5) { // Opacity scaling: equivalent to scaling transfer function color.w = color.w * renderParams.z; // Apply opacity correction for ratio of current sample distance // to data set sample distance color.w = (1.0 - pow((1.0 - color.w), renderParams.x)); } } OUT.Color = min(max(color, 0.0), 1.0); return OUT; }