- Home /
Is there a way to access uv coordinates in a custom lighting model?
Im trying to do this in a BRDF shader I've written and basically what I want to is have a different ramp texture used based on the mask texture provided.
This is my code:
Shader "Learning/BRDF_FULL_MASK"
{
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_SpecColor ("Specular Color", Color) = (1,1,1,1)
_Shininess ("Specualr Power", Range(-1,2)) = 0.5
_MainTex ("Main Texture", 2D) = "white" {}
_BumpMap ("Normal Texture", 2D) = "white" {}
_MaskTex ("Mask (RGBA)", 2D) = "white" {}
_Ramp_RED ("Shading Ramp 1", 2D) = "gray" {}
_Ramp_GREEN ("Shading Ramp 2", 2D) = "gray" {}
_Ramp_BLUE ("Shading Ramp 3", 2D) = "gray" {}
}
SubShader {
Tags {"RenderType" = "Opaque"}
CGPROGRAM
#pragma surface surf BRDF_FULL
#pragma target 3.0
float _Shininess;
float4 _Color;
sampler2D _MainTex, _MaskTex, _BumpMap, _Ramp_RED, _Ramp_GREEN, _Ramp_BLUE;
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
};
struct SurfaceOutputCustom {
fixed3 Albedo;
fixed3 Normal;
fixed3 Emission;
half Specular;
fixed Gloss;
fixed Alpha;
fixed2 uv_MaskTex;
};
half4 LightingBRDF_FULL (SurfaceOutputCustom s, half3 lightDir, half3 viewDir, half3 atten)
{
float2 uv_MaskTex;
//Get the dot product of the sirface normal and light direction
half NdotL = dot (s.Normal, lightDir);
half NdotE = dot (s.Normal, viewDir);
//Normalize diffuse
half diff = NdotL * 0.3 + 0.5;
//BRDF
float2 brdfUV = float2 (NdotE * 0.8, diff);
float3 rBRDF = tex2D(_Ramp_RED, uv_MaskTex).rgb;
float3 gBRDF = tex2D(_Ramp_GREEN, uv_MaskTex).rgb;
float3 bBRDF = tex2D(_Ramp_BLUE, uv_MaskTex).rgb;
//Specular
//half3 h = normalize(lightDir + viewDir);
//float _Shininess = max (0, dot(s.Normal, h));
//float _SpecColor = pow (_Shininess, 48.0);
float3 m = tex2D(_MaskTex, uv_MaskTex).rgb;
//half4 c = tex2D (_MainTex, IN.uv_MainTex);
float3 res = m;
if (m.r >= .1) res = rBRDF.rgb;
else if (m.g >= .1) res = gBRDF.rgb;
else if (m.b >= .1) res = bBRDF.rgb;
half4 c;
//c.rgb = (s.Albedo * _LightColor0.rgb * BRDF + _LightColor0.rgb * _SpecColor) * (NdotL * atten * 2);
c.rgb = (s.Albedo * _LightColor0.rgb * res) * (atten * 2);
c.a = s.Alpha;
return c;
}
void surf (Input IN, inout SurfaceOutputCustom o)
{
//Handle textures
//Handle Diffuse map
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
//Handle Normal map
float3 bump = UnpackNormal (tex2D(_BumpMap, IN.uv_BumpMap));
//Apply textures
//Apply Diffuse texture
o.Albedo = tex.rgb * _Color.rgb;
//Apply Normal map
o.Normal = bump.rgb;
//Specular
o.Specular = _Shininess;
o.Gloss = tex.a;
}
ENDCG
}
Fallback "Diffuse"
}
and this is the result I get from that:
and the shader mask and how I want the ramps to be applied to the model:
I think my problem is that I can't get uv coordinates calculated inside the custom lighting model. Is this possible? If it isn't what is a way to make this shader work?
p.s. The model isn't mine, I got it here - www.steffenunger.com.
$$anonymous$$ade some progress I think, still getting errors though. I found this post
where $$anonymous$$ADmarine states that you can build your own structs to use in a custom lighting model. Awesome! So I did that, SurfaceOutputCustom, and now I get the error "Shader error in 'Learning/BRDF_FULL_$$anonymous$$AS$$anonymous$$': Program 'SurfShaderInternalFunc', incompatible type for parameter #1 ("s") at line 121". I'm pretty sure it has something to do with my SurfaceOutputCustom struct, but I don't know what.
Any help is much appreciated!
Thanks!
p.s. I've updated my code in the above post for you all to see everything.
Fixed the error, I had to reference my custom struct in the "surf" function. The shader isn't shouting at me about errors but isn't working the way I want. I want to use a different ramp for different parts of the uv map that I've masked off in "_$$anonymous$$askTex".
I've added another mask pic to explain better what I want to do.