Vertex specular

Hello :slight_smile:

I am attempting to create a highly optimized shader for untextured geometry. Theoretically, this should be pretty easy. Everything was going great until I got to specularity. Apparently, vertex spec only works on OSX unless you use a SetTexture command in the shader.

Target platforms are OSX, Web Player, and Windows.

SetTexture is not appropriate for me. The purpose of the shader is to render untextured geometry in a highly optimized way, such that the graphics device receives only untextured triangles. All lighting (including spec) must be calculated per-vertex.

Shader "Custom/UntexturedLit" {
	Properties {
		//_Color ("Color", Color) = (1,1,1,1)
		_Emission ("Emission", Color) = (0,0,0,1)
		_Ambient ("Ambient", Color) = (0,0,0,1)
		_Diffuse ("Diffuse", Color) = (1,1,1,1)
		_Specular ("Specular", Color) = (1,1,1,1)
		_Shininess ("Shininess", Range(0,1)) = .5
	}
	SubShader {
	
		Pass {
			Material {
				Emission [_Emission]
				Ambient [_Ambient]
				Diffuse [_Diffuse]
				Specular [_Specular]
				Shininess [_Shininess]
			}
			Lighting On
		}
	} 
	//FallBack "Custom/UntexturedColor"
}

As previously stated, everything works great except for the one line Specular [_Specular] which works on my Mac, but not on my laptop PC. Other users have reported similar results.

The real question is, how do I force the GPU to apply the vertex specular on Windows machines without calling SetTexture? Do I need a special vertex/fragment shader for this? If so, how do I make sure the most optimal code is executed?

Thanks for your time :smile:

SetTexture actually just sets up “texture combiner stage”. It doesn’t really have to sample the texture. So you could do:

SetTexture [_DoesNotMatter] { combine primary } // means “use vertex color”

So, if I understand correctly, this will not lead to any texture data being used to fill the triangles?

Shader "Custom/UntexturedLitSpecular" {
    Properties {
        _Color ("Main Color", Color) = (1,1,1,0)
        _SpecColor ("Spec Color", Color) = (1,1,1,1)
        _Emission ("Emmisive Color", Color) = (0,0,0,0)
        _Shininess ("Shininess", Range (0.01, 1)) = 0.7
        //_MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader {
        Pass {
            Material {
                Diffuse [_Color]
                Ambient [_Color]
                Shininess [_Shininess]
                Specular [_SpecColor]
                Emission [_Emission]
            }
            Lighting On
            SeparateSpecular On
            SetTexture [_] {
                Combine primary//Combine texture * primary DOUBLE, texture * primary
            }
        }
    }
}

EDIT!

I figured it out, with some searching. Not only does SetTexture [_] { Combine primary} need to be called, but SeparateSpecular On needs to be declared as well.

…But why?