Saturday, January 15, 2011

Planet Shader #2

Possibly slightly more correct lighting. The rim light is now only applied in the direction of the sun, rather than being purely based on view position.
Shader "Planet" {
Properties {
_MainTex ("Diffuse(RGB) Spec(A)", 2D) = "white" {}
_BumpMap ("Bumpmap", 2D) = "bump" {}
_RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0)
_RimPower ("Rim Power", Range(0,8.0)) = 3.0
_SpecColor ("Specular Color", Color) = (0.5,0.5,0.5,1)
_Shininess ("Shininess", Range (0.01, 1)) = 0.078125


SubShader {
Tags { "RenderType" = "Opaque" }

#pragma surface surf Planet

float _Shininess;
sampler2D _MainTex;
sampler2D _BumpMap;
float4 _RimColor;
float _RimPower;

half4 LightingPlanet (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
half3 h = normalize (lightDir + viewDir);
half diff = max (0, dot (s.Normal, lightDir));
float nh = max (0, dot (s.Normal, h));
float spec = pow (nh, 48.0);
half rim = ((1 - (dot (normalize(viewDir), (s.Normal)))) + ((dot (normalize(lightDir), (s.Normal)))));
half4 c;
c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec * s.Alpha * _Shininess * _SpecColor) * (atten * 2);
c.rgb = c.rgb * (pow (rim, _RimPower) * _RimColor.rgb);
return c;

struct Input {
float2 uv_MainTex;
float2 uv_BumpMap;
float3 viewDir;
float3 worldRefl; INTERNAL_DATA

void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
o.Alpha = tex2D (_MainTex, IN.uv_MainTex).a;

Fallback "Diffuse"


Petroz said...

Very nice! May I use this in my game?

Simon Wittber said...

Of course!

BloodRiot said...

Hello there... on your imagem it looks great. Unfortunatly i only get a black sphere when i try it. It is not illuminated in any way.

Using unity 3.x indie with one light (tried all 3 types) on a sphere object.

Am i doing something wrong?


Simon Wittber said...

I'm not sure what the problem is, so I'll just give you what I have. You can download the package here.

BloodRiot said...

Thanks Simon. unfortunatly i'm still getting the same result. I seem to have missed a console error before but i noticed it as soon as i tried your scene.

Shader error in 'Planet': D3D shader assembly failed with: (61): error X5204: Read of uninitialized component(*) in r0: r/x/0 g/y/1 b/z/2 *a/w/3

Not really sure what this is about unfortunatly.

But thanks mate :) Really appreciate the help so far :)

Simon Wittber said...

Hmm, looks like it needs some modifications to work on Windows. Strange, I thought Unity's ShaderLab took care of that.

Anonymous said...

Add the line:

c.a = 1.0;

after the c.rgb = c.rgb * ... line.

ThorOfAsgaard said...

Doesn't look like the c.a = 1.0; comment did anything for me. Any other suggestions?

Unity3d 3 on Windows, btw.

Robert Dzikowski said...

I too use Unity 3 (free version) on Windows. I added c.a = 1.0; line, rebuild solution and it works.

Jonathan Dumaine said...

I got it to work on Windows by adding the c.a = 1.0 too.

It may be because Windows Unity defaults to D3D9. Adding a '-force-opengl' flag when launching might have solved the discrepancy as well, but Simon is right: Unity should be handling the Shader compilation similarly regardless of platform

Popular Posts