Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411500 Posts in 69373 Topics- by 58429 Members - Latest Member: Alternalo

April 25, 2024, 01:30:45 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Billboard Shadow Shader
Pages: [1]
Print
Author Topic: Billboard Shadow Shader  (Read 2236 times)
Juskelis
Level 1
*



View Profile
« on: August 25, 2015, 12:04:16 PM »

Today on "shadows suck  Facepalm":

I'm making a billboard shader that uses UV data to transform vertices for vertical billboards. I build the mesh it uses procedurally, and can handle up to 100k billboards at 60FPS. The only problem so far is that those billboards lack shadows that want to cooperate, or I just have no idea what I'm doing. Probably the second one.

I use a fairly straighforward billboard shader for the main billboard, and then use that again for the shadows pass, but have the billboards face the directional light rather than the camera, like so:

Code:
vertexOutput vert(appdata_full input)
{
/*
http://forum.unity3d.com/threads/billboard-shader-using-vertex-offsets-in-color-or-uv2-data.192652/#post-1312516
*/

vertexOutput output;

//calculate direction to light
// ripped from
// http://www.geekyhamster.com/2013/04/lighting-calculations-inside-unitys-cg.html
float3 eyeVector = normalize(
mul(unity_LightPosition[0], UNITY_MATRIX_IT_MV).xyz
);

float3 upVector = float3(0,1,0) * _Scale;
float3 sideVector = normalize(cross(eyeVector, upVector)) * _Scale;

float3 finalposition = input.vertex;
finalposition += (input.texcoord.x - 0.5) * sideVector;
finalposition += (input.texcoord.y) * upVector;

float4 pos = float4(finalposition, 1);

output.tex = input.texcoord;

output.pos = mul(UNITY_MATRIX_MVP, pos);

TRANSFER_VERTEX_TO_FRAGMENT(output);

return output;
}
I do this because I want the projected shadows to work regardless of what direction the billboards themselves are facing. Ultimately I'm trying to do what the particle shader's billboard shadows do.

Mostly this works perfectly fine. I have the shadow pass happen after the normal pass, the only tag for the shadow pass is "LightMode" = "ShadowCaster", and the rest is completely bare. When I go to run, I get weird shadow behavior, like this:


It looks like the shadow applied to the billboard is shifted from the billboard itself, which would make sense, if it was always facing the directional light. However, it isn't; it changes based on camera position/orientation. Any idea on how to fix this/get what I want out of the shader?

Here's the whole shader in case I missed something important
Code:
Shader "Custom/UV Billboard" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Scale ("Scale", Float) = 1
_Cutoff("Cutoff", Range(0,1)) = 0.5
}

/*
//surface shader variant that I'm not using
SubShader {
Tags { "RenderType" = "Opaque" }

CGPROGRAM
#pragma surface surf Lambert vertex:vert addshadow

sampler2D _MainTex;
float _Cutoff;
float _Scale;

struct Input {
float2 uv_MainTex;
};

void vert (inout appdata_full v)
{
float3 eyeVector = ObjSpaceViewDir(v.vertex);

float3 upVector = float3(0,1,0) * _Scale;
float3 sideVector = normalize(cross(eyeVector, upVector)) * _Scale;

float3 finalposition = v.vertex.xyz;
finalposition += (v.texcoord.x - 0.5) * sideVector;
finalposition += (v.texcoord.y) * upVector;

float4 pos = float4(finalposition, 1);

v.vertex = pos;
}

void surf(Input IN, inout SurfaceOutput o) {
clip(tex2D(_MainTex, IN.uv_MainTex).a - _Cutoff);
o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
}
ENDCG
}
*/


SubShader {
Pass{

Tags { "RenderType"="Opaque"}

CGPROGRAM
#include "UnityCG.cginc"

#pragma vertex vert
#pragma fragment frag

uniform sampler2D _MainTex;
uniform float _Scale;
uniform float _Cutoff;

struct vertexOutput {
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;
};

vertexOutput vert(appdata_full input)
{
/*
test stuff from
http://forum.unity3d.com/threads/billboard-shader-using-vertex-offsets-in-color-or-uv2-data.192652/#post-1312516
*/

vertexOutput output;

float3 eyeVector = ObjSpaceViewDir(input.vertex);

float3 upVector = float3(0,1,0) * _Scale;
float3 sideVector = normalize(cross(eyeVector, upVector)) * _Scale;

float3 finalposition = input.vertex;
finalposition += (input.texcoord.x - 0.5) * sideVector;
finalposition += (input.texcoord.y) * upVector;

float4 pos = float4(finalposition, 1);

output.tex = input.texcoord;

output.pos = mul(UNITY_MATRIX_MVP, pos);

return output;
}

float4 frag(vertexOutput input) : COLOR
{
float4 color = tex2D(_MainTex, float2(input.tex.xy));
clip(color.a - _Cutoff);
return color;
}
ENDCG
}

//shadow pass, use light direction rather than view direction
Pass{

Tags {"LightMode" = "ShadowCaster"}

CGPROGRAM
#include "UnityCG.cginc"
#include "AutoLight.cginc"

#pragma vertex vert
#pragma fragment frag

uniform sampler2D _MainTex;
uniform float _Scale;
uniform float _Cutoff;

struct vertexOutput {
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;

LIGHTING_COORDS(1,2)
};

vertexOutput vert(appdata_full input)
{
/*
test stuff from
http://forum.unity3d.com/threads/billboard-shader-using-vertex-offsets-in-color-or-uv2-data.192652/#post-1312516
*/

vertexOutput output;

//calculate direction to light
// ripped from
// http://www.geekyhamster.com/2013/04/lighting-calculations-inside-unitys-cg.html
float3 eyeVector = normalize(
mul(unity_LightPosition[0], UNITY_MATRIX_IT_MV).xyz
);
//eyeVector = normalize(mul(unity_LightPosition[0],UNITY_MATRIX_IT_MV).xyz);

float3 upVector = float3(0,1,0) * _Scale;
float3 sideVector = normalize(cross(eyeVector, upVector)) * _Scale;

float3 finalposition = input.vertex;
finalposition += (input.texcoord.x - 0.5) * sideVector;
finalposition += (input.texcoord.y) * upVector;

float4 pos = float4(finalposition, 1);

output.tex = input.texcoord;

output.pos = mul(UNITY_MATRIX_MVP, pos);

TRANSFER_VERTEX_TO_FRAGMENT(output);

return output;
}

float4 frag(vertexOutput input) : COLOR
{
float atten = LIGHT_ATTENUATION(input);
float4 color = tex2D(_MainTex, float2(input.tex.xy))*atten;
clip(color.a - _Cutoff);
return color;
}
ENDCG
}
}

Fallback "Diffuse"
}
Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic