Jump to content

Modding Textures EDIT: and Shaders


Lindor

Recommended Posts

6 minutes ago, Lindor said:

With this code and using tree_Tree for the plants, does it look more like you want to?

Unfortunately not because they are too dark with the tree_tree

1yj5kdh.png

Link to comment
2 minutes ago, Vishanka said:

Unfortunately not because they are too dark with the tree_tree

Okay this is strange. I thought I had it fixed. I see there's more work to do.

Link to comment
8 minutes ago, Lindor said:

Okay this is strange. I thought I had it fixed. I see there's more work to do.

Should I work upwards from the code replacement for the whole file you posted earlier or just replace the chunks from the original? could be a reason if I was meant to keep the other version

 

just tested  with the file replacement and the new code chunk (on the left), it's a bit lighter with that, right are the correct colors

q2rRh7s.png

Edited by Vishanka
Link to comment
22 minutes ago, Vishanka said:

Should I work upwards from the code replacement for the whole file you posted earlier or just replace the chunks from the original? could be a reason if I was meant to keep the other version

Upwards from the whole file code I posted, sry that I didn't mention it.

The first implementation for the saturation/lightness scaling seems to work:

uh9ZRf6.png

The specular for the very same plant (red circled) has now the correct color. Implementation is not calculation-efficient yet, but here's the code if you wanna test it:

Spoiler
#ifdef PS_SPASS_AMBDIF_NONORMAL_20 
  #define VS_OUT_hposition
  #define VS_OUT_diffuse
  #define VS_OUT_hpos
  #define VS_OUT_screenCoord
  #define VS_OUT_depthFog
  #define VS_OUT_camDist
  #define VS_OUT_lightDist
  #define VS_OUT_NORMAL
  #ifdef ENABLE_VERTEXLIGHTING
    #define VS_OUT_vertexLightData_nonrm
  #endif

  struct pixdata {
    float4 hposition   : POSITION;
    float4 diffuse     : COLOR0;
    float4 texcoord0   : TEXCOORD0;
    float4 hpos        : TEXCOORD1;
    float4 screenCoord : TEXCOORD2;
    float2 depthFog    : TEXCOORD3;
    float4 camDist     : TEXCOORD4;
    float4 lightDist   : TEXCOORD5;
    float4 normal      : TEXCOORD6;
    #ifdef VS_OUT_vertexLightData_nonrm
      float4 vlColor           : COLOR1;
    #endif
    
  };

  fragout2 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform sampler2D shadow_map,
                  uniform sampler3D textureVolume,
                  uniform sampler2D shadow_texture,
                  uniform sampler2D fog_texture,
                  uniform int       anzIterations,
                  uniform float4    shadow_data,
                  uniform float4    fog_color,
                  uniform float4    light_col_amb,
                  uniform float4    light_col_diff,
                  uniform float4    param)
                  
  {
	  fragout2 O;
	  // get texture values
	  s2half4 tex0  = tex2D(texture0, I.texcoord0.xy);
	    
  #ifdef VS_OUT_vertexLightData
    light_col_amb     += light_calc_heroLight(I.vlColor);
  #endif
  #ifdef VS_OUT_vertexLightData_nonrm
    light_col_amb.rgb += I.vlColor.rgb;
    light_col_amb     += light_calc_heroLight(I.vlColor);
	light_col_amb = saturate(light_col_amb);
  #endif
  
	  s2half3 l_dir = normalize(I.lightDist.xyz);
	  s2half3 c_dir = normalize(I.camDist.xyz);
	  s2half3 nrm = normalize(I.normal.xyz);
	  
    float4 deferred_tex     = tex2Dproj(shadow_texture, I.screenCoord);
	
	//calc sun diffuse
    float3 sun_diff = I.diffuse.xyz * light_col_diff.xyz * tex0.xyz;

    // calc moon diffuse
    float3 amb = light_col_amb.xyz * tex0.xyz;
	
	// calc specular
	float specular = pow(dot(c_dir, ((2.0 * dot(nrm, l_dir) * nrm) - l_dir)), 20);
	float3 specular_diff = light_col_diff.xyz;
  #ifdef VS_OUT_vertexLightData_nonrm
    specular_diff.xyz += I.vlColor.xyz;
    specular_diff     += light_calc_heroLight(I.vlColor);
	specular_diff = saturate(specular_diff);
  #endif
    float3 spec = specular * dot(float3(0.2126, 0.7152, 0.0722), specular_diff.xyz) * max(dot(float3(0.2126, 0.7152, 0.0722), tex0.xyz), 0.33f) * sqrt(3) * normalize(specular_diff.xyz + tex0.xyz);

/*
  #ifndef NO_SHADOWS
    #ifdef PS_SIMPLESHADOW
      s2half shadow = calcShadowSimple(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x);
    #else
      s2half shadow = calcShadow(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x, anzIterations);
    #endif
    sun_diff *= shadow;
  #endif
*/
  #ifndef NO_SHADOWS
    sun_diff *= deferred_tex.z;
  #endif float4 color = float3(red, green, blue, alpha);
//make sure the saturation loss is max as high as the lightness gain
	//make sure that a+b+c=1 and 0<a,b,c<1
	float a = 0.2126;
	float b = 0.7152;
	float c = 0.0722;
	float n_a = 3.0f * a * a - 2.0f * a + 1.0f;
	float n_b = 3.0f * b * b - 2.0f * b + 1.0f;
	float n_c = 3.0f * c * c - 2.0f * c + 1.0f;
	float normalizer = max(n_a, max(n_b, n_c));
	
	float lightness_spec = dot(float3(a, b, c), spec.xyz);
	float3 s_vector = spec.xyz - float3(lightness_spec, lightness_spec, lightness_spec);
	float saturation_spec = sqrt(dot(s_vector.xyz, s_vector.xyz) / normalizer);
	
	float lightness_diff = dot(float3(a, b, c), sun_diff.xyz);
	s_vector = sun_diff.xyz - float3(lightness_diff, lightness_diff, lightness_diff);
	float saturation_diff = sqrt(dot(s_vector.xyz, s_vector.xyz) / normalizer);

float scaling_diff = (lightness_spec + saturation_spec) / (lightness_spec + saturation_spec + lightness_diff + saturation_diff);
float scaling_spec = (lightness_diff + saturation_diff) / (lightness_spec + saturation_spec + lightness_diff + saturation_diff);

float3 diff_spec_composed = scaling_diff * sun_diff.xyz + scaling_spec * spec.xyz;

float3 new_color = float3(max(amb.x, diff_spec_composed.x), max(amb.y, diff_spec_composed.y), max(amb.z, diff_spec_composed.z)); 

  #ifdef S2_FOG
    // calc fog
    fogDiffuse( new_color, fog_texture, I.depthFog, fog_color );
  #endif

	  // calc only diffuse
	  O.col[0].xyz = new_color;
	  O.col[0].a = tex0.a;
  #if TREE_HOLE
      O.col[0].a = calcHoleAlpha(I.hpos,param);
  #endif  
	  O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
#ifdef SIMPLECOLOR
	  O.col[0] = tex0;
	  O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
#endif
	  return O;
  } 
#endif

 

Man, that pixel shader is getting longer and longer:D

Link to comment
9 minutes ago, Lindor said:

The first implementation for the saturation/lightness scaling seems to work:

I probably need the complete current file again, at the moment it looks like this for me:

2ZQUONg.png

XSSyQJp.png

 

And this was before the last code chunk, the trees also got darker; it's night at the moment so I don't know if its different now  :)

quG0q8p.png

 

original:

bQI0Ugv.png

Link to comment
4 minutes ago, Vishanka said:

nd this was before the last code chunk, the trees also got darker; it's night at the moment so I don't know if its different now  :)

quG0q8p.png

 

original:

bQI0Ugv.png

This looks like the reasonable darkening because I removed the specular in the second-to-last code chunk. Unless with original you really mean Vanilla-original, the brighter areas in the tree leaves are the specular which you didn't like at the zoomed in bushes because they were too white:)

It is expected, on larger scale with more complex models, specular looks better than on smaller scale with flat-ish models.

 

If you want to test the last code chunk I've sent, It would be good to go back to where I posted the whole-file-code, use that as a basis, and then only replace the last code chunk I've sent.

Link to comment
1 minute ago, Lindor said:

If you want to test the last code chunk I've sent, It would be good to go back to where I posted the whole-file-code, use that as a basis, and then only replace the last code chunk I've sent.

That's what I did, the result are the first 2 screenshots

 

1 minute ago, Lindor said:

Unless with original you really mean Vanilla-original, the brighter areas in the tree leaves are the specular which you didn't like at the zoomed in bushes because they were too white:)

the last screenshot is with vanilla version of the file

Link to comment

Okay I was trying really hard to get an appropriate specular effect for all shaders going which wouldn't have a bad effect on the arizona plant. The light level effect from the camera angle as shown in Vishankas video has also been implemented for leaves and twigs, with a minimum value to avoid the plants getting too dark as with the tree trunk shader.

Here's the code (full file again):

Spoiler
// speedTree tree z
#include "lighting.shader"


/////////////////////////////////////
// SPASS_G setup
/////////////////////////////////////
#ifdef SPASS_G
  #if defined(SM1_1)
    #define PS_SPASS_G_11
  #else
    #define PS_SPASS_G_20 
  #endif
#endif
/////////////////////////////////////
// SPASS_SHADOWMAP setup
/////////////////////////////////////
#ifdef SPASS_SHADOWMAP
  #define PS_SPASS_SHADOWMAP
#endif
/////////////////////////////////////
// SPASS_CUBESHADOWMAP setup
/////////////////////////////////////
#ifdef SPASS_CUBESHADOWMAP
  #if defined(SM1_1)
    #define PS_DUMMY_11
  #else
    #define PS_SPASS_CUBESHADOWMAP_20
  #endif
#endif

#ifdef LAYER_BIT1
  #define USE_TENERGY
#endif


//Inputs:
//vpos screen space position  (-1 till 1)
//param  x=opacity, y=horz-shift
float calcHoleAlpha(float4 vpos,float4 param)
{
  float opacity   = param.x;
  float horz_disp = param.y;
  vpos /= vpos.w;
  vpos.x -= horz_disp;
  float fact = vpos.x*vpos.x+vpos.y*vpos.y;
  fact = fact*fact*fact*fact;
  return fact + opacity;
}

////////////////////////////////////////////////////////////////
//SPASS_G pixel shader (>=SM2_0)
////////////////////////////////////////////////////////////////
#ifdef PS_SPASS_G_20
  struct pixdata {
    float4 hposition  : POSITION;
    float4 texcoord0  : TEXCOORD0;
    float4 depthUV    : TEXCOORD1;
  };
  #define VS_OUT_depthUV
  #define VS_OUT_hposition

  fragout1 mainPS(pixdata I,
                  float2 vPos : VPOS,
                  uniform sampler2D texture0,
                  uniform sampler2D shadow_map,
                  uniform sampler3D textureVolume,
                  uniform int anzIterations,
                  uniform float4 shadow_data,
                  uniform sampler2D gradient_texture)
  {
	  fragout1 O;
#ifndef IS_OPAQUE
    s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
    clip(tex0.a-0.5f);
#endif
  	O.col        = float4(I.depthUV.w,0,0,1);
	  return O;
  } 
#endif

////////////////////////////////////////////////////////////////
//SPASS_G pixel shader (SM1_1)
////////////////////////////////////////////////////////////////
#ifdef PS_SPASS_G_11
  struct pixdata {
    float4 hposition  : POSITION;
    float4 texcoord0  : TEXCOORD0;
    float4 depthUV    : TEXCOORD1;
    float4 posInLight : TEXCOORD2;
    float fog        : FOG;
  };
  #define VS_OUT_lowendFog
  #define VS_OUT_depthUV
  #define VS_OUT_posInLight
  #define VS_OUT_hposition


  fragout1 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform sampler2D shadow_map,
                  uniform sampler3D textureVolume,
                  uniform int anzIterations,
                  uniform float4 shadow_data,
                  uniform sampler2D gradient_texture)
  {
    fragout1 O;
  #ifdef IS_OPAQUE 
    O.col = float4( 0,0,0,1 );
  #else
    O.col = tex2D(texture0, I.texcoord0.xy);
  #endif
    return O;
  } 
#endif


////////////////////////////////////////////////////////////////
//SPASS_SHADOWMAP pixel shader (unified)
////////////////////////////////////////////////////////////////
#ifdef PS_SPASS_SHADOWMAP
  struct pixdata {
    float4 posInLight : POSITION;
    float4 texcoord0  : TEXCOORD0;
  };
  #define VS_OUT_posInLight

  fragout1 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform float4 shadow_data)
  {
    fragout1 O;
#if defined(SM1_1)
    s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
    O.col.rgb = shadow_data.zzz;
    O.col.a = tex0.a;
#else
  #ifdef IS_OPAQUE 
    O.col = float4( 0,0,0,1 );
  #else
    O.col = tex2D(texture0, I.texcoord0.xy);
    clip(O.col.a-0.5f);
  #endif
#endif
    return O;
  } 
#endif

////////////////////////////////////////////////////////////////
//SPASS_CUBEMAPSHADOW pixel shader (>=SM2_0)
////////////////////////////////////////////////////////////////
#ifdef PS_SPASS_CUBESHADOWMAP_20
  struct pixdata {
    float4 posInLight  : POSITION;
    float4 texcoord0   : TEXCOORD0;
	  float4 li_to_pix_w : TEXCOORD1;
  };
  #define VS_OUT_li_to_pix_w
  #define VS_OUT_posInLight

  fragout1 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform float4    light_data)
  {
	  fragout1 O;
	  // need opacity-channel, since this is shadowmapping!
	  float4 tex0 = tex2D(texture0, I.texcoord0.xy);
	  // square distance of scaled
	  float3 li_to_pix_w_s = light_data.z * I.li_to_pix_w.xyz;
	  float sq_dist = saturate(dot(li_to_pix_w_s, li_to_pix_w_s));
	  // endcode it in rgb!!
	  float3 depth_encoded = sq_dist * float3(1.0, 256.f, 256.f * 256.f);
	  // do not put the .x component through the frac, this gives 0.0 for 1.0 -> ERRORs
	  depth_encoded.yz = frac(depth_encoded.yz);
	  // pass it to texture
	  O.col = float4(depth_encoded, tex0.a);
	  return O;
  } 
#endif



/////////////////////////////////////////////////
//SPASS_AMBDIF pixel shader (SM1_1)
/////////////////////////////////////////////////
#ifdef PS_SPASS_AMBDIF_NONORMAL_11
  struct pixdata {
    float4 hposition   : POSITION;
    float4 diffuse     : COLOR0;
    float4 specular    : COLOR1;
    float4 texcoord0   : TEXCOORD0;
    float fog           : FOG;
  };
  #define VS_OUT_lowendFog
  #define VS_OUT_hposition
  #define VS_OUT_SM1_LIGHTING

  fragout1 mainPS(pixdata I,
      uniform sampler2D texture0)
  {
	  fragout1 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);

	  O.col.rgb = tex0.rgb * I.diffuse.rgb;
	  O.col.a = tex0.a;
  #if LAYER_BIT0
      //O.col.a = tex0.a * calcHoleAlpha(I.hpos);
  #endif  

	  return O;
  } 
#endif//


    //#ifdef PS_SIMPLESHADOW
    //  s2half shadow = calcShadowSimple(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x);
    //#else
    //  s2half shadow = calcShadow(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x, anzIterations);
    //#endif
/////////////////////////////////////////////////
//SPASS_AMBDIF pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_SPASS_AMBDIF_NONORMAL_20 
  #define VS_OUT_hposition
//  #define VS_OUT_diffuse
  #define VS_OUT_hpos
  #define VS_OUT_screenCoord
  #define VS_OUT_depthFog
  #define VS_OUT_camDist
  #define VS_OUT_lightDist
  #define VS_OUT_NORMAL
//  #define VS_OUT_specular
#ifdef ENABLE_VERTEXLIGHTING
  #define VS_OUT_vertexLightData_nonrm
#endif

  struct pixdata {
    float4 hposition   : POSITION;
//    float4 diffuse     : COLOR0;
    float4 texcoord0   : TEXCOORD0;
    float4 hpos        : TEXCOORD1;
    float4 screenCoord : TEXCOORD2;
    float2 depthFog    : TEXCOORD3;
    float4 camDist     : TEXCOORD4;
    float4 lightDist   : TEXCOORD5;
    float4 normal      : TEXCOORD6;
//    float4 specular    : COLOR1;
#ifdef VS_OUT_vertexLightData_nonrm
    float4 vlColor     : COLOR0;
#endif
    
  };

  fragout2 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform sampler2D shadow_map,
                  uniform sampler3D textureVolume,
                  uniform sampler2D shadow_texture,
                  uniform sampler2D fog_texture,
                  uniform int       anzIterations,
                  uniform float4    shadow_data,
                  uniform float4    fog_color,
                  uniform float4    light_col_amb,
                  uniform float4    light_col_diff,
                  uniform float4    param)
                  
  {
	fragout2 O;
  // get texture values
	s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
	s2half3 l_dir = normalize(I.lightDist.xyz);
	s2half3 c_dir = normalize(I.camDist.xyz);
	s2half3 nrm = normalize(I.normal.xyz);
	float lightValueSun = saturate(dot(l_dir, nrm));
	float lightValueMoon = saturate(dot(c_dir, nrm));
	    
#ifdef VS_OUT_vertexLightData
    light_col_amb += light_calc_heroLight(I.vlColor);
#endif
#ifdef VS_OUT_vertexLightData_nonrm
    light_col_amb.rgb += I.vlColor.rgb;
    light_col_amb += light_calc_heroLight(I.vlColor);
	light_col_amb = saturate(light_col_amb);
#endif
	  
    float4 deferred_tex = tex2Dproj(shadow_texture, I.screenCoord);
	
  //gamma correction setup
	float3 gamma_correction = float3(0.2126f, 0.7152f, 0.0722f);

  // calc moon diffuse
    float3 amb = max(lightValueMoon, light_col_amb.xyz) * tex0.xyz;
	
  //calc sun diffuse
	float3 sun_diff = max(lightValueSun, light_col_diff.xyz) * tex0.xyz;
#ifndef NO_SHADOWS
    sun_diff *= deferred_tex.z;
#endif
	float lightness_sun_diff = dot(gamma_correction, sun_diff.xyz);
	
  // calc specular
	float specular = pow(dot(c_dir, ((2.0 * dot(nrm, l_dir) * nrm) - l_dir)), 10);
	float3 specular_diff = light_col_diff.xyz;
#ifdef VS_OUT_vertexLightData_nonrm
    specular_diff.xyz += I.vlColor.xyz;
    specular_diff += light_calc_heroLight(I.vlColor);
	specular_diff = saturate(specular_diff);
#endif
    float3 spec = 2.0f * specular_diff.xyz * tex0.xyz;
	float maxspec = max(spec.x, max(spec.y, spec.z));
	if (maxspec > 1.0f) {
		spec /= maxspec;
	}
	spec *= specular;
	float lightness_spec = dot(gamma_correction, spec.xyz);

/*
#ifndef NO_SHADOWS
  #ifdef PS_SIMPLESHADOW
	s2half shadow = calcShadowSimple(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x);
  #else
	s2half shadow = calcShadow(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x, anzIterations);
  #endif
	sun_diff *= shadow;
#endif
*/
  
  //compose
	float3 diff_spec_composed = lerp(sun_diff, spec, step(lightness_sun_diff, lightness_spec));
	float3 new_color = float3(max(amb.x, diff_spec_composed.x), max(amb.y, diff_spec_composed.y), max(amb.z, diff_spec_composed.z)); 

  // calc fog
#ifdef S2_FOG
    fogDiffuse( new_color, fog_texture, I.depthFog, fog_color );
#endif

  // calc only diffuse
	O.col[0].xyz = new_color;
	O.col[0].a = tex0.a;
#if TREE_HOLE
	O.col[0].a = calcHoleAlpha(I.hpos,param);
#endif  
	O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
#ifdef SIMPLECOLOR
	O.col[0] = tex0;
	O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
#endif
	return O;
  } 
#endif


/////////////////////////////////////////////////
//SPASS_PNT pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_SPASS_PNT_NONORMAL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 pix_to_li   : TEXCOORD1;
    float4 normal      : TEXCOORD2;
    float4 hpos        : TEXCOORD3;
    float2 depthFog    : TEXCOORD4;
  };
  #define VS_OUT_hposition
  #define VS_OUT_pix_to_li
  #define VS_OUT_NORMAL
  #define VS_OUT_hpos
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D fog_texture,
      uniform float4 light_col_diff,
      uniform float4 light_data,
      uniform float4    param)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);

	  // get normal vector from bumpmap texture
	  s2half3 nrm = normalize(I.normal.xyz);

	  // calc diffuse
	  s2half3 l0_dir = normalize(I.pix_to_li.xyz);
	  float4 diffuse = saturate(dot(l0_dir, nrm)) * light_col_diff;

	  // calc distance of light
	  float dist_to_light = dot(I.pix_to_li.xyz, I.pix_to_li.xyz);
	  // build intensity from distance to light using light radius
	  float temp_dist = saturate(dist_to_light  * light_data.z * light_data.z);
	  float intensity = (1.0 - temp_dist) * (1.0 - temp_dist); // 1.0 - sin(1.5708 * temp_dist);
	  // multiply it by intensity of ight source
	  intensity *= light_data.y;
  #ifdef S2_FOG
    // attenuate by fog
    fogPnt( intensity, fog_texture, I.depthFog );
    //intensity *= (1.0 - tex2D( fog_texture, I.depthFog ).w);
  #endif

  #if TREE_HOLE
	  intensity *= calcHoleAlpha(I.hpos,param);
  #endif
	  O.col[0] = intensity * diffuse * tex0;
	  O.col[0].a = tex0.a;
	  O.col[1] = float4(0.0, 0.0, 0.0, 0.0);

	  return O;
  } 
#endif


/////////////////////////////////////////////////
//PS_SPASS_LIGHTNING pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_SPASS_LIGHTNING_NONORMAL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 lightDist   : TEXCOORD1;
    float2 depthFog    : TEXCOORD2;
  };
  #define VS_OUT_hposition
  #define VS_OUT_lightDist
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D fog_texture,
      uniform float4    light_col_amb,
      uniform float4    system_data)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
  	
	  // calc to-face-lightning
	  float is2Lightning = step(0.2, I.lightDist.w);
  	
	  O.col[0] = float4(is2Lightning * light_col_amb.w * float3(1.0, 1.0, 1.0), tex0.a);
	  O.col[1] = float4(is2Lightning * light_col_amb.w * light_col_amb.xyz, 0.0);

    #ifdef S2_FOG
      // calc fog
      fogGlow( O.col[0].xyz, fog_texture, I.depthFog );
      fogGlow( O.col[1].xyz, fog_texture, I.depthFog );
    #endif

	  return O;
  } 
#endif

/////////////////////////////////////////////////
//PS_DUMMY_11 pixel shader (SM1_1)
/////////////////////////////////////////////////
#ifdef PS_DUMMY_11
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
  };
  #define VS_OUT_hposition

  fragout1 mainPS(pixdata I,
		              uniform sampler2D texture0)
  {
	  fragout1 O;
 	  O.col = tex2D(texture0, I.texcoord.xy);
	  return O;
  } 
#endif
/////////////////////////////////////////////////
//PS_NULL_11 pixel shader (SM1_1)
/////////////////////////////////////////////////
#ifdef PS_NULL_11
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
  };
  #define VS_OUT_hposition

  fragout1 mainPS(pixdata I)
  {
	  fragout1 O;
 	  O.col = float4(0,0,0,0);
	  return O;
  } 
#endif
/////////////////////////////////////////////////
//PS_NULL_20 pixel shader (SM2_0)
/////////////////////////////////////////////////
#ifdef PS_NULL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
  };
  #define VS_OUT_hposition

  fragout2 mainPS(pixdata I)
  {
	  fragout2 O;
 	  O.col[0] = float4(0,0,0,0);
 	  O.col[1] = float4(0,0,0,0);
	  return O;
  } 
#endif


/////////////////////////////////////////////////
//PASS_AMBDIF pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_TRUNK_SPASS_AMBDIF_20
  #define VS_OUT_hposition
  #define VS_OUT_screenCoord
  #define VS_OUT_hpos
  #define VS_OUT_camDist
  #define VS_OUT_lightDist
  #define VS_OUT_posInLight
  #define VS_OUT_depthFog
  #ifdef ENABLE_VERTEXLIGHTING
    #define VS_OUT_vertexLightData
  #endif

  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 camDist     : TEXCOORD1;
    float4 lightDist   : TEXCOORD2;
    float4 screenCoord : TEXCOORD3;
    float4 hpos        : TEXCOORD4;
    float4 posInLight  : TEXCOORD5;
    float2 depthFog    : TEXCOORD6;
    #ifdef VS_OUT_vertexLightData
      float4 vlColor           : COLOR0;
      float4 vlNormal          : TEXCOORD7;
    #endif
  };

  fragout2 mainPS(pixdata I,
                  float2 vPos : VPOS,
                  uniform sampler2D texture0,
                  uniform sampler2D texture1,
                  uniform sampler2D texture2,
                  uniform sampler2D texture3,
                  uniform sampler2D shadow_texture,
                  uniform sampler3D textureVolume,
                  uniform sampler2D fog_texture,
                  uniform sampler2D shadow_map,
                  uniform sampler3D noise_map,
                  uniform float4    shadow_data,
                  uniform float4    fog_color,
                  uniform float4    system_data,
                  uniform float4    light_col_amb,
                  uniform float4    light_col_diff,
                  uniform float4    param)
  {
	  fragout2 O;
  //get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
	  s2half4 tex1 = decode_normal(tex2D(texture1, I.texcoord0.xy));
	  s2half3 nrm  = tex1.xyz;
  //get normal vector from bumpmap texture
//	  s2half4 tex1 = tex2D(texture1, I.texcoord0.xy);
//	  s2half3 nrm = normalize(tex1.xyz - s2half3(0.5, 0.5, 0.5));
	float4 light_hero = light_col_amb;
#ifdef VS_OUT_vertexLightData
	light_hero += light_calc_heroLight(I.vlColor) + light_calc_vertexlighting(nrm,I.vlColor,normalize(I.vlNormal.xyz));
#endif
	light_hero = saturate(light_hero);
	light_hero = light_hero - light_col_amb;

  //get shadow term from shadow texture
#ifdef NO_SHADOWS
	s2half4 shadow = float4(1.0f, 1.0f, 1.0f, 1.0f);
#else  
  #ifdef TREE_HOLE
	s2half4 shadow = calcShadowSimple(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x);
  #else
	s2half4 shadow = tex2Dproj(shadow_texture, I.screenCoord);
  #endif
#endif
/*
	shadow *= (dot(light_hero.xyz, light_hero.xyz) / sqrt(3.0f));
	float newshadow = saturate(shadow.z);
	newshadow = 1.0f - shadow;
	newshadow = pow(shadow, 5);
	newshadow = 1.0f - shadow;
*/
  //lighting setup
	s2half3 l_dir = normalize(I.lightDist.xyz);
	s2half3 c_dir = normalize(I.camDist.xyz);
	float lightValueSun = saturate(dot(l_dir, nrm));
	float lightValueMoon = saturate(dot(c_dir, nrm));
	float3 gamma_correction = float3(0.2126f, 0.7152f, 0.0722f);
	
  //calc moon diffuse
    float3 moon_diff = (light_col_amb.xyz + light_hero.xyz) * tex0.xyz * lightValueMoon;
	
  //calc sun diffuse
	float3 sun_diff = shadow.z * (light_col_diff.xyz + light_hero.xyz) * tex0.xyz * lightValueSun;
	float lightness_sun_diff = dot(gamma_correction, sun_diff.xyz);
	
  //calc specular
	float specular = pow(dot(c_dir, ((2.0 * dot(nrm, l_dir) * nrm) - l_dir)), 10);
	float3 specular_diff = light_col_diff.xyz;
#ifdef VS_OUT_vertexLightData
	float4 addvalue = light_calc_heroLight(I.vlColor) + light_calc_vertexlighting(nrm,I.vlColor,normalize(I.vlNormal.xyz));
	specular_diff += addvalue.xyz;
	specular_diff = saturate(specular_diff);
#endif
    float3 spec = 2.0f * specular_diff.xyz * tex0.xyz;
	float maxspec = max(spec.x, max(spec.y, spec.z));
	if (maxspec > 1.0f) {
		spec /= maxspec;
	}
	spec *= specular;
	float lightness_spec = dot(gamma_correction, spec.xyz);
  
  //compose
	float3 diff_spec_composed = lerp(sun_diff, spec, step(lightness_sun_diff, lightness_spec));
	float3 new_color = float3(max(moon_diff.x, diff_spec_composed.x), max(moon_diff.y, diff_spec_composed.y), max(moon_diff.z, diff_spec_composed.z));

  //TEnergy
    sTEnergy tenergy;
    calc_tenergy(tenergy,noise_map,texture2,texture3,I.texcoord0.xy,-I.texcoord0.y,system_data.x);

  //calc fog
#ifdef S2_FOG
    fogDiffuse( new_color, fog_texture, I.depthFog, fog_color );
#endif

  //set output color
	O.col[0].rgb = new_color;
	O.col[0].a = 1;
#if TREE_HOLE
      O.col[0].a = calcHoleAlpha(I.hpos,param.x);
#endif  
	  O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
	  
#ifdef USE_TENERGY
//    float tescale = pow(tex0.a,3);
    float tescale = tex0.a * tex0.a;
    O.col[0].xyz += tenergy.color0*tescale;
    O.col[1].xyz += tenergy.color1*tescale;
#endif
 
  //calc to-face-lightning
#ifdef SPASS_LIGHTNING
	float is2Lightning = saturate(step(0.2, dot(nrm, I.lightDist.xyz)) + (dot(light_hero.xyz, light_hero.xyz) / sqrt(3.0f)));
	O.col[0] = float4(is2Lightning * light_col_amb.w * float3(1.0, 1.0, 1.0), 1.0);
	O.col[1] = float4(is2Lightning * light_col_amb.w * (light_col_amb.xyz + light_hero.xyz), 0.0);
#endif
#ifdef SIMPLECOLOR
	O.col[0] = float4(1,1,1,1);
#endif

	return O; 
 } 
#endif


/////////////////////////////////////////////////
//PASS_PNT pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_TRUNK_SPASS_PNT_20
  struct pixdata {
    float4 hposition    : POSITION;
    float4 texcoord0    : TEXCOORD0;
    float4 pix_to_li_t  : TEXCOORD1;
    float4 pix_to_c     : TEXCOORD2;
    float4 pix_to_li_o  : TEXCOORD3;
    float2 depthFog     : TEXCOORD4;
  };
  #define VS_OUT_hposition
  #define VS_OUT_pix_to_li_T
  #define VS_OUT_pix_to_li_O
  #define VS_OUT_PIX_TO_C
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D texture1,
      uniform sampler2D fog_texture,
      uniform float4 light_col_diff,
      uniform float4 light_data)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
	  s2half4 tex1 = tex2D(texture1, I.texcoord0.xy);
	  // get normal vector from bumpmap texture
	  s2half3 nrm = normalize(tex1.xyz - s2half3(0.5, 0.5, 0.5));

	  // calc diffuse
	  s2half3 l0_dir = normalize(I.pix_to_li_t.xyz);
	  float4 diffuse = saturate(dot(l0_dir, nrm)) * light_col_diff;

	  // calc specular
	  s2half3 c_dir = normalize(I.pix_to_c.xyz);
	  s2half3 half_vec = normalize(l0_dir + c_dir);
	  float4 specular =  pow(saturate(dot(half_vec, nrm)), 20.0) * tex1.w * light_col_diff;

	  // calc distance of light
	  float dist_to_light = dot(I.pix_to_li_o.xyz, I.pix_to_li_o.xyz);
	  // build intensity from distance to light using light radius
	  float temp_dist = saturate(dist_to_light  * light_data.z * light_data.z);
	  float intensity = (1.0 - temp_dist) * (1.0 - temp_dist); // 1.0 - sin(1.5708 * temp_dist);
	  // multiply it by intensity of ight source
	  intensity *= light_data.y;
  #ifdef S2_FOG
    // fog
    fogPnt( intensity, fog_texture, I.depthFog );
  #endif

	  O.col[0] = intensity * ((diffuse * tex0) + specular);
	  O.col[0].a = tex0.a;
	  O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
	  return O;
  } 
#endif 



DEFINE_VERTEX_DATA 


////////////////////////////////////////////////////////////////
//Unified Vertex shader used for all shader models
////////////////////////////////////////////////////////////////
pixdata mainVS(appdata I,
               uniform float4   vtx_data_array[32],
               uniform float4x4 vtx_matrix_array[4],
               VS_PARAM_BLOCK)
{
	pixdata O;
	EXTRACT_VERTEX_VALUES

	// apply wind and calc extreme (=1.0) position
	float4 wind_pos4 = mul(pos4, vtx_matrix_array[windidx]);
	// now interpolate between org pos and extr pos
	pos4 = lerp(pos4, wind_pos4, windLerpFact);
	

#ifdef VS_IN_TREELEAFVERTEX
	float leaf_scale = param.z;
	// get vertex billboard offset from array and scale it by size
	float4 offs4 = data2.y * vtx_data_array[data2.x] * leaf_scale;
	// transform this offset backwards with inv objmat, so it is "billboarded" after next transform
	pos4 += mul(offs4, invWorldMatrix);
#endif


  #ifdef VS_OUT_vertexLightData_nonrm
    O.vlColor = computeVertexLightingColor(pos4,nrm4);
  #endif
  #ifdef VS_OUT_vertexLightData
    computeVertexLightingColorNormal( O.vlColor, O.vlNormal,pos4);
  #endif


	// convert vertex pos from objspace to screen space
  float4 wvp_pos = mul(pos4, worldViewProjMatrix);

  float camSpaceZ = pos4.x*worldViewMatrix[0][2] +  
                    pos4.y*worldViewMatrix[1][2] + 
                    pos4.z*worldViewMatrix[2][2] + 
                    worldViewMatrix[3][2];
	// convert vertex pos from objspace to worldspace
	float4 worldVertPos    = mul(pos4, worldMatrix);
	float3 worldVertNormal = normalize(mul(nrm4.xyz, (float3x3) worldMatrix));

	O.texcoord0 = uv0;

#ifdef VS_OUT_depthFog
  O.depthFog = getFogTCs( wvp_pos.w, fog_data );
  //O.depthFog.x = saturate( (wvp_pos.w - fog_data.x) * zfrustum_data.z );
  //O.depthFog.y = fog_data.w;
#endif

#ifdef VS_OUT_hposition
	// vertex pos
	O.hposition = wvp_pos;
#endif

#ifdef VS_OUT_SM1_TEXCOORD1
	O.texcoord1 = uv0;
#endif

#ifdef VS_OUT_depthUV
    O.depthUV = float4(0,0,0,-camSpaceZ*zfrustum_data.w);
#endif
#ifdef VS_OUT_posInLight
	// vertex pos in light-space
	O.posInLight = mul(pos4, lightMatrix);
#endif
#ifdef VS_OUT_li_to_pix_w
	// pass light-to-pixel to fragment shader
	O.li_to_pix_w = worldVertPos - light_pos;
#endif


	// convert light pos from worldspace into objectspace
	float4 l_pos_obj = mul(light_pos, invWorldMatrix);
	// build vector from vertex pos to light pos
	float3 vertex_to_light = l_pos_obj.xyz - pos4.xyz;
	// convert cam pos from worldspace into objectspace
	float4 c_pos_obj = mul(camera_pos, invWorldMatrix);
	// build vector from vertex pos to cam pos
#ifdef MINIMAPMODE
  float3 vertex_to_cam = c_pos_obj;
#else
	float3 vertex_to_cam = c_pos_obj.xyz - pos4.xyz;
#endif
	// convert light direction vector from worldspace to objectspace
	float4 l0_dir_obj = mul(light_pos, invWorldMatrix);
	// convert camera direction vector from worldspace to objectspace
	float4 c_dir_obj = mul(camera_pos, invWorldMatrix);

#ifdef VERT_TREEVERTEX

	// build object-to-tangent space matrix
	float3x3 objToTangentSpace;
	objToTangentSpace[0] = -1.0 * tan3;
	objToTangentSpace[1] = -1.0 * bin3;
	objToTangentSpace[2] = nrm4.xyz;

  // convert vertex_to_light from objectspace to tangentspace
  float3 vertex_to_light_tan = mul(objToTangentSpace, vertex_to_light);
	// convert vertex_to_cam from objectspace to tangentspace
	float3 vertex_to_cam_tan = mul(objToTangentSpace, vertex_to_cam);

	// convert light direction vector from objectspace to tangentspace
	float3 l0_dir_tan = mul(objToTangentSpace, l0_dir_obj.xyz);

	// calc direction vector from vertex position to camera-position
	c_dir_obj -= pos4;
	// convert camera direction vector from objectspace to tangentspace
	float3 c_dir_tan = mul(objToTangentSpace, c_dir_obj.xyz);

  #ifdef VS_OUT_lightDist
	  // store light vector
	  O.lightDist = float4(l0_dir_tan, 0.0);
  #endif
  #ifdef VS_OUT_camDist
	// store camera vec in texcoord2
	O.camDist = float4(c_dir_tan, 0.0);
  #endif
#else
  #ifdef VS_OUT_lightDist
	  // store light vector & dot
	  O.lightDist = float4(l0_dir_obj.xyz, dot(nrm4.xyz, l0_dir_obj.xyz));
  #endif
  #ifdef VS_OUT_camDist
	// store camera vec in texcoord2
	O.camDist = float4(c_dir_obj.xyz, dot(nrm4.xyz, c_dir_obj.xyz));
  #endif
#endif 

//ONLY USE IF VS_OUT_camDist AND VS_OUT_lightDist AND VS_OUT_NORMAL
//#ifdef VS_OUT_specular
//	float specvalue = pow(dot(normalize(O.camDist.xyz), ((2.0 * dot(normalize(O.normal.xyz), normalize(O.lightDist.xyz)) * normalize(O.normal.xyz)) - normalize(O.lightDist.xyz))), 20);
//	O.specular = float4(specvalue, 0.0, 0.0, 0.0);
//#endif

  #ifdef VS_OUT_vertexLightData
    O.vlNormal.xyz = mul(objToTangentSpace, O.vlNormal.xyz);
  #endif



#ifdef VS_OUT_hpos
	// pass screenpos to fragment shader
	O.hpos     = O.hposition;
	O.hpos.xy *= param.xy;
#endif

#ifdef VS_OUT_NORMAL
	// norma
	O.normal = nrm4;
#endif

#ifdef VS_OUT_screenCoord
	// vertex-position in screen space
  O.screenCoord = calcScreenToTexCoord(O.hposition);
#endif

#ifdef VS_OUT_SM1_LIGHTING
	O.diffuse = calcLight(worldVertPos, worldVertNormal, camera_pos, globLightData, O.specular);
#endif 
#ifdef VS_OUT_diffuse
	// convert light direction vector from worldspace to objectspace
	float4 l0_dir = mul(light_pos, invWorldMatrix);
	float  diffuse = saturate(dot(nrm4, l0_dir));
	// prepare color
	O.diffuse = float4(diffuse, diffuse, diffuse, 1.0);
#endif 


#ifdef VS_OUT_lowendFog
	O.fog = calcFog(O.hposition, fog_data);
#endif


	// pass vertex to light to pixelshader, so it becomes pixel to light
#ifdef VS_OUT_pix_to_li_T
	O.pix_to_li_t = float4(vertex_to_light_tan, 0.0);
#endif
#ifdef VS_OUT_pix_to_li_O
	O.pix_to_li_o = float4(vertex_to_light, 0.0);
#endif
#ifdef VS_OUT_pix_to_li
	// pass vertex to light to pixelshader, so it becomes pixel to light
	O.pix_to_li = float4(vertex_to_light, 0.0);
#endif
#ifdef VS_OUT_PIX_TO_C
	// pass vertex to cam to pixelshader, so it becomes pixel to cam
	O.pix_to_c = float4(vertex_to_cam_tan, 0.0);
#endif

	return O;
}

 

It shouldn't bee too white, too bright or too dark, also not too few or too much. Still whole arizona plants can get affected (no way around that), but it doesn't look bad imho.

@Vishanka Can you test this on day and nighttime and tell me if you like it that way? This was my last try on specular, if you don't like that, I'll need to remove it for you. How are the light levels on trees/bushes during night/day and on different camera rotations? And should I implement a minimum light level for the tree trunk as well or not?

 

EDIT: Did small improvement of specular.

Edited by Lindor
Link to comment
12 hours ago, Lindor said:

Can you test this on day and nighttime and tell me if you like it that way?

As you can see there's still a problem; the plants and trees are glowing now.

7rIFi84.png

 

However I like the effect when using light aura, could be a pinch desaturated again (with the same contrast) for a more natural lighting if it's possible to do that; and if it's possible in general to fix the glowing plant problem from above.

IrHEYJO.png

If all that should not be possible I like the very first version best with just the changes to 'tree_Branch' to get lighter by the heros light aura as well.

--

The other topic with the hair - if you have time would you mind to look into that? Unfortunately I could not make any visual changes no matter what I did

Link to comment

All changes I propose here are meant to be implemented from the last code onwards, and they all are only for the PS_SPASS_AMBDIF_NONORMAL_20 code chunk.

41 minutes ago, Vishanka said:

As you can see there's still a problem; the plants and trees are glowing now.

I thought this was the wanted effect of the video. But easy to invert (it's a one-liner): instead of lightening the colors depending on camera angle, we can darken the colors depending on camera angle. search for this expression:

max(lightValueMoon, light_col_amb.xyz)

and replace with:

min(lightValueMoon, light_col_amb.xyz)

 

44 minutes ago, Vishanka said:

However I like the effect when using light aura, could be a pinch desaturated again (with the same contrast) for a more natural lighting if it's possible to do that; and if it's possible in general to fix the glowing plant problem from above.

Desaturation will always decrease the absolute contrast. Can only keep the relative contrast.
Do you want to desaturate the diffuse, the specular or both?

For diffuse desaturation:

Spoiler

search for:

  //gamma correction setup
	float3 gamma_correction = float3(0.2126f, 0.7152f, 0.0722f);

  // calc moon diffuse
    float3 amb = max(lightValueMoon, light_col_amb.xyz) * tex0.xyz;

replace with:

  //gamma correction setup
	float3 gamma_correction = float3(0.2126f, 0.7152f, 0.0722f);

  // calc moon diffuse
    float3 amb = max(lightValueMoon, light_col_amb.xyz) * tex0.xyz;	    
#ifdef VS_OUT_vertexLightData_nonrm
    float lightness_old_amb = dot(gamma_correction, amb);
    amb += float3(0.5f, 0.5f, 0.5f);
    amb *= lightness_old_amb / dot(gamma_correction, amb);
#endif

 

For specular:

Spoiler

search for:


	spec *= specular;

replace with:

	spec *= specular;
#ifdef VS_OUT_vertexLightData_nonrm
	float lightness_spec_old = dot(gamma_correction, spec);
	spec += float3(0.5f, 0.5f, 0.5f);
	spec *= lightness_spec_old / dot(gamma_correction, spec);
#endif

 

For both you can play around with the numbers where it says "float3(0.5f, 0.5f, 0.5f);". Choose a number between 0.0f and 1.0f, the higher the number, the more desaturation. All three numbers need to be the same.

 

59 minutes ago, Vishanka said:

The other topic with the hair - if you have time would you mind to look into that? Unfortunately I could not make any visual changes no matter what I did

It might be possible. The function for that is scripted in lighting.shader, but the problem is the input. The tree shaders get the input (by that I mean the light level and direction) from two specifically for this shader hardcoded data arrays:

               uniform float4   vtx_data_array[32],
               uniform float4x4 vtx_matrix_array[4],

And then, depending on the settings, it makes:

computeVertexLightingColorNormal( O.vlColor, O.vlNormal,pos4);

or:

O.vlColor = computeVertexLightingColor(pos4,nrm4);

Which are the functions scripted in lighting.shader. If O.vlColor and O.vlNormal are empty and only get filled by the functions, then it's possible. If the functions need input which is hardcoded in one of the above arrays, I'd need to figure out how the hardcoded "light_data" input works and if it can be used instead. All this of course all assuming that hair.shader is even used by the character model's hair.

It is a lot of work and I have like 20 different sub-projects running simultaneaously, you'll have to be patient. But I'll get to it someday into the future.

Link to comment
16 minutes ago, Lindor said:

All this of course all assuming that hair.shader is even used by the character model's hair.

If it was used shouldn't be there any change if I replace these shaders with that for skin for example?

obj_hair = {
  diffusePnt    = "null.shader",
  diffusePntShd = "null.shader",
  z             = "object/hairZ.shader",
  shadowmap     = "null.shader",
  cubeshadowmap = "null.shader",
  ambDiff       = "null.shader",
}

Or this with any other shader

newSurface = {
  name         = "sera_hair1_surf",
  texture0Name = "maps/heroes/seraphim/sera_hair1_do.tga",
  texture2Name = "maps/heroes/seraphim/sera_hair1_sc.tga",
  flags        = SURFACE_FLAG_MASKED,
  shader       = obj_hair,
}
mgr.surfCreate(newSurface);

 

Link to comment

Wait a minute, I know what is happening with the glowing leaves. Here is the Pixel shader:

Spoiler
#ifdef PS_SPASS_AMBDIF_NONORMAL_20 
  #define VS_OUT_hposition
  #define VS_OUT_diffuse
  #define VS_OUT_hpos
  #define VS_OUT_screenCoord
  #define VS_OUT_depthFog
  #define VS_OUT_camDist
  #define VS_OUT_lightDist
  #define VS_OUT_NORMAL
//  #define VS_OUT_specular
#ifdef ENABLE_VERTEXLIGHTING
  #define VS_OUT_vertexLightData_nonrm
#endif

  struct pixdata {
    float4 hposition   : POSITION;
    float4 diffuse     : COLOR0;
    float4 texcoord0   : TEXCOORD0;
    float4 hpos        : TEXCOORD1;
    float4 screenCoord : TEXCOORD2;
    float2 depthFog    : TEXCOORD3;
    float4 camDist     : TEXCOORD4;
    float4 lightDist   : TEXCOORD5;
    float4 normal      : TEXCOORD6;
//    float4 specular    : COLOR1;
#ifdef VS_OUT_vertexLightData_nonrm
    float4 vlColor     : COLOR1;
#endif
    
  };

  fragout2 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform sampler2D shadow_map,
                  uniform sampler3D textureVolume,
                  uniform sampler2D shadow_texture,
                  uniform sampler2D fog_texture,
                  uniform int       anzIterations,
                  uniform float4    shadow_data,
                  uniform float4    fog_color,
                  uniform float4    light_col_amb,
                  uniform float4    light_col_diff,
                  uniform float4    param)
                  
  {
	fragout2 O;
  // get texture values
	s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
	s2half3 l_dir = normalize(I.lightDist.xyz);
	s2half3 c_dir = normalize(I.camDist.xyz);
	s2half3 nrm = normalize(I.normal.xyz);
	float lightValueSun = saturate(dot(l_dir, nrm));
	float lightValueMoon = saturate(dot(c_dir, nrm));
	    
#ifdef VS_OUT_vertexLightData
    light_col_amb += light_calc_heroLight(I.vlColor);
#endif
#ifdef VS_OUT_vertexLightData_nonrm
    light_col_amb.rgb += I.vlColor.rgb;
    light_col_amb += light_calc_heroLight(I.vlColor);
	light_col_amb = saturate(light_col_amb);
#endif
	  
    float4 deferred_tex = tex2Dproj(shadow_texture, I.screenCoord);
	
  //gamma correction setup
	float3 gamma_correction = float3(0.2126f, 0.7152f, 0.0722f);

  // calc moon diffuse
    float3 amb = lightValueMoon * light_col_amb.xyz * tex0.xyz;
#ifdef VS_OUT_vertexLightData_nonrm
    float lightness_old_amb = dot(gamma_correction, amb);
    amb += float3(0.33f, 0.33f, 0.33f);
    amb *= lightness_old_amb / dot(gamma_correction, amb);
#endif
	
  //calc sun diffuse
	float3 sun_diff = max(I.diffuse.xyz, lightValueSun) * light_col_diff.xyz * tex0.xyz;
#ifndef NO_SHADOWS
    sun_diff *= deferred_tex.z;
#endif
	float lightness_sun_diff = dot(gamma_correction, sun_diff.xyz);
	
  // calc specular
	float specular = pow(dot(c_dir, ((2.0 * dot(nrm, l_dir) * nrm) - l_dir)), 10);
	float3 specular_diff = light_col_diff.xyz;
#ifdef VS_OUT_vertexLightData_nonrm
    specular_diff.rgb += I.vlColor.rgb;
    specular_diff += light_calc_heroLight(I.vlColor);
	specular_diff = saturate(specular_diff);
#endif
    float3 spec = 2.0f * specular_diff.xyz * tex0.xyz;
	float maxspec = max(spec.x, max(spec.y, spec.z));
	if (maxspec > 1.0f) {
		spec /= maxspec;
	}
	spec *= specular;
#ifdef VS_OUT_vertexLightData_nonrm
	float lightness_spec_old = dot(gamma_correction, spec);
	spec += float3(0.33f, 0.33f, 0.33f);
	spec *= lightness_spec_old / dot(gamma_correction, spec);
#endif
	float lightness_spec = dot(gamma_correction, spec);

/*
#ifndef NO_SHADOWS
  #ifdef PS_SIMPLESHADOW
	s2half shadow = calcShadowSimple(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x);
  #else
	s2half shadow = calcShadow(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x, anzIterations);
  #endif
	sun_diff *= shadow;
#endif
*/
  
  //compose
	float3 diff_spec_composed = lerp(sun_diff, spec, step(lightness_sun_diff, lightness_spec));
	float3 new_color = float3(max(amb.x, diff_spec_composed.x), max(amb.y, diff_spec_composed.y), max(amb.z, diff_spec_composed.z)); 

  // calc fog
#ifdef S2_FOG
    fogDiffuse( new_color, fog_texture, I.depthFog, fog_color );
#endif

  // calc only diffuse
	O.col[0].xyz = new_color;
	O.col[0].a = tex0.a;
#if TREE_HOLE
	O.col[0].a = calcHoleAlpha(I.hpos,param);
#endif  
	O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
#ifdef SIMPLECOLOR
	O.col[0] = tex0;
	O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
#endif
	return O;
  } 
#endif

 

It should be better now. The desaturation is implemented, I have chosen a value of 0.33f, you can change that to whatever you like.

Link to comment
2 minutes ago, Vishanka said:

If it was used shouldn't be there any change if I replace these shaders with that for skin for example?

no. As I said, it's a dummy shader. It is hardcoded what shader is used. Changing anything inside surface.txt won't do anything. Maybe the shader itself is hardcoded, maybe it's hair.shader.

Link to comment

Since this is also the topic forother shaders: I have inverted the stars brightness on the armageddon clothing shader, now they're bright outside and dimmed inside the nebula to make more sense:yyptDbg.jpeg

Also something from the category "funny and interesting screenshots": I've discovered an interesting effect when walking behind smoke with the new ancient bark shader:

FvpdK3e.jpeg

and @Vishanka for you I have the (hopefully) final version of the treeShared.shader file:

Spoiler
// speedTree tree z
#include "lighting.shader"


/////////////////////////////////////
// SPASS_G setup
/////////////////////////////////////
#ifdef SPASS_G
  #if defined(SM1_1)
    #define PS_SPASS_G_11
  #else
    #define PS_SPASS_G_20 
  #endif
#endif
/////////////////////////////////////
// SPASS_SHADOWMAP setup
/////////////////////////////////////
#ifdef SPASS_SHADOWMAP
  #define PS_SPASS_SHADOWMAP
#endif
/////////////////////////////////////
// SPASS_CUBESHADOWMAP setup
/////////////////////////////////////
#ifdef SPASS_CUBESHADOWMAP
  #if defined(SM1_1)
    #define PS_DUMMY_11
  #else
    #define PS_SPASS_CUBESHADOWMAP_20
  #endif
#endif

#ifdef LAYER_BIT1
  #define USE_TENERGY
#endif


//Inputs:
//vpos screen space position  (-1 till 1)
//param  x=opacity, y=horz-shift
float calcHoleAlpha(float4 vpos,float4 param)
{
  float opacity   = param.x;
  float horz_disp = param.y;
  vpos /= vpos.w;
  vpos.x -= horz_disp;
  float fact = vpos.x*vpos.x+vpos.y*vpos.y;
  fact = fact*fact*fact*fact;
  return fact + opacity;
}

////////////////////////////////////////////////////////////////
//SPASS_G pixel shader (>=SM2_0)
////////////////////////////////////////////////////////////////
#ifdef PS_SPASS_G_20
  struct pixdata {
    float4 hposition  : POSITION;
    float4 texcoord0  : TEXCOORD0;
    float4 depthUV    : TEXCOORD1;
  };
  #define VS_OUT_depthUV
  #define VS_OUT_hposition

  fragout1 mainPS(pixdata I,
                  float2 vPos : VPOS,
                  uniform sampler2D texture0,
                  uniform sampler2D shadow_map,
                  uniform sampler3D textureVolume,
                  uniform int anzIterations,
                  uniform float4 shadow_data,
                  uniform sampler2D gradient_texture)
  {
	  fragout1 O;
#ifndef IS_OPAQUE
    s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
    clip(tex0.a-0.5f);
#endif
  	O.col        = float4(I.depthUV.w,0,0,1);
	  return O;
  } 
#endif

////////////////////////////////////////////////////////////////
//SPASS_G pixel shader (SM1_1)
////////////////////////////////////////////////////////////////
#ifdef PS_SPASS_G_11
  struct pixdata {
    float4 hposition  : POSITION;
    float4 texcoord0  : TEXCOORD0;
    float4 depthUV    : TEXCOORD1;
    float4 posInLight : TEXCOORD2;
    float fog        : FOG;
  };
  #define VS_OUT_lowendFog
  #define VS_OUT_depthUV
  #define VS_OUT_posInLight
  #define VS_OUT_hposition


  fragout1 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform sampler2D shadow_map,
                  uniform sampler3D textureVolume,
                  uniform int anzIterations,
                  uniform float4 shadow_data,
                  uniform sampler2D gradient_texture)
  {
    fragout1 O;
  #ifdef IS_OPAQUE 
    O.col = float4( 0,0,0,1 );
  #else
    O.col = tex2D(texture0, I.texcoord0.xy);
  #endif
    return O;
  } 
#endif


////////////////////////////////////////////////////////////////
//SPASS_SHADOWMAP pixel shader (unified)
////////////////////////////////////////////////////////////////
#ifdef PS_SPASS_SHADOWMAP
  struct pixdata {
    float4 posInLight : POSITION;
    float4 texcoord0  : TEXCOORD0;
  };
  #define VS_OUT_posInLight

  fragout1 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform float4 shadow_data)
  {
    fragout1 O;
#if defined(SM1_1)
    s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
    O.col.rgb = shadow_data.zzz;
    O.col.a = tex0.a;
#else
  #ifdef IS_OPAQUE 
    O.col = float4( 0,0,0,1 );
  #else
    O.col = tex2D(texture0, I.texcoord0.xy);
    clip(O.col.a-0.5f);
  #endif
#endif
    return O;
  } 
#endif

////////////////////////////////////////////////////////////////
//SPASS_CUBEMAPSHADOW pixel shader (>=SM2_0)
////////////////////////////////////////////////////////////////
#ifdef PS_SPASS_CUBESHADOWMAP_20
  struct pixdata {
    float4 posInLight  : POSITION;
    float4 texcoord0   : TEXCOORD0;
	  float4 li_to_pix_w : TEXCOORD1;
  };
  #define VS_OUT_li_to_pix_w
  #define VS_OUT_posInLight

  fragout1 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform float4    light_data)
  {
	  fragout1 O;
	  // need opacity-channel, since this is shadowmapping!
	  float4 tex0 = tex2D(texture0, I.texcoord0.xy);
	  // square distance of scaled
	  float3 li_to_pix_w_s = light_data.z * I.li_to_pix_w.xyz;
	  float sq_dist = saturate(dot(li_to_pix_w_s, li_to_pix_w_s));
	  // endcode it in rgb!!
	  float3 depth_encoded = sq_dist * float3(1.0, 256.f, 256.f * 256.f);
	  // do not put the .x component through the frac, this gives 0.0 for 1.0 -> ERRORs
	  depth_encoded.yz = frac(depth_encoded.yz);
	  // pass it to texture
	  O.col = float4(depth_encoded, tex0.a);
	  return O;
  } 
#endif



/////////////////////////////////////////////////
//SPASS_AMBDIF pixel shader (SM1_1)
/////////////////////////////////////////////////
#ifdef PS_SPASS_AMBDIF_NONORMAL_11
  struct pixdata {
    float4 hposition   : POSITION;
    float4 diffuse     : COLOR0;
    float4 specular    : COLOR1;
    float4 texcoord0   : TEXCOORD0;
    float fog           : FOG;
  };
  #define VS_OUT_lowendFog
  #define VS_OUT_hposition
  #define VS_OUT_SM1_LIGHTING

  fragout1 mainPS(pixdata I,
      uniform sampler2D texture0)
  {
	  fragout1 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);

	  O.col.rgb = tex0.rgb * I.diffuse.rgb;
	  O.col.a = tex0.a;
  #if LAYER_BIT0
      //O.col.a = tex0.a * calcHoleAlpha(I.hpos);
  #endif  

	  return O;
  } 
#endif//


    //#ifdef PS_SIMPLESHADOW
    //  s2half shadow = calcShadowSimple(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x);
    //#else
    //  s2half shadow = calcShadow(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x, anzIterations);
    //#endif
/////////////////////////////////////////////////
//SPASS_AMBDIF pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_SPASS_AMBDIF_NONORMAL_20 
  #define VS_OUT_hposition
  #define VS_OUT_diffuse
  #define VS_OUT_hpos
  #define VS_OUT_screenCoord
  #define VS_OUT_depthFog
  #define VS_OUT_camDist
  #define VS_OUT_lightDist
  #define VS_OUT_NORMAL
//  #define VS_OUT_specular
#ifdef ENABLE_VERTEXLIGHTING
  #define VS_OUT_vertexLightData_nonrm
#endif

  struct pixdata {
    float4 hposition   : POSITION;
    float4 diffuse     : COLOR0;
    float4 texcoord0   : TEXCOORD0;
    float4 hpos        : TEXCOORD1;
    float4 screenCoord : TEXCOORD2;
    float2 depthFog    : TEXCOORD3;
    float4 camDist     : TEXCOORD4;
    float4 lightDist   : TEXCOORD5;
    float4 normal      : TEXCOORD6;
//    float4 specular    : COLOR1;
#ifdef VS_OUT_vertexLightData_nonrm
    float4 vlColor     : COLOR1;
#endif
    
  };

  fragout2 mainPS(pixdata I,
                  uniform sampler2D texture0,
                  uniform sampler2D shadow_map,
                  uniform sampler3D textureVolume,
                  uniform sampler2D shadow_texture,
                  uniform sampler2D fog_texture,
                  uniform int       anzIterations,
                  uniform float4    shadow_data,
                  uniform float4    fog_color,
                  uniform float4    light_col_amb,
                  uniform float4    light_col_diff,
                  uniform float4    param)
                  
  {
	fragout2 O;
  // get texture values
	s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
	s2half3 l_dir = normalize(I.lightDist.xyz);
	s2half3 c_dir = normalize(I.camDist.xyz);
	s2half3 nrm = normalize(I.normal.xyz);
	float lightValueSun = saturate(dot(l_dir, nrm));
	float lightValueMoon = saturate(dot(c_dir, nrm));
	    
#ifdef VS_OUT_vertexLightData
    light_col_amb += light_calc_heroLight(I.vlColor);
#endif
#ifdef VS_OUT_vertexLightData_nonrm
    light_col_amb.rgb += I.vlColor.rgb;
    light_col_amb += light_calc_heroLight(I.vlColor);
	light_col_amb = saturate(light_col_amb);
#endif
	  
    float4 deferred_tex = tex2Dproj(shadow_texture, I.screenCoord);
	
  //gamma correction setup
	float3 gamma_correction = float3(0.2126f, 0.7152f, 0.0722f);

  // calc moon diffuse
    float3 amb = lightValueMoon * light_col_amb.xyz * tex0.xyz;
#ifdef VS_OUT_vertexLightData_nonrm
    float lightness_old_amb = dot(gamma_correction, amb);
    amb += float3(0.33f, 0.33f, 0.33f);
    amb *= lightness_old_amb / dot(gamma_correction, amb);
#endif
	float lightness_amb = dot(gamma_correction, amb.xyz);
	
  //calc sun diffuse
	float3 sun_diff = max(I.diffuse.xyz, lightValueSun) * light_col_diff.xyz * tex0.xyz;
#ifndef NO_SHADOWS
    sun_diff *= deferred_tex.z;
#endif
	float lightness_sun_diff = dot(gamma_correction, sun_diff.xyz);
	
  // calc specular
	float specular = pow(dot(c_dir, ((2.0 * dot(nrm, l_dir) * nrm) - l_dir)), 10);
	float3 specular_diff = light_col_diff.xyz;
#ifdef VS_OUT_vertexLightData_nonrm
    specular_diff.rgb += I.vlColor.rgb;
    specular_diff += light_calc_heroLight(I.vlColor);
	specular_diff = saturate(specular_diff);
#endif
    float3 spec = 2.0f * specular_diff.xyz * tex0.xyz;
	float maxspec = max(spec.x, max(spec.y, spec.z));
	if (maxspec > 1.0f) {
		spec /= maxspec;
	}
	spec *= specular;
#ifdef VS_OUT_vertexLightData_nonrm
	if (lightness_amb > lightness_sun_diff) {
		float lightness_spec_old = dot(gamma_correction, spec);
		spec += float3(0.33f, 0.33f, 0.33f);
		spec *= lightness_spec_old / dot(gamma_correction, spec);
	}
#endif
	float lightness_spec = dot(gamma_correction, spec);

/*
#ifndef NO_SHADOWS
  #ifdef PS_SIMPLESHADOW
	s2half shadow = calcShadowSimple(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x);
  #else
	s2half shadow = calcShadow(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x, anzIterations);
  #endif
	sun_diff *= shadow;
#endif
*/
  
  //compose
	float3 diff_spec_composed = lerp(sun_diff, spec, step(lightness_sun_diff, lightness_spec));
	float3 new_color = float3(max(amb.x, diff_spec_composed.x), max(amb.y, diff_spec_composed.y), max(amb.z, diff_spec_composed.z)); 

  // calc fog
#ifdef S2_FOG
    fogDiffuse( new_color, fog_texture, I.depthFog, fog_color );
#endif

  // calc only diffuse
	O.col[0].xyz = new_color;
	O.col[0].a = tex0.a;
#if TREE_HOLE
	O.col[0].a = calcHoleAlpha(I.hpos,param);
#endif  
	O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
#ifdef SIMPLECOLOR
	O.col[0] = tex0;
	O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
#endif
	return O;
  } 
#endif


/////////////////////////////////////////////////
//SPASS_PNT pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_SPASS_PNT_NONORMAL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 pix_to_li   : TEXCOORD1;
    float4 normal      : TEXCOORD2;
    float4 hpos        : TEXCOORD3;
    float2 depthFog    : TEXCOORD4;
  };
  #define VS_OUT_hposition
  #define VS_OUT_pix_to_li
  #define VS_OUT_NORMAL
  #define VS_OUT_hpos
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D fog_texture,
      uniform float4 light_col_diff,
      uniform float4 light_data,
      uniform float4    param)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);

	  // get normal vector from bumpmap texture
	  s2half3 nrm = normalize(I.normal.xyz);

	  // calc diffuse
	  s2half3 l0_dir = normalize(I.pix_to_li.xyz);
	  float4 diffuse = saturate(dot(l0_dir, nrm)) * light_col_diff;

	  // calc distance of light
	  float dist_to_light = dot(I.pix_to_li.xyz, I.pix_to_li.xyz);
	  // build intensity from distance to light using light radius
	  float temp_dist = saturate(dist_to_light  * light_data.z * light_data.z);
	  float intensity = (1.0 - temp_dist) * (1.0 - temp_dist); // 1.0 - sin(1.5708 * temp_dist);
	  // multiply it by intensity of ight source
	  intensity *= light_data.y;
  #ifdef S2_FOG
    // attenuate by fog
    fogPnt( intensity, fog_texture, I.depthFog );
    //intensity *= (1.0 - tex2D( fog_texture, I.depthFog ).w);
  #endif

  #if TREE_HOLE
	  intensity *= calcHoleAlpha(I.hpos,param);
  #endif
	  O.col[0] = intensity * diffuse * tex0;
	  O.col[0].a = tex0.a;
	  O.col[1] = float4(0.0, 0.0, 0.0, 0.0);

	  return O;
  } 
#endif


/////////////////////////////////////////////////
//PS_SPASS_LIGHTNING pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_SPASS_LIGHTNING_NONORMAL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 lightDist   : TEXCOORD1;
    float2 depthFog    : TEXCOORD2;
  };
  #define VS_OUT_hposition
  #define VS_OUT_lightDist
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D fog_texture,
      uniform float4    light_col_amb,
      uniform float4    system_data)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
  	
	  // calc to-face-lightning
	  float is2Lightning = step(0.2, I.lightDist.w);
  	
	  O.col[0] = float4(is2Lightning * light_col_amb.w * float3(1.0, 1.0, 1.0), tex0.a);
	  O.col[1] = float4(is2Lightning * light_col_amb.w * light_col_amb.xyz, 0.0);

    #ifdef S2_FOG
      // calc fog
      fogGlow( O.col[0].xyz, fog_texture, I.depthFog );
      fogGlow( O.col[1].xyz, fog_texture, I.depthFog );
    #endif

	  return O;
  } 
#endif

/////////////////////////////////////////////////
//PS_DUMMY_11 pixel shader (SM1_1)
/////////////////////////////////////////////////
#ifdef PS_DUMMY_11
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
  };
  #define VS_OUT_hposition

  fragout1 mainPS(pixdata I,
		              uniform sampler2D texture0)
  {
	  fragout1 O;
 	  O.col = tex2D(texture0, I.texcoord.xy);
	  return O;
  } 
#endif
/////////////////////////////////////////////////
//PS_NULL_11 pixel shader (SM1_1)
/////////////////////////////////////////////////
#ifdef PS_NULL_11
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
  };
  #define VS_OUT_hposition

  fragout1 mainPS(pixdata I)
  {
	  fragout1 O;
 	  O.col = float4(0,0,0,0);
	  return O;
  } 
#endif
/////////////////////////////////////////////////
//PS_NULL_20 pixel shader (SM2_0)
/////////////////////////////////////////////////
#ifdef PS_NULL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
  };
  #define VS_OUT_hposition

  fragout2 mainPS(pixdata I)
  {
	  fragout2 O;
 	  O.col[0] = float4(0,0,0,0);
 	  O.col[1] = float4(0,0,0,0);
	  return O;
  } 
#endif


/////////////////////////////////////////////////
//PASS_AMBDIF pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_TRUNK_SPASS_AMBDIF_20
  #define VS_OUT_hposition
  #define VS_OUT_screenCoord
  #define VS_OUT_hpos
  #define VS_OUT_camDist
  #define VS_OUT_lightDist
  #define VS_OUT_posInLight
  #define VS_OUT_depthFog
  #ifdef ENABLE_VERTEXLIGHTING
    #define VS_OUT_vertexLightData
  #endif

  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 camDist     : TEXCOORD1;
    float4 lightDist   : TEXCOORD2;
    float4 screenCoord : TEXCOORD3;
    float4 hpos        : TEXCOORD4;
    float4 posInLight  : TEXCOORD5;
    float2 depthFog    : TEXCOORD6;
    #ifdef VS_OUT_vertexLightData
      float4 vlColor           : COLOR0;
      float4 vlNormal          : TEXCOORD7;
    #endif
  };

  fragout2 mainPS(pixdata I,
                  float2 vPos : VPOS,
                  uniform sampler2D texture0,
                  uniform sampler2D texture1,
                  uniform sampler2D texture2,
                  uniform sampler2D texture3,
                  uniform sampler2D shadow_texture,
                  uniform sampler3D textureVolume,
                  uniform sampler2D fog_texture,
                  uniform sampler2D shadow_map,
                  uniform sampler3D noise_map,
                  uniform float4    shadow_data,
                  uniform float4    fog_color,
                  uniform float4    system_data,
                  uniform float4    light_col_amb,
                  uniform float4    light_col_diff,
                  uniform float4    param)
  {
	  fragout2 O;
  //get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
	  s2half4 tex1 = decode_normal(tex2D(texture1, I.texcoord0.xy));
	  s2half3 nrm  = tex1.xyz;
  //get normal vector from bumpmap texture
//	  s2half4 tex1 = tex2D(texture1, I.texcoord0.xy);
//	  s2half3 nrm = normalize(tex1.xyz - s2half3(0.5, 0.5, 0.5));
	float4 light_hero = light_col_amb;
#ifdef VS_OUT_vertexLightData
	light_hero += light_calc_heroLight(I.vlColor) + light_calc_vertexlighting(nrm,I.vlColor,normalize(I.vlNormal.xyz));
#endif
	light_hero = saturate(light_hero);
	light_hero = light_hero - light_col_amb;

  //get shadow term from shadow texture
#ifdef NO_SHADOWS
	s2half4 shadow = float4(1.0f, 1.0f, 1.0f, 1.0f);
#else  
  #ifdef TREE_HOLE
	s2half4 shadow = calcShadowSimple(shadow_map, textureVolume, I.posInLight, vPos, shadow_data.y, shadow_data.x);
  #else
	s2half4 shadow = tex2Dproj(shadow_texture, I.screenCoord);
  #endif
#endif
/*
	shadow *= (dot(light_hero.xyz, light_hero.xyz) / sqrt(3.0f));
	float newshadow = saturate(shadow.z);
	newshadow = 1.0f - shadow;
	newshadow = pow(shadow, 5);
	newshadow = 1.0f - shadow;
*/
  //lighting setup
	s2half3 l_dir = normalize(I.lightDist.xyz);
	s2half3 c_dir = normalize(I.camDist.xyz);
	float lightValueSun = saturate(dot(l_dir, nrm));
	float lightValueMoon = saturate(dot(c_dir, nrm));
	float3 gamma_correction = float3(0.2126f, 0.7152f, 0.0722f);
	
  //calc moon diffuse
    float3 moon_diff = (light_col_amb.xyz + light_hero.xyz) * tex0.xyz * lightValueMoon;
#ifdef VS_OUT_vertexLightData
    float lightness_old_moon = dot(gamma_correction, moon_diff);
    moon_diff += float3(0.33f, 0.33f, 0.33f);
    moon_diff *= lightness_old_moon / dot(gamma_correction, moon_diff);
#endif
	float lightness_moon_diff = dot(gamma_correction, moon_diff.xyz);
	
  //calc sun diffuse
	float3 sun_diff = shadow.z * light_col_diff.xyz * tex0.xyz * lightValueSun;
	float lightness_sun_diff = dot(gamma_correction, sun_diff.xyz);
	
  //calc specular
	float specular = pow(dot(c_dir, ((2.0 * dot(nrm, l_dir) * nrm) - l_dir)), 10);
	float3 specular_diff = light_col_diff.xyz;
#ifdef VS_OUT_vertexLightData
	float4 addvalue = light_calc_heroLight(I.vlColor) + light_calc_vertexlighting(nrm,I.vlColor,normalize(I.vlNormal.xyz));
	specular_diff += addvalue.xyz;
	specular_diff = saturate(specular_diff);
#endif
    float3 spec = 2.0f * specular_diff.xyz * tex0.xyz;
	float maxspec = max(spec.x, max(spec.y, spec.z));
	if (maxspec > 1.0f) {
		spec /= maxspec;
	}
	spec *= specular;
#ifdef VS_OUT_vertexLightData
	if (lightness_moon_diff > lightness_sun_diff) {
		float lightness_old_spec = dot(gamma_correction, spec);
		spec += float3(0.33f, 0.33f, 0.33f);
		spec *= lightness_old_spec / dot(gamma_correction, spec);
	}
#endif
	float lightness_spec = dot(gamma_correction, spec.xyz);
  
  //compose
	float3 diff_spec_composed = lerp(sun_diff, spec, step(lightness_sun_diff, lightness_spec));
	float3 new_color = float3(max(moon_diff.x, diff_spec_composed.x), max(moon_diff.y, diff_spec_composed.y), max(moon_diff.z, diff_spec_composed.z));

  //TEnergy
    sTEnergy tenergy;
    calc_tenergy(tenergy,noise_map,texture2,texture3,I.texcoord0.xy,-I.texcoord0.y,system_data.x);

  //calc fog
#ifdef S2_FOG
    fogDiffuse( new_color, fog_texture, I.depthFog, fog_color );
#endif

  //set output color
	O.col[0].rgb = new_color;
	O.col[0].a = 1;
#if TREE_HOLE
      O.col[0].a = calcHoleAlpha(I.hpos,param.x);
#endif  
	  O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
	  
#ifdef USE_TENERGY
//    float tescale = pow(tex0.a,3);
    float tescale = tex0.a * tex0.a;
    O.col[0].xyz += tenergy.color0*tescale;
    O.col[1].xyz += tenergy.color1*tescale;
#endif
 
  //calc to-face-lightning
#ifdef SPASS_LIGHTNING
	float is2Lightning = saturate(step(0.2, dot(nrm, I.lightDist.xyz)) + (dot(light_hero.xyz, light_hero.xyz) / sqrt(3.0f)));
	O.col[0] = float4(is2Lightning * light_col_amb.w * float3(1.0, 1.0, 1.0), 1.0);
	O.col[1] = float4(is2Lightning * light_col_amb.w * (light_col_amb.xyz + light_hero.xyz), 0.0);
#endif
#ifdef SIMPLECOLOR
	O.col[0] = float4(1,1,1,1);
#endif

	return O; 
 } 
#endif


/////////////////////////////////////////////////
//PASS_PNT pixel shader (>=SM2_0)
/////////////////////////////////////////////////
#ifdef PS_TRUNK_SPASS_PNT_20
  struct pixdata {
    float4 hposition    : POSITION;
    float4 texcoord0    : TEXCOORD0;
    float4 pix_to_li_t  : TEXCOORD1;
    float4 pix_to_c     : TEXCOORD2;
    float4 pix_to_li_o  : TEXCOORD3;
    float2 depthFog     : TEXCOORD4;
  };
  #define VS_OUT_hposition
  #define VS_OUT_pix_to_li_T
  #define VS_OUT_pix_to_li_O
  #define VS_OUT_PIX_TO_C
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D texture1,
      uniform sampler2D fog_texture,
      uniform float4 light_col_diff,
      uniform float4 light_data)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
	  s2half4 tex1 = tex2D(texture1, I.texcoord0.xy);
	  // get normal vector from bumpmap texture
	  s2half3 nrm = normalize(tex1.xyz - s2half3(0.5, 0.5, 0.5));

	  // calc diffuse
	  s2half3 l0_dir = normalize(I.pix_to_li_t.xyz);
	  float4 diffuse = saturate(dot(l0_dir, nrm)) * light_col_diff;

	  // calc specular
	  s2half3 c_dir = normalize(I.pix_to_c.xyz);
	  s2half3 half_vec = normalize(l0_dir + c_dir);
	  float4 specular =  pow(saturate(dot(half_vec, nrm)), 20.0) * tex1.w * light_col_diff;

	  // calc distance of light
	  float dist_to_light = dot(I.pix_to_li_o.xyz, I.pix_to_li_o.xyz);
	  // build intensity from distance to light using light radius
	  float temp_dist = saturate(dist_to_light  * light_data.z * light_data.z);
	  float intensity = (1.0 - temp_dist) * (1.0 - temp_dist); // 1.0 - sin(1.5708 * temp_dist);
	  // multiply it by intensity of ight source
	  intensity *= light_data.y;
  #ifdef S2_FOG
    // fog
    fogPnt( intensity, fog_texture, I.depthFog );
  #endif

	  O.col[0] = intensity * ((diffuse * tex0) + specular);
	  O.col[0].a = tex0.a;
	  O.col[1] = float4(0.0, 0.0, 0.0, 0.0);
	  return O;
  } 
#endif 



DEFINE_VERTEX_DATA 


////////////////////////////////////////////////////////////////
//Unified Vertex shader used for all shader models
////////////////////////////////////////////////////////////////
pixdata mainVS(appdata I,
               uniform float4   vtx_data_array[32],
               uniform float4x4 vtx_matrix_array[4],
               VS_PARAM_BLOCK)
{
	pixdata O;
	EXTRACT_VERTEX_VALUES

	// apply wind and calc extreme (=1.0) position
	float4 wind_pos4 = mul(pos4, vtx_matrix_array[windidx]);
	// now interpolate between org pos and extr pos
	pos4 = lerp(pos4, wind_pos4, windLerpFact);
	

#ifdef VS_IN_TREELEAFVERTEX
	float leaf_scale = param.z;
	// get vertex billboard offset from array and scale it by size
	float4 offs4 = data2.y * vtx_data_array[data2.x] * leaf_scale;
	// transform this offset backwards with inv objmat, so it is "billboarded" after next transform
	pos4 += mul(offs4, invWorldMatrix);
#endif


  #ifdef VS_OUT_vertexLightData_nonrm
    O.vlColor = computeVertexLightingColor(pos4,nrm4);
  #endif
  #ifdef VS_OUT_vertexLightData
    computeVertexLightingColorNormal( O.vlColor, O.vlNormal,pos4);
  #endif


	// convert vertex pos from objspace to screen space
  float4 wvp_pos = mul(pos4, worldViewProjMatrix);

  float camSpaceZ = pos4.x*worldViewMatrix[0][2] +  
                    pos4.y*worldViewMatrix[1][2] + 
                    pos4.z*worldViewMatrix[2][2] + 
                    worldViewMatrix[3][2];
	// convert vertex pos from objspace to worldspace
	float4 worldVertPos    = mul(pos4, worldMatrix);
	float3 worldVertNormal = normalize(mul(nrm4.xyz, (float3x3) worldMatrix));

	O.texcoord0 = uv0;

#ifdef VS_OUT_depthFog
  O.depthFog = getFogTCs( wvp_pos.w, fog_data );
  //O.depthFog.x = saturate( (wvp_pos.w - fog_data.x) * zfrustum_data.z );
  //O.depthFog.y = fog_data.w;
#endif

#ifdef VS_OUT_hposition
	// vertex pos
	O.hposition = wvp_pos;
#endif

#ifdef VS_OUT_SM1_TEXCOORD1
	O.texcoord1 = uv0;
#endif

#ifdef VS_OUT_depthUV
    O.depthUV = float4(0,0,0,-camSpaceZ*zfrustum_data.w);
#endif
#ifdef VS_OUT_posInLight
	// vertex pos in light-space
	O.posInLight = mul(pos4, lightMatrix);
#endif
#ifdef VS_OUT_li_to_pix_w
	// pass light-to-pixel to fragment shader
	O.li_to_pix_w = worldVertPos - light_pos;
#endif


	// convert light pos from worldspace into objectspace
	float4 l_pos_obj = mul(light_pos, invWorldMatrix);
	// build vector from vertex pos to light pos
	float3 vertex_to_light = l_pos_obj.xyz - pos4.xyz;
	// convert cam pos from worldspace into objectspace
	float4 c_pos_obj = mul(camera_pos, invWorldMatrix);
	// build vector from vertex pos to cam pos
#ifdef MINIMAPMODE
  float3 vertex_to_cam = c_pos_obj;
#else
	float3 vertex_to_cam = c_pos_obj.xyz - pos4.xyz;
#endif
	// convert light direction vector from worldspace to objectspace
	float4 l0_dir_obj = mul(light_pos, invWorldMatrix);
	// convert camera direction vector from worldspace to objectspace
	float4 c_dir_obj = mul(camera_pos, invWorldMatrix);

#ifdef VERT_TREEVERTEX

	// build object-to-tangent space matrix
	float3x3 objToTangentSpace;
	objToTangentSpace[0] = -1.0 * tan3;
	objToTangentSpace[1] = -1.0 * bin3;
	objToTangentSpace[2] = nrm4.xyz;

  // convert vertex_to_light from objectspace to tangentspace
  float3 vertex_to_light_tan = mul(objToTangentSpace, vertex_to_light);
	// convert vertex_to_cam from objectspace to tangentspace
	float3 vertex_to_cam_tan = mul(objToTangentSpace, vertex_to_cam);

	// convert light direction vector from objectspace to tangentspace
	float3 l0_dir_tan = mul(objToTangentSpace, l0_dir_obj.xyz);

	// calc direction vector from vertex position to camera-position
	c_dir_obj -= pos4;
	// convert camera direction vector from objectspace to tangentspace
	float3 c_dir_tan = mul(objToTangentSpace, c_dir_obj.xyz);

  #ifdef VS_OUT_lightDist
	  // store light vector
	  O.lightDist = float4(l0_dir_tan, 0.0);
  #endif
  #ifdef VS_OUT_camDist
	// store camera vec in texcoord2
	O.camDist = float4(c_dir_tan, 0.0);
  #endif
#else
  #ifdef VS_OUT_lightDist
	  // store light vector & dot
	  O.lightDist = float4(l0_dir_obj.xyz, dot(nrm4.xyz, l0_dir_obj.xyz));
  #endif
  #ifdef VS_OUT_camDist
	// store camera vec in texcoord2
	O.camDist = float4(c_dir_obj.xyz, dot(nrm4.xyz, c_dir_obj.xyz));
  #endif
#endif 

//ONLY USE IF VS_OUT_camDist AND VS_OUT_lightDist AND VS_OUT_NORMAL
//#ifdef VS_OUT_specular
//	float specvalue = pow(dot(normalize(O.camDist.xyz), ((2.0 * dot(normalize(O.normal.xyz), normalize(O.lightDist.xyz)) * normalize(O.normal.xyz)) - normalize(O.lightDist.xyz))), 20);
//	O.specular = float4(specvalue, 0.0, 0.0, 0.0);
//#endif

  #ifdef VS_OUT_vertexLightData
    O.vlNormal.xyz = mul(objToTangentSpace, O.vlNormal.xyz);
  #endif



#ifdef VS_OUT_hpos
	// pass screenpos to fragment shader
	O.hpos     = O.hposition;
	O.hpos.xy *= param.xy;
#endif

#ifdef VS_OUT_NORMAL
	// norma
	O.normal = nrm4;
#endif

#ifdef VS_OUT_screenCoord
	// vertex-position in screen space
  O.screenCoord = calcScreenToTexCoord(O.hposition);
#endif

#ifdef VS_OUT_SM1_LIGHTING
	O.diffuse = calcLight(worldVertPos, worldVertNormal, camera_pos, globLightData, O.specular);
#endif 
#ifdef VS_OUT_diffuse
	// convert light direction vector from worldspace to objectspace
	float4 l0_dir = mul(light_pos, invWorldMatrix);
	float  diffuse = saturate(dot(nrm4, l0_dir));
	// prepare color
	O.diffuse = float4(diffuse, diffuse, diffuse, 1.0);
#endif 


#ifdef VS_OUT_lowendFog
	O.fog = calcFog(O.hposition, fog_data);
#endif


	// pass vertex to light to pixelshader, so it becomes pixel to light
#ifdef VS_OUT_pix_to_li_T
	O.pix_to_li_t = float4(vertex_to_light_tan, 0.0);
#endif
#ifdef VS_OUT_pix_to_li_O
	O.pix_to_li_o = float4(vertex_to_light, 0.0);
#endif
#ifdef VS_OUT_pix_to_li
	// pass vertex to light to pixelshader, so it becomes pixel to light
	O.pix_to_li = float4(vertex_to_light, 0.0);
#endif
#ifdef VS_OUT_PIX_TO_C
	// pass vertex to cam to pixelshader, so it becomes pixel to cam
	O.pix_to_c = float4(vertex_to_cam_tan, 0.0);
#endif

	return O;
}

 

 

Link to comment
  • 9 months later...
On 7/23/2022 at 2:42 AM, Lindor said:

I have taken another thought on this. When balancing light_col_amb (moonlight) and light_col_diff (daylight, also magiclight/streetlight etc.) can take values between 0 and 1. We want to balance it so the result is also between 0 and 1. What I've done above is just adding them. Not a problem per se, the game automatically caps color at 1.

The plot would look like this (x and y are moon- and sunlight values):
YI1x122.gif
Not the best. Might become too bright too quickliy.

The intuitive solution would be to go with average instead:
wCxNW7f.gif
The issue is: at day, moon is 0 and sun is 1 and vice versa, so we's never really get to 1.

The next best solution would be to go with max of day and sun:
PssYCHP.gif
Not bad., but we have that wierd sharp edge. Light transition wouldn't feel smooth.

Is there a function which is smooth is always x if x=y, always x if y=0 and always y if x=0? Yes there is. Some math magic including orthogonal projection later and we have this:
IFjewlj.gif
This is what we wanted! Formula: ((x^2)+(y^2))/(x+y)

So you should use this code instead:

  Reveal hidden contents
#ifdef PS_SPASS_LIGHTNING_NONORMAL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 lightDist   : TEXCOORD1;
    float2 depthFog    : TEXCOORD2;
  };
  #define VS_OUT_hposition
  #define VS_OUT_lightDist
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D fog_texture,
      uniform float4    light_col_amb,
      uniform float4    light_col_diff,
      uniform float4    system_data)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
  	
	  // calc to-face-lightning
	  float is2Lightning = step(0.2, I.lightDist.w);
	  float lightAlpha = (light_col_amb.w * light_col_amb.w + light_col_diff.w * light_col_diff.w) / (light_col_amb.w + light_col_diff.w);
	  float normalize = sqrt(dot(light_col_amb.xyz + light_col_diff.xyz, light_col_amb.xyz + light_col_diff.xyz));
	  float lengthAmb = sqrt(dot(light_col_amb.xyz, light_col_amb.xyz));
	  float lengthDiff = sqrt(dot(light_col_diff.xyz, light_col_diff.xyz));
	  float lengthFinal = (lengthAmb * lengthAmb + lengthDiff * lengthDiff) / (lengthAmb + lengthDiff);
  	
	  O.col[0] = float4(is2Lightning * lightAlpha * float3(1.0, 1.0, 1.0), tex0.a);
	  O.col[1] = float4(is2Lightning * lightAlpha * (lengthFinal / normalize) * (light_col_amb.xyz + light_col_diff.xyz), 0.0);

    #ifdef S2_FOG
      // calc fog
      fogGlow( O.col[0].xyz, fog_texture, I.depthFog );
      fogGlow( O.col[1].xyz, fog_texture, I.depthFog );
    #endif

	  return O;
  } 
#endif

 

It's done here for the whole vector though, and the length can be more than 1 (it can be sqrt(3)). Another option would be doing it component-wise, not for the whole vector:

  Reveal hidden contents
#ifdef PS_SPASS_LIGHTNING_NONORMAL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 lightDist   : TEXCOORD1;
    float2 depthFog    : TEXCOORD2;
  };
  #define VS_OUT_hposition
  #define VS_OUT_lightDist
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D fog_texture,
      uniform float4    light_col_amb,
      uniform float4    light_col_diff,
      uniform float4    system_data)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
  	
	  // calc to-face-lightning
	  float is2Lightning = step(0.2, I.lightDist.w);
	  float lightAlpha = (light_col_amb.w * light_col_amb.w + light_col_diff.w * light_col_diff.w) / (light_col_amb.w + light_col_diff.w);
	  float lightRed = (light_col_amb.x * light_col_amb.x + light_col_diff.x * light_col_diff.x) / (light_col_amb.x + light_col_diff.x);
	  float lightGreen = (light_col_amb.y * light_col_amb.y + light_col_diff.y * light_col_diff.y) / (light_col_amb.y + light_col_diff.y);
	  float lightBlue = (light_col_amb.z * light_col_amb.z + light_col_diff.z * light_col_diff.z) / (light_col_amb.z + light_col_diff.z);
  	
	  O.col[0] = float4(is2Lightning * lightAlpha * float3(1.0, 1.0, 1.0), tex0.a);
	  O.col[1] = float4(is2Lightning * lightAlpha * float3(lightRed, lightGreen, lightBlue), 0.0);

    #ifdef S2_FOG
      // calc fog
      fogGlow( O.col[0].xyz, fog_texture, I.depthFog );
      fogGlow( O.col[1].xyz, fog_texture, I.depthFog );
    #endif

	  return O;
  } 
#endif

 

I think this is the better option, both aesthetics- and calculationcost-wise.

I have thought of another function:

Download.gif.68306d227481e908e3aceea351cfba94.gif

f(x, y) = x-xy+y

Just that at x=y, it isn't f(x) = x, it's f(x) = x(2-x)

Still kinda cool, though.

Link to comment
  • 8 months later...
On 7/23/2022 at 2:42 AM, Lindor said:

I have taken another thought on this. When balancing light_col_amb (moonlight) and light_col_diff (daylight, also magiclight/streetlight etc.) can take values between 0 and 1. We want to balance it so the result is also between 0 and 1. What I've done above is just adding them. Not a problem per se, the game automatically caps color at 1.

The plot would look like this (x and y are moon- and sunlight values):
YI1x122.gif
Not the best. Might become too bright too quickliy.

The intuitive solution would be to go with average instead:
wCxNW7f.gif
The issue is: at day, moon is 0 and sun is 1 and vice versa, so we's never really get to 1.

The next best solution would be to go with max of day and sun:
PssYCHP.gif
Not bad., but we have that wierd sharp edge. Light transition wouldn't feel smooth.

Is there a function which is smooth is always x if x=y, always x if y=0 and always y if x=0? Yes there is. Some math magic including orthogonal projection later and we have this:
IFjewlj.gif
This is what we wanted! Formula: ((x^2)+(y^2))/(x+y)

So you should use this code instead:

  Reveal hidden contents
#ifdef PS_SPASS_LIGHTNING_NONORMAL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 lightDist   : TEXCOORD1;
    float2 depthFog    : TEXCOORD2;
  };
  #define VS_OUT_hposition
  #define VS_OUT_lightDist
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D fog_texture,
      uniform float4    light_col_amb,
      uniform float4    light_col_diff,
      uniform float4    system_data)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
  	
	  // calc to-face-lightning
	  float is2Lightning = step(0.2, I.lightDist.w);
	  float lightAlpha = (light_col_amb.w * light_col_amb.w + light_col_diff.w * light_col_diff.w) / (light_col_amb.w + light_col_diff.w);
	  float normalize = sqrt(dot(light_col_amb.xyz + light_col_diff.xyz, light_col_amb.xyz + light_col_diff.xyz));
	  float lengthAmb = sqrt(dot(light_col_amb.xyz, light_col_amb.xyz));
	  float lengthDiff = sqrt(dot(light_col_diff.xyz, light_col_diff.xyz));
	  float lengthFinal = (lengthAmb * lengthAmb + lengthDiff * lengthDiff) / (lengthAmb + lengthDiff);
  	
	  O.col[0] = float4(is2Lightning * lightAlpha * float3(1.0, 1.0, 1.0), tex0.a);
	  O.col[1] = float4(is2Lightning * lightAlpha * (lengthFinal / normalize) * (light_col_amb.xyz + light_col_diff.xyz), 0.0);

    #ifdef S2_FOG
      // calc fog
      fogGlow( O.col[0].xyz, fog_texture, I.depthFog );
      fogGlow( O.col[1].xyz, fog_texture, I.depthFog );
    #endif

	  return O;
  } 
#endif

 

It's done here for the whole vector though, and the length can be more than 1 (it can be sqrt(3)). Another option would be doing it component-wise, not for the whole vector:

  Reveal hidden contents
#ifdef PS_SPASS_LIGHTNING_NONORMAL_20
  struct pixdata {
    float4 hposition   : POSITION;
    float4 texcoord0   : TEXCOORD0;
    float4 lightDist   : TEXCOORD1;
    float2 depthFog    : TEXCOORD2;
  };
  #define VS_OUT_hposition
  #define VS_OUT_lightDist
  #define VS_OUT_depthFog

  fragout2 mainPS(pixdata I,
      uniform sampler2D texture0,
      uniform sampler2D fog_texture,
      uniform float4    light_col_amb,
      uniform float4    light_col_diff,
      uniform float4    system_data)
  {
	  fragout2 O;

	  // get texture values
	  s2half4 tex0 = tex2D(texture0, I.texcoord0.xy);
  	
	  // calc to-face-lightning
	  float is2Lightning = step(0.2, I.lightDist.w);
	  float lightAlpha = (light_col_amb.w * light_col_amb.w + light_col_diff.w * light_col_diff.w) / (light_col_amb.w + light_col_diff.w);
	  float lightRed = (light_col_amb.x * light_col_amb.x + light_col_diff.x * light_col_diff.x) / (light_col_amb.x + light_col_diff.x);
	  float lightGreen = (light_col_amb.y * light_col_amb.y + light_col_diff.y * light_col_diff.y) / (light_col_amb.y + light_col_diff.y);
	  float lightBlue = (light_col_amb.z * light_col_amb.z + light_col_diff.z * light_col_diff.z) / (light_col_amb.z + light_col_diff.z);
  	
	  O.col[0] = float4(is2Lightning * lightAlpha * float3(1.0, 1.0, 1.0), tex0.a);
	  O.col[1] = float4(is2Lightning * lightAlpha * float3(lightRed, lightGreen, lightBlue), 0.0);

    #ifdef S2_FOG
      // calc fog
      fogGlow( O.col[0].xyz, fog_texture, I.depthFog );
      fogGlow( O.col[1].xyz, fog_texture, I.depthFog );
    #endif

	  return O;
  } 
#endif

 

I think this is the better option, both aesthetics- and calculationcost-wise.

 

On 5/19/2023 at 11:46 PM, Lindor said:

I have thought of another function:

Download.gif.68306d227481e908e3aceea351cfba94.gif

f(x, y) = x-xy+y

Just that at x=y, it isn't f(x) = x, it's f(x) = x(2-x)

Still kinda cool, though.

I have finally found what I was looking for and it is beautiful :)

finally.PNG.f492cd533c9073039b21f3e447337e29.PNG

f(x, y) = ((x^2)(y-1)+(y^2)(x-1))/(2xy-x-y)

Has all the properties wanted:
=> f(x, x) = x
=> f(0, y) = y
=> f(x, 0) = x
=> f(1, y) = 1
=> f(x, 1) = 1
=> f(1, 1) = 1
=> f(0, 0) = 0 (in the limit from the positive side)

Link to comment

If we limit the highest exponent to 2 and say we want the function to be a fraction of two polynomials, this is the entire set of all the functions which satisfy the wanted properties:

Numerator:      c * (x^2 - 2 * x^2 * y^2 + y^2) - 2 * x^2 * y^2 + x^2 * y + y^2 * x
/
Denominator:   c * (x + y - x^2 * y - y^2 * x) - x^2 * y - y^2 * x - 2 * x * y

 

The one I posted above is for c = -1

It also works for the limit as c goes to infinity

 

After all this, it's funny because I still think just taking the max is best. It's the best compromise between calculation intensity and beauty. If you don't care about complexity, I think a value of c = -0.5 would probably look best.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...
Please Sign In or Sign Up