Search Home Members Contacts
About Us
Products
Downloads
Community
Support
Pages: [1]
  Print  
Author Topic: Terrain Managed Lighting?  (Read 920 times)
Aki
Customers
Community Member
*****
Posts: 84


« on: September 22, 2009, 03:48:26 PM »

I've attempted to implement terrain lighting several times - first with a shader with TV3D semantics and progressive LOD, then with splatting and LOD, then without splatting and just LOD, then finally without LOD.


Here's some poorly organized clips of my test code:

Code:
IDMat = m_Material->CreateLightMaterial(1, 1, 1, 1, 0.05f, 0.3, "basic material");
m_WorldLandscape->GenerateTerrain("texture/height.png",cTV_PRECISION_HIGH,64,64,0,0,0,true);
m_WorldLandscape->EnableLOD(true, 1024, cTV_PRECISION_VERY_LOW, 128, true);
m_WorldLandscape->SetProgressiveLOD(true);
m_WorldLandscape->SetTextureEx(0,IDSand,-1);
m_WorldLandscape->SetCullMode(cTV_BACK_CULL);
m_WorldLandscape->SetMaterial(IDMat,-1);
m_WorldLandscape->SetLightingMode(cTV_LIGHTING_MANAGED, 1, 6);

All results using progressive LOD properly rendered the first (in order of creation) four point lights, as well as my directional light (I didn't try with different amounts of directional lights).  I had used the SetLightingMode function to increase the amount of active lights on the object to an arbitrarily high number as well as simply 6 point lights.  No matter what, it always only showed my first four created point lights, even though level geometry responded to all 7 that I had created.

Without LOD, lighting just didn't work.

I think this is a bug, and yes, I did use materials.  From what I've seen thus far, TV3D has a very sound lighting architecture, but this problem (assuming I didn't make a dumb mistake, which is very possible) is a real pain and essentially nullifies the benefit of managed lighting for those who use terrain.  Until anybody figures this out, I guess I'll be forced to sort arrays aggressively.
« Last Edit: September 22, 2009, 03:53:09 PM by Aki » Logged

Aki
Customers
Community Member
*****
Posts: 84


« Reply #1 on: October 06, 2009, 10:56:39 AM »

Anyone interested in a fix for this can use my shader, though it's nowhere near as convenient as automatic managed lighting would be.  Remember to use std::vector and sort your light array, then pass the nearest 8 lights to this shader.


Code:
//////////////////////////////////////////////////

   matrix WorldVP:WorldViewProjection;
   matrix World:World;   
   matrix ViewInv:ViewInverse;
   
   float Time:TIME;

//////////////////////////////////////////////////

   float ViewRange = 4096.0f;
   float4 FogColor = {0.6,0.6,0.7,1.0};
   
   float4 LightDir_Direction = 0;
   float4 LightDir_Color = 0;
   
   float4 LightPoint_Position[8];
   float4 LightPoint_Color[8];
   float LightPoint_Radius[8];
   bool LightPoint_Flicker[8];   
   bool LightPoint_Pulse[8];

//////////////////////////////////////////////////

   texture LayerTX:TEXTURE0;

   sampler2D Layer = sampler_state
      {
texture = (LayerTX);
MIPFILTER = ANISOTROPIC;
MAGFILTER = ANISOTROPIC;
MINFILTER = ANISOTROPIC;
      };

   struct IN_Diffuse
     {
  float4 Pos:POSITION;
float2 UV:TEXCOORD0;
float3 Normal:NORMAL;
     };
   struct OUT_Diffuse
     {
  float4 Pos:POSITION;
  float2 UV:TEXCOORD0;
float4 Diffuse:TEXCOORD1;
float Fog:TEXCOORD2;
     };

   OUT_Diffuse VS_Diffuse(IN_Diffuse IN)
     {
       OUT_Diffuse OUT;
       OUT.Pos = mul(IN.Pos,WorldVP);
       OUT.UV=IN.UV;    

       float4 Ambient=LightDir_Color/2;
       float4 Normalized=normalize(mul(IN.Normal,World));
       float4 Directional=dot(LightDir_Direction,Normalized)*LightDir_Color;

       OUT.Diffuse=lerp(Ambient+Directional,Ambient+Ambient,LightDir_Direction.x*LightDir_Direction.x);
       
       int i;
       
       for(i=0;i<8;i++)
       {
       float4 Attenuation=LightPoint_Position[i]-IN.Pos;
       if (length(Attenuation)<LightPoint_Radius[i])
       {
       OUT.Diffuse+=saturate(1.0-(length(Attenuation)/LightPoint_Radius[i]))*dot(normalize(Attenuation),Normalized)*LightPoint_Color[i]*(1+0.3*sin(Time)*LightPoint_Pulse[i])*saturate(120+120*sin(Time*4)*LightPoint_Flicker[i]);
       }
       }
       
       OUT.Fog=saturate(length(mul(IN.Pos,WorldVP).z/ViewRange));
       return OUT;
     }

   float4 PS_Diffuse(OUT_Diffuse IN) : COLOR
     {
float4 Albedo;
float4 Color;
Albedo=tex2D(Layer,IN.UV);
Color=Albedo*saturate(IN.Diffuse);
Color=lerp(Color,FogColor,IN.Fog*IN.Fog);
return Color;
     }

    technique Diffuse
      {
  pass p0
      {
  VertexShader = compile vs_3_0 VS_Diffuse();
  PixelShader  = compile ps_3_0 PS_Diffuse();
      }
      }

//////////////////////////////////////////////////
Logged

Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.3 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks