Archive for the ‘progress’ tag

Material System

without comments

Work continues on the LxEngine material system…

The above is a simple “toon” shader on the Suzanne model. The shader code is based on the simple example provided at LightHouse3d, but bases the color on a 1d texture look-up on a slightly blurred color texture rather discrete if-else statements.

The Video

Here’s a quick video of some of the material effects:

The Code

At the highest-level, the implementation of the new shader is very simple. The new shader is defined by creating a new directory “ToonSimple” in the materials sub-directory of the media directory. This directory contains a vertex shader, a fragment shader, and JSON parameters description.

The material is then loaded in the C++ code via a call to

pRasterizer->acquireMaterial("ToonSimple")

and attached to the Instance‘s spMaterial member. LxEngine handles all the shader loading and parameter activation.

On to the details…

 

Vertex Shader

The vertex shader code is quite simple and uses a fixed light direction:

uniform mat4    unifProjMatrix;
uniform mat4    unifViewMatrix;
uniform mat3    unifNormalMatrix;
 
in      vec3    vertNormal;
 
varying out float fragIntensity;
 
void main()
{
    // Keep it simple and use a fixed light direction
    vec3 lightDir = vec3(.5,-.5, 1.0);
 
    // The fragIntensity is effectively just the intensity of the diffuse 
    // value from the Phong reflection model.
    //
    fragIntensity = dot(normalize(lightDir), unifNormalMatrix * vertNormal);
 
    gl_Position = unifProjMatrix * unifViewMatrix * gl_Vertex;
}

The uniforms – unifProjMatrix, unifViewMatrix, unifNormalMatrix – are all “standard” LxEngine names, therefore it will automatically set the correct matrix values when activating the shader. Likewise with the attribute vertNormal; it too will be set automatically by the existing engine code. (This will be explained momentarily.)

Fragment Shader

The fragment shader is quite simple:

#version 150
#extension GL_ARB_explicit_attrib_location : enable
 
uniform sampler1D unifTexture0;
 
in      float fragIntensity;
 
layout(location = 0) out vec4 outColor;
 
void main()
{
    outColor = texture(unifTexture0, fragIntensity);  
}

Now the fragment shader does have an interesting detail: the uniform unifTexture0 is not a “standard” LxEngine uniform. (How could it be? The transformation matrices are common to many shaders, as are properties like the geometry’s normals, but is a texture map ever going to be “standard” enough that the engine would know what to set?)

This is a custom uniform, but it still does not require any C++ code for the engine to set it’s value properly. We’ll get to that momentarily.

Automatically setting the shader variables

The automatic setting of uniforms and attributes is done via calls to getActiveUniform and getActiveAttrib after the GLSL program is compiled. The MaterialClass class wraps the GLSL program and provides iteration functions that exemplify the use of these OpenGL calls:

void 
MaterialClass::iterateUniforms (std::function<void(const Uniform& uniform)> f)
{
    int uniformCount;
    gl->getProgramiv(mProgram, GL_ACTIVE_UNIFORMS, &uniformCount); 
    for (int i = 0; i < uniformCount; ++i)  
    {
        Uniform uniform;
        char    uniformName[128];
        GLsizei uniformNameLength;
 
        gl->getActiveUniform(mProgram, GLuint(i), sizeof(uniformName), &uniformNameLength, &uniform.size, &uniform.type, uniformName);
 
        if (uniformNameLength >= sizeof(uniformName))
        {
            throw lx_error_exception("GLSL program contains a uniform with too long a name size!");
        }
        else
        {
            uniform.name = uniformName;
            uniform.location = gl->getUniformLocation(mProgram, uniformName);
            f(uniform);
        }
    }
}

The LxEngine internal rasterizer code, after compiling a GLSL shader for the first time, will iterate over the uniforms and attributes to generate a set of values that need to be set whenever that material is made active. The set of “instructions” necessary to set those values is encapsulated in a std::vector<std::function<void()>> – which, in effect, allows a sort of dynamic code generation at the expense of a bit of overhead to the std::function calls. The flexibility and simplicity definitely win out over the efficiency loss for the purposes of LxEngine.

For example, below is a code snippet from the shader attribute instruction generation function (or see the latest version of the material source code for more details):

std::function<void()>   
Material::_generateInstruction(RasterizerGL* pRasterizer, const Attribute& attribute, lx0::lxvar& value)
{
    ...
 
    if (attribute.name == "vertNormal")
    {
        return [=]() {
            auto& vboNormals = pRasterizer->mContext.spGeometry->mVboNormal;
            if (vboNormals)
            {
                gl->bindBuffer(GL_ARRAY_BUFFER, vboNormals);
                gl->vertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, 0, 0);
                gl->enableVertexAttribArray(location);
            }
            else
                gl->disableVertexAttribArray(location);
 
            check_glerror();
        };
    }

Setting a custom uniform

The non-standard unifTexture0 uniform is set somewhat differently. The material definition – in addition to the vertex and fragment shaders – also includes a simple JSON parameter description file. In this case, it contains only one parameter:

{
    parameters: {
        unifTexture0 : "media2/textures/gradients/1d/suncopper_1-00.png"
    }
}

In this case, the _generateInstruction() method loops over all unrecognized uniform names and searches for a user-specified parameter value for that uniform. In this case, it finds “unifTexture0″ as both an unrecognized uniform and a value in the parameter mapping.

Since the information about the uniform also includes the data type (GL_SAMPLER_1D), LxEngine can figure out to interpret that string value as an image filename, can load that file and store it in the texture cache, and generate an instruction to set that texture when activating the material:

else if (uniform.type == GL_SAMPLER_1D)
{
    auto filename = value.as<std::string>();
 
    TexturePtr spTexture = pRasterizer->mTextureCache.findOrCreate(filename );
    GLuint textureId = spTexture->mId;
 
    // Activate the corresponding texture unit and set *that* to the GL id
    return [=]() {
        const auto unit = pRasterizer->mContext.textureUnit++;
 
        // Set the shader uniform to the *texture unit* containing the texture (NOT
        // the GL id of the texture)
        gl->uniform1i(loc, unit);
 
        gl->activeTexture(GL_TEXTURE0 + unit);
        gl->bindTexture(GL_TEXTURE_1D, textureId);
 
        // Set the parameters on the texture unit
        gl->texParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, mFilter);
        gl->texParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, mFilter);
        gl->enable(GL_TEXTURE_1D);
        check_glerror();
    };
}

Adding simple shaders should be simple

The point really is that adding a simple shader, like this toon shader, is simple to do. The new material system in LxEngine makes it trivial as common uniforms and attributes are automatically set up and the mechanism for specifying custom uniforms is quite easy.

The objective is an engine designed to make experimentation and research simple.

The toon shader run with an alternate texture (i.e. same material “class” / shader program, different material “instance” / parameterization) displayed with a 2-pass, 9×9 Gaussian fullscreen blur active.

What’s Next? LxEngine Tutorial 4

I’m currently working on cleaning up and writing up a good description of “Tutorial 4″ of LxEngine. I want to add a couple more effects to make the tutorial feel a bit more substantial first (perhaps add shadow mapping?), but would also like to get a finished tutorial out the door. As a preview, the fourth tutorial will include at least the following: writing an application via Javascript, geometry generated from scripts, multipass rendering, multithreading, time-lapse events, and…well, probably more if I don’t hurry up and finish this off!

A Complete Game

without comments

Progress update…

A Complete Game

Over the last several months, I’ve been working primarily with web-related technologies (basic HTML, CSS, PHP, some CMS customization, etc.). In my spare time, I’ve been playing around with the more graphical / game-aspects HTML5. I’ve written a couple “draft” quality JQuery plug-ins: one for basic image effects (saturation effects, etc.), a seamless image tiler / previewer, a seamless image generator, a fire effect, and one more thing: a complete game.

I’m interested in graphics, engine architecture, and games, but often find myself exploring a specific technology rather than trying to create something “complete.” In other words, I tend to take a deep and narrow approach to coding rather than a broad, shallow approach.

My goal this time is to produce a small, maybe-not-that-impressive, but complete game. I realize I’ve never really done this before…

Gravity Tide

I’ve decided to code name it Gravity Tide. So far:

  • 2D Graphics via an HTML Canvas element
  • Music via the HTML5 Audio element (and via opengameart.org since I’m not a musician!)
  • A main menu and credits screen
  • 1 Level currently…

Once I add a splashscreen, load/save functionality, a couple more levels, a few power-ups, a few new enemies, end-of-level “bosses”, and a generic minimal game story, I think it – again, may not be epic quality – but it will be a complete game.

Written by arthur

December 16th, 2011 at 10:43 am

Procedural Patterns

without comments

What I’ve been working on…

…patterns (and the unit tests that test them).  The above is image snapshot of some of the unit test image results of several procedurally generated patterns.

Written by arthur

July 7th, 2011 at 1:38 pm

Posted in lxengine

Tagged with , , , ,

Shader Builder Progress

without comments

Significant progress in the LxEngine ShaderBuilder.  The builder now supports Phong shading and procedural patterns such as tile, spot, diamond, and wave.

Below is a quick, low-quality demo video of the work-in-progress LxEngine Tutorial 3, which loads of a Blender model and allows the user to cycle through a set of shaders to apply (each material defined via a concise JSON description in the XML file):

Video

 

 

Note how the specular highlights on the different, individual tiles of the checker patterns are not the same for the red checker materials. This really is a nested procedural! Each tile in the checker not only gets a color, but has its own Phong specification. Also check out the bright highlights on the last Phong checker: that’s actually another level of nesting where a border pattern adds much brighter specularity to the edges of the tile.

Stills

Here is the Stanford bunny shaded with a checker pattern with a nested wave pattern:

Stanford Bunny

Here’s the Suzanne model from Blender, shaded with the normal-based shader:

Blender's Suzanne

Finally, here’s the classic Utah Teapot with a spot pattern:

Utah Teapot

What’s Next?

I have a host of todo’s lined up, but…any reader suggestions on what next to add to LxEngine? I’m looking for something that – while still somewhat feasible for a single person to implement – would help the engine stand out as having potential to be a top-of-the-line engine someday.

  • Continue the shader work and add a Tutorial 4 with even more advanced multi-pass, multi-layer rendering and animation?
  • Further Bullet Physics integration to demo how that library can easily and effectively be used within LxEngine?
  • A miniature MineCraft procedural world sample with an infinite world with a sky, rain, and snow since MineCraft is all the rage?
  • A simple FPS to demo a complete game with LxEngine?
  • Something completely different?

Written by arthur

July 1st, 2011 at 1:26 pm

LxEngine Tutorial 2

without comments

With version 0.0.1 of LxEngine only recently released, the engine is obviously still in early development; however, I’ve gone ahead and posted  a second tutorial on using LxEngine.  This is part of an effort to accelerate development and produce a high-quality SDK by documenting from the start.

Tutorial 2 builds upon the first but now uses the LxEngine Rasterizer subsystem to do the rendering.  With a couple dozen lines of code, a simple spinning cube is set up.  The next tutorials will then build upon this to add lighting, material, and procedural effects.

 

The tutorial itself likely won’t win any awards for outstanding visuals as it’s supposed to be demonstrating the Rasterizer architecture.  Hopefully the next tutorial will be able to work in some effects!

(And yes, the window title in the video does incorrectly say, “Tutorial 01″. Oops. Seems criminal to reupload a mere spinning cube video to correct just that, though.)

Written by arthur

June 28th, 2011 at 7:21 pm

Terrain Rendering Update

without comments

Another update.  Nothing groundbreaking, but some solid progress:

  • Automatically generated “infinite” terrain using multiple frequency Perlin noise
  • A checker map with Perlin noise on one tile, alpha blended texture on the other

Update

Added trivial texture mapping and splatting:

Terrain with grass and direct texture splatting

Unfortunately, without mipmapping support the textures do not look very good at a distance.  Adding texture LOD support to the GLSL shader would be a good next step.

The textures used are from OpenGameArt.org:

Written by arthur

December 27th, 2010 at 6:41 pm

Progress Update

without comments

Nothing technically astounding to report: only some regular progress.

I’ve been moving away from OGRE and towards coding my own OpenGL-based renderer. Why? Because I realized that, as much as I want LxEngine to utilize the work of others and avoid reinventing the wheel, this is also currently a hobby project and, bottom-line, I enjoy writing custom graphics code.

That out of the way, I’ve been very interested in terrain lately. Between the Lithosphere demo (see earlier blog entry) and unfortunately downloading and instantly getting a minor addiction to Minecraft, I’m fascinated by what a procedural terrain engine theoretically could do.

Step 1: Height maps. These seem to have a nice balance between simplicity (e.g. path-finding and collision detection) and capacity to display something interesting. Here’s a heightmap generated from a sin + cos wave with a checker pattern and fake diffuse lighting:

Video was probably overkill for such a simple example, but I thought I’d use this as an excuse to try out CamStudio (a free, open source screen recording app).  Pretty simple to use.  I recommend it.

Update

A bit more work and some head-scratching to really understand Perlin noise, and the result is this heightmap:

Terrain generated from a Perlin Noise function

Thanks to these pages for the information on Perlin noise:

Update 2

Added automatic generation of additional tiles and a cheap GLSL fog effect:

Perlin Noise-based Terrain with Fog

Written by arthur

December 22nd, 2010 at 1:17 pm