Skip to content

Instantly share code, notes, and snippets.

@vinjn
Last active December 15, 2015 03:29
Show Gist options
  • Save vinjn/5194189 to your computer and use it in GitHub Desktop.
Save vinjn/5194189 to your computer and use it in GitHub Desktop.
VolumeRayCasting hlsl SM4/5
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
Texture2D FrontS : register( t0 );
Texture2D BackS : register( t1 );
Texture3D VolumeS : register( t2 );
Texture2D TransferFunction : register( t3 );
SamplerState samLinear : register( s0 );
cbuffer cbNeverChanges : register( b0 )
{
matrix View;
};
cbuffer cbChangeOnResize : register( b1 )
{
matrix Projection;
};
cbuffer cbChangesEveryFrame : register( b2 )
{
matrix World;
};
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
float4 pos : POSITION;
float2 tex : TEXCOORD0;
};
struct VS_OUTPUT
{
float4 posH : SV_POSITION;
float3 texC : TEXCOORD0;
float4 pos : TEXCOORD1;
};
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_OUTPUT VS( VS_INPUT input )
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.posH = mul( input.pos, World );
output.posH = mul( output.posH, View );
output.posH = mul( output.posH, Projection );
output.texC = input.pos.xyz;
output.pos = output.posH;
return output;
}
float4 PosToColorPS(VS_OUTPUT input) : SV_TARGET
{
return float4(input.texC, 1);
}
#define StepSize 0.005f
#define Iterations 10000
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 RayCastPS(VS_OUTPUT input) : SV_TARGET
{
//calculate projective texture coordinates
//used to project the front and back position textures onto the cube
float2 texC = input.pos.xy / input.pos.w;
texC.x = 0.5f*texC.x + 0.5f;
texC.y = -0.5f*texC.y + 0.5f;
float3 front = FrontS.Sample(samLinear, texC).xyz;
float3 back = BackS.Sample(samLinear, texC).xyz;
float3 dir = normalize(back - front);
float3 pos = front;
float4 dst = float4(0, 0, 0, 0);
float4 src = 0;
float3 Step = dir * StepSize;
for(int i = 0; i < Iterations; i++)
{
float value = VolumeS.SampleLevel(samLinear, pos.xyz, 0).r;
#if 0
// colorless
float4 src = float4(value, value,value,value);
#else
// colorful
float4 src = float4(TransferFunction.SampleLevel(samLinear, float2(value, 0), 0).rgb, value);
#endif
src.a *= .5f; //reduce the alpha to have a more transparent result
//Front to back blending
// dst.rgb = dst.rgb + (1 - dst.a) * (src.a * src.rgb)
// dst.a = dst.a + (1 - dst.a) * src.a
src.rgb *= src.a;
dst = (1.0f - dst.a)*src + dst;
//break from the loop when alpha gets high enough
if(dst.a >= .95f)
break;
//advance the current position
pos.xyz += Step;
//break if the position is greater than <1, 1, 1>
if(pos.x > 1.0f || pos.y > 1.0f || pos.z > 1.0f)
break;
}
return dst;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment