I have the following shader,
I'm trying to add an alpha to the white, however all attempts have proven to be difficult.
This is the project from which I obtained the shader for reference - github
I think it has to do with one of the passes overwriting.
Shader "Suibokuga/Suibokuga" {
Properties {
_MainTex ("Water Texture", 2D) = "white" {}
_Alpha ("Transfer/Diffusion coefficient for water particles", Range(0.01, 1.5)) = 1.0
_Evaporation ("a unit quantity of water for evaporation", Range(0.0001, 0.005)) = 0.00015
_PaperTex ("Paper Texture", 2D) = "white" {}
_Brush ("brush", Vector) = (-1, -1, -1, -1)
_Prev ("previous brush position", Vector) = (-1, -1, -1, -1)
}
CGINCLUDE
#include "UnityCG.cginc"
#pragma target 3.0
/*
* r : water particles
* b : capacities of water
* a : the heights of the bottoms
*/
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float _Alpha;
float _Evaporation;
sampler2D _PaperTex;
float2 _Prev;
float3 _Brush; // x,y : position, z : size
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata IN) {
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.uv = IN.uv;
return OUT;
}
void sample (float2 uv, out float4 o, out float4 l, out float4 t, out float4 r, out float4 b) {
float2 texel = _MainTex_TexelSize.xy;
o = tex2D(_MainTex, uv);
l = tex2D(_MainTex, uv + float2(-texel.x, 0));
t = tex2D(_MainTex, uv + float2( 0, -texel.y));
r = tex2D(_MainTex, uv + float2( texel.x, 0));
b = tex2D(_MainTex, uv + float2( 0, texel.y));
}
float waterDelta (float4 k, float4 o) {
float ld = (k.w + k.x) - (o.w + o.x); // level difference
float transfer = (k.w + k.x) - max(o.w, k.w + k.z); // transferable water particles
return max(
0.0,
0.25 * _Alpha * min(ld, transfer)
);
}
float waterFlow (float2 uv) {
float4 o, l, t, r, b;
sample(uv, o, l, t, r, b);
float nw = o.r;
nw += (waterDelta(l, o) - waterDelta(o, l));
nw += (waterDelta(t, o) - waterDelta(o, t));
nw += (waterDelta(r, o) - waterDelta(o, r));
nw += (waterDelta(b, o) - waterDelta(o, b));
return max(nw, 0);
}
float evaporation (float wo) {
return max(wo - _Evaporation, 0.0);
}
float brush (float2 uv) {
const int count = 10;
float2 dir = _Brush.xy - _Prev.xy;
float l = length(dir);
if(l <= 0) {
float d = length(uv - _Brush.xy);
return smoothstep(0.0, _Brush.z, _Brush.z - d);
}
float ld = l / count;
float2 norm = normalize(dir);
float md = 100;
for(int i = 0; i < count; i++) {
float2 p = _Prev.xy + norm * ld * i;
float d = length(uv - p);
if(d < md) {
md = d;
}
}
return smoothstep(0.0, _Brush.z, _Brush.z - md);
// float d = length(uv - _Brush.xy);
// return smoothstep(0.0, _Brush.z, _Brush.z - d);
}
ENDCG
SubShader {
Cull Off ZWrite Off ZTest Always
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment init
float4 init (v2f IN) : SV_Target {
float4 paper = tex2D(_PaperTex, IN.uv);
return float4(
0,
0,
paper.r,
paper.r
);
}
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment waterUpdate
float4 waterUpdate (v2f IN) : SV_Target {
float4 col = tex2D(_MainTex, IN.uv);
col.x = evaporation(waterFlow(IN.uv));
float dw = brush(IN.uv);
// if(dw > 0) {
col.x = min(col.x + brush(IN.uv), 1.0);
// }
return col;
}
ENDCG
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment visualize
float4 visualize (v2f IN) : SV_Target {
float4 col = tex2D(_MainTex, IN.uv);
return float4(1.0 - col.xxx, 1.0);
}
ENDCG
}
}
}
You seem to miss a blending step.
Try adding this line to the end of the last pass
Blend SrcAlpha OneMinusSrcAlpha
Check this page to learn about alpha blending for Unity shaders.
The line I attached is for standard transparency, you might want to try different blending options.
Related
I have a shader for voxel rendering which do not support transparency.
Shader code:
Shader "Custom/Voxel"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_AOColor ("AO Color", Color) = (0,0,0,1)
_AOIntensity ("AO Intensity", Range(0, 1)) = 1.0
_AOPower ("AO Power", Range(1, 10)) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma vertex vert
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float3 position;
float4 custom_uv;
float4 color : COLOR;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
int _AtlasX;
int _AtlasY;
fixed4 _AtlasRec;
half4 _AOColor;
float _AOIntensity;
float _AOPower;
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_INSTANCING_BUFFER_END(Props)
void vert (inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
o.custom_uv = v.texcoord;
o.position = v.vertex;
v.color.rgb = _AOColor;
v.color.a = pow((1-v.color.a) * _AOIntensity, _AOPower );
}
void surf (Input IN, inout SurfaceOutputStandard o)
{
fixed2 atlasOffset = IN.custom_uv.zw;
fixed2 scaledUV = IN.custom_uv.xy;
fixed2 atlasUV = scaledUV;
atlasUV.x = (atlasOffset.x * _AtlasRec.x) + frac(atlasUV.x) * _AtlasRec.x;
atlasUV.y = (((_AtlasY - 1) - atlasOffset.y) * _AtlasRec.y) + frac(atlasUV.y) * _AtlasRec.y;
// Albedo comes from a texture tinted by color
fixed4 c = tex2Dgrad(_MainTex, atlasUV, ddx(atlasUV * _AtlasRec), ddy(atlasUV * _AtlasRec)) * _Color;
//fixed4 c = tex2D(_MainTex, atlasUV) * _Color;
o.Albedo = lerp(c.rgb, IN.color.rgb, IN.color.a);
o.Alpha = c.a;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
}
ENDCG
}
FallBack "Diffuse"
}
What I have changed/added by googling attempts:
Tags { "Queue"="Transparent" "RenderType" = "Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
This did nothing.
Then I have tried to change:
#pragma surface surf Standard fullforwardshadows
with
#pragma surface surf Standard alpha
or
#pragma surface surf Standard fullforwardshadows alpha:fade
So in result those block that should are transparent, but the rest are kinda too (non transparent tiles works good in original version):
https://i.imgur.com/EwMIQnq.png
I am working on a cel shader for a uni project that I would like to only be affected by scene lights over x intensity. I am struggling in figuring out how to implement this within the code. The code I have been working with I found online, and have been using it to test and understand how shaders work. I am unsure if I need to implement some kind of conditional statement? Some of the information I have read has said that using conditional statements within shaders makes for poor performance.
I am new to shaders and any help would be greatly appreciated.
Thank you in advance :)
ps. I am limited to using Unity 2018.3.8
Properties {
[Header(Base Parameters)]
_Color ("Tint", Color) = (0, 0, 0, 1)
_MainTex ("Texture", 2D) = "white" {}
[HDR] _Emission ("Emission", color) = (0, 0, 0, 1)
[HDR]
_SpecularColor("Specular Color", Color) = (0.9, 0.9, 0.9, 1)
// Controls the size of the specular reflection.
_Glossiness("Glossiness", Float) = 32
[HDR]
_RimColor("Rim Color", Color) = (1,1,1,1)
_RimAmount("Rim Amount", Range(0, 1)) = 0.716
// Control how smoothly the rim blends when approaching unlit
// parts of the surface.
_RimThreshold("Rim Threshold", Range(0, 1)) = 0.1
}
SubShader {
Tags{ "RenderType"="Opaque" "Queue"="Geometry"}
CGPROGRAM
#pragma surface surf Stepped fullforwardshadows
#pragma target 3.0
sampler2D _MainTex;
fixed4 _Color;
half3 _Emission;
float4 _SpecularColor;
float _Glossiness;
float4 _RimColor;
float _RimAmount;
float _RimThreshold;
float3 worldPos;
float4 LightingStepped(SurfaceOutput s, float3 lightDir, half3 viewDir, float shadowAttenuation){
float shadow = shadowAttenuation;
s.Normal=normalize(s.Normal);
float diff = dot(s.Normal, lightDir);
float towardsLightChange = fwidth(diff);
float lightIntensity = smoothstep(0, towardsLightChange, diff);
float3 diffuse = _LightColor0.rgb * lightIntensity * s.Albedo;
float diffussAvg = (diffuse.r + diffuse.g + diffuse.b) / 3;
float3 halfVector = normalize(viewDir + lightDir);
float NdotH = dot(s.Normal, halfVector);
float specularIntensity = pow(NdotH * lightIntensity, _Glossiness * _Glossiness);
float specularIntensitySmooth = smoothstep(0.005, 0.01, specularIntensity);
float3 specular = specularIntensitySmooth * _SpecularColor.rgb * diffussAvg;
float rimDot = 1 - dot(viewDir, s.Normal);
float rimIntensity = rimDot * pow(dot(lightDir, s.Normal), _RimThreshold);
rimIntensity = smoothstep(_RimAmount - 0.01, _RimAmount + 0.01, rimIntensity);
float3 rim = rimIntensity * _RimColor.rgb * diffussAvg;
float4 color;
color.rgb = (diffuse + specular + rim) * shadow;
color.a = s.Alpha;
return color;
}
struct Input {
float2 uv_MainTex;
float3 worldPos;
};
void surf (Input i, inout SurfaceOutput o) {
worldPos = i.worldPos;
fixed4 col = tex2D(_MainTex, i.uv_MainTex);
col *= _Color;
o.Albedo = col.rgb;
o.Alpha = col.a;
o.Emission = _Emission;
}
ENDCG
}
FallBack "Standard"
}
I just realized that a global variable in Unity must be initialized in a function. Being new to shaders, I can't tell if I am doing this the wrong way.
For example, when I define a const variable:
const float PI = 3.14159265359;
then try to write a code that uses in the frag functiion:
fixed4 frag(v2f i) : SV_Target
{
float result = PI * otherVariable;
///Use the result value...
}
It doesn't work. I gets a black screen as the result or the expected result wont show up.
The confusing part is that when I re-initialize the global variable (PI) again in the frag function, I get the expected result.
For example, this is what works:
float PI = 3.14159265359;
then try to write a code that uses in the frag function:
fixed4 frag(v2f i) : SV_Target
{
//re-initialize
PI = 3.14159265359;
float result = PI * otherVariable;
}
I have so many constant global variables that I can't keep re-initiated them.
One complete example of this problem is this Shadertoy code I ported.
Shader "Unlit/Atmospheric Scattering 2"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//https://www.shadertoy.com/view/lslXDr
// math const
float PI = 3.14159265359;
float DEG_TO_RAD = (3.14159265359 / 180.0);
float MAX = 10000.0;
// scatter const
float K_R = 0.166;
float K_M = 0.0025;
float E = 14.3;
float C_R = float3(0.3, 0.7, 1.0); // 1 / wavelength ^ 4
float G_M = -0.85; // Mie g
float R = 1.0;
float R_INNER = 0.7;
float SCALE_H = 4.0 / (1.0 - 0.7);
float SCALE_L = 1.0 / (1.0 - 0.7);
int NUM_OUT_SCATTER = 10;
float FNUM_OUT_SCATTER = 10.0;
int NUM_IN_SCATTER = 10;
float FNUM_IN_SCATTER = 10.0;
// angle : pitch, yaw
float3x3 rot3xy(float2 angle) {
float2 c = cos(angle);
float2 s = sin(angle);
return float3x3(
c.y, 0.0, -s.y,
s.y * s.x, c.x, c.y * s.x,
s.y * c.x, -s.x, c.y * c.x
);
}
// ray direction
float3 ray_dir(float fov, float2 size, float2 pos) {
float2 xy = pos - size * 0.5;
float cot_half_fov = tan((90.0 - fov * 0.5) * DEG_TO_RAD);
float z = size.y * 0.5 * cot_half_fov;
return normalize(float3(xy, -z));
}
// ray intersects sphere
// e = -b +/- sqrt( b^2 - c )
float2 ray_vs_sphere(float3 p, float3 dir, float r) {
float b = dot(p, dir);
float c = dot(p, p) - r * r;
float d = b * b - c;
if (d < 0.0) {
return float2(MAX, -MAX);
}
d = sqrt(d);
return float2(-b - d, -b + d);
}
// Mie
// g : ( -0.75, -0.999 )
// 3 * ( 1 - g^2 ) 1 + c^2
// F = ----------------- * -------------------------------
// 2 * ( 2 + g^2 ) ( 1 + g^2 - 2 * g * c )^(3/2)
float phase_mie(float g, float c, float cc) {
float gg = g * g;
float a = (1.0 - gg) * (1.0 + cc);
float b = 1.0 + gg - 2.0 * g * c;
b *= sqrt(b);
b *= 2.0 + gg;
//b = mul(b,sqrt(b));
//b = mul(b,2.0 + gg);
return 1.5 * a / b;
}
// Reyleigh
// g : 0
// F = 3/4 * ( 1 + c^2 )
float phase_reyleigh(float cc) {
return 0.75 * (1.0 + cc);
}
float density(float3 p) {
return exp(-(length(p) - R_INNER) * SCALE_H);
}
float optic(float3 p, float3 q) {
float3 step = (q - p) / FNUM_OUT_SCATTER;
float3 v = p + step * 0.5;
float sum = 0.0;
for (int i = 0; i < NUM_OUT_SCATTER; i++) {
sum += density(v);
v += step;
}
sum *= length(step) * SCALE_L;
//sum = mul(sum,length(step) * SCALE_L);
return sum;
}
float3 in_scatter(float3 o, float3 dir, float2 e, float3 l) {
float len = (e.y - e.x) / FNUM_IN_SCATTER;
float3 step = dir * len;
float3 p = o + dir * e.x;
float3 v = p + dir * (len * 0.5);
float3 sum = float3(0.,0.,0.);
for (int i = 0; i < NUM_IN_SCATTER; i++) {
float2 f = ray_vs_sphere(v, l, R);
float3 u = v + l * f.y;
float n = (optic(p, v) + optic(v, u)) * (PI * 4.0);
sum += density(v) * exp(-n * (K_R * C_R + K_M));
v += step;
}
sum *= len * SCALE_L;
//sum = mul(sum,len * SCALE_L);
float c = dot(dir, -l);
float cc = c * c;
return sum * (K_R * C_R * phase_reyleigh(cc) + K_M * phase_mie(G_M, c, cc)) * E;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
fixed4 frag(v2f i) : SV_Target
{
//Re-initialize BEGIN
// math const
PI = 3.14159265359;
DEG_TO_RAD = (3.14159265359 / 180.0);
MAX = 10000.0;
// scatter const
K_R = 0.166;
K_M = 0.0025;
E = 14.3;
C_R = float3(0.3, 0.7, 1.0); // 1 / wavelength ^ 4
G_M = -0.85; // Mie g
R = 1.0;
R_INNER = 0.7;
SCALE_H = 4.0 / (1.0 - 0.7);
SCALE_L = 1.0 / (1.0 - 0.7);
NUM_OUT_SCATTER = 10;
FNUM_OUT_SCATTER = 10.0;
NUM_IN_SCATTER = 10;
FNUM_IN_SCATTER = 10.0;
//Re-initialize END
float4 fragColor = 0;
float2 fragCoord = i.vertex.xy;
// default ray dir
float3 dir = ray_dir(45.0, _ScreenParams.xy, fragCoord.xy);
// default ray origin
float3 eye = float3(0.0, 0.0, 2.4);
// rotate camera
float3x3 rot = rot3xy(float2(0.0, _Time.y * 0.5));
/* dir = rot * dir;
eye = rot * eye;*/
dir = mul(rot,dir);
eye = mul(rot,eye);
// sun light dir
float3 l = float3(0, 0, 1);
float2 e = ray_vs_sphere(eye, dir, R);
if (e.x > e.y) {
discard;
}
float2 f = ray_vs_sphere(eye, dir, R_INNER);
e.y = min(e.y, f.x);
float3 I = in_scatter(eye, dir, e, l);
fragColor = float4(I, 1.0);
return fragColor;
}
ENDCG
}
}
}
This shader is attached to a Material that is then attached to the camera with the code below:
[ExecuteInEditMode]
public class CameraEffect : MonoBehaviour
{
public Material mat;
// Called by camera to apply image effect
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (mat != null)
{
Graphics.Blit(source, destination, mat);
}
else
{
Graphics.Blit(source, destination);
}
}
}
It works fine but notice how I had to re-initialize the PI, DEG_TO_RAD, MAX and other global variables...Without doing that it won't work.The screen is simply black and this is not the first shader that has caused this same issue.
Why is this happening?
Am I declaring the variables the wrong way?
Hi!
Any constants you can write like this:
//float my_constant = 104.3;
#define my_constant 104.3f
You can create custom library for shaders and use variables and functions as you wish. For example create file with name MyConstants.cginc and put in in your project. Code:
#ifndef MY_CONSTANTS_INCLUDED
#define MY_CONSTANTS_INCLUDED
#define DEG_TO_RAD 0.01745329251994f
#define MAX 10000.0f
#define PI 3.14159265359f
//scatter const
// .....
// .....
float3 ray_dir(float fov, float2 size, float2 pos) {
float2 xy = pos - size * 0.5;
float cot_half_fov = tan((90.0 - fov * 0.5) * DEG_TO_RAD);
float z = size.y * 0.5 * cot_half_fov;
return normalize(float3(xy, -z));
}
//.... and other methods
#endif
And Using library in your shader
//.....
#include "UnityCG.cginc"
#include "MyConstants.cginc"
//.....
here is my script
Shader "Custom/Eyeball" {
Properties
{
_Color ("Base Color", Color) = (1,1,1,0.5)
_MainTex ("Base (RGB)", 2D) = "white" {}
_EyeTex ("Eye Texture (RGB)", 2D) = "white" {}
_EyeColor1 ("Eye Color 1", Color) = (1,1,1,0.5)
_EyeColor2 ("Eye Color 2", Color) = (1,1,1,0.5)
_ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
_RimPower ("Rim Power", float) = 3.0
_Cube ("Reflection Cubemap", Cube) = "_Skybox" { TexGen CubeReflect }
[MaterialToggle] RampColor ("Ramp Color", Float) = 0
[MaterialToggle] CreatePupil ("Create Pupil", Float) = 0
[HideInInspector]EyeSize ("Eye Size", float) = 3.0
[HideInInspector]PupilSize ("Pupil Size", float) = 3.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert vertex:vert
#pragma multi_compile DUMMY RAMPCOLOR_ON
#pragma multi_compile DUMMY2 CREATEPUPIL_ON
sampler2D _MainTex;
sampler2D _EyeTex;
samplerCUBE _Cube;
fixed4 _Color;
fixed4 _EyeColor1;
fixed4 _EyeColor2;
fixed4 _ReflectColor;
uniform float4x4 EyeMatrix;
half _RimPower;
half EyeSize;
half PupilSize;
struct Input {
float2 uv_MainTex;
float4 eyeCoords;
float3 worldRefl;
float3 viewDir;
};
void vert (inout appdata_full v, out Input o)
{
o.eyeCoords = mul(EyeMatrix, mul(_Object2World, v.vertex));
}
void surf (Input IN, inout SurfaceOutput o)
{
half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
if (IN.eyeCoords.z > 0)
{
half4 irisTex = tex2D (_EyeTex, saturate(IN.eyeCoords.xy/EyeSize+0.5));
fixed irisBoundary = saturate((0.99 - irisTex.a)/0.05);
#ifdef CREATEPUPIL_ON
fixed pupilBoundary = saturate(saturate(irisTex.a - PupilSize) / 0.05);
#endif
#ifdef RAMPCOLOR_ON
#ifdef CREATEPUPIL_ON
o.Albedo = lerp(fixed3(0,0,0), lerp(c.rgb, lerp(_EyeColor1.rgb, _EyeColor2.rgb, irisTex.r), irisBoundary), pupilBoundary) * c.a;
#else
o.Albedo = lerp(c.rgb, lerp(_EyeColor1.rgb, _EyeColor2.rgb, irisTex.r), irisBoundary)* c.a;
#endif
#else
#ifdef CREATEPUPIL_ON
o.Albedo = lerp(fixed3(0,0,0), lerp(c.rgb, irisTex, irisBoundary), pupilBoundary)* c.a;
#else
o.Albedo = lerp(c.rgb, irisTex, irisBoundary)* c.a;
#endif
#endif
}
else
o.Albedo = c.rgb;
//o.Albedo *= _Color.rgb;
fixed4 reflcol = texCUBE (_Cube, IN.worldRefl) * _ReflectColor * c.a * _Color.a;
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
//o.Emission = _ReflectColor.rgb * pow (rim, _RimPower);
o.Emission = (_Color.a * o.Albedo* c.a + reflcol.rgb) * pow (rim, _RimPower);
o.Alpha = 1;
}
ENDCG
}
FallBack "Diffuse"
}
i have o problem with my shader code (HLSL). I use "DirectX for Managed Code" and Shader Model 3.0. I try to write a custom depth value into the depth buffer by using the DEPTH semantic in the pixel shader output struct:
struct PSOutput
{
float4 col : COLOR0;
float dept : DEPTH;
};
and i use this struct as return value in my pixel shader:
PSOutput PSFunction(VertexShaderOutput input)
{
PSOutput output;
...
output.col = float4(...);
output.dept = ...;
return output;
}
DirectX throws an exeption when i try to compile this shader, but gives no detailed information why. But when i remove the depth variable from the output struct it works! I also tried to write DEPTH0 as semantic, but no success. I hope anyone can help my with that.
EDIT:
If i write the following, it fails:
PSOutput PSFunction(VertexShaderOutput input)
{
PSOutput output;
float resDepth = input.Position[2] / input.Position[3];
if(...)
{
resDepth = ...;
}
output.col = float4(...);
output.dept = resDepth;
return output;
}
but if i write this code, it compiles:
PSOutput PSFunction(VertexShaderOutput input)
{
PSOutput output;
float resDepth = input.Position[2] / input.Position[3];
if(...)
{
resDepth = ...;
}
output.col = float4(...);
output.dept = 0.5;
return output;
}
any ideas?
Here's the full code:
float4x4 World;
float4x4 View;
float4x4 Projection;
float4 CamPos;
float4 LightDir;
float4 ObjColor;
static const float PI = 3.14159265f;
static const int MAX_FU = 32;
float fuPercent[MAX_FU];
float4 fuColor[MAX_FU];
int buildDir;
static int fuCount = 2;
float4 boxMin;
float4 boxMax;
struct VertexShaderInput
{
float4 Position : POSITION0;
float3 Normal : NORMAL;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float3 Normal : NORMAL;
float3 ExactPos : TEXCOORD1;
};
struct PSOutput
{
float4 col : COLOR0;
//float dept : DEPTH;
};
VertexShaderOutput VSFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.Normal = mul(input.Normal, World);
output.ExactPos = input.Position;
return output;
}
PSOutput PSFunction(VertexShaderOutput input)
{
PSOutput output;
float4 resColor = ObjColor;
float resDepth = input.Position[2] / input.Position[3];
float prpos = 0;
if (buildDir == 0)
{
prpos = (input.ExactPos[1] - boxMin[1]) / (boxMax[1] - boxMin[1]);
}
else if (buildDir == 1)
{
prpos = 1.0 - ((input.ExactPos[1] - boxMin[1]) / (boxMax[1] - boxMin[1]));
}
else if (buildDir == 2)
{
prpos = (input.ExactPos[2] - boxMin[2]) / (boxMax[2] - boxMin[2]);
}
else if (buildDir == 3)
{
prpos = 1.0 - ((input.ExactPos[2] - boxMin[2]) / (boxMax[1] - boxMin[2]));
}
else if (buildDir == 4)
{
prpos = (input.ExactPos[0] - boxMin[0]) / (boxMax[0] - boxMin[0]);
}
else if (buildDir == 5)
{
prpos = 1.0 - ((input.ExactPos[0] - boxMin[0]) / (boxMax[0] - boxMin[0]));
}
float currPerc = 1.1;
for (int i = 0; i < fuCount; i++)
{
if (prpos - 0.0001 <= fuPercent[i])
{
if (fuPercent[i] < currPerc)
{
currPerc = fuPercent[i];
resColor = fuColor[i];
}
}
else
{
resDepth = 1.0;
resColor[3] = 0.0;
}
}
float3 nor = input.Normal;
float3 pos = input.ExactPos;
float glo = 0.5;
float id = (acos(dot(LightDir,nor) / pow(dot(LightDir,LightDir) * dot(nor, nor), 0.5)) / PI );
id = pow(id,2);
float3 look = reflect(normalize(pos - CamPos), nor);
float gl = (acos(dot(LightDir,look) / pow(dot(LightDir,LightDir) * dot(look, look), 0.5)) / PI );
gl = max(gl * 10.0 - 9.0, 0.0);
gl = pow(gl,2) * glo;
output.col = float4(resColor[0] * id + gl, resColor[1] * id + gl, resColor[2] * id + gl, resColor[3]);
//output.dept = resDepth;
return output;
}
technique MyTechnique
{
pass Pass1
{
VertexShader = compile vs_3_0 VSFunction();
PixelShader = compile ps_3_0 PSFunction();
}
}
If FXC is throwing an exception during compilation rather than giving you a compilation error it's probably not anything you've done wrong.
If you're using the DirectX SDK make sure you're using the most recent version (June 2010). If you're using the Windows Kit 8.0 SDK then you may have found a compiler bug. What version of the SDK / fxc are you using?
Can you post a shader that actually compiles (one with the missing VertexShaderOutput struct and without ...'s in place of actual code)? I've filled in the missing code and have no problem compiling it using fxc from Windows Kit 8.0.
EDIT:
Nope, I hadn't spotted you'd commented out the code that made it not compile.
Sure enough, it doesn't compile, but that's because it's not valid code (as reported by the compile errors). You're using the POSITION semantic as an input to your pixel shader, which is not valid. If you want to use the outputted position from a vertex shader as input to a pixel shader, copy it into a second attribute and use that instead. If I substitute the following code into your shader it then compiles:
struct VertexShaderOutput
{
float4 ClipPosition : POSITION; // Renamed this to ClipPosition.
float4 Position : TEXCOORD0; // This is valid to use as an input to the pixel shader.
float3 Normal : NORMAL;
float3 ExactPos : TEXCOORD1;
};
struct PSOutput
{
float4 col : COLOR0;
float dept : DEPTH;
};
VertexShaderOutput VSFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.ClipPosition = mul(viewPosition, Projection);
output.Position = output.ClipPosition; // Copy output position to our other attribute.
output.Normal = mul(input.Normal, World);
output.ExactPos = input.Position;
return output;
}