RSI

Members
  • Content count

    45
  • Joined

  • Last visited

  1. Hi everyone! Just wanted to let everyone know that ShaderMap 4 (SM4) has been released and is now free for non commercial use. You can learn more at the new website https://shadermap.com Thanks for checking it out! Neil
  2. I've written a tutorial on how to take photographs of a static object and convert them to normal maps and albedo/diffuse maps with ShaderMap 3. The basics of the tutorial are: Setup your camera to take static photos of the object. Photograph the object four times each lighted from a different direction. Bring the photos into ShaderMap 3 using the Normal from Photos template. View the results in real-time and make changes to intensity. Read the entire tutorial here: Normal Map Photography | ShaderMap Tutorials       Learn more about ShaderMap at: http://shadermap.com  
  3. Tutorial demonstrating how to draw a tangent space normal map for an existing texture map.   http://shadermaptutorials.com/tutorial/drawing-a-normal-map-for-a-texture/     Here are some images from the tutrorial:         View additional ShaderMap Tutorials at the home page: http://shadermaptutorials.com/   Thanks for looking
  4. Developing ShaderMap 3 at the Moment
  5. ShaderMap 3 has been released with a lot of new features.   Major features include: Baking Maps from 3D models, a Map Filter System, a vastly improved Project Grid, real displacement preview in the Material Visualizer, Floating Point image generation, and a bunch of new maps. For a complete list of each new feature and bug fixes please visit the ShaderMap What's New page.   Normal Map generated from a 3D Buddha relief model:     Real Displacement Visualization:     You can watch videos of ShaderMap 3, and download a demo version at the ShaderMap Website.   Thanks for taking the time to check it out. I worked really hard on this update and hope it is useful to the game development and computer graphics communities.   Cheers, Neil
  6. ShaderMap 2.0.7 Update

    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. 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
  7. Blending Normal Maps

    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/ In other news, I'm on Google+ here: Neil Kemp and I've started a G+ page for ShaderMap as well: ShaderMap+
  8. Still alive

    I care. Please stay alive. Unless you transfer into the singularity then you know.. it's cool. How much for beach front on the oblivion lake? I'm buying early in hopes it cools to a useful resource.
  9. Woody3D Discontinued

    Wow, you guys really like the name Woody3D. I don't... I was never happy using a phallic (almost comical) name for the tree lib. Not sure why I settled on it other than it seemed easy to remember and usually made people smile. I'm wondering if you ever used Woody3D in a project or if you know anyone that did? My numbers suggest that it was never very popular.
  10. Woody3D Discontinued

    [quote name='Servant of the Lord' timestamp='1342639344'] What are you going to do with Woody3D in it's current state? Open source it? [/quote] I'm going to use Woody's math library, geometry classes, and animation systems, to build a new tool for creating trees and plants. Open sourcing it is not something I want to do at the moment.
  11. Working on SM2 full force at the moment.
  12. Woody3D Discontinued

    Thanks for your comments. If you create a tool that is useful and easy to use it will be popular no matter what it is named. And hey! It's not like I'm tossing out the knowledge and algorithms.
  13. I just killed Woody3D. Think I need a drink.
  14. Woody3D Discontinued

    I'll just post what I wrote on the woody3d.com website, then I'll explain... [color=#0066cc]"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. [/color] [color=#0066CC]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."[/color] 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:
  15. 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: [source] // 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);[/source] Here is the on_initialize function: [source]// 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; }[/source] 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: [source]// 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