- Home /
World Relative UVs with normalmaps
Hello ! I am currently using a shader allowing me to place my texture relative to the world. I simply put the textures used for the floor (normals pointing up) and for the walls (normals pointing elsewhere).
struct Input
{
float3 worldNormal;
float3 worldPos;
};
void surf (Input IN, inout SurfaceOutput o)
{
float2 UV;
fixed4 c;
if(abs(IN.worldNormal.x)>0.5)
{
UV = IN.worldPos.zy; // side
c = tex2D(_MainTexWall, UV* _Scale); // use WALLSIDE texture
}
else if(abs(IN.worldNormal.z)>0.5)
{
UV = IN.worldPos.xy; // front
c = tex2D(_MainTexWall, UV* _Scale); // use WALL texture
}
else
{
UV = IN.worldPos.xz; // top
c = tex2D(_MainTexFlr, UV* _FlrScale); // use FLR texture
}
o.Albedo = c.rgb;
}
I want to add normalmapping to this shader. Some of you might already know what my question is going to be since the problem is written in the doc :
float3 worldNormal - will contain world normal vector if surface shader does not write to o.Normal.
float3 worldNormal; INTERNAL_DATA - will contain world normal vector if surface shader writes to o.Normal. To get the normal vector based on per-pixel normal map, use WorldNormalVector (IN, o.Normal).
I can't read worldNormal as soon as I add
o.Normal = something
and
struct Input
{
float3 worldNormal;
float3 worldPos;
INTERNAL_DATA
};
But using WorldNormalVector(IN, o.Normal) doesn't seem to do much if i haven't changed the value of o.Normal before...
I feel like in order to read my worldNormal, I need to write it myself, which doesn't seem possible since I can't read it...
So, does anybody have any idea so I can add normalmapping to my textures ?
Thanks a lot for your help !
Answer by Setsuki · Oct 17, 2013 at 03:00 PM
Here is the solution by Orihaus in the comments of http://www.blog.radiator.debacle.us/2012/01/joys-of-using-world-space-procedural.html
Shader "WorldUV/Bumped Diffuse" {
Properties
{
_MainTex ("Base", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_Scale ("Scale", float) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 400
CGPROGRAM
#pragma surface surf Lambert
struct Input
{
float4 color : COLOR;
float2 uv_MainTex;
float2 uv_BumpMap;
float3 worldPos;
float3 worldNormal; INTERNAL_DATA
};
sampler2D _MainTex;
sampler2D _BumpMap;
fixed4 _Color;
half _Scale;
void surf (Input IN, inout SurfaceOutput o)
{
float3 correctWorldNormal = WorldNormalVector(IN, float3( 0, 0, 1 ) );
float2 uv = IN.worldPos.zx;
if( abs( correctWorldNormal.x ) > 0.5 ) uv = IN.worldPos.zy;
if( abs( correctWorldNormal.z ) > 0.5 ) uv = IN.worldPos.xy;
uv.x *= _Scale;
uv.y *= _Scale;
fixed4 tex = tex2D( _MainTex, uv );
o.Albedo = IN.color * tex.rgb ;
o.Normal = UnpackNormal( tex2D( _BumpMap, uv ) );
}
ENDCG
}
FallBack "Bumped Specular"
}