- Home /
How to extend a Material Shader so that it also maps the Normal Maps in WorldSpace?
Hey!
I am working on a Material Shader right now, which applys a texture onto a surface depending on world coordinates. A pretty good example for this approach is this video ([https://www.youtube.com/watch?v=CNWsN10KZCs][1])
I managed to get the mapping of the assigned texture right. However I'm struggling to add the normalmaps right. I tried different approaches, but nothing worked so far. Here is the code-snippet I'm working with:
Shader "Custom/Test_WorldSpaceTexture" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Texture", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_BumpMap ("Normal", 2D) = "bump" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Standard
sampler2D _MainTex;
sampler2D _BumpMap;
struct Input {
float2 uv_BumpMap;
INTERNAL_DATA
float3 worldNormal;
float3 worldPos; };
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
if(abs(IN.worldNormal.y) > 0.5)
{
o.Albedo = tex2D(_MainTex, IN.worldPos.xz) * _Color;
}
else if(abs(IN.worldNormal.x) > 0.5)
{
o.Albedo = tex2D(_MainTex, IN.worldPos.yz) * _Color;
}
else
{
o.Albedo = tex2D(_MainTex, IN.worldPos.yx) * _Color;
}
o.Emission = o.Albedo;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
//o.Normal = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
}
FallBack "Diffuse"
}
Is there a simple way to extend the surf-method so that it will also map the normal map accordingly? If not, could you give me some suggestions that would point me in the right direction.
This problem seems trivial to me. But I wasn't able to figure it out so far. I'm pretty new and inexperienced with writing shaders. But I'm eager to learn new things. Help or Support would be highly appreciated!
[1]: https://www.youtube.com/watch?v=CNWsN10KZCs
Answer by Namey5 · Jan 09, 2019 at 12:11 PM
Seeing as you aren't blending the textures, this should be pretty simple to implement;
struct Input
{
float2 uv_BumpMap;
float3 worldPos;
float3 worldNormal;
INTERNAL_DATA
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o)
{
float3 worldNorm = WorldNormalVector (IN, float3 (0,0,1)); //You need to use this if you are writing to o.Normal
if(abs(worldNorm.y) > 0.5)
{
o.Albedo = tex2D(_MainTex, IN.worldPos.xz) * _Color;
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.worldPos.xz));
}
else if(abs(worldNorm.x) > 0.5)
{
o.Albedo = tex2D(_MainTex, IN.worldPos.yz) * _Color;
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.worldPos.yz));
}
else
{
o.Albedo = tex2D(_MainTex, IN.worldPos.yx) * _Color;
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.worldPos.yx));
}
o.Emission = o.Albedo;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
}