Jump to content

  • Log In with Google      Sign In   
  • Create Account

Rendering Systems



ShaderMap 2.0.7 Update

Posted by , in ShaderMap 20 August 2012 - - - - - - · 928 views

The latest update of ShaderMap brings improved normal to displacment conversion with additional controls for contrast and height. There are other new features as well including linear magnification on preview image controls, additional zoom controls, and a map control button to refresh source images from file.

Posted Image


Next up... ShaderMap 2 R1

I'll be rebuilding the normal editor which means implementing a layer system, adding a stencil brush for painting displacement/normals, adding shapes using a vector library, an eraser tool for rasterized layers, and line/box/oval/curve gizmos. Wish me luck.

_Neil


Blending Normal Maps

Posted by , in Graphics 31 July 2012 - - - - - - · 1,374 views
combine normal maps and 1 more...
ShaderMap 2 currently implements overlay and detail oriented methods (called pure rotation in SM2) for painting normals. I may do a write up of the SM2 blending modes and maths behind them in the future.

In the meantime here is a really great article I found on blending a detail normal map with a base normal map. http://blog.selfshadow.com/publications/blending-in-detail/

Posted Image

In other news, I'm on Google+ here: Neil Kemp

and I've started a G+ page for ShaderMap as well: ShaderMap+


Woody3D Discontinued

Posted by , in Woody3D 17 July 2012 - - - - - - · 1,796 views

I'll just post what I wrote on the woody3d.com website, then I'll explain...

"Woody3D was developed by Neil Kemp at Rendering Systems Inc. as an inexpensive solution for developers to bring fully animated trees and foliage to their applications and engines. Woody3D was discontinued in July 2012.

Real-time tree generation and animation remain a core focus for Neil and Rendering Systems. In the future they’ll place a higher emphasis on modeling tools and less on source code integration."

Woody3D was a long term comitment for me. Three years of development. I wanted to create affordable real-time trees for developers. Why did it fail? Simple, the technology was complex and not easily integrated into today's popular engines. It focused more on source code integration and had a very nerdy user inteface. It should have focused on a simple intuitive interface (draw the tree - grab and bend the branches, etc.) with easy export to popular file formats.

So that's what I plan to do. Start again. I believe I can take what learned from Woody3D (and ShaderMap 2) to build a better (single) tool to generate fully animated 3D trees and plants for video games, simulations, and software rendering systems. I can't fail if I don't quit.

The Woody3D Field of Trees video will remain online:




ShaderMap 2 SDK Tutorial - Creating Maps

Posted by , in ShaderMap 16 July 2012 - - - - - - · 1,744 views

Each map in ShaderMap 2 is a plugin. The plugin is a Windows DLL with the file extension .smp. To create a map plugin you will need to download the ShaderMap 2 SDK. http://shadermap.com/downloads/ As of this tutorial I am using version 2.0.5. You will also need Visual Studio 2008 - 2010.

Once you have the SDK downloaded and unzipped navigate to the folder 'map'. Inside you will see the VS solution file called map.sln. This solution contains 3 project files. Each project builds an example map. The 3 maps demonstrate how to build:

- source maps
- maps with no inputs
- maps with inputs

For the purpose of this tutorial I will be focusing on the third project. Right click on the project 'example_3' and set it as the default project. Open the source file 'example_3.cpp' so you can follow along.

Each map plugin uses the file 'map_plugin_core.cpp' which contains all API functions for interacting with ShaderMap 2. It is included at the top of each plugin file.

Each map plugin must implement 4 functions that are prototyped in the 'map_plugin_core.cpp' file. They are:

// Initialize plugin - Called when the plugin is loaded.
// This tells ShaderMap about the plugin and sets up the plugin property controls
BOOL on_initialize(void);

// Process plugin - called each time the map needs to be regenerated - the map_id is used to gain access to the map property values.
BOOL on_process(unsigned int map_id);

// Called just before the plugin is unloaded when ShaderMap is shutdown.
// If global resources are used this is the place to release them.
BOOL on_shutdown(void);

// Called when a project is loaded - It sends the version of the plugin with which the project was saved.
// The values are arranged in the order 0,1,2,...property index.
// If the order of the property controls have changed since the version parameter then modify the index array accordingly.
void on_arrange_load_data(unsigned int version, unsigned int index_count, unsigned int* index_array);


Here is the on_initialize function:
// Initialize plugin - This tells ShaderMap about the plugin and sets up the plugin property controls
// Is called when the plugin is loaded by ShaderMap
BOOL on_initialize(void)
{		
	// Tell ShaderMap we are starting initialize
	mp_begin_initialize();

		// Set version - useful for tracking property changes
		// from version to version. See on_arrange_load_data()
		mp_set_version(101);

		// Tell ShaderMap this map plugin is type MAP
		mp_set_map_type(MAP_PLUGIN_TYPE_MAP);

		// Set name and description
		mp_set_name(_T("Example 3 Map"));
		mp_set_description(_T("An example of normal map plugin with 1 input."));

		// Set the thumbnail filename. This image must be located in "APP_DIRECTORY\plugins\(x86|x64)\maps\thumbs"
		// See examples of thumbnails in that folder.
		// Thumbnail must be 128 x 128 pixels but thumb is much smaller at 71 x 71 and offset from top-left by 12 pixels
		mp_set_thumbnail(_T("example_3.png"));

		// Set default save format for the map
		mp_set_default_format(MAP_FORMAT_TGA_RGB_8);

		// Is a normal map
		mp_enable_normal_map(TRUE);
		
		// Add 1 input
		mp_add_input(_T("Normal Map"), _T("An image with normal vectors stored per pixel."));

		// Add properties controls																										Property Index
		// Add a coodinate system property with a default coordinate system set
		mp_add_property_coordsys(_T("Coord System"), MAP_COORDSYS_X_POS_RIGHT | MAP_COORDSYS_Y_POS_DOWN | MAP_COORDSYS_Z_POS_NEAR, 0);	// 0

	// Tell ShaderMap initialize was success - map is added
	mp_end_initialize();
	
	// Success
	return TRUE;
}


The first and last API calls are mp_begin_initialize(); and mp_end_initialize(); Everything else is between those two functions.

Here we setup the version integer, the map type (source or map), the name and description, the thumbnail filename, default file save format, if the map is a normal map or not (if so then will require a coordinate system to be set), map inputs with a description, and property controls associated with the map.

Here we have set up a map that is a normal map and takes a single normal map as input. It has one property control which is a coordinate system control. In essence this map allows the user to transform the normals of the input map to a new coordinate system. But you could make it do anything (randomize normals, etc).

The on_process function is shown below:

// Process plugin - called each time the map needs to be regenerated
BOOL on_process(unsigned int map_id)
{
	// Local data
	unsigned int			thread_limit, width, height, origin, tile_type, image_type, input_coord_system, user_coord_system, i, count_i;
	float					x, y, z;

	const unsigned char*	input_pixel_array_8;
	const unsigned short*	input_pixel_array_16;

	unsigned char*			map_pixel_d_array_8;
	unsigned short*			map_pixel_d_array_16;
	

	// Get suggested thread limit for plugin process - not used in this example
	thread_limit			= mp_get_map_thread_limit();

	// -----------------

	// Get size of input
	width				= (int)mp_get_input_width(map_id, 0);
	height				= (int)mp_get_input_height(map_id, 0);
	if(!width || !height)
	{	
		LOG_ERROR_MSG(map_id, _T("Invalid input size. Width or height is zero."));
		return FALSE;
	}
	// Get origin of input
	origin				= mp_get_input_origin(map_id, 0);

	// Get tile type of input
	tile_type			= mp_get_input_tile_type(map_id, 0);

	// Get image type of input
	image_type			= mp_get_input_image_type(map_id, 0);

	// As the input is a normal map - we must get its coordinate system
	input_coord_system	= mp_get_input_coordsys(map_id, 0);

	// -----------------

	// Tell ShaderMap the tile type of this map so children of this map inherit the tile type
	switch(tile_type)
	{
	case 0:
		mp_set_map_tile_type(map_id, MAP_TILE_NONE);
		break;
	case 1:
		mp_set_map_tile_type(map_id, MAP_TILE_X);
		break;
	case 2:
		mp_set_map_tile_type(map_id, MAP_TILE_Y);
		break;
	case 3:
		mp_set_map_tile_type(map_id, MAP_TILE_XY);
		break;
	}

	// -----------------

	// Allocate map pixels and get pointer to input pixel array
	// 8 bit
	if(image_type == MAP_IMAGE_TYPE_8)
	{
		// Allocate 8 bit map pixels
		map_pixel_d_array_8 = new (std::nothrow) unsigned char[width * height * 4];
		if(!map_pixel_d_array_8)
		{	
			LOG_ERROR_MSG(map_id, _T("Failed to allocate map pixels."));
			return FALSE;
		}

		// Get pixel array of input 0
		input_pixel_array_8 = (const unsigned char*)mp_get_input_pixel_array(map_id, 0);
	}
	// 16 bit
	else
	{
		// Allocate 16 bit map pixels
		map_pixel_d_array_16 = new (std::nothrow) unsigned short[width * height * 4];
		if(!map_pixel_d_array_16)
		{	
			LOG_ERROR_MSG(map_id, _T("Failed to allocate map pixels."));
			return FALSE;
		}

		// Get pixel array of input 0
		input_pixel_array_16 = (const unsigned short*)mp_get_input_pixel_array(map_id, 0);
	}

	// -----------------
	
	// Get property values
	user_coord_system	= mp_get_property_coordsys(map_id, 0);	

	// -----------------

	// Set the map coordsys as defined by the user
	mp_set_map_coordsys(map_id, user_coord_system);

	// Get number of items in the pixel arrays
	count_i				= width * height * 4;

	// 8 bit
	if(image_type == MAP_IMAGE_TYPE_8)
	{
		// For every pixel
		for(i=0; i<count_i; i+=4)
		{
			// Convert input pixel to normal
			x			= 2.0f * ((float)input_pixel_array_8[i] / 255.0f) - 1.0f;
			y			= 2.0f * ((float)input_pixel_array_8[i+1] / 255.0f) - 1.0f;
			z			= 2.0f * ((float)input_pixel_array_8[i+2] / 255.0f) - 1.0f;

			// Normalize vector
			normalize_vector(x, y, z);

			// Compare input coordsys with user coordsys and flip values as needed
			// Adjust X
			if((input_coord_system & MAP_COORDSYS_X_POS_RIGHT) != (user_coord_system & MAP_COORDSYS_X_POS_RIGHT))
			{	x		= -x;
			}
			// Adjust Y
			if((input_coord_system & MAP_COORDSYS_Y_POS_DOWN) != (user_coord_system & MAP_COORDSYS_Y_POS_DOWN))
			{	y		= -y;
			}
			// Adjust Z
			if((input_coord_system & MAP_COORDSYS_Z_POS_NEAR) != (user_coord_system & MAP_COORDSYS_Z_POS_NEAR))
			{	z		= -z;
			}

			// Store normal as color in the map pixel array
			map_pixel_d_array_8[i]		= (unsigned char)((x + 1.0f) / 2.0f * 255.0f);
			map_pixel_d_array_8[i+1]	= (unsigned char)((y + 1.0f) / 2.0f * 255.0f);
			map_pixel_d_array_8[i+2]	= (unsigned char)((z + 1.0f) / 2.0f * 255.0f);
			map_pixel_d_array_8[i+3]	= input_pixel_array_8[i+3];

			// Check for cancel
			if(mp_is_cancel_process())
			{	delete [] map_pixel_d_array_8;
				return FALSE;
			}
		}
	}
	// 16 bit
	else
	{
		// For every pixel
		for(i=0; i<count_i; i+=4)
		{
			// Convert input pixel to normal
			x			= 2.0f * ((float)input_pixel_array_16[i] / 65535.0f) - 1.0f;
			y			= 2.0f * ((float)input_pixel_array_16[i+1] / 65535.0f) - 1.0f;
			z			= 2.0f * ((float)input_pixel_array_16[i+2] / 65535.0f) - 1.0f;			

			// Normalize vector
			normalize_vector(x, y, z);

			// Compare user coordsys and flip values as needed
			// Adjust X
			if((input_coord_system & MAP_COORDSYS_X_POS_RIGHT) != (user_coord_system & MAP_COORDSYS_X_POS_RIGHT))
			{	x		= -x;
			}
			// Adjust Y
			if((input_coord_system & MAP_COORDSYS_Y_POS_DOWN) != (user_coord_system & MAP_COORDSYS_Y_POS_DOWN))
			{	y		= -y;
			}
			// Adjust Z
			if((input_coord_system & MAP_COORDSYS_Z_POS_NEAR) != (user_coord_system & MAP_COORDSYS_Z_POS_NEAR))
			{	z		= -z;
			}

			// Store normal as color in the map pixel array
			map_pixel_d_array_16[i]		= (unsigned short)((x + 1.0f) / 2.0f * 65535.0f);
			map_pixel_d_array_16[i+1]	= (unsigned short)((y + 1.0f) / 2.0f * 65535.0f);
			map_pixel_d_array_16[i+2]	= (unsigned short)((z + 1.0f) / 2.0f * 65535.0f);
			map_pixel_d_array_16[i+3]	= input_pixel_array_16[i+3];

			// Check for cancel
			if(mp_is_cancel_process())
			{	delete [] map_pixel_d_array_8;
				return FALSE;
			}
		}
	}

	// -----------------

	// Create the final map using the map pixels
	// 8 bit
	if(image_type == MAP_IMAGE_TYPE_8)
	{
		if(!mp_create_map(map_id, width, height, origin, image_type, map_pixel_d_array_8))
		{	
			LOG_ERROR_MSG(map_id, _T("Failed to create map with mp_create_map()."));
			delete [] map_pixel_d_array_8;
			return FALSE;
		}

		// Cleanup
		delete [] map_pixel_d_array_8;
		map_pixel_d_array_8 = 0;
	}
	// 16 bit
	else
	{
		if(!mp_create_map(map_id, width, height, origin, image_type, map_pixel_d_array_16))
		{	
			LOG_ERROR_MSG(map_id, _T("Failed to create map with mp_create_map()."));
			delete [] map_pixel_d_array_16;
			return FALSE;
		}

		// Cleanup
		delete [] map_pixel_d_array_16;
		map_pixel_d_array_16 = 0;
	}

	// Update map progress 100%
	mp_set_map_progress(map_id, 100);	

	// Success
	return TRUE;
}


The first part of the function uses API calls to get info about the input map and the property values, The next registers the tile type of the map. A pixel array is allocated based on 8 bit or 16 bit channels at the same size as the input map. The coordinate system is registered as the one the user has defined in the coordinate system property control. Depending on the image type the pixels (normals) are copied into the new pixel array and set to the new coordinate system.

At the end of the function the pixels are sent to ShaderMap using the mp_create_map() function. Which takes the map_id, size, and array of pixels in RGBA format.

To install this plugin, add the binary *.SMP file to the ShaderMap plugins directory: "SM2_DIRECTORY\plugins\(x86 or x64)\maps\"

and install the plugin thumbnail to the directory: "SM2_DIRECTORY\plugins\(x86 or x64)\maps\thumbs\"

Now the map will be available from the Advanced Map Setup page inside ShaderMap 2.


ShaderMap 2.0.5 Update

Posted by , in ShaderMap 10 July 2012 - - - - - - · 1,049 views

A new version of ShaderMap 2 is now available for download. This version brings bug fixes, new features, and options.
Some of the new features include:

  • Support for OBJ quads
  • Lockable and savable source maps
  • Optimized GPU usage
  • Option to override tile types for source maps
  • Option to set default geometry for projects
  • A V Brush vector reset button
  • Keyboard shortcuts
  • And last but not least, a built in support page

For a complete list of updates visit http://shadermap.com/forums/showthread.php?tid=35
To download the latest version visit: http://shadermap.com/downloads

Here is an image of the support page. With it you can get news and updates right in the app.

Posted Image

I'll be posting another SDK tutorial later this week. This time of Map Plugins


ShaderMap 2 SDK Tutorial - Creating Materials

Posted by , in Graphics, ShaderMap 25 June 2012 - - - - - - · 2,518 views
shadermap, materials, shaders and 3 more...
ShaderMap 2 allows users to create materials using the ShaderMap 2 SDK. A material can use any map in the ShaderMap project or load external image files such as cube maps. The material also provides a user interface wtih associated HLSL constants. To get started let's look at the basic structure of the ShaderMap 2 material file.

Each material file is an XML file. It is made of two parts: Setup and FX.

Material File Structure:
<?xml version="1.0" encoding="utf-8" ?>
<shadermap_material version="2.0">
   <setup name="Material Name" description="Material Description">
  
	 ... SETUP ELEMENTS HERE ...
  
   </setup>
  
   <fx vsm="2_0" psm="2_a">
  
   <![CDATA[
  
	 ... OPTIONAL EFFECT SCRIPT HERE ...
  
   ]]>
  
   </fx>
</shadermap_material>

The Setup Section

The first section of the XML is the SETUP section. Information in this section defines the maps and properties that the material will use.

The "setup" element requires 2 attributes: "name" and "description".

There are 4 types of elements that can be added to the Setup Section: lighting, world, input, and texture.


Lighting Element

The lighting element takes the form: <lighting is_active="0 | 1" />
If lighting is set to 1 then the following constants will be sent to the shader:

// Light data
int g_light_count;
float3 g_light_vector_array[4];
float3 g_light_color_array[4];
float g_light_specular_array[4];
float3 g_light_ambient_color;


World Element

<world type="matrix | vector | position" fx_name="name_of_fx_constant" />

The "world" element can be of type "matrix", "vector", or "position". This element tells ShaderMap to send world information about the object it is rendering.
  • Matrix types are sent to the fx_name as float4x4.
  • Vector types are sent to the fx_name as float3.
  • Position types are sent to the fx_name as float3.

1. The "matrix" type has the additional attribute "define" which defines the matrix to be sent to the fx_name constant. It can be any combination of the following characters:
  • 'w' - World matrix
  • 'v' - View matrix
  • 'p' - Projection matrix
  • 'r' - Rotation matrix
  • 'i' - Inverse of matrix
  • 't' - Transpose of matrix

Ex. <world type="matrix" define="wvp" fx_name="world_view_projection" />

Each matrix is multiplied by the next. The inverse and transpose are applied to whatever matrix has previously been created.

A string of "wit" sends the world_inverse_transpose matrix
A string of "wvp" sends the world_view_projection matrix
A string of "ri" sends the inversed rotation matrix

There is no scaling in ShaderMap or rather all matrices have a scale of 1.0.

2. The "vector" type has the additional attribute "define" which can be any one of the following values:
  • "view" - The view vector in world space

Ex. <world type="vector" define="view" fx_name="view_vector_ws" />

3. The "position" type has the additional attribute "define" which can be on of the following values:
  • "eye" - The eye position in world space
  • "target" - The eye target position in world space
  • "object" - The object position in world space

Ex. <world type="position" define="object" fx_name="object_position_ws" />


Input Element

<input type="list | slider | checkbox | color" fx_name="name_of_fx_constant" />

The "input" element defines a property control that will appear in the map properties section when that map is selected. This element can be a "list", "slider", "checkbox" or "color" control. Each type has additional attributes specific to the type.

Values of the current input are sent to the FX constant defined in "fx_name".

List types are sent to the fx_name as int
Slider types are sent to the fx_name as int
Checkbox types are sent to the fx_name as bool
Color types are sent to the fx_name as float3

1. The "list" type has the additional attributes: "prefix", "items", and "default".
  • "prefix" - A prefix to the list. A list of colors might use "color: "
  • "items" - A list of strings divided by the ; character. "A;B;C"
  • "default" - The default item in the list. A zero based index (integer).

Ex. <input type="list" prefix="Pre: " items="A;B;C" default="0" fx_name="my_list" />

2. The "slider" type has the additional attributes: "name", "min", "max", and "default".
  • "name" - The name shown next to the slider control
  • "min" - The minimum value of the slider (integer)
  • "max" - The maximum value of the slider (integer)
  • "default" - The default value of the slider (integer)
<input type="slider" name="Slide It" min="-300" max="300" default="50" fx_name="my_slider" />

3. The "checkbox" type has the additional attributes: "name" and "default"
  • "name" - The name shown next to the checkbox control
  • "default" - The default state 1 or 0.
Ex. <input type="checkbox" name="Check It" default="1" fx_name="my_checkbox" />

4. The "color" type has the additional attributes: "name" and "default"
  • "name" - The name shown next to the color control
  • "default" - The default color of the control in HEX format.

Ex. <input type="color" name="Color It" default="ffffff" fx_name="my_color" />


Texture Element

<texture type="map | image | cube" fx_name="name_of_fx_constant" />

The "texture" element tells ShaderMap to send a texture to ShaderMap. The texture can be from a Map or an image file. Two types of image files are allowed and they are standard images (jpeg, bmp, etc.) and cube maps (always dds).

If any texture is sent to the shader then the tile constant is sent as well. It is a float2 and is always named g_uv_tile. Multiply this by all texture coords to get proper tiling.

1. The "map" type texture sends a user defined map to the shader. It has the additional attributes: "name", "desc", "is_normal", and "is_checkbox".
  • "name" - The name of the map required by the shader.
  • "desc" - A description of the map required by the shader.
  • "is_normal" - Can be either 1 or 0. If set to 1 then the map sent should be a normal map. An additional constant is sent the the FX shader which contains the coordinate system of the normal map. It will take the form <fx_name>_coordsys. It is a float3 vector. It represents the coordinate system relative to the default tangent space used by ShaderMap. A vector of (1,1,1) means it is in X = +Right, Y = +Down, Z = +Near. A value of (1,1,-1) means that Y = +Up
  • "is_checkbox" - Can be 1 or 0. If 1 then a checkbox control will be added to the properties that allows the user to disable sendingthis texture.

Ex. <texture type="map" name="Normal Map" desc="Tangent space normal map is used for bump mapping." fx_name="g_normal_texture" is_normal="1" is_checkbox="1" />

2. The "image" type texture sends an image from file to the shader. It has the additional attributes: "name", "file", and "is_checkbox".
  • "name" - The name of the image shown only if is_checkbox is 1.
  • "file" - The filename of the image to load as a texture. It is relative to the location of the material file.
  • "is_checkbox" - Can be 1 or 0. If 1 then a checkbox control will be added to the properties that allows the user to disable sending this texture.

<texture type="image" file="res\cel\cel.png" name="Cel Texture" fx_name="g_cel_texture" is_checkbox="0" />

3. The "cube" type texture sends a DDS cube map from file to the shader. It has the additional attributes: "file" and "is_checkbox".
  • "name" - The name of the cube map shown only if is_checkbox is 1.
  • "file" - The filename of the cube map to load as a texture. It is relative to the location of the material file.
  • "is_checkbox" - Can be 1 or 0. If 1 then a checkbox control will be added to the properties that allows the user to disable sending this texture.

Ex. <texture type="cube" name="Reflection Map" file="env.dds" fx_name="g_cube_texture" is_checkbox="0" />


Ex. A Diffuse Lighting Material Setup:

	 <setup name="Diffuse Light" description="A diffuse lighting material. Uses a diffuse map.">  
  
		  <lighting is_active="1" />
	  
		  <world type="matrix" define="w" fx_name="g_world_matrix" />
		  <world type="matrix" define="wvp" fx_name="g_world_view_projection" />
		  <world type="matrix" define="wit" fx_name="g_world_inverse_transpose" />
	  
		  <input type="slider" name="Multiplier" min="0" max="500" default="100" fx_name="g_multiplier" />
					  
		  <texture type="map" name="Diffuse Map" desc="Diffuse texture defines base color of material." fx_name="g_diffuse_texture" is_normal="0" is_checkbox="1" />
				
	 </setup>


The FX Section

The second section of the XML is the FX section. This section can include an entire Direct3D effect script enclosed in the CDATA section or can just be a link to a file in the same directory as the XML.

Attributes for the "fx" element are "vsm", "psm", and "file". vsm is the maximum vertex shader model required by the material. psm is the maximum pixel shader model required. The file attribute is optional, if set the fx is loaded from an external file rather than from the CDATA section. Ex. file="external_shader.fx"

Because ShaderMap uses DirectX 9c the maximum shader model supported is SHADER MODEL 3.

To learn more about DirectX Effect files see the Direct3D9c documentation:

http://msdn.microsof...9(v=vs.85).aspx
http://msdn.microsof...8(v=vs.85).aspx

or just google it: http://www.google.co...rect3D9 Effects


Diffuse Lighting Material

Here is a complete material example. It serves as a good starting point for creating your own materials. It takes one map as diffuse and uses per-pixel n dot l lighting for each of the project directional lights.

<!--
===============================================================
SHADERMAP MAP MATERIAL FILE

Learn more at http://shadermap.com
===============================================================

-->
<?xml version="1.0" encoding="utf-8" ?>
<shadermap_material version="2.0">
	 <setup name="Diffuse Light" description="A diffuse lighting material. Uses a diffuse map.">   
   
		  <lighting is_active="1" />
	   
		  <world type="matrix" define="w" fx_name="g_world_matrix" />
		  <world type="matrix" define="wvp" fx_name="g_world_view_projection" />
		  <world type="matrix" define="wit" fx_name="g_world_inverse_transpose" />
	   
		  <input type="slider" name="Multiplier" min="0" max="500" default="100" fx_name="g_multiplier" />
					   
		  <texture type="map" name="Diffuse Map" desc="Diffuse texture defines base color of material." fx_name="g_diffuse_texture" is_normal="0" is_checkbox="1" />
				
	 </setup>
   
	 <fx vsm="2_0" psm="2_a">
	 <![CDATA[   
   
	 // ==============================================================
		
	 // Light data
	 int g_light_count;
	 float3 g_light_vector_array[4];
	 float3 g_light_color_array[4];
	 float g_light_specular_array[4];
	 float3 g_light_ambient_color;

	 // World data   
	 float4x4 g_world_matrix;
	 float4x4 g_world_view_projection;
	 float4x4 g_world_inverse_transpose;
   
	 // Input data
	 int g_multiplier;

	 // Map data
	 float2 g_uv_tile;
	 texture g_diffuse_texture;	
	
	 // Samplers
	 sampler g_diffuse_sampler =
	 sampler_state
	 {
		  Texture = <g_diffuse_texture>;
	 };
	
   
	 // I/O structs
	 struct VS_INPUT
	 {
		  float3 position : POSITION;
		  float3 normal : NORMAL;
		  float2 uv : TEXCOORD0;
		  float4 tangent : TANGENT;
	 };
   
	 struct VS_OUTPUT
	 {
		  float4 position : POSITION;
		  float2 uv : TEXCOORD0;
		  float3 normal : TEXCOORD1;
	 };  
   
	 // ==============================================================
  
	
	 // Vertex shader
	 VS_OUTPUT vs_main(VS_INPUT IN)
	 {
		  // Local data		 
		  VS_OUTPUT OUT;
		   
		 
		  // Store output position, UV, and normal
		  OUT.position = mul(float4(IN.position, 1.0f), g_world_view_projection);
		  OUT.uv = IN.uv * g_uv_tile;  
		  OUT.normal = mul(IN.normal, (float3x3)g_world_inverse_transpose);
	   
		  return OUT;
	 }
   
	 // Pixel (fragment) shader
	 float4 ps_main(VS_OUTPUT IN) : COLOR
	 {
		  // Local data
		  int i;
		  float n_dot_l;
		  float3 n, d, l;
		  float4 c;
		 
		 
		  // Get texture color
		  c = tex2D(g_diffuse_sampler, IN.uv);
		 
		  // Get normal
		  n = normalize(IN.normal);
			  
		  // Base light color
		  d = float3(0.0f, 0.0f, 0.0f);
		 
		  // Calculate diffuse light color		 
		  for(i=0; i<g_light_count; i++)
		  {
			   // Light vector
			   l = normalize(-g_light_vector_array[i]);
			  
			   // N dot L
			   n_dot_l = saturate(dot(n, l));
			  
			   // Add in light
			   d += n_dot_l * g_light_color_array[i];			  
		  }
				  
		  // Calculate final color and return;
		  c.rgb = saturate(saturate(c.rgb * (g_multiplier / 100.0f)) * d);
		 
		  return c;
	 }	
	
	 // ==============================================================
   
	 // ShaderMap Technique
	 technique shadermap_material
	 {
		  pass
		  {
			   VertexShader = compile vs_2_0 vs_main();
			   PixelShader = compile ps_2_a ps_main();
		  }
	 }
	
	 // ==============================================================
	 ]]>
	 </fx>
   
</shadermap_material>

And here is it running in ShaderMap 2:

Posted Image


You can download the full material file here: Diffuse Lighting Material

To install the XML material file - place it in the following directory: C:\Program Files\ShaderMap 2\plugins\materials\

For more information and examples download the free ShaderMap SDK: http://shadermap.com/downloads


ShaderMap 2 Now Available

Posted by , in ShaderMap 19 June 2012 - - - - - - · 1,252 views
normal map, normal generation and 3 more...
Hi everyone, it's been a while since I last published anything. That's because I've been working my heart out for a full year on ShaderMap 2. I am really proud of what I've been able to accomplish on this project.

Here's a rundown of the new features available and if you want to learn more just follow the links at the bottom. I made some videos of it in action if you want to see it in action. I'll be posting weekly entries on using the new ShaderMap SDK to build materials and plugins for ShaderMap.

- Redesigned User Interface
- Normal Map Painting
- Internal / External visualizer window
- 32 / 64 bit binaries
- Muli-core support
- Added more image formats including PSD and DDS.
- External editor integration
- ShaderMap material editor
- Advanced maps configuration
- Expandable using map plugins
- Expandable using HLSL shaders for materials
- Free ShaderMap SDK for developers

To dowload the demo, visit http://shadermap.com/

You can watch video of ShaderMap here http://shadermap.com/video/


Posted Image


Woody3D.pause() ShaderMap2.play()

Posted by , in ShaderMap, Woody3D 17 June 2011 - - - - - - · 667 views

woody3d.pause()

As it stands Woody still requires a couple more months of development to be ready for the next release. I'm really excited about all of the new features in the upcoming release but I've been developing Woody3D for about 3 years. That's a long time for a single developer to work on a project with no end in sight and little reward... I need a break.

Or rather...

I need a finite project to work on.

shadermap2.play()

Earlier this week, I began implementing the interface I'd previously drawn in PhotoShop.

Posted Image

It's built using C++and Direct3D 9 in a Win32 framework. All controls are derived from a ui_base class which maintains a list of children controls and provides an interface for event callbacks, updates, and drawing.

Here's what I've done on the interface so far:
  • Tool tip support
  • Drag and drop support
  • UI framework
  • Button control
  • Checkbox control
  • ShaderMap 2 icon artwork
  • Menu interface
  • Start page

I'll continue developing the UI then do an open test here and on the ShaderMap forums to get all the bugs worked out. Then I'll get to work on the plugin system.

Woody fans have no fear, development will .play() soon after ShaderMap2 is released. Switching projects has already brought my energy levels back near immortal levels.



Roots and "Tree" Hierarchy Control

Posted by , in MFC, Woody3D 03 June 2011 - - - - - - · 941 views

Posted Image

Woody3D can create tree roots as shown above. There is a problem however, as it currently uses a very simple hierarchy for branch levels. It does not allow for more than one child per branch. This means you can add roots but not branches. That's a pretty boring tree.

Next version will support a more flexible hierarchy. To manage the various parts of the tree, I'll be using a CtreeCtrl in the Tree Forge. Below is a colored
CtreeCtrl (with fancy gradient selection bar).

Posted Image

And here is the source for the control if you're interested in how it works. Feel free to modify it and use it in your own MFC projects.

Color_Tree.h
#ifndef ___COLOR_TREE_CONTROL_H___
#define ___COLOR_TREE_CONTROL_H___


class Color_Tree : public CTreeCtrl
{
private:
	
	COLORREF							___select_background_color;
	COLORREF							___select_font_color;
	COLORREF							___lost_focus_select_background_color;
	COLORREF							___lost_focus_select_font_color;

	BOOL								___is_select_full_row;
	BOOL								___is_select_full_row_gradient;

protected:

	DECLARE_MESSAGE_MAP()
	
	afx_msg	void						OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
	
public:

	// Constructor / Destructor
	Color_Tree(void);
	~Color_Tree(void);

	void								enable_select_full_row(BOOL enable, BOOL is_gradient);
	void								set_select_color(COLORREF select_background_color, COLORREF select_font_color, 
													     COLORREF lost_focus_select_background_color, COLORREF lost_focus_select_font_color);
};


#endif

Color_Tree.cpp
#include "stdafx.h"
#include "Color_Tree.h"
 


// Local Gradient rectangle function
BOOL draw_gradient_rect(CDC *pDC,
              	const CRect &draw_rect,
              	const COLORREF start_color,
              	const COLORREF end_color,
              	const bool is_horizontal)
{
	// Local data
	BYTE				red_start, green_start, blue_start, 
						red_end, green_end, blue_end; 
	TRIVERTEX			vertex_array[2] = { 0 };
	GRADIENT_RECT		gradient_rect[1] = { 0 };


	// Validate DC
	if(!pDC || !pDC->GetSafeHdc())
	{	return FALSE;
	}

	// Get RGB bytes from start color
	red_start				= GetRValue(start_color);
	green_start				= GetGValue(start_color);
	blue_start				= GetBValue(start_color);

	// Set first vertex
	vertex_array[0].x		= draw_rect.left;
	vertex_array[0].y		= draw_rect.top;
	vertex_array[0].Red		= (static_cast<USHORT>(red_start)   << 8);
	vertex_array[0].Green	= (static_cast<USHORT>(green_start) << 8);
	vertex_array[0].Blue	= (static_cast<USHORT>(blue_start)  << 8);
	vertex_array[0].Alpha	= 0x0000;

	// Get RGB bytes from end color
	red_end					= GetRValue(end_color);
	green_end				= GetGValue(end_color);
	blue_end				= GetBValue(end_color);

	// Set second vertex
	vertex_array[1].x		= draw_rect.right;
	vertex_array[1].y		= draw_rect.bottom;
	vertex_array[1].Red		= (static_cast<USHORT>(red_end) 	<< 8 );
	vertex_array[1].Green	= (static_cast<USHORT>(green_end)   << 8 );
	vertex_array[1].Blue	= (static_cast<USHORT>(blue_end)	<< 8 );
	vertex_array[1].Alpha	= 0x0000;

	// Gradient vertex index	
	gradient_rect[0].UpperLeft  = 0;
	gradient_rect[0].LowerRight = 1;

	// Draw gradient rect
	return GradientFill( pDC->GetSafeHdc(),
					     vertex_array, 
					     2,
					     &gradient_rect, 
					     1,
					     is_horizontal ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V ) == TRUE;
}

// c()
Color_Tree::Color_Tree(void)
{	
	___is_select_full_row			= FALSE;
	___is_select_full_row_gradient	= FALSE;
}
// d()
Color_Tree::~Color_Tree(void)
{
}

// Message map
BEGIN_MESSAGE_MAP(Color_Tree, CTreeCtrl)	
	ON_NOTIFY_REFLECT( NM_CUSTOMDRAW, OnCustomDraw)
END_MESSAGE_MAP()


// Handle color of select
void Color_Tree::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{	
	// Local data
	NMTVCUSTOMDRAW*		pcd;
	RECT				rect;
	CDC*				pDC;
	CBrush				brush;


	// Get custom draw struct
	pcd = (NMTVCUSTOMDRAW*)pNMHDR;

	// Handle by draw stage
	switch(pcd->nmcd.dwDrawStage)
	{
	case CDDS_PREPAINT: 

    	*pResult = CDRF_NOTIFYITEMDRAW;

    	break;
		// Pre paint of tree item
	case CDDS_ITEMPREPAINT: 
   	
		// To Get item
    	HTREEITEM hItem = (HTREEITEM)pcd->nmcd.dwItemSpec;
		
		// Handle control has focus
		if(this->GetFocus() == this)
		{	
			// If item is selected
			if(pcd->nmcd.uItemState & CDIS_SELECTED)
			{
				pcd->clrText	= ___select_font_color;	
				pcd->clrTextBk	= ___select_background_color;

				// Determine if item is in view
				// Get text rect
				if(___is_select_full_row && this->GetItemRect(hItem, &rect, TRUE))
				{
					// Adjust rect
					pcd->nmcd.rc.left = rect.right;

					// Gradient fill
					if(___is_select_full_row_gradient)
					{
						// Get DC and fill
						pDC = this->GetDC();
						draw_gradient_rect(pDC, pcd->nmcd.rc, ___select_background_color, this->GetBkColor(), true);

						// Cleanup
						this->ReleaseDC(pDC);
					}
					// Solid fill
					else
					{
						// Get DC and Create brush
						pDC = this->GetDC();				
						brush.CreateSolidBrush(___select_background_color);					
						
						// Solid fill
						pDC->FillRect(&pcd->nmcd.rc, &brush);
					
						// Cleanup
						brush.DeleteObject();
						this->ReleaseDC(pDC);
					}
				}
			}
			// If item is hot (mouse over)
			else if(pcd->nmcd.uItemState & CDIS_HOT)
			{
			     pcd->clrText	= this->GetTextColor();
			}			
		}
		else
		{
			// If item is selected
			if(pcd->nmcd.uItemState & CDIS_SELECTED)
			{
				pcd->clrText	= ___lost_focus_select_font_color;	
				pcd->clrTextBk	= ___lost_focus_select_background_color;

				// Determine if item is in view
				// Get text rect
				if(___is_select_full_row && this->GetItemRect(hItem, &rect, TRUE))
				{
					// Adjust rect
					pcd->nmcd.rc.left = rect.right;

					// Gradient fill
					if(___is_select_full_row_gradient)
					{
						// Get DC and fill
						pDC = this->GetDC();
						draw_gradient_rect(pDC, pcd->nmcd.rc, ___lost_focus_select_background_color, this->GetBkColor(), true);

						// Cleanup
						this->ReleaseDC(pDC);
					}
					// Solid fill
					else
					{
						// Get DC and Create brush
						pDC = this->GetDC();					
						brush.CreateSolidBrush(___lost_focus_select_background_color);

						// Solid fill
						pDC->FillRect(&pcd->nmcd.rc, &brush);

						// Cleanup
						brush.DeleteObject();
						this->ReleaseDC(pDC);
					}
				}
			}
			// If item is hot (mouse over)
			else if(pcd->nmcd.uItemState & CDIS_HOT)
			{
			     pcd->clrText	= this->GetTextColor();
			}
		}

    	*pResult = CDRF_DODEFAULT;

    	break;
	}
}

// Enable select full row
void Color_Tree::enable_select_full_row(BOOL enable, BOOL is_gradient)
{	___is_select_full_row = enable;
	___is_select_full_row_gradient = is_gradient;
}

// Set the colors for selecting items
void Color_Tree::set_select_color(COLORREF select_background_color, COLORREF select_font_color, 
							  	COLORREF lost_focus_select_background_color, COLORREF lost_focus_select_font_color)
{
	___select_background_color				= select_background_color;
	___select_font_color					= select_font_color;
	___lost_focus_select_background_color	= lost_focus_select_background_color;
	___lost_focus_select_font_color			= lost_focus_select_font_color;
}

Example

	CImageList	___tree_image_list;
	Color_Tree	___tree_control;


	// Local data
	CBitmap		bitmap;
	HTREEITEM	o_1, o_2, c_1, c_2;


	// Setup tree colors
	___tree_control.SetBkColor(RGB(116, 127, 138));
	___tree_control.SetTextColor(RGB(255, 255, 255));
	___tree_control.SetLineColor(RGB(255, 255, 255));
	___tree_control.set_select_color(RGB(196, 210, 224), RGB(0, 0, 0), RGB(102, 114, 124), RGB(255, 255, 255));
		
	// Setup tree images
	___tree_image_list.Create(16, 16, ILC_COLOR32, 1, 4);	
	// Bitmap 1
	bitmap.LoadBitmap(IDB_BITMAP1);
	___tree_image_list.Add(&bitmap, RGB(0, 0, 0));
	bitmap.DeleteObject();
	// Bitmap 2
	bitmap.LoadBitmap(IDB_BITMAP2);
	___tree_image_list.Add(&bitmap, RGB(0, 0, 0));
	bitmap.DeleteObject();
	// Set image list
	___tree_control.SetImageList(&___tree_image_list, TVSIL_NORMAL);

	// Set item height
	___tree_control.SetItemHeight(20);

	// Custom enable select of whole row - do not use 'Full Row Select' property for Control - it disables lines
	// Allows for horizontal gradient too.
	___tree_control.enable_select_full_row(TRUE, TRUE);

	// Add items
	o_1 = ___tree_control.InsertItem(_T("Trunk"), 0, 0);
	c_1 = ___tree_control.InsertItem(_T("Standard Branch 0"), 1, 1, o_1);
	c_2 = ___tree_control.InsertItem(_T("Standard Branch 1"), 1, 1, o_1);
	___tree_control.InsertItem(_T("Imposter Branch 0"), 1, 1, c_2);
	o_2 = ___tree_control.InsertItem(_T("Leaf Types"), 0, 0);
	___tree_control.InsertItem(_T("Mesh Leaf 0"), 1, 1, o_2);
	___tree_control.InsertItem(_T("Billboard Leaf 0"), 1, 1, o_2);



Leaf Meshes vs. Leaf Billboards

Posted by , in Woody3D 01 June 2011 - - - - - - · 1,228 views

Posted Image

Above is a tree which uses spoke meshes for leaves (used imposter branches for leaves [see wire-frame render in comments]). Below is a tree which uses billboarded quads for leaves.

Posted Image

I'm thinking that mesh type leaves are the way forward. I'll keep support for billboards, they could be very useful for vines, but the next version will not rely on them exclusively. With mesh type leaves the user can choose from a palette of leaf mesh types. Also export to static formats would be possible.


What do you think?







Twitter

Posted Image

Google GameDev.Net Search Bar

Posted Image

Recent Comments



PARTNERS