General Shader Questions

edited in Questions and Answers
While we wait for the presentation from the shader workshop to be cleaned up and made available I have a question; and we might as well start a general thread.

How do you declare a cubemap in a Unity3D shader script and apply it to the scene?

I know @Chippit talked about it in the workshop but I don't think he went into detail.

Comments

  • Add the cubemap to your Properties if you want to be able to interact with it using the Unity inspector. (You usually would, but you might not want to if it's something you manipulate in code that you don't want exposed to the user.)
    Properties
    {
    	...
    	_Cube ("Cubemap", CUBE) = "black" { TexGen CubeReflect } // I use black because they're usually used for reflections, which are usually additive. So the default colour being black means you don't see anything until you choose a cubemap.
    	...
    }


    Then you need to add a vector to your v2f (or whatever you call it) struct. This contains the lookup vector you use for getting which pixel in your cubemap you want to use.
    struct v2f {
    	...
    	float3 reflNormal: TEXCOORD3; // TEXCOORD has some number as a prefix depending on how many you've used before this.
    	...
    };


    Depending on what you want to do with it, how you work out your reflNormal may change. If you're using your cubemap as reflection, then you're looking up the cubemap by thinking of it as a vector that goes from your eye/camera, bounces off of a surface (i.e. is reflected about the surface's normal), and leaves to hit the cubemap somewhere. You'd therefore use something like:
    o.reflNormal = reflect(-viewDir, o.norm)


    (There are actually some pretty huge possibilities here, depending on how math-y you want to get. You can rotate the reflNormal over time to get the cubemap to rotate. You could treat the cubemap as light, for gorgeous image-based lighting. And those are just the more "standard" things.)

    For looking up the cubemap, you use something like:
    fixed3 cubemap = texCUBE(_Cube, i.reflNormal).rgb;


    texCUBE seems to expect world space coordinates, so make sure that when you're working out what your reflNormal is, you're giving it the view direction and normal in world space.
    Thanked by 1Fengol
  • Here's what I created prior to seeing @Elyaradine's comment.

    Why does it seem to be so hard to find information on shaders?

    Shader "Fengol/IceCube" {
    	Properties {
        _Cubemap ("Cube Map", CUBE) = ""{}
    	}
    	SubShader {
    
    Pass {
    
    		CGPROGRAM
    		#include "UnityCG.cginc"
          
        #pragma vertex vert
        #pragma fragment frag
        
        sampler2D _MainTex;
        samplerCUBE _Cubemap;
    		
        struct v2f
          {
            float4  pos : POSITION;
            float3  norm : NORMAL;
          };
          
          v2f vert (appdata_base input)      
          {
            v2f output;
            output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
            output.norm = mul(UNITY_MATRIX_MVP, input.normal);
            return output;
          }
          
          fixed4 frag (v2f input) : COLOR0
          {
            float4 output = texCUBE(_Cubemap, input.norm);
            return output;
          }
        
    		ENDCG
        }
    	} 
    	FallBack "Diffuse"
    }
  • I found this link useful listing the built-in values for Unity3D which @Chippit described e.g. time

    http://docs.unity3d.com/Manual/SL-BuiltinValues.html
Sign In or Register to comment.