Home | History | Annotate | Download | only in d3d11spikysphere
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 Luca Barbieri
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial
     15  * portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  **************************************************************************/
     26 
     27 #define INPUT_PATCH_SIZE 3
     28 #define OUTPUT_PATCH_SIZE 3
     29 
     30 static const float PI = 3.141592653589793238462643f;
     31 
     32 cbuffer cb_frame
     33 {
     34 	float4x4 model;
     35 	float4x4 view_proj;
     36 	float disp_scale;
     37 	float disp_freq;
     38 	float tess_factor;
     39 };
     40 
     41 struct IA2VS
     42 {
     43 	float3 position : POSITION;
     44 };
     45 
     46 struct VS2HS
     47 {
     48 	float3 position : POSITION;
     49 };
     50 
     51 VS2HS vs(IA2VS input)
     52 {
     53 	VS2HS result;
     54 	result.position = input.position;
     55 	return result;
     56 }
     57 
     58 struct HS2DS_PATCH
     59 {
     60 	float tessouter[3] : SV_TessFactor;
     61 	float tessinner[1] : SV_InsideTessFactor;
     62 };
     63 
     64 struct HS2DS
     65 {
     66 	float3 position : POSITION;
     67 };
     68 
     69 HS2DS_PATCH hs_patch(InputPatch<VS2HS, INPUT_PATCH_SIZE> ip)
     70 {
     71 	HS2DS_PATCH result;
     72 
     73 	result.tessouter[0] = result.tessouter[1] = result.tessouter[2]
     74 		= result.tessinner[0] = tess_factor;
     75 	return result;
     76 }
     77 
     78 [domain("tri")]
     79 [partitioning("fractional_even")]
     80 [outputtopology("triangle_cw")]
     81 [outputcontrolpoints(OUTPUT_PATCH_SIZE)]
     82 [patchconstantfunc("hs_patch")]
     83 HS2DS hs(InputPatch<VS2HS, INPUT_PATCH_SIZE> p, uint i : SV_OutputControlPointID)
     84 {
     85 	HS2DS result;
     86 	result.position = p[i].position;
     87 	return result;
     88 }
     89 
     90 struct DS2PS
     91 {
     92 	float4 position : SV_POSITION;
     93 	float3 objpos : OBJPOS;
     94 	// float3 worldpos : WORLDPOS;
     95 	float3 objnormal : OBJNORMAL;
     96 	float3 worldnormal : WORLDNORMAL;
     97 };
     98 
     99 float3 dnormf_dt(float3 f, float3 dfdt)
    100 {
    101 	float ff = dot(f, f);
    102 	return (ff * dfdt - dot(f, dfdt) * f) / (ff * sqrt(ff));
    103 }
    104 
    105 float3 map(float3 p, float3 q, float3 r, float3 k)
    106 {
    107 	return normalize(p * k.x + q * k.y + r * k.z);
    108 }
    109 
    110 float3 dmap_du(float3 p, float3 q, float3 r, float3 k)
    111 {
    112 	return dnormf_dt(p * k.x + q * k.y + r * k.z, p);
    113 }
    114 
    115 float dispf(float v)
    116 {
    117 	return cos(v * disp_freq);
    118 }
    119 
    120 float ddispf(float v)
    121 {
    122 	return -sin(v * disp_freq) * disp_freq;
    123 }
    124 
    125 float disp(float3 k)
    126 {
    127 	return dispf(k.x) * dispf(k.y) * dispf(k.z);
    128 }
    129 
    130 float ddisp_du(float3 k)
    131 {
    132 	return ddispf(k.x) * dispf(k.y) * dispf(k.z);
    133 }
    134 
    135 float3 ddisp(float3 k)
    136 {
    137 	float3 f = float3(dispf(k.x), dispf(k.y), dispf(k.z));
    138 	return float3(ddispf(k.x) * f.y * f.z, ddispf(k.y) * f.z * f.x, ddispf(k.z) * f.x * f.y);
    139 }
    140 
    141 [domain("tri")]
    142 DS2PS ds(HS2DS_PATCH input,
    143                     float3 k : SV_DomainLocation,
    144                     const OutputPatch<HS2DS, OUTPUT_PATCH_SIZE> patch)
    145 {
    146 	DS2PS result;
    147 
    148 	float3 s = map(patch[0].position, patch[1].position, patch[2].position, k);
    149 	float3 d = 1.0 + disp(s) * disp_scale;
    150 	result.objpos = s * d;
    151 	result.objpos /= (1.0 + disp_scale);
    152 	float3 worldpos = mul(model, float4(result.objpos, 1.0f));
    153 	result.position = mul(view_proj, float4(worldpos, 1.0f));
    154 
    155 	float3 dd = ddisp(s) * disp_scale;
    156 
    157 	/*
    158 	float3 ds_du = dmap_du(patch[0].position, patch[1].position, patch[2].position, k);
    159 	float3 ds_dv = dmap_du(patch[1].position, patch[2].position, patch[0].position, k.yzx);
    160 	float3 ds_dw = dmap_du(patch[2].position, patch[0].position, patch[1].position, k.zxy);
    161 
    162 	float3 ds_dU = ds_du - ds_dw;
    163 	float3 ds_dV = ds_dv - ds_dw;
    164 
    165 	float3 dc_dU = s * dot(dd, ds_dU) + ds_dU * d;
    166 	float3 dc_dV = s * dot(dd, ds_dV) + ds_dV * d;
    167 	*/
    168 
    169 	// this should be faster
    170 	float3 _u = normalize((abs(s.x) > abs(s.y)) ? float3(-s.z, 0, s.x) : float3(0, -s.z, s.y));
    171 	float3 _v = normalize(cross(s, _u));
    172 	float3 dc_dU = s * dot(dd, _u) + _u * d;
    173 	float3 dc_dV = s * dot(dd, _v) + _v * d;
    174 
    175 	result.objnormal = normalize(cross(dc_dU, dc_dV));
    176 	result.worldnormal = mul(model, result.objnormal);
    177 	return result;
    178 }
    179 
    180 float4 ps(DS2PS input) : SV_TARGET
    181 {
    182 	float3 pseudoambient = float3(0.4, 0.4, 0.6);
    183 	float3 diffuse = float3(0.6, 0.6, 0.4);
    184 	float3 light = normalize(float3(0, 1, -1));
    185 
    186 	float4 r;
    187 //	r.xyz = normalize(input.objpos + 2 * input.objnormal);
    188 	r.xyz = pseudoambient * saturate(dot(normalize(input.objnormal), normalize(input.objpos)));
    189 	r.xyz += saturate(dot(light, normalize(input.worldnormal))) * diffuse;
    190 
    191 	r.w = 1;
    192 	return r;
    193 }
    194