Vishanka 236 Posted July 25, 2022 Share Posted July 25, 2022 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 Link to comment
Lindor 438 Posted July 25, 2022 Author Share Posted July 25, 2022 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
Vishanka 236 Posted July 25, 2022 Share Posted July 25, 2022 (edited) 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 Edited July 25, 2022 by Vishanka Link to comment
Lindor 438 Posted July 25, 2022 Author Share Posted July 25, 2022 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: 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 Link to comment
Vishanka 236 Posted July 25, 2022 Share Posted July 25, 2022 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: 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 original: Link to comment
Lindor 438 Posted July 25, 2022 Author Share Posted July 25, 2022 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 original: 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
Vishanka 236 Posted July 25, 2022 Share Posted July 25, 2022 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
Lindor 438 Posted July 25, 2022 Author Share Posted July 25, 2022 sry I need some time here, but I'm working on it Link to comment
Lindor 438 Posted July 26, 2022 Author Share Posted July 26, 2022 (edited) 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 July 26, 2022 by Lindor Link to comment
Vishanka 236 Posted July 26, 2022 Share Posted July 26, 2022 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. 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. 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
Lindor 438 Posted July 26, 2022 Author Share Posted July 26, 2022 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
Vishanka 236 Posted July 26, 2022 Share Posted July 26, 2022 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
Lindor 438 Posted July 26, 2022 Author Share Posted July 26, 2022 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
Lindor 438 Posted July 26, 2022 Author Share Posted July 26, 2022 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
Vishanka 236 Posted July 26, 2022 Share Posted July 26, 2022 24 minutes ago, Lindor said: maybe it's hair.shader. Yes, tested it, that one changes stuff Link to comment
Lindor 438 Posted July 26, 2022 Author Share Posted July 26, 2022 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: 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: 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
Lindor 438 Posted May 19, 2023 Author Share Posted May 19, 2023 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): Not the best. Might become too bright too quickliy. The intuitive solution would be to go with average instead: 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: 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: 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: 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
Lindor 438 Posted February 10 Author Share Posted February 10 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): Not the best. Might become too bright too quickliy. The intuitive solution would be to go with average instead: 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: 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: 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: 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 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
Lindor 438 Posted February 11 Author Share Posted February 11 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
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now