Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 9 of 9

Thread: GPU-based volume raycasting

  1. #1
    Junior Member Newbie
    Join Date
    Jul 2012
    Location
    Beijing
    Posts
    13

    Question GPU-based volume raycasting

    hello, i have download an source code of GPU-based volume raycasting,which is based on Qt. And i upload it to my google code as below:
    http://code.google.com/p/qt-color-de...downloads/list
    I have read several times of the source code, but in some place i still cannot understand.
    in frag_shader
    Code :
    vec2 intersectBox(vec4 texel_zero, vec4 texel_dir_norm)
    {
    	float t1,t2;
    	t1=(0.0-texel_zero.x)/texel_dir_norm.x;
    	t2=(1.0-texel_zero.x)/texel_dir_norm.x;
    	float tminX=min(t1,t2);
    	float tmaxX=max(t1,t2);
    	t1=(0.0-texel_zero.y)/texel_dir_norm.y;
    	t2=(1.0-texel_zero.y)/texel_dir_norm.y;
    	float tminY=min(t1,t2);
    	float tmaxY=max(t1,t2);
    	t1=(0.0-texel_zero.z)/texel_dir_norm.z;
    	t2=(1.0-texel_zero.z)/texel_dir_norm.z;
    	float tminZ=min(t1,t2);
    	float tmaxZ=max(t1,t2);
    	float largest_tmin = max(max(tminX, tminY), max(tminX, tminZ));
    	float smallest_tmax = min(min(tmaxX, tmaxY), min(tmaxX, tmaxZ));
    	vec2 result=vec2(largest_tmin,smallest_tmax);
    	return result;
    }
    Can somebody tell me how this function get the near and far .
    Last edited by qlizhi; 10-15-2012 at 01:53 AM.

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    Apr 2010
    Posts
    785
    That looks like a (fairly standard) algorithm to intersect a ray with an axis aligned box (i.e. your favourite search engine should produce a better explanation than what follows ). The basic idea is for each axis to determine the distances (t1, t2) along the ray where it enters/leaves the box. Since this is done for each axis separately you only care about where the ray crosses the planes that coincide with the box sides that are orthogonal to the axis you are processing. The ray is inside the box when it has entered it over all three planes and leaves the box as soon as it exits the first one again, that's why you want the largest of the tmin (enter distances), and the smallest of the tmax (leave distances).

    FWIW, I'm pretty sure this can be vectorized for better efficiency.

  3. #3
    Junior Member Newbie
    Join Date
    Jul 2012
    Location
    Beijing
    Posts
    13
    Thank you very much, but i still donot know what does "t1=(0.0-texel_zero.x)/texel_dir_norm.x" mean.

  4. #4
    Advanced Member Frequent Contributor
    Join Date
    Apr 2010
    Posts
    785
    Ok, fair enough. I'm afraid I don't know how to describe this substantially different from what I already wrote. Perhaps someone else wants to give it a try.

  5. #5
    Junior Member Newbie
    Join Date
    Jul 2012
    Location
    Beijing
    Posts
    13
    haha~~ i got it. thanks a lot!

  6. #6
    Junior Member Newbie
    Join Date
    Jul 2012
    Location
    Beijing
    Posts
    13
    The last question about this code is the main render code:
    Code :
    bool VolRenCore::Render()
    {
    		glClearColor(m_BackgroundColor[0], m_BackgroundColor[1], m_BackgroundColor[2], 1.0f);
    		glClearDepth(1.0f);
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    		glFrontFace(GL_CCW);
    		if (!m_Data || !m_Data->GetData()) return false;
    		if (m_DataModified || m_Data->GetVersion()!=m_DataVersion)
    		{
    			_updateData();
    			m_DataModified=false;
    			m_DataVersion=m_Data->GetVersion();
    			m_VolTextureNeedUpdate=true;
    		}
    		if (!m_glewInit)
    		{
    			glewInit();
    			_initA2OTexture();
    			m_glewInit=true;
    		}	
     
    		if (!m_shaderInit)
    		{
    			_initShaders();
    			m_shaderInit=true;
    		}
     
    		if (m_NeedCalculateMatrix) 
    		{
    			_calculateMatrix();
    			m_NeedCalculateMatrix=false;
    		}
     
    		if (!_calculateBounds()) return false;
     
    		//Setup Shader
    		glUseProgramObjectARB(m_GLSLProgram);
     
    		GLint var = glGetUniformLocationARB(m_GLSLProgram, "P2MMatrix");
    		glUniformMatrix4fvARB(var,1,0,m_PixelsToModelMatrix.ele);
     
    		var   = glGetUniformLocationARB(m_GLSLProgram, "M2TMatrix");
    		glUniformMatrix4fvARB(var,1,0,m_ModelToTextureMatrix.ele);
     
    		var   = glGetUniformLocationARB(m_GLSLProgram, "sampleDistance");
    		glUniform1fARB(var,GetSampleDistance());
     
    		var   = glGetUniformLocationARB(m_GLSLProgram, "A2OTexture");
    		glUniform1iARB(var, 0);
     
    		if (m_VolTexture ==0 || m_VolTextureNeedUpdate) 
    		{	
    			_genVolTexture();
    			m_VolTextureNeedUpdate=false;		
    		}
     
    		var   = glGetUniformLocationARB(m_GLSLProgram, "VolTexture");
    		glUniform1iARB(var, 1);
     
    		if (m_TFTexture==0 || m_TF->IsModified()) 
    		{
    			_genTFTexture();
    			m_TF->SetUnmodified();
    		}
     
    		var   = glGetUniformLocationARB(m_GLSLProgram, "TF");
    		glUniform1iARB(var, 2);
     
    		float typeMin,typeMax;
    		if (m_Data->GetDataType()!=VolumeData::FLOAT)
    		{
    			VolumeData::DataType type=m_Data->GetDataType();
    			typeMin=(float)VolumeData::typemin[type];
    			typeMax=(float)VolumeData::typemax[type];
    		}
    		else 
    		{
    			typeMin=0.0f; 
    			typeMax=1.0f;
    		}
    		float tfMax=m_TF->GetMaxPos();
    		float tfMin=m_TF->GetMinPos();
     
    		var   = glGetUniformLocationARB(m_GLSLProgram, "scale");
    		glUniform1fARB(var, (typeMax-typeMin)/(tfMax-tfMin));
     
    		var   = glGetUniformLocationARB(m_GLSLProgram, "shift");
    		glUniform1fARB(var, (typeMin-tfMin)/(tfMax-tfMin));
     
    		int shade=m_Shade?1:0;
    		var   = glGetUniformLocationARB(m_GLSLProgram, "shade");
    	 	glUniform1iARB(var, shade);
     
    		if (m_Shade)
    		{
    			Vector worldPoint;
    			Vector modelPoint;
    			float lightPosition[3], lightFocalPoint[3];
    			Vector lightDirection;
     
    			worldPoint.ele[3]=1.0f;
     
    			worldPoint.ele[0]=m_LightPosition[0];
    			worldPoint.ele[1]=m_LightPosition[1];
    			worldPoint.ele[2]=m_LightPosition[2];
    			modelPoint=m_InvertModelViewMatrix*worldPoint;
     
    			lightPosition[0]=modelPoint.ele[0];
    			lightPosition[1]=modelPoint.ele[1];
    			lightPosition[2]=modelPoint.ele[2];
     
    			worldPoint.ele[0]=m_LightFocalPoint[0];
    			worldPoint.ele[1]=m_LightFocalPoint[1];
    			worldPoint.ele[2]=m_LightFocalPoint[2];
    			modelPoint=m_InvertModelViewMatrix*worldPoint;
     
    			lightFocalPoint[0]=modelPoint.ele[0];
    			lightFocalPoint[1]=modelPoint.ele[1];
    			lightFocalPoint[2]=modelPoint.ele[2];
     
    			lightDirection.ele[0]=lightFocalPoint[0]-lightPosition[0];
    			lightDirection.ele[1]=lightFocalPoint[1]-lightPosition[1];
    			lightDirection.ele[2]=lightFocalPoint[2]-lightPosition[2];
     
    			lightDirection.Normalize();
     
    			float lightColor[3];
    			lightColor[0]=m_LightColor[0]*m_LightIntensity;
    			lightColor[1]=m_LightColor[1]*m_LightIntensity;
    			lightColor[2]=m_LightColor[2]*m_LightIntensity;
     
    			float ambient[3];
    			float diffuse[3];
    			float specular[3];
    			float spacings[3];
    			float specThreshold;			
     
    			ambient[0]=m_Ambient*lightColor[0];
    			ambient[1]=m_Ambient*lightColor[1];
    			ambient[2]=m_Ambient*lightColor[2];
     
    			diffuse[0]=m_Diffuse*lightColor[0];
    			diffuse[1]=m_Diffuse*lightColor[1];
    			diffuse[2]=m_Diffuse*lightColor[2];
     
    			specular[0]=m_Specular*lightColor[0];
    			specular[1]=m_Specular*lightColor[1];
    			specular[2]=m_Specular*lightColor[2];
     
    			m_Data->GetSpacings(spacings);
     
    			specThreshold=pow(0.001f/max(max(specular[0],specular[1]),specular[2]),1.0f/m_SpecularPower);
     
    			var   = glGetUniformLocationARB(m_GLSLProgram, "ambient");
    			glUniform3fARB(var, ambient[0],ambient[1],ambient[2]);
     
    			var   = glGetUniformLocationARB(m_GLSLProgram, "diffuse");
    			glUniform3fARB(var, diffuse[0],diffuse[1],diffuse[2]);
     
    			var   = glGetUniformLocationARB(m_GLSLProgram, "specular");
    			glUniform3fARB(var, diffuse[0],diffuse[1],diffuse[2]);
     
    			var   = glGetUniformLocationARB(m_GLSLProgram, "specular_power");
    			glUniform1fARB(var, m_SpecularPower);
     
    			var   = glGetUniformLocationARB(m_GLSLProgram, "light_direction");
    			glUniform4fARB(var, lightDirection.ele[0],lightDirection.ele[1],lightDirection.ele[2],0.0f);
     
    			var   = glGetUniformLocationARB(m_GLSLProgram, "spacings");
    			glUniform4fARB(var,spacings[0],spacings[1],spacings[2],1.0f);
     
    			var   = glGetUniformLocationARB(m_GLSLProgram, "spec_threshold");
    			glUniform1fARB(var, specThreshold);
    		}
     
    		float ratio=m_SampleDistance/m_StdSampleDistance;
    		float alphaToOpacity[256];
    		int i;
    		for (i=0;i<256;i++) 
    			alphaToOpacity[i]=1.0f-pow(1.0f-i/256.0f,ratio);
     
    		glActiveTextureARB(GL_TEXTURE1_ARB);
    		glBindTexture(GL_TEXTURE_1D,m_A2OTexture);
    		glTexSubImage1D(GL_TEXTURE_1D,0,0,256,GL_LUMINANCE,GL_FLOAT,alphaToOpacity);
     
    	// render texture
     
    		glMatrixMode(GL_PROJECTION);
    		glLoadIdentity();
     
    		glMatrixMode(GL_MODELVIEW);
    		glLoadIdentity();
    		glMultMatrixf(m_PixelsToViewMatrix);	
     
    		glEnable(GL_BLEND);
    		glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
     
    		glBegin(GL_QUADS);
    		glTexCoord2i(m_ImageOrigin[0],m_ImageOrigin[1]);
    		glVertex2i(m_ImageOrigin[0],m_ImageOrigin[1]);
    		glTexCoord2i(m_ImageOrigin[0],m_ImageOrigin[1]+m_ImageInUseSize[1]);
    		glVertex2i(m_ImageOrigin[0],m_ImageOrigin[1]+m_ImageInUseSize[1]);
    		glTexCoord2i(m_ImageOrigin[0]+m_ImageInUseSize[0],m_ImageOrigin[1]+m_ImageInUseSize[1]);
    		glVertex2i(m_ImageOrigin[0]+m_ImageInUseSize[0],m_ImageOrigin[1]+m_ImageInUseSize[1]);
    		glTexCoord2i(m_ImageOrigin[0]+m_ImageInUseSize[0],m_ImageOrigin[1]);
    		glVertex2i(m_ImageOrigin[0]+m_ImageInUseSize[0],m_ImageOrigin[1]);
    		glEnd();
     
    		glUseProgramObjectARB(0);
    		glActiveTextureARB(GL_TEXTURE0_ARB);
     
    	return true;
    }

    I donot understand about the below codes:
    // render texture
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glMultMatrixf(m_PixelsToViewMatrix);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

    glBegin(GL_QUADS);
    glTexCoord2i(m_ImageOrigin[0],m_ImageOrigin[1]);
    glVertex2i(m_ImageOrigin[0],m_ImageOrigin[1]);
    glTexCoord2i(m_ImageOrigin[0],m_ImageOrigin[1]+m_ImageInUseSize[1]);
    glVertex2i(m_ImageOrigin[0],m_ImageOrigin[1]+m_ImageInUseSize[1]);
    glTexCoord2i(m_ImageOrigin[0]+m_ImageInUseSize[0],m_ImageOrigin[1]+m_ImageInUseSize[1]);
    glVertex2i(m_ImageOrigin[0]+m_ImageInUseSize[0],m_ImageOrigin[1]+m_ImageInUseSize[1]);
    glTexCoord2i(m_ImageOrigin[0]+m_ImageInUseSize[0],m_ImageOrigin[1]);
    glVertex2i(m_ImageOrigin[0]+m_ImageInUseSize[0],m_ImageOrigin[1]);
    glEnd();

    glUseProgramObjectARB(0);
    glActiveTextureARB(GL_TEXTURE0_ARB);
    why need to render texture and the texture is GL_TEXTURE1_ARB ?
    Last edited by qlizhi; 10-19-2012 at 02:15 AM.

  7. #7
    Advanced Member Frequent Contributor
    Join Date
    Apr 2010
    Posts
    785
    As far as I can tell the program uses two textures, one 3D one that contains the volume data and a 1D texture that contains some lookup table (for alpha values, going by the name). The use of texture unit 1 is a fairly arbitrary choice, the author could have used texture units 3 and 6 just as well. The only thing that needs to match is which texture is bound to which texture unit and the values assigned to the sampler uniforms (i.e.

    Code :
    var   = glGetUniformLocationARB(m_GLSLProgram, "VolTexture");
    glUniform1iARB(var, 1);
    )

    Hmm, those actually seem to be mixed up in the code you posted. The "VolTexture" sampler is assigned value 1, but then

    Code :
    glActiveTextureARB(GL_TEXTURE1_ARB);
     glBindTexture(GL_TEXTURE_1D,m_A2OTexture);

    binds the lookup table texture to texture unit 1.

  8. #8
    Junior Member Newbie
    Join Date
    Jul 2012
    Location
    Beijing
    Posts
    13
    Yes, i think it use texture m_A2OTexture, and then render it to a 2D quads. It is hard to understand. If you have time , you can download the source code.

  9. #9
    Junior Member Newbie
    Join Date
    Jul 2012
    Location
    Beijing
    Posts
    13
    When i change it to
    Code :
    glActiveTextureARB(GL_TEXTURE0_ARB);
     glBindTexture(GL_TEXTURE_1D,m_A2OTexture);
    it shows the same output.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •