Sup, folks.
I’ve got quite a conundrum on my hands.
What I’m trying to achieve is: semi-transparent material with texture and normal map.
I’m using this shader:
Shader "Cg normal mapping" {
Properties{
_MainTex("Texture", 2D) = "white" {}
_BumpMap("Normal Map", 2D) = "bump" {}
_Color("Diffuse Material Color", Color) = (1,1,1,1)
_SpecColor("Specular Material Color", Color) = (1,1,1,1)
_Shininess("Shininess", Float) = 10
_MinVisDistance("MinDistance",Float) = 0
_MaxVisDistance("MaxDistance",Float) = 20
}
CGINCLUDE
#include "UnityCG.cginc"
uniform float4 _LightColor0;
uniform sampler2D _BumpMap;
uniform sampler2D _MainTex;
uniform float4 _BumpMap_ST;
uniform float4 _Color;
uniform float4 _SpecColor;
uniform float _Shininess;
half _MinVisDistance;
half _MaxVisDistance;
struct vertexInput {
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
float3 normal : NORMAL;
float4 tangent : TANGENT;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD0;
float4 tex : TEXCOORD1;
float3 tangentWorld : TEXCOORD2;
float3 normalWorld : TEXCOORD3;
float3 binormalWorld : TEXCOORD4;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
float4x4 modelMatrix = unity_ObjectToWorld;
float4x4 modelMatrixInverse = unity_WorldToObject;
output.tangentWorld = normalize(
mul(modelMatrix, float4(input.tangent.xyz, 0.0)).xyz);
output.normalWorld = normalize(
mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
output.binormalWorld = normalize(
cross(output.normalWorld, output.tangentWorld)
* input.tangent.w);
output.posWorld = mul(modelMatrix, input.vertex);
output.tex = input.texcoord;
output.pos = UnityObjectToClipPos(input.vertex);
return output;
}
float4 fragWithAmbient(vertexOutput input) : COLOR
{
/*half2 uv_BumpMap = TRANSFORM_TEX(input.tex, _BumpMap);
half3 viewDirW = _WorldSpaceCameraPos - mul((half4x4)unity_ObjectToWorld, input.pos);
half viewDist = length(viewDirW);
half falloff = saturate((viewDist - _MinVisDistance) / (_MaxVisDistance - _MinVisDistance)); */
float4 encodedNormal = tex2D(_BumpMap,
_BumpMap_ST.xy * input.tex.xy + _BumpMap_ST.zw);
float3 localCoords = float3(2.0 * encodedNormal.a - 1.0,
2.0 * encodedNormal.g - 1.0, 0.0);
localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
float3x3 local2WorldTranspose = float3x3(
input.tangentWorld,
input.binormalWorld,
input.normalWorld);
float3 normalDirection =
normalize(mul(localCoords, local2WorldTranspose));
float3 viewDirection = normalize(
_WorldSpaceCameraPos - input.posWorld.xyz);
float3 lightDirection;
float attenuation;
if (0.0 == _WorldSpaceLightPos0.w)
{
attenuation = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
}
else
{
float3 vertexToLightSource =
_WorldSpaceLightPos0.xyz - input.posWorld.xyz;
float distance = length(vertexToLightSource);
attenuation = 1.0 / distance;
lightDirection = normalize(vertexToLightSource);
}
float3 ambientLighting =
UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
float3 diffuseReflection =
attenuation * _LightColor0.rgb * _Color.rgb
* max(0.0, dot(normalDirection, lightDirection));
float3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0)
{
specularReflection = float3(0.0, 0.0, 0.0);
}
else
{
specularReflection = attenuation * _LightColor0.rgb
* _SpecColor.rgb * pow(max(0.0, dot(
reflect(-lightDirection, normalDirection),
viewDirection)), _Shininess);
}
return float4((ambientLighting + diffuseReflection
+ specularReflection), 1);
}
ENDCG
SubShader {
Pass{
ZWrite Off
Cull Back
Blend SrcAlpha OneMinusSrcAlpha
Tags { "LightMode" = "ForwardBase" "RenderType" = "Transparent" }
CGPROGRAM
#pragma vertex vert
#pragma fragment fragWithAmbient
ENDCG
}
}
}
It works perfect except for this part:
As you can see some of the faces are darker than the other mesh and even looks like they are drawn “in front” of other parts.
Numerous surface and fragments shaders yeld the same result, even the standard one with transparency and texture/normal set:
Geometry is a basic volumetric mesh:
Am I missing something dramaticly here? Can this be achieved with one shader without mesh splitting?