Ok here is the source with the ability to reduce grass accuracy in exchange for speed.
Fur objects work too.
DONT USE MY DLL, its a custom one and will not work with any irrlicht release headers.
http://rs69.rapidshare.com/files/179071 ... alcode.zip
IRRAGEN-Shader Based Procedural Terrain System
Interesting. I'll take a look at this.
I'm curious: why a custom dll?
I'm curious: why a custom dll?
Irrlicht Demos: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=6&t=45781
I am too lazy to keep adding my own dll code to new irrlicht releases, that dll has custom fast softshadow code (its not used in the demo,but it has fbo's; not sure if irr has them yet).
"Irrlicht is obese"
If you want modern rendering techniques learn how to make them or go to the engine next door =p
If you want modern rendering techniques learn how to make them or go to the engine next door =p
holy freaking crap i hate rapidshare....i cant read the damn acces code crap. PLEASE post it someplace else!!!!
My irrlicht-based projects have gone underground for now, but if you want, check out my webcomic instead! http://brokenboomerang.net
I found this old shadser i made while backing up stuff before a format. It does parallax mapping on lightmapped levels, with no need for the actual normal/heightmaps.
just a lightmapped level with diffuse textures works fine. However it doesnt work with oct tree nodes, only animated mesh nodes.
just paste this code in COpenGLParallaxMapRenderer.cpp
and compile
In your project create an animated mesh with tangents (see the perpixel tutorial) but dont generate normals or apply any textures.
Im now working on volumeteric lighting using the same technology i made behind the grass. It should give us an infite number of volumeteric lights, the screen resolution is the only limit.
The blender conversion was partly sucessfull, each blur stage looks fine,but seems blender sees the grass as aliasing and heavily does anti aliasing on it which blurs the grass to the degree it looks like the original texture in the final output
just a lightmapped level with diffuse textures works fine. However it doesnt work with oct tree nodes, only animated mesh nodes.
just paste this code in COpenGLParallaxMapRenderer.cpp
Code: Select all
// Copyright (C) 2002-2006 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "COpenGLParallaxMapRenderer.h"
#include "IGPUProgrammingServices.h"
#include "IShaderConstantSetCallBack.h"
#include "IVideoDriver.h"
#include "os.h"
#define GL_GLEXT_LEGACY 1
#include "glext.h"
#include "COpenGLDriver.h"
#include <stdio.h>
#include <string.h>
namespace irr
{
namespace video
{
// Irrlicht Engine OpenGL render path parallax map vertex shader
// I guess it could be optimized a lot, because I wrote it in D3D ASM and
// transfered it 1:1 to OpenGL
const char OPENGL_PARALLAX_MAP_VSH[] =
"!!ARBvp1.0\n"\
"#input\n"\
"# 0-3: transposed world matrix;\n"\
"#;12: Light01 position \n"\
"#;13: x,y,z: Light01 color; .w: 1/LightRadius² \n"\
"#;14: Light02 position \n"\
"#;15: x,y,z: Light02 color; .w: 1/LightRadius² \n"\
"#;16: Eye position \n"\
"\n"\
"ATTRIB InPos = vertex.position;\n"\
"ATTRIB InColor = vertex.color;\n"\
"ATTRIB InNormal = vertex.normal;\n"\
"ATTRIB InTexCoord = vertex.texcoord[0];\n"\
"ATTRIB InTangent = vertex.texcoord[2];\n"\
"ATTRIB InBinormal = vertex.texcoord[3];\n"\
"ATTRIB InTl = vertex.texcoord[1];\n"\
"\n"\
"#output\n"\
"OUTPUT OutPos = result.position;\n"\
"OUTPUT OutLightColor1 = result.color.primary;\n"\
"OUTPUT OutLightColor2 = result.color.secondary;\n"\
"OUTPUT OutTexCoord = result.texcoord[0];\n"\
"OUTPUT OutLightVector1 = result.texcoord[1];\n"\
"OUTPUT OutLightVector2 = result.texcoord[2];\n"\
"OUTPUT OutEyeVector = result.texcoord[3];\n"\
"OUTPUT Outl = result.texcoord[4];\n"\
"\n"\
"PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix.\n"\
"TEMP Temp;\n"\
"TEMP TempColor;\n"\
"TEMP TempNormal;\n"\
"TEMP TempTangent;\n"\
"TEMP TempBinormal;\n"\
"TEMP TempLightVector1;\n"\
"TEMP TempLightVector2;\n"\
"TEMP TempEyeVector;\n"\
"TEMP TempTransLightV1;\n"\
"TEMP TempTransLightV2;\n"\
"\n"\
"# transform position to clip space \n"\
"DP4 OutPos.x, MVP[0], InPos;\n"\
"DP4 OutPos.y, MVP[1], InPos;\n"\
"DP4 OutPos.z, MVP[2], InPos;\n"\
"DP4 OutPos.w, MVP[3], InPos;\n"\
"\n"\
"# transform normal \n"\
"DP3 TempNormal.x, InNormal.x, program.local[0];\n"\
"DP3 TempNormal.y, InNormal.y, program.local[1]; \n"\
"DP3 TempNormal.z, InNormal.z, program.local[2];\n"\
"\n"\
"# transform tangent \n"\
"DP3 TempTangent.x, InTangent.x, program.local[0];\n"\
"DP3 TempTangent.y, InTangent.y, program.local[1]; \n"\
"DP3 TempTangent.z, InTangent.z, program.local[2];\n"\
"\n"\
"# transform binormal \n"\
"DP3 TempBinormal.x, InBinormal.x, program.local[0];\n"\
"DP3 TempBinormal.y, InBinormal.y, program.local[1]; \n"\
"DP3 TempBinormal.z, InBinormal.z, program.local[2];\n"\
"\n"\
"# vertex into world position \n"\
"DP4 Temp.x, InPos, program.local[0];\n"\
"DP4 Temp.y, InPos, program.local[1];\n"\
"DP4 Temp.z, InPos, program.local[2];\n"\
"DP4 Temp.w, InPos, program.local[3];\n"\
"\n"\
"# vertex - lightpositions \n"\
"SUB TempLightVector1, program.local[12], Temp; \n"\
"SUB TempLightVector2, program.local[14], Temp; \n"\
"\n"\
"# eye vector \n"\
"SUB Temp, program.local[16], Temp; \n"\
"\n"\
"# transform the light vector 1 with U, V, W \n"\
"DP3 TempTransLightV1.x, TempTangent, TempLightVector1; \n"\
"DP3 TempTransLightV1.y, TempBinormal, TempLightVector1; \n"\
"DP3 TempTransLightV1.z, TempNormal, TempLightVector1; \n"\
"\n"\
"# transform the light vector 2 with U, V, W \n"\
"DP3 TempTransLightV2.x, TempTangent, TempLightVector2; \n"\
"DP3 TempTransLightV2.y, TempBinormal, TempLightVector2; \n"\
"DP3 TempTransLightV2.z, TempNormal, TempLightVector2; \n"\
"\n"\
"# transform the eye vector with U, V, W \n"\
"DP3 TempEyeVector.x, TempTangent, Temp; \n"\
"DP3 TempEyeVector.y, TempBinormal, Temp; \n"\
"DP3 TempEyeVector.z, TempNormal, Temp; \n"\
"\n"\
"# normalize light vector 1 \n"\
"DP3 TempTransLightV1.w, TempTransLightV1, TempTransLightV1; \n"\
"RSQ TempTransLightV1.w, TempTransLightV1.w; \n"\
"MUL TempTransLightV1, TempTransLightV1, TempTransLightV1.w;\n"\
"\n"\
"# normalize light vector 2 \n"\
"DP3 TempTransLightV2.w, TempTransLightV2, TempTransLightV2; \n"\
"RSQ TempTransLightV2.w, TempTransLightV2.w; \n"\
"MUL TempTransLightV2, TempTransLightV2, TempTransLightV2.w;\n"\
"\n"\
"# normalize eye vector \n"\
"DP3 TempEyeVector.w, TempEyeVector, TempEyeVector; \n"\
"RSQ TempEyeVector.w, TempEyeVector.w; \n"\
"MUL TempEyeVector, TempEyeVector, TempEyeVector.w;\n"\
"MUL TempEyeVector, TempEyeVector, {1,-1,-1,1}; # flip x \n"\
"\n"\
"\n"\
"# move light and eye vectors out\n"\
"MAD OutLightVector1, TempTransLightV1, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\
"MAD OutLightVector2, TempTransLightV2, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\
"MAD OutEyeVector, TempEyeVector, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\
"\n"\
"# calculate attenuation of light 1\n"\
"MOV TempLightVector1.w, {0,0,0,0}; \n"\
"DP3 TempLightVector1.x, TempLightVector1, TempLightVector1; \n"\
"MUL TempLightVector1.x, TempLightVector1.x, program.local[13].w; \n"\
"RSQ TempLightVector1, TempLightVector1.x; \n"\
"MUL OutLightColor1, TempLightVector1, program.local[13]; # resulting light color = lightcolor * attenuation \n"\
"\n"\
"# calculate attenuation of light 2\n"\
"MOV TempLightVector2.w, {0,0,0,0}; \n"\
"DP3 TempLightVector2.x, TempLightVector2, TempLightVector2; \n"\
"MUL TempLightVector2.x, TempLightVector2.x, program.local[15].w; \n"\
"RSQ TempLightVector2, TempLightVector2.x; \n"\
"MUL OutLightColor2, TempLightVector2, program.local[15]; # resulting light color = lightcolor * attenuation \n"\
"\n"\
"# move out texture coordinates and original alpha value\n"\
"MOV OutTexCoord, InTexCoord; \n"\
"MOV Outl, InTl; \n"\
"MOV OutLightColor1.w, InColor.w; \n"\
"\n"\
"END\n";
// Irrlicht Engine OpenGL render path parallax map pixel shader
// I guess it could be optimized a bit, because I wrote it in D3D ASM and
// transfered it 1:1 to OpenGL
const char OPENGL_PARALLAX_MAP_PSH[] =
"!!ARBfp1.0\n"\
"\n"\
"#Input\n"\
"ATTRIB inTexCoord = fragment.texcoord[0]; \n"\
"ATTRIB light1Vector = fragment.texcoord[1]; \n"\
"ATTRIB light2Vector = fragment.texcoord[2]; \n"\
"ATTRIB eyeVector = fragment.texcoord[3]; \n"\
"ATTRIB light1Color = fragment.color.primary; \n"\
"ATTRIB light2Color = fragment.color.secondary; \n"\
"ATTRIB inTlf = fragment.texcoord[4];\n"\
"\n"\
"#Output\n"\
"OUTPUT outColor = result.color;\n"\
"TEMP temp;\n"\
"TEMP temp2;\n"\
"TEMP colorMapColor;\n"\
"TEMP normalMapColor;\n"\
"TEMP Lightmap;\n"\
"TEMP t1;\n"\
"TEMP t2;\n"\
"TEMP t3;\n"\
"TEMP t4;\n"\
"TEMP HM;\n"\
"TEMP r1;\n"\
"TEMP TextureNormAb;\n"\
"\n"\
"PARAM height_scale = program.local[0]; \n"\
"TEMP TextureNorm;\n"\
"TEMP TextureNormA;\n"\
"MUL t1,0.006,{0.0,-1.0};\n"\
"MUL t2,0.006,{-1.0,0.0};\n"\
"MUL t3,0.006,{1.0,0.0};\n"\
"MUL t4,0.006,{0.0,1.0};\n"\
"ADD t1,t1,inTexCoord;\n"\
"ADD t2,t2,inTexCoord;\n"\
"ADD t3,t3,inTexCoord;\n"\
"ADD t4,t4,inTexCoord;\n"\
"TEX TextureNorm, inTexCoord, texture[0], 2D; \n"\
"MOV TextureNormA,TextureNorm;\n"\
"ADD HM.w, TextureNorm.y, TextureNorm.x;\n"\
"ADD HM.w, TextureNorm.z, HM.w;\n"\
"MUL HM.w,HM.w,-1;\n"\
"MUL TextureNormA,TextureNorm,-4.0; \n"\
"TXP TextureNorm, t1, texture[0], 2D; \n"\
"ADD TextureNormA,TextureNormA,TextureNorm; \n"\
"ADD TextureNormA,TextureNormA,0.1; \n"\
"TXP TextureNorm, t2, texture[0], 2D; \n"\
"ADD TextureNormA,TextureNormA,TextureNorm; \n"\
"ADD TextureNormA,TextureNormA,0.1; \n"\
"TXP TextureNorm, t3, texture[0], 2D; \n"\
"ADD TextureNormA,TextureNormA,TextureNorm; \n"\
"ADD TextureNormA,TextureNormA,0.1; \n"\
"TXP TextureNorm, t4, texture[0], 2D; \n"\
"ADD TextureNormA,TextureNormA,TextureNorm; \n"\
"ADD TextureNormA,TextureNormA,0.1; \n"\
"MOV r1.w,HM.w;\n"\
"MUL r1.w,r1.w,2; \n"\
"MUL HM.w,r1.w,HM.w; \n"\
"MOV TextureNormA.w,HM.w;\n"\
"MAX_SAT TextureNormA,TextureNormA,0.1;\n"\
"MUL TextureNormA,TextureNormA,{0.75,0.65,2,1}; \n"\
"MOV normalMapColor,TextureNormA;\n"\
"MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
"\n"\
"MAD temp, eyeVector, {2,2,2,2}, {-1,-1,-1,-1};\n"\
"# extract eye vector (so substract 0.5f and multiply by 2)\n"\
"MAD temp, eyeVector, {2,2,2,2}, {-1,-1,-1,-1};\n"\
"\n"\
"# height = height * scale \n"\
"MUL normalMapColor, normalMapColor, height_scale;\n"\
"\n"\
"# calculate new texture coord: height * eye + oldTexCoord\n"\
"MAD temp, temp, normalMapColor.wwww, inTexCoord;\n"\
"\n"\
"# fetch new textures \n"\
"TXP colorMapColor, temp, texture[0], 2D; \n"\
"MOV normalMapColor,TextureNormA;\n"\
"TXP Lightmap, inTlf, texture[1], 2D; \n"\
"\n"\
"# calculate color of light1; \n"\
"MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
"MAD temp, light1Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
"DP3_SAT temp, normalMapColor, temp; \n"\
"MUL temp, light1Color, temp; \n"\
"\n"\
"# calculate color of light2; \n"\
"MAD temp2, light2Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
"DP3_SAT temp2, normalMapColor, light2Vector; \n"\
"MAD temp, light2Color, temp2, temp; \n"\
"\n"\
"# luminance * base color; \n"\
"ADD temp,temp,Lightmap; \n"\
"ADD temp,temp,0.5; \n"\
"MUL temp,temp,2; \n"\
"MUL outColor,temp,colorMapColor; \n"\
"MOV outColor.a, light1Color.a; #write interpolated vertex alpha value\n"\
"\n"\
"END\n";
//! Constructor
COpenGLParallaxMapRenderer::COpenGLParallaxMapRenderer(video::COpenGLDriver* driver,
s32& outMaterialTypeNr, IMaterialRenderer* baseMaterial)
: COpenGLShaderMaterialRenderer(driver, 0, baseMaterial), CompiledShaders(true)
{
// set this as callback. We could have done this in
// the initialization list, but some compilers don't like it.
CallBack = this;
CallBack->grab();
// basicly, this thing simply compiles these hardcoded shaders if the
// hardware is able to do them, otherwise it maps to the base material
if (!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) ||
!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
{
// this hardware is not able to do shaders. Fall back to
// base material.
outMaterialTypeNr = driver->addMaterialRenderer(this);
return;
}
// check if already compiled normal map shaders are there.
video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID);
if (renderer)
{
// use the already compiled shaders
video::COpenGLParallaxMapRenderer* nmr = (video::COpenGLParallaxMapRenderer*)renderer;
CompiledShaders = false;
VertexShader = nmr->VertexShader;
PixelShader = nmr->PixelShader;
outMaterialTypeNr = driver->addMaterialRenderer(this);
}
else
{
// compile shaders on our own
init(outMaterialTypeNr, OPENGL_PARALLAX_MAP_VSH, OPENGL_PARALLAX_MAP_PSH, EVT_TANGENTS);
}
}
//! Destructor
COpenGLParallaxMapRenderer::~COpenGLParallaxMapRenderer()
{
if (!CompiledShaders)
{
// prevent this from deleting shaders we did not create
VertexShader = 0;
PixelShader = 0;
}
}
void COpenGLParallaxMapRenderer::OnSetMaterial(video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates, video::IMaterialRendererServices* services)
{
COpenGLShaderMaterialRenderer::OnSetMaterial(material, lastMaterial,
resetAllRenderstates, services);
CurrentScale = material.MaterialTypeParam;
}
//! Returns the render capability of the material.
s32 COpenGLParallaxMapRenderer::getRenderCapability()
{
if (Driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) &&
Driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
return 0;
return 1;
}
//! Called by the engine when the vertex and/or pixel shader constants for an
//! material renderer should be set.
void COpenGLParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
// set transposed world matrix
core::matrix4 tWorld = driver->getTransform(video::ETS_WORLD).getTransposed();
services->setVertexShaderConstant(&tWorld.M[0], 0, 4);
// The viewpoint is at (0., 0., 0.) in eye space.
// Turning this into a vector [0 0 0 1] and multiply it by
// the inverse of the view matrix, the resulting vector is the
// object space location of the camera.
f32 floats[4] = {0,0,0,1};
core::matrix4 minv = driver->getTransform(video::ETS_VIEW);
minv.makeInverse();
minv.multiplyWith1x4Matrix(floats);
services->setVertexShaderConstant(floats, 16, 1);
// set transposed worldViewProj matrix
core::matrix4 worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
core::matrix4 tr = worldViewProj.getTransposed();
services->setVertexShaderConstant(&tr.M[0], 8, 4);
// here we've got to fetch the fixed function lights from the driver
// and set them as constants
int cnt = driver->getDynamicLightCount();
for (int i=0; i<2; ++i)
{
video::SLight light;
if (i<cnt)
light = driver->getDynamicLight(i);
else
{
light.DiffuseColor.set(0,0,0); // make light dark
light.Radius = 1.0f;
}
light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation
services->setVertexShaderConstant(
reinterpret_cast<f32*>(&light.Position), 12+(i*2), 1);
services->setVertexShaderConstant(
reinterpret_cast<f32*>(&light.DiffuseColor), 13+(i*2), 1);
}
// set scale factor
f32 factor = 0.02f; // default value
if (CurrentScale != 0)
factor = CurrentScale;
f32 c6[] = {factor, factor, factor, factor};
services->setPixelShaderConstant(c6, 0, 1);
}
} // end namespace video
} // end namespace irr
#endif
In your project create an animated mesh with tangents (see the perpixel tutorial) but dont generate normals or apply any textures.
Im now working on volumeteric lighting using the same technology i made behind the grass. It should give us an infite number of volumeteric lights, the screen resolution is the only limit.
The blender conversion was partly sucessfull, each blur stage looks fine,but seems blender sees the grass as aliasing and heavily does anti aliasing on it which blurs the grass to the degree it looks like the original texture in the final output
"Irrlicht is obese"
If you want modern rendering techniques learn how to make them or go to the engine next door =p
If you want modern rendering techniques learn how to make them or go to the engine next door =p