Shader Alpha

Started by
1 comment, last by royteusink 17 years, 6 months ago
Hi folks! Here is my cheap water shader, it works fine except the alphablending. I can't get it to work. Please can anyone help me to get this working?! I use a semi-transparent png texture on it. Thanks, Roy description of your image

float Script : STANDARDSGLOBAL <
    string UIWidget = "none";
    string ScriptClass = "object";
    string ScriptOrder = "standard";
    string ScriptOutput = "color";
    string Script = "Technique=ps11;";
> = 0.8;

/************* TWEAKABLES **************/

float4x4 WorldIT : WorldInverseTranspose < string UIWidget="None"; >;
float4x4 WorldViewProj : WorldViewProjection < string UIWidget="None"; >;
float4x4 World : World < string UIWidget="None"; >;
float4x4 ViewI : ViewInverse < string UIWidget="None"; >;

float Timer : Time < string UIWidget="None"; >;

texture diffuseTexture : Diffuse
<
	string ResourceName = "water_texture.png";
>;


float TimeScaleH
<
    string UIWidget = "slider";
    float UIMin = 0.1;
    float UIMax = 10;
    float UIStep = 0.1;
> = 10.0;

float TimeScaleV
<
    string UIWidget = "slider";
    float UIMin = 0.1;
    float UIMax = 10;
    float UIStep = 0.1;
> = 0.1;

float Wobble
<
    string UIWidget = "slider";
    float UIMin = 0;
    float UIMax = 2.0;
    float UIStep = 0.01;
> = 0.2;

float Horizontal
<
    string UIWidget = "slider";
    float UIMin = 0;
    float UIMax = 2.0;
    float UIStep = 0.01;
> = 0.62;

float Vertical
<
    string UIWidget = "slider";
    float UIMin = 0.01;
    float UIMax = 10.0;
    float UIStep = 0.1;
> = 10.0;

float3 LightPos : Position
<
    string Object = "PointLight";
    string Space = "World";
> = {-0.19f, 1.58f, -0.93f};

float3 LightColor
<
    string UIName =  "Light Color";
    string UIWidget = "Color";
> = {1.0f, 5.01f, 0.0f};

float3 AmbiColor : Ambient
<
    string UIName =  "Ambient Light Color";
    string UIWidget = "Color";
> = {5.01f,5.01f,5.01f};

float3 SurfColor : Diffuse
<
    string UIName =  "Surface Color";
    string UIWidget = "Color";
> = {5.01f,5.01f,5.01f};

float SpecExpon : SpecularPower
<
    string UIWidget = "slider";
    float UIMin = 1.0;
    float UIMax = 128.0;
    float UIStep = 1.0;
    string UIName =  "specular power";
> = 42.0;

/************* DATA STRUCTS **************/

/* data from application vertex buffer */
struct appdata {
    float3 Position	: POSITION;
    float4 UV		: TEXCOORD0;
    float4 Normal	: NORMAL;
    float4 DiffTexture		: TEXCOORD1;
};

/* data passed from vertex shader to pixel shader */
struct vertexOutput {
    float4 HPosition	: POSITION;
    float4 TexCoord0	: TEXCOORD0;
    float4 DiffTexture : TEXCOORD1;
    float4 diffCol	: COLOR0;
    float4 specCol	: COLOR1;
};

/*********** vertex shader ******/

vertexOutput MrWiggleVS(appdata IN)
{
    vertexOutput OUT;
    OUT.DiffTexture = IN.UV;
    float3 Nn = normalize(mul(IN.Normal, WorldIT).xyz);
    float timeNowV = (Timer*TimeScaleV);
    float timeNowH = (Timer*TimeScaleH);
    float4 Po = float4(IN.Position.xyz,1);
    float iny = Po.y * Vertical + timeNowV;
    float inxz = sqrt(dot(Po.xz,Po.xz)) * Horizontal * timeNowH;
    float hScale = Wobble * (1.0+sin(inxz));
    float wiggleX = sin(iny) * sin(hScale);
    float wiggleY = cos(iny) * sin(hScale);
    Po.x = Po.x + wiggleX;
    Nn.y = Nn.y + wiggleY;
    Nn = normalize(Nn);
    Po.z = Po.z + wiggleY;
    OUT.HPosition = mul(Po, WorldViewProj);
    Nn.y = Nn.y + wiggleX;
    Nn = normalize(Nn);
    float3 Pw = mul(Po, World).xyz;
    float3 Ln = normalize(LightPos - Pw);
    float ldn = dot(Ln,Nn);
    float diffComp = max(0,ldn);
    float3 diffContrib = SurfColor * ( diffComp * LightColor + AmbiColor);
    OUT.diffCol = float4(diffContrib,1);
    OUT.TexCoord0 = IN.UV;
    float3 Vn = normalize(ViewI[3].xyz - Pw);
    float3 Hn = normalize(Vn + Ln);
    float hdn = pow(max(0,dot(Hn,Nn)),SpecExpon);
    OUT.specCol = float4(hdn * LightColor,1);
    return OUT;
}

sampler TextureSampler = sampler_state 
{
    texture = <diffuseTexture>;
    AddressU  = CLAMP;        
    AddressV  = CLAMP;
    AddressW  = CLAMP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};


float4 PS_Textured( vertexOutput IN): COLOR
{
  float4 diffuseTexture = tex2D( TextureSampler, IN.DiffTexture );
  return IN.diffCol * diffuseTexture + IN.specCol;
}

technique ps11 <
	string Script = "Pass=p0;";
> {
	pass p0 <
	string Script = "Draw=geometry;";
> {		
		VertexShader = compile vs_1_1 MrWiggleVS();
		PixelShader  = compile ps_1_1 PS_Textured();
		ZEnable = true;
		ZWriteEnable = true;
		CullMode = None;
		SpecularEnable = true;
		ColorArg1[ 0 ] = Diffuse;
		ColorOp[ 0 ]   = SelectArg1;
		ColorArg2[ 0 ] = Specular;
		
		
		//alpha
		AlphaOp[0] = MODULATE;
		AlphaArg1[0] = TEXTURE;
		AlphaArg2[0] = DIFFUSE;
		AlphaOp[1] = DISABLE;
		AlphaBlendEnable = TRUE;
		SrcBlend = SRCALPHA;
		DestBlend = INVSRCALPHA;

	}
}


http://www.vectorstudios.nethttp://engine.vectorstudios.net
Advertisement
1. render the semi-transparent alpha blended things *after* you render all the opaque things with Z writes disabled. If you don't disable Z writes for the water, anything that's underneath the water that's drawn after the water will be rejected by the depth buffer. Because Z writes are off, you need to manually Z sort the semi-transparent things (using distance from the camera to the nearest point on the bounding box [along the view vector] is usually enough) which is why you render semi-transparent things after all the opaque things.

2. does your water texture have an alpha channel?, and are you loading it into a D3D format that has an alpha channel? Your vertex shader sets alpha to 1 and the pixel shader modulates against the texture so that's the only place the alpha for the blend can come from.

3. unrelated point: using a pixel shader replaces the fixed function texture blending cascade, so the ColorArg1, ColorArg2, ColorOp, AlphaArg1, AlphaArg2, AlphaOp parts of your effect are completely redundant.

4. unrelated point: you have SpecularEnable=true, this enables the hardware specular addition that happens *after* your shader has run. Your shader is already doing a specular add so what you're asking D3D for is: IN.diffCol * diffuseTexture + IN.specCol + IN.specCol; Maybe you want the extra exponentiation, but thought I'd mention it in case not.

5. unrelated point: I've found that the lit() HLSL intrinsic saves a bunch of shader instruction slots compared to doing the maths with separate intrinsics and gives acceptable results.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Quote:Original post by S1CA
1. render the semi-transparent alpha blended things *after* you render all the opaque things with Z writes disabled. If you don't disable Z writes for the water, anything that's underneath the water that's drawn after the water will be rejected by the depth buffer. Because Z writes are off, you need to manually Z sort the semi-transparent things (using distance from the camera to the nearest point on the bounding box [along the view vector] is usually enough) which is why you render semi-transparent things after all the opaque things.

2. does your water texture have an alpha channel?, and are you loading it into a D3D format that has an alpha channel? Your vertex shader sets alpha to 1 and the pixel shader modulates against the texture so that's the only place the alpha for the blend can come from.




1. How do i do that?! >< Can u please help me? I tried so many things and it still doens't work :(
2. Yes my texture has a alpha channel

btw I'm using MDX C#.NET 2005, NVIDIA gfxcard
http://www.vectorstudios.nethttp://engine.vectorstudios.net

This topic is closed to new replies.

Advertisement