Last active
December 15, 2015 03:29
-
-
Save vinjn/5194189 to your computer and use it in GitHub Desktop.
VolumeRayCasting hlsl SM4/5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//-------------------------------------------------------------------------------------- | |
// 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