Godot Version
4.2.2
Question
Hello, I stupidly bought a Unity asset pack thinking it would not be too hard to convert it to Godot and I have been stuck for 3 days not even managing to properly import a single proper 3d prefab… and I am no 3d artist, had to do lots of reading to even be where I am right now.
I basically used the new Unity gltFast plugin to export them into gltf, and then import them into Godot.
Textures were all wrong in materials but that seem easy to fix as long as there are no shaders involved. But while there are not a lot of shaders in the asset pack, almost every materials is using one of them so that’s no good.
Here is a picture example, focus on the gray part. White parts I just not started to touch yet, they are using another shader. Background which is not using any shader though was easy to fix and looks exactly the same than in Unity.
Now the gray middle part, the normal seems ok to me, I got the right depth on the top horizontal bars. All the rest though is messed up…
The cube motif is coming from the “dirt roughness” texture so I am assuming the problem comes from here, and there is no albedo texture, just color, so it’s a bit special.
The dirt/wear sliders and textures are dynamically simulating scratches/weariness and that seems to work well enough.
And here is the original Unity shader code
Properties
{
_BaseNormal("Base Normal", 2D) = "white" {}
_DirtRoughness("Dirt Roughness", 2D) = "white" {}
_DetailNormal("Detail Normal", 2D) = "white" {}
_DetailMask("Detail Mask", 2D) = "white" {}
_BaseColor("Base Color", Color) = (0.6544118,0.6544118,0.6544118,0)
_BaseColorOverlay("Base Color Overlay", Color) = (0.6544118,0.6544118,0.6544118,0)
_BaseDirtColor("Base Dirt Color", Color) = (0,0,0,0)
_DetailColor("Detail Color", Color) = (0,0,0,0)
_BaseNormalStrength("Base Normal Strength", Range( 0 , 1)) = 0
_BaseSmoothness("Base Smoothness", Range( 0 , 1)) = 0.5
_BaseDirtStrength("Base Dirt Strength", Range( 0.001 , 3)) = 0
_BaseMetallic("Base Metallic", Range( 0 , 1)) = 0
_DetailEdgeWear("Detail Edge Wear", Range( 0 , 1)) = 0
_DetailEdgeSmoothness("Detail Edge Smoothness", Range( 0 , 1)) = 0
_DetailDirtStrength("Detail Dirt Strength", Range( 0 , 1)) = 0
_DetailOcclusionStrength("Detail Occlusion Strength", Range( 0 , 1)) = 0
[HideInInspector] _texcoord4( "", 2D ) = "white" {}
[HideInInspector] _texcoord( "", 2D ) = "white" {}
[HideInInspector] __dirty( "", Int ) = 1
}
SubShader
{
Tags{ "RenderType" = "Opaque" "Queue" = "Geometry+0" }
Cull Back
CGPROGRAM
#include "UnityStandardUtils.cginc"
#pragma target 4.0
#pragma surface surf Standard keepalpha addshadow fullforwardshadows
struct Input
{
float2 uv_texcoord;
float2 uv4_texcoord4;
};
uniform sampler2D _DetailNormal;
uniform float4 _DetailNormal_ST;
uniform sampler2D _BaseNormal;
uniform float4 _BaseNormal_ST;
uniform float _BaseNormalStrength;
uniform float4 _BaseDirtColor;
uniform sampler2D _DirtRoughness;
uniform float4 _DirtRoughness_ST;
uniform float _BaseDirtStrength;
uniform float4 _BaseColor;
uniform float4 _BaseColorOverlay;
uniform float4 _DetailColor;
uniform sampler2D _DetailMask;
uniform float4 _DetailMask_ST;
uniform float _DetailDirtStrength;
uniform float _DetailEdgeWear;
uniform float _BaseMetallic;
uniform float _BaseSmoothness;
uniform float _DetailEdgeSmoothness;
uniform float _DetailOcclusionStrength;
void surf( Input i , inout SurfaceOutputStandard o )
{
float2 uv_DetailNormal = i.uv_texcoord * _DetailNormal_ST.xy + _DetailNormal_ST.zw;
float3 tex2DNode3 = UnpackNormal( tex2D( _DetailNormal, uv_DetailNormal ) );
float2 uv3_BaseNormal = i.uv4_texcoord4 * _BaseNormal_ST.xy + _BaseNormal_ST.zw;
float3 lerpResult11 = lerp( float3(0,0,1) , UnpackNormal( tex2D( _BaseNormal, uv3_BaseNormal ) ) , _BaseNormalStrength);
o.Normal = BlendNormals( tex2DNode3 , lerpResult11 );
float2 uv3_DirtRoughness = i.uv4_texcoord4 * _DirtRoughness_ST.xy + _DirtRoughness_ST.zw;
float4 tex2DNode143 = tex2D( _DirtRoughness, uv3_DirtRoughness );
float clampResult77 = clamp( pow( tex2DNode143.g , _BaseDirtStrength ) , 0.0 , 1.0 );
float4 lerpResult76 = lerp( _BaseDirtColor , float4( 1,1,1,0 ) , clampResult77);
float4 lerpResult71 = lerp( _BaseColor , _BaseColorOverlay , tex2DNode143.r);
float2 uv_DetailMask = i.uv_texcoord * _DetailMask_ST.xy + _DetailMask_ST.zw;
float4 tex2DNode36 = tex2D( _DetailMask, uv_DetailMask );
float4 lerpResult134 = lerp( lerpResult71 , _DetailColor , ceil( ( ( 1.0 - tex2DNode36.b ) + -0.95 ) ));
float temp_output_120_0 = ceil( ( tex2DNode36.b + -0.8 ) );
float4 lerpResult123 = lerp( lerpResult134 , float4( float3(1,0.95,0.9) , 0.0 ) , temp_output_120_0);
float clampResult49 = clamp( pow( ( tex2DNode36.r + 0.55 ) , 6.0 ) , 0.0 , 1.0 );
float4 lerpResult92 = lerp( lerpResult123 , ( lerpResult123 * clampResult49 ) , _DetailDirtStrength);
float clampResult62 = clamp( ( ( tex2DNode36.r + -0.55 ) * 2.0 ) , 0.0 , 1.0 );
float4 clampResult101 = clamp( ( clampResult62 + lerpResult92 ) , float4( 0,0,0,0 ) , float4( 1,1,1,0 ) );
float4 lerpResult32 = lerp( lerpResult92 , clampResult101 , _DetailEdgeWear);
o.Albedo = ( lerpResult76 * lerpResult32 ).rgb;
float lerpResult94 = lerp( 0.0 , clampResult62 , _DetailEdgeWear);
float clampResult97 = clamp( ( lerpResult94 + temp_output_120_0 ) , 0.0 , 1.0 );
float clampResult145 = clamp( ( clampResult97 + _BaseMetallic ) , 0.0 , 1.0 );
o.Metallic = clampResult145;
float4 temp_cast_2 = (_DetailEdgeSmoothness).xxxx;
float4 lerpResult121 = lerp( ( ( max( clampResult62 , tex2DNode143.a ) * lerpResult76 ) * _BaseSmoothness ) , temp_cast_2 , clampResult97);
o.Smoothness = lerpResult121.r;
float lerpResult138 = lerp( 1.0 , tex2DNode36.g , _DetailOcclusionStrength);
o.Occlusion = lerpResult138;
o.Alpha = 1;
}
ENDCG
}
Fallback "Diffuse"
CustomEditor "ASEMaterialInspector"
And here is my Godot version
shader_type spatial;
render_mode blend_mix,depth_draw_always,cull_back,diffuse_burley,specular_schlick_ggx;
group_uniforms DetailNormal;
uniform sampler2D _DetailNormal : hint_normal,filter_linear_mipmap,repeat_enable;
uniform vec4 _DetailNormal_ST;
group_uniforms BaseNormal;
uniform sampler2D _BaseNormal : hint_normal,filter_linear_mipmap,repeat_enable;
uniform vec4 _BaseNormal_ST;
uniform float _BaseNormalStrength : hint_range( 0 , 1) = 0;
group_uniforms DetailMask;
uniform sampler2D _DetailMask;
uniform vec4 _DetailMask_ST;
group_uniforms DirtRoughness;
uniform sampler2D _DirtRoughness : hint_roughness_normal;
uniform vec4 _DirtRoughness_ST;
uniform float _BaseDirtStrength : hint_range( 0.001, 3) = 0;
group_uniforms;
uniform vec4 _BaseDirtColor : source_color = vec4(0,0,0,0);
uniform vec4 _BaseColor : source_color = vec4(0.6544118,0.6544118,0.6544118,0);
uniform vec4 _BaseColorOverlay : source_color = vec4(0.6544118,0.6544118,0.6544118,0);
uniform vec4 _DetailColor : source_color = vec4(0,0,0,0);
uniform float _DetailDirtStrength : hint_range( 0 , 1) = 0;
uniform float _DetailEdgeWear : hint_range( 0 , 1) = 0;
uniform float _BaseMetallic : hint_range( 0 , 1) = 0;
uniform float _BaseSmoothness : hint_range( 0 , 1) = 0.5;
uniform float _DetailEdgeSmoothness : hint_range( 0 , 1) = 0;
uniform float _DetailOcclusionStrength : hint_range( 0 , 1) = 0;
// Those 2 functions are native to Unity but I found the code on internet to port them
vec3 blend_normals(vec3 n1, vec3 n2) {
vec3 blendedNormal = vec3(n1.x + n2.x, n1.y + n2.y, n1.z * n2.z);
return normalize(blendedNormal);
}
vec3 UnpackNormal(vec4 packednormal)
{
return packednormal.xyz * 2.0 - 1.0;
//#if defined(SHADER_API_GLES) defined(SHADER_API_MOBILE)
//return packednormal.xyz * 2 - 1;
//#else
//vec3 normal;
//normal.xy = packednormal.wy * 2.0 - 1.0;
//normal.z = sqrt(1.0 - normal.x*normal.x - normal.y * normal.y);
//return normal;
//#endif
}
void fragment() {
// Calculate the detail normal UV coordinates
vec2 uv_DetailNormal = UV * _DetailNormal_ST.xy + _DetailNormal_ST.zw;
// Sample the detail normal map and unpack it
// vec3 tex2DNode3 = texture(_DetailNormal, uv_DetailNormal).rgb;
vec3 tex2DNode3 = UnpackNormal(texture(_DetailNormal, uv_DetailNormal));
// Calculate the base normal UV coordinates
vec2 uv3_BaseNormal = UV * _BaseNormal_ST.xy + _BaseNormal_ST.zw;
// Sample the base normal map and unpack it.
//vec3 lerpResult11 = mix(vec3(0.0, 0.0, 1.0), texture(_BaseNormal, uv3_BaseNormal).rgb, _BaseNormalStrength);
vec3 lerpResult11 = mix(vec3(0.0, 0.0, 1.0), UnpackNormal(texture(_BaseNormal, uv3_BaseNormal)).rgb, _BaseNormalStrength);
// Blend the normals
NORMAL = blend_normals(tex2DNode3, lerpResult11);
// Calculate the dirt roughness UV coordinates
vec2 uv3_DirtRoughness = UV * _DirtRoughness_ST.xy + _DirtRoughness_ST.zw;
// Sample the dirt roughness map
vec4 tex2DNode143 = texture(_DirtRoughness, uv3_DirtRoughness);
// Calculate the base dirt color
vec4 lerpResult76 = mix(_BaseDirtColor, vec4(1.0, 1.0, 1.0, 0.0), clamp(pow(tex2DNode143.g, _BaseDirtStrength), 0.0, 1.0));
// Calculate the base color overlay
vec4 lerpResult71 = mix(_BaseColor, _BaseColorOverlay, tex2DNode143.r);
// Calculate the detail mask UV coordinates
vec2 uv_DetailMask = UV * _DetailMask_ST.xy + _DetailMask_ST.zw;
// Sample the detail mask
vec4 tex2DNode36 = texture(_DetailMask, uv_DetailMask);
// Calculate intermediate values
vec4 lerpResult134 = mix(lerpResult71, _DetailColor, ceil((1.0 - tex2DNode36.b) + -0.95));
float temp_output_120_0 = ceil(tex2DNode36.b + -0.8);
vec4 lerpResult123 = mix(lerpResult134, vec4(vec3(1.0, 0.95, 0.9), 0.0), temp_output_120_0);
float clampResult49 = clamp(pow(tex2DNode36.r + 0.55, 6.0), 0.0, 1.0);
vec4 lerpResult92 = mix(lerpResult123, lerpResult123 * clampResult49, _DetailDirtStrength);
float clampResult62 = clamp((tex2DNode36.r + -0.55) * 2.0, 0.0, 1.0);
vec4 clampResult101 = clamp(clampResult62 + lerpResult92, vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 0.0));
vec4 lerpResult32 = mix(lerpResult92, clampResult101, _DetailEdgeWear);
// Set the final albedo color
ALBEDO = (lerpResult76 * lerpResult32).rgb;
// Additional calculations
float lerpResult94 = mix(0.0, clampResult62, _DetailEdgeWear);
float clampResult97 = clamp(lerpResult94 + temp_output_120_0, 0.0, 1.0);
float clampResult145 = clamp(clampResult97 + _BaseMetallic, 0.0, 1.0);
METALLIC = clampResult145;
vec4 temp_cast_2 = vec4(_DetailEdgeSmoothness, _DetailEdgeSmoothness, _DetailEdgeSmoothness, _DetailEdgeSmoothness);
vec4 lerpResult121 = mix(
(max(clampResult62, tex2DNode143.a) * lerpResult76) * _BaseSmoothness,
temp_cast_2,
clampResult97
);
// Unity use smoothness, but godot use roughness
ROUGHNESS = 1.0 - lerpResult121.r;
float lerpResult138 = mix(1.0, tex2DNode36.g, _DetailOcclusionStrength);
AO = lerpResult138;
// Set Alpha to 1
ALPHA = 1.0;
}
I never touched at shaders before so I am a bit lost, I am really not sure about the Unity uv3_x => Godot UV conversion, but using UV2 seems to make things even worse.
Would appreciate any pointers !