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
0
Question by jamesflowerdew · Dec 18, 2013 at 02:33 PM · shaderlightinggeometry

A shader that uses lighting but ignores it's own mesh/normals for lighting.

I have two games that have a dynamic lighting system that involes a setting and rising sun/moon so I can't lightmap this. They have custom built terrains, and currently all grasses and trees need tinted via SetColor to match the lighting/ambience. They also do not respond to where they are (grass in cave is as bright as grass on a hilltop). This is because I had to set them to "unlit" or use emission, as when they poster to the camera, they would change colour (as their orientation to the light changed) if they used unity's normal lighting. Is it possible to build shaders that compute lighting based on the location of the object without using the geometry within? this way a grass could be in shadow because it's behind a tree, but lit equally no matter where it faces.

Thanks, James :)

P.S:

Here's a sample of what I'm currently having to use, I set the color in my day/night managent script to be an average of the sun colour and the ambient colour.


Shader "gamevial/Tree" { Properties { _Color ("Main Color", Color) = (1,1,1,1) _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {} }

 SubShader {
     Tags {"Queue"="Transparent" "IgnoreProjector"="True" }
     Lighting Off
     Cull Off
     Alphatest Greater 0.5
     Pass{
         //Alphatest Greater 0.5
         Tags{ "LightMode"="ShadowCaster"}
         SetTexture [_MainTex] {}
     }
     Material{
     
     }
     Pass {
         //Blend SrcAlpha OneMinusSrcAlpha 
         ZWrite On
         Tags{ "LightMode"="Always"}
         SetTexture [_MainTex] {
             constantColor [_Color]
             Combine texture * constant DOUBLE
         }  
     }
     
 
 }

}

Comment
Add comment · Show 10
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 Owen-Reynolds · Dec 18, 2013 at 09:26 PM 0
Share

Yes, you can definitely, for example, send one normal as a parameter (like _Color, but a Vector3.) Then redo lighting to always use that normal.

But I'd guess that ShaderLab (your code snippet) may not allow that much fiddling. Probably a surface shader, with o.normal=myFakeNormal somewhere?

avatar image jamesflowerdew · Jan 03, 2014 at 02:38 PM 0
Share

Hi Owen, and thanks for replying. I still can't get the shader to ignore the geometry normals for lighting. I post my attempt (you'll see other attempts in there too).

 Shader "gamevial/NewGrass" {
     Properties {
         _$$anonymous$$ainTex ("Base (RGB)", 2D) = "white" {}
         _$$anonymous$$yColor ("Some Color", Color) = (0,1,0,1)
 
     }
      SubShader {
           Tags { "RenderType" = "Transparent"  }
         Lighting On
         //Alphatest Greater 0
         //Blend SrcAlpha One$$anonymous$$inusSrcAlpha
             //
             LOD 100
         CGPROGRA$$anonymous$$
            #pragma surface surf Lambert addshadow
            struct Input {
             float2 uv_$$anonymous$$ainTex;
             float3 worldNormal; 
             INTERNAL_DATA
         };
         sampler2D _$$anonymous$$ainTex;
         fixed4 _$$anonymous$$yColor;
         void surf (Input IN, inout SurfaceOutput o) {
             half4 c = tex2D (_$$anonymous$$ainTex, IN.uv_$$anonymous$$ainTex);
             //
             o.Albedo = c.rgb;
             o.Alpha = c.a;
             //o.Emission=_LightColor0;
             o.Normal=(1,1,1,1);//WorldNormalVector(IN, o.Normal); 
             o.Specular=0;
         }
         ENDCG
     }
 }

The object is still lit as based on it's orientation etc. $$anonymous$$y knowledge of cg shaders is poor, so I don't know how stupid my workings are, appologies in advance.

avatar image kromenak · Jan 04, 2014 at 03:21 AM 1
Share

It's been awhile since I've worked with CG shaders, but I'd suggest starting with the simplest possible shader, like those outlined here: http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderExamples.html

For example, the first textured shader on that page doesn't use normals at all in the definition - maybe that would solve your problem?

FWIW, I tested this shader, and it doesn't seem to have the issue you're describing where view angle causes the lighting to change. However, it might be missing other features that you need for the shader in your game:

 Shader "HVS_WIP/Surface" 
 {
     Properties 
     {
         _$$anonymous$$ainTex ("Texture", 2D) = "white" {}
         _Color ("Color (RGB)", Color) = (0.5, 0.5, 0.5, 1.0)
     }
      
     // Surface Shader
     SubShader
     {
         Tags { "RenderType" = "Opaque" }
     
         CGPROGRA$$anonymous$$
         
         #pragma surface surf Lambert 
 
             // Add these as an optimization
         //noforwardadd nolightmap nodirlightmap approxview halfasview
         
         uniform sampler2D_half _$$anonymous$$ainTex;
         uniform fixed4 _Color;
         
         struct Input
         {
             float2 uv_$$anonymous$$ainTex;
         };
         
         void surf(Input i, inout SurfaceOutput o)
         {
             o.Albedo = tex2D(_$$anonymous$$ainTex, i.uv_$$anonymous$$ainTex).rgb;
         }
         
         ENDCG
     }
 }

Hope it helps, but again, I'm unfortunately a bit out of practice with writing shaders :-\

avatar image jamesflowerdew · Jan 07, 2014 at 11:00 AM 0
Share

Thanks $$anonymous$$romenak, this shader kind-of worked. I needed to turn shadows on as shadow maps from objects behind were overwriting in front of all instances of the objects, the effect is now amazing, but I suspect that a surface shader is overkill here. All I theoretically need to do is compute what kind of light is being received, and multiply it by the texture. Really bad pseudo-code follows...

 $$anonymous$$aterial{
         Emission(_AmountoflightHittingSaidPoint)
 }
 Pass {
     SetTexture [_$$anonymous$$ainTex] {
           
           Combine texture * primary
     }
 }

"_AmountOfLightHittingSaidPoint" would be a mix of the ambient lighting and a sum of the lights (and ideally but not necessarily the shadows) affecting the model.

I'm doing grass here, so having a shader that does as little work as possible is the ideal here.

I also include the edited version of your shader below, $$anonymous$$romenak, as it is awesome. Thanks! (note: I added a fallback simpler shader for older cards)

 Shader "HVS_WIP/Surface" 
 {
     Properties {
      _$$anonymous$$ainTex ("Texture", 2D) = "white" {}
      _Cutoff ("Cutoff", float) = 0.5
      _Colour ("Fallback Colour",Color)=(1,1,1,1)
     }
     // Surface Shader
     SubShader {
         Tags { "RenderType" = "GrassBillboardShader" }
         ZWrite On
         CGPROGRA$$anonymous$$
         #pragma surface surf Lambert alphatest:_Cutoff addshadow halfasview
         // Add these as an optimization
         
         uniform sampler2D_half _$$anonymous$$ainTex;
          //fixed _Cutoff;
        struct Input{
          float2 uv_$$anonymous$$ainTex;
          fixed _Cutoff;
        };
  
        void surf(Input IN, inout SurfaceOutput o) {
            fixed4 c=tex2D(_$$anonymous$$ainTex, IN.uv_$$anonymous$$ainTex);
          o.Albedo = c.rgb;
          o.Alpha =tex2D(_$$anonymous$$ainTex, IN.uv_$$anonymous$$ainTex).a;
         
        }
  
        ENDCG
     }
     
      SubShader {
         Tags { "RenderType" = "GrassBillboardShader" }
             ZWrite On
             Lighting On
             Cull Back
             AlphaTest Greater [_Cutoff]
             Blend SrcAlpha One$$anonymous$$inusSrcAlpha
             $$anonymous$$aterial{
             Ambient(1,1,1,1)
                 Diffuse[_Colour]
                 //Emission[_Colour]
             }
             Pass {
                   SetTexture [_$$anonymous$$ainTex] {
                       constantColor [_Colour]
                     Combine texture * primary
                 }
             }
     }
 }
 
avatar image jamesflowerdew · Apr 28, 2014 at 11:41 AM 0
Share

I never found a simpler shader solution for this than the above, but I found a Hack, which sometimes does the trick. Ins$$anonymous$$d of building a shader that overwrites or ignores the normals you can edit the meshes to point all normals in one direction which then allows you to create roughly the same illusion regardless of shader (so you can use dirt cheap ones :) ). An example is given below.

 using UnityEngine;
 #if UNITY_EDITOR
 using UnityEditor;
 #endif
 using System.Collections;
 
 public class leavesNormals : $$anonymous$$onoBehaviour {
     public bool DoIt;
     public string pName;
     // Use this for initialization
     void Start () {
     
     }
     
     // Update is called once per frame
     void Update () {
     
     }
     
     void OnDrawGizmosSelected(){
         if(DoIt){
             
             DoIt=false;
             $$anonymous$$eshFilter v$$anonymous$$eshFilter=GetComponent<$$anonymous$$eshFilter>();
             $$anonymous$$esh v$$anonymous$$esh=v$$anonymous$$eshFilter.mesh;
             if(pName==""){
                 pName=v$$anonymous$$esh.name;
             }
                 Vector3[] vNormals=v$$anonymous$$esh.normals;
             for (int i=0;i<vNormals.Length;i++){
                 
                 vNormals[i]=Vector3.up;
             }
             v$$anonymous$$esh.normals=vNormals;
             #if UNITY_EDITOR
             AssetDatabase.CreateAsset( v$$anonymous$$esh, "Assets/$$anonymous$$yAssets/TreeFabs/"+pName+".asset");
         
                AssetDatabase.SaveAssets();
 #endif
         }
     }
 }

Click the boolean on the inpector to make a "flattened" mesh copy saved to the folder "Assetts/$$anonymous$$yAssets/Treefabs" in your project folder. I'd still love to know how to do the above, but hope this helps others in my spot.

Show more comments

0 Replies

· Add your reply
  • Sort: 

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

20 People are following this question.

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

Related Questions

Adding a Pass to the Standard Shader 0 Answers

Block/Obscure light without shadows 0 Answers

How can I add metalic and occlusion to my lighting model? 0 Answers

Mesh based volumetric lighting with RenderTexture 1 Answer

Help with adding a normalmap to a shader 1 Answer


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