Converting pixelshader asm to HLSL - hlsl

I am trying to convert an inline asm ps_1_3 pixelshader back to HLSL and I am stuck at one instruction that I cannot find any documentation for. The instruction is +mov and such a modifier is not listed in the modifiers. I translated it to a simple assignment, but the rendered scene then looks different. Maybe my other translations are wrong as well.
Full asm code:
Sampler[0] = (DiffuseMapSampler);
pixelShader = asm
{
ps_1_3
tex t0
#ifdef _POINTLIGHT_
add r0.rgb, v0, v0
+mov r0.a, v0.a
mul_x4 r0, t0, r0
#else
mul_x4 r0, t0, v0
#endif
#if defined(OVERGROWTH) && HASALPHA2MASK
mul_x2 r0.a, r0.a, t0.a
#endif
};
Struct and Sampler
struct VS_OUTPUT
{
float4 Pos : POSITION0;
float2 Tex0 : TEXCOORD0;
#if _HASSHADOW_
float4 TexShadow : TEXCOORD1;
#endif
float4 Color : COLOR0;
float Fog : FOG;
};
texture DiffuseMap;
sampler DiffuseMapSampler = sampler_state
{
Texture = (DiffuseMap);
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
MipMapLodBias = 0;
};
My HLSL translation
float4 basicPixelShaderNoShadow(VS_OUTPUT VsOut) : COLOR
{
float4 diffuseMap = tex2D(DiffuseMapSampler, VsOut.Tex0);
float4 outCol;
#ifdef _POINTLIGHT_
outCol.rgb = VsOut.Color.rgb * 2;
outCol.a = VsOut.Color.a;
outCol = diffuseMap * outCol * 4;
#else
outCol = diffuseMap * VsOut.Color * 4;
#endif
#if defined(OVERGROWTH) && HASALPHA2MASK
outCol.a *= 2 * diffuseMap.a;
#endif
return outCol;
}

The +mov means 'in parallel'. Found an example for it here. The differences in rendering come from a change in ps version. The HLSL was set to ps_2_a and when using ps_1_3 for it as well everything renders the same as with asm.

Related

How to use pixel shader to render material from a Wavefront Obj file?

Some 3d meshes that get exported to Wavefront.obj format usually come with a .mtl file that has additional data to the texture it uses and its materials, when exported from Blender they always come with Ambient, Diffuse, Specular, and Emissive RGB data as part of its material, but I'm not sure how I can use this data in the pixel shader and get the right color output.
I would appreciate it if anyone can explain to me how to use these materials and any code sample would be very welcome.
Traditional materials and lighting models use "Ambient", "Diffuse", "Specular", and "Emissive" colors which is why you find those in Wavefront OBJ files. These can often be replaced or used in multiplicative conjunction with texture colors.
The (now defunct) XNA Game Studio product did a good job of providing simple 'classic' shaders in the BasicEffect "Stock Shaders". I use them in the DirectX Tool Kit for DX11 and DX12.
Take a look at BasicEffect.fx for a traditional material pixel shader. If you are looking mostly for pixel-shader handling, that's "per-pixel lighting" as opposed to "vertex lighting" which was more common back when we had less powerful GPUs.
Here's a 'inlined' version so you can follow it all in one place:
struct VSInputNmTx
{
float4 Position : SV_Position;
float3 Normal : NORMAL;
float2 TexCoord : TEXCOORD0;
};
Texture2D<float4> Texture : register(t0);
sampler Sampler : register(s0);
cbuffer Parameters : register(b0)
{
float4 DiffuseColor : packoffset(c0);
float3 EmissiveColor : packoffset(c1);
float3 SpecularColor : packoffset(c2);
float SpecularPower : packoffset(c2.w);
float3 LightDirection[3] : packoffset(c3);
float3 LightDiffuseColor[3] : packoffset(c6);
float3 LightSpecularColor[3] : packoffset(c9);
float3 EyePosition : packoffset(c12);
float3 FogColor : packoffset(c13);
float4 FogVector : packoffset(c14);
float4x4 World : packoffset(c15);
float3x3 WorldInverseTranspose : packoffset(c19);
float4x4 WorldViewProj : packoffset(c22);
};
struct VSOutputPixelLightingTx
{
float2 TexCoord : TEXCOORD0;
float4 PositionWS : TEXCOORD1;
float3 NormalWS : TEXCOORD2;
float4 Diffuse : COLOR0;
float4 PositionPS : SV_Position;
};
// Vertex shader: pixel lighting + texture.
VSOutputPixelLighting VSBasicPixelLightingTx(VSInputNmTx vin)
{
VSOutputPixelLighting vout;
vout.PositionPS = mul(vin.Position, WorldViewProj);
vout.PositionWS.xyz = mul(vin.Position, World).xyz;
// ComputeFogFactor
vout.PositionWS.w = saturate(dot(vin.Position, FogVector));
vout.NormalWS = normalize(mul(vin.Normal, WorldInverseTranspose));
vout.Diffuse = float4(1, 1, 1, DiffuseColor.a);
vut.TexCoord = vin.TexCoord;
return vout;
}
struct PSInputPixelLightingTx
{
float2 TexCoord : TEXCOORD0;
float4 PositionWS : TEXCOORD1;
float3 NormalWS : TEXCOORD2;
float4 Diffuse : COLOR0;
};
// Pixel shader: pixel lighting + texture.
float4 PSBasicPixelLightingTx(PSInputPixelLightingTx pin) : SV_Target0
{
float4 color = Texture.Sample(Sampler, pin.TexCoord) * pin.Diffuse;
float3 eyeVector = normalize(EyePosition - pin.PositionWS.xyz);
float3 worldNormal = normalize(pin.NormalWS);
ColorPair lightResult = ComputeLights(eyeVector, worldNormal, 3);
color.rgb *= lightResult.Diffuse;
// AddSpecular
color.rgb += lightResult.Specular * color.a;
// ApplyFog (we passed fogfactor in via PositionWS.w)
color.rgb = lerp(color.rgb, FogColor * color.a, pin.PositionWS.w);
return color;
}
Here is the helper function ComputeLights which implements a Blinn-Phong reflection model for the specular highlight.
struct ColorPair
{
float3 Diffuse;
float3 Specular;
};
ColorPair ComputeLights(float3 eyeVector, float3 worldNormal, uniform int numLights)
{
float3x3 lightDirections = 0;
float3x3 lightDiffuse = 0;
float3x3 lightSpecular = 0;
float3x3 halfVectors = 0;
[unroll]
for (int i = 0; i < numLights; i++)
{
lightDirections[i] = LightDirection[i];
lightDiffuse[i] = LightDiffuseColor[i];
lightSpecular[i] = LightSpecularColor[i];
halfVectors[i] = normalize(eyeVector - lightDirections[i]);
}
float3 dotL = mul(-lightDirections, worldNormal);
float3 dotH = mul(halfVectors, worldNormal);
float3 zeroL = step(0, dotL);
float3 diffuse = zeroL * dotL;
float3 specular = pow(max(dotH, 0) * zeroL, SpecularPower) * dotL;
ColorPair result;
result.Diffuse = mul(diffuse, lightDiffuse) * DiffuseColor.rgb + EmissiveColor;
result.Specular = mul(specular, lightSpecular) * SpecularColor;
return result;
}
These BasicEffect shaders don't make use of ambient color, but you could modify them to do so if you wanted. All ambient color does is provide a 'minimum color value' that's independent of dynamic lights.
Note that there also some unofficial Physically-Based Rendering (PBR) materials extension in some Wavefront OBJ files. See Extending Wavefront MTL for Physically-Based. More modern geometry formats like glTF assume PBR materials properties which is things like an albedo texture, normal texture, roughness/metalness texture, etc..

Interpret the HLSL Shader Compiler Macro code

Profile:
WiN7 Prof SP1
Directx11
Development IDE: VS 2015
Program Language: C#
Application Type: 3D Rendering
Directx11 Wrapper: SLimDX
In my C# project I have a 3D renderer that is working.
I want to integrate a third Party HLSL Shader Code.
I have translated the code for Directx11 Feature level and it compiles with fxc.exe without errors or warnings.
The shader is loaded by my C# application and I can access all shader variables and set values of them.
Problem:
When I try to get a reference in my C# Code to access the first pass of the first technique of the Shader I get a SlimDX runtime Error.
I can reference the first technique of the shader with no runtime error but the obtained object has a flag is_valid = false showing the technique was not referenced correctly.
Clarification: I don't try to make a draw call but in preparation of the draw call I have to get a reference to the relevant pass.
Question:
I can't understand what the last compiler directives about the techniques mean exactly.
Can someone translate which HLSL Code will eventually produced from the compiler directive?
I mean the beginning from :
#define OBJECT_TEC(name, mmdpass) \
#include "../ray.conf"
#include "../ray_advanced.conf"
#include "../shader/math.fxsub"
#include "../shader/common.fxsub"
#include "../shader/gbuffer.fxsub"
#include "../shader/lighting.fxsub"
float3 LightDirection : DIRECTION < string Object = "Light"; >;
float3 LightSpecular : SPECULAR < string Object = "Light"; >;
bool ExistRay : CONTROLOBJECT<string name = "ray.x";>;
texture DiffuseMap: MATERIALTEXTURE;
sampler DiffuseMapSamp = sampler_state
{
texture = <DiffuseMap>;
MINFILTER = ANISOTROPIC;
MAGFILTER = ANISOTROPIC;
MIPFILTER = POINT;
MAXANISOTROPY = 16;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
};
float4 GetTextureColor(float4 albedo, float2 uv)
{
if (use_texture)
{
float4 TexColor = tex2D(DiffuseMapSamp, uv);
TexColor.rgb = lerp(1, TexColor * TextureMulValue + TextureAddValue, TextureMulValue.a + TextureAddValue.a).rgb;
albedo *= TexColor;
}
return srgb2linear(albedo);
}
void DrawObjectVS(
in float4 Position : POSITION,
in float3 Normal : NORMAL,
in float4 Texcoord : TEXCOORD0,
out float4 oTexcoord : TEXCOORD0,
out float3 oNormal : TEXCOORD1,
out float3 oViewdir : TEXCOORD2,
out float4 oPosition : SV_Position)
{
oNormal = Normal;
oTexcoord = Texcoord;
oViewdir = CameraPosition - Position.xyz;
oPosition = mul(Position, matWorldViewProject);
}
float4 DrawObjectPS(float4 texcoord : TEXCOORD0, float3 normal : TEXCOORD1, float3 viewdir : TEXCOORD2) : SV_Target
{
#if EXIST_RAY
#if DISCARD_ALPHA_ENABLE
float alpha = MaterialDiffuse.a;
#if DISCARD_ALPHA_MAP_ENABLE
if (use_texture) alpha *= tex2D(DiffuseMapSamp, texcoord.xy).a;
#endif
clip(alpha - DiscardAlphaThreshold);
#endif
return 0;
#else
if (ExistRay)
{
#if DISCARD_ALPHA_ENABLE
float alpha = MaterialDiffuse.a;
#if DISCARD_ALPHA_MAP_ENABLE
if (use_texture) alpha *= tex2D(DiffuseMapSamp, texcoord.xy).a;
#endif
clip(alpha - DiscardAlphaThreshold);
#endif
return 0;
}
else
{
float4 albedo = GetTextureColor(MaterialDiffuse, texcoord.xy);
float3 L = normalize(-LightDirection);
float3 V = normalize(viewdir);
float3 N = normalize(normal);
float MaterialRoughness = SmoothnessToRoughness(ShininessToSmoothness(MaterialPower));
float4 lighting = albedo;
lighting.rgb *= DiffuseBRDF(N, L, V, MaterialRoughness);
lighting.rgb += SpecularBRDF_GGX(N, L, V, MaterialRoughness, 0.04, 1.0);
lighting.rgb *= LightSpecular;
return linear2srgb(lighting);
}
#endif
}
#define OBJECT_TEC(name, mmdpass) \
technique name < string MMDPass = mmdpass;\
> { \
pass DrawObject { \
AlphaTestEnable = FALSE; AlphaBlendEnable = FALSE; \
VertexShader = compile vs_3_0 DrawObjectVS(); \
PixelShader = compile ps_3_0 DrawObjectPS(); \
} \
}
OBJECT_TEC(MainTec0, "object")
OBJECT_TEC(MainTecBS0, "object_ss")
technique EdgeTec < string MMDPass = "edge"; > {}
technique ShadowTech < string MMDPass = "shadow"; > {}
technique ZplotTec < string MMDPass = "zplot"; > {}

Upgraded MonoGame and now I can't get my shader to compile

I upgraded my monogame to the latest version. When building the shader in the pipeline tool at first I got the error Vertex shader 'SpriteVertexShader' must be SM 4.0 level 9.1 or higher! So I changed ps_2_0 to ps_4_0_level_9_1 but now I'm getting the error:
error X3004: undeclared identifier 'SecondPassTextureSampler'
Anybody have an idea on how to fix this issue?
#include "Macros.fxh"
texture Bitmap;
sampler2D FirstPassTexture = sampler_state{
Texture = (Bitmap);
MagFilter = Linear;
MinFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
sampler2D SecondPassTexture = sampler_state{
Texture = (Bitmap);
MagFilter = Linear;
MinFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
#define KERNEL_RADIUS 7
#define KERNEL_WIDTH (2*KERNEL_RADIUS + 1)
// Uniforms
BEGIN_CONSTANTS
float kernel[KERNEL_WIDTH];
float2 offsets[KERNEL_WIDTH];
MATRIX_CONSTANTS
float4x4 MatrixTransform _vs(c0) _cb(c0);
END_CONSTANTS
struct VSOutput
{
float4 position : SV_Position;
float4 color : COLOR0;
float2 texCoord : TEXCOORD0;
};
VSOutput SpriteVertexShader( float4 position : SV_Position,
float4 color : COLOR0,
float2 texCoord : TEXCOORD0)
{
VSOutput output;
output.position = mul(position, MatrixTransform);
output.color = color;
output.texCoord = texCoord;
return output;
}
float4 gaussH(VSOutput input): SV_Target0
{
float4 color = float4(0,0,0,0);
for(int i = 0; i < KERNEL_WIDTH; ++i)
color += SAMPLE_TEXTURE(SecondPassTexture, (input.texCoord + float2(offsets[i].x, 0.0) )) * kernel[i];
return color * input.color;
}
float4 gaussV(VSOutput input): SV_Target0
{
float4 color = float4(0.0,0.0,0.0,0);
for(int i = 0; i < KERNEL_WIDTH; ++i)
color += SAMPLE_TEXTURE(SecondPassTexture, (input.texCoord + float2(0.0, offsets[i].y) )) * kernel[i];
return color * input.color;
}
float4 gaussVGlow(VSOutput input): SV_Target0
{
float4 color = float4(1.0,1.0,1.0,0);
for(int i = 0; i < KERNEL_WIDTH; ++i)
{
float alpha = SAMPLE_TEXTURE(SecondPassTexture, (input.texCoord + float2(0.0, offsets[i].y) )).a * kernel[i];
color.a += alpha;
}
// This will make stripes on top of the glow
/*
float m = smoothstep(0.45, 0.55, 0.5*cos(25.0*atan2(input.texCoord.y-0.5, input.texCoord.x-0.5))+0.5) * 0.5 + 0.5;
color.a *= m;
*/
color.a = pow(color.a, 0.5);
color.rgb *= color.a; // Yeah, you have to pre multiply your alpha -- either that or render with premultiply option
return color * input.color;
}
technique Blur {
pass p0 {
VertexShader = compile vs_4_0_level_9_1 SpriteVertexShader();
PixelShader = compile ps_4_0_level_9_1 gaussH();
}
pass p1 {
VertexShader = compile vs_4_0_level_9_1 SpriteVertexShader();
PixelShader = compile ps_4_0_level_9_1 gaussV();
}
pass p1Glow {
VertexShader = compile vs_4_0_level_9_1 SpriteVertexShader();
PixelShader = compile ps_4_0_level_9_1 gaussVGlow();
}
}
Macros.fxh is: http://pastebin.com/y51kFfii
From the Monogame Forum:
You get an error because you use the macro SAMPLE_TEXTURE for sampling, but do not use the macro DECLARE_TEXTURE for declaring the texture.
If you want to use the macros in Macros.fxh then the texture needs to be named SecondPassTexture and the sampler needs to be named SecondPassTextureSampler. (Do not change the line where SAMPLE_TEXTURE is called.)
If you look at the macro (_Macro.fxh, line 31), the code
SAMPLE_TEXTURE(SecondPassTexture, (input.texCoord + float2(0.0, offsets[i].y) ))
expands to
SecondPassTexture.Sample(SecondPassTextureSampler, (input.texCoord + float2(0.0, offsets[i].y) ))
But in your case (original post) it should be
Bitmap.Sample(SecondPassTexture, (input.texCoord + float2(0.0, offsets[i].y) ))
Here is a simpler solution, you can try:
Just replace all SAMPLE_TEXTURE with tex2D. (Leave the samplers as in the original post.)

DX9 vertexshader error X3000: Illegal character in shader file

I got an error while compiling my vertexshader.
loadfilefrommemory(water.vs)(44,2): error X3000: Illegal character in shader file
The file is ANSI codec and I created new files many times. And I still get these error with Illegal character. I read much questions but the error just appears on (1, 1) on other questions. So what am I doing wrong?
Here is my File:
//------- Constants --------
float4x4 xView;
float4x4 xProjection;
float4x4 xWorld;
float4x4 xReflectionView;
float4x4 xWindDirection;
float xWaveLength;
float xTime;
float xWindForce;
//------- Technique: Water --------
struct WaterVertexToPixel
{
float4 Position : POSITION;
float4 ReflectionMapSamplingPos : TEXCOORD1;
float2 BumpMapSamplingPos : TEXCOORD2;
float4 RefractionMapSamplingPos : TEXCOORD3;
float4 Position3D : TEXCOORD4;
};
WaterVertexToPixel main(float4 inPos : POSITION, float2 inTex: TEXCOORD)
{
WaterVertexToPixel Output = (WaterVertexToPixel)0;
float4x4 preViewProjection = mul (xView, xProjection);
float4x4 preWorldViewProjection = mul (xWorld, preViewProjection);
float4x4 preReflectionViewProjection = mul (xReflectionView, xProjection);
float4x4 preWorldReflectionViewProjection = mul (xWorld, preReflectionViewProjection);
Output.Position = mul(inPos, preWorldViewProjection);
Output.ReflectionMapSamplingPos = mul(inPos, preWorldReflectionViewProjection);
Output.RefractionMapSamplingPos = mul(inPos, preWorldViewProjection);
Output.Position3D = inPos;
float4 absoluteTexCoords = float4(inTex, 0, 1);
float4 rotatedTexCoords = mul(absoluteTexCoords, xWindDirection);
float2 moveVector = float2(0, 1);
// moving the water
Output.BumpMapSamplingPos = rotatedTexCoords.xy/xWaveLength + xTime*xWindForce*moveVector.xy;
return Output;
}

Texture Mapping Problem in Direct3D

hey guys
i am having trouble rendering textures through shaders. I really don't know why, the shader file just implements a simple phong lighting and interpolate the texture on a simple quad but all i am getting is the lighting and material colors, as if there is no texture(the texture is a Stone texture but all i am getting is white color)
here is the shader file
//------------------------------------
uniform extern float4x4 matWVP;
uniform extern float4x4 matITW;
uniform extern float4x4 matW;
uniform extern float4 DiffMatr;
uniform extern float4 DiffLight;
uniform extern float4 AmbLight;
uniform extern float4 SpecLight;
uniform extern float4 AmbMatr;
uniform extern float3 LightPosW;
uniform extern float4 SpecMatr;
uniform extern float SpecPower;
uniform extern float3 EyePos;
uniform extern texture Tex;
//------------------------------------
sampler sTex = sampler_state
{
Texture = <Tex>;
Minfilter = LINEAR;
Magfilter = LINEAR;
Mipfilter = POINT;
AddressU = WRAP;
AddressV = WRAP;
};
struct vOut {
float4 posH : POSITION0;
float3 posW : TEXCOORD0;
float3 normW: TEXCOORD1;
float2 cTex : TEXCOORD2;
};
//------------------------------------
vOut VS_Def(float3 posL : POSITION0
, float3 normL : NORMAL0
, float2 cTex : TEXCOORD0)
{
vOut V = (vOut)0;
V.posH = mul(float4(posL, 1.0f), matWVP);
V.posW = mul(float4(posL, 1.0f), matW).xyz;
V.normW = mul(float4(normL, 1.0f), matITW).xyz;
V.normW = normalize(V.normW);
V.cTex = V.cTex;
return V;
}
float4 PS_Def(float3 posW : TEXCOORD0
,float4 normW : TEXCOORD1
,float2 cTex : TEXCOORD2 ): COLOR
{
float3 LightVec = LightPosW - posW;
LightVec = normalize(LightVec);
float3 RefLightVec = reflect(-LightVec, normW);
float3 EyeVec = EyePos - posW;
EyeVec = normalize(EyePos - posW);
float d = max(0.0f, dot(normW, LightVec));
float s = pow(max(dot(RefLightVec, EyeVec), 0.0f), SpecPower);
float3 Diff = d * (DiffMatr * DiffLight).rgb;
float3 Amb = (AmbMatr * AmbLight).rgb;
float3 Spec = s * (SpecMatr * SpecLight).rgb;
float3 TexColor = tex2D(sTex, cTex.xy).rgb;
float3 color = Diff + Amb;
return float4(color * TexColor + Spec, DiffMatr.a);;
}
//-----------------------------------
technique DefTech
{
pass p0
{
VertexShader = compile vs_2_0 VS_Def();
PixelShader = compile ps_2_0 PS_Def();
}
}
the lighting and material colors are as follows:
(P.S : WHITE = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f))
Diffuse Material = WHITE;
Ambient Material = WHITE;
Specular Material = WHITE * 0.5f;
Diffuse Lighting = WHITE * 0.8f;
Ambient Lighting = WHITE * 0.8f;
Specular Lighting = WHITE * 0.5f;
Specular Power = 48.0f;
Appreciate the help, guys
In your vertex shader you have
V.cTex = V.cTex;
Shouldn't this be
V.cTex = cTex;