XiaJun
XiaJun

Reputation: 1915

Volume rendering using Cg:compile error:semantic "POSITION" not visible in this profile

I am now coding to implement direct ray-casting volume rendering using OpenGL,Cg and C++.My computer's system is Win7 and my graphics is nVidia GTX570.

Actually,I have implement basic functions of direct ray-casting volume rendering sucessfully.But now I want to add illumination on it and I use local illumination model.After I add several lines of code for illumination,I get Cg compiler error.Before adding,it runs well.

The Cg profile I use is CG_PROFILE_VP40 and CG_PROFILE_FP40.

Now I post my Cg code:

#define kNumberOfRaySteps 800
// Define interface between the application and the vertex program
struct app_vertex
 {
   float4 Position     : POSITION;
   float4 TexCoord     : TEXCOORD1; 
   float4 Color        : COLOR0;
};

// Define the interface between the vertex- and the fragment programs
struct vertex_fragment
 {
   float4 Position    : POSITION; // For the rasterizer
   float4 TexCoord    : TEXCOORD0;
   float4 Color       : TEXCOORD1;
   float4 Pos         : TEXCOORD2;
};

struct fragment_out 
{
  float4 Color      : COLOR0;
};

//Blinn-Phong illumination
float3 shading(float3 N, float3 V, float3 L) {
    // material properties
    float3 Ka = float3(0.1, 0.1, 0.1); // ambient
    float3 Kd = float3(0.6, 0.6, 0.6); // diffuse
    float3 Ks = float3(0.2, 0.2, 0.2); // specular
    float n = 100.0; // shininess
    // light properties
    float3 lightColor = float3(1.0, 1.0, 1.0);
    float3 ambientLight = float3(0.3, 0.3, 0.3);
    // Calculate halfway vector
    float3 H= normalize(L + V);
    // Compute ambient term
    float3 ambient = Ka * ambientLight;
    // Compute the diffuse term
    float diffuseLight = max(dot(L, N), 0);
    float3 diffuse = Kd * lightColor * diffuseLight;
    // Compute the specular term
    float specularLight = pow(max(dot(H, N), 0), n);
    if (diffuseLight <= 0) specularLight = 0;
    float3 specular = Ks * lightColor * specularLight;
    return ambient + diffuse + specular;
}

// Raycasting vertex program implementation
vertex_fragment vertex_main( app_vertex IN )
{    
  vertex_fragment OUT;

  // Get OpenGL state matrices
  float4x4 ModelView = glstate.matrix.modelview[0];//model view matrix 0
  float4x4 ModelViewProj = glstate.matrix.mvp;//modelview-projection matrix

  // Transform vertex
  OUT.Position = mul( ModelViewProj, IN.Position );
  OUT.Pos =  mul( ModelViewProj, IN.Position ); 
  OUT.TexCoord = IN.TexCoord;
  OUT.Color = IN.Color;
  return OUT;
}

// Raycasting fragment program implementation
fragment_out fragment_main( vertex_fragment IN,
                            uniform sampler2D tex, //back face
                            uniform sampler2D preint_table,//pre-intergration classification
                            uniform sampler3D volume_tex, //volume data
                            uniform float stepsize,
                            //add local illumination
                            uniform float3 lightPosition,//the external light position
                            uniform float3 eyePosition,//the eye position
                            uniform sampler3D normal_vec//normal vectors
                        )     
{
  fragment_out OUT;
  // find the right place to lookup in the backside buffer
  //normalize the spatial position to range [0,1]
  float2 texc = ((IN.Pos.xy / IN.Pos.w) + 1) / 2; 
  // the start position of the ray is stored in the texturecoordinate
  float4 start = IN.TexCoord; 
  float4 back_position  = tex2D(tex, texc);
  float3 dir = float3(0,0,0);
  dir.x = back_position.x - start.x;
  dir.y = back_position.y - start.y;
  dir.z = back_position.z - start.z;
  // the length from front to back is calculated and used to terminate the ray
  float len = length(dir.xyz); 
  float3 norm_dir = normalize(dir);
  float delta = stepsize;
  float3 delta_dir = norm_dir * delta;
  float delta_dir_len = length(delta_dir);
  float3 vec1 = start.xyz;//position of back point
  float3 vec2 = start.xyz;//position of front point
  float4 col_acc = float4(0,0,0,0);
  float alpha_acc = 0;//accumulation of alpha value(opacity)
  float length_acc = 0;
  float4 color_sample;
  float alpha_sample;
  float4 lookup = float4(0.0,0.0,0.0,0.0);
   //set background color to blue
  float4 backgroundColor = float4(1.0,1.0,1.0,0.0);


  //loops:sample points
  for(int i = 0; i < kNumberOfRaySteps; i++)
  {
      vec2 += delta_dir;

      lookup.x = (tex3D(volume_tex,vec1)).x;//scalar value of back point
      lookup.y = (tex3D(volume_tex,vec2)).x;//scalar value of front point
      color_sample = tex2D(preint_table,lookup.xy);
      alpha_sample = color_sample.a;

     //add code for illumination
     float3 N = tex3D(normal_vec,start.xyz).xyz;//normal vector
     //calculate light and viewing directions
     float3 L = normalize(lightPosition - IN.Position.xyz);
     float3 V = normalize(eyePosition - IN.Position.xyz);

      col_acc   += (1.0 - alpha_acc) * color_sample * alpha_sample * 2;

      //add ilumination color 
      col_acc += float4(shading(N,V,L),0.0);

      alpha_acc += (1.0 - alpha_acc) * alpha_sample;
      vec1 += delta_dir;//next sample point
      length_acc += delta_dir_len;//accumulation of ray length in the cube
      //change the background color from black to other color
      if(length_acc >= len) 
          col_acc += (1.0 - alpha_acc) * backgroundColor;
      // terminate if opacity > 1 or the ray is outside the volume
      if(length_acc >= len || alpha_acc > 0.99) break; 
  }

  OUT.Color =  col_acc;

  return OUT;
}

The information about Cg error: enter image description here

I found that if I erase the line

col_acc += float4(shading(N,V,L),0.0);

Then the program runs well,surely I cannot get the illumination effect. So I guess there is something wrong with the function shading of calculating illumination effect.

But I cannot figure it out. Could someone tell me how to solve this problem?

Upvotes: 2

Views: 2040

Answers (1)

XiaJun
XiaJun

Reputation: 1915

At last ,I resolved this problem.

The reason of this error is that I cannot access a POSITION parameter in a fragment shader,as the POSITION output of the vertex shader goes only to the rasterizer, and not to the fragment shader.So I need to pass it as a non-POSITION parameter,for example,TEXCOORD.In this program ,I can access the paramter Pos in stead of Position to get the right result.

Unfortunately,no one answer me. Is the reason is that there are not many people use Cg and do GPU programming? I wonder why.

Upvotes: 10

Related Questions