[GSoC 2012] Volume Rendering with LOD aimed at terrain

Threads related to Google Summer of Code
Post Reply
User avatar
Xavyiy
OGRE Expert User
OGRE Expert User
Posts: 847
Joined: Tue Apr 12, 2005 2:35 pm
Location: Albacete - Spain
x 87

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Xavyiy »

Hehe, here is the fragment program I'm using in the avobe image:

Code: Select all

void main(void)
{	
	vec3 blend_weights = (abs(vNormal) -0.2)*7.0;
    blend_weights = max(blend_weights, 0.0);
    blend_weights /= blend_weights.x + blend_weights.y + blend_weights.z;
	
	vec2 coord1 = vPosition.yz * uTexturesScale.x;
    vec2 coord2 = vPosition.zx * uTexturesScale.y;
    vec2 coord3 = vPosition.xy * uTexturesScale.z;
	
	vec3 colX = texture2D(uTexX, coord1).xyz;
	vec3 colY = texture2D(uTexY, coord2).xyz;
	vec3 colZ = texture2D(uTexZ, coord3).xyz;
	
	vec3 plainColor = colX * blend_weights.x +
			          colY * blend_weights.y +
			          colZ * blend_weights.z;
					  
    // Tangent space normal mapping
	vec3 tangent = vec3(1, 0, 0);
    vec3 binormal = normalize(cross(tangent, vNormal));
    tangent = normalize(cross(vNormal, binormal));
    mat3 rotMatrix = transpose(mat3(tangent, binormal, vNormal));
	
    vec3 normalX = (texture2D(uTexXNormal, coord1).xyz - 0.5)*2.0;
    vec3 normalY = (texture2D(uTexYNormal, coord2).xyz - 0.5)*2.0;
    vec3 normalZ = (texture2D(uTexZNormal, coord3).xyz - 0.5)*2.0;
	
    vec3 normal = normalX.xyz * blend_weights.x +  
                  normalY.xyz * blend_weights.y +  
                  normalZ.xyz * blend_weights.z;
			 
	// Lighting
	vec3 lightDir = rotMatrix * normalize(uLightPosition_-vPosition);
	vec3 viewDir  = rotMatrix * normalize(uCameraPosition-vPosition);
	float nDotL = dot(normal, lightDir);
	
	// Diffuse
	vec3 diffuseColor = uLightColor * clamp(nDotL, 0.0, 1.0);
	
	// Specular
    vec3 reflected = normalize(2.0 * nDotL * normal - lightDir); // Reflected vector
    float dotProduct = clamp(dot(reflected, viewDir), 0.0, 1.0);
	
	vec3 specularColor = uLightColor * max(pow(dotProduct, uShininess), 0.0);
	
	// Linear attenuation
	float attenuation = uAttenuationDistance/(uAttenuationDistance+vLightDistance);
   
    vec3 finalColor = plainColor*(uAmbientColor + attenuation*diffuseColor) + attenuation*specularColor;
	
	gl_FragColor = vec4(finalColor, 1.0);
}
Hope it helps!

P.D.: I've the HLSL version too, if needed!
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Mattan Furst »

@PhilipLB

I have to say that your doing bloody marvelous work.

Not to nitpick, but do you know what is the black triangle in the top right corner at the beginning and at 0:39 in your video. Are you having issues with the triangulation process, is that just part of the terrain data or some sort of known issue with the algorithm, because accept for that everything looks great.

Update: I think I also see some breaks in the terrain (0:42)
it's turtles all the way down
PhilipLB
Google Summer of Code Student
Google Summer of Code Student
Posts: 550
Joined: Thu Jun 04, 2009 5:07 pm
Location: Berlin
x 108

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by PhilipLB »

Wow, thx! :)

About the flying thingy at the beginning: This one is fine, Acropora exported it that way.
About the issue at 0:42: This one is no crack but a skirt with another "dominant" texture than grass through the triplanar texturing. Not that beautifull, yep.
So far, I'm not aware of any triangulation issues. :)
Google Summer of Code 2012 Student
Topic: "Volume Rendering with LOD aimed at terrain"
Project links: Project thread, WIKI page, Code fork for the project
Mentor: Mattan Furst


Volume GFX, accepting donations.
PhilipLB
Google Summer of Code Student
Google Summer of Code Student
Posts: 550
Joined: Thu Jun 04, 2009 5:07 pm
Location: Berlin
x 108

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by PhilipLB »

@Xavyiy:
I'm playing arround to fix the colours in my shader. They are the same now as in yours, but far darker. Any idea, how that comes? Do you use any ambient light?
Here's how the changed parts look now:

Code: Select all

	float4 textColour = float4(col1.xyz * blendWeights.x +
		col2.xyz * blendWeights.y +
		col3.xyz * blendWeights.z, 1);
...
oColor = saturate(textColour * lightContribution + ambient);
// Edit:

Actually, I think it looks ok. I added a second light source to brighten up the dark parts a bit and 0.1 ambient. I think I'm just not used to it. What do you think?
Attachments
screenshot07172012_115006360.png
screenshot07172012_115006360.png (182.32 KiB) Viewed 4169 times
Google Summer of Code 2012 Student
Topic: "Volume Rendering with LOD aimed at terrain"
Project links: Project thread, WIKI page, Code fork for the project
Mentor: Mattan Furst


Volume GFX, accepting donations.
User avatar
Xavyiy
OGRE Expert User
OGRE Expert User
Posts: 847
Joined: Tue Apr 12, 2005 2:35 pm
Location: Albacete - Spain
x 87

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Xavyiy »

Yes, I'm using a strong ambient light (near to pure white). You've to think that otherwise (without ambient light and only taking account one light source), there should be very dark areas due to some terrain parts are not receiving any light.

Also, I think you should implement specular highlights in your shader, it really improves the overall look on certain view angles :). You've an example on the code I posted before:

Code: Select all

// Specular
    vec3 reflected = normalize(2.0 * nDotL * normal - lightDir); // Reflected vector
    float dotProduct = clamp(dot(reflected, viewDir), 0.0, 1.0);
   
   vec3 specularColor = uLightColor * max(pow(dotProduct, uShininess), 0.0);
Use a big shininess value, in the [100, 2000] range, otherwise specular highlights are going to be too strong. (The bigger shininess value, the less specular highlights)

Let me know if you've any problem,

Xavier
Last edited by Xavyiy on Tue Jul 17, 2012 11:37 am, edited 1 time in total.
User avatar
Xavyiy
OGRE Expert User
OGRE Expert User
Posts: 847
Joined: Tue Apr 12, 2005 2:35 pm
Location: Albacete - Spain
x 87

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Xavyiy »

This is what you should get using an ambient colour of (0.71, 0.71, 0.71) and a single light source with colour (1, 0.98, 0.73):
Image
PhilipLB
Google Summer of Code Student
Google Summer of Code Student
Posts: 550
Joined: Thu Jun 04, 2009 5:07 pm
Location: Berlin
x 108

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by PhilipLB »

Ah, found the error!
Before:

Code: Select all

oColor = saturate(textColour * lightContribution + ambient);
After:

Code: Select all

oColor = saturate(textColour * (lightContribution + ambient));
Thank you a lot for showing me your light setup. My shader produces similar results now. :) Specular lights are already supported due to CGs lit function.
Google Summer of Code 2012 Student
Topic: "Volume Rendering with LOD aimed at terrain"
Project links: Project thread, WIKI page, Code fork for the project
Mentor: Mattan Furst


Volume GFX, accepting donations.
User avatar
Xavyiy
OGRE Expert User
OGRE Expert User
Posts: 847
Joined: Tue Apr 12, 2005 2:35 pm
Location: Albacete - Spain
x 87

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Xavyiy »

Great!
Can't wait to see another video of your progresses! Keep up the good work!

Xavier
DragonM
Gnoblar
Posts: 22
Joined: Mon Jul 21, 2008 4:35 am
x 7

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by DragonM »

PhilipLB wrote:O(n^2) is bad, yep.

Going over an Octree could really be sensible, thx! Added this to the wiki. At least, this is stuff for the end of the GSoC or afterwards. :)
If the process still doesn't take long, even high complexity is acceptable for an offline processing task. However, I can vouch the quoted complexity is killer.

I've implemented precisely that scheme for converting heightmap data to voxel data, and my software estimated its runtime to completely convert my heightmap dataset at 21 days and some hours. The conversion task is so perfectly linear that the completion estimator is extremely accurate. I use PolyVox for voxel storage. Exhaustive traversal of a large voxel space is incredibly expensive.

My solution didn't involve anything as exotic as octrees. I simply traverse the X-Z plane, writing voxels at the height calculated from the heightmap data, then, in a second pass, traverse the X-Z plane by block (PolyVox stores voxels in 32x32x32 voxel blocks, so it's most efficient to step through a PolyVox volume block by block) using PolyVox::Raycast to find the height at block corners, then calculate the block coordinates that encompass that corner and save the block. This method converts my dataset in a matter of hours. (The only reason it still takes hours is because I still generate LODs using PolyVox's basic technique, which exhaustively traverses the entire volume.) It could even be further optimized to traverse X-Z only once, saving as it goes, but to save myself code complexity headache, I left it alone after I achieved an acceptable runtime.

DM
DragonM
Gnoblar
Posts: 22
Joined: Mon Jul 21, 2008 4:35 am
x 7

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by DragonM »

I gather from reading the first post of the thread that your implementation loads all LODs simultaneously?

Ogre Terrain was guilty of this misstep as well. It's crippling for trying to render large terrains. First, it causes an exceedingly long load time, and second, it burns memory like crazy, both system and video memory.

It's far more useful to load only the necessary LODs. It's entirely possible that the camera may never actually get close enough to a large part of the terrain to require the higher level of detail in a particular play session, so the time and memory spent loading it is wasted.

More to the point, the total amount of terrain renderable (the draw distance) becomes severely memory bound. At the terrain resolution I wish to use, Ogre Terrain could only render 2km x 2km of terrain before running out of video memory. In the voxel system I currently have implemented, I can render 32km x 32km of terrain at LOD5, while still achieving my desired resolution near the camera. The larger draw distance is a considerably more compelling world.

I do hope you'll consider refactoring the LOD system while you're threading it to be able to load only necessary LODs, instead of all of them. You should also take care that your save format can accommodate that feature. It took another GSoC project to correct that problem in Ogre Terrain. I'd hate to see this one fall victim to the same mistake.

DM
PhilipLB
Google Summer of Code Student
Google Summer of Code Student
Posts: 550
Joined: Thu Jun 04, 2009 5:07 pm
Location: Berlin
x 108

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by PhilipLB »

Hi,

interesting postings, thx!

Streaming in the LOD levels is something for later, but shouldn't be that hard with the given data structures. It's already on the Ideas-list in the wiki. :)
Google Summer of Code 2012 Student
Topic: "Volume Rendering with LOD aimed at terrain"
Project links: Project thread, WIKI page, Code fork for the project
Mentor: Mattan Furst


Volume GFX, accepting donations.
PhilipLB
Google Summer of Code Student
Google Summer of Code Student
Posts: 550
Joined: Thu Jun 04, 2009 5:07 pm
Location: Berlin
x 108

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by PhilipLB »

Parallelization, small weaks and fixes. Image
Google Summer of Code 2012 Student
Topic: "Volume Rendering with LOD aimed at terrain"
Project links: Project thread, WIKI page, Code fork for the project
Mentor: Mattan Furst


Volume GFX, accepting donations.
PhilipLB
Google Summer of Code Student
Google Summer of Code Student
Posts: 550
Joined: Thu Jun 04, 2009 5:07 pm
Location: Berlin
x 108

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by PhilipLB »

About the RTSS:
I'm currently reading a bit into it. First small task would be to assign a material with 1 light and a color (or so) to my Chunks.
They currently implement SimpleRenderable::setMaterial(String matName).
So how could I do this with the RTSS?
As far as I can see, the RTSS expects an already existing material where it can replace the technique?
So the way to go would be to create some kind of factory method in the chunk to generate a material which can be fed into the RTSS?
Google Summer of Code 2012 Student
Topic: "Volume Rendering with LOD aimed at terrain"
Project links: Project thread, WIKI page, Code fork for the project
Mentor: Mattan Furst


Volume GFX, accepting donations.
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Mattan Furst »

The RTSS is built so that it can read a material technique (passes, textures, blend states, etc...). Read the current scene setup (lights, fog, etc...) and combine both to produce a new technique with a shaders that reflect both states.
The shader themselves are built by an array of components called sub render states (SRS). Each sub render state is responsible for a different sections in the overall shader. in a basic shader there are usually 5 components:
  • Transform (see: OgreShaderFFPTransform) - responsible for adding code to the vertex shader which computes the position of the vertex in projection space
  • Color (see: OgreShaderFFPColour) - responsible for adding code to the shaders that calculate the basic color of the object (regardless of lights) based on things such as assigned hardware buffer colour, tracked colour components, object ambient, diffuse, specular and emissive properties, etc...
  • Lighting (see: OgreShaderFFPLighting) - responsible for adding code to the shaders that calculate the added color from light
  • Texture (see: OgreShaderFFPTexture) - responsible for adding code that modulates the color of the pixels based on textures assigned to the material
  • Fog (see: OgreShaderFFPFog) - responsible for adding code that modulates the color of a pixel based on the scene fog parameters.
Subrender states are used in the creation of a shader in one if either:
  1. They have been assigned to a render state which is being used
  2. They have been assigned to a material using specific script
  3. They are one of the 5 SRSs listed above and another SRS with the same execution order (more on this in a bit) has not already been created for the material.
I believe in your case you will need to create a new sub-render state that will replace the Texture SRS.

General steps to do so will be:
  1. Create a new SRS (inherited from Ogre::RTShader::SubRenderState) and SRS factory (inherited from Ogre::RTShader::SubRenderStateFactory) that will replace the regular fixed pipeline Texture stage. Note that in order for your SRS to replace the regular texture SRS. The returned value to the function getExecutionOrder() should be FFP_TEXTURING (same as in OgreShaderFFPTexture.cpp).
  2. Add to your material a script that will inform the rtss to create your SRS. inside the pass add the lines

    Code: Select all

    rtshader_system
    {
    	volumeterrain true
    }
    
  3. Override the SRS factory function createInstance(ScriptCompiler* compiler, PropertyAbstractNode* prop, Pass* pass, SGScriptTranslator* translator). You will be able with it to check whether the above line was added to a pass and if so return and instance of your sub-render state.
  4. Register your sub-render state factory to the shader generator
  5. Now the only thing is to write the SRS itself
Other notes
  • Writing your first SRS is kind of complicated. I am sure you can do it on your own but if you want some help I'm on skype.
  • Keep in mind that your not writing running a shader. your writing code that will write code inside a shader.
  • Take a look at OgreShaderFFPTransform.cpp it is by far the simplest SRS. If you can understand whats going on there the rest should be easier
  • Notice that if you need a parameter in the pixel shader such as a texture coord or normal. It is your SRS responsibility add code that will calulate its value in the vertex shader than move it to the pixel shader.
it's turtles all the way down
PhilipLB
Google Summer of Code Student
Google Summer of Code Student
Posts: 550
Joined: Thu Jun 04, 2009 5:07 pm
Location: Berlin
x 108

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by PhilipLB »

Ok, that makes a few things clearer, thx. :)
I'll have a deeper look at it tomorrow evening then.
Google Summer of Code 2012 Student
Topic: "Volume Rendering with LOD aimed at terrain"
Project links: Project thread, WIKI page, Code fork for the project
Mentor: Mattan Furst


Volume GFX, accepting donations.
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Mattan Furst »

One more note:

The end of GSoC is arriving in less than a month. As far as I'm concerned the only thing I would want you to do before we can merge your project to Ogre is to separate the sample to a sample and plug-in. I'd rather you didn't start things you think you might not finish before the end.

If its more convenient to you we can do an early merge with Ogre (provided you do the separation to plug-in first). Than you can continue with whatever you want till the end of the GSoC.

P.S.
If you want I can also write the shell for the terrain SRS
it's turtles all the way down
PhilipLB
Google Summer of Code Student
Google Summer of Code Student
Posts: 550
Joined: Thu Jun 04, 2009 5:07 pm
Location: Berlin
x 108

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by PhilipLB »

Alright, then I swap the two points in the roadmap and do the plugin first.

PS: I might come back for the SRS. :) But first, I'd like to give it a try to learn something.
Google Summer of Code 2012 Student
Topic: "Volume Rendering with LOD aimed at terrain"
Project links: Project thread, WIKI page, Code fork for the project
Mentor: Mattan Furst


Volume GFX, accepting donations.
User avatar
spacegaier
OGRE Team Member
OGRE Team Member
Posts: 4304
Joined: Mon Feb 04, 2008 2:02 pm
Location: Germany
x 135
Contact:

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by spacegaier »

That info from Mattan should find its way into the wiki. So if someone has a bit of time, that would be great (PhilipLB?).
Ogre Admin [Admin, Dev, PR, Finance, Wiki, etc.] | BasicOgreFramework | AdvancedOgreFramework
Don't know what to do in your spare time? Help the Ogre wiki grow! Or squash a bug...
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Mattan Furst »

@spacegaier

I'll add it to the wiki this weekend. Its kind of my responsibility anyway. I'll try to write something with more meat in it too.
it's turtles all the way down
User avatar
spacegaier
OGRE Team Member
OGRE Team Member
Posts: 4304
Joined: Mon Feb 04, 2008 2:02 pm
Location: Germany
x 135
Contact:

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by spacegaier »

Mattan Furst wrote:@spacegaier

I'll add it to the wiki this weekend. Its kind of my responsibility anyway. I'll try to write something with more meat in it too.
That would be awesome!
Ogre Admin [Admin, Dev, PR, Finance, Wiki, etc.] | BasicOgreFramework | AdvancedOgreFramework
Don't know what to do in your spare time? Help the Ogre wiki grow! Or squash a bug...
drwbns
Orc Shaman
Posts: 788
Joined: Mon Jan 18, 2010 6:06 pm
Location: Costa Mesa, California
x 24

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by drwbns »

Amazing progress, love to watch this thread :)
PhilipLB
Google Summer of Code Student
Google Summer of Code Student
Posts: 550
Joined: Thu Jun 04, 2009 5:07 pm
Location: Berlin
x 108

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by PhilipLB »

Just to make sure: I'd go for a component like the OgreTerrain or the RTTS now, not a plugin in this sense: http://www.ogre3d.org/tikiwiki/tiki-ind ... e=Cookbook
Reason: There are no structures to extend yet (like registering specific factories).
Or am I overlooking something?

Wheras I actually could offer some infrastructure within the component then for the implementations of the Source interface. Something to think about later. :)
Google Summer of Code 2012 Student
Topic: "Volume Rendering with LOD aimed at terrain"
Project links: Project thread, WIKI page, Code fork for the project
Mentor: Mattan Furst


Volume GFX, accepting donations.
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Mattan Furst »

You don't need a plug-in in the sense of a structure extender. But the other way in which plug-ins are distinguished from components like RTSS is in a system's ability to load them dynamically as needed. As long as the code does not need to be tightly coupled to the Ogre core there is no reason why not to offer this ability.
This ability makes it easier to conserve in the size of the Ogre DLL which is important in some situations.

I would prefer if you implement it as a plug-in.

The main difference for you would just be the implementation of the plug-in interface (Ogre::Plugin), and the specialized implementation of the DLL startup and shutdown functions, as indicated by the example MyPluginDLL.cpp file in the wiki page you directed to.
it's turtles all the way down
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by CABAListic »

The distinction between Plugin and Component is a question: Can the functionality of the code be used without directly interfacing with its interface?

For example, any Ogre code is (usually) rendersystem agnostic - it doesn't matter which rendersystem you use, so you can dynamically load - at runtime - any number of them and just select one and go ahead. The user code is not affected by the choice. Similarly the Octree SceneManager does not require any concrete interaction from the user.

On the other hand, the Terrain and RTSS components do need direct interfacing, therefore they need to be linked to at compile time, not runtime. So the question is, does a hypothetical plugin for this volume rendering make sense? Can it be used without writing explicit code depending on it? I somehow doubt it, so unless I'm wrong I very much think a component is the right way to go.

(And just for the record: The Portal Connected Zone SceneManager is an example where the wrong decision was made, although to be fair we didn't have components at the time it was created. Either way, the point is that you can't really use it without directly interfacing with it, so it is pretty useless as a plugin.)
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: [GSoC 2012] Volume Rendering with LOD aimed at terrain

Post by Mattan Furst »

@CABAListic
Given that until now the volume terrain system existed as a sample, separated from Ogre, it should be possible to make it exist as a separate plug-in. You are right though in the sense that I have no ideas how future endeavors will influence the code and the ability to keep it decoupled from Ogre.

@PhillipLB
Since CABAListic says a component is the way to go, than given his greater experience in the subject, I would defer to his opinion.

Update:
@CABAListic
Just realized you meant interaction of the user with the terrain volume system. Not the interaction of Ogre and the terrain system. In that case your completely right.
it's turtles all the way down
Post Reply