Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by headkitgames · Oct 22, 2010 at 09:47 AM · iphoneshadow

shadow on plane for iphone

hi folks!

could anybody explain to me how I could make a simple plane generate some shadow on an object?

thnx!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
4
Best Answer

Answer by Peter G · Oct 23, 2010 at 06:20 PM

You have 3 options depending on what you want since you cannot use realtime shadows on Unity iPhone. I don't know if iPhone 4 even supports it, but at no level will the engine let you.

  1. You can use a projector or blob-shadow. You can use the built-in prefab if you want, but you will need to create a texture that looks like the shadow from a plane. (I'm pretty sure a square plane will never cast that generic round shadow :).) That will give you the best looking result for the iPhone. Since it is a projector, it will fit to your geometry, and always be drawn on top. But, the biggest down side is that there are many "wasted" draw calls when using projectors. Meaning, that projectors require that every object is drawn at least once more so draw calls can get too high quickly.

  2. Another faster method would be to create another plane at ground level with your shadow texture put on it. Then parent you first plane to it. Then your "shadow" will follow your plane like it is a real shadow, and you are will only be charged 1 draw call. The disadvantage, this won't work with uneven terrain.

  3. The third and by far the best if the object doesn't move is to light map it. You can do that in your modeler or in Unity's brand new Beast light mapping tool. That would look the best if your object doesn't move, and be most efficient. The only downside might be that PVTRC compression takes away some quality, but you would more than likely see that in all your textures in exchange for faster performance and load times.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image headkitgames · Oct 25, 2010 at 10:27 AM 0
Share

thank you, man!

avatar image
2

Answer by ricardo_arango · Sep 02, 2011 at 02:45 PM

You can use the following script and shader to project a Mesh onto a plane. Just attach the script to the GameObject with the Renderer Component:

SCRIPT (C#):

using UnityEngine; using System.Collections.Generic;

[RequireComponent(typeof(Renderer))]
public class PlaneShadows : MonoBehaviour { public Transform plane; public Renderer objToProjectRenderer; private GameObject _objShadow; public Material shadowMaterial; private Material _shadowMaterial; public Light theLight; public Camera cam; private Matrix4x4 mat = new Matrix4x4(); private Vector3 L, n, E; private float c, d;

 public void SetUp (){
     // Create a copy of the obj to project
     _objShadow = new GameObject(objToProjectRenderer.gameObject.name + " shadow");
     _objShadow.hideFlags = HideFlags.HideInHierarchy;

     if(objToProjectRenderer.GetType() == typeof(MeshRenderer)){
         _objShadow.AddComponent<MeshFilter>();
         _objShadow.GetComponent<MeshFilter>().sharedMesh = objToProjectRenderer.gameObject.GetComponent<MeshFilter>().sharedMesh;

         MeshRenderer shadowMR = _objShadow.AddComponent<MeshRenderer>();
         shadowMR.sharedMaterial = shadowMaterial;
         shadowMR.castShadows = false;
         shadowMR.receiveShadows = false;

         _shadowMaterial = shadowMR.sharedMaterial;
     }
     else{
         if(objToProjectRenderer.GetType() == typeof(SkinnedMeshRenderer)){
             SkinnedMeshRenderer objectSMR = (SkinnedMeshRenderer)objToProjectRenderer;
             SkinnedMeshRenderer shadowSMR = _objShadow.AddComponent<SkinnedMeshRenderer>();

             shadowSMR.sharedMesh = objectSMR.sharedMesh;
             shadowSMR.bones = objectSMR.bones;
             shadowSMR.sharedMaterial = shadowMaterial;
             shadowSMR.castShadows = false;
             shadowSMR.receiveShadows = false;

             _shadowMaterial = shadowSMR.sharedMaterial;
         }
     }
 }

 void Start(){
     SetUp ();
 }

 void Update(){  
     if(_objShadow){
         _objShadow.transform.position = objToProjectRenderer.transform.position;
         _objShadow.transform.rotation = objToProjectRenderer.transform.rotation;
         _objShadow.transform.localScale = objToProjectRenderer.transform.localScale;        

         switch(theLight.type){
             case LightType.Point:
                 // Calculate the projection matrix
                 // Let L be the position of the light
                 // P the position of a vertex of the object we want to shadow
                 // E a point of the plane (not seen in the figure)
                 // n the normal vector of the plane

                 L = theLight.transform.position;
                 n = -plane.up;
                 E = plane.position;

                 d = Vector3.Dot(L, n);
                 c = Vector3.Dot(E, n) - d;

                 mat[0, 0] = L.x*n.x + c;
                 mat[1, 0] = L.y*n.x;
                 mat[2, 0] = L.z*n.x;
                 mat[3, 0] = n.x;

                 mat[0, 1] = L.x*n.y;
                 mat[1, 1] = L.y*n.y + c;
                 mat[2, 1] = L.z*n.y;
                 mat[3, 1] = n.y;

                 mat[0, 2] = L.x*n.z;
                 mat[1, 2] = L.y*n.z;
                 mat[2, 2] = L.z*n.z + c;
                 mat[3, 2] = n.z;

                 mat[0, 3] = -L.x * (c+d);
                 mat[1, 3] = -L.y * (c+d);
                 mat[2, 3] = -L.z * (c+d);
                 mat[3, 3] = -d;
             break;

             case LightType.Spot:
                 goto case LightType.Directional;

             case LightType.Directional:
                 // Calculate the projection matrix
                 // Let L be the direction of the light
                 // P the position of a vertex of the object we want to shadow
                 // E a point of the plane (not seen in the figure)
                 // n the normal vector of the plane

                 L = theLight.transform.forward;
                 n = -plane.up;
                 E = plane.position;

                 d = Vector3.Dot(L, n);
                 c = Vector3.Dot(E, n);

                 mat[0, 0] = d-n.x*L.x;
                 mat[1, 0] = -n.x*L.y;
                 mat[2, 0] = -n.x*L.z;
                 mat[3, 0] = 0;

                 mat[0, 1] = -n.y*L.x;
                 mat[1, 1] = d-n.y*L.y;
                 mat[2, 1] = -n.y*L.z;
                 mat[3, 1] = 0;

                 mat[0, 2] = -n.z*L.x;
                 mat[1, 2] = -n.z*L.y;
                 mat[2, 2] = d-n.z*L.z;
                 mat[3, 2] = 0;

                 mat[0, 3] = c*L.x;
                 mat[1, 3] = c*L.y;
                 mat[2, 3] = c*L.z;
                 mat[3, 3] = d;
             break;
         }

         Shader.SetGlobalMatrix("_projectionMatrix", mat);
         Shader.SetGlobalMatrix("_viewInv", cam.cameraToWorldMatrix);
         Shader.SetGlobalMatrix("_view", cam.worldToCameraMatrix);
         _shadowMaterial.SetVector("_planeNormal", plane.up);
     }
 }

}

SHADER:

Shader "PlaneShadows" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _ShadowColor ("Shadow Color", Color) = (1,1,1,1) _planeNormal ("Plane Normal", Vector) = (0,0,0,0) _shadowBias ("Bias", Float) = 0.01 } SubShader { Pass { Tags{ "RenderType" = "Opaque" "Queue" = "Opaque" } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma exclude_renderers xbox360 #pragma exclude_renderers ps3 #pragma target 3.0

             float4 _planeNormal;
             float4 _ShadowColor;
             float _shadowBias;

             float4x4 _projectionMatrix;
             float4x4 _viewInv;
             float4x4 _view;

             // vertex input: position, UV
             struct appdata {
                 float4 vertex : POSITION;
                 float4 texcoord : TEXCOORD0;
             };
             struct v2f {
                 float4 pos : SV_POSITION;
                 float4 uv : TEXCOORD0;
             };              
             v2f vert (appdata v) {
                 v2f o;

                 // Get model (world) matrix
                 float4x4 modelMatrix = mul(_viewInv, UNITY_MATRIX_MV);

                 // Transform to world
                 float4 vertex = mul (modelMatrix, v.vertex);
                 // Project to plane
                 float4 pos = mul (_projectionMatrix, vertex);
                 // Add shadow bias
                 pos += _planeNormal * _shadowBias;
                 // Transform to view
                 pos = mul (_view, pos);
                 // Project to screen
                 o.pos = mul (UNITY_MATRIX_P, pos);

                 return o;
             }               
             half4 frag( v2f i ) : COLOR {
                 return _ShadowColor;
             }               
         ENDCG
     }
 }

}

The code is based on this : http://www.devmaster.net/articles/shadowprojection/

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image roamcel · Nov 06, 2011 at 08:02 AM 0
Share

@ricardo_arango thanks for the useful script but I have a question, is there a chance that the script or the shader can cast on the deformed terrain or objects? The result of the above works on a flat plane, but does not follow terrain anomalies.

avatar image ricardo_arango ♦♦ · Nov 24, 2011 at 04:58 PM 0
Share

You can use a projector for that.

avatar image cregox · Nov 07, 2012 at 10:08 AM 0
Share

tempting idea, but link is broken and couldn't make this works as is. I got just a grey flat fog on the ground that looks almost nothing like a shadow.

avatar image kieec · Mar 05, 2013 at 10:50 AM 0
Share

Hi~Ricardo Does it accept multiple models to project shadows? Thanks! Also I tried on my skinned character with animations and only one element of plygon casts shadow. Have you tried on this?

avatar image ricardo_arango ♦♦ · Mar 08, 2013 at 03:20 PM 0
Share

@Cawas: It works if projected on a plane. It is the object squashed. In Unity 4 shadows are supported on mobile devices and you can use those. Note that the script as it is only work in the Game View after entering play mode.

@kieec : You need to add the script to each Renderer. You could also try modifying it to take more than one renderer.

Show more comments
avatar image
1

Answer by zannghast · Oct 22, 2010 at 09:54 AM

I recommend you skimming through the 3D Platform Game (a.k.a. "Lerpz" Tutorial) found here: Link

Skip everything in the manual and find the section on creating the protagonist's simple shadow. That's a comprehensive, albeit simple, tutorial on how to create a shadow.

Some simple advise though:

  • I'm not sure you can make the Plane object (or any flat mesh for that matter) generate shadows for you. To my knowledge, it's always through dynamic lighting, baking the shadow, or some other neat trick involving totally separate objects.
  • If you're developing for the iPhone (and if you're still considering a 3G release), you're better off "baking" the shadows - that is, creating 'fake' blobs of black or gray that is essentially a "part" of your imported object. Real-time shadows is a big no no in this area.
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image headkitgames · Oct 25, 2010 at 10:27 AM 0
Share

thank you, man!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Are soft shadows supported on iOS ? 2 Answers

Do blob shadow projectors work on iPhone? 1 Answer

Support for dynamic shadows on newer iOS devices (supporting OpenGL ES 2.0) 1 Answer

blob shadow z-fighting on iphone 3 Answers

fake shadow with least performance hit 4 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges