Ok, I know that my 3D knowledge is terrible, I also find that it’s very hard to me to find myself in 3D math… My attempt to switch form business software development into 3D gamedev is not so easy that I wanted to.
BUT, finally I have some idea and I hope it will work.
The idea is to use modified PointLightShadowRenderer. The renderer in its standard form renders shadows for one light and of course does not know anything about other lights. In the result we can have a shadow (cast by light A) just next to light source B. In my renderer’s version I’m passing to shader all other nearby lights (positions xyz + InvRadius) and the number of them as well.
I can compile the code, there are no errors, it works somehow when I just modify the ‘shadow’ value, setting it to 0 or 1 (scene is dark or light).
I have all necessary modified files, my own versions of Lighting.j3md, PostShadow.j3md, PostShadow15.frag.
Now the code:
Updating shader and material values inside MyPointLightShadowRenderer.java:
[java]
Technique technique = material.getActiveTechnique();
if (technique == null)
return;
LightList list = _lightNode.getLocalLightList();
ArrayList<PointLight> arr = new ArrayList<PointLight>(list.size());
Light l;
float dist = 0;
for (int i = 0; i < list.size(); i++)
{
l = list.get(i);
if (l == light) continue;
if (!(l instanceof PointLight)) continue;
PointLight p = (PointLight)l;
dist = p.getPosition().distance(light.getPosition());
if (dist > p.getRadius() * 2) continue;
arr.add(p);
}
if (arr.size() == 0) return;
Uniform lightPos = null;
Vector3f pos = null;
PointLight pl = null;
try
{
material.getMaterialDef().addMaterialParam(VarType.Int, "LightCount", arr.size(), null);
material.setInt("LightCount", arr.size());
//material.getMaterialDef().addMaterialParam(VarType.Vector3Array, "LightsPositions", null, null);
Shader shader = technique.getShader();
lightPos = shader.getUniform("g_LightsPositions");
if (lightPos.getValue() == null) return;
for (int i = 0; i < arr.size(); i++)
{
pl = arr.get(i);
pos = pl.getPosition();
float radius = pl.getInvRadius();
lightPos.setVector4InArray(pos.getX(), pos.getY(), pos.getZ(), radius, i);
}
//Uniform lightPos = shader.getUniform("g_LightPosition");
}
catch (Exception e)
{
e.printStackTrace();
}
[/java]
The above code updates both MyLighting and MyPostShadow materials. Again, all values are successfully passed.
Now the shader, MyPostShadow15.frag, only main methos is modified:
[java]
#ifdef NUM_LIGHTS
uniform vec4 g_LightsPositions[NUM_LIGHTS];
uniform mat4 g_WorldMatrix;
#endif
void main(){
#ifdef DISCARD_ALPHA
#ifdef COLOR_MAP
float alpha = texture2D(m_ColorMap,texCoord).a;
#else
float alpha = texture2D(m_DiffuseMap,texCoord).a;
#endif
if(alpha < m_AlphaDiscardThreshold){
discard;
}
#endif
float shadow = 1.0;
#ifdef POINTLIGHT
shadow = getPointLightShadows(worldPos, m_LightPos,
m_ShadowMap0,m_ShadowMap1,m_ShadowMap2,m_ShadowMap3,m_ShadowMap4,m_ShadowMap5,
projCoord0, projCoord1, projCoord2, projCoord3, projCoord4, projCoord5);
#else
#ifdef PSSM
shadow = getDirectionalLightShadows(m_Splits, shadowPosition,
m_ShadowMap0,m_ShadowMap1,m_ShadowMap2,m_ShadowMap3,
projCoord0, projCoord1, projCoord2, projCoord3);
#else
//spotlight
shadow = getSpotLightShadows(m_ShadowMap0,projCoord0);
#endif
#endif
#ifdef FADE
shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));
#endif
// MY CODE BEGINS HERE -----------------------------------------------
#ifdef NUM_LIGHTS
if (shadow < 1.0)
{
vec3 lightVector;
vec4 lightPosition;
float attenuation;
float shadsub = 0.0;
for (int i = 0; i < NUM_LIGHTS; i++)
{
lightPosition = g_LightsPositions[i];
//calculateLightVector(lightPosition, lightVector, attenuation);
vec4 vLightPos = g_WorldMatrix * vec4(lightPosition.xyz,1.0);
vec4 vPos = g_WorldMatrix * worldPos;
lightVector = vLightPos.xyz - vPos.xyz;
//lightVector = lightPosition.xyz - v_wsPosition;
float dist = length(lightVector);
lightVector /= vec3(dist);
attenuation = clamp(1.0 - lightPosition.w * dist, 0.0, 1.0); //
shadsub += attenuation;
}
shadsub = clamp(shadsub, 0.0, 1.0);
shadow += shadsub;
//shadow = 0.0; // CZAAAARNE
}
#endif
// MY CODE ENDS HERE -----------------------------------------------------
shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
//shadow = 0.0;
outFragColor = vec4(shadow, shadow, shadow, 1.0);
}
[/java]
I’m just unable to make a formula that modify in correct way the ‘shadow’ value. The lights from g_LightsPositions should lighten the calculated shadow, make him even disappear if the light is close enough.
Any clues?