มัลติเพลเยอร์ทำงานใน OpenGL อย่างไร


13

ใน Direct3D นั้น shader แบบหลายตัวนั้นใช้งานง่ายเพราะคุณสามารถกำหนด pass ภายในโปรแกรมได้อย่างแท้จริง ใน OpenGL ดูเหมือนว่าจะซับซ้อนกว่านี้เล็กน้อยเนื่องจากเป็นไปได้ที่จะให้โปรแกรม shader เป็นจุดสุดยอดรูปทรงเรขาคณิตและส่วนที่แตกต่างกันตามที่คุณต้องการ

ตัวอย่างที่เป็นที่นิยมของเครื่องมัลติพลาสเดอร์คือเครื่องจิ้มอเนกประสงค์ การผ่านหนึ่งครั้งจะมีเอฟเฟ็กต์การแรเงาที่เกิดขึ้นจริงและอีกอันจะสร้างโครงร่าง ถ้าฉันมีสองจุดยอด "cel.vert" และ "outline.vert" และสองชิ้นส่วน "cel.frag" และ "outline.frag" (คล้ายกับที่คุณทำใน HLSL) ฉันจะทำได้อย่างไร รวมเข้าด้วยกันเพื่อสร้าง shader toon แบบเต็ม?

ฉันไม่ต้องการให้คุณพูดว่าสามารถใช้รูปทรงเรขาคณิตสำหรับเรื่องนี้ได้เพราะฉันแค่อยากรู้ทฤษฎีที่อยู่เบื้องหลัง GLSL หลายตัว;)


"ใน Direct3D มัลติเพลเยอร์นั้นใช้งานง่ายเพราะคุณสามารถกำหนดการส่งผ่านภายในโปรแกรมได้อย่างแท้จริง" ไม่คุณไม่สามารถ คุณสามารถกำหนดรหัสผ่านในไฟล์ FX ได้ แต่นั่นไม่เหมือนกับ HLSL shader
Nicol Bolas

คำตอบ:


11

ไม่มี "ทฤษฎี" เบื้องหลังมัลติพอยต์ ไม่มี "ตัวคูณทวีคูณ" Multipass นั้นง่ายมาก: คุณวาดวัตถุด้วยโปรแกรมเดียว จากนั้นคุณวาดวัตถุที่มีความแตกต่างกันโปรแกรม

คุณสามารถใช้สิ่ง D3DX เช่นไฟล์ FX เพื่อซ่อนรหัสผ่านพิเศษเหล่านี้ แต่พวกเขายังคงทำงานอย่างนั้น OpenGL ไม่มีที่ซ่อนสำหรับมัน


1

แสดงวัตถุด้วยเซลล์ shader จากนั้นแสดงผลอีกครั้งด้วยส่วนโครงร่าง


1
ดังนั้นฉันควรสร้างสองโปรแกรมที่แตกต่างกัน? ทำไมจึงเป็นเช่นนั้นฉันสามารถให้โปรแกรม shader ได้มากที่สุดเท่าที่ฉันต้องการ? จะต้องมีวิธีการทำกับโปรแกรมเดียว
jmegaffin

1
คุณไม่ได้ให้จุดยอดหลายจุด (ฯลฯ ) มีเพียงฟังก์ชั่นหลักเดียวเท่านั้นดังนั้นคุณจึงไม่มีจุดเข้าใช้งานหลายจุด มันคล้ายกับโปรแกรม C ที่คุณสามารถมีไฟล์หลายไฟล์ซึ่งเชื่อมโยงเข้าด้วยกันเพื่อสร้างโปรแกรม คุณสามารถแชร์ไฟล์เหล่านี้ระหว่างโปรแกรมที่แตกต่างกันดังนั้นคุณไม่จำเป็นต้องทำซ้ำรหัส แต่แต่ละไฟล์ไม่จำเป็นต้องเป็นโปรแกรมด้วยตัวเอง
Chewy Gumball

1
นั่นเป็นวิธีที่จะทำให้ Render หนึ่งครั้งพร้อมกับคู่หนึ่ง shader (จุดสุดยอด + ชิ้นส่วน) จากนั้นแสดงผลอีกครั้งด้วยอีกคู่หนึ่ง (หรือใช้จุดสุดยอดเดียวกัน บางครั้งคุณแสดงผลเป็นบัฟเฟอร์และใช้ (ยัง) shader อื่นเพื่อ 'ผสมผสาน' ลงในผลลัพธ์สุดท้าย
Valmond

1

ใน OpenGL 4.0 มีโปรแกรมย่อยเครื่องแบบ สิ่งเหล่านี้ช่วยให้คุณสามารถกำหนดฟังก์ชั่นที่สามารถสลับออกตอนรันไทม์ด้วยค่าใช้จ่ายน้อยมาก ดังนั้นคุณสามารถสร้าง 1 ฟังก์ชันสำหรับแต่ละรอบได้ นอกจากนี้ 1 ฟังก์ชั่นสำหรับแต่ละประเภท Shader

มีการสอนที่นี่

สำหรับรุ่น OpenGL ที่เก่าที่สุดทางออกที่ดีที่สุดของคุณคือการมีเฉดสีที่แตกต่างกันและสลับไปมาระหว่างกัน มิฉะนั้นคุณสามารถเพิ่มค่าที่คุณคูณด้วยเครื่องแบบที่เป็น 0.0 หรือ 1.0 เพื่อเปิดหรือปิด มิฉะนั้นเป็นเงื่อนไขหากสามารถใช้คำสั่งได้ แต่ OpenGL จะดำเนินการผลลัพธ์ที่เป็นไปได้ทั้งหมดในทุกการดำเนินการ / ผ่านดังนั้นตรวจสอบให้แน่ใจว่าข้อความเหล่านั้นไม่หนักเกินไป


0

มีบางคนที่รู้เรื่องเกี่ยวกับ GLSL เป็นอย่างมากดังนั้นฉันหวังว่าพวกเขาจะสร้างสถิติที่ตรง แต่ขึ้นอยู่กับสิ่งที่ฉันได้เห็นคุณควรจะสามารถทำสิ่งนี้ได้ (pseudocode ฉัน จะปล่อยให้ GLSL ตามจริงกับคนที่รู้จักดีกว่า):

out vec4 fragment_color
vec4 final_color
final_color = flat_color
If this fragment is in shadow
    final_color = shadow_color
If this fragment is an edge
    final_color = edge_color
If this fragment is a highlight
    final_color = highlight_color
fragment_color = final_color

ด้วยการใช้ifs ด้วยวิธีนี้คุณจะได้รับหลาย ๆ รอบ มันสมเหตุสมผลไหม

แก้ไข:นอกจากนี้หวังว่าคำถามนี้ใน SOจะช่วยขจัดความเข้าใจผิดบางอย่าง


2
เป็นสิ่งสำคัญที่จะต้องทราบว่า GLSL จะดำเนินการคำสั่งทั้งหมดใน if branch ทุก pass แม้ว่าจะไม่ได้เปิดใช้งานก็ตาม เห็นได้ชัดว่าเพียงการคำนวณทุกอย่างและเพิ่มสีทั้งหมดเข้าด้วยกัน แต่การคูณค่าด้วย 1.0 หรือ 0.0 เพื่อเปิดใช้งานหรือปิดใช้งานพวกเขาจะเร็วขึ้น
ดาวิดซี. บิชอป

1
@ DavidC.Bishop: นั่นไม่จริง อย่างน้อยไม่รับประกันว่าจะเป็นจริง คอมไพเลอร์จะตัดสินว่าสาขาที่แท้จริงนั้นเร็วกว่าหรือวิธี "คำนวณทุกอย่างและแยกออกภายหลัง" เร็วกว่า
Nicol Bolas

1
นอกเหนือจากนี้พฤติกรรมที่อ้างถึงโดย @ DavidC.Bishop นั้นแทบจะไม่เฉพาะกับ shaders และ GPU CPU สมัยใหม่ที่ใช้งานโปรแกรมปกติจะทำงานอย่างน้อยหนึ่งสาขาในกรณีที่ค่าทดสอบยังไม่พร้อมใช้งาน หากพวกเขากลายเป็นผิดพวกเขาจะย้อนกลับและทำซ้ำ สิ่งนี้จบลงด้วยการเร่งความเร็วโดยเฉลี่ย
ipeet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.