2013-10-29 13 views
5

मुझे समस्या है कि नीचे पिक्सेल शेडर (एचएलएसएल) निर्देशों (नीचे सुझाए गए अनुकूलन के साथ) को संकलित करता है। हालांकि, मैं इसे शेडर मॉडल 2 के साथ उपयोग करना चाहता हूं और इसलिए दुर्भाग्य से मैं केवल निर्देशों का उपयोग कर सकता हूं। क्या कोई भी शेडर के परिणाम को बदले बिना किसी भी संभावित अनुकूलन को देखता है?एचएलएसएल शेडर का अनुकूलन

शेडर आरजीबी से स्क्रीन के एक कम या कम गोलाकार क्षेत्र को सफेद के ढाल में बदलता है -> लाल -> काला कुछ अतिरिक्त चमक आदि के साथ बदलता है।

शेडर कोड है:

// Normalized timefactor (1 = fully enabled) 
float timeFactor; 

// Center of "light" 
float x; 
float y; 

// Size of "light" 
float viewsizeQ; 
float fadesizeQ; 

// Rotational shift 
float angleShift; 

// Resolution 
float screenResolutionWidth; 
float screenResolutionHeight; 
float screenZoomQTimesX; 

// Texture sampler 
sampler TextureSampler : register(s0); 

float4 method(float2 texCoord : TEXCOORD0) : COLOR0 
{ 
// New color after transformation 
float4 newColor; 

// Look up the texture color. 
float4 color = tex2D(TextureSampler, texCoord); 

// Calculate distance 
float2 delta = (float2(x, y) - texCoord.xy) 
      * float2(screenResolutionWidth, screenResolutionHeight); 

// Get angle from center 
float distQ = dot(delta, delta) - sin((atan2(delta.x, delta.y) + angleShift) * 13) * screenZoomQTimesX; 

// Within fadeSize 
if (distQ < fadesizeQ) 
{ 
    // Make greyscale 
    float grey = dot(color.rgb, float3(0.3, 0.59, 0.11)); 

    // Increase contrast by applying a color transformation based on a quasi-sigmoid gamma curve 
    grey = 1/(1 + pow(1.25-grey/2, 16)); 

    // Transform Black/White color range to Black/Red/White color range 
    // 1 -> 0.5f ... White -> Red 
    if (grey >= 0.75) 
    { 
    newColor.r = 0.7 + 0.3 * color.r; 
    grey = (grey - 0.75) * 4; 
    newColor.gb = 0.7 * grey + 0.3 * color.gb; 
    } 
    else // 0.5f -> 0 ... Red -> Black 
    { 
    newColor.r = 1.5 * 0.7 * grey + 0.3 * color.r; 
    newColor.gb = 0.3 * color.gb ; 
    } 

    // Within viewSize (Full transformation, only blend with timefactor) 
    if (distQ < viewsizeQ) 
    { 
color.rgb = lerp(newColor.rgb, color.rgb, timeFactor); 
    } 
    // Outside viewSize but still in fadeSize (Spatial fade-out but also with timefactor) 
    else 
    { 
     float factor = timeFactor * (1 - (distQ - viewsizeQ)/(fadesizeQ - viewsizeQ)); 
     color.rgb = lerp(newColor.rgb, color.rgb, factor); 
    } 
} 

उत्तर

5

कुछ बिट्स और टुकड़े भी, आपके पास प्रकाश केंद्र + स्क्रीन चौड़ाई/ऊंचाई के लिए एक्स, वाई है। फिर अपने कोड में

float2 light; 
float2 screenResolution; 

:

द्वारा की जगह

float2 delta = (light - texCoord.xy) * screenResolution; 

2 अधिक निर्देश निकाल देना चाहिए।

अगला एटान 2 का उपयोग है, जो सबसे भूख होने की संभावना है।

आप एक और फ्लोट 2 (फ्लोट 2 vecshift) घोषित कर सकते हैं, जहां x = cos (AngleShift) और y = sin (angleShift)। बस इसे सीपीयू में प्रीकंप्यूट करें।

तो आप निम्न कर सकते (मूल रूप से एक क्रॉस उत्पाद कर के बजाय atan2 का उपयोग कर के कोण को निकालने के लिए):

float2 dn = normalize(delta); 
float cr = dn.x *vecshift.y -dn.y * vecshift.x; 
float distQ = dot(delta, delta) - sin((asin(cr))*13) *screenZoomQTimesX; 

कृपया ध्यान दें की तुलना में मैं कुछ की असिन के पाप पर बहुत उत्सुक नहीं हूँ, लेकिन बहुपद फॉर्म आपके उपयोग के मामले में फिट नहीं होगा। मुझे यकीन है कि sin * asin tho का उपयोग करने से संशोधित करने के लिए एक बहुत साफ संस्करण है)

का उपयोग करना? इसके बजाय निर्माण/अन्यथा भी आपके निर्देश गणना के लिए मदद कर सकते हैं।

color.rgb = lerp(newColor.rgb, color.rgb, distQ < viewsizeQ ? timeFactor : timeFactor * (1 - (distQ - viewsizeQ)/(fadesizeQ - viewsizeQ))); 

2 और निर्देशों को कम करता है।

यहां पूर्ण संस्करण, 60 निर्देशों पर सेट करता है।

// Normalized timefactor (1 = fully enabled) 
float timeFactor; 

float2 light; 

float viewsizeQ; 
float fadesizeQ; 

float2 screenResolution; 
float screenZoomQTimesX; 

float2 vecshift; 

// Texture sampler 
sampler TextureSampler : register(s0); 

float4 method(float2 texCoord : TEXCOORD0) : COLOR0 
{ 
// New color after transformation 
float4 newColor; 

// Look up the texture color. 
float4 color =tex2D(Samp, texCoord); 

// Calculate distance 
float2 delta = (light - texCoord.xy) * screenResolution; 

float2 dn = normalize(delta); 
float cr = dn.x *vecshift.y -dn.y * vecshift.x; 

float distQ = dot(delta, delta) - sin((asin(cr))*13) *screenZoomQTimesX; 
//float distQ = dot(delta, delta) - a13 *screenZoomQTimesX; 

if (distQ < fadesizeQ) 
{ 
    // Make greyscale 
    float grey = dot(color.rgb, float3(0.3, 0.59, 0.11)); 

    // Increase contrast by applying a color transformation based on a quasi-sigmoid gamma curve 
    grey = 1/(1 + pow(1.25-grey/2, 16)); 

    // Transform Black/White color range to Black/Red/White color range 
    // 1 -> 0.5f ... White -> Red 
    if (grey >= 0.75) 
    { 
     newColor.r = 0.7 + 0.3 * color.r; 
     grey = (grey - 0.75) * 4; 
     newColor.gb = 0.7 * grey + 0.3 * color.gb; 
    } 
    else // 0.5f -> 0 ... Red -> Black 
    { 
     newColor.r = 1.5 * 0.7 * grey + 0.3 * color.r; 
     newColor.gb = 0.3 * color.gb ; 
    } 

    color.rgb = lerp(newColor.rgb, color.rgb, distQ < viewsizeQ ? timeFactor : timeFactor * (1 - (distQ - viewsizeQ)/(fadesizeQ - viewsizeQ))); 
} 
return color; 

} 
4

सुझाव

  • के एक जोड़े को आप अपने अर्ध अवग्रह के लिए (एक लुकअप तालिका के रूप में) एक -1 डी नमूना इस्तेमाल कर सकते हैं। यदि power 0 से 1 तक जाता है, तो 1 x 256 (या जो भी क्षैतिज आकार आपके फ़ंक्शन को सबसे सुरक्षित रखता है) का बनावट बनाएं और tex1D का उपयोग करके अपने वर्तमान power के लिए बस एक मान देखें। इस बनावट को भरने के लिए आपको इस फ़ंक्शन को CPU पर चलाने की आवश्यकता होगी, लेकिन यह लोड लोड के दौरान एक बार किया जाएगा।
  • आप इसके बजाय color.rgb = /*0.7 */ factor * newColor.rgb + /*0.3 **/ (1 - factor) * color.rgb; के रूप में वर्तनी के बजाय lerp फ़ंक्शन का उपयोग कर सकते हैं, color.rgb = lerp(newColor.rgb, color.rgb, factor); (आमतौर पर अधिकांश GPUs पर असेंबली निर्देश के लिए संकलित) का उपयोग करें, आपको निर्देशों को सहेजते हैं।
+0

आपके सुझावों के लिए धन्यवाद! मैं एचएलएसएल में लुकअप-टेबल कैसे कार्यान्वित करूं - क्या आप मुझे एक उदाहरण दे सकते हैं? उपरोक्त कोड का कौन सा हिस्सा लेर्प निर्देश द्वारा अनुकूलित किया जा सकता है? –

+1

उपर्युक्त उत्तर के हिस्से के रूप में स्पष्टीकरण जोड़ा गया। – Ani

+0

धन्यवाद, लेर्प (अब उपरोक्त शेडर कोड में शामिल) ने एक निर्देश सहेजा जो हमें 68 (69 से) तक ले जाता है। –

1

कुछ और lerps का उपयोग करके मैं इसे 64 निर्देशों से नीचे प्राप्त करने में सक्षम था। लुकअप टेबल मदद नहीं करता क्योंकि एटान 2 वास्तव में बनावट को देखने से कम निर्देशों का नेतृत्व करता है।

// Normalized timefactor (1 = fully enabled) 
float timeFactor; 

// Center of "light" 
float x; 
float y; 

// Size of "light" 
float viewsizeQ; 
float fadesizeQ; 

// Rotational shift 
float angleShift; 

// Resolution 
float screenResolutionWidth; 
float screenResolutionHeight; 
float screenZoomQTimesX; 

// Texture sampler 
sampler TextureSampler : register(s0); 

float4 method(float2 texCoord : TEXCOORD0) : COLOR0 
{ 
float4 newColor; 

// Look up the texture color. 
float4 color = tex2D(TextureSampler, texCoord); 

// Calculate distance 
float2 delta = (float2(x, y) - texCoord.xy) 
      * float2(screenResolutionWidth, screenResolutionHeight); 

// Get angle from center 
float distQ = dot(delta, delta) - sin((atan2(delta.x, delta.y) + angleShift) * 13) * screenZoomQTimesX; 

// Outside fadeSize: No color transformation 
if (distQ >= fadesizeQ) return color; 

// Otherwise (within color transformed region) ///////////////////////////////////////////////////////// 

// Make greyscale 
float grey = dot(color.rgb, float3(0.3, 0.59, 0.11)); 

// Increase contrast by applying a color transformation based on a quasi-sigmoid gamma curve 
grey = 1/(1 + pow(1.25-grey/2, 16)); 

// Transform greyscale to white->red->black gradient 
// 1 -> 0.5f ... White -> Red 
if (grey >= 0.5) 
{ 
newColor = lerp(float4(0.937,0.104,0.104,1), float4(1,1,1,1), 2 * (grey-0.5) 
} 
else // 0.5f -> 0 ... Red -> Black 
{ 
newColor = lerp(float4(0,0,0,1), float4(0.937,0.104,0.104,1), 2 * grey); 
} 

float factor = saturate(timeFactor * (1 - (distQ - viewsizeQ)/(fadesizeQ - viewsizeQ))); 
color.rgb = lerp(color.rgb, newColor.rgb, factor); 

return color; 
} 
संबंधित मुद्दे