const program = await renderer.debug.getShaderAsync(scene, camera, mesh)
console.log('**VERTEX SHADER CODE**\n\n', program.vertexShader)
console.log('**FRAGMENT SHADER CODE**\n\n', program.fragmentShader)
three.js, userData 노드
three.js는 Mesh 등과 같은 객체에 사용자 데이터를 넣기 위한 userData 속성이 있습니다. 이처럼 userData 속성에 저장된 값을 쉐이더에서 참조할 수 있도록 해주는 노드가 userData 노드입니다. 사용 예시는 다음과 같습니다.
mesh.userData.한글 = new THREE.Color('#ffff00')
material.outputNode = vec4(userData('한글'), 1)
이렇게 사용된 Mesh 객체를 통해 userData의 값이 변경되면 자동으로 TSL 코드를 통해 반영됩니다.
Java 11, HTTP Client API
Java 11부터는 별도의 외부 라이브러리 없이도 Java에서 기본적으로 제공하는 HTTP Client API를 통해 거의 대부분의 네트워크 통신(클라이언트에서 서버로의 요청) 기능을 처리할 수 있습니다.
이 API는 HttpURLConnection을 대체하기 위해 설계되었으며, HTTP/1.1과 HTTP/2, 동기/비동기 통신, WebSocket, Proxy, Authentication, TLS/SSL, HTTP/2 Server Push 등을 지원합니다.
예를들어서 GET 방식의 동기적 요청은 다음 코드와 같습니다.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class App {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com"))
.GET()
.build();
HttpResponse<String> response = client.send(
request,
HttpResponse.BodyHandlers.ofString()
);
System.out.println("Status: " + response.statusCode());
System.out.println("Headers: " + response.headers());
System.out.println("Body:" + response.body());
}
}
17번 코드의 send 매서드에 지정한 2번째 인자는 body를 문자열로 받겠다는 의도입니다.
POST 방식의 동기적 요청에 대한 코드 예시는 다음과 같습니다.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class App {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String json = """
{
"name": "Tom",
"age": 20
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/users"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(
request,
HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}
위의 코드는 동기적 요청인데, 비동기적 요청 방식으로 변경하면 다음과 같습니다.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class App {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
String json = """
{
"name": "Tom",
"age": 20
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/users"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
client.sendAsync(
request,
HttpResponse.BodyHandlers.ofString())
.thenAccept(response -> {
System.out.println(response.statusCode());
System.out.println(response.body());
})
.join();
}
}
TypeScript, 익명 클래스
타입스크립트, 정확히는 JavaScript도 익명 클래스를 정의할 수 있습니다. 다음처럼요.
const x = new class<Type> {
content: Type;
constructor(value: Type) {
this.content = value;
}
say() {
console.log(this.content);
}
}("Hello World!");
x.say();
TypeScript, this 라는 타입에 관하여
타입스크립트에서는 클래스에서 사용되는 this라는 타입이 있습니다. 이 this 타입은 동적으로 현재 클래스에 대한 타입으로 결정됩니다. 애매하고 어렵죠? 예시를 통해 좀더 살펴보면..
class Box {
content: string = "";
sameAs(other: this) {
return other.content === this.content;
}
}
class DerivedBox1 extends Box {
otherContent: string = "?";
}
class DerivedBox2 extends Box {
otherContent: string = "?";
}
const base = new Box();
const derived1 = new DerivedBox1();
derived1.sameAs(base);
const derived2 = new DerivedBox2();
derived2.sameAs(base);
위의 코드에서 Box 클래스의 sameAs 인자의 other 타입이 this입니다. 이 Box 클래스를 상속받는 파생클래스들을 통해 sameAs를 사용할 경우 sameAs의 첫번째 인자인 other는 각 파생클래스의 타입이 됩니다. 즉 derived1의 sameAs 매서드의 정의는 다음과 같고…
sameAs(other: DerivedBox1): boolean
derived2의 sameAs 매서드의 정의는 다음과 같습니다.
sameAs(other: DerivedBox2): boolean
