Home Technical Talk

JIStyles' Skin no likey Max2009

When I try loading JIStyles_skinshader_R3.fx in Max 2009's DirectX Shader material, I get the red wireframe...
C:\Program Files\Autodesk\3ds Max 2009\memory(375,14): error X3000: syntax error: unexpected token 'VertexShader'

I'll email Joel, but has anyone else got it to work in Max 2009?

Replies

  • MoP
    Offline / Send Message
    MoP polycounter lvl 18
    Nope. I get the same problem in 2008 as well. I just ended up using the StandardFX.fx file that ships with Max, it does most of what I want anyway. Doesn't do the fake SSS, but that's ok.
  • Mark Dygert
    I gave up on waiting for an update and use the standardFX file that MoP pointed to. I had hoped that for some miraculous reason it would work with 2009 (haven't installed it yet have to wait until next cycle)

    The standardFX does a decent job for what I need it to do.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    I can look at it tomorrow (dont have 2009 at home), trivially I would firs try that "VertexShader" functions should be renamed to something else as its both a reserved keyword and a function here...

    that is make line 375: (which is also in your error message you posted)
    VertexOutput VertexShader_main(ApplicationData IN,uniform half4 LightPosition)

    and then later in the technique block at the end do:
    VertexShader = compile vs_1_1 VertexShader_main(LightPosition1);

    which appears a couple times, replace the second VertexShader with VertexShader_main
  • TSM
    Fixed it ... well kinda - Haven't tested it but it compiles now. I had to comment out some math in the Translucency lighting model function. Might looked borked.
    //==============================Info===============================
    /*
    
    Soft Light Skin Shader
    release 1 (First public release)
    
    History:
    	
    	- R1 (10/05/2006): Initial beta release
    	
    ----------------------------------------------------
    
    Written by Joel Styles (aka J.I. Styles)
    http://www.jistyles.com
    
    Description:
    	Another day, another skin shader -- getting believable organics is one
    	of those holy grails of cg, and we're only just starting to get closer to 
    	that goal in real-time. After a lot of research into skin, this is my attempt
    	at getting somewhere close to that, so this is my visual approximation.
    	As always, I don't think this shader is quite up to development standards
    	code-wise -- I'm an artist, not a programmer, so don't expect the most
    	pretty code out there ;)
    		
    	happy tinkering! :D
    	-Joel
    
    Features:
    	- Diffuse
    	- Soft Light blending algorithm
    	- Normal map lighting model
    	- Translucency kludge (based off melanin and hemoglobin tones)
    	- Correct fresnel ramped specular
    	- 3, 2, and 1 light setup technique's
    
    Known nasties:
    	- No shadow occlusion
    	- Controls still quite tweaky
    	- Not fully tested on a wide range of hardware
    	- No depth ramp, it's a constant 
    	(eg, no differentiation between a thin ear and a thick skull)
    	
    Referances & thanks:
    	Ben Cloward - used your normal lighting method too :)
    	Nvidia samples
    	Direct X sdk
    	Shader X2
    	Polycount
    	Sumea
    	CGtalk
    
    
    
    
    */
    //=============================Globals==============================
    half4x4 WorldIT 		:	WorldInverseTranspose	< string UIWidget = "None"; >;
    half4x4 WorldVP 		:	WorldViewProjection 	< string UIWidget = "None"; >;
    half4x4 World 		:	World 			< string UIWidget = "None"; >;
    half4x4 ViewI 		:	ViewInverse 		< string UIWidget = "None"; >;
    //================================UI================================
    half4 LightPosition1 : POSITION
    <
    	string Object = "PointLight";
    	string UIName =  "Light 1";
    	string Space = "World";
    	int refID = 0;
    > 	= {1403.0f, 1441.0f, 1690.0f, 0.0f};
    
    
    half4 LightColour1 : LIGHTCOLOR
    <
    	int LightRef = 0;
    > 	= { 1.0f, 1.0f, 1.0f, 0.0f };
    
    
    half4 LightPosition2 : POSITION
    <
    	string Object = "PointLight";
    	string UIName =  "Light 2";
    	string Space = "World";
    	int refID = 1;
    > 	= {1403.0f, 1441.0f, 1690.0f, 0.0f};
    
    
    half4 LightColour2 : LIGHTCOLOR
    <
    	int LightRef = 1;
    > 	= { 1.0f, 1.0f, 1.0f, 0.0f };
    
    
    half4 LightPosition3 : POSITION
    <
    	string Object = "PointLight";
    	string UIName =  "Light 3";
    	string Space = "World";
    	int refID = 2;
    > 	= {1403.0f, 1441.0f, 1690.0f, 0.0f};
    
    
    half4 LightColour3 : LIGHTCOLOR
    <
    	int LightRef = 2;
    > 	= { 1.0f, 1.0f, 1.0f, 0.0f };
    
    half4 SpecColour
    <
    	string UIWidget = "Color";
    	string UIName =  "Specular Colour";
    >  = {0.45f, 0.65f, 1.0f, 1.0f};
    
    
    half SpecPower
    <
    	string UIWidget = "Slider";
    	half UIMin = 0.0;
    	half UIMax = 100.0;
    	half UIStep = 0.01;
    	string UIName =  "Specular Power";
    > = 0.2;
    
    
    half SpecGloss
    <
    	string UIWidget = "Slider";
    	half UIMin = 0.0;
    	half UIMax = 100.0;
    	half UIStep = 0.01;
    	string UIName =  "Specular Glossiness";
    > = 15.0;
    
    half SpecFresnel
    <
    	string UIWidget = "Slider";
    	half UIMin = 0.0;
    	half UIMax = 100.0;
    	half UIStep = 0.01;
    	string UIName =  "Specular Fresnel";
    > 	= 3.0;
    
    half FresnelPower
    <
    	string UIWidget = "Slider";
    	half UIMin = 0.0;
    	half UIMax = 100.0;
    	half UIStep = 0.01;
    	string UIName =  "Specular Fresnel Power";
    > 	= 15.0;
    
    
    half FresnelGloss
    <
    	string UIWidget = "Slider";
    	half UIMin = 0.0;
    	half UIMax = 100.0;
    	half UIStep = 0.01;
    	string UIName =  "Specular Fresnel Gloss";
    > 	= 0.0;
    
    half4 TransColIn
    <
    	string UIWidget = "Color";
    	string UIName =  "Translucency - Unscattered";
    >  = {0.87f, 0.91f, 0.96f, 1.0f};
    
    half4 TransColOut
    <
    	string UIWidget = "Color";
    	string UIName =  "Translucency - Melanin";
    >  = {1.0f, 0.71f, 0.32f, 1.0f};
    
    half4 TransColBack
    <
    	string UIWidget = "Color";
    	string UIName =  "Translucency - Hemoglobin";
    >  = {0.58f, 0.2f, 0.24f, 1.0f};
    
    half TransMultiplier
    <
    	string UIWidget = "Slider";
    	half UIMin = 0.0;
    	half UIMax = 100.0;
    	half UIStep = 0.01;
    	string UIName = "Translucent Power";
    > 	= 1.0;
    
    half TransRampOff
    <
    	string UIWidget = "slider";
    	half UIMin = -100.0;
    	half UIMax = 100.0;
    	half UIStep = 0.01;
    	string UIName = "Translucent Ramp Off";
    > 	= 1.5;
    
    half MicroScale
    <
    	string UIWidget = "slider";
    	half UIMin = -1000;
    	half UIMax = 1000;
    	half UIStep = 1;
    	string UIName = "Micro Structure Scale";
    > 	= 50;
    
    texture DiffTex
    <
    	string name = "Blank_Diff.tga";
    	string UIName = "Diffuse Map";
    	string TextureType = "2D";
    >;
    
    texture NormalTex
    <
        string name = "default_bump_normal.dds";
    	string UIName = "Normal Map";
        string TextureType = "2D";
    >;
    
    texture MicroTex
    <
        string name = "default_bump_normal.dds";
    	string UIName = "Micro Structure Map";
        string TextureType = "2D";
    >;
    
    texture SpecTex
    <
    	string name = "Blank_Spec.tga";
    	string UIName = "Specular Map RGBA";
    	string TextureType = "2D";
    >;
    
    texture TransTex
    <
    	string name = "Blank_Trans.tga";
    	string UIName = "Translucency Map RGBA";
    	string TextureType = "2D";
    >;
    
    
    //============================Texture samplers==============================
    sampler2D DiffSampler = sampler_state
    {
    	Texture	=	<DiffTex>;
    	MinFilter	=	Linear;
    	MagFilter	=	Linear;
    	MipFilter	=	Linear;
    	AddressU	=	WRAP;
    	AddressV	=	WRAP;
    };
    
    
    sampler2D SpecSampler = sampler_state
    {
    	Texture	=	<SpecTex>;
    	MinFilter	=	Linear;
    	MagFilter	=	Linear;
    	MipFilter	=	Linear;
    	AddressU	=	WRAP;
    	AddressV	=	WRAP;
    };
    
    sampler2D TransSampler = sampler_state
    {
    	Texture	=	<TransTex>;
    	MinFilter	=	Linear;
    	MagFilter	=	Linear;
    	MipFilter	=	Linear;
    	AddressU	=	WRAP;
    	AddressV	=	WRAP;
    };
    
    sampler2D NormalSampler = sampler_state
    {
    	Texture	=	<NormalTex>;
    	MinFilter	=	Linear;
    	MagFilter	=	Linear;
    	MipFilter	=	Linear;
    	AddressU	=	WRAP;
    	AddressV	=	WRAP;
    };
    
    sampler2D MicroSampler = sampler_state
    {
    	Texture	=	<MicroTex>;	
    	MinFilter	=	Linear;
    	MagFilter	=	Linear;
    	MipFilter	=	Linear;
    	AddressU	=	WRAP;
    	AddressV	=	WRAP;
    
    };
    //============================Input Structures============================
    //application data passed to vertex shader
    struct ApplicationData 
    {
    	half4 Position	:	POSITION;
    	half2 UV		:	TEXCOORD0;
    	half3 Normal	:	NORMAL;
    	half3 Tangent	: 	TANGENT;
    	half3 Binormal	: 	BINORMAL;
    
    
    };
    
    
    //vertex shader data passed to pixel shader
    struct VertexOutput 
    {
    	half4 Position		:	POSITION;
    	half2 TexCoord		:	TEXCOORD0;
    	half3 WorldNormal	:	TEXCOORD1;
    	half3 EyeVec     		:	TEXCOORD2;
    	half3 LightVec		:	TEXCOORD3;
    	half3 WorldTangent	: 	TEXCOORD4;
    	half3 WorldBinormal	: 	TEXCOORD5;
    };
    
    //=======================Translucency lighting model=======================
    half4 TransPass(	half4 DotLN,
    			half2 TexUV)
    {
    	float4 Translucence 	= smoothstep(-TransRampOff  * tex2D(TransSampler,TexUV),1.0,DotLN);// - smoothstep(1,1,DotLN);
    	half4 Colourise		= lerp(TransColBack, lerp(TransColOut * TransMultiplier,TransColIn,DotLN),Translucence);
    	
    	return (Colourise*Translucence);
    }
    
    //================Specular component 1 (front on)=======================
    half4 SpecularFrontOn(	half3 Normals,
    					half3 EyeVec,
    					half3 LightVec,
    					half4 Power,
    					half4 Gloss)
    {
    	half3 SpecReflect = (2 * dot(Normals,LightVec) * Normals - LightVec);
    	half4 Specular = pow(saturate(dot(SpecReflect, EyeVec)), Gloss) * Power;
    
    	return Specular;
    }
    
    
    half4 FresnelMask(	half3 Normals,
    				half3 EyeVec)
    {
    	half4 Fresnel = dot(EyeVec,Normals) * SpecFresnel;
    	return saturate(Fresnel);
    }
    
    //==============================Vertex shader================================
    VertexOutput v(ApplicationData IN, uniform half4 LightPosition) 
    {
    	VertexOutput OUT;
    
    	OUT.WorldNormal 	= mul(IN.Normal, WorldIT).xyz;
    	OUT.WorldTangent 	= mul(IN.Tangent, WorldIT).xyz;
    	OUT.WorldBinormal 	= mul(IN.Binormal, WorldIT).xyz;
    	 
    	half3 WorldSpacePos 	= mul(IN.Position, World);
    	OUT.LightVec 		= LightPosition - WorldSpacePos;
    	OUT.TexCoord.xy 	= IN.UV;
    	OUT.EyeVec 		= ViewI[3].xyz - WorldSpacePos;
    	OUT.Position 		= mul(IN.Position, WorldVP);
    	return OUT;
    	
    }
    
    
    //================================Pixel shader - Complete================================
    half4 p(VertexOutput IN, uniform half4 LightColour) : COLOR 
    {
    	
    	half2 TexUV		= IN.TexCoord.xy;
    	half3 normal 		= (tex2D(NormalSampler,TexUV).xyz * 2.0 - 1.0)
    					+ (tex2D(MicroSampler,TexUV*MicroScale).xyz * 2.0 - 1.0);
    	
    half3 WN = IN.WorldNormal;
    half3 TN = IN.WorldTangent;
    half3 BN = IN.WorldBinormal;
    
    half3 N = (WN * normal.z) + (normal.x * BN + normal.y * -TN);
    N = normalize(N);
    	
    		half3 EV 			= normalize(IN.EyeVec);
    		half3 LV 			= normalize(IN.LightVec.xyz);
    	
    		half4 DotLN		= dot(LV,N);
    
    	half4 Translucency	= TransPass(DotLN,TexUV);
    	half4 a 			= tex2D(DiffSampler,TexUV);
    	half4 b 			= (Translucency);
    	half4 BaseLighting	= ((1 - a) * (a*b) + a * (1 - (1 - a) * (1 - b))) * b;
    
    
    	half4 FresnelStrength	= saturate(1 - FresnelMask(WN,EV)) * FresnelPower + 1;
    	half4 FresnelGlossiness	= FresnelMask(WN,EV) * FresnelGloss + 1;
    	half4 Spec			= SpecularFrontOn(N,EV,LV,SpecPower * FresnelStrength ,SpecGloss * FresnelGlossiness * tex2D(SpecSampler,TexUV).a)
    					* SpecColour
    					* tex2D(SpecSampler,TexUV)
    					* Translucency.x;
    	
    	half4 LightingOutput	= BaseLighting
    					* LightColour
    					+ Spec;
    	
    	return LightingOutput;
    } 
    
    //================================TECHNIQUES================================
    
    technique SkinShader_Complete_1Light
    {
    	pass componentlight1
    	{		
    		VertexShader 	= compile vs_1_1 v(LightPosition1);
    		ZEnable 		= true;
    		ZWriteEnable 	= true;
    		AlphaBlendEnable	= false;
    		SrcBlend 		= SrcAlpha;
    		DestBlend 		= InvSrcAlpha;
    		CullMode 		= CW; //None, CW, or CCW
    		PixelShader 	= compile ps_2_0 p(LightColour1);
    	}
    }
    
    technique SkinShader_Complete_2Lights
    {
    	pass componentlight1
    	{		
    		VertexShader 	= compile vs_1_1 v(LightPosition1);
    		ZEnable 		= true;
    		ZWriteEnable 	= true;
    		AlphaBlendEnable	= false;
    		SrcBlend 		= SrcAlpha;
    		DestBlend 		= InvSrcAlpha;
    		CullMode 		= CW; //None, CW, or CCW
    		PixelShader 	= compile ps_2_0 p(LightColour1);
    	}
    	
    		pass componentlight2
    	{		
    		VertexShader 	= compile vs_1_1 v(LightPosition2);
    		ZEnable 		= true;
    		ZWriteEnable 	= false;
    		ZFunc 		= LessEqual;
    		AlphaBlendEnable	= true;
    		SrcBlend 		= SrcAlpha;
    		DestBlend 		= One;
    		CullMode 		= CW; //None, CW, or CCW
    		PixelShader 	= compile ps_2_0 p(LightColour2);
    	}
    }
    
    technique SkinShader_Complete_3Lights
    {
    	pass componentlight1
    	{		
    		VertexShader 	= compile vs_1_1 v(LightPosition1);
    		ZEnable 		= true;
    		ZWriteEnable 	= true;
    		AlphaBlendEnable	= false;
    		SrcBlend 		= SrcAlpha;
    		DestBlend 		= InvSrcAlpha;
    		CullMode 		= CW; //None, CW, or CCW
    		PixelShader 	= compile ps_2_0 p(LightColour1);
    	}
    	
    		pass componentlight2
    	{		
    		VertexShader 	= compile vs_1_1 v(LightPosition2);
    		ZEnable 		= true;
    		ZWriteEnable 	= false;
    		ZFunc 		= LessEqual;
    		AlphaBlendEnable	= true;
    		SrcBlend 		= SrcAlpha;
    		DestBlend 		= One;
    		CullMode 		= CW; //None, CW, or CCW
    		PixelShader 	= compile ps_2_0 p(LightColour2);
    	}
    	
    		pass componentlight3
    	{		
    		VertexShader 	= compile vs_1_1 v(LightPosition3);
    		ZEnable 		= true;
    		ZWriteEnable 	= false;
    		ZFunc 		= LessEqual;
    		AlphaBlendEnable	= true;
    		SrcBlend 		= SrcAlpha;
    		DestBlend 		= One;
    		CullMode 		= CW; //None, CW, or CCW
    		PixelShader 	= compile ps_2_0 p(LightColour3);
    	}
    }
    
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    it was what I suspected ("VertexShader" used as function name) here is a fixed file

    http://crazybutcher.planetquake.gamespy.com/files/JIStyles_skinshader_R4.fx

    by the way TSM the thing you posted used a very old version of the shader as base
  • Eric Chadwick
    Thanks CrazyButcher and TSM, I appreciate it. I'll point Joel here in case he wants it.
  • CrazyButcher
    Offline / Send Message
    CrazyButcher polycounter lvl 20
    I sent him a message via icq, not sure if he still uses it so
  • MoP
    Offline / Send Message
    MoP polycounter lvl 18
    Nice one, thanks Christoph.
  • Mark Dygert
    awesome, bye bye standardfx!
  • J.I. Styles
    Offline / Send Message
    J.I. Styles polycounter lvl 18
    wow

    Thankyou guys for supporting those still using this.

    I've spent the past 2 years under a rock, only to find that this is still being used - on one side I'm humbled that people still use this shader, on the side side... damn! it's old and crusty :D

    Maybe it's time to do some updates... I've been slowly updating my folio over the past months. Maybe it's time to update the shaders too.

    rant on...
    After this much time I'm rather surprised there isn't a bigger community interest in shaders. Those that do create them aren't that prone to sharing or supporting the art based community, yet there's a large hole to be filled here. I really do hope that this will change in the future... I'm really not one to talk though, since I have abandoned it for this much time myself. We'll see if I can get some updates togethor hey :)
Sign In or Register to comment.