SubShader {
SeperateSpecular On
Pass {
Name “BASE”
Cull Front
//Blend One OneMinusDstColor
Blend One One
BindChannels {
Bind “Vertex”, vertex
Bind “normal”, normal
}
SetTexture [_EnvMap] {
combine texture
}
}
Pass {
Name “BASE”
ZWrite on
Blend One One
BindChannels {
Bind “Vertex”, vertex
Bind “normal”, normal
}
Thank you for this quick and simple env mapping shader.
However, there are two problems with it:
First, we had the effect that the shader became non-transparent in our builds, while it worked fine in the editor. This is a problem with the rendering queue, which seems to differ (or maybe even yield non-deterministic results) between those two. We solved that problem by explicitly assigning the correct render queue position in the shader.
Second, the “Blend One One” is a fully additive blending, and will often burn out (=“overexpose”) areas with a reflection. There are two variations that yield better results.
The first is “Blend One OneMinusSrcColor”, which is probably what you want. It prevents overexposure, while still giving full brightness where the reflection is strongest. NOTE that the Unity ShaderLab documentation for this is WRONG, listing this as “Blend One OneMinusDstColor” - which results in strong color distortion, amongst other problems). Note that this is only correct for greyscale envmaps.
The other would be “Blend SrcAlpha OneMinusSrcAlpha”, which would be the standard setting for “correct” alpha blending, and can be used if your Envmap is a “real” color map with a designated alpha channel. As long as your envmap is greyscale without alpha, you should use the former blendfunction.
So the modified shader looks like this:
///////////////////////////////////////////////////////
Shader "EnvMapGlass" {
Properties {
_EnvMap ("EnvMap", 2D) = "black" { TexGen SphereMap }
}
SubShader {
SeperateSpecular On
Tags {"Queue" = "Transparent" }
Pass {
Name "BASE"
ZWrite on
//Blend One One // additive
Blend One OneMinusSrcColor // soft additive
//Blend SrcAlpha OneMinusSrcAlpha // real alpha blending
BindChannels {
Bind "Vertex", vertex
Bind "normal", normal
}
SetTexture [_EnvMap] {
combine texture
}
}
}
Fallback off
}
The shader posted by cgoran is great but it appears to break batching. If you are doing an iOS game, your enemy is draw calls and your friend is the automatic batching. If you have poly objects under 300 verts they will be automatically batched thus reducing your draw calls. So you can have… say… 4 poly objects, and if they are batched, they only take one draw call. I need batching in my application. Of course if you are only applying the shader to one object, then batching may not be an issue for you. I’m not a shader expert so I don’t know why cgoran’s shader breaks batching. If anyone knows, I would love to learn. This brings me to Wolfram’s adjustments.
Wolfram’s shader appears to have some mistyped brackets. I fixed the bracket situation and figured I would post his corrected code. It works for me and more importantly it allows the glass transparancy while reenabling batching. (very useful in iOS development).
My only problem with this implementation of glass for iOS is it seems to work great for spheres but if you flatten out a cube to a scale of say X:2 Y:.1 Z:2 (forming somewhat of a platform), then depending on the x position on the screen, your platform appears almost entirely opaque white. I think this is what Wolfram was observing. If you stick with the additive command of Blend One One and comment out the soft additive and real alpha, then that white opaqueness is really overexposed and blown out. It looks pretty bad. That’s why I use the soft additive command Blend One OneMinusSrcColor and have commented out the other two options.
If anyone knows if there is a way to adjust or further minimize that white opaqueness, that would be really helpful. It is my guess it has something to do with the fact that we are use a spheremap as our texture instead of say a cubemap. When a cubemap would be less beneficial for performance and memory in iOS.
Allan
// Upgrade NOTE: replaced 'SeperateSpecular' with 'SeparateSpecular'
Shader "Mobile/EnvMapGlass1"
{
Properties
{
_EnvMap ("EnvMap", 2D) = "black" { TexGen SphereMap }
}
SubShader
{
SeparateSpecular On
Tags {"Queue" = "Transparent" }
Pass
{
Name "BASE"
ZWrite on
//Blend One One // additive
Blend One OneMinusSrcColor // soft additive
//Blend SrcAlpha OneMinusSrcAlpha // real alpha blending
BindChannels
{
Bind "Vertex", vertex
Bind "normal", normal
}
SetTexture [_EnvMap]
{
combine texture
}
}
}
}