Spherical Environment Map Trim Shader (iPhone)

Hey all-

So I’ve been trying to get a shader to work on the iPhone that uses 2 textures, a base (diffuse) map, and a spherical environment map that only draws on trim, or metallic parts of the base map (using the alpha channel of the base texture as a mask). I’ve got this working on the iPhone hardware using 2 passes (it looks good, reminiscent of the technique used in NWN), but I can’t help feeling it could be done in one pass, since it only uses 2 textures…

Here is what I am currently doing:

Pass 1) Draw the Environment Map (color it for fun)
Pass 2) Draw the Diffuse over it, alpha blending out the parts where I want the trim to be (using Blend SrcAlphaMinusOne SrcAlpha since my mask is white where I want it to not draw).

Works pretty well (I’ll paste the shader code below). I’ve tried doing this with one pass, and the difficulty I’m running into there is I can’t set the blend mode differently for the first texture than the second - any ideas if this can be done in one pass, or is this 2 pass solution the best that can be done? (Also, if anyone has any optimizations for this 2 pass solution I’d love to see them - I’m totally new to this shader stuff - and please feel free to use/modify this shader if it proves to be any use to you!)

Shader "TwoPassEnv" {
Properties {
        _Color ("Main Color", Color) = (1,1,1,1)
        _SpecColor ("Spec Color", Color) = (1,1,1,1)
        _EnvColor ("Environment Main Color", Color) = (1,1,1,1)
        _Emission ("Emmisive Color", Color) = (0,0,0,0)
        _Shininess ("Shininess", Range (0.01, 1)) = 0.7
        _EnvShininess ("Environment Shininess", Range (0.01, 1)) = 0.7
        _MainTex ("Base (RGB)", 2D) = "white" {} 
        _EnvMap ("EnvMap", 2D) = "black" { TexGen SphereMap } 
        }

SubShader {
       	
       	Lighting On
        
        // Environment Map Pass First
        //   Lay down a colored environment map first
        // and then draw diffuse map over it, with 
        // the parts to remain shiney alpha blended out
        ///////////////////////////////////////////////////
        Pass {

     
                Material {
                        Diffuse [_EnvColor]
                        Ambient [_EnvColor]
                        Shininess [_EnvShininess]
                        Specular [_EnvColor]
                        Emission [_Emmission]
                }
                
                SetTexture [_EnvMap] {
                        Combine texture * primary DOUBLE
                }
                
        }


         // Diffuse Pass On top, with Trim alpha'd out
         /////////////////////////////////////
         Pass {
                ZWrite Off

                //Assumes your alpha mask is white where you want shiney trim
                Blend OneMinusSrcAlpha SrcAlpha
                Material {
                        Diffuse [_Color]
                        Ambient [_Color]
                        Shininess [_Shininess]
                        Specular [_SpecColor]
                        Emission [_Emmission]
                }
              

                 SetTexture [_MainTex] {
                         Combine texture * primary DOUBLE, texture * primary
                 }
               
        }
       }
}

-jdm

Thanks!

I’m trying to figure out how to get it so that the areas that aren’t environment mapped are completely invisible. This would allow me to create something that looks like a puddle of water. Any thoughts?

Ok, here we go. I combined stuff from your shader with a shader I found on the Unify Community wiki. It should work great for creating believable water puddles, provided it works on iPhone of course :wink:

On a side note, I couldn’t figure out how to get it so that you can adjust the diffuse color - being able to edit transparency in the inspector would be particularly useful.

Shader "Reflective/MaskedTexture"
{
   Properties
   {
	  _Color ("Main Color", Color) = (1,1,1,1)
      _MainTex ("Base (RGB)", 2D) = "white" {TexGen SphereMap}
      _Mask ("Culling Mask", 2D) = "white" {}
      _Cutoff ("Alpha cutoff", Range (0,1)) = 0.1
   }
   SubShader
   {
      Tags {"Queue"="Transparent"}
      Lighting Off
      ZWrite Off
      Blend SrcAlpha OneMinusSrcAlpha
      AlphaTest GEqual [_Cutoff]
      Pass
      {
         SetTexture [_Mask] {
			combine texture
		}
		
         SetTexture [_MainTex] {
			combine texture, previous
		}
      }
   }
}