Lindor 438 Posted February 22, 2022 Share Posted February 22, 2022 (edited) Search the texture and surface.txt entry change them load ingame or into grannyviewer it looks completely different from what you expected repeat from step 2 This is no fun. No wonder I make no progress with my mod. Scripting is just so much more fun and result-yielding. I'm just searching for excuses to not work on my textures. I wish there was a way to directly edit the surface at the model. I want to see how it looks ingame WHILE I'm retexturing. Including everything surface.txt does with the flags and shaders. Is it possibe? Can you help me with that? Do I really have to go to dirty untrustworthy websites to get a more or less legal version of 3ds max 8? I don't want to do that. And buying? Haha no. Even if I had the money. Not in a million years will I spend that much money on a 3d modelling software while blender exists just because companies these days didn't like modders. Why does this crypto-like format even exist? Who thought that would be a good idea? Pls help. Edited June 2, 2022 by Lindor Link to comment
Popular Post Flix 5,116 Posted February 22, 2022 Popular Post Share Posted February 22, 2022 I don't know of any shortcut to learning texture artwork. It takes time and patience to learn how saturation and hue will translate when rendered, not to mention the dramatic effects that the sg maps can have. With my very first projects it took dozens of iterations before I was able to make something that looked decent in-game. I turned the first design into the second: But not shown is the days and days of everything attempted in between: And even this final result feels so amateurish to me nowadays that I recreated it from scratch recently, and it took perhaps one afternoon session: 1 1 Link to comment
Lindor 438 Posted February 23, 2022 Author Share Posted February 23, 2022 (edited) 49 minutes ago, Flix said: It takes time and patience to learn how saturation and hue will translate when rendered, not to mention the dramatic effects that the sg maps can have. Is there even something to learn? To me, it feels like utter chaos. I always thought that I'm not a visual artist, by any means. I can't draw. The best pictures I've ever created are the thumbnails of my Skyrim mods, there I learned that even I can do visual art. But Sacred 2 simply does not want to cooperate. I don't feel like it's on me, I feel like the standard way of doing it is just not good. The cycle I described above: it's not fun, you can't see the effect your editing has ingame until it's too late, sometimes the 2d mapping to the 3d model is SO CHAOTIC (-> Deylen helmet) and there's absolutely no learning effect. I want to edit the texture at the model directly. This would make sense. Right now it's just a guessing game. 49 minutes ago, Flix said: And even this final result feels so amateurish to me nowadays that I recreated it from scratch recently, and it took perhaps one afternoon session: Honestly? I like the left one much more, it's not even close. Right just looks like something taken straight out of the Borderlands game. Textile and leather are supposed to be irregular and a little bit dirty. But I guess it's taste in the end. Edited February 23, 2022 by Lindor 1 Link to comment
Popular Post Flix 5,116 Posted February 23, 2022 Popular Post Share Posted February 23, 2022 What you're perceiving as a dirty look are hundreds of pixel artifacts from the absolutely hamfisted way I was darkening individual colors instead of entire areas, and then repeatedly saving the file with compression before opening & editing it again after each failed attempt, like a JPG growing increasingly more grainy and jagged with each successive save. It's dumb, boneheaded luck on my part that people looked at that and saw dirt when I was going for the image on the right the entire time. I guess there's a tip for you if you want a dirty look. 2 Link to comment
Lindor 438 Posted February 23, 2022 Author Share Posted February 23, 2022 Now here's an issue I have: I'm somewhat fascinated by starry textures On 1/18/2022 at 3:21 AM, Lindor said: Inspiration were the Diablo 3 Galactic Wings, that's also why I chose the green fad-in. But I'm thinking about making them purple Cosmic Wngs: Galactic Wings: You see, there's a really cool rendering effect happening while moving with these Wings, it really feels like an open gate to space and cosmos. THIS is what I envision. I think the closest Sacred 2 has is the crystal shader, not sure, nevertheless I tried and you all know the results: It doesn't work. And that is the best I could come up with amongst hundreds if not thousands of different versions. Absolutely horrible. But you see, I'm not the only one with that problem though. Sopor Aethernis e.g. is supposed to be starry as well. It actually looks kinda OK-ish in the character menu: However that doesn't tell the real story. Look at this leg: What is this? Absolutely no depth. Flat, flubbery and distorted! Where is the depth effect we desire? It looks like colorized pantyhose tights. The real Problem is triggering the different shader effects. The fx7 shader e.g. only works on somewhat smooth gradients. The crystal effect is controlled by the glow map, but it only works for big enough "sections" again. Space however is made of hundreds of layers of super small stars, it is not possible to divide it into different big sections unless you have a very small amount of very large stars. I wish there was a way to lay multiple surfaces on the same part of the same model, then we could have the dark blue background space controlled by the fx7 shader, some nebulas in a surface in front and then multiple surfaces of stars with crystal shader in front. But I'm not even sure if that would work. The shaders are simply suuuper sensitive to the colors. One pixel off, and the whole shader stops working. The best example is the lava shader, I'm still trying to figure out how to properly use that without the whole thing just becoming outright red. And I haven't even talked aout the biggest problem yet: The mapping of the the Deylen helmet is an absolute nightmare, and all the other pieces aren't easy to figure out either. I feel absolutely cursed here, not being able to retexture directly at the model and instead guessing where each section is... it's not good. The thing is that the game does not let me freely do what I envision. It puts limit after limit. There are people who think limiting options would enhance creativity. I don't. It's so bad that I'm actually thinking that this right here: 17 hours ago, dimitrius154 said: That would require to completely rewrite and recompile s2render.dll. would be more result yielding AND quicker than to work with what we got, even though it would take forever. There is one last hope I have, which is doing something similar to what has been done to blueprint.txt: A thread where the leading post explains in detail what each shader and flag in surface.txt is doing including their limitations, the information comes from people sharing their knowledge in the thread. Link to comment
dimitrius154 612 Posted February 23, 2022 Share Posted February 23, 2022 3 minutes ago, Lindor said: the crystal shader, not sure, nevertheless I tried and you all know the results Hmm, try decreasing opacity via lowering the diffuse texture's alpha channel brightness. 1 Link to comment
Vishanka 236 Posted February 23, 2022 Share Posted February 23, 2022 53 minutes ago, Lindor said: Flat, flubbery and distorted! Where is the depth effect we desire? It looks like colorized pantyhose tights. The ugliness of the Communitypatch Sets is the main reason I never wanted to play it. Maybe as a start you could change the _sg files to add some glow to the stars on the... leggings. That should make the stars look a bit less like someone took a space google image and pasted it on it as the new texture. Link to comment
Flix 5,116 Posted February 23, 2022 Share Posted February 23, 2022 1 hour ago, Lindor said: The best example is the lava shader, I'm still trying to figure out how to properly use that without the whole thing just becoming outright red. For the lava shader you can use any texture you want as the texture3Name. That's why EE has blight, eldritch, bloodlust, and ghostly in the hq/fx folder (this was Dmitriy's idea). You could sub in something else entirely. You might have some luck getting the illusion of movement that way. The more opaque the alpha channel in the sg map, the more intense the lava effect. This also supersedes/diminishes the emissive glow however. Link to comment
Lindor 438 Posted February 24, 2022 Author Share Posted February 24, 2022 2 hours ago, dimitrius154 said: Hmm, try decreasing opacity via lowering the diffuse texture's alpha channel brightness. Well it seemed to have potential when I tried it with my original design, although it didn't help with the glow map, at least the diffuse map now got the same effect you can see on the spider armor. I tried following this cool tutorial and combining it with your tip: It doesn't want to work, the picture looks beautiful, but always something goes wrong no matter how I choose the glow/diffuse maps, one always steals the show. 1 hour ago, Vishanka said: The ugliness of the Communitypatch Sets is the main reason I never wanted to play it. Maybe as a start you could change the _sg files to add some glow to the stars on the... leggings. That should make the stars look a bit less like someone took a space google image and pasted it on it as the new texture. Agreed! It's on my, uhm, five sites long to-do-list on my desktop. Which has been sitting there for years, not stopping to grow. But CM has also some nice looking stuff to offer, the nine hells set e.g. looks pretty decent imho. Or the HE mutation set, but credits there go to the original devs, CM simply unlocked it AFAIK. 1 hour ago, Flix said: The more opaque the alpha channel in the sg map, the more intense the lava effect. This also supersedes/diminishes the emissive glow however. Aaaah. Thx for the info Flix, will be added to the surface.txt thread Link to comment
dimitrius154 612 Posted February 24, 2022 Share Posted February 24, 2022 4 hours ago, Lindor said: .Thx for the info Flix, will be added to the surface.txt thread Therefore, it's the diffuse + specular glow. To be expected. Also, some buff special effects add to the confusion. Then again, one should remember, that the game's engine is effectively older, then the first Mass Effect. Link to comment
Lindor 438 Posted March 15, 2022 Author Share Posted March 15, 2022 The effect of the scorpion shield/nature magic dryad buff, FX_SC_SCHILD, looks like something promising. Now this is a visual effect and not a surface, but it looks like surface functions could maybe be used by these fx. If they're pointing to a specific surface.txt shader and/or flags in s2render.dll, that would be great. Unfortunately, these fx don't have a particle script. Interesting files are: pak/graphics25/hq/fx/skorpionshield.dds pak/graphics13/hq/fx/skorpionshield.dds pak/graphics01/hq/fx/skorpionshield2.dds pak/graphics01/hq/fx/skorpionshield.dds None of which are mentioned anywhere in surface.txt, unfortunately. So in the end what's left is searching the dlls with ollydbg for any mentions of these fx and it's files, and I'm really bad this. I'm afraid to ask this, but can someone do a little search for me, please? But do not waste your time if it takes too long, in the end it's just a hope, a suspicion. There's no evidence whatsoever that the fx use a surface.txt shader/flags other than the way it works and looks ingame. Link to comment
Lindor 438 Posted April 13, 2022 Author Share Posted April 13, 2022 Info: It is possible to script your own shader at the beginning of the file! I'm getting closer. Somewhat. Look only at the torsoes. Left uses fx6, middle uses crystal and right uses a custom shader: XXXXX = { diffusePnt = "object/diffVelvetPnt.shader", diffusePntShd = "object/diffVelvetPnt.shader", z = "object/z.shader", shadowmap = "object/shadowMap.shader", cubeshadowmap = "object/cubeShadowMap.shader", ambDiff = "object/ambDiffPulse.shader", } It is super hard, but I'm getting there. Slowly. 1 Link to comment
Lindor 438 Posted June 2, 2022 Author Share Posted June 2, 2022 (edited) I have learned how the original Inquisitor's Astute Supremacy Set's shader's refletion works. It's using a technique called "Skyboxing". The Skybox is not dependent on the textures you input! This is how the skybox looks mapped at the creatures without any additional calculations done: The Skybox is calculated around the player character (more accurately: the camera's view center) and NOT the object! This is why you can't use it on characters with energy shields or it'll look like this: Also underwater is wierd: It gets black as well, however if you're making a screenshot for a split second it goes back to normal: I was able to trick the system however, this is how it actually looks: And here are some more screenshots: Kinda metallic isn't it? I still have no idea why the fx7 shader only works on smooth gradient-like textures, but I can assure you it's not the reflection effect! It has to do smth with the texcoords I think. Edited June 2, 2022 by Lindor Link to comment
Popular Post Lindor 438 Posted June 9, 2022 Author Popular Post Share Posted June 9, 2022 Ladies and gentleman, I did it! I managed to transform the texcoords into screen space and made it so that it resizes with the camera distance. So the textures are now independent of the model, there's no mapping anymor. Which is exactly the effect of D3's Cosmic/Galactic Wings I desire so much. Trust me, it was an insane amount of work! I've taken the wobbly effect from the fx6 shader e.g. used for the Saraki's path to the netherworld set, glow is dependent on the wobbly texture's brightness so that the stars light up when they're hit by the wobbly area. This is how it looks in the main menu: And this ingame: A little bit pixelish and sped up due to the GIF conversion process, but I hope you get the idea. Ideally this isn't the final version since I want to make it a little bit brighter first, but I don't know how possible that is without destroying everything. @VishankaIf I remember correctly, you were interested into this as well. What do you think? To anyone interested, this is my code: Spoiler // ambient #include "extractvalues.shader" #define LIGHTBLOCKS 4 struct appdata { float3 position : POSITION; float3 normal : NORMAL; float3 tangent : TANGENT; float3 binormal : BINORMAL; float2 texcoord : TEXCOORD0; float2 data : TEXCOORD1; }; struct pixdata { float4 hposition : POSITION; float4 texcoord0 : TEXCOORD0; float4 texcoord1 : TEXCOORD1; float4 surfNrm_ws : TEXCOORD2; float4 lightNrm_ws : TEXCOORD3; float4 camDist_ws : TEXCOORD4; float4 screenCoord : TEXCOORD5; }; #ifdef SM1_1 struct fragout { float4 col : COLOR; }; #else struct fragout { float4 col[2] : COLOR; }; #endif pixdata mainVS(appdata I, uniform float4x4 worldViewProjMatrix, uniform float4x4 worldMatrix, uniform float4 target_data, uniform float4 light_pos, uniform float4 camera_pos) { pixdata O; // vertex pos float4 pos4 = float4(I.position.xyz, 1.0); float4 nrm4 = float4(I.normal, 0.0); O.hposition = mul(pos4, worldViewProjMatrix); // lighting O.surfNrm_ws = mul(nrm4, worldMatrix); O.lightNrm_ws = normalize(light_pos); O.camDist_ws = camera_pos - mul(pos4, worldMatrix); float c_dist_ws = sqrt(dot(O.camDist_ws.xyz, O.camDist_ws.xyz)); // pass texture coords //O.texcoord0 = mul(float4(I.texcoord.xy, 1.0, 1.0), worldViewProjMatrix); //O.texcoord0 = mul(float4(I.data.xy - I.texcoord.xy, 1.0, 1.0), worldViewProjMatrix); float4 halfway = calcScreenToTexCoord(O.hposition); O.screenCoord = halfway; float resolution = 0.05 * c_dist_ws; O.texcoord0 = float4(((halfway.x / halfway.w) - 0.5) * resolution, ((halfway.y / halfway.w) - 0.5) * resolution, halfway.z * resolution, halfway.w * resolution); O.texcoord1 = float4(I.texcoord.xy, 1.0, 1.0); return O; } fragout mainPS(pixdata I, uniform sampler2D texture0, uniform sampler2D texture1, uniform sampler2D texture2, uniform sampler2D shadow_texture, uniform samplerCUBE textureCube, uniform float4 system_data) { fragout O; #ifdef SM1_1 s2half4 tex0 = tex2D(texture0, I.texcoord0.xy); O.col = float4(tex0.xyz, 1.0); #else float time = system_data.x; s2half4 tex0 = tex2D(texture0, I.texcoord0.xy); s2half4 shadow = tex2Dproj(shadow_texture, I.screenCoord); /* //calc reflection and glow s2half3 c_dir_ws = normalize(I.camDist_ws.xyz); s2half3 nrm_wrld = normalize(I.surfNrm_ws.xyz); float4 reflection = texCUBE(textureCube, reflect(-c_dir_ws, nrm_wrld)); float4 final_glow = tex0 * reflection; float glow_alpha = dot(final_glow.xyz, final_glow.xyz); */ //calc fx6's wobbly effect float4 sum_color = float4(0.0, 0.0, 0.0, 0.0); float I = 0, sum_num = 6; for(I = 0; I < sum_num; I++) { float2 offsetUV = I.texcoord0.xy / 7.0; offsetUV.y += frac(0.55 + 0.45 * I * time / sum_num + 0.15 + I / sum_num); s2half4 wave_offset = tex2D(texture2, offsetUV); float h_offs = (I / sum_num) + (0.1 + 0.03 * I / sum_num) * (wave_offset.x - 0.5); offsetUV = I.texcoord0.xy / 7.0; wave_offset = tex2D(texture2, offsetUV); float v_offs = (0.3 * I / sum_num) * wave_offset.z * (wave_offset.y - 0.5); // calc lookup float2 newUV = I.texcoord0.xy / 7.0; newUV += float2(h_offs, v_offs); // fx base color s2half4 base_color = tex2D(texture1, newUV); base_color = pow(base_color, 1.0 + 2.0 * wave_offset.x + 2.0 * wave_offset.y); sum_color += base_color; } sum_color /= sum_num; float lerpval = 0.5 + ((dot(tex0.xyz, tex0.xyz) - dot(sum_color.xyz, sum_color.xyz)) / 6.0); float4 final_col = lerp(sum_color, tex0, lerpval); float glow_alpha = saturate(dot(final_col.xyz, final_col.xyz) + 20.0 * dot(sum_color.xyz, sum_color.xyz)); float4 final_glow = final_col * glow_alpha; O.col[0] = float4(final_col.xyz, 1.0); //O.col[1] = float4(0.0, 0.0, 0.0, 0.0); O.col[1] = float4(final_glow.xyz, glow_alpha); #endif return O; } It's a little bit messy, not all leftovers are cleaned and it misses commentary, but there's not a single unnecessary line of actual code, it's pretty much good to go. Just hard to understand. 1 1 Link to comment
Popular Post Flix 5,116 Posted June 9, 2022 Popular Post Share Posted June 9, 2022 Damn. It's like his clothes just ripped a hole in space-time and you're seeing through it. 1 1 Link to comment
Popular Post Dax 481 Posted June 9, 2022 Popular Post Share Posted June 9, 2022 On 6/2/2022 at 3:08 PM, Lindor said: Hehe. The boar has the same facial expression like my dog when he did something wrong. Even the tongue is out a bit! 2 Link to comment
gogoblender 3,070 Posted June 10, 2022 Share Posted June 10, 2022 20 hours ago, Dax said: Hehe. The boar has the same facial expression like my dog when he did something wrong. Even the tongue is out a bit! bull terrier! There is two walked regularly on our street gogo Link to comment
gogoblender 3,070 Posted June 10, 2022 Share Posted June 10, 2022 22 hours ago, Lindor said: Ladies and gentleman, I did it! I managed to transform the texcoords into screen space and made it so that it resizes with the camera distance. So the textures are now independent of the model, there's no mapping anymor. Which is exactly the effect of D3's Cosmic/Galactic Wings I desire so much. Trust me, it was an insane amount of work! I've taken the wobbly effect from the fx6 shader e.g. used for the Saraki's path to the netherworld set, glow is dependent on the wobbly texture's brightness so that the stars light up when they're hit by the wobbly area. This is how it looks in the main menu: And this ingame: A little bit pixelish and sped up due to the GIF conversion process, but I hope you get the idea. Ideally this isn't the final version since I want to make it a little bit brighter first, but I don't know how possible that is without destroying everything. @VishankaIf I remember correctly, you were interested into this as well. What do you think? To anyone interested, this is my code: Reveal hidden contents // ambient #include "extractvalues.shader" #define LIGHTBLOCKS 4 struct appdata { float3 position : POSITION; float3 normal : NORMAL; float3 tangent : TANGENT; float3 binormal : BINORMAL; float2 texcoord : TEXCOORD0; float2 data : TEXCOORD1; }; struct pixdata { float4 hposition : POSITION; float4 texcoord0 : TEXCOORD0; float4 texcoord1 : TEXCOORD1; float4 surfNrm_ws : TEXCOORD2; float4 lightNrm_ws : TEXCOORD3; float4 camDist_ws : TEXCOORD4; float4 screenCoord : TEXCOORD5; }; #ifdef SM1_1 struct fragout { float4 col : COLOR; }; #else struct fragout { float4 col[2] : COLOR; }; #endif pixdata mainVS(appdata I, uniform float4x4 worldViewProjMatrix, uniform float4x4 worldMatrix, uniform float4 target_data, uniform float4 light_pos, uniform float4 camera_pos) { pixdata O; // vertex pos float4 pos4 = float4(I.position.xyz, 1.0); float4 nrm4 = float4(I.normal, 0.0); O.hposition = mul(pos4, worldViewProjMatrix); // lighting O.surfNrm_ws = mul(nrm4, worldMatrix); O.lightNrm_ws = normalize(light_pos); O.camDist_ws = camera_pos - mul(pos4, worldMatrix); float c_dist_ws = sqrt(dot(O.camDist_ws.xyz, O.camDist_ws.xyz)); // pass texture coords //O.texcoord0 = mul(float4(I.texcoord.xy, 1.0, 1.0), worldViewProjMatrix); //O.texcoord0 = mul(float4(I.data.xy - I.texcoord.xy, 1.0, 1.0), worldViewProjMatrix); float4 halfway = calcScreenToTexCoord(O.hposition); O.screenCoord = halfway; float resolution = 0.05 * c_dist_ws; O.texcoord0 = float4(((halfway.x / halfway.w) - 0.5) * resolution, ((halfway.y / halfway.w) - 0.5) * resolution, halfway.z * resolution, halfway.w * resolution); O.texcoord1 = float4(I.texcoord.xy, 1.0, 1.0); return O; } fragout mainPS(pixdata I, uniform sampler2D texture0, uniform sampler2D texture1, uniform sampler2D texture2, uniform sampler2D shadow_texture, uniform samplerCUBE textureCube, uniform float4 system_data) { fragout O; #ifdef SM1_1 s2half4 tex0 = tex2D(texture0, I.texcoord0.xy); O.col = float4(tex0.xyz, 1.0); #else float time = system_data.x; s2half4 tex0 = tex2D(texture0, I.texcoord0.xy); s2half4 shadow = tex2Dproj(shadow_texture, I.screenCoord); /* //calc reflection and glow s2half3 c_dir_ws = normalize(I.camDist_ws.xyz); s2half3 nrm_wrld = normalize(I.surfNrm_ws.xyz); float4 reflection = texCUBE(textureCube, reflect(-c_dir_ws, nrm_wrld)); float4 final_glow = tex0 * reflection; float glow_alpha = dot(final_glow.xyz, final_glow.xyz); */ //calc fx6's wobbly effect float4 sum_color = float4(0.0, 0.0, 0.0, 0.0); float I = 0, sum_num = 6; for(I = 0; I < sum_num; I++) { float2 offsetUV = I.texcoord0.xy / 7.0; offsetUV.y += frac(0.55 + 0.45 * I * time / sum_num + 0.15 + I / sum_num); s2half4 wave_offset = tex2D(texture2, offsetUV); float h_offs = (I / sum_num) + (0.1 + 0.03 * I / sum_num) * (wave_offset.x - 0.5); offsetUV = I.texcoord0.xy / 7.0; wave_offset = tex2D(texture2, offsetUV); float v_offs = (0.3 * I / sum_num) * wave_offset.z * (wave_offset.y - 0.5); // calc lookup float2 newUV = I.texcoord0.xy / 7.0; newUV += float2(h_offs, v_offs); // fx base color s2half4 base_color = tex2D(texture1, newUV); base_color = pow(base_color, 1.0 + 2.0 * wave_offset.x + 2.0 * wave_offset.y); sum_color += base_color; } sum_color /= sum_num; float lerpval = 0.5 + ((dot(tex0.xyz, tex0.xyz) - dot(sum_color.xyz, sum_color.xyz)) / 6.0); float4 final_col = lerp(sum_color, tex0, lerpval); float glow_alpha = saturate(dot(final_col.xyz, final_col.xyz) + 20.0 * dot(sum_color.xyz, sum_color.xyz)); float4 final_glow = final_col * glow_alpha; O.col[0] = float4(final_col.xyz, 1.0); //O.col[1] = float4(0.0, 0.0, 0.0, 0.0); O.col[1] = float4(final_glow.xyz, glow_alpha); #endif return O; } It's a little bit messy, not all leftovers are cleaned and it misses commentary, but there's not a single unnecessary line of actual code, it's pretty much good to go. Just hard to understand. beautiful effect with the robes.. and the zoom you pulled off makes it magnetic approach, good drama lindor. gonna show it to Schot, maybe there's also an idea here for default avatars for DarkMatters when new members register? gogo 1 Link to comment
Lindor 438 Posted June 10, 2022 Author Share Posted June 10, 2022 (edited) Final version of the shader. To me it looks like 10x better, but in actuality it's probably like 1% improvement for a whole day of work on it. No GIF today because too much gets lost during conversion process. Shader Code: (now cleaned up and with commentary to make it understandable) Spoiler // ambient #include "extractvalues.shader" #define LIGHTBLOCKS 4 struct appdata { float3 position : POSITION; float3 normal : NORMAL; float3 tangent : TANGENT; float3 binormal : BINORMAL; float2 texcoord : TEXCOORD0; float2 data : TEXCOORD1; }; struct pixdata { float4 hposition : POSITION; float4 texcoord0 : TEXCOORD0; float4 surfNrm_ws : TEXCOORD1; float4 lightNrm_ws : TEXCOORD2; float4 camDist_ws : TEXCOORD3; float4 screenCoord : TEXCOORD4; }; #ifdef SM1_1 struct fragout { float4 col : COLOR; }; #else struct fragout { float4 col[2] : COLOR; }; #endif pixdata mainVS(appdata I, uniform float4x4 worldViewProjMatrix, uniform float4x4 worldMatrix, uniform float4 light_pos, uniform float4 camera_pos) { pixdata O; // vertex pos float4 pos4 = float4(I.position.xyz, 1.0); float4 nrm4 = float4(I.normal, 0.0); O.hposition = mul(pos4, worldViewProjMatrix); // lighting O.surfNrm_ws = mul(nrm4, worldMatrix); O.lightNrm_ws = normalize(light_pos); O.camDist_ws = camera_pos - mul(pos4, worldMatrix); float c_dist_ws = sqrt(dot(O.camDist_ws.xyz, O.camDist_ws.xyz)); // pass texture coords. THIS IS WHERE THE MAGIC HAPPENS! float4 halfway = calcScreenToTexCoord(O.hposition); O.screenCoord = halfway; float resolution = 0.05 * c_dist_ws; O.texcoord0 = float4(((halfway.x / halfway.w) - 0.5) * resolution, ((halfway.y / halfway.w) - 0.5) * resolution, halfway.z * resolution, halfway.w * resolution); return O; } fragout mainPS(pixdata I, uniform sampler2D texture0, uniform sampler2D texture1, uniform sampler2D texture2, uniform sampler2D shadow_texture, uniform samplerCUBE textureCube, uniform float4 system_data) { fragout O; #ifdef SM1_1 s2half4 tex0 = tex2D(texture0, I.texcoord0.xy); O.col = float4(tex0.xyz, 1.0); #else float time = system_data.x; s2half4 tex0 = tex2D(texture0, I.texcoord0.xy); s2half4 shadow = tex2Dproj(shadow_texture, I.screenCoord); //take the wobbly effect from the fx6 shader (it's called "fx6" in surface.txt, but the shader is called "ambDiffFx5.shader") float4 sum_color = float4(0.0, 0.0, 0.0, 0.0); float I = 0, sum_num = 6; for(I = 0; I < sum_num; I++) { float2 offsetUV = I.texcoord0.xy / 7.0; //make it a little bit slower than in fx6 offsetUV.y += frac(0.55 + 0.3375 * I * time / sum_num + 0.15 + I / sum_num); s2half4 wave_offset = tex2D(texture2, offsetUV); float h_offs = (I / sum_num) + (0.1 + 0.03 * I / sum_num) * (wave_offset.x - 0.5); offsetUV = I.texcoord0.xy / 7.0; wave_offset = tex2D(texture2, offsetUV); float v_offs = (0.3 * I / sum_num) * wave_offset.z * (wave_offset.y - 0.5); // calc lookup float2 newUV = I.texcoord0.xy / 7.0; newUV += float2(h_offs, v_offs); // fx base color s2half4 base_color = tex2D(texture1, newUV); base_color = pow(base_color, 1.0 + 2.0 * wave_offset.x + 2.0 * wave_offset.y); sum_color += base_color; } sum_color /= sum_num; //end of fx6's wobbly effect calculation, begin of my own color tweaks for the wobbly texture float brightness_sum_old = sqrt(dot(sum_color.xyz, sum_color.xyz) / 3); // convert rgb into hsl -> set s=1.0 and l=0.5 -> convert back to rgb // trick: HSL colors of kind (hue, 1.0, 0.5) have always one color equal 0.0 and one equal 1.0 in rgb. Just keep the ratios between low, mid and high rgb value constant. if (sum_color.y <= sum_color.z) { if (sum_color.x <= sum_color.y) { float low = sum_color.x; float mid = sum_color.y; float high = sum_color.z; //avoid dividing by 0 mid = low / (1.0001f + low - high); low = 0.0; high = 1.0; sum_color.x = low; sum_color.y = mid; sum_color.z = high; } else { if (sum_color.x <= sum_color.z) { float low = sum_color.y; float mid = sum_color.x; float high = sum_color.z; mid = low / (1.0001f + low - high); low = 0.0; high = 1.0; sum_color.y = low; sum_color.x = mid; sum_color.z = high; } else { float low = sum_color.y; float mid = sum_color.z; float high = sum_color.x; mid = low / (1.0001f + low - high); low = 0.0; high = 1.0; sum_color.y = low; sum_color.z = mid; sum_color.x = high; } } } else { if (sum_color.x <= sum_color.z) { float low = sum_color.x; float mid = sum_color.z; float high = sum_color.y; mid = low / (1.0001f + low - high); low = 0.0; high = 1.0; sum_color.x = low; sum_color.z = mid; sum_color.y = high; } else { if (sum_color.x <= sum_color.y) { float low = sum_color.z; float mid = sum_color.x; float high = sum_color.y; mid = low / (1.0001f + low - high); low = 0.0; high = 1.0; sum_color.z = low; sum_color.x = mid; sum_color.y = high; } else { float low = sum_color.z; float mid = sum_color.y; float high = sum_color.x; mid = low / (1.0001f + low - high); low = 0.0; high = 1.0; sum_color.z = low; sum_color.y = mid; sum_color.x = high; } } } float brightness_sum_new = sqrt(dot(sum_color.xyz, sum_color.xyz) / 3); //pre-converted brightness is very dark brightness_sum_old *= 5.0; //and finally, swap new brightness for old one so it doesn't get max brightness everywhere. if (brightness_sum_old < brightness_sum_new) { sum_color *= (brightness_sum_old / brightness_sum_new); brightness_sum_new = brightness_sum_old; } //end of wobbly texture magic, begin of starry texture magic float brightness_tex0 = sqrt(dot(tex0.xyz, tex0.xyz) / 3); //convert rgb into hsl to get the saturation float max_tex0 = max(tex0.x, max(tex0.y, tex0.z)); float min_tex0 = min(tex0.x, min(tex0.y, tex0.z)); float lightness_tex0 = 0.5 * (max_tex0 + min_tex0); float chroma_tex0 = max_tex0 - min_tex0; float saturation_tex0 = 0.0; if (abs(lightness_tex0 - 0.5) < 0.49f) { saturation_tex0 = chroma_tex0 / (1.0 - abs(2.0 * lightness_tex0 - 1.0)); } //compose wobbly+starry. saturation is necessary so that the stars don't get overlayed with the wobbly. float lerpval = saturation_tex0 * (0.5 + 0.5 * (brightness_sum_new - brightness_tex0)); float4 final_col = lerp(tex0, sum_color, lerpval); //calc glow. Make stars glow as shiny as possible whenever they get "hit" by the wobbly texture. Make nebula (wobbly texture) glow a little bit. Make everything else only glow very slightly to not make it too dark. float glow_alpha = saturate(0.01 + 2.0 * ((1.0 - saturation_tex0) + 0.2) * brightness_sum_new); float4 final_glow = final_col * glow_alpha; //and ready to go O.col[0] = float4(final_col.xyz, tex0.w); O.col[1] = float4(final_glow.xyz, glow_alpha); #endif return O; } Surface.txt code: fxTEST = { diffusePnt = "null.shader", //You can add something here if you want to, like the velvet shader. Only makes sense if you plan making the fx transparent. diffusePntShd = "null.shader", //You can add something here if you want to, like the velvet shader. Only makes sense if you plan making the fx transparent. z = "object/z.shader", //always needs to be the same shadowmap = "object/shadowMap.shader", //always needs to be the same cubeshadowmap = "object/cubeShadowMap.shader", //always needs to be the same ambDiff = "object/fx/ambDiffFxTest.shader", //whis is how I named the shader and where I put it. You have to put it in the correct folder inside shader.zip/unified. } Example surface: newSurface = { name = "in-armageddon-torso_s", texture0Name = "maps/heroes/inquisitor/sets/armageddon/TEST.tga", //starry texture texture1Name = "maps/heroes/inquisitor/sets/armageddon/s_inquisitor-armageddon-chest_sg.tga", //wobbly texture texture2Name = "maps/heroes/inquisitor/sets/scourge/s_inq_scourge_fx2.tga", //this needs to always be the same flags = SURFACE_FLAG_OPAQUE, shader = fxTEST, } mgr.surfCreate(newSurface); Edited June 10, 2022 by Lindor Link to comment
Dax 481 Posted June 10, 2022 Share Posted June 10, 2022 I think supersexycool describes it the best way. Combined with other mods, Sacred 2 becomes a whole new experience. 1 Link to comment
Lindor 438 Posted June 10, 2022 Author Share Posted June 10, 2022 I know I said this would be the final version of the shader, but it still doesn't quite look as I wish. This is the texture I'm using for the starry background: Actually a lot gets lost with the .jpg transformation, it's very much brighter and purplier in .dds. I tried to upload it as .bmp, shareX automatically converts it to .png: Still not perfect, but a lot closer to what it looks like in .dds. Apply it to the model and it suddenly gets super dark instead of the purple background: I've tried to correct this in the shader, but I fail to do it the way I want it to look. I wish the non-nebula'ed background was a little bit brighter, more purple and with more very tiny stars, kinda like a purple noise. The whole thing gets complicated by my efforts to make the stars shine and glow only when they're hit by the nebula, so the non-nebula'ed version is supposed to be brighter, noisier and purplier but not too much so you can see the difference to the glowing nebula'ed stars. These are my attempts, left is the version I said would be final and right two are my attempts to correct: It's a little bit better, but still far from what I envision. @Flix @dimitrius154 @Vishanka I need your threes texturing experience. Is my texture too dark? Or is it the shader? Link to comment
dimitrius154 612 Posted June 10, 2022 Share Posted June 10, 2022 1 hour ago, Lindor said: I need your threes texturing experience. Is my texture too dark? Or is it the shader? Interesting, you're getting the RGB spectral diffusion. I'd advise lightening the dark parts and darkening the rest. 1 Link to comment
Flix 5,116 Posted June 10, 2022 Share Posted June 10, 2022 2 hours ago, dimitrius154 said: Interesting, you're getting the RGB spectral diffusion. I'd advise lightening the dark parts and darkening the rest. ^ This. Adjust the levels to bring the dark and light closer together since they're too far apart now. My other thought was that the UV mapping on the model could be retooled. It looks like your source texture is getting squished down to a very small size and then tiled across the surface. The smaller details get lost. 1 Link to comment
Lindor 438 Posted June 11, 2022 Author Share Posted June 11, 2022 (edited) Sirs, you two are genii! Thx for help! I have five different goals, and I've had 28 different tries since my last post. I'm gonna upload the try which suited best for each goal: Nebula keeps original color Spoiler Nebula gets layed over everything that is not a star Spoiler Stars only light up (very brightly) when they're inside nebula (This is by far the hardest goal, hence why this is also my latest attempt) Spoiler nebula glows a little bit Spoiler all non-nebula'ed regions don't glow but have visible strry purple details Spoiler I want all five goals at once. I have created five different additional textures, which one you think I should use? Or ar all five bad? Spoiler (first one is original from post above) 3 hours ago, Flix said: My other thought was that the UV mapping on the model could be retooled. It looks like your source texture is getting squished down to a very small size and then tiled across the surface. The smaller details get lost. Great idea, the starry texture has actually 7x the resolution of the nevula. Problem is that this is necessary because otherwise this happens: Spoiler Same as with the leggins effect from the seraphim quite a couple of posts above. The details also get lost no matter what. Edited June 11, 2022 by Lindor Link to comment
Lindor 438 Posted June 13, 2022 Author Share Posted June 13, 2022 (edited) It has taken me an absolutely enormous effort, but I've finally managed to make it look exactly the way I want it to! Final shader contains all kinds of goodies including gamma correction! Here's how it looks like: @Flix @dimitrius154 thx for help again, your tip with adjusting the texture's brightness was worth pure gold! I ended up using this picure: Spoiler And here is a little evolution of the six previous versions of the shader, just so you see how tiny the amount improvement per step is: Spoiler Last but not least, the golden heart of the countless hours of work, the shader itself, cleaned up and with commentary, free for everyone who wants to use it or just wants to see how it works: (for surface.txt usage see example in my post above) Spoiler // ambient #include "extractvalues.shader" #define LIGHTBLOCKS 4 struct appdata { float3 position : POSITION; float3 normal : NORMAL; float3 tangent : TANGENT; float3 binormal : BINORMAL; float2 texcoord : TEXCOORD0; float2 data : TEXCOORD1; }; struct pixdata { float4 hposition : POSITION; float4 texcoord0 : TEXCOORD0; float4 surfNrm_ws : TEXCOORD1; float4 lightNrm_ws : TEXCOORD2; float4 camDist_ws : TEXCOORD3; float4 screenCoord : TEXCOORD4; }; #ifdef SM1_1 struct fragout { float4 col : COLOR; }; #else struct fragout { float4 col[2] : COLOR; }; #endif pixdata mainVS(appdata I, uniform float4x4 worldViewProjMatrix, uniform float4x4 worldMatrix, uniform float4 light_pos, uniform float4 camera_pos) { pixdata O; // vertex pos float4 pos4 = float4(I.position.xyz, 1.0); float4 nrm4 = float4(I.normal, 0.0); O.hposition = mul(pos4, worldViewProjMatrix); // lighting O.surfNrm_ws = mul(nrm4, worldMatrix); O.lightNrm_ws = normalize(light_pos); O.camDist_ws = camera_pos - mul(pos4, worldMatrix); float c_dist_ws = sqrt(dot(O.camDist_ws.xyz, O.camDist_ws.xyz)); // pass texture coords float4 halfway = calcScreenToTexCoord(O.hposition); O.screenCoord = halfway; float resolution = 0.05 * c_dist_ws; //float resolution = 0.01 * c_dist_ws; O.texcoord0 = float4(((halfway.x / halfway.w) - 0.5) * resolution, ((halfway.y / halfway.w) - 0.5) * resolution, halfway.z * resolution, halfway.w * resolution); return O; } fragout mainPS(pixdata I, uniform sampler2D texture0, uniform sampler2D texture1, uniform sampler2D texture2, uniform sampler2D shadow_texture, uniform samplerCUBE textureCube, uniform float4 system_data) { fragout O; #ifdef SM1_1 s2half4 tex0 = tex2D(texture0, I.texcoord0.xy); O.col = float4(tex0.xyz, 1.0); #else float time = system_data.x; s2half4 tex0 = tex2D(texture0, I.texcoord0.xy); s2half4 shadow = tex2Dproj(shadow_texture, I.screenCoord); //take the wobbly effect from the fx6 shader (it's called "fx6" in surface.txt, but the shader is called "ambDiffFx5.shader") float4 sum_color = float4(0.0, 0.0, 0.0, 0.0); float I = 0, sum_num = 6; for(I = 0; I < sum_num; I++) { //calc horizontal offset float2 offsetUV = I.texcoord0.xy / 5.0; //make it a little bit slower than in fx6 offsetUV.y += frac(0.55 + 0.3375 * I * time / sum_num + 0.15 + I / sum_num); s2half4 wave_offset = tex2D(texture2, offsetUV); float h_offs = (I / sum_num) + (0.1 + 0.03 * I / sum_num) * (wave_offset.x - 0.5); //calc vertical offset offsetUV = I.texcoord0.xy / 5.0; wave_offset = tex2D(texture2, offsetUV); float v_offs = (0.3 * I / sum_num) * wave_offset.z * (wave_offset.y - 0.5); //calc lookup float2 newUV = I.texcoord0.xy / 5.0; //increase range of wobblyness compared to fx6 through multiplying by 2 newUV += 2.0 * float2(h_offs, v_offs); //fx base color s2half4 base_color = tex2D(texture1, newUV); base_color = pow(base_color, 1.0 + 2.0 * wave_offset.x + 2.0 * wave_offset.y); //fx sum color sum_color += base_color; } sum_color /= sum_num; //end of fx6's wobbly effect calculation //HSL color room's Lightness and Saturation from RGB color room //sum_color float lightness_gamma_corrected_sum = (0.2126 * sum_color.x) + (0.7152 * sum_color.y) + (0.0722 * sum_color.z); //tex0 float saturation_tex0 = sqrt(dot(tex0.xyz, tex0.xyz) - dot(tex0.xyz, tex0.yzx)); float lightness_gamma_corrected_tex0 = 0.2126 * tex0.x + 0.7152 * tex0.y + 0.0722 * tex0.z; //compose wobbly+starry. saturation is necessary so that the stars don't get overlayed with the wobbly. float3 final_col = float3(0.0, 0.0, 0.0); float3 final_glow = float3(0.0, 0.0, 0.0); float glow_intensity = 0.0; //star if ((1.0 - saturation_tex0) * lightness_gamma_corrected_tex0 > 0.27) { final_col = tex0.xyz; final_glow = tex0.xyz; //high_nebula if (lightness_gamma_corrected_sum > 0.05f) { //aimed effect: stars inside nebulas shall glow bright glow_intensity = lightness_gamma_corrected_tex0; } //low_nebula else { //aimed effect: visual difference between glowing star inside nebula and normal background star outside nebula //the lower the dimm value, the more the star gets dimmed float dimm_min = 0.5f; float dimm_max = 1.0f; //the less saturation and the more brightness, the more the star gets dimmed aka the lower the dimm value float dimm = lerp(dimm_min, dimm_max, sqrt(saturation_tex0 * (1.0f - lightness_gamma_corrected_tex0))); float glow_min = lightness_gamma_corrected_tex0 * dimm; float glow_max = lightness_gamma_corrected_sum; final_col *= dimm; final_glow *= dimm; //multiply by 20.0 because (0.0 < lightness_gamma_corrected_sum < 0.05) and (20.0 * 0.05 = 1) glow_intensity = lerp(glow_min, glow_max, 20.0 * lightness_gamma_corrected_sum); } } //no_star else { //high_nebula if (lightness_gamma_corrected_sum > 0.05) { //aimed effect: nebula replaces everything that is not a star and glows a little bit final_col = sum_color.xyz; final_glow = sum_color.xyz; glow_intensity = 0.35; } //low_nebula else { //aimed effect: smooth fade-off of nebula diffuse and glow into starry background //multiply by 20.0 because (0.0 < lightness_gamma_corrected_sum < 0.05) and (20.0 * 0.05 = 1) float lerpval = 20.0 * lightness_gamma_corrected_sum; //calc diffuse, glow and glow_intensity for starry and nebula //copy code from star/low_nebula float dimm_min = 0.5f; float dimm_max = 1.0f; float dimm = lerp(dimm_min, dimm_max, sqrt(saturation_tex0 * (1.0f - lightness_gamma_corrected_tex0))); float glow_min = lightness_gamma_corrected_tex0 * dimm; float glow_max = lightness_gamma_corrected_sum; //diffuse float3 diffuse_starry = tex0.xyz * dimm; float3 diffuse_nebula = sum_color.xyz; //glow float3 glow_starry = tex0.xyz * dimm; float3 glow_nebula = sum_color.xyz; //intensity float glow_intensity_starry = lerp(glow_min, glow_max, lerpval); float glow_intensity_nebula = 0.35; //compose final_col = lerp(diffuse_starry, diffuse_nebula.xyz, lerpval); final_glow = lerp(glow_starry, glow_nebula.xyz, lerpval); glow_intensity = lerp(glow_intensity_starry, glow_intensity_nebula, lerpval); } } //apply intensity final_glow *= glow_intensity; //and ready to go O.col[0] = float4(final_col, tex0.w); O.col[1] = float4(final_glow, tex0.w); #endif return O; } It was totally worth it! On 6/10/2022 at 2:03 AM, gogoblender said: beautiful effect with the robes.. and the zoom you pulled off makes it magnetic approach, good drama lindor. gonna show it to Schot, maybe there's also an idea here for default avatars for DarkMatters when new members register? gogo Forgot to answer last time, sry Uh I like the idea Custom avatars for every Sacred/Sacred 2 character sounds amazing! Take what you want!! Do you want the original GIF or should I make a new one with the final version? A lot gets lost during the GIF transformation however. Edited June 13, 2022 by Lindor 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