Lights: Remove hard edge and attenuate specular

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14796 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
vincentlj 2013-12-26 18:00:54 +00:00
parent 067564c7cf
commit 5512a72d62
5 changed files with 32 additions and 59 deletions

View File

@ -17,7 +17,6 @@ void main() {
xpos /= xpos.w;
float d = distance(center, xpos.xyz);
if (d > r) discard;
float att = energy * 200.0 / (4. * 3.14 * d * d);
vec3 norm = texture2D(ntex, texc).xyz;
@ -33,5 +32,5 @@ void main() {
float Specular = pow(RdotE, spec);
gl_FragData[0] = vec4(NdotL * col * att, 1.);
gl_FragData[1] = vec4(Specular * col, 1.);
gl_FragData[1] = vec4(Specular * col * att, 1.);
}

View File

@ -393,11 +393,7 @@ public:
void setPosition(float x, float y, float z)
{
const core::vector3df &campos =
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
const video::IVideoDriver * const drv = irr_driver->getVideoDriver();
core::vector3df pos(x,y,z);
pos -= campos;
// get position in eye space coordinates
core::matrix4 m_view = drv->getTransform(video::ETS_VIEW);

View File

@ -25,6 +25,7 @@
#include "graphics/material.hpp"
#include "graphics/rtts.hpp"
#include "graphics/shaders.hpp"
#include "graphics/screenquad.hpp"
using namespace video;
using namespace scene;
@ -38,29 +39,29 @@ aabbox3df LightNode::box;
LightNode::LightNode(scene::ISceneManager* mgr, float radius, float e, float r, float g, float b):
ISceneNode(mgr->getRootSceneNode(), mgr, -1)
{
if (!sphere)
sq = new ScreenQuad(irr_driver->getVideoDriver());
SMaterial &mat = sq->getMaterial();
mat.Lighting = false;
mat.MaterialType = irr_driver->getShader(ES_POINTLIGHT);
mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH));
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
{
mat.Lighting = false;
mat.MaterialType = irr_driver->getShader(ES_POINTLIGHT);
mat.setTexture(0, irr_driver->getRTT(RTT_NORMAL_AND_DEPTH));
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
{
mat.TextureLayer[i].TextureWrapU =
mat.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE;
}
mat.setFlag(EMF_BILINEAR_FILTER, false);
mat.setFlag(EMF_ZWRITE_ENABLE, false);
mat.MaterialTypeParam = pack_textureBlendFunc(EBF_ONE, EBF_ONE);
mat.BlendOperation = EBO_ADD;
sphere = mgr->getGeometryCreator()->createSphereMesh(1, 16, 16);
box = sphere->getBoundingBox();
mat.TextureLayer[i].TextureWrapU =
mat.TextureLayer[i].TextureWrapV = ETC_CLAMP_TO_EDGE;
}
mat.setFlag(EMF_BILINEAR_FILTER, false);
mat.setFlag(EMF_ZWRITE_ENABLE, false);
mat.MaterialTypeParam = pack_textureBlendFunc(EBF_ONE, EBF_ONE);
mat.BlendOperation = EBO_ADD;
sphere = mgr->getGeometryCreator()->createSphereMesh(1, 16, 16);
box = sphere->getBoundingBox();
setScale(vector3df(radius));
m_radius = radius;
energy = e;
@ -81,12 +82,16 @@ void LightNode::render()
cb->setPosition(getPosition().X, getPosition().Y, getPosition().Z);
cb->setRadius(m_radius);
cb->setEnergy(energy);
// Irrlicht's ScreenQuad reset the matrixes, we need to keep them
IVideoDriver * const drv = irr_driver->getVideoDriver();
drv->setTransform(ETS_WORLD, AbsoluteTransformation);
drv->setMaterial(mat);
drv->drawMeshBuffer(sphere->getMeshBuffer(0));
matrix4 tmpworld = drv->getTransform(ETS_WORLD);
matrix4 tmpview = drv->getTransform(ETS_VIEW);
matrix4 tmpproj = drv->getTransform(ETS_PROJECTION);
sq->render(false);
drv->setTransform(ETS_WORLD, tmpworld);
drv->setTransform(ETS_VIEW, tmpview);
drv->setTransform(ETS_PROJECTION, tmpproj);
return;
}
void LightNode::OnRegisterSceneNode()

View File

@ -56,6 +56,7 @@ protected:
static core::aabbox3df box;
static scene::IMesh *sphere;
class ScreenQuad *sq;
float m_radius;
float m_color[3];

View File

@ -710,35 +710,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
radius_sum *= radius_sum;
if (radius_sum < distance_sq)
continue;
bool inside = false;
const float camdistance_sq = (m_lights[i]->getPosition() - campos).getLengthSQ();
float adjusted_radius = m_lights[i]->getRadius() + camnear;
adjusted_radius *= adjusted_radius;
// Camera inside the light's radius? Needs adjustment for the near plane.
if (camdistance_sq < adjusted_radius)
{
inside = true;
video::SMaterial &m = m_lights[i]->getMaterial(0);
m.FrontfaceCulling = true;
m.BackfaceCulling = false;
m.ZBuffer = video::ECFN_GREATER;
}
// Action
m_lights[i]->render();
// Reset the inside change
if (inside)
{
video::SMaterial &m = m_lights[i]->getMaterial(0);
m.FrontfaceCulling = false;
m.BackfaceCulling = true;
m.ZBuffer = video::ECFN_LESSEQUAL;
}
} // for i in lights
// Handle SSAO